@@ -4447,27 +4447,36 @@ def mapRAFTResults(self, results=None, SFs=True):
44474447 if SFs :
44484448 for moor in self .mooringList .values ():
44494449 moor .safety_factors ['tension' ] = 1e10
4450-
4450+
4451+ # initialize raftResults dictionary in Line [Why isn't line an edge?]
4452+ for moor in self .mooringList .values ():
4453+ for line in moor .ss .lineList :
4454+ line .raftResults = {}
4455+
44514456 for iCase in range (nCases ):
44524457 i = 0
44534458 for moor in self .mooringList .values ():
4454- for line in moor .ss .lineList :
4455- line .raftResults = {
4456- 'Tmoor_avg' : self .array .results ['case_metrics' ][iCase ]['array_mooring' ]['Tmoor_avg' ][[i , i + len (self .ms .lineList )]],
4457- 'Tmoor_std' : self .array .results ['case_metrics' ][iCase ]['array_mooring' ]['Tmoor_std' ][[i , i + len (self .ms .lineList )]],
4458- 'Tmoor_min' : self .array .results ['case_metrics' ][iCase ]['array_mooring' ]['Tmoor_min' ][[i , i + len (self .ms .lineList )]],
4459- 'Tmoor_max' : self .array .results ['case_metrics' ][iCase ]['array_mooring' ]['Tmoor_max' ][[i , i + len (self .ms .lineList )]],
4460- 'Tmoor_PSD' : self .array .results ['case_metrics' ][iCase ]['array_mooring' ]['Tmoor_PSD' ][[i , i + len (self .ms .lineList )], :]
4461- }
4462- if SFs :
4463- moor .safety_factors ['tension' ] = min (moor .safety_factors ['tension' ], min (line .type ['MBL' ]/ line .raftResults ['Tmoor_max' ]))
4464- moor .safety_factors ['analysisType' ] = f'(RAFT) MoorMod={ self .array .moorMod } '
4459+ moor .raftResults [iCase ] = {
4460+ 'Tmoor_avg' : self .array .results ['case_metrics' ][iCase ]['array_mooring' ]['Tmoor_avg' ][[i , i + len (self .ms .lineList )]],
4461+ 'Tmoor_std' : self .array .results ['case_metrics' ][iCase ]['array_mooring' ]['Tmoor_std' ][[i , i + len (self .ms .lineList )]],
4462+ 'Tmoor_min' : self .array .results ['case_metrics' ][iCase ]['array_mooring' ]['Tmoor_min' ][[i , i + len (self .ms .lineList )]],
4463+ 'Tmoor_max' : self .array .results ['case_metrics' ][iCase ]['array_mooring' ]['Tmoor_max' ][[i , i + len (self .ms .lineList )]],
4464+ 'Tmoor_PSD' : self .array .results ['case_metrics' ][iCase ]['array_mooring' ]['Tmoor_PSD' ][[i , i + len (self .ms .lineList )], :]
4465+ }
4466+ if SFs :
4467+ SF = np .zeros ((len (moor .ss .lineList )))
4468+ for i , line in enumerate (moor .ss .lineList ):
4469+ line_MBL = line .type ['MBL' ]
4470+ SF [i ] = line_MBL / np .mean (moor .raftResults [iCase ]['Tmoor_avg' ])
4471+
4472+ moor .safety_factors ['tension' ] = min ([moor .safety_factors ['tension' ], min (SF )])
4473+ moor .safety_factors ['analysisType' ] = f'(RAFT) MoorMod={ self .array .moorMod } '
44654474
44664475 i += 1
44674476
44684477 def generateSheets (self , filename ):
44694478 """
4470- Generates sheets in an Excel workbook with platform and mooring line information.
4479+ Generates sheets in an Excel workbook with RAFT cases, platform, and mooring line information.
44714480
44724481 Parameters
44734482 ----------
@@ -4480,7 +4489,32 @@ def generateSheets(self, filename):
44804489
44814490 """
44824491
4492+ def style_it (sheet , row , col_start , col_end , fill_color = "FFFF00" ):
4493+ """
4494+ Applies styling to a range of cells in the given sheet.
4495+
4496+ Parameters
4497+ ----------
4498+ sheet : openpyxl.worksheet.worksheet.Worksheet
4499+ The worksheet to apply styling to.
4500+ row : int
4501+ The row number to apply styling to.
4502+ col_start : int
4503+ The starting column number for the range.
4504+ col_end : int
4505+ The ending column number for the range.
4506+
4507+ Returns
4508+ -------
4509+ None
4510+ """
4511+ for col in range (col_start , col_end + 1 ):
4512+ cell = sheet .cell (row = row , column = col )
4513+ cell .fill = openpyxl .styles .PatternFill (start_color = fill_color , end_color = fill_color , fill_type = "solid" )
4514+ cell .font = openpyxl .styles .Font (bold = True )
4515+
44834516 import openpyxl
4517+ from openpyxl .drawing .image import Image
44844518
44854519 if not self .array .results :
44864520 if not self .array .design ['cases' ]:
@@ -4496,33 +4530,121 @@ def generateSheets(self, filename):
44964530 default_sheet = workbook .active
44974531 workbook .remove (default_sheet )
44984532
4533+ if self .array .design :
4534+ # Create a sheet for cases information
4535+ cases_sheet = workbook .create_sheet (title = "Cases" )
4536+ cases_sheet .append (self .array .design ['cases' ]['keys' ])
4537+ for iCase in range (nCases ):
4538+ cases_sheet .append (self .array .design ['cases' ]['data' ][iCase ])
4539+
44994540 # Create a sheet for platforms
45004541 platform_sheet = workbook .create_sheet (title = "Platforms" )
4501- platform_sheet .append (["ID" , "X" , "Y" , "Depth" , "Case" , "Results (Avg)" ])
4542+ platform_sheet .append (["ID" , "X" , "Y" , "Depth" , "Case" , "Results (Avg)" , " " , " " , " " , " " , " " , " " , " " , "Results (Std)" ])
45024543 platform_sheet .merge_cells (start_row = 1 , start_column = 6 , end_row = 1 , end_column = 13 )
4503- platform_sheet .append ([" " , " " , " " , " " , " " , "Surge (m)" , "Sway (m)" , "Heave (m)" , "Roll (deg)" , "Pitch (deg)" , "Yaw (deg)" , "NacAcc (m/s^2)" , "TwrBend (Nm)" ]) #, "RtrSpd (RPM)", "RtrTrq (Nm)", "Power (MW)"
4544+ platform_sheet .merge_cells (start_row = 1 , start_column = 14 , end_row = 1 , end_column = 21 )
4545+ platform_sheet .append ([" " , " " , " " , " " , " " ,
4546+ "Surge (m)" , "Sway (m)" , "Heave (m)" , "Roll (deg)" , "Pitch (deg)" , "Yaw (deg)" , "NacAcc (m/s^2)" , "TwrBend (kNm)" , #, "RtrSpd (RPM)", "RtrTrq (Nm)", "Power (MW)"
4547+ "Surge (m)" , "Sway (m)" , "Heave (m)" , "Roll (deg)" , "Pitch (deg)" , "Yaw (deg)" , "NacAcc (m/s^2)" , "TwrBend (kNm)" ]) #, "RtrSpd (RPM)", "RtrTrq (Nm)", "Power (MW)"
4548+ platform_sheet .merge_cells (start_row = 1 , start_column = 1 , end_row = 2 , end_column = 1 )
4549+ platform_sheet .merge_cells (start_row = 1 , start_column = 2 , end_row = 2 , end_column = 2 )
4550+ platform_sheet .merge_cells (start_row = 1 , start_column = 3 , end_row = 2 , end_column = 3 )
4551+ platform_sheet .merge_cells (start_row = 1 , start_column = 4 , end_row = 2 , end_column = 4 )
4552+ platform_sheet .merge_cells (start_row = 1 , start_column = 5 , end_row = 2 , end_column = 5 )
4553+ surgeMax = float ('-inf' )
4554+ swayMax = float ('-inf' )
4555+ rollMax = float ('-inf' )
4556+ pitchMax = float ('-inf' )
4557+ nacAccMax = float ('-inf' )
4558+ twrBendMax = float ('-inf' )
45044559 for pf in self .platformList .values ():
45054560 depth_at_pf = self .getDepthAtLocation (pf .r [0 ], pf .r [1 ])
45064561 if hasattr (pf , 'raftResults' ):
45074562 for iCase in range (nCases ):
45084563 if iCase == 0 :
4509- platform_sheet .append ([pf .id , round (pf .r [0 ], 2 ), round (pf .r [1 ], 2 ), round (depth_at_pf , 2 ), iCase ,
4510- round (pf .raftResults [iCase ]['surge_avg' ], 2 ), round (pf .raftResults [iCase ]['sway_avg' ], 2 ), round (pf .raftResults [iCase ]['heave_avg' ], 2 ),
4511- round (pf .raftResults [iCase ]['roll_avg' ], 2 ), round (pf .raftResults [iCase ]['pitch_avg' ], 2 ), round (pf .raftResults [iCase ]['yaw_avg' ], 2 ),
4512- round (pf .raftResults [iCase ]['AxRNA_avg' ][0 ], 2 ), round (pf .raftResults [iCase ]['Mbase_avg' ][0 ], 2 )]) #, round(pf.raftResults[iCase]['omega_avg'][0], 2), round(pf.raftResults[iCase]['torque_avg'][0], 2), round(pf.raftResults[iCase]['power_avg'][0]*1e-6, 2)])
4564+ platform_sheet .append ([pf .id , round (pf .r [0 ], 3 ), round (pf .r [1 ], 3 ), round (depth_at_pf , 3 ), iCase ,
4565+ round (pf .raftResults [iCase ]['surge_avg' ], 3 ), round (pf .raftResults [iCase ]['sway_avg' ], 3 ), round (pf .raftResults [iCase ]['heave_avg' ], 3 ),
4566+ round (pf .raftResults [iCase ]['roll_avg' ], 3 ), round (pf .raftResults [iCase ]['pitch_avg' ], 3 ), round (pf .raftResults [iCase ]['yaw_avg' ], 3 ),
4567+ round (pf .raftResults [iCase ]['AxRNA_avg' ][0 ], 3 ), round (pf .raftResults [iCase ]['Mbase_avg' ][0 ]/ 1e3 , 3 ), #, round(pf.raftResults[iCase]['omega_avg'][0], 3), round(pf.raftResults[iCase]['torque_avg'][0], 3), round(pf.raftResults[iCase]['power_avg'][0]*1e-6, 3)])
4568+ round (pf .raftResults [iCase ]['surge_std' ], 3 ), round (pf .raftResults [iCase ]['sway_std' ], 3 ), round (pf .raftResults [iCase ]['heave_std' ], 3 ),
4569+ round (pf .raftResults [iCase ]['roll_std' ], 3 ), round (pf .raftResults [iCase ]['pitch_std' ], 3 ), round (pf .raftResults [iCase ]['yaw_std' ], 3 ),
4570+ round (pf .raftResults [iCase ]['AxRNA_std' ][0 ], 3 ), round (pf .raftResults [iCase ]['Mbase_std' ][0 ]/ 1e3 , 3 )]) #, round(pf.raftResults[iCase]['omega_avg'][0], 3), round(pf.raftResults[iCase]['torque_avg'][0], 3), round(pf.raftResults[iCase]['power_avg'][0]*1e-6, 3)])
45134571 else :
45144572 platform_sheet .append ([" " , " " , " " , " " , iCase ,
4515- round (pf .raftResults [iCase ]['surge_avg' ], 2 ), round (pf .raftResults [iCase ]['sway_avg' ], 2 ), round (pf .raftResults [iCase ]['heave_avg' ], 2 ),
4516- round (pf .raftResults [iCase ]['roll_avg' ], 2 ), round (pf .raftResults [iCase ]['pitch_avg' ], 2 ), round (pf .raftResults [iCase ]['yaw_avg' ], 2 ),
4517- round (pf .raftResults [iCase ]['AxRNA_avg' ][0 ], 2 ), round (pf .raftResults [iCase ]['Mbase_avg' ][0 ], 2 )]) #, round(pf.raftResults[iCase]['omega_avg'][0], 2), round(pf.raftResults[iCase]['torque_avg'][0], 2), round(pf.raftResults[iCase]['power_avg'][0]*1e-6, 2)])
4573+ round (pf .raftResults [iCase ]['surge_avg' ], 3 ), round (pf .raftResults [iCase ]['sway_avg' ], 3 ), round (pf .raftResults [iCase ]['heave_avg' ], 3 ),
4574+ round (pf .raftResults [iCase ]['roll_avg' ], 3 ), round (pf .raftResults [iCase ]['pitch_avg' ], 3 ), round (pf .raftResults [iCase ]['yaw_avg' ], 3 ),
4575+ round (pf .raftResults [iCase ]['AxRNA_avg' ][0 ], 3 ), round (pf .raftResults [iCase ]['Mbase_avg' ][0 ]/ 1e3 , 3 ), #, round(pf.raftResults[iCase]['omega_avg'][0], 3), round(pf.raftResults[iCase]['torque_avg'][0], 3), round(pf.raftResults[iCase]['power_avg'][0]*1e-6, 3)])
4576+ round (pf .raftResults [iCase ]['surge_std' ], 3 ), round (pf .raftResults [iCase ]['sway_std' ], 3 ), round (pf .raftResults [iCase ]['heave_std' ], 3 ),
4577+ round (pf .raftResults [iCase ]['roll_std' ], 3 ), round (pf .raftResults [iCase ]['pitch_std' ], 3 ), round (pf .raftResults [iCase ]['yaw_std' ], 3 ),
4578+ round (pf .raftResults [iCase ]['AxRNA_std' ][0 ], 3 ), round (pf .raftResults [iCase ]['Mbase_std' ][0 ]/ 1e3 , 3 )]) #, round(pf.raftResults[iCase]['omega_avg'][0], 3), round(pf.raftResults[iCase]['torque_avg'][0], 3), round(pf.raftResults[iCase]['power_avg'][0]*1e-6, 3)])
4579+ # Update min and max values
4580+ surgeMax = max (surgeMax , abs (pf .raftResults [iCase ]['surge_avg' ])); swayMax = max (swayMax , abs (pf .raftResults [iCase ]['sway_avg' ]))
4581+ rollMax = max (rollMax , abs (pf .raftResults [iCase ]['roll_avg' ])); pitchMax = max (pitchMax , abs (pf .raftResults [iCase ]['pitch_avg' ]))
4582+ nacAccMax = max (nacAccMax , abs (pf .raftResults [iCase ]['AxRNA_avg' ][0 ])); twrBendMax = max (twrBendMax , abs (pf .raftResults [iCase ]['Mbase_avg' ][0 ]/ 1e3 ))
4583+
4584+ platform_sheet .merge_cells (start_row = platform_sheet .max_row - nCases + 1 , start_column = 1 , end_row = platform_sheet .max_row , end_column = 1 )
4585+ platform_sheet .merge_cells (start_row = platform_sheet .max_row - nCases + 1 , start_column = 2 , end_row = platform_sheet .max_row , end_column = 2 )
4586+ platform_sheet .merge_cells (start_row = platform_sheet .max_row - nCases + 1 , start_column = 3 , end_row = platform_sheet .max_row , end_column = 3 )
4587+ platform_sheet .merge_cells (start_row = platform_sheet .max_row - nCases + 1 , start_column = 4 , end_row = platform_sheet .max_row , end_column = 4 )
45184588 else :
4519- platform_sheet .append ([pf .id , round (pf .r [0 ], 2 ), round (pf .r [1 ], 2 ), round (depth_at_pf , 2 )])
4589+ platform_sheet .append ([pf .id , round (pf .r [0 ], 3 ), round (pf .r [1 ], 3 ), round (depth_at_pf , 3 )])
4590+
4591+ platform_sheet .append (["----------------------" ])
4592+ platform_sheet .append (["Highest average values" ])
4593+ for cell in platform_sheet [platform_sheet .max_row ]:
4594+ cell .font = openpyxl .styles .Font (bold = True )
4595+
4596+ platform_sheet .append (["Surge (m)" , "Sway (m)" , "Roll (deg)" , "Pitch (deg)" , "NacAcc (m/s^2)" , "TwrBend (Nm)" ])
4597+ platform_sheet .append ([round (surgeMax , 3 ), round (swayMax , 3 ), round (rollMax , 3 ), round (pitchMax , 3 ), round (nacAccMax , 3 ), round (twrBendMax , 3 )])
4598+ # style maximum values (bold and italic)
4599+ for cell in platform_sheet [platform_sheet .max_row ]:
4600+ cell .font = openpyxl .styles .Font (bold = True , italic = True )
45204601
45214602 # Create a sheet for mooring lines
45224603 mooring_sheet = workbook .create_sheet (title = "Mooring Lines" )
4523- mooring_sheet .append (["ID" , "endA" , "endB" , "Shrd" , "Safety Factors" , "Fid Level" ])
4604+ mooring_sheet .append (["ID" , "endA" , "endB" , "Shrd" , "Safety Factors" , "Fid Level" , "Case" , "Avg EndA Tension (kN)" , "Std EndA Tension (kN)" , "Avg EndB Tension (kN)" , "Std EndB Tension (kN) " ])
45244605 for moor in self .mooringList .values ():
4525- mooring_sheet .append ([moor .id , moor .attached_to [0 ].id , moor .attached_to [1 ].id , moor .shared , round (moor .safety_factors ['tension' ], 2 ), moor .safety_factors ['analysisType' ]])
4606+ if hasattr (moor , 'raftResults' ):
4607+ for iCase in range (nCases ):
4608+ if iCase == 0 :
4609+ mooring_sheet .append ([moor .id , moor .attached_to [0 ].id , moor .attached_to [1 ].id , moor .shared , round (moor .safety_factors ['tension' ], 3 ), moor .safety_factors ['analysisType' ], iCase ,
4610+ round (moor .raftResults [iCase ]['Tmoor_avg' ][0 ], 3 )/ 1e3 , round (moor .raftResults [iCase ]['Tmoor_std' ][0 ], 3 )/ 1e3 ,
4611+ round (moor .raftResults [iCase ]['Tmoor_avg' ][1 ], 3 )/ 1e3 , round (moor .raftResults [iCase ]['Tmoor_std' ][1 ], 3 )/ 1e3 ])
4612+ if moor .safety_factors ['tension' ]< 2.0 :
4613+ style_it (mooring_sheet , mooring_sheet .max_row , 1 , 6 , fill_color = "FF0000" )
4614+
4615+ else :
4616+ mooring_sheet .append ([" " , " " , " " , " " , " " , " " , iCase ,
4617+ round (moor .raftResults [iCase ]['Tmoor_avg' ][0 ], 3 )/ 1e3 , round (moor .raftResults [iCase ]['Tmoor_std' ][0 ], 3 )/ 1e3 ,
4618+ round (moor .raftResults [iCase ]['Tmoor_avg' ][1 ], 3 )/ 1e3 , round (moor .raftResults [iCase ]['Tmoor_std' ][1 ], 3 )/ 1e3 ])
4619+ if np .any (moor .raftResults [iCase ]['Tmoor_avg' ]/ 1e3 < 100 ):
4620+ style_it (mooring_sheet , mooring_sheet .max_row , 7 , mooring_sheet .max_column , fill_color = "FFFF00" )
4621+ mooring_sheet .merge_cells (start_row = mooring_sheet .max_row - nCases + 1 , start_column = 1 , end_row = mooring_sheet .max_row , end_column = 1 )
4622+ mooring_sheet .merge_cells (start_row = mooring_sheet .max_row - nCases + 1 , start_column = 2 , end_row = mooring_sheet .max_row , end_column = 2 )
4623+ mooring_sheet .merge_cells (start_row = mooring_sheet .max_row - nCases + 1 , start_column = 3 , end_row = mooring_sheet .max_row , end_column = 3 )
4624+ mooring_sheet .merge_cells (start_row = mooring_sheet .max_row - nCases + 1 , start_column = 4 , end_row = mooring_sheet .max_row , end_column = 4 )
4625+ mooring_sheet .merge_cells (start_row = mooring_sheet .max_row - nCases + 1 , start_column = 5 , end_row = mooring_sheet .max_row , end_column = 5 )
4626+ mooring_sheet .merge_cells (start_row = mooring_sheet .max_row - nCases + 1 , start_column = 6 , end_row = mooring_sheet .max_row , end_column = 6 )
4627+ else :
4628+ mooring_sheet .append ([moor .id , moor .attached_to [0 ].id , moor .attached_to [1 ].id , moor .shared , round (moor .safety_factors ['tension' ], 3 ), moor .safety_factors ['analysisType' ]])
4629+
4630+ # Create a sheet for a 2D Plot
4631+ plot_sheet_2D = workbook .create_sheet (title = "2D Plot" )
4632+ fig , ax = plt .subplots ()
4633+ ax = self .plot2d (ax = ax , plot_boundary = False , plot_bathymetry = True )
4634+ filenameFolder = os .path .dirname (filename )
4635+ imagePath = os .path .join (filenameFolder , 'temp_plot_2D.png' )
4636+ fig .savefig (imagePath , dpi = 300 )
4637+ img = Image (imagePath )
4638+ plot_sheet_2D .add_image (img , 'A1' )
4639+
4640+ # Create a sheet for a 3D Plot
4641+ plot_sheet_3D = workbook .create_sheet (title = "3D Plot" )
4642+ fig , ax = plt .subplots (subplot_kw = {'projection' : '3d' })
4643+ ax = self .plot3d (ax = ax , fowt = True , draw_boundary = True , boundary_on_bath = True , draw_bathymetry = True )
4644+ imagePath = os .path .join (filenameFolder , 'temp_plot_3D.png' )
4645+ fig .savefig (imagePath , dpi = 300 )
4646+ img = Image (imagePath )
4647+ plot_sheet_3D .add_image (img , 'A1' )
45264648
45274649 # Save the workbook
45284650 workbook .save (filename )
0 commit comments