Propwash Module
The aim of this page is to document the modifications necessary for the Propwash module within EFDC+.
Input files
The propwash module will require several input files to run. These will all be in the JSON format.
Other propwash parameters
Ship propeller data
Ship track data
Propwash Parameters
input file name: propwash_parms.inp
This input file contains some parameters related to the determination of some propwash velocity field size. I know Luis had determined some of these likely will not change but I think it would be best to have some flexibility if these need to be changed.
{
"mesh":
{
"num_axial_elems": 68,
"radial_elems_per_axial": 10
},
"parms":
{
"num_efflux_zone": 5,
"zone_flow_est": 15,
"established_flow": 50,
"efflux_mult": 0.35,
"flow_mult": 3.5,
"wash_mult": 200.0
}
}
!< @todo are these hardwired for all time?
integer(kind = rk4) :: total_r_elems ! number of elements in the r direction odd
integer(kind = rk4) :: half_r_elems ! half corresponds to r = 0
integer(kind = rk4) :: num_efflux_zone !< efflux zone number of x elements
integer(kind = rk4) :: zone_flow_est !< zone of flow establishment
integer(kind = rk4) :: established_flow !< zone of established flow
integer(kind = rk4) :: num_x !< total number of x elements
integer(kind = rk4) :: num_theta ! every 15 degrees in [0,345]
real(kind = rkd) :: efflux_mult !< multiplier for the size of the efflux zone
real(kind = rkd) :: flow_mult !< multiplier for the size of the flow establishment zone
real(kind = rkd) :: wash_mult !< multiplier to decide how long the propwash field is
Ship Propeller data
input name: propwash_propeller_data.inp
Proposed format for the ship propeller data
{
"all_ships" :
[
{
"ship_id" : 1234 ,
"ship_name" : "sample name",
"thrust_coeff" : 0.24 ,
"revolutions_per_min" : 2 ,
"prop_diameter" : 2.3,
"prop_hub_diameter" : 0.2 ,
"blade_area_ratio" : 0.6,
"pitch_ratio" : 0.9,
"num_blades" : 4,
"length": 40,
"power": 2000,
"max_draught": 4,
"min_draught": 3,
"gross_tonnage": 2000
},
{
"ship_id" : 5678,
"ship_name" : "another ship name",
"thrust_coeff" : 0.3,
"revolutions_per_min" : 3 ,
"prop_diameter" : 4.1,
"prop_hub_diameter" : 0.35,
"blade_area_ratio" : 0.75,
"pitch_ratio" : 0.9,
"num_blades" : 4,
"length": 40,
"power": 2000,
"max_draught": 4,
"min_draught": 3,
"gross_tonnage": 2000
},
]
}
An unlimited number of ships may be added to this input file. Dynamic array allocation will be based on the total number of ships inputted into this file.
The “ship_id' is an integer value that should uniquely identify the ship. We could change this into a string value if that is preferable. But it will just require additional care on the string handling.
All of these ships are placed into a ship type and all ships can be referenced from a global array of all the ships.
Units and precision specification for a given ship object:
Note, [units = n/a]
indicates there are no units for this property.
Ship Track Data
Input name: propwash_track_data.inp
We can approach tracking of the ships in several ways. One approach would be to have a single input file with all of the ship tracks. The JSON format of that file could look something like a series of ship_id objects containing an array of ship_position objects. Each ship_position object contains the x,y,z coordinates and time. I would imagine this file would be based on observational data for a system or specific by a user within EE. I think within EE, there should be some checks to make sure this track would be valid. Otherwise we could get into a situation where the boat may appear to be traveling over land as highlighted in the Figure below. We need to avoid the situation akin to the one shown in the Figure below.
To get the boat position between time stamps within EFDC+ linear interpolation between the positions will be required.
The ship track data can now handle multiple tracks per ship.
A simple example (with made up data values) to highlight the JSON structure is given below:
Units and precision specification for a given ship_position object:
Required Type/class Methods
Within the EFDC+ code I am organizing everything around a “ship class ”. Note, types and class may be used interchangeable throughout this discussion. That ship class looks like:
Position class:
Position Cell Class (extends position type)
Propeller class
Velocity field class:
Erosive flux class:
All tracks class:
The methods will be subroutines that act on the data within this ship class. Again, the conversion from typical object oriented terminology to Fortran specific terms may be used interchangeable, e.g., subroutine/method. The necessary subroutines we need for now are listed below.
init_propwash_data
Purpose: This should initialize necessary arrays for handling the propwash calculations. Should call the read data routines.
read_propeller_data
Input data: propeller_data
Purpose: Read in the propeller specific data for a given ship
read_ship_tracks
Input data: ship_track
Purpose: Read in the ship tracks array into a global array of ship_track objects.
broadcast_ship_tracks
Purpose: Send out the ship track data from master to all processes.
output_ship_data
Purpose: Write out any relevant data on the ship or propwash that might be relevant. Could put the total erosive flux and other calculated parameters necessary for debugging?
Other data we want to analyze with EE?
get_current_position
Purpose: Get the current position of the ship. This should be based on the ship track that is read in from a file. May require calling the interpolate_position subroutine to get the position between time stamps. Should check that the
interpolate_position
Purpose: Interpolate the position of the ship if the current simulation time is between time stamps. Should put a check on if an interpolation is necessary and/or setup a threshold value for interpolating between values since the time steps might be really small compared to the speed of the boat and recomputing the interpolation may be unnecessary.
calculate_velocity_field
Purpose: calculates the propwash velocity field from the ship based on the work Luis has done. This sets up the sub-grid cells that will be projected onto the EFDC+ large scale grid cells.
determine_bed_intersection
Purpose: determine which cells intersect the calculated propwash velocity field.
determine_resultant_velocity
Purpose: Determine the resultant velocity between the sub-grid propwash cells and interpolated large scale velocity (from the normal EFDC+ hydrodynamics.
calculate_erosive_flux
Purpose: Determine the erosive flux using the resultant velocity at each sub-grid cell.
update_global_erosive_flux
Purpose: Determine the total erosive flux for the cell and update the global erosive flux
communicate_across_domains
Purpose: Communicate and track a ship when it reaches a ghost cell of the current sub-domain.
Ship heading
To determine the heading angle in the 2D I/J or X/Y space everything is based off of the positive x-axis and angles are counterclockwise from that. This is illustrated below for two different hypothetical tracks.