Hi all,
I’m looking into coupling both AeroDyn and BeamDyn to an external piece of simulation software. One of the main problems I foresee is that the software that will act as the driver program uses an explicit numerical integrator for updating its states, and these states would be used as inputs to both AeroDyn and BeamDyn. This means that I cannot just use OpenFAST as a reference for how to coordinate the two modules with the driver program because OpenFAST uses a predictor-corrector integration method (and uses an “iterative nonlinear input-output solver” for BeamDyn because I believe it has “direct-feedthrough” due to accelerations playing a role in both its input and output). That is to say, I can’t see how these same methods could be used in a driver program that uses explicit integration only for its own states.
So I’ve been trying to find other options. I’ve seen reference to OpenFAST’s modules having been built with the possibility of tight coupling, where some driver program actually uses its own numerical integration method to update the states of the modules. I’m thinking that this might be the way to go. I found a small guiding template in the NWTC Programmer’s Handbook for tight coupling (which I’ve posted below), but I’m unclear of two main things.
The first is that AeroDyn doesn’t actually have a function AD_CalcContStateDeriv, and I was wondering why that is. Is it because AeroDyn doesn’t actually have any continuous states unless DBEMT is enabled, i.e. when WakeMod=2? In general, how is tight coupling expected to be done with AeroDyn?
The second thing is how to deal with the result from the constraint state residual. In the template code below, the residual is calculated, and then the constraint variable is set. I’m wondering what this section of a tight coupling would look like with AeroDyn specifically. My confusion is probably due to the fact that I haven’t come across constraint residuals or Differential Algebraic Equations before, so it’s a bit new to me. If the explanation is too difficult for here, could you point me to some resources?
Thank you,
Dustin
!.............................................................................................................
! Routines called in tight coupling -- time marching only
!.............................................................................................................
DO n = 0,2
Time = n * TimeInterval ! Note that the discrete states must be updated only at the TimeInterval defined in initialization
! set inputs (u) here:
! u =
! Update constraint states at Time
! DO
CALL ModName_CalcConstrStateResidual( Time, u(1), p, x, xd, z, OtherState, Z_residual, ErrStat, ErrMsg )
IF ( ErrStat /= ErrID_None ) THEN ! Check if there was an error and do something about it if necessary
CALL WrScr( ErrMsg )
END IF
! z =
! END DO
! Calculate the outputs at Time
CALL ModName_CalcOutput( Time, u(1), p, x, xd, z, OtherState, y, ErrStat, ErrMsg )
IF ( ErrStat /= ErrID_None ) THEN ! Check if there was an error and do something about it if necessary
CALL WrScr( ErrMsg )
END IF
! Calculate the continuous state derivatives at Time
CALL ModName_CalcContStateDeriv( Time, u(1), p, x, xd, z, OtherState, dxdt, ErrStat, ErrMsg )
IF ( ErrStat /= ErrID_None ) THEN ! Check if there was an error and do something about it if necessary
CALL WrScr( ErrMsg )
END IF