From 9fdc8ee272f66c6d03cf837b4d64bfb64607e1af Mon Sep 17 00:00:00 2001 From: Matt Hall <5151457+mattEhall@users.noreply.github.com> Date: Tue, 28 Jan 2025 12:35:35 -0700 Subject: [PATCH] moorMod is now stored outside of ms, and a couple other tweaks: - Moved the moorMod switch out of the MoorPy System object and into the RAFT objects to avoid burying it. - A couple adjustments for more consistent handling of cases whether a mooring section is provided in the RAFT input YAML. - This helps for a couple less typical use cases. --- raft/raft_fowt.py | 11 ++++++----- raft/raft_model.py | 38 +++++++++++++++++++------------------- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/raft/raft_fowt.py b/raft/raft_fowt.py index add13b9..d7a59bc 100644 --- a/raft/raft_fowt.py +++ b/raft/raft_fowt.py @@ -164,11 +164,11 @@ def __init__(self, design, w, mpb, depth=600, x_ref=0, y_ref=0, heading_adjust=0 self.body = mpb # reference to Body in mooring system corresponding to this turbine # this FOWT's own MoorPy system (may not be used) - if design['mooring']: + if 'mooring' in design: self.ms = mp.System() self.ms.parseYAML(design['mooring']) - self.ms.moorMod = getFromDict(design['mooring'], 'moorMod', default=0, dtype=int) + self.moorMod = getFromDict(design['mooring'], 'moorMod', default=0, dtype=int) # ensure proper setup with one coupled Body tied to this FOWT if len(self.ms.bodyList) == 0: @@ -189,6 +189,7 @@ def __init__(self, design, w, mpb, depth=600, x_ref=0, y_ref=0, heading_adjust=0 else: self.ms = None + self.moorMod = 0 self.F_moor0 = np.zeros(6) # mean mooring forces in a given scenario self.C_moor = np.zeros([6,6]) # mooring stiffness matrix in a given scenario @@ -286,9 +287,9 @@ def setPosition(self, r6): # solve the mooring system equilibrium of this FOWT's own MoorPy system if self.ms: self.ms.solveEquilibrium() - if self.ms.moorMod == 0 or self.ms.moorMod == 2: + if self.moorMod == 0 or self.moorMod == 2: C_moor = self.ms.getCoupledStiffnessA(lines_only=True) - elif self.ms.moorMod == 1: + elif self.moorMod == 1: self.ms.updateSystemDynamicMatrices() _, _, _, C_moor = self.ms.getCoupledDynamicMatrices(lines_only=True) @@ -2025,7 +2026,7 @@ def saveTurbineOutputs(self, results, case): T_moor_std = np.zeros([2*nLines], dtype=float) C_moor, J_moor = self.ms.getCoupledStiffness(lines_only=True, tensions=True) # get stiffness matrix and tension jacobian matrix T_moor = self.ms.getTensions() # get line end mean tensions - if self.ms.moorMod == 0: + if self.moorMod == 0: for ih in range(self.nWaves+1): for iw in range(self.nw): T_moor_amps[ih,:,iw] = np.matmul(J_moor, self.Xi[ih,:,iw]) # FFT of mooring tensions diff --git a/raft/raft_model.py b/raft/raft_model.py index a615f0d..77f478a 100644 --- a/raft/raft_model.py +++ b/raft/raft_model.py @@ -102,7 +102,7 @@ def __init__(self, design, nTurbines=1): else: raise Exception("When using 'array_mooring', a MoorDyn-style input file must be provided as 'file'.") - self.ms.moorMod = getFromDict(design['array_mooring'], 'moorMod', default=0, dtype=int) + self.moorMod = getFromDict(design['array_mooring'], 'moorMod', default=0, dtype=int) else: self.ms = None @@ -211,9 +211,9 @@ def analyzeUnloaded(self, ballast=0, heave_tol = 1): if self.ms: try: - if self.ms.moorMod == 0 or self.ms.moorMod == 2: + if self.moorMod == 0 or self.moorMod == 2: C_moor = self.ms.getCoupledStiffness(lines_only=True) - elif self.ms.moorMod == 1: + elif self.moorMod == 1: self.ms.updateLumpedMassSystem() _, _, _, C_moor = self.ms.getCoupledDynamicMatrices(lines_only=True) @@ -224,9 +224,9 @@ def analyzeUnloaded(self, ballast=0, heave_tol = 1): if self.fowtList[0].ms: try: - if self.fowtList[0].ms.moorMod == 0 or self.fowtList[0].ms.moorMod == 2: + if self.fowtList[0].moorMod == 0 or self.fowtList[0].moorMod == 2: C_moor = self.fowtList[0].ms.getCoupledStiffness(lines_only=True) - elif self.fowtList[0].ms.moorMod == 1: + elif self.fowtList[0].moorMod == 1: self.fowtList[0].ms.updateSystemDynamicMatrices() _, _, _, C_moor = self.fowtList[0].ms.getCoupledDynamicMatrices(lines_only=True) @@ -377,7 +377,7 @@ def analyzeCases(self, display=0, meshDir=os.path.join(os.getcwd(),'BEM'), RAO_p T_moor = self.ms.getTensions() # get line end mean tensions - if self.ms.moorMod == 0: + if self.moorMod == 0: for ih in range(nWaves+1): for iw in range(self.nw): T_moor_amps[ih,:,iw] = np.matmul(J_moor, self.Xi[ih,:,iw]) # FFT of mooring tensions @@ -461,9 +461,9 @@ def solveEigen(self, display=0): # include array-level mooring stiffness if self.ms: - if self.ms.moorMod == 0 or self.ms.moorMod == 2: + if self.moorMod == 0 or self.moorMod == 2: C_moor = self.ms.getCoupledStiffnessA(lines_only=True) - elif self.ms.moorMod == 1: + elif self.moorMod == 1: self.ms.updateSystemDynamicMatrices() _, _, _, C_moor = self.ms.getCoupledDynamicMatrices(lines_only=True) C_tot += C_moor @@ -732,9 +732,9 @@ def step_func_equil(X, args, Y, oths, Ytarget, err, tol_, iter, maxIter): # add array mooring system stiffness (if applicable) if self.ms: - if self.ms.moorMod == 0 or self.ms.moorMod == 2: + if self.moorMod == 0 or self.moorMod == 2: Kmoor = self.ms.getCoupledStiffnessA(lines_only=True) - elif self.ms.moorMod == 1: + elif self.moorMod == 1: self.ms.updateSystemDynamicMatrices() _, _, _, Kmoor = self.ms.getCoupledDynamicMatrices(lines_only=True) @@ -752,9 +752,9 @@ def step_func_equil(X, args, Y, oths, Ytarget, err, tol_, iter, maxIter): if fowt.ms: if fowt.ms: fowt.ms.solveEquilibrium() - if fowt.ms.moorMod == 0 or fowt.ms.moorMod == 2: + if fowt.moorMod == 0 or fowt.moorMod == 2: Kmoor_fowt = fowt.ms.getCoupledStiffnessA(lines_only=True) - elif fowt.ms.moorMod == 1: + elif fowt.moorMod == 1: fowt.ms.updateSystemDynamicMatrices() _, _, _, Kmoor_fowt = fowt.ms.getCoupledDynamicMatrices(lines_only=True) K6 += Kmoor_fowt @@ -961,12 +961,12 @@ def solveDynamics(self, case, tol=0.01, conv_plot=0, RAO_plot=0, display=0): # We would need to pass the motions of the extremities of the mooring lines within getCoupledDynamicMatrices # I think this would be straightforward for lines connecting the fairlead to the anchor, but not sure about cases with buoys M_moor, A_moor, B_moor, C_moor = (np.zeros([6,6]) for _ in range(4)) - if not fowt.ms or fowt.ms.moorMod == 0: + if not fowt.ms or fowt.moorMod == 0: C_moor = fowt.C_moor - elif fowt.ms.moorMod == 1: + elif fowt.moorMod == 1: fowt.updateMooringDynamicMatrices(XiLast, fowt.S[0,:]) M_moor, A_moor, B_moor, C_moor = fowt.ms.getCoupledDynamicMatrices(lines_only=True) - elif fowt.ms.moorMod == 2: + elif fowt.moorMod == 2: C_moor = fowt.C_moor fowt.updateMooringDynamicMatrices(XiLast, fowt.S[0,:]) M_moor, A_moor, B_moor, _ = fowt.ms.getCoupledDynamicMatrices(lines_only=True) @@ -1007,7 +1007,7 @@ def solveDynamics(self, case, tol=0.01, conv_plot=0, RAO_plot=0, display=0): # Recompute mooring damping matrix as it depends on body motions (linearization of drag lods). The other matrices are kept the same. # Note: Is it worth recomputing the mooring damping matrix at each step? The impact of mooring damping on body dynamics is small, and the motion # RAOs are probably not changing much. Perhaps compute this only once and keep it constant? - if fowt.ms and (fowt.ms.moorMod == 1 or fowt.ms.moorMod == 2): + if fowt.ms and (fowt.moorMod == 1 or fowt.moorMod == 2): fowt.updateMooringDynamicMatrices(XiLast, fowt.S[0,:]) _, _, B_moor, _ = fowt.ms.getCoupledDynamicMatrices(lines_only=True) @@ -1112,12 +1112,12 @@ def solveDynamics(self, case, tol=0.01, conv_plot=0, RAO_plot=0, display=0): # include array-level mooring stiffness if self.ms: M_moor, A_moor, B_moor, C_moor = (np.zeros([Z_sys.shape[0], Z_sys.shape[1]]) for _ in range(4)) - if self.ms.moorMod == 0: + if self.moorMod == 0: C_moor = self.ms.getCoupledStiffnessA(lines_only=True) - elif self.ms.moorMod == 1: + elif self.moorMod == 1: self.updateMooringDynamicMatrices(XiLast_all, self.fowtList[0].S[0,:]) M_moor, A_moor, B_moor, C_moor = self.ms.getCoupledDynamicMatrices(lines_only=True) - elif self.ms.moorMod == 2: + elif self.moorMod == 2: self.updateMooringDynamicMatrices(XiLast_all, self.fowtList[0].S[0,:]) C_moor = self.ms.getCoupledStiffnessA(lines_only=True) M_moor, A_moor, B_moor, _ = self.ms.getCoupledDynamicMatrices(lines_only=True)