Python external function examples: Vessel clearance external result

This topic is intended to be read in conjunction with the main external function documentation, and the example source code.

This ZIP file contains all of the Python external function examples, with each example contained in the appropriately named sub-folder.

This example calculates three external results for the global X, Y and Z position difference between a specified position on a vessel and a specified position on another model object.

The external function is set as a globally applied load on a vessel, although the function class does not implement a Calculate() method and so has no effect on the vessel motion. The example demonstrates how to register multiple results from an external function and how to log data required for those results and then return the appropriate result values when requested by OrcaFlex.

This example comprises OrcaFlex file VesselClearanceExternalResult.dat and Python script VesselClearanceExternalResult.py.

To calculate the results, the function needs to know in advance the clearance objects and the body positions on the vessel and the clearance objects so that the necessary global position data can be logged during the simulation. The function allows for several clearance objects and body positions to be specified. In the example model, the object tags for Vessel1 specify two position pairs, named ShapeClearance and BuoyClearance. When requesting the external result, the ObjectExtra.ExternalResultText property should contain one of these names (either Shape or Buoy) to specify which set of positions to base the results on.

The text format used in this example is JSON (Javascript Object Notation). Python has a built in module, json, for reading and writing Python types to string and back and it is a convenient way to format the parameters without having to implement a lot of your own code to convert between text and Python values.

The Initialise method in the external function reads the tags and converts the text data to Python types. The body position data is stored in a dictionary (self.clearanceObjects) of ObjectBodyPosition instances (a helper class).

The RegisterResults method returns details of the results calculated by this external function to OrcaFlex by setting the info.ExternalResults property. The result details are returned as an array of dictionaries, one dictionary for each result. The data required to register a result is explained here.

When the simulation is running, at every log sample interval the LogResult method will be called. This gives our external function a chance to retrieve instantaneous results from OrcaFlex and perform any calculations required before logging this data with OrcaFlex. In this example we need to obtain the instantaneous global position data for each vessel body position and clearance object body position defined in the tags. Our log data is a dictionary of vessel / clearance object position tuples, keyed by the name given to the combination in the initialization parameters. This log data is returned as a string to OrcaFlex by setting the info.LogData property, again we use json as a convenient way to convert this data to text.

In this example we have only one instance of the external function, set for the Global Applied Force X for the vessel. If we had multiple instances, for example if our function actually modified the applied force in the X, Y and Z directions, then we want to avoid unnecessarily extracting and logging the same data more than once. To avoid this we test the info.DataName property before doing any logging.

Once the model is running dynamics, or the simulation has completed then the results we registered in RegisterResults will be available through the OrcaFlex results form. When selecting one of the custom results we need to specify which clearance object we want, we do this by providing one of the names we defined in the tags (either Shape or Buoy for this example) in the External result text field on the Select Results form in OrcaFlex. This will be passed to our external function in the info.ObjectExtra.ExternalResultText property in the call to our DeriveResult method when the external result is requested. The info.ResultID property will contain the requested result's ID we registered in RegisterResults, and the info.LogData property contains our logged data from the LogResult method.

Our DeriveResult method first converts the logged data string back to Python types using json.loads then looks up the required set of position data based on the value passed in info.ObjectExtra.ExternalResultText. Next we check the info.ResultID property to see which result value we need to return. The result value is returned by setting the info.Value property.