From 66836dbd76c52123dc9a6e947e726336eefd05a8 Mon Sep 17 00:00:00 2001 From: Derek Slaughter Date: Fri, 9 Jun 2023 11:58:51 -0400 Subject: [PATCH 1/3] Fix Registry not compiling on Windows This commit removes the dependency on std::filesystem which is not well supported by all compilers. This will now compiler on VS2015. This also fixes some bugs with generating templates and registry files when beginning a new module. --- modules/openfast-registry/CMakeLists.txt | 2 +- modules/openfast-registry/src/main.cpp | 19 +- modules/openfast-registry/src/registry.cpp | 3 + .../src/registry_gen_fortran.cpp | 3 +- modules/openfast-registry/src/templates.hpp | 1930 ++++++++--------- 5 files changed, 983 insertions(+), 974 deletions(-) diff --git a/modules/openfast-registry/CMakeLists.txt b/modules/openfast-registry/CMakeLists.txt index 051b9d0727..58020bfa11 100644 --- a/modules/openfast-registry/CMakeLists.txt +++ b/modules/openfast-registry/CMakeLists.txt @@ -23,7 +23,7 @@ add_executable(openfast_registry src/registry.hpp src/templates.hpp ) -set_property(TARGET openfast_registry PROPERTY CXX_STANDARD 17) +target_compile_features(openfast_registry PRIVATE cxx_std_11) set_target_properties(openfast_registry PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/modules/openfast-registry diff --git a/modules/openfast-registry/src/main.cpp b/modules/openfast-registry/src/main.cpp index 25720a6e9e..a38844b0bf 100644 --- a/modules/openfast-registry/src/main.cpp +++ b/modules/openfast-registry/src/main.cpp @@ -1,5 +1,4 @@ #include -#include #include "registry.hpp" #include "templates.hpp" @@ -113,6 +112,7 @@ int main(int argc, char *argv[]) bool is_template = arg.substr(1).compare("template") == 0; output_template(module_name, module_nickname, output_force_template, is_template); + return EXIT_SUCCESS; } else if ((arg.compare("-h") == 0) || (arg.compare("/h") == 0)) { @@ -124,9 +124,16 @@ int main(int argc, char *argv[]) // Set input file path inp_file_path = arg; - // Add input file directory to list of directories to search - std::filesystem::path path(arg); - reg.include_dirs.push_back(path.parent_path()); + // Replace backslashes with forward slashes in path + std::string path = std::regex_replace(arg, std::regex("\\\\"), "/"); + + // If path contains / remove everything after it + auto slash_index = path.find_last_of("/"); + if (slash_index != std::string::npos) + path = path.substr(0, slash_index); + + // Add input file directory to list of include directories + reg.include_dirs.push_back(path); } } @@ -172,7 +179,7 @@ void output_template(std::string &module_name, std::string &module_nickname, boo } // Select file contents - auto contents = (is_template ? module_template : registry_template).substr(1); + auto contents = (is_template ? module_template : registry_template); // Populate module name and module nickname contents = std::regex_replace(contents, std::regex("ModuleName"), module_name); @@ -180,4 +187,6 @@ void output_template(std::string &module_name, std::string &module_nickname, boo // Output contents to file outfile << contents; + + std::cerr << "Created " << (is_template ? "template" : "registry") << " file '" << fname << "'" << std::endl; } diff --git a/modules/openfast-registry/src/registry.cpp b/modules/openfast-registry/src/registry.cpp index b0ad7ad660..cc998fb8bf 100644 --- a/modules/openfast-registry/src/registry.cpp +++ b/modules/openfast-registry/src/registry.cpp @@ -1,3 +1,6 @@ +#include +#include + #include "registry.hpp" void Registry::gen_module_files(std::string const &out_dir) diff --git a/modules/openfast-registry/src/registry_gen_fortran.cpp b/modules/openfast-registry/src/registry_gen_fortran.cpp index a560b59830..f16d6c354b 100644 --- a/modules/openfast-registry/src/registry_gen_fortran.cpp +++ b/modules/openfast-registry/src/registry_gen_fortran.cpp @@ -1,5 +1,4 @@ #include -#include #include "registry.hpp" #include "templates.hpp" @@ -75,7 +74,7 @@ void Registry::gen_fortran_module(const Module &mod, const std::string &out_dir) } // Write preamble - w << std::regex_replace(FAST_preamble.substr(1), std::regex("ModuleName"), mod.name); + w << std::regex_replace(FAST_preamble, std::regex("ModuleName"), mod.name); // Output USE statements for non-root modules for (auto const &mod : this->use_modules) diff --git a/modules/openfast-registry/src/templates.hpp b/modules/openfast-registry/src/templates.hpp index c4e05a8cb1..628d89bfad 100644 --- a/modules/openfast-registry/src/templates.hpp +++ b/modules/openfast-registry/src/templates.hpp @@ -3,971 +3,969 @@ #include -const std::string FAST_preamble = R""""( -!STARTOFREGISTRYGENERATEDFILE 'ModuleName_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 -!********************************************************************************************************************************* -! ModuleName_Types -!................................................................................................................................. -! This file is part of ModuleName. -! -! 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 ModuleName. 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 ModuleName_Types -!--------------------------------------------------------------------------------------------------------------------------------- -)""""; - -const std::string registry_template = R""""( -################################################################################################################################### -# Registry for ModuleName in the FAST Modularization Framework -# This Registry file is used to create MODULE ModuleName_Types, which contains all of the user-defined types needed in ModuleName. -# It also contains copy, destroy, pack, and unpack routines associated with each defined data types. -# -# Entries are of the form -# keyword -# -# Use ^ as a shortcut for the value from the previous line. -# See NWTC Programmer's Handbook at https://nwtc.nrel.gov/FAST-Developers for further information on the format/contents of this file. -################################################################################################################################### - -# ...... Include files (definitions from NWTC Library) ............................................................................ -include Registry_NWTC_Library.txt - - -# ..... Initialization data ....................................................................................................... -# Define inputs that the initialization routine may need here: -# e.g., the name of the input file, the file root name, etc. -typedef ModuleName/ModName 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.\" - - -# 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\" - -# if this module has implemented linearization, return the names of the rows/columns of the Jacobian matrices: -#typedef ^ InitOutputType CHARACTER(LinChanLen) LinNames_y {:} - - \"Names of the outputs used in linearization\" - -#typedef ^ InitOutputType CHARACTER(LinChanLen) LinNames_x {:} - - \"Names of the continuous states used in linearization\" - -#typedef ^ InitOutputType CHARACTER(LinChanLen) LinNames_xd {:} - - \"Names of the discrete states used in linearization\" - -#typedef ^ InitOutputType CHARACTER(LinChanLen) LinNames_z {:} - - \"Names of the constraint states used in linearization\" - -#typedef ^ InitOutputType CHARACTER(LinChanLen) LinNames_u {:} - - \"Names of the inputs used in linearization\" - -#typedef ^ InitOutputType LOGICAL RotFrame_y {:} - - \"Flag that tells FAST/MBC3 if the outputs used in linearization are in the rotating frame\" - -#typedef ^ InitOutputType LOGICAL RotFrame_x {:} - - \"Flag that tells FAST/MBC3 if the continuous states used in linearization are in the rotating frame\" - -#typedef ^ InitOutputType LOGICAL RotFrame_xd {:} - - \"Flag that tells FAST if the discrete states used in linearization are in the rotating frame\" - -#typedef ^ InitOutputType LOGICAL RotFrame_z {:} - - \"Flag that tells FAST if the constraint states used in linearization are in the rotating frame\" - -#typedef ^ InitOutputType LOGICAL RotFrame_u {:} - - \"Flag that tells FAST/MBC3 if the inputs used in linearization are in the rotating frame\" - -#typedef ^ InitOutputType LOGICAL IsLoad_u {:} - - \"Flag that tells FAST if the inputs used in linearization are loads (for preconditioning matrices)\" - -#typedef ^ InitOutputType IntKi DerivOrder_x {:} - - \"Integer that tells FAST/MBC3 the order derivative for the continuous states used in linearization\" - - - -# ..... States .................................................................................................................... -# Define continuous (differentiable) states here: -typedef ^ ContinuousStateType ReKi DummyContState - - - \"Remove this variable if you have continuous states\" - - -# Define discrete (nondifferentiable) states here: -typedef ^ DiscreteStateType ReKi DummyDiscState - - - \"Remove this variable if you have discrete states\" - - -# Define constraint states here: -typedef ^ ConstraintStateType ReKi DummyConstrState - - - \"Remove this variable if you have constraint states\" - - -# Define any other states, including integer or logical states here: -typedef ^ OtherStateType IntKi 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/optimization 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 DbKi DT - - - \"Time step for cont. state integration & disc. state update\" seconds - - -# ..... Inputs .................................................................................................................... -# Define inputs that are contained on the mesh here: -#typedef ^ InputType MeshType MeshedInput - - - \"Meshed data\" - -# Define inputs that are not on this mesh here: -typedef ^ InputType ReKi DummyInput - - - \"Remove this variable if you have input data\" - - - -# ..... Outputs ................................................................................................................... -# Define outputs that are contained on the mesh here: -#typedef ^ OutputType MeshType MeshedOutput - - - \"Meshed data\" - -# Define outputs that are not on this mesh here: -typedef ^ OutputType ReKi WriteOutput {:} - - \"Example of data to be written to an output file\" \"s,-\" -)""""; - -const std::string module_template = R""""( -!********************************************************************************************************************************** -!> ## ModuleName -!! The ModuleName and ModuleName_Types modules make up a template for creating user-defined calculations in the FAST Modularization -!! Framework. ModuleName_Types will be auto-generated by the FAST registry program, based on the variables specified in the -!! ModuleName_Registry.txt file. -!! -! .................................................................................................................................. -!! ## LICENSING -!! Copyright (C) 2012-2013, 2015-2016 National Renewable Energy Laboratory -!! -!! This file is part of ModuleName. -!! -!! 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 ModuleName - - USE ModuleName_Types - USE NWTC_Library - - IMPLICIT NONE - - PRIVATE - - TYPE(ProgDesc), PARAMETER :: ModName_Ver = ProgDesc( 'ModuleName', '', '' ) !< module date/version information - - - ! ..... Public Subroutines ................................................................................................... - - PUBLIC :: ModName_Init ! Initialization routine - PUBLIC :: ModName_End ! Ending routine (includes clean up) - - PUBLIC :: ModName_UpdateStates ! Loose coupling routine for solving for constraint states, integrating - ! continuous states, and updating discrete states - PUBLIC :: ModName_CalcOutput ! Routine for computing outputs - - PUBLIC :: ModName_CalcConstrStateResidual ! Tight coupling routine for returning the constraint state residual - PUBLIC :: ModName_CalcContStateDeriv ! Tight coupling routine for computing derivatives of continuous states - PUBLIC :: ModName_UpdateDiscState ! Tight coupling routine for updating discrete states - - PUBLIC :: ModName_JacobianPInput ! Routine to compute the Jacobians of the output(Y), continuous - (X), discrete - - ! (Xd), and constraint - state(Z) functions all with respect to the inputs(u) - PUBLIC :: ModName_JacobianPContState ! Routine to compute the Jacobians of the output(Y), continuous - (X), discrete - - ! (Xd), and constraint - state(Z) functions all with respect to the continuous - ! states(x) - PUBLIC :: ModName_JacobianPDiscState ! Routine to compute the Jacobians of the output(Y), continuous - (X), discrete - - ! (Xd), and constraint - state(Z) functions all with respect to the discrete - ! states(xd) - PUBLIC :: ModName_JacobianPConstrState ! Routine to compute the Jacobians of the output(Y), continuous - (X), discrete - - ! (Xd), and constraint - state(Z) functions all with respect to the constraint - ! states(z) - PUBLIC :: ModName_GetOP ! Routine to get the operating-point values for linearization (from data structures to arrays) - -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 ModName_Init( InitInp, u, p, x, xd, z, OtherState, y, misc, Interval, InitOut, ErrStat, ErrMsg ) -!.................................................................................................................................. - - TYPE(ModName_InitInputType), INTENT(IN ) :: InitInp !< Input data for initialization routine - TYPE(ModName_InputType), INTENT( OUT) :: u !< An initial guess for the input; input mesh must be defined - TYPE(ModName_ParameterType), INTENT( OUT) :: p !< Parameters - TYPE(ModName_ContinuousStateType), INTENT( OUT) :: x !< Initial continuous states - TYPE(ModName_DiscreteStateType), INTENT( OUT) :: xd !< Initial discrete states - TYPE(ModName_ConstraintStateType), INTENT( OUT) :: z !< Initial guess of the constraint states - TYPE(ModName_OtherStateType), INTENT( OUT) :: OtherState !< Initial other states (logical, etc) - TYPE(ModName_OutputType), INTENT( OUT) :: y !< Initial system outputs (outputs are not calculated; - !! only the output mesh is initialized) - TYPE(ModName_MiscVarType), INTENT( OUT) :: misc !< Misc variables for optimization (not copied in glue code) - REAL(DbKi), INTENT(INOUT) :: Interval !< Coupling interval in seconds: the rate that - !! (1) ModName_UpdateStates() is called in loose coupling & - !! (2) ModName_UpdateDiscState() is called in tight coupling. - !! Input is the suggested time from the glue code; - !! Output is the actual coupling interval that will be used - !! by the glue code. - TYPE(ModName_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) :: NumOuts ! number of outputs; would probably be in the parameter type - INTEGER(IntKi) :: ErrStat2 ! local error status - CHARACTER(ErrMsgLen) :: ErrMsg2 ! local error message - CHARACTER(*), PARAMETER :: RoutineName = 'ModName_Init' - - !! Initialize variables - - ErrStat = ErrID_None - ErrMsg = '' - NumOuts = 2 - - - ! Initialize the NWTC Subroutine Library - - call NWTC_Init( ) - - ! Display the module information - - call DispNVD( ModName_Ver ) - - - ! Define parameters here: - - p%DT = Interval - - - ! Define initial system states here: - - x%DummyContState = 0.0_ReKi - xd%DummyDiscState = 0.0_ReKi - z%DummyConstrState = 0.0_ReKi - OtherState%DummyOtherState = 0.0_ReKi - - ! define optimization variables here: - misc%DummyMiscVar = 0.0_ReKi - - ! Define initial guess for the system inputs here: - - u%DummyInput = 0.0_ReKi - - - ! Define system output initializations (set up mesh) here: - call AllocAry( y%WriteOutput, NumOuts, 'WriteOutput', ErrStat2, ErrMsg2 ) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) ! set return error status based on local (concatenate errors) - if (ErrStat >= AbortErrLev) return ! if there are local variables that need to be deallocated, do so before early return - - y%DummyOutput = 0 - y%WriteOutput = 0 - - - ! Define initialization-routine output here: - call AllocAry(InitOut%WriteOutputHdr,NumOuts,'WriteOutputHdr',ErrStat2,ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - call AllocAry(InitOut%WriteOutputUnt,NumOuts,'WriteOutputUnt',ErrStat2,ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - if (ErrStat >= AbortErrLev) return ! if there are local variables that need to be deallocated, do so before early return - - InitOut%WriteOutputHdr = (/ 'Time ', 'Column2' /) - InitOut%WriteOutputUnt = (/ '(s)', '(-)' /) - - - ! If you want to choose your own rate instead of using what the glue code suggests, tell the glue code the rate at which - ! this module must be called here: - - !Interval = p%DT - - - if (InitInp%Linearize) then - - ! If this module does not implement the four Jacobian routines at the end of this template, or the module cannot - ! linearize with the features that are enabled, stop the simulation if InitInp%Linearize is true. - - CALL SetErrStat( ErrID_Fatal, 'ModuleName cannot perform linearization analysis.', ErrStat, ErrMsg, RoutineName) - - ! Otherwise, if the module does allow linearization, return the appropriate Jacobian row/column names and rotating-frame flags here: - ! Allocate and set these variables: InitOut%LinNames_y, InitOut%LinNames_x, InitOut%LinNames_xd, InitOut%LinNames_z, InitOut%LinNames_u - ! Allocate and set these variables: InitOut%RotFrame_y, InitOut%RotFrame_x, InitOut%RotFrame_xd, InitOut%RotFrame_z, InitOut%RotFrame_u - ! Allocate and set these variables: InitOut%IsLoad_u, InitOut%DerivOrder_x - - end if - - -END SUBROUTINE ModName_Init -!---------------------------------------------------------------------------------------------------------------------------------- -!> This routine is called at the end of the simulation. -SUBROUTINE ModName_End( u, p, x, xd, z, OtherState, y, misc, ErrStat, ErrMsg ) -!.................................................................................................................................. - - TYPE(ModName_InputType), INTENT(INOUT) :: u !< System inputs - TYPE(ModName_ParameterType), INTENT(INOUT) :: p !< Parameters - TYPE(ModName_ContinuousStateType), INTENT(INOUT) :: x !< Continuous states - TYPE(ModName_DiscreteStateType), INTENT(INOUT) :: xd !< Discrete states - TYPE(ModName_ConstraintStateType), INTENT(INOUT) :: z !< Constraint states - TYPE(ModName_OtherStateType), INTENT(INOUT) :: OtherState !< Other states - TYPE(ModName_OutputType), INTENT(INOUT) :: y !< System outputs - TYPE(ModName_MiscVarType), INTENT(INOUT) :: misc !< 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) :: ErrStat2 ! local error status - CHARACTER(ErrMsgLen) :: ErrMsg2 ! local error message - CHARACTER(*), PARAMETER :: RoutineName = 'ModName_End' - - ! Initialize ErrStat - - ErrStat = ErrID_None - ErrMsg = '' - - - !! Place any last minute operations or calculations here: - - - !! Close files here (but because of checkpoint-restart capability, it is not recommended to have files open during the simulation): - - - !! Destroy the input data: - - call ModName_DestroyInput( u, ErrStat2, ErrMsg2 ) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - - - !! Destroy the parameter data: - - call ModName_DestroyParam( p, ErrStat2, ErrMsg2 ) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - - !! Destroy the state data: - - call ModName_DestroyContState( x, ErrStat2,ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - call ModName_DestroyDiscState( xd, ErrStat2,ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - call ModName_DestroyConstrState( z, ErrStat2,ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - call ModName_DestroyOtherState( OtherState, ErrStat2,ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - - - !! Destroy the output data: - - call ModName_DestroyOutput( y, ErrStat2, ErrMsg2 ); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - - - !! Destroy the misc data: - - call ModName_DestroyMisc( misc, ErrStat2, ErrMsg2 ); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - - -END SUBROUTINE ModName_End -!---------------------------------------------------------------------------------------------------------------------------------- -!> This is a loose coupling routine for solving constraint states, integrating continuous states, and updating discrete and other -!! states. Continuous, constraint, discrete, and other states are updated to values at t + Interval. -SUBROUTINE ModName_UpdateStates( t, n, Inputs, InputTimes, p, x, xd, z, OtherState, misc, ErrStat, ErrMsg ) -!.................................................................................................................................. - - REAL(DbKi), INTENT(IN ) :: t !< Current simulation time in seconds - INTEGER(IntKi), INTENT(IN ) :: n !< Current step of the simulation: t = n*Interval - TYPE(ModName_InputType), INTENT(INOUT) :: Inputs(:) !< Inputs at InputTimes (output from this routine only - !! because of record keeping in routines that copy meshes) - REAL(DbKi), INTENT(IN ) :: InputTimes(:) !< Times in seconds associated with Inputs - TYPE(ModName_ParameterType), INTENT(IN ) :: p !< Parameters - TYPE(ModName_ContinuousStateType), INTENT(INOUT) :: x !< Input: Continuous states at t; - !! Output: Continuous states at t + Interval - TYPE(ModName_DiscreteStateType), INTENT(INOUT) :: xd !< Input: Discrete states at t; - !! Output: Discrete states at t + Interval - TYPE(ModName_ConstraintStateType), INTENT(INOUT) :: z !< Input: Constraint states at t; - !! Output: Constraint states at t + Interval - TYPE(ModName_OtherStateType), INTENT(INOUT) :: OtherState !< Other states: Other states at t; - !! Output: Other states at t + Interval - TYPE(ModName_MiscVarType), INTENT(INOUT) :: misc !< 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 - - TYPE(ModName_ContinuousStateType) :: dxdt ! Continuous state derivatives at t - TYPE(ModName_DiscreteStateType) :: xd_t ! Discrete states at t (copy) - TYPE(ModName_ConstraintStateType) :: z_Residual ! Residual of the constraint state functions (Z) - TYPE(ModName_InputType) :: u ! Instantaneous inputs - - INTEGER(IntKi) :: ErrStat2 ! local error status - CHARACTER(ErrMsgLen) :: ErrMsg2 ! local error message - CHARACTER(*), PARAMETER :: RoutineName = 'ModName_UpdateStates' - - - ! Initialize variables - - ErrStat = ErrID_None ! no error has occurred - ErrMsg = '' - - - ! This subroutine contains an example of how the states could be updated. Developers will - ! want to adjust the logic as necessary for their own situations. - - - - ! Get the inputs at time t, based on the array of values sent by the glue code: - - ! before calling ExtrapInterp routine, memory in u must be allocated; we can do that with a copy: - call ModName_CopyInput( Inputs(1), u, MESH_NEWCOPY, ErrStat2, ErrMsg2 ) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - if ( ErrStat >= AbortErrLev ) then - call cleanup() ! to avoid memory leaks, we have to destroy the local variables that may have allocatable arrays or meshes - return - end if - - call ModName_Input_ExtrapInterp( Inputs, InputTimes, u, t, ErrStat2, ErrMsg2 ) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - if ( ErrStat >= AbortErrLev ) then - call cleanup() - return - end if - - - - ! Get first time derivatives of continuous states (dxdt): - - call ModName_CalcContStateDeriv( t, u, p, x, xd, z, OtherState, misc, dxdt, ErrStat2, ErrMsg2 ) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - if ( ErrStat >= AbortErrLev ) then - call cleanup() - return - end if - - - ! Update discrete states: - ! Note that xd [discrete state] is changed in ModName_UpdateDiscState() so xd will now contain values at t+Interval - ! We'll first make a copy that contains xd at time t, which will be used in computing the constraint states - call ModName_CopyDiscState( xd, xd_t, MESH_NEWCOPY, ErrStat2, ErrMsg2 ) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - if ( ErrStat >= AbortErrLev ) then - call cleanup() - return - end if - - call ModName_UpdateDiscState( t, n, u, p, x, xd, z, OtherState, misc, ErrStat2, ErrMsg2 ) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - if ( ErrStat >= AbortErrLev ) then - call cleanup() - return - end if - - - ! Solve for the constraint states (z) here: - - ! Iterate until the value is within a given tolerance. - - ! DO - - call ModName_CalcConstrStateResidual( t, u, p, x, xd_t, z, OtherState, misc, Z_Residual, ErrStat2, ErrMsg2 ) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - if ( ErrStat >= AbortErrLev ) then - call cleanup() - return - end if - - ! z = - - ! END DO - - - - ! Integrate (update) continuous states (x) here: - - !x = function of dxdt and x - - - ! Destroy local variables before returning - call cleanup() - - -CONTAINS - SUBROUTINE cleanup() - ! note that this routine inherits all of the data in ModName_UpdateStates - - - CALL ModName_DestroyInput( u, ErrStat2, ErrMsg2) - CALL ModName_DestroyConstrState( Z_Residual, ErrStat2, ErrMsg2) - CALL ModName_DestroyContState( dxdt, ErrStat2, ErrMsg2) - CALL ModName_DestroyDiscState( xd_t, ErrStat2, ErrMsg2) - - END SUBROUTINE cleanup -END SUBROUTINE ModName_UpdateStates -!---------------------------------------------------------------------------------------------------------------------------------- -!> This is a routine for computing outputs, used in both loose and tight coupling. -SUBROUTINE ModName_CalcOutput( t, u, p, x, xd, z, OtherState, y, misc, ErrStat, ErrMsg ) -!.................................................................................................................................. - - REAL(DbKi), INTENT(IN ) :: t !< Current simulation time in seconds - TYPE(ModName_InputType), INTENT(IN ) :: u !< Inputs at t - TYPE(ModName_ParameterType), INTENT(IN ) :: p !< Parameters - TYPE(ModName_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at t - TYPE(ModName_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at t - TYPE(ModName_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at t - TYPE(ModName_OtherStateType), INTENT(IN ) :: OtherState !< Other states at t - TYPE(ModName_MiscVarType), INTENT(INOUT) :: misc !< Misc variables for optimization (not copied in glue code) - TYPE(ModName_OutputType), INTENT(INOUT) :: y !< Outputs computed at t (Input only so that mesh con- - !! 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 - - - ! Initialize ErrStat - - ErrStat = ErrID_None - ErrMsg = '' - - - ! Compute outputs here: - y%DummyOutput = 2.0_ReKi - - y%WriteOutput(1) = REAL(t,ReKi) - y%WriteOutput(2) = 1.0_ReKi - - -END SUBROUTINE ModName_CalcOutput -!---------------------------------------------------------------------------------------------------------------------------------- -!> This is a tight coupling routine for computing derivatives of continuous states. -SUBROUTINE ModName_CalcContStateDeriv( t, u, p, x, xd, z, OtherState, misc, dxdt, ErrStat, ErrMsg ) -!.................................................................................................................................. - - REAL(DbKi), INTENT(IN ) :: t !< Current simulation time in seconds - TYPE(ModName_InputType), INTENT(IN ) :: u !< Inputs at t - TYPE(ModName_ParameterType), INTENT(IN ) :: p !< Parameters - TYPE(ModName_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at t - TYPE(ModName_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at t - TYPE(ModName_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at t - TYPE(ModName_OtherStateType), INTENT(IN ) :: OtherState !< Other states at t - TYPE(ModName_MiscVarType), INTENT(INOUT) :: misc !< Misc variables for optimization (not copied in glue code) - TYPE(ModName_ContinuousStateType), INTENT( OUT) :: dxdt !< Continuous state derivatives at t - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - - - ! Initialize ErrStat - - ErrStat = ErrID_None - ErrMsg = '' - - - ! Compute the first time derivatives of the continuous states here: - - dxdt%DummyContState = 0.0_ReKi - - -END SUBROUTINE ModName_CalcContStateDeriv -!---------------------------------------------------------------------------------------------------------------------------------- -!> This is a tight coupling routine for updating discrete states. -SUBROUTINE ModName_UpdateDiscState( t, n, u, p, x, xd, z, OtherState, misc, ErrStat, ErrMsg ) -!.................................................................................................................................. - - REAL(DbKi), INTENT(IN ) :: t !< Current simulation time in seconds - INTEGER(IntKi), INTENT(IN ) :: n !< Current step of the simulation: t = n*Interval - TYPE(ModName_InputType), INTENT(IN ) :: u !< Inputs at t - TYPE(ModName_ParameterType), INTENT(IN ) :: p !< Parameters - TYPE(ModName_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at t - TYPE(ModName_DiscreteStateType), INTENT(INOUT) :: xd !< Input: Discrete states at t; - !! Output: Discrete states at t + Interval - TYPE(ModName_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at t - TYPE(ModName_OtherStateType), INTENT(IN ) :: OtherState !< Other states at t - TYPE(ModName_MiscVarType), INTENT(INOUT) :: misc !< 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 - - - ! Initialize ErrStat - - ErrStat = ErrID_None - ErrMsg = '' - - - ! Update discrete states here: - - xd%DummyDiscState = 0.0_Reki - -END SUBROUTINE ModName_UpdateDiscState -!---------------------------------------------------------------------------------------------------------------------------------- -!> This is a tight coupling routine for solving for the residual of the constraint state functions. -SUBROUTINE ModName_CalcConstrStateResidual( t, u, p, x, xd, z, OtherState, misc, Z_residual, ErrStat, ErrMsg ) -!.................................................................................................................................. - - REAL(DbKi), INTENT(IN ) :: t !< Current simulation time in seconds - TYPE(ModName_InputType), INTENT(IN ) :: u !< Inputs at t - TYPE(ModName_ParameterType), INTENT(IN ) :: p !< Parameters - TYPE(ModName_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at t - TYPE(ModName_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at t - TYPE(ModName_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at t (possibly a guess) - TYPE(ModName_OtherStateType), INTENT(IN ) :: OtherState !< Other states at t - TYPE(ModName_MiscVarType), INTENT(INOUT) :: misc !< Misc variables for optimization (not copied in glue code) - TYPE(ModName_ConstraintStateType), INTENT( OUT) :: Z_residual !< Residual of the constraint state functions using - !! the input values described above - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - - - ! Initialize ErrStat - - ErrStat = ErrID_None - ErrMsg = '' - - - ! Solve for the residual of the constraint state functions here: - - Z_residual%DummyConstrState = 0.0_ReKi - -END SUBROUTINE ModName_CalcConstrStateResidual - - -!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -! ###### The following four routines are Jacobian routines for linearization capabilities ####### -! If the module does not implement them, set ErrStat = ErrID_Fatal in ModName_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 ModName_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(ModName_InputType), INTENT(IN ) :: u !< Inputs at operating point (may change to inout if a mesh copy is required) - TYPE(ModName_ParameterType), INTENT(IN ) :: p !< Parameters - TYPE(ModName_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at operating point - TYPE(ModName_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at operating point - TYPE(ModName_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at operating point - TYPE(ModName_OtherStateType), INTENT(IN ) :: OtherState !< Other states at operating point - TYPE(ModName_OutputType), INTENT(IN ) :: 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(ModName_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) with respect - !! to the inputs (u) [intent in to avoid deallocation] - REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dXdu(:,:) !< Partial derivatives of continuous state functions (X) with - !! respect to the inputs (u) [intent in to avoid deallocation] - REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dXddu(:,:) !< Partial derivatives of discrete state functions (Xd) with - !! respect to the inputs (u) [intent in to avoid deallocation] - REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dZdu(:,:) !< Partial derivatives of constraint state functions (Z) with - !! respect to the inputs (u) [intent in to avoid deallocation] - - - ! Initialize ErrStat - - ErrStat = ErrID_None - ErrMsg = '' - - - IF ( PRESENT( dYdu ) ) THEN - - ! Calculate the partial derivative of the output functions (Y) with respect to the inputs (u) here: - - ! allocate and set dYdu - - END IF - - IF ( PRESENT( dXdu ) ) THEN - - ! Calculate the partial derivative of the continuous state functions (X) with respect to the inputs (u) here: - - ! allocate and set dXdu - - END IF - - IF ( PRESENT( dXddu ) ) THEN - - ! Calculate the partial derivative of the discrete state functions (Xd) with respect to the inputs (u) here: - - ! allocate and set dXddu - - END IF - - IF ( PRESENT( dZdu ) ) THEN - - ! Calculate the partial derivative of the constraint state functions (Z) with respect to the inputs (u) here: - - ! allocate and set dZdu - - END IF - - -END SUBROUTINE ModName_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 ModName_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(ModName_InputType), INTENT(IN ) :: u !< Inputs at operating point (may change to inout if a mesh copy is required) - TYPE(ModName_ParameterType), INTENT(IN ) :: p !< Parameters - TYPE(ModName_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at operating point - TYPE(ModName_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at operating point - TYPE(ModName_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at operating point - TYPE(ModName_OtherStateType), INTENT(IN ) :: OtherState !< Other states at operating point - TYPE(ModName_OutputType), INTENT(IN ) :: 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(ModName_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 - !! (Y) with respect to the continuous - !! states (x) [intent in to avoid deallocation] - REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dXdx(:,:) !< Partial derivatives of continuous state - !! functions (X) with respect to - !! the continuous states (x) [intent in to avoid deallocation] - REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dXddx(:,:) !< Partial derivatives of discrete state - !! functions (Xd) with respect to - !! the continuous states (x) [intent in to avoid deallocation] - REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dZdx(:,:) !< Partial derivatives of constraint state - !! functions (Z) with respect to - !! the continuous states (x) [intent in to avoid deallocation] - - - ! Initialize ErrStat - - ErrStat = ErrID_None - ErrMsg = '' - - - - IF ( PRESENT( dYdx ) ) THEN - - ! Calculate the partial derivative of the output functions (Y) with respect to the continuous states (x) here: - - ! allocate and set dYdx - - END IF - - IF ( PRESENT( dXdx ) ) THEN - - ! Calculate the partial derivative of the continuous state functions (X) with respect to the continuous states (x) here: - - ! allocate and set dXdx - - END IF - - IF ( PRESENT( dXddx ) ) THEN - - ! Calculate the partial derivative of the discrete state functions (Xd) with respect to the continuous states (x) here: - - ! allocate and set dXddx - - END IF - - IF ( PRESENT( dZdx ) ) THEN - - - ! Calculate the partial derivative of the constraint state functions (Z) with respect to the continuous states (x) here: - - ! allocate and set dZdx - - END IF - - -END SUBROUTINE ModName_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 ModName_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(ModName_InputType), INTENT(IN ) :: u !< Inputs at operating point (may change to inout if a mesh copy is required) - TYPE(ModName_ParameterType), INTENT(IN ) :: p !< Parameters - TYPE(ModName_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at operating point - TYPE(ModName_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at operating point - TYPE(ModName_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at operating point - TYPE(ModName_OtherStateType), INTENT(IN ) :: OtherState !< Other states at operating point - TYPE(ModName_OutputType), INTENT(IN ) :: 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 dYdxd. - TYPE(ModName_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) with respect to the discrete - !! states (xd) [intent in to avoid deallocation] - REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dXdxd(:,:) !< Partial derivatives of continuous state - !! functions (X) with respect to the - !! discrete states (xd) [intent in to avoid deallocation] - REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dXddxd(:,:)!< Partial derivatives of discrete state - !! functions (Xd) with respect to the - !! discrete states (xd) [intent in to avoid deallocation] - REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dZdxd(:,:) !< Partial derivatives of constraint state - !! functions (Z) with respect to the - !! discrete states (xd) [intent in to avoid deallocation] - - - ! Initialize ErrStat - - ErrStat = ErrID_None - ErrMsg = '' - - - IF ( PRESENT( dYdxd ) ) THEN - - ! Calculate the partial derivative of the output functions (Y) with respect to the discrete states (xd) here: - - ! allocate and set dYdxd - - END IF - - IF ( PRESENT( dXdxd ) ) THEN - - ! Calculate the partial derivative of the continuous state functions (X) with respect to the discrete states (xd) here: - - ! allocate and set dXdxd - - END IF - - IF ( PRESENT( dXddxd ) ) THEN - - ! Calculate the partial derivative of the discrete state functions (Xd) with respect to the discrete states (xd) here: - - ! allocate and set dXddxd - - END IF - - IF ( PRESENT( dZdxd ) ) THEN - - ! Calculate the partial derivative of the constraint state functions (Z) with respect to the discrete states (xd) here: - - ! allocate and set dZdxd - - END IF - - -END SUBROUTINE ModName_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 ModName_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(ModName_InputType), INTENT(IN ) :: u !< Inputs at operating point (may change to inout if a mesh copy is required) - TYPE(ModName_ParameterType), INTENT(IN ) :: p !< Parameters - TYPE(ModName_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at operating point - TYPE(ModName_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at operating point - TYPE(ModName_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at operating point - TYPE(ModName_OtherStateType), INTENT(IN ) :: OtherState !< Other states at operating point - TYPE(ModName_OutputType), INTENT(IN ) :: 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 dYdz. - TYPE(ModName_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] - - - ! Initialize ErrStat - - ErrStat = ErrID_None - ErrMsg = '' - - IF ( PRESENT( dYdz ) ) THEN - - ! Calculate the partial derivative of the output functions (Y) with respect to the constraint states (z) here: - - ! allocate and set dYdz - - END IF - - IF ( PRESENT( dXdz ) ) THEN - - ! Calculate the partial derivative of the continuous state functions (X) with respect to the constraint states (z) here: - - ! allocate and set dXdz - - END IF - - IF ( PRESENT( dXddz ) ) THEN - - ! Calculate the partial derivative of the discrete state functions (Xd) with respect to the constraint states (z) here: - - ! allocate and set dXddz - - END IF - - IF ( PRESENT( dZdz ) ) THEN - - ! Calculate the partial derivative of the constraint state functions (Z) with respect to the constraint states (z) here: - - ! allocate and set dZdz - - END IF - - -END SUBROUTINE ModName_JacobianPConstrState -!---------------------------------------------------------------------------------------------------------------------------------- -!> Routine to pack the data structures representing the operating points into arrays for linearization. -SUBROUTINE ModName_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(ModName_InputType), INTENT(IN ) :: u !< Inputs at operating point (may change to inout if a mesh copy is required) - TYPE(ModName_ParameterType), INTENT(IN ) :: p !< Parameters - TYPE(ModName_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at operating point - TYPE(ModName_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at operating point - TYPE(ModName_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at operating point - TYPE(ModName_OtherStateType), INTENT(IN ) :: OtherState !< Other states at operating point - TYPE(ModName_OutputType), INTENT(IN ) :: y !< Output at operating point - TYPE(ModName_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 - - - ! Initialize ErrStat - - ErrStat = ErrID_None - ErrMsg = '' - - IF ( PRESENT( u_op ) ) THEN - - END IF - - IF ( PRESENT( y_op ) ) THEN - END IF - - IF ( PRESENT( x_op ) ) THEN - - END IF - - IF ( PRESENT( dx_op ) ) THEN - - END IF - - IF ( PRESENT( xd_op ) ) THEN - - END IF - - IF ( PRESENT( z_op ) ) THEN - - END IF - -END SUBROUTINE ModName_GetOP -!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -END MODULE ModuleName -!********************************************************************************************************************************** -)""""; +const std::string FAST_preamble( + "!STARTOFREGISTRYGENERATEDFILE 'ModuleName_Types.f90'\n" + "!\n" + "! WARNING This file is generated automatically by the FAST registry.\n" + "! Do not edit. Your changes to this file will be lost.\n" + "!\n" + "! FAST Registry\n" + "!*********************************************************************************************************************************\n" + "! ModuleName_Types\n" + "!.................................................................................................................................\n" + "! This file is part of ModuleName.\n" + "!\n" + "! Copyright (C) 2012-2016 National Renewable Energy Laboratory\n" + "!\n" + "! Licensed under the Apache License, Version 2.0 (the \"License\");\n" + "! you may not use this file except in compliance with the License.\n" + "! You may obtain a copy of the License at\n" + "!\n" + "! http://www.apache.org/licenses/LICENSE-2.0\n" + "!\n" + "! Unless required by applicable law or agreed to in writing, software\n" + "! distributed under the License is distributed on an \"AS IS\" BASIS,\n" + "! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" + "! See the License for the specific language governing permissions and\n" + "! limitations under the License.\n" + "!\n" + "!\n" + "! W A R N I N G : This file was automatically generated from the FAST registry. Changes made to this file may be lost.\n" + "!\n" + "!*********************************************************************************************************************************\n" + "!> This module contains the user-defined types needed in ModuleName. It also contains copy, destroy, pack, and\n" + "!! unpack routines associated with each defined data type. This code is automatically generated by the FAST Registry.\n" + "MODULE ModuleName_Types\n" + "!---------------------------------------------------------------------------------------------------------------------------------\n"); + +const std::string registry_template( + "###################################################################################################################################\n" + "# Registry for ModuleName in the FAST Modularization Framework\n" + "# This Registry file is used to create MODULE ModuleName_Types, which contains all of the user-defined types needed in ModuleName.\n" + "# It also contains copy, destroy, pack, and unpack routines associated with each defined data types.\n" + "#\n" + "# Entries are of the form\n" + "# keyword \n" + "#\n" + "# Use ^ as a shortcut for the value from the previous line.\n" + "# See NWTC Programmer's Handbook at https://nwtc.nrel.gov/FAST-Developers for further information on the format/contents of this file.\n" + "###################################################################################################################################\n" + "\n" + "# ...... Include files (definitions from NWTC Library) ............................................................................\n" + "include Registry_NWTC_Library.txt\n" + "\n" + "\n" + "# ..... Initialization data .......................................................................................................\n" + "# Define inputs that the initialization routine may need here:\n" + "# e.g., the name of the input file, the file root name, etc.\n" + "typedef ModuleName/ModName InitInputType CHARACTER(1024) InputFile - - - \"Name of the input file; remove if there is no file\" -\n" + "typedef ^ ^ LOGICAL Linearize - .FALSE. - \"Flag that tells this module if the glue code wants to linearize.\" -\n" + "\n" + "# Define outputs from the initialization routine here:\n" + "typedef ^ InitOutputType CHARACTER(ChanLen) WriteOutputHdr {:} - - \"Names of the output-to-file channels\" -\n" + "typedef ^ InitOutputType CHARACTER(ChanLen) WriteOutputUnt {:} - - \"Units of the output-to-file channels\" -\n" + "# if this module has implemented linearization, return the names of the rows/columns of the Jacobian matrices:\n" + "#typedef ^ InitOutputType CHARACTER(LinChanLen) LinNames_y {:} - - \"Names of the outputs used in linearization\" - \n" + "#typedef ^ InitOutputType CHARACTER(LinChanLen) LinNames_x {:} - - \"Names of the continuous states used in linearization\" -\n" + "#typedef ^ InitOutputType CHARACTER(LinChanLen) LinNames_xd {:} - - \"Names of the discrete states used in linearization\" -\n" + "#typedef ^ InitOutputType CHARACTER(LinChanLen) LinNames_z {:} - - \"Names of the constraint states used in linearization\" -\n" + "#typedef ^ InitOutputType CHARACTER(LinChanLen) LinNames_u {:} - - \"Names of the inputs used in linearization\" -\n" + "#typedef ^ InitOutputType LOGICAL RotFrame_y {:} - - \"Flag that tells FAST/MBC3 if the outputs used in linearization are in the rotating frame\" -\n" + "#typedef ^ InitOutputType LOGICAL RotFrame_x {:} - - \"Flag that tells FAST/MBC3 if the continuous states used in linearization are in the rotating frame\" -\n" + "#typedef ^ InitOutputType LOGICAL RotFrame_xd {:} - - \"Flag that tells FAST if the discrete states used in linearization are in the rotating frame\" -\n" + "#typedef ^ InitOutputType LOGICAL RotFrame_z {:} - - \"Flag that tells FAST if the constraint states used in linearization are in the rotating frame\" -\n" + "#typedef ^ InitOutputType LOGICAL RotFrame_u {:} - - \"Flag that tells FAST/MBC3 if the inputs used in linearization are in the rotating frame\" -\n" + "#typedef ^ InitOutputType LOGICAL IsLoad_u {:} - - \"Flag that tells FAST if the inputs used in linearization are loads (for preconditioning matrices)\" -\n" + "#typedef ^ InitOutputType IntKi DerivOrder_x {:} - - \"Integer that tells FAST/MBC3 the order derivative for the continuous states used in linearization\" -\n" + "\n" + "\n" + "# ..... States ....................................................................................................................\n" + "# Define continuous (differentiable) states here:\n" + "typedef ^ ContinuousStateType ReKi DummyContState - - - \"Remove this variable if you have continuous states\" -\n" + "\n" + "# Define discrete (nondifferentiable) states here:\n" + "typedef ^ DiscreteStateType ReKi DummyDiscState - - - \"Remove this variable if you have discrete states\" -\n" + "\n" + "# Define constraint states here:\n" + "typedef ^ ConstraintStateType ReKi DummyConstrState - - - \"Remove this variable if you have constraint states\" -\n" + "\n" + "# Define any other states, including integer or logical states here:\n" + "typedef ^ OtherStateType IntKi DummyOtherState - - - \"Remove this variable if you have other states\" -\n" + "\n" + "\n" + "# ..... Misc/Optimization variables.................................................................................................\n" + "# Define any data that are used only for efficiency purposes (these variables are not associated with time):\n" + "# e.g. indices for searching in an array, large arrays that are local variables in any routine called multiple times, etc.\n" + "typedef ^ MiscVarType ReKi DummyMiscVar - - - \"Remove this variable if you have misc/optimization variables\" -\n" + "\n" + "\n" + "# ..... Parameters ................................................................................................................\n" + "# Define parameters here:\n" + "# Time step for integration of continuous states (if a fixed-step integrator is used) and update of discrete states:\n" + "typedef ^ ParameterType DbKi DT - - - \"Time step for cont. state integration & disc. state update\" seconds\n" + "\n" + "\n" + "# ..... Inputs ....................................................................................................................\n" + "# Define inputs that are contained on the mesh here:\n" + "#typedef ^ InputType MeshType MeshedInput - - - \"Meshed data\" -\n" + "# Define inputs that are not on this mesh here:\n" + "typedef ^ InputType ReKi DummyInput - - - \"Remove this variable if you have input data\" -\n" + "\n" + "\n" + "# ..... Outputs ...................................................................................................................\n" + "# Define outputs that are contained on the mesh here:\n" + "#typedef ^ OutputType MeshType MeshedOutput - - - \"Meshed data\" -\n" + "# Define outputs that are not on this mesh here:\n" + "typedef ^ OutputType ReKi DummyOutput - - - \"Remove this variable if you have output data\" -\n" + "typedef ^ OutputType ReKi WriteOutput {:} - - \"Example of data to be written to an output file\" \"s,-\"\n"); + +const std::string module_template( + "!**********************************************************************************************************************************\n" + "!> ## ModuleName\n" + "!! The ModuleName and ModuleName_Types modules make up a template for creating user-defined calculations in the FAST Modularization\n" + "!! Framework. ModuleName_Types will be auto-generated by the FAST registry program, based on the variables specified in the\n" + "!! ModuleName_Registry.txt file.\n" + "!!\n" + "! ..................................................................................................................................\n" + "!! ## LICENSING\n" + "!! Copyright (C) 2012-2013, 2015-2016 National Renewable Energy Laboratory\n" + "!!\n" + "!! This file is part of ModuleName.\n" + "!!\n" + "!! Licensed under the Apache License, Version 2.0 (the \"License\");\n" + "!! you may not use this file except in compliance with the License.\n" + "!! You may obtain a copy of the License at\n" + "!!\n" + "!! http://www.apache.org/licenses/LICENSE-2.0\n" + "!!\n" + "!! Unless required by applicable law or agreed to in writing, software\n" + "!! distributed under the License is distributed on an \"AS IS\" BASIS,\n" + "!! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" + "!! See the License for the specific language governing permissions and\n" + "!! limitations under the License.\n" + "!**********************************************************************************************************************************\n" + "MODULE ModuleName\n" + "\n" + " USE ModuleName_Types\n" + " USE NWTC_Library\n" + "\n" + " IMPLICIT NONE\n" + "\n" + " PRIVATE\n" + "\n" + " TYPE(ProgDesc), PARAMETER :: ModName_Ver = ProgDesc( 'ModuleName', '', '' ) !< module date/version information\n" + "\n" + "\n" + " ! ..... Public Subroutines ...................................................................................................\n" + "\n" + " PUBLIC :: ModName_Init ! Initialization routine\n" + " PUBLIC :: ModName_End ! Ending routine (includes clean up)\n" + "\n" + " PUBLIC :: ModName_UpdateStates ! Loose coupling routine for solving for constraint states, integrating\n" + " ! continuous states, and updating discrete states\n" + " PUBLIC :: ModName_CalcOutput ! Routine for computing outputs\n" + "\n" + " PUBLIC :: ModName_CalcConstrStateResidual ! Tight coupling routine for returning the constraint state residual\n" + " PUBLIC :: ModName_CalcContStateDeriv ! Tight coupling routine for computing derivatives of continuous states\n" + " PUBLIC :: ModName_UpdateDiscState ! Tight coupling routine for updating discrete states\n" + "\n" + " PUBLIC :: ModName_JacobianPInput ! Routine to compute the Jacobians of the output(Y), continuous - (X), discrete -\n" + " ! (Xd), and constraint - state(Z) functions all with respect to the inputs(u)\n" + " PUBLIC :: ModName_JacobianPContState ! Routine to compute the Jacobians of the output(Y), continuous - (X), discrete -\n" + " ! (Xd), and constraint - state(Z) functions all with respect to the continuous\n" + " ! states(x)\n" + " PUBLIC :: ModName_JacobianPDiscState ! Routine to compute the Jacobians of the output(Y), continuous - (X), discrete -\n" + " ! (Xd), and constraint - state(Z) functions all with respect to the discrete\n" + " ! states(xd)\n" + " PUBLIC :: ModName_JacobianPConstrState ! Routine to compute the Jacobians of the output(Y), continuous - (X), discrete -\n" + " ! (Xd), and constraint - state(Z) functions all with respect to the constraint\n" + " ! states(z)\n" + " PUBLIC :: ModName_GetOP ! Routine to get the operating-point values for linearization (from data structures to arrays)\n" + "\n" + "CONTAINS\n" + "!----------------------------------------------------------------------------------------------------------------------------------\n" + "!> This routine is called at the start of the simulation to perform initialization steps.\n" + "!! The parameters are set here and not changed during the simulation.\n" + "!! The initial states and initial guess for the input are defined. \n" + "SUBROUTINE ModName_Init( InitInp, u, p, x, xd, z, OtherState, y, misc, Interval, InitOut, ErrStat, ErrMsg )\n" + "!..................................................................................................................................\n" + "\n" + " TYPE(ModName_InitInputType), INTENT(IN ) :: InitInp !< Input data for initialization routine\n" + " TYPE(ModName_InputType), INTENT( OUT) :: u !< An initial guess for the input; input mesh must be defined\n" + " TYPE(ModName_ParameterType), INTENT( OUT) :: p !< Parameters\n" + " TYPE(ModName_ContinuousStateType), INTENT( OUT) :: x !< Initial continuous states\n" + " TYPE(ModName_DiscreteStateType), INTENT( OUT) :: xd !< Initial discrete states\n" + " TYPE(ModName_ConstraintStateType), INTENT( OUT) :: z !< Initial guess of the constraint states\n" + " TYPE(ModName_OtherStateType), INTENT( OUT) :: OtherState !< Initial other states (logical, etc)\n" + " TYPE(ModName_OutputType), INTENT( OUT) :: y !< Initial system outputs (outputs are not calculated;\n" + " !! only the output mesh is initialized)\n" + " TYPE(ModName_MiscVarType), INTENT( OUT) :: misc !< Misc variables for optimization (not copied in glue code)\n" + " REAL(DbKi), INTENT(INOUT) :: Interval !< Coupling interval in seconds: the rate that\n" + " !! (1) ModName_UpdateStates() is called in loose coupling &\n" + " !! (2) ModName_UpdateDiscState() is called in tight coupling.\n" + " !! Input is the suggested time from the glue code;\n" + " !! Output is the actual coupling interval that will be used\n" + " !! by the glue code.\n" + " TYPE(ModName_InitOutputType), INTENT( OUT) :: InitOut !< Output for initialization routine\n" + " INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation\n" + " CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None\n" + "\n" + " ! local variables\n" + "\n" + " INTEGER(IntKi) :: NumOuts ! number of outputs; would probably be in the parameter type\n" + " INTEGER(IntKi) :: ErrStat2 ! local error status\n" + " CHARACTER(ErrMsgLen) :: ErrMsg2 ! local error message\n" + " CHARACTER(*), PARAMETER :: RoutineName = 'ModName_Init'\n" + "\n" + " !! Initialize variables\n" + "\n" + " ErrStat = ErrID_None\n" + " ErrMsg = ''\n" + " NumOuts = 2\n" + "\n" + "\n" + " ! Initialize the NWTC Subroutine Library\n" + "\n" + " call NWTC_Init( )\n" + "\n" + " ! Display the module information\n" + "\n" + " call DispNVD( ModName_Ver )\n" + "\n" + "\n" + " ! Define parameters here:\n" + "\n" + " p%DT = Interval\n" + "\n" + "\n" + " ! Define initial system states here:\n" + "\n" + " x%DummyContState = 0.0_ReKi\n" + " xd%DummyDiscState = 0.0_ReKi\n" + " z%DummyConstrState = 0.0_ReKi\n" + " OtherState%DummyOtherState = 0.0_ReKi\n" + "\n" + " ! define optimization variables here:\n" + " misc%DummyMiscVar = 0.0_ReKi\n" + "\n" + " ! Define initial guess for the system inputs here:\n" + "\n" + " u%DummyInput = 0.0_ReKi\n" + "\n" + "\n" + " ! Define system output initializations (set up mesh) here:\n" + " call AllocAry( y%WriteOutput, NumOuts, 'WriteOutput', ErrStat2, ErrMsg2 )\n" + " call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) ! set return error status based on local (concatenate errors)\n" + " if (ErrStat >= AbortErrLev) return ! if there are local variables that need to be deallocated, do so before early return\n" + " \n" + " y%DummyOutput = 0\n" + " y%WriteOutput = 0\n" + "\n" + "\n" + " ! Define initialization-routine output here:\n" + " call AllocAry(InitOut%WriteOutputHdr,NumOuts,'WriteOutputHdr',ErrStat2,ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName)\n" + " call AllocAry(InitOut%WriteOutputUnt,NumOuts,'WriteOutputUnt',ErrStat2,ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName)\n" + " if (ErrStat >= AbortErrLev) return ! if there are local variables that need to be deallocated, do so before early return\n" + "\n" + " InitOut%WriteOutputHdr = (/ 'Time ', 'Column2' /)\n" + " InitOut%WriteOutputUnt = (/ '(s)', '(-)' /)\n" + "\n" + "\n" + " ! If you want to choose your own rate instead of using what the glue code suggests, tell the glue code the rate at which\n" + " ! this module must be called here:\n" + "\n" + " !Interval = p%DT\n" + "\n" + "\n" + " if (InitInp%Linearize) then\n" + "\n" + " ! If this module does not implement the four Jacobian routines at the end of this template, or the module cannot\n" + " ! linearize with the features that are enabled, stop the simulation if InitInp%Linearize is true.\n" + "\n" + " CALL SetErrStat( ErrID_Fatal, 'ModuleName cannot perform linearization analysis.', ErrStat, ErrMsg, RoutineName)\n" + "\n" + " ! Otherwise, if the module does allow linearization, return the appropriate Jacobian row/column names and rotating-frame flags here:\n" + " ! Allocate and set these variables: InitOut%LinNames_y, InitOut%LinNames_x, InitOut%LinNames_xd, InitOut%LinNames_z, InitOut%LinNames_u\n" + " ! Allocate and set these variables: InitOut%RotFrame_y, InitOut%RotFrame_x, InitOut%RotFrame_xd, InitOut%RotFrame_z, InitOut%RotFrame_u\n" + " ! Allocate and set these variables: InitOut%IsLoad_u, InitOut%DerivOrder_x\n" + "\n" + " end if\n" + "\n" + "\n" + "END SUBROUTINE ModName_Init\n" + "!----------------------------------------------------------------------------------------------------------------------------------\n" + "!> This routine is called at the end of the simulation.\n" + "SUBROUTINE ModName_End( u, p, x, xd, z, OtherState, y, misc, ErrStat, ErrMsg )\n" + "!..................................................................................................................................\n" + "\n" + " TYPE(ModName_InputType), INTENT(INOUT) :: u !< System inputs\n" + " TYPE(ModName_ParameterType), INTENT(INOUT) :: p !< Parameters\n" + " TYPE(ModName_ContinuousStateType), INTENT(INOUT) :: x !< Continuous states\n" + " TYPE(ModName_DiscreteStateType), INTENT(INOUT) :: xd !< Discrete states\n" + " TYPE(ModName_ConstraintStateType), INTENT(INOUT) :: z !< Constraint states\n" + " TYPE(ModName_OtherStateType), INTENT(INOUT) :: OtherState !< Other states\n" + " TYPE(ModName_OutputType), INTENT(INOUT) :: y !< System outputs\n" + " TYPE(ModName_MiscVarType), INTENT(INOUT) :: misc !< Misc variables for optimization (not copied in glue code)\n" + " INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation\n" + " CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None\n" + "\n" + " ! local variables\n" + " INTEGER(IntKi) :: ErrStat2 ! local error status\n" + " CHARACTER(ErrMsgLen) :: ErrMsg2 ! local error message\n" + " CHARACTER(*), PARAMETER :: RoutineName = 'ModName_End'\n" + "\n" + " ! Initialize ErrStat\n" + "\n" + " ErrStat = ErrID_None\n" + " ErrMsg = ''\n" + "\n" + "\n" + " !! Place any last minute operations or calculations here:\n" + "\n" + "\n" + " !! Close files here (but because of checkpoint-restart capability, it is not recommended to have files open during the simulation):\n" + "\n" + "\n" + " !! Destroy the input data:\n" + "\n" + " call ModName_DestroyInput( u, ErrStat2, ErrMsg2 )\n" + " call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName)\n" + "\n" + "\n" + " !! Destroy the parameter data:\n" + "\n" + " call ModName_DestroyParam( p, ErrStat2, ErrMsg2 )\n" + " call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName)\n" + "\n" + " !! Destroy the state data:\n" + "\n" + " call ModName_DestroyContState( x, ErrStat2,ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName)\n" + " call ModName_DestroyDiscState( xd, ErrStat2,ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName)\n" + " call ModName_DestroyConstrState( z, ErrStat2,ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName)\n" + " call ModName_DestroyOtherState( OtherState, ErrStat2,ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName)\n" + "\n" + "\n" + " !! Destroy the output data:\n" + "\n" + " call ModName_DestroyOutput( y, ErrStat2, ErrMsg2 ); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName)\n" + "\n" + " \n" + " !! Destroy the misc data:\n" + "\n" + " call ModName_DestroyMisc( misc, ErrStat2, ErrMsg2 ); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName)\n" + "\n" + "\n" + "END SUBROUTINE ModName_End\n" + "!----------------------------------------------------------------------------------------------------------------------------------\n" + "!> This is a loose coupling routine for solving constraint states, integrating continuous states, and updating discrete and other \n" + "!! states. Continuous, constraint, discrete, and other states are updated to values at t + Interval.\n" + "SUBROUTINE ModName_UpdateStates( t, n, Inputs, InputTimes, p, x, xd, z, OtherState, misc, ErrStat, ErrMsg )\n" + "!..................................................................................................................................\n" + "\n" + " REAL(DbKi), INTENT(IN ) :: t !< Current simulation time in seconds\n" + " INTEGER(IntKi), INTENT(IN ) :: n !< Current step of the simulation: t = n*Interval\n" + " TYPE(ModName_InputType), INTENT(INOUT) :: Inputs(:) !< Inputs at InputTimes (output from this routine only \n" + " !! because of record keeping in routines that copy meshes)\n" + " REAL(DbKi), INTENT(IN ) :: InputTimes(:) !< Times in seconds associated with Inputs\n" + " TYPE(ModName_ParameterType), INTENT(IN ) :: p !< Parameters\n" + " TYPE(ModName_ContinuousStateType), INTENT(INOUT) :: x !< Input: Continuous states at t;\n" + " !! Output: Continuous states at t + Interval\n" + " TYPE(ModName_DiscreteStateType), INTENT(INOUT) :: xd !< Input: Discrete states at t;\n" + " !! Output: Discrete states at t + Interval\n" + " TYPE(ModName_ConstraintStateType), INTENT(INOUT) :: z !< Input: Constraint states at t;\n" + " !! Output: Constraint states at t + Interval\n" + " TYPE(ModName_OtherStateType), INTENT(INOUT) :: OtherState !< Other states: Other states at t;\n" + " !! Output: Other states at t + Interval\n" + " TYPE(ModName_MiscVarType), INTENT(INOUT) :: misc !< Misc variables for optimization (not copied in glue code)\n" + " INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation\n" + " CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None\n" + "\n" + " ! Local variables\n" + "\n" + " TYPE(ModName_ContinuousStateType) :: dxdt ! Continuous state derivatives at t\n" + " TYPE(ModName_DiscreteStateType) :: xd_t ! Discrete states at t (copy)\n" + " TYPE(ModName_ConstraintStateType) :: z_Residual ! Residual of the constraint state functions (Z)\n" + " TYPE(ModName_InputType) :: u ! Instantaneous inputs\n" + " \n" + " INTEGER(IntKi) :: ErrStat2 ! local error status\n" + " CHARACTER(ErrMsgLen) :: ErrMsg2 ! local error message\n" + " CHARACTER(*), PARAMETER :: RoutineName = 'ModName_UpdateStates'\n" + "\n" + "\n" + " ! Initialize variables\n" + "\n" + " ErrStat = ErrID_None ! no error has occurred\n" + " ErrMsg = ''\n" + "\n" + "\n" + " ! This subroutine contains an example of how the states could be updated. Developers will\n" + " ! want to adjust the logic as necessary for their own situations.\n" + "\n" + "\n" + "\n" + " ! Get the inputs at time t, based on the array of values sent by the glue code:\n" + "\n" + " ! before calling ExtrapInterp routine, memory in u must be allocated; we can do that with a copy:\n" + " call ModName_CopyInput( Inputs(1), u, MESH_NEWCOPY, ErrStat2, ErrMsg2 )\n" + " call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName)\n" + " if ( ErrStat >= AbortErrLev ) then\n" + " call cleanup() ! to avoid memory leaks, we have to destroy the local variables that may have allocatable arrays or meshes\n" + " return\n" + " end if\n" + "\n" + " call ModName_Input_ExtrapInterp( Inputs, InputTimes, u, t, ErrStat2, ErrMsg2 ) \n" + " call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName)\n" + " if ( ErrStat >= AbortErrLev ) then\n" + " call cleanup()\n" + " return\n" + " end if\n" + "\n" + "\n" + "\n" + " ! Get first time derivatives of continuous states (dxdt):\n" + "\n" + " call ModName_CalcContStateDeriv( t, u, p, x, xd, z, OtherState, misc, dxdt, ErrStat2, ErrMsg2 )\n" + " call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName)\n" + " if ( ErrStat >= AbortErrLev ) then\n" + " call cleanup()\n" + " return\n" + " end if\n" + "\n" + "\n" + " ! Update discrete states:\n" + " ! Note that xd [discrete state] is changed in ModName_UpdateDiscState() so xd will now contain values at t+Interval\n" + " ! We'll first make a copy that contains xd at time t, which will be used in computing the constraint states\n" + " call ModName_CopyDiscState( xd, xd_t, MESH_NEWCOPY, ErrStat2, ErrMsg2 )\n" + " call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName)\n" + " if ( ErrStat >= AbortErrLev ) then\n" + " call cleanup()\n" + " return\n" + " end if\n" + "\n" + " call ModName_UpdateDiscState( t, n, u, p, x, xd, z, OtherState, misc, ErrStat2, ErrMsg2 )\n" + " call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName)\n" + " if ( ErrStat >= AbortErrLev ) then\n" + " call cleanup()\n" + " return\n" + " end if\n" + "\n" + "\n" + " ! Solve for the constraint states (z) here:\n" + "\n" + " ! Iterate until the value is within a given tolerance.\n" + "\n" + " ! DO \n" + "\n" + " call ModName_CalcConstrStateResidual( t, u, p, x, xd_t, z, OtherState, misc, Z_Residual, ErrStat2, ErrMsg2 )\n" + " call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName)\n" + " if ( ErrStat >= AbortErrLev ) then\n" + " call cleanup()\n" + " return\n" + " end if\n" + "\n" + " ! z =\n" + "\n" + " ! END DO\n" + "\n" + "\n" + "\n" + " ! Integrate (update) continuous states (x) here:\n" + "\n" + " !x = function of dxdt and x\n" + "\n" + "\n" + " ! Destroy local variables before returning\n" + " call cleanup()\n" + "\n" + "\n" + "CONTAINS\n" + " SUBROUTINE cleanup()\n" + " ! note that this routine inherits all of the data in ModName_UpdateStates\n" + "\n" + "\n" + " CALL ModName_DestroyInput( u, ErrStat2, ErrMsg2)\n" + " CALL ModName_DestroyConstrState( Z_Residual, ErrStat2, ErrMsg2)\n" + " CALL ModName_DestroyContState( dxdt, ErrStat2, ErrMsg2)\n" + " CALL ModName_DestroyDiscState( xd_t, ErrStat2, ErrMsg2) \n" + "\n" + " END SUBROUTINE cleanup\n" + "END SUBROUTINE ModName_UpdateStates\n" + "!----------------------------------------------------------------------------------------------------------------------------------\n" + "!> This is a routine for computing outputs, used in both loose and tight coupling.\n" + "SUBROUTINE ModName_CalcOutput( t, u, p, x, xd, z, OtherState, y, misc, ErrStat, ErrMsg )\n" + "!..................................................................................................................................\n" + "\n" + " REAL(DbKi), INTENT(IN ) :: t !< Current simulation time in seconds\n" + " TYPE(ModName_InputType), INTENT(IN ) :: u !< Inputs at t\n" + " TYPE(ModName_ParameterType), INTENT(IN ) :: p !< Parameters\n" + " TYPE(ModName_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at t\n" + " TYPE(ModName_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at t\n" + " TYPE(ModName_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at t\n" + " TYPE(ModName_OtherStateType), INTENT(IN ) :: OtherState !< Other states at t\n" + " TYPE(ModName_MiscVarType), INTENT(INOUT) :: misc !< Misc variables for optimization (not copied in glue code)\n" + " TYPE(ModName_OutputType), INTENT(INOUT) :: y !< Outputs computed at t (Input only so that mesh con-\n" + " !! nectivity information does not have to be recalculated)\n" + " INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation\n" + " CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None\n" + "\n" + "\n" + " ! Initialize ErrStat\n" + "\n" + " ErrStat = ErrID_None\n" + " ErrMsg = ''\n" + "\n" + "\n" + " ! Compute outputs here:\n" + " y%DummyOutput = 2.0_ReKi\n" + "\n" + " y%WriteOutput(1) = REAL(t,ReKi)\n" + " y%WriteOutput(2) = 1.0_ReKi\n" + "\n" + "\n" + "END SUBROUTINE ModName_CalcOutput\n" + "!----------------------------------------------------------------------------------------------------------------------------------\n" + "!> This is a tight coupling routine for computing derivatives of continuous states.\n" + "SUBROUTINE ModName_CalcContStateDeriv( t, u, p, x, xd, z, OtherState, misc, dxdt, ErrStat, ErrMsg )\n" + "!..................................................................................................................................\n" + "\n" + " REAL(DbKi), INTENT(IN ) :: t !< Current simulation time in seconds\n" + " TYPE(ModName_InputType), INTENT(IN ) :: u !< Inputs at t\n" + " TYPE(ModName_ParameterType), INTENT(IN ) :: p !< Parameters\n" + " TYPE(ModName_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at t\n" + " TYPE(ModName_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at t\n" + " TYPE(ModName_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at t\n" + " TYPE(ModName_OtherStateType), INTENT(IN ) :: OtherState !< Other states at t\n" + " TYPE(ModName_MiscVarType), INTENT(INOUT) :: misc !< Misc variables for optimization (not copied in glue code)\n" + " TYPE(ModName_ContinuousStateType), INTENT( OUT) :: dxdt !< Continuous state derivatives at t\n" + " INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation\n" + " CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None\n" + "\n" + "\n" + " ! Initialize ErrStat\n" + "\n" + " ErrStat = ErrID_None\n" + " ErrMsg = ''\n" + "\n" + "\n" + " ! Compute the first time derivatives of the continuous states here:\n" + "\n" + " dxdt%DummyContState = 0.0_ReKi\n" + "\n" + "\n" + "END SUBROUTINE ModName_CalcContStateDeriv\n" + "!----------------------------------------------------------------------------------------------------------------------------------\n" + "!> This is a tight coupling routine for updating discrete states.\n" + "SUBROUTINE ModName_UpdateDiscState( t, n, u, p, x, xd, z, OtherState, misc, ErrStat, ErrMsg )\n" + "!..................................................................................................................................\n" + "\n" + " REAL(DbKi), INTENT(IN ) :: t !< Current simulation time in seconds\n" + " INTEGER(IntKi), INTENT(IN ) :: n !< Current step of the simulation: t = n*Interval\n" + " TYPE(ModName_InputType), INTENT(IN ) :: u !< Inputs at t\n" + " TYPE(ModName_ParameterType), INTENT(IN ) :: p !< Parameters\n" + " TYPE(ModName_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at t\n" + " TYPE(ModName_DiscreteStateType), INTENT(INOUT) :: xd !< Input: Discrete states at t;\n" + " !! Output: Discrete states at t + Interval\n" + " TYPE(ModName_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at t\n" + " TYPE(ModName_OtherStateType), INTENT(IN ) :: OtherState !< Other states at t\n" + " TYPE(ModName_MiscVarType), INTENT(INOUT) :: misc !< Misc variables for optimization (not copied in glue code)\n" + " INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation\n" + " CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None\n" + "\n" + "\n" + " ! Initialize ErrStat\n" + "\n" + " ErrStat = ErrID_None\n" + " ErrMsg = ''\n" + "\n" + "\n" + " ! Update discrete states here:\n" + "\n" + " xd%DummyDiscState = 0.0_Reki\n" + "\n" + "END SUBROUTINE ModName_UpdateDiscState\n" + "!----------------------------------------------------------------------------------------------------------------------------------\n" + "!> This is a tight coupling routine for solving for the residual of the constraint state functions.\n" + "SUBROUTINE ModName_CalcConstrStateResidual( t, u, p, x, xd, z, OtherState, misc, Z_residual, ErrStat, ErrMsg )\n" + "!..................................................................................................................................\n" + "\n" + " REAL(DbKi), INTENT(IN ) :: t !< Current simulation time in seconds\n" + " TYPE(ModName_InputType), INTENT(IN ) :: u !< Inputs at t\n" + " TYPE(ModName_ParameterType), INTENT(IN ) :: p !< Parameters\n" + " TYPE(ModName_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at t\n" + " TYPE(ModName_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at t\n" + " TYPE(ModName_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at t (possibly a guess)\n" + " TYPE(ModName_OtherStateType), INTENT(IN ) :: OtherState !< Other states at t\n" + " TYPE(ModName_MiscVarType), INTENT(INOUT) :: misc !< Misc variables for optimization (not copied in glue code)\n" + " TYPE(ModName_ConstraintStateType), INTENT( OUT) :: Z_residual !< Residual of the constraint state functions using\n" + " !! the input values described above\n" + " INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation\n" + " CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None\n" + "\n" + "\n" + " ! Initialize ErrStat\n" + "\n" + " ErrStat = ErrID_None\n" + " ErrMsg = ''\n" + "\n" + "\n" + " ! Solve for the residual of the constraint state functions here:\n" + "\n" + " Z_residual%DummyConstrState = 0.0_ReKi\n" + "\n" + "END SUBROUTINE ModName_CalcConstrStateResidual\n" + "\n" + "\n" + "!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n" + "! ###### The following four routines are Jacobian routines for linearization capabilities #######\n" + "! If the module does not implement them, set ErrStat = ErrID_Fatal in ModName_Init() when InitInp%Linearize is .true.\n" + "!----------------------------------------------------------------------------------------------------------------------------------\n" + "!> Routine to compute the Jacobians of the output (Y), continuous- (X), discrete- (Xd), and constraint-state (Z) functions\n" + "!! with respect to the inputs (u). The partial derivatives dY/du, dX/du, dXd/du, and dZ/du are returned.\n" + "SUBROUTINE ModName_JacobianPInput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, dYdu, dXdu, dXddu, dZdu)\n" + "!..................................................................................................................................\n" + "\n" + " REAL(DbKi), INTENT(IN ) :: t !< Time in seconds at operating point\n" + " TYPE(ModName_InputType), INTENT(IN ) :: u !< Inputs at operating point (may change to inout if a mesh copy is required)\n" + " TYPE(ModName_ParameterType), INTENT(IN ) :: p !< Parameters\n" + " TYPE(ModName_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at operating point\n" + " TYPE(ModName_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at operating point\n" + " TYPE(ModName_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at operating point\n" + " TYPE(ModName_OtherStateType), INTENT(IN ) :: OtherState !< Other states at operating point\n" + " TYPE(ModName_OutputType), INTENT(IN ) :: y !< Output (change to inout if a mesh copy is required);\n" + " !! Output fields are not used by this routine, but type is\n" + " !! available here so that mesh parameter information (i.e.,\n" + " !! connectivity) does not have to be recalculated for dYdu.\n" + " TYPE(ModName_MiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables\n" + " INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation\n" + " CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None\n" + " REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dYdu(:,:) !< Partial derivatives of output functions (Y) with respect\n" + " !! to the inputs (u) [intent in to avoid deallocation]\n" + " REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dXdu(:,:) !< Partial derivatives of continuous state functions (X) with\n" + " !! respect to the inputs (u) [intent in to avoid deallocation]\n" + " REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dXddu(:,:) !< Partial derivatives of discrete state functions (Xd) with\n" + " !! respect to the inputs (u) [intent in to avoid deallocation]\n" + " REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dZdu(:,:) !< Partial derivatives of constraint state functions (Z) with\n" + " !! respect to the inputs (u) [intent in to avoid deallocation]\n" + "\n" + "\n" + " ! Initialize ErrStat\n" + "\n" + " ErrStat = ErrID_None\n" + " ErrMsg = ''\n" + "\n" + "\n" + " IF ( PRESENT( dYdu ) ) THEN\n" + "\n" + " ! Calculate the partial derivative of the output functions (Y) with respect to the inputs (u) here:\n" + "\n" + " ! allocate and set dYdu\n" + "\n" + " END IF\n" + "\n" + " IF ( PRESENT( dXdu ) ) THEN\n" + "\n" + " ! Calculate the partial derivative of the continuous state functions (X) with respect to the inputs (u) here:\n" + "\n" + " ! allocate and set dXdu\n" + "\n" + " END IF\n" + "\n" + " IF ( PRESENT( dXddu ) ) THEN\n" + "\n" + " ! Calculate the partial derivative of the discrete state functions (Xd) with respect to the inputs (u) here:\n" + "\n" + " ! allocate and set dXddu\n" + "\n" + " END IF\n" + "\n" + " IF ( PRESENT( dZdu ) ) THEN\n" + "\n" + " ! Calculate the partial derivative of the constraint state functions (Z) with respect to the inputs (u) here:\n" + "\n" + " ! allocate and set dZdu\n" + "\n" + " END IF\n" + "\n" + "\n" + "END SUBROUTINE ModName_JacobianPInput\n" + "!----------------------------------------------------------------------------------------------------------------------------------\n" + "!> Routine to compute the Jacobians of the output (Y), continuous- (X), discrete- (Xd), and constraint-state (Z) functions\n" + "!! with respect to the continuous states (x). The partial derivatives dY/dx, dX/dx, dXd/dx, and dZ/dx are returned.\n" + "SUBROUTINE ModName_JacobianPContState( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, dYdx, dXdx, dXddx, dZdx )\n" + "!..................................................................................................................................\n" + "\n" + " REAL(DbKi), INTENT(IN ) :: t !< Time in seconds at operating point\n" + " TYPE(ModName_InputType), INTENT(IN ) :: u !< Inputs at operating point (may change to inout if a mesh copy is required)\n" + " TYPE(ModName_ParameterType), INTENT(IN ) :: p !< Parameters\n" + " TYPE(ModName_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at operating point\n" + " TYPE(ModName_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at operating point\n" + " TYPE(ModName_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at operating point\n" + " TYPE(ModName_OtherStateType), INTENT(IN ) :: OtherState !< Other states at operating point\n" + " TYPE(ModName_OutputType), INTENT(IN ) :: y !< Output (change to inout if a mesh copy is required);\n" + " !! Output fields are not used by this routine, but type is\n" + " !! available here so that mesh parameter information (i.e.,\n" + " !! connectivity) does not have to be recalculated for dYdx.\n" + " TYPE(ModName_MiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables\n" + " INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation\n" + " CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None\n" + " REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dYdx(:,:) !< Partial derivatives of output functions\n" + " !! (Y) with respect to the continuous\n" + " !! states (x) [intent in to avoid deallocation]\n" + " REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dXdx(:,:) !< Partial derivatives of continuous state\n" + " !! functions (X) with respect to\n" + " !! the continuous states (x) [intent in to avoid deallocation]\n" + " REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dXddx(:,:) !< Partial derivatives of discrete state\n" + " !! functions (Xd) with respect to\n" + " !! the continuous states (x) [intent in to avoid deallocation]\n" + " REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dZdx(:,:) !< Partial derivatives of constraint state\n" + " !! functions (Z) with respect to\n" + " !! the continuous states (x) [intent in to avoid deallocation]\n" + "\n" + "\n" + " ! Initialize ErrStat\n" + "\n" + " ErrStat = ErrID_None\n" + " ErrMsg = ''\n" + "\n" + "\n" + "\n" + " IF ( PRESENT( dYdx ) ) THEN\n" + "\n" + " ! Calculate the partial derivative of the output functions (Y) with respect to the continuous states (x) here:\n" + "\n" + " ! allocate and set dYdx\n" + "\n" + " END IF\n" + "\n" + " IF ( PRESENT( dXdx ) ) THEN\n" + "\n" + " ! Calculate the partial derivative of the continuous state functions (X) with respect to the continuous states (x) here:\n" + "\n" + " ! allocate and set dXdx\n" + "\n" + " END IF\n" + "\n" + " IF ( PRESENT( dXddx ) ) THEN\n" + "\n" + " ! Calculate the partial derivative of the discrete state functions (Xd) with respect to the continuous states (x) here:\n" + "\n" + " ! allocate and set dXddx\n" + "\n" + " END IF\n" + "\n" + " IF ( PRESENT( dZdx ) ) THEN\n" + "\n" + "\n" + " ! Calculate the partial derivative of the constraint state functions (Z) with respect to the continuous states (x) here:\n" + "\n" + " ! allocate and set dZdx\n" + "\n" + " END IF\n" + "\n" + "\n" + "END SUBROUTINE ModName_JacobianPContState\n" + "!----------------------------------------------------------------------------------------------------------------------------------\n" + "!> Routine to compute the Jacobians of the output (Y), continuous- (X), discrete- (Xd), and constraint-state (Z) functions\n" + "!! with respect to the discrete states (xd). The partial derivatives dY/dxd, dX/dxd, dXd/dxd, and dZ/dxd are returned.\n" + "SUBROUTINE ModName_JacobianPDiscState( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, dYdxd, dXdxd, dXddxd, dZdxd )\n" + "!..................................................................................................................................\n" + "\n" + " REAL(DbKi), INTENT(IN ) :: t !< Time in seconds at operating point\n" + " TYPE(ModName_InputType), INTENT(IN ) :: u !< Inputs at operating point (may change to inout if a mesh copy is required)\n" + " TYPE(ModName_ParameterType), INTENT(IN ) :: p !< Parameters\n" + " TYPE(ModName_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at operating point\n" + " TYPE(ModName_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at operating point\n" + " TYPE(ModName_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at operating point\n" + " TYPE(ModName_OtherStateType), INTENT(IN ) :: OtherState !< Other states at operating point\n" + " TYPE(ModName_OutputType), INTENT(IN ) :: y !< Output (change to inout if a mesh copy is required);\n" + " !! Output fields are not used by this routine, but type is\n" + " !! available here so that mesh parameter information (i.e.,\n" + " !! connectivity) does not have to be recalculated for dYdxd.\n" + " TYPE(ModName_MiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables\n" + " INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation\n" + " CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None\n" + " REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dYdxd(:,:) !< Partial derivatives of output functions\n" + " !! (Y) with respect to the discrete\n" + " !! states (xd) [intent in to avoid deallocation]\n" + " REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dXdxd(:,:) !< Partial derivatives of continuous state\n" + " !! functions (X) with respect to the\n" + " !! discrete states (xd) [intent in to avoid deallocation]\n" + " REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dXddxd(:,:)!< Partial derivatives of discrete state\n" + " !! functions (Xd) with respect to the\n" + " !! discrete states (xd) [intent in to avoid deallocation]\n" + " REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dZdxd(:,:) !< Partial derivatives of constraint state\n" + " !! functions (Z) with respect to the\n" + " !! discrete states (xd) [intent in to avoid deallocation]\n" + "\n" + "\n" + " ! Initialize ErrStat\n" + "\n" + " ErrStat = ErrID_None\n" + " ErrMsg = ''\n" + "\n" + "\n" + " IF ( PRESENT( dYdxd ) ) THEN\n" + "\n" + " ! Calculate the partial derivative of the output functions (Y) with respect to the discrete states (xd) here:\n" + "\n" + " ! allocate and set dYdxd\n" + "\n" + " END IF\n" + "\n" + " IF ( PRESENT( dXdxd ) ) THEN\n" + "\n" + " ! Calculate the partial derivative of the continuous state functions (X) with respect to the discrete states (xd) here:\n" + "\n" + " ! allocate and set dXdxd\n" + "\n" + " END IF\n" + "\n" + " IF ( PRESENT( dXddxd ) ) THEN\n" + "\n" + " ! Calculate the partial derivative of the discrete state functions (Xd) with respect to the discrete states (xd) here:\n" + "\n" + " ! allocate and set dXddxd\n" + "\n" + " END IF\n" + "\n" + " IF ( PRESENT( dZdxd ) ) THEN\n" + "\n" + " ! Calculate the partial derivative of the constraint state functions (Z) with respect to the discrete states (xd) here:\n" + "\n" + " ! allocate and set dZdxd\n" + "\n" + " END IF\n" + "\n" + "\n" + "END SUBROUTINE ModName_JacobianPDiscState\n" + "!----------------------------------------------------------------------------------------------------------------------------------\n" + "!> Routine to compute the Jacobians of the output (Y), continuous- (X), discrete- (Xd), and constraint-state (Z) functions\n" + "!! with respect to the constraint states (z). The partial derivatives dY/dz, dX/dz, dXd/dz, and dZ/dz are returned.\n" + "SUBROUTINE ModName_JacobianPConstrState( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, dYdz, dXdz, dXddz, dZdz )\n" + "!..................................................................................................................................\n" + "\n" + " REAL(DbKi), INTENT(IN ) :: t !< Time in seconds at operating point\n" + " TYPE(ModName_InputType), INTENT(IN ) :: u !< Inputs at operating point (may change to inout if a mesh copy is required)\n" + " TYPE(ModName_ParameterType), INTENT(IN ) :: p !< Parameters\n" + " TYPE(ModName_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at operating point\n" + " TYPE(ModName_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at operating point\n" + " TYPE(ModName_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at operating point\n" + " TYPE(ModName_OtherStateType), INTENT(IN ) :: OtherState !< Other states at operating point\n" + " TYPE(ModName_OutputType), INTENT(IN ) :: y !< Output (change to inout if a mesh copy is required);\n" + " !! Output fields are not used by this routine, but type is\n" + " !! available here so that mesh parameter information (i.e.,\n" + " !! connectivity) does not have to be recalculated for dYdz.\n" + " TYPE(ModName_MiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables\n" + " INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation\n" + " CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None\n" + " REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dYdz(:,:) !< Partial derivatives of output\n" + " !! functions (Y) with respect to the\n" + " !! constraint states (z) [intent in to avoid deallocation]\n" + " REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dXdz(:,:) !< Partial derivatives of continuous\n" + " !! state functions (X) with respect to\n" + " !! the constraint states (z) [intent in to avoid deallocation]\n" + " REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dXddz(:,:) !< Partial derivatives of discrete state\n" + " !! functions (Xd) with respect to the\n" + " !! constraint states (z) [intent in to avoid deallocation]\n" + " REAL(R8Ki), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dZdz(:,:) !< Partial derivatives of constraint\n" + " !! state functions (Z) with respect to\n" + " !! the constraint states (z) [intent in to avoid deallocation]\n" + "\n" + "\n" + " ! Initialize ErrStat\n" + "\n" + " ErrStat = ErrID_None\n" + " ErrMsg = ''\n" + "\n" + " IF ( PRESENT( dYdz ) ) THEN\n" + "\n" + " ! Calculate the partial derivative of the output functions (Y) with respect to the constraint states (z) here:\n" + "\n" + " ! allocate and set dYdz\n" + "\n" + " END IF\n" + "\n" + " IF ( PRESENT( dXdz ) ) THEN\n" + "\n" + " ! Calculate the partial derivative of the continuous state functions (X) with respect to the constraint states (z) here:\n" + "\n" + " ! allocate and set dXdz\n" + "\n" + " END IF\n" + "\n" + " IF ( PRESENT( dXddz ) ) THEN\n" + "\n" + " ! Calculate the partial derivative of the discrete state functions (Xd) with respect to the constraint states (z) here:\n" + "\n" + " ! allocate and set dXddz\n" + "\n" + " END IF\n" + "\n" + " IF ( PRESENT( dZdz ) ) THEN\n" + "\n" + " ! Calculate the partial derivative of the constraint state functions (Z) with respect to the constraint states (z) here:\n" + "\n" + " ! allocate and set dZdz\n" + "\n" + " END IF\n" + "\n" + "\n" + "END SUBROUTINE ModName_JacobianPConstrState\n" + "!----------------------------------------------------------------------------------------------------------------------------------\n" + "!> Routine to pack the data structures representing the operating points into arrays for linearization.\n" + "SUBROUTINE ModName_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, u_op, y_op, x_op, dx_op, xd_op, z_op )\n" + "\n" + " REAL(DbKi), INTENT(IN ) :: t !< Time in seconds at operating point\n" + " TYPE(ModName_InputType), INTENT(IN ) :: u !< Inputs at operating point (may change to inout if a mesh copy is required)\n" + " TYPE(ModName_ParameterType), INTENT(IN ) :: p !< Parameters\n" + " TYPE(ModName_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at operating point\n" + " TYPE(ModName_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at operating point\n" + " TYPE(ModName_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at operating point\n" + " TYPE(ModName_OtherStateType), INTENT(IN ) :: OtherState !< Other states at operating point\n" + " TYPE(ModName_OutputType), INTENT(IN ) :: y !< Output at operating point\n" + " TYPE(ModName_MiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables\n" + " INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation\n" + " CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None\n" + " REAL(ReKi), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: u_op(:) !< values of linearized inputs\n" + " REAL(ReKi), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: y_op(:) !< values of linearized outputs\n" + " REAL(ReKi), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: x_op(:) !< values of linearized continuous states\n" + " REAL(ReKi), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: dx_op(:) !< values of first time derivatives of linearized continuous states\n" + " REAL(ReKi), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: xd_op(:) !< values of linearized discrete states\n" + " REAL(ReKi), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: z_op(:) !< values of linearized constraint states\n" + "\n" + "\n" + " ! Initialize ErrStat\n" + "\n" + " ErrStat = ErrID_None\n" + " ErrMsg = ''\n" + "\n" + " IF ( PRESENT( u_op ) ) THEN\n" + "\n" + " END IF\n" + "\n" + " IF ( PRESENT( y_op ) ) THEN\n" + " END IF\n" + "\n" + " IF ( PRESENT( x_op ) ) THEN\n" + "\n" + " END IF\n" + "\n" + " IF ( PRESENT( dx_op ) ) THEN\n" + "\n" + " END IF\n" + "\n" + " IF ( PRESENT( xd_op ) ) THEN\n" + "\n" + " END IF\n" + "\n" + " IF ( PRESENT( z_op ) ) THEN\n" + "\n" + " END IF\n" + "\n" + "END SUBROUTINE ModName_GetOP\n" + "!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n" + "\n" + "END MODULE ModuleName\n" + "!**********************************************************************************************************************************\n"); #endif \ No newline at end of file From 13d0a7721d545b72e6197e9921ba914f22369637 Mon Sep 17 00:00:00 2001 From: Derek Slaughter Date: Fri, 9 Jun 2023 12:01:34 -0400 Subject: [PATCH 2/3] Fix MAP issue if CMake used to generate VS project Visual Studio can't handle mixing C and Fortran source in the same library. This commit splits the C and Fortran into two libraries. --- glue-codes/simulink/CMakeLists.txt | 1 + modules/map/CMakeLists.txt | 15 ++++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/glue-codes/simulink/CMakeLists.txt b/glue-codes/simulink/CMakeLists.txt index f4251c35cd..a9d055fc44 100644 --- a/glue-codes/simulink/CMakeLists.txt +++ b/glue-codes/simulink/CMakeLists.txt @@ -43,6 +43,7 @@ matlab_add_mex( $ $ $ + $ $ $ $ diff --git a/modules/map/CMakeLists.txt b/modules/map/CMakeLists.txt index b69312b4db..f7ce852553 100644 --- a/modules/map/CMakeLists.txt +++ b/modules/map/CMakeLists.txt @@ -33,13 +33,18 @@ 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(maplib - src/map.f90 - src/MAP_Types.f90 +add_library(maplib_fortran src/MAP_Fortran_Types.f90 + src/MAP_Types.f90 + src/map.f90 +) +target_link_libraries(maplib_fortran nwtclibs) + +add_library(maplib ${MAP_CLIB_SOURCES} + ${MAP_C_HEADERS} ) -target_link_libraries(maplib nwtclibs) +target_link_libraries(maplib maplib_fortran) target_include_directories(maplib PUBLIC $ $ @@ -49,7 +54,7 @@ target_include_directories(maplib PUBLIC ) set_target_properties(maplib PROPERTIES PUBLIC_HEADER src/MAP_Types.h) -install(TARGETS maplib +install(TARGETS maplib maplib_fortran EXPORT "${CMAKE_PROJECT_NAME}Libraries" RUNTIME DESTINATION bin ARCHIVE DESTINATION lib From 912aa542040f073cdf66c54c30c64d5cc294c6ad Mon Sep 17 00:00:00 2001 From: Derek Slaughter Date: Fri, 9 Jun 2023 12:36:48 -0400 Subject: [PATCH 3/3] Resolve issue compiling MAP --- glue-codes/simulink/CMakeLists.txt | 1 + modules/map/CMakeLists.txt | 16 ++++++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/glue-codes/simulink/CMakeLists.txt b/glue-codes/simulink/CMakeLists.txt index a9d055fc44..dbb1fa9a2f 100644 --- a/glue-codes/simulink/CMakeLists.txt +++ b/glue-codes/simulink/CMakeLists.txt @@ -44,6 +44,7 @@ matlab_add_mex( $ $ $ + $ $ $ $ diff --git a/modules/map/CMakeLists.txt b/modules/map/CMakeLists.txt index f7ce852553..ef52239d12 100644 --- a/modules/map/CMakeLists.txt +++ b/modules/map/CMakeLists.txt @@ -36,25 +36,29 @@ file(GLOB MAP_C_HEADERS src/*.h src/*/*.h) add_library(maplib_fortran src/MAP_Fortran_Types.f90 src/MAP_Types.f90 - src/map.f90 ) target_link_libraries(maplib_fortran nwtclibs) -add_library(maplib +add_library(maplib_c ${MAP_CLIB_SOURCES} ${MAP_C_HEADERS} ) -target_link_libraries(maplib maplib_fortran) -target_include_directories(maplib PUBLIC +target_link_libraries(maplib_c nwtclibs) +target_include_directories(maplib_c PUBLIC $ $ $ $ $ ) -set_target_properties(maplib PROPERTIES PUBLIC_HEADER src/MAP_Types.h) +set_target_properties(maplib_c PROPERTIES PUBLIC_HEADER src/MAP_Types.h) + +add_library(maplib + src/map.f90 +) +target_link_libraries(maplib maplib_fortran maplib_c) -install(TARGETS maplib maplib_fortran +install(TARGETS maplib maplib_fortran maplib_c EXPORT "${CMAKE_PROJECT_NAME}Libraries" RUNTIME DESTINATION bin ARCHIVE DESTINATION lib