Skip to content

Commit

Permalink
Added staticsMod and forcingMod as settings in yaml:
Browse files Browse the repository at this point in the history
- Made these two parameters attributes of the Model class, and can now
  be read in from the "settings" section of the RAFT yaml. Default 0.
  Updated docs as well.
  • Loading branch information
mattEhall committed Dec 9, 2024
1 parent 520920b commit e52ef2e
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 24 deletions.
2 changes: 2 additions & 0 deletions designs/VolturnUS-S.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ settings: # global Settings
max_freq : 0.40 # [Hz] highest frequency to consider
XiStart : 0 # sets initial amplitude of each DOF for all frequencies
nIter : 10 # sets how many iterations to perform in Model.solveDynamics()
staticsMod : 0 # sets hydrostatic stiffness approach in Model.solveStaticss (0) constant stiffness matrix or (1) nonlinear
forcingMod : 0 # sets forcing approach in Model.solveStatics: (0) constant or (1) updated each time

site:
water_depth : 200 # [m] uniform water depth
Expand Down
4 changes: 3 additions & 1 deletion docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,9 @@ Modeling Settings
max_freq : 0.40 # [Hz] highest frequency to consider
XiStart : 0 # sets initial amplitude of each DOF for all frequencies
nIter : 10 # sets how many iterations to perform in Model.solveDynamics()
staticsMod : 0 # sets hydrostatic stiffness approach in Model.solveStaticss (0) constant stiffness matrix or (1) nonlinear
forcingMod : 0 # sets forcing approach in Model.solveStatics: (0) constant or (1) updated each time
Site Characteristics
^^^^^^^^^^^^^^^^^^^^

Expand Down
50 changes: 27 additions & 23 deletions raft/raft_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ def __init__(self, design, nTurbines=1):
self.XiStart = getFromDict(design['settings'], 'XiStart' , default=0.1 , dtype=float) # sets initial amplitude of each DOF for all frequencies
self.nIter = getFromDict(design['settings'], 'nIter' , default=15 , dtype=int ) # sets how many iterations to perform in Model.solveDynamics()

self.staticsMod = getFromDict(design['settings'], 'staticsMod' , default=0, dtype=int) # use (0) stiffness matrix or (1) nonlinear reactions in Model.solveStatics()
self.forcingMod = getFromDict(design['settings'], 'forcingsMod', default=0, dtype=int) # use (0) constant or (1) updated forcing in Model.solveStatics()

self.w = np.arange(min_freq, max_freq+0.5*min_freq, min_freq) *2*np.pi # angular frequencies to analyze (rad/s)
self.nw = len(self.w) # number of frequencies

Expand Down Expand Up @@ -162,8 +165,11 @@ def __init__(self, design, nTurbines=1):
self.design = design # save design dictionary for possible later use/reference

# Set mooring current modeling mode (0: no current; 1: uniform current included in MoorPy)
self.mooring_currentMod = getFromDict(design['mooring'], 'currentMod', default=0, dtype=int)

if 'mooring' in design:
self.mooring_currentMod = getFromDict(design['mooring'], 'currentMod', default=0, dtype=int)
else:
self.mooring_currentMod = 0

# Initialize array-level mooring system if it exists
if self.ms:
self.ms.initialize()
Expand Down Expand Up @@ -534,19 +540,16 @@ def solveStatics(self, case, display=0):
- return total loads
statics_mod - 0: linearized hydrostatics; 1: hydrostatics are updated each iteration based on new poses
forcing_mod - 0: don't update environmental loads; 1: loads are updated each iteration based on new poses
self.staticsMod - 0: linearized hydrostatics; 1: hydrostatics are updated each iteration based on new poses
self.forcingMod - 0: don't update environmental loads; 1: loads are updated each iteration based on new poses
New change: supports either a single wind speed or a list (where there is one wind speed per turbine)
'''

statics_mod = 0
forcing_mod = 0

if statics_mod == 0: # if using linearized hydrostatics approach, get the matrices

if self.staticsMod == 0: # if using linearized hydrostatics approach, get the matrices
K_hydrostatic = [] #np.zeros([self.nDOF, self.nDOF]) # this will be the constant hydrostatic stiffness matrix--buoyancy and weight terms
F_undisplaced = np.zeros(self.nDOF) # force and moment vector before any displacements
if forcing_mod == 0: # if using constant environmental mean forcing
if self.forcingMod == 0: # if using constant environmental mean forcing
F_env_constant = np.zeros(self.nDOF) # constant environmental force and moment vector


Expand All @@ -569,13 +572,13 @@ def solveStatics(self, case, display=0):
fowt.setPosition(X_initial[6*i:6*i+6]) # zero platform offsets
fowt.calcStatics()

if statics_mod == 0:
if self.staticsMod == 0:
K_hydrostatic.append(fowt.C_struc + fowt.C_hydro)
F_undisplaced[6*i:6*i+6 ] += fowt.W_struc + fowt.W_hydro

if display > 1: print(" F_undisplaced "+" ".join(["{:+8.2e}"]*6).format(*F_undisplaced[6*i:6*i+6]))

if forcing_mod == 0 and case:
if self.forcingMod == 0 and case:

# If list of wind speeds, set each turbine case with corresponding wind speed
if type(caseorig['wind_speed']) == list :
Expand Down Expand Up @@ -627,10 +630,11 @@ def solveStatics(self, case, display=0):
tols = np.array([0.05,0.05,0.05, 0.005,0.005,0.005]*len(self.fowtList)) # create vector of tolerances - tol = 0.05 rtol = tol/10


'''Calculates mean offsets and linearized mooring properties for the current load case.
setEnv and calcSystemProps must be called first. This will ultimately become a method for solving mean operating point.
Mean offsets are saved in the FOWT object.
'''
'''Calculates mean offsets and linearized mooring properties for the
current load case. Methods setEnv and calcSystemProps must be called
first. This will ultimately become a method for solving mean
operating point. Mean offsets are saved in the FOWT object.
'''

def eval_func_equil(X, args):

Expand All @@ -656,25 +660,25 @@ def eval_func_equil(X, args):
Xi0 = X[6*i:6*i+6] - np.array([fowt.x_ref, fowt.y_ref,0,0,0,0]) # fowt mean offset from its reference position

# update FOWT hydrostatic loads
if statics_mod == 0 : # constant linear hydrostatics option
if self.staticsMod == 0 : # constant linear hydrostatics
Fnet[6*i:6*i+6] += F_undisplaced[6*i:6*i+6] # add original hydrostatics forces
Fnet[6*i:6*i+6] += -np.matmul(K_hydrostatic[i], Xi0) # use stiffness matrix to add hydrostatic reaction forces based on offsets
elif statics_mod == 1: # switch for whether to recompute hydrostatics
elif self.staticsMod == 1: # recompute hydrostatics
fowt.calcStatics()
Fnet[6*i:6*i+6] += fowt.W_struc # weight
Fnet[6*i:6*i+6] += fowt.W_hydro # buoyancy
#breakpoint()
else:
raise Exception('Invalid statics_mod value')
raise Exception('Invalid self.staticsMod value')


# if it's a loaded case, include mean environmental loads
if case: # <<<<<<

if forcing_mod == 0: # constant loads approach
if self.forcingMod == 0: # constant loads approach
Fnet[6*i:6*i+6] += F_env_constant[6*i:6*i+6]

elif forcing_mod == 1: # updated loads approach
elif self.forcingMod == 1: # updated loads approach

# If list of wind speeds, set each turbine case with corresponding wind speed
if type(caseorig['wind_speed']) == list :
Expand Down Expand Up @@ -738,7 +742,7 @@ def step_func_equil(X, args, Y, oths, Ytarget, err, tol_, iter, maxIter):
for i, fowt in enumerate(self.fowtList):
K6 = np.zeros([6,6])

if statics_mod == 0:
if self.staticsMod == 0:
K6 += K_hydrostatic[i]
else:
K6 += fowt.C_struc + fowt.C_hydro
Expand Down Expand Up @@ -1495,7 +1499,7 @@ def plot(self, ax=None, hideGrid=False, draw_body=True, color=None, nodes=0,
fig = ax.get_figure()
if self.ms:
self.ms.plot(ax=ax, **mp_args2)

# plot each FOWT
for fowt in self.fowtList:
fowt.plot(ax, color=color, zorder=zorder, nodes=nodes,
Expand Down

0 comments on commit e52ef2e

Please sign in to comment.