Axis systems are right-handed.
In the global axis system the Z-axis points up.
The mean sea-surface is defined as Z=0
The default unit system is m, kN, mT (metric tonne). G and RHO are defined accordingly.
Unfortunately there is no standard way of defining rotations in 3D.
DAVE uses a rotation vector to represent rotations. This means that the rotation is defined as a vector with three components (rx,ry,rz). The magnitude of the vector is the rotation in degrees. The axis of rotation is the direction of the vector.
(0,0,90): A rotation of 90 degrees about the Z-axis
(0,-10,0): A rotation of -10 degrees about the Y-axis
(10,10,0): A rotation of sqrt(10^2 + 10^2) about the (1,1,0) axis.
Hint: If euler angles are needed then axis systems can be stacked to obtain the same result.
The following 2D rotations are available: tilt_x, tilt_y, heel, trim, heading and heading_compass. These are derived from the projection of one of the local axis onto the global axis system. For example the tilt about the x-axis is derived from the z-component of the y-axis.
A 3d rotation of (5,0,0) will give a heel of 5 degrees and a tilt_x of 8.7% A 3d rotation of (0,0,120) will give a heading of 120 degrees and a heading_compass of 330.
Filesystem and configuration
By default DAVE will try to create a subfolder “DAVE_models” in the users HOME folder (%homepath% in windows, ~ in linux). This folder will be used for storing temporary files, the log file, and as default save location for assets and models.
DAVE can be configured by changing the settings in the settings.py file or by manually overriding them after importing settings.py and before importing scene.py
import DAVE.settings from DAVE.scene import * from pathlib import Path # override some of the settings DAVE.settings.RESOURCE_PATH = [Path(r'c:\data')] DAVE.settings.BLENDER_EXEC = r'C:\Program Files\Blender Foundation\Blender.82 alphalender.exe' # now create the scene s = Scene() print(s.resources_paths)
All settings are defined in UPPERCASE.
/ or \
DAVE is multiplatform. It runs fine under windows as well as linux. Windows uses a \ in path definitions while linux uses as /. The python standard pathlib library is used to deal with paths. In most situations however a string will work fine as well.
The standard file-format for saving DAVE scenes and nodes is vanilla python.
When loading a model or asset from a file into a scene the contents
of that file are executed in the python interpreter. In the interpreter a
available which refers to the current scene.
This makes it possible to define DAVE models in a very flexible way as arbitrary code can be executed when importing the model. Importing a model into DAVE is basically the same as running a file, so beware of the involed security implications.
Scene and nodes
A node is an item or element in a model. For example a ship or a force. A Scene is a collection of nodes.
The common way of working is as follows:
- Create a scene
- Add nodes to it
Nodes are added to the scene using .new_nodetype() where nodetype is
the type of the node. Each node has a unique name. This is always needs
to be provided to the .new_node function.
A complete list of node types and corresponding functions is provided
s = Scene()
# create an empty scene
# creates a poi with name anchor
s.new_poi(‘point 2’, position = (10,0,0)) # create a second poi at x=10
s.new_cable(‘line’,poiA = ‘point 1’, poiB = ‘point 2′)
# creates a cable between the two points
# save to file
Nodes in a scene can be referenced by either name or by reference. The .new_nodetype() functions return a reference to the newly created node.
s = Scene() a = s.new_axis('axis') # a is now a reference to node 'axis' p1 = s.new_poi('poi_1', parent = a ) # refer by reference p2 = s.new_poi('poi_2', parent = 'axis' ) # refer by name
A reference to a node can also be obtained from the scene using square brackets:
s = Scene() s.new_axis('axis') a = s['axis'] print(a.position)
The following node types can be used:
|Axis system with position and orientation|
|A disk with a radius and axis direction|
|Same as axis system, but provides a weight as well|
A RigidBody is technically idential to an axis system. So everything that applies to Axis also applies to RigidBody and everywhere where an axis system is used a rigidbody can be used as well.
- Axis can be placed on other axis systems.
- Pois can be located on an axis system.
- Sheaves need to be placed on a poi.
If a node has a parent then this means that its position and orientation are expressed relative to that parent. For nodes without a parent everything is defined relative to the global axis system.
Geometry nodes are also used to transfer forces.
Axis and Poi type nodes can receive forces and moments and apply them to their parents. See
Cables running over sheave type nodes will apply the forces directly to the parent node of the sheave.
Degrees of freedom
Axis and RigidBodies can have all their six individual degrees of freedom either fixed or free. If a degree of freedom is free then this means that the node is able to move/rotate in this degree of freedom.
Connectors connect two or more nodes and can apply a force on them based on their positions and orientations.
|A finite length cable with linear stiffness. A cable runs between two Poi nodes and can run over multiple pois or sheaves. A cable may have a diameter.|
|A beam connects two axis systems with a linear beam element|
|Connects two axis systems with six linear springs. Orientation of the springs is determined by the master axis system|
|Connects two axis systems with two linear springs. Orientation of the springs is determined by shortest distance between the two axis systems|
Forces apply a force to a node. The magnitude of the force may depend on the position and/or orientation of the node.
|An fixed force and/or moment applied on a Poi|
|A linear hydrostatic spring attached to an Axis|
|A buoyancy mesh attached to an Axis|
(Almost) Everything gets better when visualized :-).
Inertia is included via PointMass nodes. There is no direct API interface for these elements. They are included under the hood in the Axis nodes (and this in the derived RigidBody node). Also the ballast-system node type employs them to add the inertia of the ballast tanks.
TriMeshSource is a node that defines a triangular mesh. It is not created directly but is created implicitly when
creating a buoyuany node. It may be accessed via
Buoyancy.trimesh. Multiple buoyancy nodes may share the same TriMeshSource.
Apart from methods to create nodes, Scene also harbors functionality to delete, import, re-order and export nodes.
A Scene is not a singleton. Multiple scenes can exist next to each-other.
A new and empty Scene can be created as follows:
s = Scene()
s can be anything, for example
my_scene but s is nice and short which is useful as it will be used a lot.
Optionally a filename can be provided to the constructor. In that case that file will be imported.
my_vessel = Scene('path/to/my_vessel.dave_asset')
It is also possible to create a (deep) copy of a scene. This is done as follows:
copy_of_scene = Scene(copy_from = other_scene)
Nodes can be added to the scene using the s.new_poi, s.new_axis, etc.. functions which were introduced in the previous section.
Note: Beware of name-conflicts when importing. The
Scene.import_scene() provides the option to add a prefix to names of imported nodes.
A list of nodes is maintained as the ._nodes property of a scene. It is advised not to use this directly.
Obtaining a reference to a single node can be done using its name:
node = s['node_name']
This is the reason why all node names should be unique. To get a list of all available node names use
It is also possible to:
- Get all nodes of a type, use :
- Get all nodes that depend on a node :
- Get all child nodes :
Removing nodes can be tricky due to nodes depending on each other. For example deleting a poi which is also used a endpoint for a cable will cause problems for that cable. The same applies to axis systems with nodes on it (children)
Scene.clear() can be used to delete all nodes from a scene.
To delete a single node there are two options:
Scene.delete(). This deletes a node from the scene. All nodes that depend on this node will be deleted as well.
Scene.dissolve(). This “evaporates” the node. Attempts to maintain child nodes. Often used in combination with the containerize option of
Saving or exporting
The standard file-format for saving DAVE scenes and nodes is vanilla python.
Solving static equilibrium is done using
If there is a static equilibrium condition then this function will
attempt to find it by changing the non-fixed degrees of freedom of the
A goal-seek function is available:
In the default resource system the resources may be located in any of the folders listed in
The value of this property is initialized with