Systematic series are useful when optimising a hull form. Maxsurf includes a powerful tool for parametrically transforming a hull form to have slightly different parameters. In this example we develop a program to create a series of eight hull forms with varying parameters. The hull forms could then be imported into Seakeeper or Hullspeed for analysis and comparison. In the future, automation will also be available for Seakeeper and Hullspeed. This will allow you to fully exploit the advantages of using automation.
This example has been designed to work for any design, however, parametric transformations work best on plain hull forms, rather than designs with appendages. For best results with designs including appendages, turn the appendage surfaces off before transforming.
The example is divided into several sub procedures, some of which are activated from buttons in the Excel sheet; some are activated by calls from other procedures. An overview of the process used by this macro is shown in Figure 14
.
Figure 14 The Process for Creating A Systematic Series
Resources
The Excel File with this example is located in C:\Program Files\Maxsurf\ Automation Samples\Maxsurf\SystematicSeries.xls, or in the Maxsurf install directory.
The Excel file has some headings and formatting included already, creating the layout will not be discussed in this Manual.
The Parent hull form is loaded into Maxsurf using a dialog box to allow the user to select the file. The dialog box is part of the Excel method Application.GetOpenFilename. The procedure is activated using a button in the spreadsheet.
To create buttons, use the Command Button on the Control Toolbox Menu bar. The most left hand button toggles between design mode (for editing buttons) and exit design mode, for executing buttons.

Figure 15 The Command Button Button on the Control Toolbox Menu Bar.
The Command Button is linked to a procedure by changing the name to something appropriate, and then creating a procedure of the same name followed by _Click(). For Example, the Button to Load the parent hull form is named GetParentHull, the procedure is called
Sub GetParentHull_Click()
The name of the Command button can be set in Excel using the properties dialog, accessed from the Control Toolbox menu. The properties can also be set from the VB editor.
The Open File Dialog box is brought up using a similar code to that shown on page 36, Basic Operations. The code used in this example writes the filename to a cell in Excel, so that other procedures can easily access the file name.
Dim Filter As String
Dim FileName As String
Filter = "Maxsurf Design File (*.msd), *msd"
'The Filter only allows certain file types to be loaded
FileName = Application.GetOpenFilename(Filter, , "Open Maxsurf File", , False)
The filter defines the visible file types in the Open File dialog box. This code will store the name of the File to be opened in the Variable FileName. If the Cancel button is pressed in the dialog, the word “FALSE” will be stored in the variable FileName.
Before we open the File, we need to check for an error (For example, when the cancel button has been clicked). If it has, we can’t open the file. The following section of code will load the design if one has been specified, or exit if not.
If FileName = "False" Then
Exit Sub
Else
Range("D7") = FileName
msApp.Design.Open FileName, False, False
msApp.Refresh
End If
End Sub
These segments of code, when combined, will open a Maxsurf File, according to what is selected in the Dialog box. This is a useful piece of generic code that can be applied to most automation files.
To create a systematic series, we want to take the current hydrostatics and transform the hull to have slightly different parameters. So to create the series, we need to read in the current Hydrostatic Data, define which parameters we would like to change and how much we would like to change them and then perform the transformation.
The macro that creates the series uses a set of nested For Next loops to test all the options. In the middle of the nested For Next loops is a call to ParaTransform. This sub procedure reads in the target Cb, LWL and Draft values and then performs the parametric transformation. The Call to ParaTransform will take place 8 times, creating the eight different hull forms.
Sub CreateSeries_Click()
Dim msDesign As Maxsurf.Design
Set msDesign = msApp.Design
Dim Cb As Double
Dim LWL As Double
Dim ImmersedDepth As Double
Call OpenFile
Call CalcHydrostatics("L10")
'Chr(67) represents the letter C
z = 67
For i = 0 To 1
Cb = Cells(12, 12) + Cells(11, 8 + i)
For j = 0 To 1
LWL = Cells(11, 12) + Cells(12, 8 + j)
For k = 0 To 1
ImmersedDepth = Cells(15, 12) + Cells(13, 8 + k)
Call ParaTransform(Cb, LWL, ImmersedDepth)
Call CalcHydrostatics(Chr(z) & "28")
z = z + 1
Next
Next
Next
MsgBox "Done"
End Sub
The cells referenced in this code are for the Hydrostatic data for the parent hull form, and the amount by which the hydrostatic data will change. The code makes calls to three different procedures, namely:
· OpenFile
· CalcHydrostatics
· ParaTransform
The call to CalcHydrostatics is made in two different locations. The call reads in a variable that specifies a cell in the worksheet. This cell is the upper most cell for the list of hydrostatic data to be written in.
This code could easily be modified to have more parameters or more hull forms in the series than one at each corner of the parametric space.
Note:
The hydrostatic calculations and parametric transformation include visible surfaces only. After the call to open the Parent File, a line of code could be included, to turn visibility of certain surfaces off.
The use of Hydrostatic Data has been described in this manual already, for more information on using it, see Tutorial Part 4: Calculating the Hydrostatics on page 31. The code in example has been designed to be applied anywhere in the spreadsheet, in this example it will be executed nine times.
The code makes a particular cell active (as specified by the input string), and then writes data to all the other cells relative to the active cell. The code reads as follows.
Sub CalcHydrostatics(StartCell As String)
'Calculate the Parent Hydrostatics and Display in the page
Dim msDesign As Maxsurf.Design
Set msDesign = msApp.Design
msApp.Trimming = True
With msDesign.Hydrostatics
msDesign.Hydrostatics.Calculate 1025, 2
'Select the top Cell of the row
Range((StartCell)).Activate
'Write Contents into Cells, relative to the active cell
'Giving relative positions makes alterations to the layout simple
ActiveCell = .Displacement
ActiveCell.Offset(1, 0) = .LWL
ActiveCell.Offset(2, 0) = .Cb
ActiveCell.Offset(3, 0) = .BeamWL
ActiveCell.Offset(4, 0) = .Draft
ActiveCell.Offset(5, 0) = .ImmersedDepth
ActiveCell.Offset(6, 0) = .Cm
ActiveCell.Offset(7, 0) = .Cp
ActiveCell.Offset(8, 0) = .Cwp
ActiveCell.Offset(9, 0) = _
(msDesign.FrameOfReference.FwdPerp - .LCB) / .LWL
ActiveCell.Offset(10, 0) = _
(msDesign.FrameOfReference.FwdPerp - .LCB) / .LWL
ActiveCell.Offset(11, 0) = .WSA
End With
End Sub
Because all cell references are relative, it can be used for any location in the work sheet. The code will also not require updating if changes are made to the worksheet layout.
The parametric transformation is done in a sub procedure that requires three variable inputs, the Block Coefficient, the Waterline Length and the Immersed Depth. The call to this procedure requires these three variables, as specified in the name of the transformation procedure:
Call ParaTransform(Cb, LWL, Draft)
The sub procedure name includes the three variable inputs and their type in the brackets.
Private Sub ParaTransform(Cb As Double, LWL As Double, Draft As Double)
The code that executes the transformation reads as follows:
Private Sub ParaTransform(Cb As Double, LWL As Double, Draft As Double)
Dim msDesign As Maxsurf.Design
Set msDesign = msApp.Design
Call OpenFile
msDesign.Hydrostatics.Transform _
Range("L18"), _
Cb, _
Range("L15"), _
Range("L10"), _
Draft, _
Range("L13"), _
LWL, _
True, _
True, _
False, _
False, _
True
The Range properties refer to the cells containing the Hydrostatic data in the Excel sheet. The second half of this procedure saves the transformed hull into a specified directory.
To save the file into a specified directory, we need to have that directory specified and have a different name for each different hull. The obvious name for each hull in the series is the values of the parameters that have been modified.
If the save directory has not been specified, a call is made to the sub procedure GetSaveFolder_click. This procedure will specify the directory to be saved into. Otherwise, the hull will be saved into the specified directory.
'Check if save directory exists.
'Separate the File Name from the end
k = InStrRev(Range("D8"), "\", -1, vbTextCompare)
If k < 1 Then 'No directory is specified
Call GetSaveFolder_click
k = InStrRev(Range("D8"), "\", -1, vbTextCompare)
End If
FolderPath = Left$(Range("D8"), k - 1)
'check if the save folder exists, if not, get a new one
If Dir(FolderPath, vbDirectory) = "" Then
Call GetSaveFolder_click
End If
msDesign.SaveAs Range("D8") & "_" & Round(Cb, 1) & "_" & Round(LWL, 1) & "_" & Round(ImmersedDepth, 1) & ".msd", True
'msDesign.ExportIGES Range("D8") & Round(Cb, 1) & "_" & Round(LWL, 1) & "_" & Round(Draft, 1) & ".igs"
msApp.Refresh
End Sub
The code for exporting IGES files has been included but commented out. Depending on the purpose of the files, IGES files may be more appropriate.
If a valid parent hull form has already been selected then it is unnecessary to bring up the Dialog box again. This procedure checks for the existence of a valid file by testing if the file name is present in the specified directory.
Sub OpenFile()
'Opens the named File
Dim FilePathName As Variant
Dim FilesInFolder As Variant
Dim Path As Variant
Dim PathSegments As Variant
FilePathName = Range("D7")
'Path Segments represent each folder name of the Path and File Name
PathSegments = Split(FilePathName, "\", , vbTextCompare)
'If there is are no "\"
If UBound(PathSegments) < 1 Then
Call GetParentHull_Click
Exit Sub
End If
'Path is the Folder Path
Path = PathSegments
ReDim Preserve Path(UBound(Path) - 1)
Path = Join(Path, "\")
'Join rejoins all the split segments.
FileName = PathSegments(UBound(PathSegments))
'All the design files in the Path Folder
FilesInFolder = Dir(Path & "\" & "*.msd")
'This loops through the names of all the files in the folder
'and compares to the FileName to be opened
While FilesInFolder <> ""
If FileName = FilesInFolder Then
'If the file is in the folder, it is opened
msApp.Design.Open FilePathName, False, False
Exit Sub
End If
FilesInFolder = Dir()
Wend
Call GetParentHull_Click
End Sub
If the parent hull file is not in the specified folder, this procedure makes a Call to another procedure, namely GetParentHull_Click. The Call method will run the named procedure and then return to this procedure.