Python API reference

This page documents every public name of the cabledyn package. Everything is imported from the top-level package, for example from cabledyn import CableDynDriver, read_output. The workflows that use these objects are described in Python package.

Two groups of names have different installation requirements:

  • The standalone-driver API (running decks, reading and analysing results, editing decks, batch studies, and all exception classes) is pure Python. It needs NumPy and, to run analyses, the CableDyn_driver executable, but never the CableDyn shared library.

  • The in-process coupling API (CableDyn, abi_version(), abi_minor(), library_path(), and version_string()) loads the CableDyn shared library the first time one of these names is accessed. These names are deliberately left out of cabledyn.__all__, so from cabledyn import * works in an installation without the shared library.

Plotting methods import matplotlib and to_dataframe imports pandas only when they are called; both are optional dependencies. Every plotting method returns the matplotlib axes it drew on and draws on a new figure unless an ax is supplied. The exception is animate(), which returns a matplotlib FuncAnimation.

Unless stated otherwise, quantities are in SI units: metres, seconds, kilograms, and newtons. Result objects are immutable, and the NumPy arrays they hold are read-only.

Running the standalone driver

class cabledyn.CableDynDriver(executable=None)

Run complete standalone decks through CableDyn_driver.exe.

Parameters:

executable (str | os.PathLike | None) – Explicit native executable. When omitted, CABLEDYN_DRIVER is checked before release/development names on PATH.

executable

Absolute path of the resolved native driver.

Type:

pathlib.Path

Raises:

DriverNotFoundError – If no executable driver can be located.

version(*, timeout=10.0)

Query and return the complete native version banner.

Parameters:

timeout (float) – Finite, positive time limit, in seconds.

Returns:

The version banner the driver prints for --version.

Return type:

str

Raises:
  • ValueError – If timeout is not finite and positive.

  • DriverExecutionError – If the query times out or exits with a non-zero code.

run(deck, output_root, *, timeout=None, cwd=None, env=None, overwrite=False)

Run one complete deck and validate its primary output.

Existing results are protected unless overwrite is true. With overwrite, the previous result files of this root are moved into a temporary directory beside them while the solver runs. They are deleted only after the new run succeeds; on any failure the partial new files are removed and the previous results are restored.

Parameters:
  • deck (str | os.PathLike) – Input deck. A relative path is resolved against cwd when given.

  • output_root (str | os.PathLike) – Output stem without .out; a relative stem is resolved against the working directory. Missing parent directories are created.

  • timeout (float | None) – None (no limit) or a finite, positive limit in seconds.

  • cwd (str | os.PathLike | None) – Working directory of the run; defaults to the deck directory, preserving relative ancillary-file references.

  • env (collections.abc.Mapping[str, str] | None) – Entries merged over the process environment.

  • overwrite (bool) – Replace existing result files of this root.

Returns:

The written files and captured streams of the converged run.

Return type:

DriverResult

Raises:
  • ValueError – If timeout is invalid, or output_root has no stem or ends in .out.

  • NotADirectoryError – If cwd does not exist.

  • FileNotFoundError – If the deck does not exist.

  • FileExistsError – If result files exist for the root and overwrite is false.

  • DriverExecutionError – If the driver times out, exits with a non-zero code (for example on non-convergence), or does not write a valid main output.

class cabledyn.DriverResult(executable, deck, output_root, main_output, static_output, elements_output, line_outputs, rod_outputs, stdout, stderr, returncode)

Files and captured streams from one completed driver run.

A result exists only after a zero native exit, which the driver reserves for a fully converged analysis, and validation of the main table.

executable

Absolute path of the native driver that ran.

Type:

pathlib.Path

deck

Absolute path of the input deck.

Type:

pathlib.Path

output_root

Absolute output stem, without .out.

Type:

pathlib.Path

main_output

Main channel history <root>.out.

Type:

pathlib.Path

static_output

Static line profile <root>.static.out, or None if not written.

Type:

pathlib.Path | None

elements_output

Per-element static table <root>.elements.out written for finite-EI lines, or None if not written.

Type:

pathlib.Path | None

line_outputs

Per-line node-position (.p.out) and segment-tension (.t.out) files, sorted by name.

Type:

tuple[pathlib.Path, …]

rod_outputs

Per-rod node-position files, sorted by name.

Type:

tuple[pathlib.Path, …]

stdout

Captured standard output of the driver.

Type:

str

stderr

Captured standard error of the driver.

Type:

str

returncode

Native exit code; always 0 for a result.

Type:

int

read_main()

Read the primary channel history again from disk.

Returns:

The main output table: time in seconds followed by the requested channels (tensions in N, positions in m, angles in deg).

Return type:

TimeHistory

Raises:

OutputFormatError – If the file is missing, malformed, or not a time history.

read_static()

Read the static profile, raising if this run did not create one.

Returns:

The static line profile, with lengths in metres and tensions in newtons.

Return type:

StaticProfile

Raises:
  • FileNotFoundError – If the run did not write a static profile.

  • OutputFormatError – If the file is malformed or not a line profile.

property line_ids

Line identifiers for which a per-line output file was produced.

read_line_positions(line_id)

Read one line’s static node table or dynamic node-position history.

Parameters:

line_id (int) – Positive, one-based line identifier.

Returns:

A LineNodeHistory for a dynamic run, or a static table with Node, X(m), Y(m), and Z(m) columns; positions in metres.

Return type:

OutputTable

Raises:
  • ValueError – If line_id is not a positive integer.

  • FileNotFoundError – If the run did not write that line’s position output.

  • OutputFormatError – If the file is malformed, ambiguous, or not a line-position table.

read_line_tensions(line_id)

Read one line’s static segment table or dynamic segment-tension history.

Parameters:

line_id (int) – Positive, one-based line identifier.

Returns:

A LineSegmentHistory for a dynamic run, or a static table with Segment and Tension(N) columns; tensions in newtons.

Return type:

OutputTable

Raises:
  • ValueError – If line_id is not a positive integer.

  • FileNotFoundError – If the run did not write that line’s tension output.

  • OutputFormatError – If the file is malformed, ambiguous, or not a line-tension table.

Batch studies

cabledyn.run_study(case_manifest, *, executable=None, driver=None, output_directory=None, channels=None, start=None, stop=None, timeout=None, jobs=1, overwrite=False)

Run every case in a generate_deck_cases manifest.

Individual native failures are recorded and do not prevent remaining jobs from running. Manifest/hash/preflight errors fail before the first solver process starts.

Parameters:
  • case_manifest (str | os.PathLike) – cases.json written by cabledyn.generate_deck_cases().

  • executable (str | os.PathLike | None) – Native driver to use; located as by CableDynDriver when omitted. Not allowed together with driver.

  • driver (CableDynDriver | None) – Pre-configured driver to use instead of executable.

  • output_directory (str | os.PathLike | None) – Directory for results, logs, summary.csv, and study.json; defaults to study-results beside the manifest.

  • channels (str | collections.abc.Iterable[str] | None) – Main-output channels summarized in summary.csv; every non-time channel when None.

  • start (float | None) – Optional statistics window, in seconds.

  • stop (float | None) – Optional statistics window, in seconds.

  • timeout (float | None) – Per-case time limit, in seconds; None for no limit.

  • jobs (int) – Number of independent native processes run at once (not solver threads within a process).

  • overwrite (bool) – Allow a non-empty output directory and replace existing case outputs.

Returns:

The batch record, including failed cases.

Return type:

StudyResult

Raises:
  • ValueError – If both driver and executable are given, or jobs, timeout, start, stop, or channels is invalid.

  • StudyFormatError – If the manifest is malformed or a deck digest does not match it.

  • FileExistsError – If the output directory is not empty and overwrite is false.

  • FileNotFoundError – If the driver executable does not exist.

  • DriverNotFoundError – If no driver can be located.

  • DriverExecutionError – If the driver version query fails.

  • StudyOutputError – If the cases ran but summary.csv or study.json could not be written.

class cabledyn.StudyResult(case_manifest, study_manifest, summary_csv, executable, executable_sha256, solver_version, started_at, finished_at, cases)

Completed batch record and its deterministic summary artifacts.

case_manifest

The cases.json manifest that was run.

Type:

pathlib.Path

study_manifest

The study.json record written for the batch.

Type:

pathlib.Path

summary_csv

The summary.csv table of per-case channel statistics, in each channel’s unit.

Type:

pathlib.Path

executable

Absolute path of the native driver used.

Type:

pathlib.Path

executable_sha256

SHA-256 digest of the driver executable.

Type:

str

solver_version

Native version banner of the driver.

Type:

str

started_at

UTC start time, ISO 8601.

Type:

str

finished_at

UTC finish time, ISO 8601.

Type:

str

cases

One result per case, in manifest order.

Type:

tuple[StudyCaseResult, …]

property passed

Whether every case completed with a converged native analysis.

property failed_cases

Cases whose native run or post-processing failed.

class cabledyn.StudyCaseResult(name, status, deck, deck_sha256, output_root, elapsed_seconds, returncode, main_output, static_output, stdout_log, stderr_log, error)

Disposition and artifacts for one attempted generated case.

name

Case name from the manifest.

Type:

str

status

"completed", "failed" (the native run failed), or "postprocess_failed" (the run finished but its outputs or logs could not be processed).

Type:

str

deck

Absolute path of the generated deck.

Type:

pathlib.Path

deck_sha256

SHA-256 digest of the deck, verified against the manifest.

Type:

str

output_root

Absolute output stem of the case, without .out.

Type:

pathlib.Path

elapsed_seconds

Wall-clock time spent on the case, in seconds.

Type:

float

returncode

Native exit code, or None if the process did not report one.

Type:

int | None

main_output

Main channel history, or None if not written.

Type:

pathlib.Path | None

static_output

Static line profile, or None if not written.

Type:

pathlib.Path | None

stdout_log

File holding the captured standard output.

Type:

pathlib.Path

stderr_log

File holding the captured standard error.

Type:

pathlib.Path

error

Short diagnostic for a failed case, otherwise None.

Type:

str | None

Raises:

ValueError – If status is unknown or elapsed_seconds is negative or not finite.

Parameter sweeps

parameter_grid() builds the case specifications that generate_deck_cases() consumes, from lists of values for each deck selector.

cabledyn.parameter_grid(parameters, *, mode='product', prefix='case')

Return case specifications for every combination (or pairing) of values.

mode="product" takes the Cartesian product of the value lists in selector order (the last selector varies fastest); mode="zip" pairs the i-th values of equally long lists. Cases are named <prefix>000, <prefix>001, … with enough digits for the case count (at least three).

Parameters:
  • parameters (collections.abc.Mapping[str, list | tuple]) – {selector: values}, for example {"option.dtM": [0.01, 0.02]}. Each value list is a non-empty sequence (not a string). Values are passed through unchanged, in the units the deck selector expects (SI for CableDyn decks), so any value the selector accepts can be used. Selector and value validity is checked later, when the decks are generated.

  • mode (str) – "product" or "zip".

  • prefix (str) – Case-name prefix matching [A-Za-z0-9][A-Za-z0-9_.-]*.

Returns:

{case_name: {selector: value}} in case order, ready for cabledyn.generate_deck_cases().

Return type:

dict[str, dict[str, object]]

Raises:

ValueError – If prefix is invalid, parameters is empty, a selector is not a non-empty string, a value list is empty or a string, mode is unknown, or "zip" lists differ in length.

Reading results

read_output() returns the most specific table class for the file it reads: TimeHistory for the main output, LineNodeHistory and LineSegmentHistory for per-line dynamic outputs, StaticProfile for the static profile, and OutputTable for any other numeric table. TimeHistory and StaticProfile are subclasses of OutputTable; LineNodeHistory and LineSegmentHistory are subclasses of TimeHistory, so every table method is available on them.

cabledyn.read_output(path)

Read and strictly validate a CableDyn numeric output table.

Fortran-formatted numbers (including D exponents) are accepted. Every data row must have one finite value per channel. A time history that repeats a channel name (as an OpenFAST OutList may) keeps every column: repeats are renamed <name>_2, <name>_3, … with a UserWarning. Other layouts reject a repeated name.

Parameters:

path (str | os.PathLike) – Output file to read.

Returns:

A TimeHistory, LineNodeHistory, LineSegmentHistory, or StaticProfile when the layout is recognized, otherwise a plain OutputTable.

Return type:

OutputTable

Raises:

OutputFormatError – If the file cannot be read, has no recognized header, or holds a truncated, overflowed, non-numeric, or non-finite value.

class cabledyn.OutputTable(path, title, channels, units, values)

A validated CableDyn/OpenFAST-style numeric table.

Instances are normally created by cabledyn.read_output(), which returns a more specific subclass when the table layout is recognized.

path

Absolute path of the source file.

Type:

pathlib.Path

title

Free-text lines that precede the column header, joined by newlines.

Type:

str

channels

Column names, in file order.

Type:

tuple[str, …]

units

Raw units row, one entry per channel, or None when the file has no units row. Use unit() for a normalized unit of one channel.

Type:

tuple[str, …] | None

values

Read-only (n_rows, n_channels) array of finite values, each column in its channel’s unit (SI: N, m, s, deg, and so on).

Type:

numpy.ndarray

Raises:

ValueError – If values is not a finite 2-D array with one column per channel, or units does not match channels.

column(channel)

Return a read-only view of one named channel.

Parameters:

channel (str) – Channel name exactly as it appears in channels. When a file repeats a channel name, the readers keep every column and rename the repeats <name>_2, <name>_3, …; column(name) then returns the first occurrence.

Returns:

Read-only (n_rows,) view of the channel, in the channel’s unit (see unit()).

Return type:

numpy.ndarray

Raises:

KeyError – If the table has no channel of that name.

unit(channel)

Return a normalized unit string, or None if none was recorded.

Surrounding brackets are removed. Without a units row, the unit is taken from a Name(unit) channel name or, for native main-output channels such as FairTen1, from the channel’s documented unit.

Parameters:

channel (str) – Channel name exactly as it appears in channels.

Returns:

Unit string such as "N", "m", or "deg", or None if the unit cannot be determined.

Return type:

str | None

Raises:

KeyError – If the table has no channel of that name.

to_dataframe(*, units_in_columns=True)

Return a pandas DataFrame without making pandas a base dependency.

Parameters:

units_in_columns (bool) – Label columns Name_[unit] when a unit is known; otherwise use the bare channel names.

Returns:

A copy of values, shape (n_rows, n_channels), with one column per channel.

Return type:

pandas.DataFrame

Raises:

ImportError – If pandas is not installed.

export_pydatview(path, *, overwrite=False, delimiter=None)

Export a generic table that pyDatView can read reliably.

Units are embedded in the single header row as Name_[unit]. CSV is selected for a .csv suffix; other suffixes default to tab-separated text. The source table is never modified.

Parameters:
  • path (str | os.PathLike) – Target file. Missing parent directories are created.

  • overwrite (bool) – Replace an existing file instead of raising FileExistsError.

  • delimiter (str | None) – One-character column separator overriding the suffix-based choice.

Returns:

Absolute path of the written file.

Return type:

pathlib.Path

Raises:
  • FileExistsError – If path exists and overwrite is false.

  • ValueError – If path is the source file or delimiter is not one character.

class cabledyn.TimeHistory(path, title, channels, units, values)

A validated monotonically increasing time-history table.

A subclass of cabledyn.OutputTable with a time column, in seconds, whose values strictly increase. cabledyn.read_output() returns it for a main output file. The attributes are those of cabledyn.OutputTable, with values of shape (n_samples, n_channels).

Raises:

OutputFormatError – If the time values do not strictly increase.

property time_channel

Name of the table’s time column (Time or Time(s)).

property time

Read-only sample times in seconds.

period(start=None, stop=None)

Return samples in the closed interval [start, stop].

Parameters:
  • start (float | None) – Interval limits in seconds. None leaves that end open.

  • stop (float | None) – Interval limits in seconds. None leaves that end open.

Returns:

A new table of the same class holding only the selected rows.

Return type:

TimeHistory

Raises:

ValueError – If a limit is not finite, start exceeds stop, or no sample lies in the interval.

statistics(channels=None)

Compute population statistics over the represented period.

Parameters:

channels (str | collections.abc.Iterable[str] | None) – One channel name, several names, or None for every channel except time.

Returns:

One entry per selected channel, in the requested order, in each channel’s unit.

Return type:

tuple[ChannelStatistics, …]

Raises:

KeyError – If a requested channel is not in the table.

fatigue(channel, *, wohler_exponent, reference_cycles=None, reference_frequency=None, start=None, stop=None, bins=None)

Return uncorrected rainflow cycles and a damage-equivalent range.

Supply exactly one of reference_cycles or reference_frequency. A frequency is converted to cycles using the selected record duration. Cycle ranges, rather than amplitudes, are used throughout. No mean-stress correction is applied.

Parameters:
  • channel (str) – Channel to analyse; not the time channel.

  • wohler_exponent (float) – Positive S-N curve slope exponent m.

  • reference_cycles (float | None) – Number of equivalent constant-range cycles.

  • reference_frequency (float | None) – Equivalent-cycle frequency, in Hz; multiplied by the record duration to give the reference cycle count.

  • start (float | None) – Optional analysis window, in seconds.

  • stop (float | None) – Optional analysis window, in seconds.

  • bins (int | collections.abc.Iterable[float] | None) – Optional range histogram: a bin count, or explicit increasing bin edges spanning every cycle range. See cabledyn.cycle_histogram().

Returns:

The cycles, the damage-equivalent range, and the analysis settings.

Return type:

FatigueResult

Raises:

ValueError – If the channel is the time channel, fewer than two samples are selected, or the fatigue settings are invalid.

spectrum(channel, *, segment_length, overlap=0.5, fft_length=None, window='hann', detrend='constant', start=None, stop=None, uniform_rtol=1e-06, uniform_atol=0.0)

Return a one-sided Welch PSD density for a uniformly sampled channel.

segment_length is deliberately mandatory. The method never resamples data and rejects time-step variation outside the stated tolerances.

Parameters:
  • channel (str) – Channel to analyse; not the time channel.

  • segment_length (int) – Samples per Welch segment; at least 2 and at most the sample count.

  • overlap (float) – Fraction of a segment shared with the next, in [0, 1).

  • fft_length (int | None) – FFT length; None uses segment_length.

  • window (str) – "hann" (periodic Hann) or "boxcar".

  • detrend (str) – "constant" removes each segment’s mean; "none" keeps it.

  • start (float | None) – Optional analysis window, in seconds.

  • stop (float | None) – Optional analysis window, in seconds.

  • uniform_rtol (float) – Relative and absolute (seconds) tolerances for accepting the time steps as uniform.

  • uniform_atol (float) – Relative and absolute (seconds) tolerances for accepting the time steps as uniform.

Returns:

The spectrum, in (channel unit)^2/Hz against frequency in Hz, and the settings that produced it.

Return type:

PowerSpectrum

Raises:
  • KeyError – If the table has no channel of that name.

  • ValueError – If channel is the time channel, the window is invalid, the samples are not uniformly spaced, or a setting is out of range. See cabledyn.power_spectrum().

coherence(channel_x, channel_y, *, segment_length, overlap=0.5, fft_length=None, window='hann', detrend='constant', start=None, stop=None, power_floor_ratio=2.220446049250313e-14, uniform_rtol=1e-06, uniform_atol=0.0)

Return magnitude-squared Welch coherence with invalid low-power bins masked.

Parameters:
  • channel_x (str) – Two distinct non-time channels.

  • channel_y (str) – Two distinct non-time channels.

  • segment_length (int) – Samples per Welch segment; at least two complete segments are needed.

  • overlap (float) – Fraction of a segment shared with the next, in [0, 1).

  • fft_length (int | None) – FFT length; None uses segment_length.

  • window (str) – "hann" (periodic Hann) or "boxcar".

  • detrend (str) – "constant" removes each segment’s mean; "none" keeps it.

  • start (float | None) – Optional analysis window, in seconds.

  • stop (float | None) – Optional analysis window, in seconds.

  • power_floor_ratio (float) – A bin is valid only where both auto-spectra exceed this fraction of their maxima. Must lie in [0, 1).

  • uniform_rtol (float) – Relative and absolute (seconds) tolerances for accepting the time steps as uniform.

  • uniform_atol (float) – Relative and absolute (seconds) tolerances for accepting the time steps as uniform.

Returns:

The dimensionless coherence against frequency in Hz, its valid-bin mask, and the settings that produced it.

Return type:

CoherenceResult

Raises:
  • KeyError – If the table has no channel of either name.

  • ValueError – If a channel is the time channel, the channels are the same, the window is invalid, or a setting is out of range.

plot(*channels, start=None, stop=None, ax=None)

Plot one or more channels against time using optional matplotlib.

Parameters:
  • *channels (str) – Channels to plot; every non-time channel when none are given.

  • start (float | None) – Optional time window, in seconds.

  • stop (float | None) – Optional time window, in seconds.

  • ax (matplotlib.axes.Axes | None) – Axes to draw on; a new figure is created when omitted.

Returns:

The axes drawn on, with time in seconds on the horizontal axis.

Return type:

matplotlib.axes.Axes

Raises:
  • ImportError – If matplotlib is not installed.

  • KeyError – If a requested channel is not in the table.

  • ValueError – If the time window is invalid or contains no sample.

class cabledyn.LineNodeHistory(path, title, channels, units, values)

Dynamic positions of every node of one line, in End-A-to-End-B order.

A subclass of cabledyn.TimeHistory read from a per-line position file. After the time column, the channels are Node<i>X(m), Node<i>Y(m), and Node<i>Z(m) for every node i. The attributes are those of cabledyn.OutputTable, with values of shape (n_samples, 1 + 3 * n_nodes); positions are in metres.

Raises:

OutputFormatError – If the node channels are malformed, not contiguous from Node1, or not in metres, or time does not strictly increase.

property node_ids

One-based node identifiers in public End-A-to-End-B order.

coordinates(time)

Return an interpolated, read-only (n_nodes, 3) XYZ snapshot.

Parameters:

time (float) – Physical time of the snapshot, in seconds.

Returns:

Read-only (n_nodes, 3) node positions, in metres, linearly interpolated in time, in End-A-to-End-B order.

Return type:

numpy.ndarray

Raises:

ValueError – If time is not finite or lies outside the recorded interval.

arc_length(time)

Return cumulative deformed chord length from End A at time.

Parameters:

time (float) – Physical time of the snapshot, in seconds.

Returns:

Read-only (n_nodes,) cumulative sum of straight node-to-node distances, in metres, starting at zero.

Return type:

numpy.ndarray

Raises:

ValueError – If time is not finite or lies outside the recorded interval.

plot_geometry(time, *, plane='xz', ax=None)

Plot an interpolated line centreline in xy, xz, yz, or 3-D.

Parameters:
  • time (float) – Physical time of the snapshot, in seconds.

  • plane (str) – "xy", "xz", "yz", or "3d".

  • ax (matplotlib.axes.Axes | None) – Axes to draw on; a new figure is created when omitted. For "3d" it must be a 3-D axes.

Returns:

The axes drawn on.

Return type:

matplotlib.axes.Axes

Raises:
  • ImportError – If matplotlib is not installed.

  • ValueError – If plane is not recognized, or time is not finite or lies outside the recorded interval.

class cabledyn.LineSegmentHistory(path, title, channels, units, values)

Dynamic effective tension at every segment of one line.

A subclass of cabledyn.TimeHistory read from a per-line tension file. After the time column, the channels are Segment<i>Tension(N) for every segment i, numbered from End A. The attributes are those of cabledyn.OutputTable, with values of shape (n_samples, 1 + n_segments); tensions are in newtons.

Raises:

OutputFormatError – If the segment channels are malformed, not contiguous from Segment1, or not in newtons, or time does not strictly increase.

property segment_ids

One-based segment identifiers in public End-A-to-End-B order.

tensions(time)

Return linearly interpolated segment tensions at one physical time.

Parameters:

time (float) – Physical time, in seconds.

Returns:

Read-only (n_segments,) effective tensions, in newtons, in End-A-to-End-B order.

Return type:

numpy.ndarray

Raises:

ValueError – If time is not finite or lies outside the recorded interval.

spatial_statistics(start=None, stop=None)

Return the tension envelope and population statistics at every segment.

Parameters:
  • start (float | None) – Optional time window, in seconds; None leaves that end open.

  • stop (float | None) – Optional time window, in seconds; None leaves that end open.

Returns:

Per-segment tension statistics, in newtons, each of shape (n_segments,).

Return type:

SpatialStatistics

Raises:

ValueError – If a window limit is not finite, start exceeds stop, or no sample lies in the window.

plot_range(time, *, ax=None)

Plot the dynamic tension range graph at one interpolated time.

Parameters:
  • time (float) – Physical time, in seconds.

  • ax (matplotlib.axes.Axes | None) – Axes to draw on; a new figure is created when omitted.

Returns:

The axes drawn on: tension, in newtons, against segment number.

Return type:

matplotlib.axes.Axes

Raises:
  • ImportError – If matplotlib is not installed.

  • ValueError – If time is not finite or lies outside the recorded interval.

plot_envelope(start=None, stop=None, *, ax=None)

Plot minimum/maximum and mean segment tension over a physical-time window.

Parameters:
  • start (float | None) – Optional time window, in seconds; None leaves that end open.

  • stop (float | None) – Optional time window, in seconds; None leaves that end open.

  • ax (matplotlib.axes.Axes | None) – Axes to draw on; a new figure is created when omitted.

Returns:

The axes drawn on: tension, in newtons, against segment number.

Return type:

matplotlib.axes.Axes

Raises:
  • ImportError – If matplotlib is not installed.

  • ValueError – If the window is invalid or contains no sample.

class cabledyn.StaticProfile(path, title, channels, units, values)

One or more CableDyn line profiles indexed by line and arc length.

A subclass of cabledyn.OutputTable read from a static profile file. It has at least the LineID, Node, and ArcLength columns, with each line’s rows contiguous and ordered from End A. Further columns, such as X, Y, Z, Tension, Curvature, and BendMoment, are available through column(), in SI units: coordinates and arc length in m, tension in N, curvature in 1/m, and bending moment in N-m. The attributes are those of cabledyn.OutputTable, with values of shape (n_rows, n_channels).

Raises:

OutputFormatError – If a required column is missing, LineID or Node values are not positive integers, a line’s rows are not contiguous, or a line’s arc length or node order is not increasing.

property line_ids

Line identifiers in first-appearance order.

line(line_id)

Return the rows belonging to one line identifier.

Parameters:

line_id (int) – One-based line identifier, as in the LineID column.

Returns:

A new profile holding only that line’s rows, ordered from End A.

Return type:

StaticProfile

Raises:

KeyError – If the profile has no rows for line_id.

summary(line_id)

Return core geometry and demand extrema for one line.

Parameters:

line_id (int) – One-based line identifier, as in the LineID column.

Returns:

Deformed length (m), tension extrema (N), maximum curvature (1/m), minimum bend radius (m), and maximum bending moment (N-m).

Return type:

StaticLineSummary

Raises:

KeyError – If the profile has no rows for line_id.

summaries()

Return one engineering summary per line.

Returns:

One summary per line, in the order of line_ids.

Return type:

tuple[StaticLineSummary, …]

plot(channel, *, x='ArcLength', line_id=None, ax=None)

Plot a range variable against arc length or another profile column.

Parameters:
  • channel (str) – Profile column plotted on the vertical axis.

  • x (str) – Profile column plotted on the horizontal axis.

  • line_id (int | None) – Plot one line; every line when omitted.

  • ax (matplotlib.axes.Axes | None) – Axes to draw on; a new figure is created when omitted.

Returns:

The axes drawn on.

Return type:

matplotlib.axes.Axes

Raises:
  • ImportError – If matplotlib is not installed.

  • KeyError – If a column or line_id is not in the profile.

plot_geometry(*, plane='xz', line_id=None, ax=None)

Plot the static centreline in xy, xz, yz, or three dimensions.

Parameters:
  • plane (str) – "xy", "xz", "yz", or "3d".

  • line_id (int | None) – Plot one line; every line when omitted.

  • ax (matplotlib.axes.Axes | None) – Axes to draw on; a new figure is created when omitted. For "3d" it must be a 3-D axes.

Returns:

The axes drawn on, with coordinates in metres.

Return type:

matplotlib.axes.Axes

Raises:
  • ImportError – If matplotlib is not installed.

  • KeyError – If the profile lacks the needed X/Y/Z columns or line_id.

  • ValueError – If plane is not recognized.

class cabledyn.ChannelStatistics(channel, unit, count, minimum, maximum, mean, standard_deviation, rms)

Population statistics for one time-history channel.

channel

Channel name.

Type:

str

unit

Channel unit, or None if unknown.

Type:

str | None

count

Number of samples summarized.

Type:

int

minimum

Smallest sample.

Type:

float

maximum

Largest sample.

Type:

float

mean

Arithmetic mean.

Type:

float

standard_deviation

Population standard deviation (divisor count).

Type:

float

rms

Root-mean-square value.

Type:

float

class cabledyn.StaticLineSummary(line_id, node_count, deformed_length, minimum_tension, maximum_tension, maximum_curvature, minimum_bend_radius, maximum_bend_moment)

Engineering summary of one line in a static profile.

Extrema of columns that the profile does not contain are None.

line_id

Line identifier.

Type:

int

node_count

Number of profile rows (nodes) for the line.

Type:

int

deformed_length

Arc length at the last node, in metres.

Type:

float

minimum_tension

Smallest tension, in newtons.

Type:

float | None

maximum_tension

Largest tension, in newtons.

Type:

float | None

maximum_curvature

Largest curvature, in 1/m.

Type:

float | None

minimum_bend_radius

Reciprocal of maximum_curvature, in metres; infinite for a line with zero curvature everywhere.

Type:

float | None

maximum_bend_moment

Largest absolute bending moment, in N-m.

Type:

float | None

class cabledyn.SpatialStatistics(location_kind, location_ids, quantity, unit, count, minimum, maximum, mean, standard_deviation, rms)

Population statistics at every node or segment of a line history.

Each array holds one value per location, in the order of location_ids.

location_kind

Kind of location, for example "Segment".

Type:

str

location_ids

Read-only, strictly increasing one-based location identifiers.

Type:

numpy.ndarray

quantity

Summarized quantity, for example "Tension".

Type:

str

unit

Unit of the quantity, or None if unknown.

Type:

str | None

count

Number of time samples summarized.

Type:

int

minimum

Smallest value at each location.

Type:

numpy.ndarray

maximum

Largest value at each location.

Type:

numpy.ndarray

mean

Arithmetic mean at each location.

Type:

numpy.ndarray

standard_deviation

Population standard deviation at each location.

Type:

numpy.ndarray

rms

Root-mean-square value at each location.

Type:

numpy.ndarray

Reading other codes’ outputs

These readers return the same table classes as read_output(), so statistics, fatigue, spectra, plots, comparisons, and exports work unchanged on results of OpenFAST (maintained by NLR, the National Laboratory of the Rockies, formerly NREL) and MoorDyn and on the files of an OpenFAST run that uses CableDyn as its mooring module. read_table() chooses the reader from the file name. Malformed files raise OutputFormatError.

cabledyn.read_table(path, *, format='auto')

Read any supported output table.

Automatic selection uses the file name: .outb is OpenFAST binary, *.MD.Line<N>.out a MoorDyn line file, *.MD.out a MoorDyn main file, and anything else the CableDyn reader (which also reads OpenFAST text output and *.CD.out files).

Parameters:
Returns:

The table returned by the selected reader, usually a TimeHistory or one of its subclasses.

Return type:

OutputTable

Raises:
  • ValueError – If format is unknown.

  • OutputFormatError – If the file cannot be read or is malformed.

cabledyn.read_openfast_output(path)

Read an OpenFAST text .out or binary .outb time-series file.

The binary format is recognized by the .outb suffix. Compressed binary files store each channel as 16-bit integers with a per-channel scale and offset, so values carry that quantization; time is reconstructed exactly as OpenFAST encodes it. The file description becomes the table title.

An OpenFAST OutList may request a channel twice (the r-test ElastoDyn file lists TwrBsFzt twice). Every column is kept: the first occurrence keeps its name, so column(name) returns it, and the k-th becomes <name>_k, with a UserWarning.

Parameters:

path (str | os.PathLike) – OpenFAST output file; a .outb suffix selects the binary reader.

Returns:

Time, in seconds, followed by the OpenFAST channels in their recorded units; values has shape (n_samples, n_channels).

Return type:

TimeHistory

Raises:

OutputFormatError – If the file cannot be read, is truncated or malformed, has an empty channel name, holds a non-finite value, or its time does not strictly increase.

cabledyn.read_moordyn_output(path)

Read a MoorDyn main output file such as <root>.MD.out.

Channel names keep MoorDyn’s spelling (for example FAIRTEN1); pass a channel mapping to cabledyn.compare_histories() to line them up with CableDyn names such as FairTen1.

Parameters:

path (str | os.PathLike) – MoorDyn main output file.

Returns:

Time, in seconds, followed by the MoorDyn channels in their recorded units (tensions in N, positions in m); values has shape (n_samples, n_channels).

Return type:

TimeHistory

Raises:

OutputFormatError – If the file cannot be read, has no Time header row, a units row or data row of the wrong width, a non-numeric or non-finite value, or non-increasing time.

cabledyn.read_moordyn_line(path)

Read a MoorDyn-F per-line output file <root>.MD.Line<N>.out.

Parameters:

path (str | os.PathLike) – MoorDyn-F per-line output file.

Returns:

The validated line history, with node and segment accessors.

Return type:

MoorDynLineHistory

Raises:

OutputFormatError – If the file cannot be read, is not a rectangular table of finite numbers with increasing time, or holds channels that are not a consistent set of MoorDyn line quantities.

class cabledyn.MoorDynLineHistory(path, title, channels, units, values)

A MoorDyn-F per-line output <root>.MD.Line<N>.out.

MoorDyn numbers nodes from 0 (End A) to N (End B) and segments from 1 to N. Every channel must be one of the MoorDyn-F line quantities (node vectors p v a U D b V with x/y/z components, node scalars Wz and Kurv, and segment scalars Ten Dmp Str SRt Lst), and each quantity present must cover every node or segment of the line.

A subclass of cabledyn.TimeHistory with the same attributes; values has shape (n_samples, n_channels). Positions are in metres, velocities in m/s, forces and tensions in newtons, and times in seconds.

Raises:

OutputFormatError – If a channel is not a MoorDyn line channel, or the quantities present do not cover a consistent, contiguous set of nodes and segments.

property quantities

MoorDyn quantity codes present, e.g. ("p", "Ten"), in file order.

property segment_count

Number of segments N of the line.

property node_count

Number of nodes N + 1 of the line.

node_vectors(quantity, time)

Return an interpolated, read-only (N + 1, 3) node vector snapshot.

Parameters:
  • quantity (str) – "p" (position, m), "v" (velocity, m/s), "a" (acceleration, m/s^2), "U" (fluid velocity, m/s), "D" (drag, N), "b" (seabed force, N), or "V" (other force, N).

  • time (float) – Physical time, in seconds, within the recorded interval.

Returns:

Read-only (N + 1, 3) array of x, y, z components, one row per node from Node0 (End A), linearly interpolated in time.

Return type:

numpy.ndarray

Raises:
  • ValueError – If quantity is unknown, or time is not finite or lies outside the recorded interval.

  • KeyError – If the file does not record that quantity.

positions(time)

Return interpolated (N + 1, 3) node positions in metres at time.

Parameters:

time (float) – Physical time, in seconds, within the recorded interval.

Returns:

Read-only (N + 1, 3) node positions, in metres, from End A.

Return type:

numpy.ndarray

Raises:
  • ValueError – If time is not finite or lies outside the recorded interval.

  • KeyError – If the file does not record node positions.

segment_values(quantity, time)

Return one interpolated segment scalar (Ten, Dmp, Str, SRt, Lst).

Parameters:
  • quantity (str) – "Ten" (tension, N), "Dmp" (internal damping force, N), "Str" (strain, dimensionless), "SRt" (strain rate, 1/s), or "Lst" (stretched length, m).

  • time (float) – Physical time, in seconds, within the recorded interval.

Returns:

Read-only (N,) values, one per segment from Seg1 (End A), linearly interpolated in time.

Return type:

numpy.ndarray

Raises:
  • ValueError – If quantity is unknown, or time is not finite or lies outside the recorded interval.

  • KeyError – If the file does not record that quantity.

segment_tensions(time)

Return interpolated segment tensions (Seg<i>Ten) at time.

Parameters:

time (float) – Physical time, in seconds, within the recorded interval.

Returns:

Read-only (N,) segment tensions, in newtons, from End A.

Return type:

numpy.ndarray

Raises:
  • ValueError – If time is not finite or lies outside the recorded interval.

  • KeyError – If the file does not record segment tensions.

cabledyn.read_coupled_run(root)

Read the files of a coupled OpenFAST + CableDyn run from its output root.

When both <root>.out and <root>.outb exist the call fails, because either could be stale. At least one file must exist.

Parameters:

root (str | os.PathLike) – OpenFAST output root: the .fst path without its suffix. A .fst, .out, or .outb suffix is removed.

Returns:

The files found; members for missing files are None.

Return type:

CoupledRun

Raises:
  • FileNotFoundError – If none of the files exists.

  • OutputFormatError – If both <root>.out and <root>.outb exist, a file is malformed, or <root>.CD.static.out is not a line profile.

class cabledyn.CoupledRun(root, cabledyn, static, openfast)

The result files of one OpenFAST run that uses CableDyn (CompMooring = 5).

A member is None when the run did not write that file.

root

Absolute OpenFAST output root, without a suffix.

Type:

pathlib.Path

cabledyn

CableDyn channel history <root>.CD.out; time in seconds.

Type:

TimeHistory | None

static

Coupled static line profile <root>.CD.static.out; lengths in metres and tensions in newtons.

Type:

StaticProfile | None

openfast

OpenFAST glue-code output <root>.out or <root>.outb.

Type:

TimeHistory | None

Comparing runs

compare_histories() aligns two TimeHistory tables on one time grid, without extrapolating beyond the interval they share, and reports error metrics and statistic changes for each channel. Differences are candidate minus reference, in the unit of the channel.

cabledyn.compare_histories(reference, candidate, *, channels=None, start=None, stop=None, grid='reference', percentile=95.0, check_units=True)

Compare candidate against reference channel by channel.

Parameters:
  • reference (TimeHistory) – Reference record.

  • candidate (TimeHistory) – Record compared against it.

  • channels (str | collections.abc.Iterable[str] | collections.abc.Mapping[str, str] | None) – None compares every non-time channel present in both tables under the same name. A name or list of names compares those names; a mapping {reference_name: candidate_name} pairs differently named channels (for example {"FairTen1": "FAIRTEN1"}).

  • start (float | None) – Optional period, in seconds, applied after restricting to the shared interval.

  • stop (float | None) – Optional period, in seconds, applied after restricting to the shared interval.

  • grid (str) – "reference" (default) interpolates the candidate onto the reference samples; "candidate" does the reverse.

  • percentile (float) – Percentile in [0, 100] reported as percentile_delta.

  • check_units (bool) – When both tables record a unit for a pair, a mismatch raises ValueError unless this is false.

Returns:

The aligned time grid, in seconds, and one ChannelComparison per channel pair, with differences in the channel unit.

Return type:

HistoryComparison

Raises:
  • TypeError – If either argument is not a TimeHistory.

  • KeyError – If a requested channel is missing from its table.

  • ValueError – If grid or percentile is invalid, a limit is not finite, no channel can be paired, the time channel is requested, the aligned period has fewer than two samples, or the units of a pair differ.

class cabledyn.HistoryComparison(reference, candidate, time, percentile, channels)

Comparison of every selected channel over one aligned time grid.

reference

Source file of the reference history.

Type:

pathlib.Path

candidate

Source file of the candidate history.

Type:

pathlib.Path

time

Read-only (n_samples,) aligned sample times, in seconds.

Type:

numpy.ndarray

percentile

Percentile, in [0, 100], used for ChannelComparison.percentile_delta.

Type:

float

channels

One comparison per channel pair, in the requested order.

Type:

tuple[ChannelComparison, …]

property start_time

First aligned sample time in seconds.

property end_time

Last aligned sample time in seconds.

channel(name)

Return the comparison of reference channel name.

Parameters:

name (str) – Reference channel name.

Returns:

The metrics for that channel.

Return type:

ChannelComparison

Raises:

KeyError – If the channel was not compared.

worst(count=1, *, metric='normalized_rms_difference')

Return the count channels with the largest metric (nan last).

Parameters:
  • count (int) – Positive number of channels to return; fewer are returned when fewer were compared.

  • metric (str) – Name of a numeric ChannelComparison field. Channels are ranked by its absolute value.

Returns:

Up to count comparisons, largest abs(metric) first.

Return type:

tuple[ChannelComparison, …]

Raises:

ValueError – If metric is not a numeric field or count is not a positive integer.

export(path, *, overwrite=False)

Atomically write one CSV row per channel with every metric.

The header row holds the ChannelComparison field names.

Parameters:
  • path (str | os.PathLike) – Target CSV file. Missing parent directories are created.

  • overwrite (bool) – Replace an existing file instead of raising FileExistsError.

Returns:

Absolute path of the written file.

Return type:

pathlib.Path

Raises:
  • FileExistsError – If path exists and overwrite is false.

  • ValueError – If path is one of the compared result files.

class cabledyn.ChannelComparison(channel, candidate_channel, unit, count, max_abs_difference, mean_difference, rms_difference, normalized_rms_difference, relative_max_difference, correlation, reference_maximum, candidate_maximum, maximum_delta, minimum_delta, mean_delta, standard_deviation_delta, percentile_delta)

Error metrics for one channel pair, difference = candidate - reference.

normalized_rms_difference divides the RMS difference by the reference standard deviation and relative_max_difference divides the largest absolute difference by the largest absolute reference value; either is nan when its denominator is zero. correlation is the Pearson coefficient, nan when either signal is constant. The *_delta members are candidate minus reference for the statistic named, and percentile_delta uses HistoryComparison.percentile.

Differences, deltas, and maxima are in the unit of the channel (for example N for a tension, m for a position).

channel

Reference channel name.

Type:

str

candidate_channel

Candidate channel name paired with it.

Type:

str

unit

Channel unit (the reference unit when recorded, otherwise the candidate unit), or None if unknown.

Type:

str | None

count

Number of aligned samples compared.

Type:

int

max_abs_difference

Largest absolute difference.

Type:

float

mean_difference

Mean difference (bias).

Type:

float

rms_difference

Root-mean-square difference.

Type:

float

normalized_rms_difference

RMS difference over the reference standard deviation; dimensionless.

Type:

float

relative_max_difference

Largest absolute difference over the largest absolute reference value; dimensionless.

Type:

float

correlation

Pearson correlation coefficient, in [-1, 1].

Type:

float

reference_maximum

Largest aligned reference value.

Type:

float

candidate_maximum

Largest aligned candidate value.

Type:

float

maximum_delta

Change of the maximum.

Type:

float

minimum_delta

Change of the minimum.

Type:

float

mean_delta

Change of the mean.

Type:

float

standard_deviation_delta

Change of the population standard deviation.

Type:

float

percentile_delta

Change of the HistoryComparison.percentile percentile.

Type:

float

Signal processing

Each function returns a new table of the same class as its input, with the same channels, units, source path, and title; the input is never modified. The filters require uniform sampling, so resample a variable-step record first.

cabledyn.resample(history, *, step=None, times=None, start=None, stop=None)

Linearly interpolate every channel onto new sample times.

Give exactly one of step (a uniform grid from start, default the first sample, up to and including stop, default the last sample) or times (strictly increasing values inside the recorded interval).

Parameters:
  • history (TimeHistory) – Record to resample; any TimeHistory subclass.

  • step (float | None) – Positive uniform time step, in seconds.

  • times (array_like | None) – (n_samples,) strictly increasing sample times, in seconds, inside the recorded interval.

  • start (float | None) – Uniform-grid limits, in seconds; allowed only with step.

  • stop (float | None) – Uniform-grid limits, in seconds; allowed only with step.

Returns:

A new table of the same class as history, with values of shape (n_samples, n_channels) and every channel in its original unit.

Return type:

TimeHistory

Raises:

ValueError – If not exactly one of step and times is given, start or stop accompanies times, a value is not finite, step is not positive, start exceeds stop, times is not strictly increasing, or a requested time lies outside the recorded interval.

cabledyn.moving_average(history, window, *, channels=None, uniform_rtol=1e-06)

Return the centred moving mean over window samples (an odd integer >= 1).

Unselected channels are kept at the retained sample times unchanged. The first and last window // 2 samples are dropped.

Parameters:
  • history (TimeHistory) – Uniformly sampled record; any TimeHistory subclass.

  • window (int) – Odd, positive number of samples averaged, at most the sample count.

  • channels (str | collections.abc.Iterable[str] | None) – Channels to smooth; every non-time channel when None.

  • uniform_rtol (float) – Relative tolerance for accepting the time steps as uniform.

Returns:

A new table of the same class as history with n_samples - 2 * (window // 2) rows; units are unchanged.

Return type:

TimeHistory

Raises:
  • KeyError – If a selected channel is not in the table.

  • ValueError – If window is not an odd positive integer or exceeds the record, no channel or the time channel is selected, or the sampling is not uniform.

cabledyn.fft_filter(history, *, low=None, high=None, channels=None, detrend='linear', uniform_rtol=1e-06)

Keep only the frequency band low <= f <= high (Hz) with a zero-phase FFT filter.

Give high alone for a low-pass, low alone for a high-pass, or both for a band-pass filter.

The FFT treats the record as periodic, so a record whose ends do not match rings near its ends. With detrend="linear" (default) the least-squares straight line is subtracted before the transform, which removes the largest end mismatch of a drifting record, and restored afterwards only for a low-pass filter, whose band includes zero frequency. detrend="none" filters the record as it is, which is exact for a record holding a whole number of periods of every component. The filter is ideal, not tapered: judge results away from the record ends and sharp transients.

Parameters:
  • history (TimeHistory) – Uniformly sampled record; any TimeHistory subclass.

  • low (float | None) – Positive lower pass-band edge, in Hz; None for a low-pass filter.

  • high (float | None) – Positive upper pass-band edge, in Hz; None for a high-pass filter. A low-pass edge must lie below the Nyquist frequency.

  • channels (str | collections.abc.Iterable[str] | None) – Channels to filter; every non-time channel when None. Other channels are returned unchanged.

  • detrend (str) – "linear" or "none", as described above.

  • uniform_rtol (float) – Relative tolerance for accepting the time steps as uniform.

Returns:

A new table of the same class and shape as history, with the same sample times and units.

Return type:

TimeHistory

Raises:
  • KeyError – If a selected channel is not in the table.

  • ValueError – If neither edge is given, an edge is not finite and positive, low >= high, detrend is unknown, no channel or the time channel is selected, the sampling is not uniform, a low-pass edge reaches the Nyquist frequency, or the pass band holds no frequency bin.

Fatigue analysis

TimeHistory.fatigue() is the usual entry point. The functions below apply the same rainflow counting and damage-equivalent-range calculation to any scalar sequence.

cabledyn.rainflow_cycles(values, *, time=None)

Count Downing–Socie/ASTM-style cycles in a finite scalar history.

Complete closed cycles have weight 1.0. Unclosed residual cycles have weight 0.5, following the wind-energy convention used by NREL MLife.

Parameters:
  • values (collections.abc.Iterable[float] | numpy.ndarray) – Non-empty, finite, one-dimensional load history.

  • time (collections.abc.Iterable[float] | numpy.ndarray | None) – Optional strictly increasing sample times, in seconds, one per value. When given, each cycle also records its bounding times.

Returns:

The counted cycles; empty for a constant history.

Return type:

tuple[RainflowCycle, …]

Raises:

ValueError – If the history or the times are empty, not finite, or mismatched, or the times do not strictly increase.

cabledyn.cycle_histogram(cycles, bins)

Group weighted cycle counts by range without altering DEL calculations.

Parameters:
  • cycles (collections.abc.Iterable[RainflowCycle]) – Cycles to group, typically from rainflow_cycles().

  • bins (int | collections.abc.Iterable[float]) – A number of equal-width bins from zero to the largest range, or explicit strictly increasing edges that span every cycle range.

Returns:

The weighted counts per bin.

Return type:

RainflowHistogram

Raises:

ValueError – If bins is invalid, the edges do not span every range, or a bin count is requested for an empty cycle set.

cabledyn.damage_equivalent_range(cycles, *, wohler_exponent, reference_cycles)

Return the uncorrected DEL range for an explicit reference cycle count.

The damage-equivalent range is (sum(n_i * S_i**m) / reference_cycles) ** (1 / m) over cycle weights n_i and ranges S_i, with m the Wohler exponent.

Parameters:
  • cycles (collections.abc.Iterable[RainflowCycle]) – Cycles to combine, typically from rainflow_cycles().

  • wohler_exponent (float) – Positive S-N curve slope exponent m.

  • reference_cycles (float) – Positive number of equivalent constant-range cycles.

Returns:

The damage-equivalent range; 0.0 for an empty cycle set.

Return type:

float

Raises:

ValueError – If the exponent or the reference cycle count is not finite and positive.

class cabledyn.FatigueResult(channel, source, unit, sample_count, start_time, end_time, duration, wohler_exponent, reference_cycles, equivalent_frequency, cycle_count, damage_equivalent_range, cycles, histogram=None)

Uncorrected short-term rainflow/DEL result for one channel.

Returned by cabledyn.TimeHistory.fatigue(). The damage-equivalent range (DEL) is the constant range that, applied reference_cycles times, gives the same Palmgren-Miner damage as the counted cycles for an S-N curve of slope wohler_exponent. No mean-stress correction is applied.

channel

Name of the analysed channel.

Type:

str

source

Absolute path of the result file the channel was read from.

Type:

pathlib.Path

unit

Channel unit, or None if unknown; ranges share this unit.

Type:

str | None

sample_count

Number of samples analysed.

Type:

int

start_time

Time of the first analysed sample, in seconds.

Type:

float

end_time

Time of the last analysed sample, in seconds.

Type:

float

duration

end_time - start_time, in seconds.

Type:

float

wohler_exponent

S-N curve slope exponent m.

Type:

float

reference_cycles

Number of equivalent constant-range cycles.

Type:

float

equivalent_frequency

reference_cycles / duration, in Hz.

Type:

float

cycle_count

Sum of the cycle weights.

Type:

float

damage_equivalent_range

The damage-equivalent range, in the channel unit.

Type:

float

cycles

Every counted cycle and half-cycle, in extraction order.

Type:

tuple[RainflowCycle, …]

histogram

Range histogram, present when bins were requested.

Type:

RainflowHistogram | None

plot_histogram(*, ax=None)

Plot weighted cycle counts against cycle range.

Parameters:

ax (matplotlib.axes.Axes | None) – Axes to draw on; a new figure is created when omitted.

Returns:

The axes drawn on.

Return type:

matplotlib.axes.Axes

Raises:

ValueError – If the result has no histogram.

export_histogram(path, *, overwrite=False)

Atomically export range-bin bounds, centres, and weighted counts.

Writes a CSV file with one row per bin, with bounds and centres in the channel unit. Missing parent directories are created.

Parameters:
  • path (str | os.PathLike) – Target CSV file.

  • overwrite (bool) – Replace an existing file instead of raising FileExistsError.

Returns:

Absolute path of the written file.

Return type:

pathlib.Path

Raises:
  • ValueError – If the result has no histogram or path is the source file.

  • FileExistsError – If path exists and overwrite is false.

export_cycles(path, *, overwrite=False)

Atomically export every exact rainflow cycle used by the DEL.

Writes a CSV file with one row per cycle: its weight, range, mean, and bounding sample indices, plus bounding times in seconds when they are known. Ranges and means are in the channel unit. Missing parent directories are created.

Parameters:
  • path (str | os.PathLike) – Target CSV file.

  • overwrite (bool) – Replace an existing file instead of raising FileExistsError.

Returns:

Absolute path of the written file.

Return type:

pathlib.Path

Raises:
  • ValueError – If path is the source file.

  • FileExistsError – If path exists and overwrite is false.

class cabledyn.RainflowCycle(range, mean, count, start_index, end_index, start_time=None, end_time=None)

One closed cycle or residual half-cycle from a load history.

range

Peak-to-trough range of the cycle (not its amplitude); positive.

Type:

float

mean

Mean of the two reversal values that bound the cycle.

Type:

float

count

Cycle weight: 1.0 for a closed cycle, 0.5 for a residual half-cycle.

Type:

float

start_index

Zero-based index of the first bounding reversal in the analysed samples.

Type:

int

end_index

Zero-based index of the second bounding reversal; greater than start_index.

Type:

int

start_time

Time of start_index, in seconds, when sample times were supplied.

Type:

float | None

end_time

Time of end_index, in seconds, when sample times were supplied.

Type:

float | None

class cabledyn.RainflowHistogram(bin_edges, counts)

Weighted rainflow counts grouped by cycle range.

bin_edges

Read-only, strictly increasing range-bin edges, one more than the bins.

Type:

numpy.ndarray

counts

Read-only weighted cycle count in each bin (half-cycles count 0.5).

Type:

numpy.ndarray

property bin_centers

Read-only arithmetic centres of the range bins.

property total_cycles

Weighted number of full-cycle equivalents in all bins.

Fatigue damage

A FatigueCurve gives cycles to failure for a stress range (S–N, MPa) or a normalised tension range (T–N). The factory functions return curves with published constants; the source is in each docstring and in FatigueCurve.source. channel_damage() and damage_along_arc() apply Palmgren–Miner damage to rainflow cycles, and lifetime_fatigue() weights the damage of several sea states over a design life.

class cabledyn.FatigueCurve(name, kind, m1, log_a1, m2=None, log_a2=None, source='', thickness_exponent=0.0, reference_thickness=None, endurance_limit=None)

A single-slope or bilinear S-N or T-N curve, N = a S^-m.

name

Curve label, for example "DNV-RP-C203 D (seawater, CP)".

Type:

str

kind

"S-N" (ranges are stress ranges in MPa) or "T-N" (ranges are tension ranges divided by a reference breaking strength).

Type:

str

m1

Inverse slope of the first (high-range, low-cycle) segment.

Type:

float

log_a1

log10 of the first segment’s intercept a1.

Type:

float

m2

Inverse slope of the second (low-range) segment of a bilinear curve; larger than m1. None for a single-slope curve.

Type:

float | None

log_a2

log10 of the second segment’s intercept; given with m2.

Type:

float | None

source

Publication the constants come from; empty for a user curve.

Type:

str

thickness_exponent

Thickness exponent k of a welded-steel curve; 0 when the curve has no thickness effect.

Type:

float

reference_thickness

Reference thickness, in millimetres, of the thickness correction; required when thickness_exponent is positive.

Type:

float | None

endurance_limit

Optional range, in the curve unit, at or below which a cycle does no damage. None (the default, and the published form of every built-in curve) keeps every cycle.

Type:

float | None

Raises:

ValueError – If a constant is not finite, a slope is not positive, only one of m2/log_a2 is given, m2 does not exceed m1, or the thickness settings are inconsistent.

property unit

The unit of the ranges the curve takes, "MPa" or "-".

property bilinear

Whether the curve has a second segment.

property transition_range

Range at which the two segments meet, in the curve unit; None if single-slope.

property transition_cycles

Cycles to failure at transition_range; None if single-slope.

cycles_to_failure(ranges)

Return the constant-range endurance N for each range.

Parameters:

ranges (array_like) – Non-negative, finite ranges in the curve unit.

Returns:

Read-only cycles to failure, of the shape of ranges; inf for a zero range or one at or below the endurance limit.

Return type:

numpy.ndarray

Raises:

ValueError – If a range is negative or not finite.

thickness_factor(thickness)

Return the stress-range factor (max(t, t_ref) / t_ref) ** k.

Multiply a nominal stress range by this factor to apply the thickness effect of a welded-steel curve.

Parameters:

thickness (float) – Positive plate or wall thickness, in millimetres.

Returns:

The factor; 1.0 for a curve without a thickness effect.

Return type:

float

Raises:

ValueError – If thickness is not finite and positive.

tension_scale(*, area=None, breaking_strength=None)

Return the factor that turns a tension range in newtons into a curve range.

An S-N curve needs the nominal cross-section area in square metres (the factor is 1 / (area * 1e6), giving MPa); a T-N curve needs the reference breaking_strength in newtons (the factor is 1 / breaking_strength).

Parameters:
  • area (float | None) – Nominal cross-section area, in m^2; S-N curves only.

  • breaking_strength (float | None) – Reference breaking strength, in N; T-N curves only.

Returns:

The multiplier from newtons to the curve unit.

Return type:

float

Raises:

ValueError – If the argument the curve kind needs is missing or not positive, or the other one is given.

cabledyn.dnv_rp_c203_curve(name, environment='air')

Return a DNV-RP-C203 S-N curve for welded or plain steel.

Source: DNV-RP-C203 Fatigue design of offshore steel structures (2016 edition, amended 2019), Table 2-1 (in air: m1 3 or 4 up to 1e7 cycles, m2 = 5 beyond), Table 2-2 (seawater with cathodic protection: m1 up to 1e6 cycles, m2 = 5 beyond), and Table 2-4 (free corrosion: single slope m = 3). The thickness exponent k is taken from the same tables, with the reference thickness of 25 mm for welded connections other than tubular joints. Stress ranges are in MPa.

Parameters:
  • name (str) – Curve class: B1, B2, C, C1, C2, D, E, F, F1, F3, G, W1, W2, or W3 (case-insensitive).

  • environment (str) – "air", "seawater_cp", or "free_corrosion".

Returns:

The S-N curve.

Return type:

FatigueCurve

Raises:

ValueError – If the curve class or the environment is not recognised.

cabledyn.dnv_os_e301_curve(component)

Return a DNV-OS-E301 fatigue curve for a mooring-line component.

Source: DNV-OS-E301 Position mooring, Ch.2 Sec.2, fatigue limit state, design curves n_c(s) = a_D s^-m:

Component

a_D

m

Range

studlink_chain

1.2e11

3.0

MPa

studless_chain

6.0e10

3.0

MPa

stranded_rope

3.4e14

4.0

MPa

spiral_strand_rope

1.7e17

4.8

MPa

polyester_rope

0.259

13.46

T/MBS

The chain and steel-rope ranges are nominal stress ranges in MPa (see chain_nominal_area() for chain). The polyester curve, from DNVGL-OS-E301 (July 2018), takes the tension range divided by the rope’s minimum breaking strength, so it is returned as a T-N curve.

Parameters:

component (str) – One of the component names in the table.

Returns:

The single-slope curve.

Return type:

FatigueCurve

Raises:

ValueError – If component is not recognised.

cabledyn.api_rp_2sk_curve(component, *, mean_load_ratio=None)

Return an API RP 2SK T-N curve, N R^M = K.

Source: API RP 2SK Design and Analysis of Stationkeeping Systems for Floating Structures, 3rd edition (2005), fatigue analysis T-N curves. R is the tension range divided by the reference breaking strength: for chain and connecting links, that of ORQ chain of the same diameter; for wire rope, the rope’s minimum breaking strength.

Component

M

K

studlink_chain

3.36

1000

studless_chain

3.36

316

connecting_link

3.36

178 (Baldt and Kenter links)

stranded_rope

4.09

10**(3.20 - 2.79 Lm)

spiral_strand_rope

5.05

10**(3.25 - 3.43 Lm)

Lm is the ratio of the mean tension to the reference breaking strength.

Parameters:
  • component (str) – One of the component names in the table.

  • mean_load_ratio (float | None) – Lm in [0, 1); required for wire rope and rejected for chain and links.

Returns:

The single-slope T-N curve.

Return type:

FatigueCurve

Raises:

ValueError – If component is not recognised, or mean_load_ratio is missing, out of range, or given for chain.

cabledyn.chain_nominal_area(diameter)

Return the nominal chain cross-section 2 * pi * d**2 / 4 in m^2.

DNV-OS-E301 (Ch.2 Sec.2, fatigue limit state) refers the chain stress range to the area of the two legs of a link, from the nominal bar diameter.

Parameters:

diameter (float) – Nominal chain (bar) diameter, in metres.

Returns:

The nominal area, in m^2.

Return type:

float

Raises:

ValueError – If diameter is not finite and positive.

cabledyn.miner_damage(cycles, curve, *, scale=1.0, ultimate_strength=None)

Return the Palmgren-Miner damage sum(n_i / N(S_i)) of rainflow cycles.

Each cycle range and mean is multiplied by scale to express it in the curve unit. With ultimate_strength (in the curve unit) the Goodman correction S_eq = S / (1 - S_mean / S_u) is applied to every cycle with a tensile mean; compressive means are left uncorrected.

Parameters:
  • cycles (collections.abc.Iterable[RainflowCycle]) – Counted cycles, typically from cabledyn.rainflow_cycles().

  • curve (FatigueCurve) – S-N or T-N curve.

  • scale (float) – Positive factor from the history unit to the curve unit, for example FatigueCurve.tension_scale().

  • ultimate_strength (float | None) – Ultimate strength for the Goodman correction, in the curve unit; None (the default) applies no correction.

Returns:

The damage; 0.0 for no cycles.

Return type:

float

Raises:

ValueError – If scale or ultimate_strength is not finite and positive, the cycles are not RainflowCycle values, or a cycle mean reaches the ultimate strength.

cabledyn.channel_damage(history, channel, curve, *, scale=1.0, ultimate_strength=None, start=None, stop=None)

Return the rainflow Palmgren-Miner damage of one channel.

Parameters:
  • history (TimeHistory) – Record to analyse.

  • channel (str) – Non-time channel, for example "FairTen1".

  • curve (FatigueCurve) – S-N or T-N curve.

  • scale (float) – Factor from the channel unit to the curve unit; for a tension channel use FatigueCurve.tension_scale().

  • ultimate_strength (float | None) – Enables the Goodman correction (see miner_damage()).

  • start (float | None) – Optional analysis window, in seconds.

  • stop (float | None) – Optional analysis window, in seconds.

Returns:

The damage and the settings that produced it.

Return type:

ChannelDamage

Raises:
  • KeyError – If the table has no channel of that name.

  • ValueError – If channel is the time channel, fewer than two samples are selected, or a setting is invalid.

class cabledyn.ChannelDamage(channel, source, curve, scale, goodman, duration, cycle_count, damage)

Palmgren-Miner damage of one channel over one record.

channel

Analysed channel.

Type:

str

source

Result file of the channel.

Type:

pathlib.Path

curve

Curve used.

Type:

FatigueCurve

scale

Factor applied to the channel to express it in the curve unit.

Type:

float

goodman

Whether the Goodman correction was applied.

Type:

bool

duration

Length of the analysed record, in seconds.

Type:

float

cycle_count

Sum of the rainflow cycle weights.

Type:

float

damage

Miner damage accumulated over duration.

Type:

float

property damage_rate

Damage per year of exposure to this record, damage * year / duration.

property fatigue_life

Years to a damage of one at damage_rate; inf for no damage.

cabledyn.cable_stress(tension, curvature, *, area, modulus, radius)

Return the axial stress at the outer and inner fibre, T/A +/- E kappa r.

This is the usual two-fibre recovery for a cable component (an armour wire or a conductor) at distance radius from the neutral axis. The solver’s curvature is a magnitude, so the bending stress is applied at the fibre on the outside (+) and the inside (-) of the bend; the rotation of the bending plane is not tracked.

Parameters:
  • tension (array_like) – Effective tension, in newtons.

  • curvature (array_like) – Curvature magnitude, in 1/m, broadcastable against tension.

  • area (float) – Positive area that carries the tension, in m^2.

  • modulus (float) – Positive Young’s modulus of the component, in Pa.

  • radius (float) – Non-negative distance of the fibre from the neutral axis, in metres.

Returns:

Read-only outer-fibre and inner-fibre stress, in Pa.

Return type:

tuple[numpy.ndarray, numpy.ndarray]

Raises:

ValueError – If a section property is invalid or a value is not finite.

cabledyn.damage_along_arc(history, line_id, curve, *, quantity='tension', area=None, breaking_strength=None, modulus=None, radius=None, ultimate_strength=None, arc_length=None, start=None, stop=None)

Return the Miner damage at every output node of a line.

With quantity="tension" the Ten<L>N<J> channels are counted: an S-N curve needs the nominal area and a T-N curve the reference breaking_strength (see FatigueCurve.tension_scale()).

With quantity="stress" the stress at the two extreme fibres is recovered from Ten<L>N<J> and Curv<L>N<J> by cable_stress() (area, modulus, and radius are required, and the curve must be S-N); each fibre is counted separately and the larger damage is kept. Both channels must be written for the same nodes.

Parameters:
  • history (TimeHistory) – Main output with the node channels.

  • line_id (int) – Deck line identifier.

  • curve (FatigueCurve) – S-N or T-N curve.

  • quantity (str) – "tension" or "stress".

  • area (float | None) – Section properties, in SI units, as described above.

  • breaking_strength (float | None) – Section properties, in SI units, as described above.

  • modulus (float | None) – Section properties, in SI units, as described above.

  • radius (float | None) – Section properties, in SI units, as described above.

  • ultimate_strength (float | None) – Enables the Goodman correction, in the curve unit.

  • arc_length (StaticProfile | collections.abc.Mapping[int, float] | None) – Node positions along the line (see cabledyn.node_range_graph()).

  • start (float | None) – Optional analysis window, in seconds.

  • stop (float | None) – Optional analysis window, in seconds.

Returns:

Damage at each output node.

Return type:

DamageProfile

Raises:
  • KeyError – If the needed node channels are missing.

  • ValueError – If quantity is unknown, a section property is missing or invalid, or the tension and curvature channels cover different nodes.

class cabledyn.DamageProfile(line_id, quantity, curve, node_ids, location_kind, location, damage, duration, source)

Palmgren-Miner damage at every output node of one line.

line_id

Deck line identifier.

Type:

int

quantity

"tension" or "stress".

Type:

str

curve

Curve used.

Type:

FatigueCurve

node_ids

Output nodes, in End-A-to-End-B order.

Type:

tuple[int, …]

location_kind

"ArcLength" or "Node".

Type:

str

location

(n,) arc length in metres, or node number.

Type:

numpy.ndarray

damage

(n,) damage over the record; for "stress" the larger of the two fibres.

Type:

numpy.ndarray

duration

Length of the analysed record, in seconds.

Type:

float

source

Result file.

Type:

pathlib.Path

property critical_node

Node with the largest damage.

property maximum_damage

Largest damage on the line.

plot(*, ax=None)

Plot damage against location on a logarithmic axis.

Parameters:

ax (matplotlib.axes.Axes | None) – Axes to draw on; a new figure is created when omitted.

Returns:

The axes drawn on.

Return type:

matplotlib.axes.Axes

cabledyn.study_sea_state_damage(study, probabilities, evaluate, *, start=None, stop=None)

Evaluate the short-term damage of each sea state of a batch study.

Each case named in probabilities must have completed. Its main output is read, trimmed to [start, stop] (for example to drop the start-up transient), and passed to evaluate, which returns the damage over that record: a number, an array, a ChannelDamage, or a DamageProfile. The duration is that of the returned result, or the trimmed record length for a plain number or array.

Parameters:
  • study (StudyResult) – Result of cabledyn.run_study().

  • probabilities (collections.abc.Mapping[str, float]) – Probability of occurrence of each case, by case name.

  • evaluate (collections.abc.Callable) – Damage of one trimmed record, for example lambda h: channel_damage(h, "FairTen1", curve, scale=s).

  • start (float | None) – Optional analysis window applied to every case, in seconds.

  • stop (float | None) – Optional analysis window applied to every case, in seconds.

Returns:

One entry per named case, in study order; pass them to lifetime_fatigue().

Return type:

tuple[SeaStateDamage, …]

Raises:
  • KeyError – If a named case is not in the study.

  • StudyOutputError – If a named case did not complete or has no main output.

  • ValueError – If probabilities is empty or a probability is invalid.

class cabledyn.SeaStateDamage(name, probability, duration, damage)

Short-term damage of one sea state and its probability of occurrence.

name

Sea-state (case) name.

Type:

str

probability

Fraction of the design life spent in this sea state, in (0, 1].

Type:

float

duration

Length of the simulated record that produced damage, in seconds.

Type:

float

damage

Read-only (n,) damage over duration: one value for a single channel, or one per location for a DamageProfile.

Type:

numpy.ndarray

Raises:

ValueError – If the name is empty, a value is out of range or not finite, or the damage is not a non-empty one-dimensional non-negative array.

property annual_damage

The read-only damage contribution per year, p * damage * year / duration.

cabledyn.lifetime_fatigue(states, *, design_life, design_factor=1.0)

Combine sea-state damage into annual and lifetime damage.

annual = DFF * sum(p_i * D_i * year / T_i) over sea states with probability p_i, short-term damage D_i over a record of T_i seconds, and design fatigue factor DFF; the lifetime damage is annual * design_life and the fatigue life 1 / annual years. A year is 365.25 days. The probabilities may sum to less than one (sea states that do no damage may be left out) but not to more.

Parameters:
  • states (collections.abc.Iterable[SeaStateDamage]) – Sea states with unique names and damage arrays of one shape.

  • design_life (float) – Positive design life, in years.

  • design_factor (float) – Positive design fatigue factor that multiplies the damage; 1.0 by default. Take its value from the governing standard.

Returns:

Annual damage, lifetime damage, and fatigue life per location.

Return type:

LifetimeFatigue

Raises:

ValueError – If there are no states, a name repeats, the damage shapes differ, the probabilities sum to more than one, or a setting is invalid.

class cabledyn.LifetimeFatigue(states, design_life, design_factor, annual_damage, lifetime_damage, fatigue_life)

Probability-weighted fatigue over a design life.

Arrays are read-only with one value per location (one for a single channel).

states

The weighted sea states.

Type:

tuple[SeaStateDamage, …]

design_life

Design life, in years.

Type:

float

design_factor

Design fatigue factor applied to the damage.

Type:

float

annual_damage

Factored damage per year, summed over the sea states.

Type:

numpy.ndarray

lifetime_damage

annual_damage * design_life; fatigue fails where it exceeds one.

Type:

numpy.ndarray

fatigue_life

1 / annual_damage, in years (inf where there is no damage).

Type:

numpy.ndarray

property total_probability

Sum of the sea-state probabilities.

property critical_index

Location index with the largest lifetime damage.

property maximum_lifetime_damage

Largest lifetime damage.

property minimum_fatigue_life

Shortest fatigue life, in years.

property passed

Whether the lifetime damage is at most one everywhere.

contributions()

Return each sea state’s share of the factored annual damage.

Returns:

Read-only factored annual damage per sea state, by name.

Return type:

dict[str, numpy.ndarray]

export(path, *, overwrite=False)

Atomically write the per-sea-state contributions as CSV.

One row per sea state and location index, with its probability, record duration, short-term damage, and factored annual damage.

Parameters:
  • path (str | os.PathLike) – Target CSV file; missing parent directories are created.

  • overwrite (bool) – Replace an existing file instead of raising FileExistsError.

Returns:

Absolute path of the written file.

Return type:

pathlib.Path

Raises:

FileExistsError – If path exists and overwrite is false.

Range graphs

class cabledyn.RangeGraph(line_id, quantity, unit, location_kind, location, maximum, minimum, mean, source, time_window=None)

Envelope of one quantity along one line.

Arrays are read-only and hold one value per location, in End-A-to-End-B order. minimum and mean are None when the source does not define them (an element table records only a peak curvature per element).

line_id

Deck line identifier; None when the source does not identify the line (a per-line file whose name has no .Line<L>. part).

Type:

int | None

quantity

"tension", "curvature", "bend_moment", for a range file also "declination" and "clearance", or, for an element table, "axial_resultant".

Type:

str

unit

Unit of the quantity: N, 1/m, N-m, deg, or m.

Type:

str | None

location_kind

"ArcLength" (location in metres from End A) or "Node" (location is the one-based node number).

Type:

str

location

(n,) non-decreasing locations.

Type:

numpy.ndarray

maximum

(n,) largest value at each location.

Type:

numpy.ndarray

minimum

(n,) smallest value at each location.

Type:

numpy.ndarray | None

mean

(n,) time-mean value at each location.

Type:

numpy.ndarray | None

source

Result file the graph was built from.

Type:

pathlib.Path

time_window

First and last sample time used, in seconds; None for a static or element source.

Type:

tuple[float, float] | None

Raises:

ValueError – If the arrays do not match, are not finite, the locations decrease, or minimum exceeds maximum somewhere.

property peak

Largest value on the line.

property peak_location

Location of peak (the first, if it repeats).

plot(*, ax=None, label=None)

Plot the envelope: a min-max band, the mean, and the maximum.

Parameters:
  • ax (matplotlib.axes.Axes | None) – Axes to draw on; a new figure is created when omitted. Pass the axes of an earlier graph to overlay, for example, a static profile on a dynamic envelope.

  • label (str | None) – Legend prefix; defaults to the quantity.

Returns:

The axes drawn on.

Return type:

matplotlib.axes.Axes

export(path, *, overwrite=False)

Atomically write the graph as a unit-labelled CSV, one row per location.

Columns: the location (ArcLength_[m] or Node_[-]), then Minimum, Maximum, and Mean in the quantity unit (blank where undefined).

Parameters:
  • path (str | os.PathLike) – Target CSV file; missing parent directories are created.

  • overwrite (bool) – Replace an existing file instead of raising FileExistsError.

Returns:

Absolute path of the written file.

Return type:

pathlib.Path

Raises:

FileExistsError – If path exists and overwrite is false.

cabledyn.read_range_graphs(source)

Return every range graph of a solver-side range file.

<root>.Line<L>.range.out is written by the driver for a line with the LINES Outputs flag r: the minimum, maximum, and mean over the output times of the range window of the node tension, curvature, bend moment, and declination, and the seabed clearance when the deck has a seabed, at every node against its arc length.

Parameters:

source (str | os.PathLike | OutputTable) – The range file, or the table cabledyn.read_output() read from it.

Returns:

"tension", "curvature", "bend_moment", "declination", and, with a seabed, "clearance".

Return type:

dict[str, RangeGraph]

Raises:
  • OutputFormatError – If the file is not a valid output table.

  • ValueError – If the table is not a range file.

cabledyn.read_range_graph(source, quantity)

Return one range graph of a solver-side range file.

Parameters:
  • source (str | os.PathLike | OutputTable) – The range file <root>.Line<L>.range.out, or its table.

  • quantity (str) – "tension", "curvature", "bend_moment", "declination", or "clearance".

Returns:

Minimum, maximum, and mean at every node against the arc length from End A at the start of the run, with the range window as time_window.

Return type:

RangeGraph

Raises:
  • KeyError – If the file has no such quantity (clearance needs a seabed).

  • ValueError – If quantity is unknown or the table is not a range file.

cabledyn.node_range_graph(history, line_id, quantity, *, arc_length=None, start=None, stop=None)

Return the dynamic range graph of one line from its node channels.

Parameters:
  • history (TimeHistory) – Main output holding Ten<L>N<J>, Curv<L>N<J>, or BendMom<L>N<J> channels (matched case-insensitively, leading zeros allowed).

  • line_id (int) – Deck line identifier L.

  • quantity (str) – "tension", "curvature", or "bend_moment".

  • arc_length (StaticProfile | collections.abc.Mapping[int, float] | None) – Where each node lies along the line: a static profile of the same run, a mapping from node number to arc length in metres, or None to use node numbers.

  • start (float | None) – Optional time window, in seconds.

  • stop (float | None) – Optional time window, in seconds.

Returns:

Minimum, maximum, and mean at each output node.

Return type:

RangeGraph

Raises:
  • KeyError – If the line has no channel of that quantity, or arc_length lacks one of its nodes.

  • ValueError – If quantity or line_id is invalid, two channels name the same node, or the window is invalid.

cabledyn.static_range_graph(profile, line_id, quantity)

Return the static range graph of one line from a static profile.

The minimum, maximum, and mean are the static value itself.

Parameters:
  • profile (StaticProfile) – A .static.out table.

  • line_id (int) – Deck line identifier.

  • quantity (str) – "tension", "curvature", or "bend_moment".

Returns:

The static value against arc length.

Return type:

RangeGraph

Raises:
  • KeyError – If the line or the column is not in the profile.

  • ValueError – If quantity or line_id is invalid.

cabledyn.element_range_graph(table, line_id, quantity)

Return a range graph of one line from a cubic-Hermite element table.

Locations are unstretched (reference) arc lengths from End A. "curvature" and "bend_moment" give each element’s peak at the arc where it occurs (PeakReferenceArc), with no minimum or mean. "axial_resultant" gives the minimum and maximum axial force resultant of each element, placed at the element’s mid-arc.

Parameters:
  • table (OutputTable) – A .elements.out table read with cabledyn.read_output().

  • line_id (int) – Deck line identifier.

  • quantity (str) – "curvature", "bend_moment", or "axial_resultant".

Returns:

The element envelope against reference arc length.

Return type:

RangeGraph

Raises:
  • KeyError – If the line is not in the table.

  • ValueError – If the table lacks an element-table column, or quantity or line_id is invalid.

Design checks

cabledyn.bend_check(source, limits, *, condition, line_id, arc_length=None, start=None, stop=None)

Check the curvature of one line against the storage or dynamic MBR.

Sources:

  • a main output TimeHistory – the Curv<L>N<J> node channels, with the time of the governing curvature;

  • a StaticProfile – its Curvature column;

  • a cubic-Hermite element table (.elements.out) – the peak curvature of each element, found between the nodes.

Parameters:
  • source (TimeHistory | StaticProfile | OutputTable) – Result holding the curvature.

  • limits (BendLimits | float) – The cable’s MBRs, or one MBR in metres.

  • condition (str) – "storage" or "dynamic": which MBR of limits applies, and the label of the report.

  • line_id (int) – Deck line identifier.

  • arc_length (StaticProfile | collections.abc.Mapping[int, float] | None) – Node positions for a time-history source (see cabledyn.node_range_graph()).

  • start (float | None) – Optional time window for a time-history source, in seconds.

  • stop (float | None) – Optional time window for a time-history source, in seconds.

Returns:

Utilisation along the line with the governing location and time.

Return type:

BendCheck

Raises:
  • KeyError – If the line or its curvature is missing from source.

  • ValueError – If condition or limits is invalid, or the window or time arguments do not apply to the source.

class cabledyn.BendLimits(storage_mbr, dynamic_mbr)

Minimum bend radii of a cable, from its manufacturer.

storage_mbr

MBR without tension (storage, handling, static lay), in metres.

Type:

float

dynamic_mbr

MBR in dynamic service, in metres; normally larger than the storage MBR.

Type:

float

Raises:

ValueError – If a radius is not finite and positive.

mbr(condition)

Return the MBR of "storage" or "dynamic".

Raises:

ValueError – If condition is neither.

class cabledyn.BendCheck(line_id, condition, mbr, location_kind, location, curvature, utilisation, critical_time, source)

Bend-radius check of one line against one MBR.

line_id

Deck line identifier.

Type:

int

condition

"storage" or "dynamic".

Type:

str

mbr

Minimum bend radius checked against, in metres.

Type:

float

location_kind

"ArcLength" (metres from End A) or "Node".

Type:

str

location

(n,) checked locations.

Type:

numpy.ndarray

curvature

(n,) largest curvature magnitude at each location, in 1/m.

Type:

numpy.ndarray

utilisation

(n,) curvature * mbr.

Type:

numpy.ndarray

critical_time

Time of the governing curvature, in seconds; None for a static source.

Type:

float | None

source

Result file checked.

Type:

pathlib.Path

property maximum_utilisation

Largest utilisation on the line.

property passed

Whether the utilisation is at most one everywhere.

property critical_location

Location of the largest utilisation.

property minimum_radius

Smallest bend radius, in metres (inf for a straight line).

report()

Return a one-line pass/fail summary with the governing location and time.

plot(*, ax=None)

Plot utilisation along the line with the limit of one.

Parameters:

ax (matplotlib.axes.Axes | None) – Axes to draw on; a new figure is created when omitted.

Returns:

The axes drawn on.

Return type:

matplotlib.axes.Axes

export(path, *, overwrite=False)

Atomically write location, curvature, radius, and utilisation as CSV.

Parameters:
  • path (str | os.PathLike) – Target CSV file; missing parent directories are created.

  • overwrite (bool) – Replace an existing file instead of raising FileExistsError.

Returns:

Absolute path of the written file.

Return type:

pathlib.Path

Raises:

FileExistsError – If path exists and overwrite is false.

cabledyn.mbr_utilisation(curvature, mbr)

Return the bend utilisation |kappa| * MBR (at most one to pass).

Parameters:
  • curvature (array_like) – Curvature, in 1/m.

  • mbr (float) – Positive minimum bend radius, in metres.

Returns:

Read-only utilisation, of the shape of curvature.

Return type:

numpy.ndarray

Raises:

ValueError – If mbr is invalid or a curvature is not finite.

cabledyn.tension_check(history, channels, *, breaking_strength, condition='intact', standard='API RP 2SK', analysis=None, consequence_class=None, safety_factor=None, strength_factor=None, start=None, stop=None)

Check line tension against the minimum breaking load.

standard selects the format:

  • "API RP 2SK" – T_max <= MBL / SF with the factor of safety of API_RP_2SK_SAFETY_FACTORS for condition ("intact", "damaged", or "transient") and analysis ("dynamic" or "quasi-static");

  • "DNV-OS-E301" – gamma_mean T_mean + gamma_dyn T_dyn <= S_C with the partial factors of DNV_OS_E301_PARTIAL_FACTORS: ULS for "intact", ALS for "damaged", in consequence_class 1 or 2. T_mean is the window mean and T_dyn = T_max - T_mean. The characteristic strength is S_C = strength_factor MBS; the default DNV_OS_E301_STRENGTH_FACTOR (0.95) is the standard’s value for a new chain or steel-wire-rope line body, so give the factor of the design basis for other line bodies (fibre rope, cable);

  • "custom" – T_max <= MBL / safety_factor.

The governing channel is the one with the largest utilisation. Run the check once on the intact and once on the damaged (one line removed) simulation.

Parameters:
  • history (TimeHistory) – Record holding the tension channels, in newtons.

  • channels (str | collections.abc.Sequence[str]) – Tension channel(s) to check, for example "FairTen1".

  • breaking_strength (float) – Minimum breaking load (MBL/MBS) of the line, in newtons.

  • condition (str) – "intact", "damaged", or (API RP 2SK and custom only) "transient".

  • standard (str) – "API RP 2SK", "DNV-OS-E301", or "custom".

  • analysis (str | None) – API RP 2SK analysis method: "dynamic" (default) or "quasi-static"; rejected for the other standards.

  • consequence_class (int | None) – DNV-OS-E301 consequence class, 1 (default) or 2; rejected for the other standards.

  • safety_factor (float | None) – Factor of safety; required for "custom" and rejected otherwise.

  • strength_factor (float | None) – DNV-OS-E301 characteristic-strength factor S_C / MBS, in (0, 1]; default DNV_OS_E301_STRENGTH_FACTOR. Rejected for the other standards.

  • start (float | None) – Optional time window, in seconds.

  • stop (float | None) – Optional time window, in seconds.

Returns:

The governing channel’s check.

Return type:

TensionCheck

Raises:
  • KeyError – If a channel is missing.

  • ValueError – If a setting is invalid for the chosen standard, or no channel is given.

cabledyn.DNV_OS_E301_STRENGTH_FACTOR: float = 0.95

DNV-OS-E301 characteristic strength of a new chain or steel-wire-rope line body, S_C = 0.95 S_mbs: the default strength_factor of cabledyn.tension_check(). Other line bodies take the factor of their design basis.

class cabledyn.TensionCheck(standard, condition, channel, time, maximum_tension, mean_tension, design_tension, capacity, utilisation, factors)

Tension check of the governing channel against the breaking strength.

utilisation = design_tension / capacity, which must not exceed one.

standard

"API RP 2SK", "DNV-OS-E301", or "custom".

Type:

str

condition

"intact", "damaged", or "transient".

Type:

str

channel

Governing channel.

Type:

str

time

Time of its maximum tension, in seconds.

Type:

float

maximum_tension

Largest tension of the governing channel, in newtons.

Type:

float

mean_tension

Its mean tension over the window, in newtons.

Type:

float

design_tension

Factored demand, in newtons: the maximum tension for the factor-of-safety format, gamma_mean T_mean + gamma_dyn T_dyn for DNV-OS-E301.

Type:

float

capacity

Resistance, in newtons: MBL / factor of safety, or 0.95 MBS for DNV-OS-E301.

Type:

float

utilisation

design_tension / capacity.

Type:

float

factors

The factor of safety, or (gamma_mean, gamma_dyn).

Type:

tuple[float, …]

property passed

Whether the utilisation is at most one.

report()

Return a one-line pass/fail summary.

cabledyn.API_RP_2SK_SAFETY_FACTORS: dict[tuple[str, str], float]

API RP 2SK (3rd edition, 2005) factors of safety on the maximum line tension, keyed by (condition, analysis): intact 2.00 (quasi-static) and 1.67 (dynamic), damaged (one line broken) 1.43 and 1.25, transient 1.18 and 1.05.

cabledyn.DNV_OS_E301_PARTIAL_FACTORS: dict[tuple[str, int], tuple[float, float]]

DNV-OS-E301 (Ch.2 Sec.2) partial safety factors (gamma_mean, gamma_dyn) on the mean and dynamic tension, keyed by (limit state, consequence class): ULS class 1 (1.10, 1.50), ULS class 2 (1.40, 2.10), ALS class 1 (1.00, 1.10), ALS class 2 (1.00, 1.25).

Spectral analysis

TimeHistory.spectrum() and TimeHistory.coherence() are the usual entry points. The functions below apply the same Welch estimators to arrays held in memory.

cabledyn.power_spectrum(time, values, *, channel, source, unit, segment_length, overlap=0.5, fft_length=None, window='hann', detrend='constant', uniform_rtol=1e-06, uniform_atol=0.0)

Calculate an explicitly configured one-sided Welch PSD density.

The record is split into segments of segment_length samples, each is detrended, windowed, and transformed, and the periodograms are averaged. Incomplete trailing samples are not used. The data are never resampled.

Parameters:
  • time (array_like) – Strictly increasing, uniformly spaced sample times, in seconds.

  • values (array_like) – Finite channel samples, one per time.

  • channel (str) – Channel name recorded in the result.

  • source (pathlib.Path) – Result file the samples came from, recorded in the result.

  • unit (str | None) – Channel unit, or None if unknown.

  • segment_length (int) – Samples per Welch segment; at least 2 and at most the sample count.

  • overlap (float) – Fraction of a segment shared with the next, in [0, 1).

  • fft_length (int | None) – FFT length; None uses segment_length. A longer length zero-pads each segment.

  • window (str) – "hann" (periodic Hann) or "boxcar".

  • detrend (str) – "constant" removes each segment’s mean; "none" keeps it.

  • uniform_rtol (float) – Relative and absolute tolerances for accepting the time steps as uniform.

  • uniform_atol (float) – Relative and absolute tolerances for accepting the time steps as uniform.

Returns:

The spectrum and the settings that produced it.

Return type:

PowerSpectrum

Raises:

ValueError – If the samples are not finite, uniformly sampled, and strictly increasing in time, or a setting is out of range.

cabledyn.magnitude_squared_coherence(time, x, y, *, channel_x, channel_y, source, segment_length, overlap=0.5, fft_length=None, window='hann', detrend='constant', power_floor_ratio=2.220446049250313e-14, uniform_rtol=1e-06, uniform_atol=0.0)

Calculate Welch magnitude-squared coherence without asserting zero-power bins.

Uses the same segmenting and windowing as power_spectrum(). At least two complete segments are required, because a single segment always gives a coherence of one.

Parameters:
  • time (array_like) – Strictly increasing, uniformly spaced sample times, in seconds.

  • x (array_like) – Finite samples of the two channels, one per time.

  • y (array_like) – Finite samples of the two channels, one per time.

  • channel_x (str) – Distinct channel names recorded in the result.

  • channel_y (str) – Distinct channel names recorded in the result.

  • source (pathlib.Path) – Result file the samples came from, recorded in the result.

  • segment_length (int) – Samples per Welch segment.

  • overlap (float) – Fraction of a segment shared with the next, in [0, 1).

  • fft_length (int | None) – FFT length; None uses segment_length.

  • window (str) – "hann" (periodic Hann) or "boxcar".

  • detrend (str) – "constant" removes each segment’s mean; "none" keeps it.

  • power_floor_ratio (float) – A bin is valid only where both auto-spectra exceed this fraction of their maxima. Must lie in [0, 1).

  • uniform_rtol (float) – Relative and absolute tolerances for accepting the time steps as uniform.

  • uniform_atol (float) – Relative and absolute tolerances for accepting the time steps as uniform.

Returns:

The coherence, its valid-bin mask, and the settings that produced it.

Return type:

CoherenceResult

Raises:

ValueError – If the samples are not uniformly sampled, fewer than two segments fit, or a setting is out of range.

class cabledyn.PowerSpectrum(channel, source, unit, start_time, end_time, sample_interval, sample_count, segment_length, overlap_samples, fft_length, segment_count, window, detrend, uniform_rtol, uniform_atol, frequency, density)

One-sided Welch power spectral density for one uniformly sampled channel.

Usually obtained from cabledyn.TimeHistory.spectrum() or cabledyn.power_spectrum(). The density is scaled so that integrating it over frequency recovers the mean-square value of the detrended signal.

channel

Name of the analysed channel.

Type:

str

source

Absolute path of the result file the channel was read from.

Type:

pathlib.Path

unit

Engineering unit of the channel, or None if unknown.

Type:

str | None

start_time

Time of the first analysed sample, in seconds.

Type:

float

end_time

Time of the last analysed sample, in seconds.

Type:

float

sample_interval

Uniform sample interval, in seconds.

Type:

float

sample_count

Number of samples in the analysed record.

Type:

int

segment_length

Number of samples in each Welch segment.

Type:

int

overlap_samples

Number of samples shared by consecutive segments.

Type:

int

fft_length

FFT length; larger than segment_length when segments are zero-padded.

Type:

int

segment_count

Number of complete segments averaged.

Type:

int

window

Segment window, "hann" or "boxcar".

Type:

str

detrend

Per-segment detrending, "constant" (mean removal) or "none".

Type:

str

uniform_rtol

Relative tolerance used to accept the sample times as uniform.

Type:

float

uniform_atol

Absolute tolerance used to accept the sample times as uniform, in seconds.

Type:

float

frequency

Read-only bin frequencies from 0 Hz to the Nyquist frequency, in Hz.

Type:

numpy.ndarray

density

Read-only one-sided power spectral density in each bin, in density_unit.

Type:

numpy.ndarray

property density_unit

Unit of density, for example N^2/Hz, or None if unknown.

property frequency_resolution

Spacing between adjacent frequency bins, in Hz.

moment_unit(order)

Return the engineering unit of a spectral moment of order.

Parameters:

order (float) – Finite moment order.

Returns:

The squared channel unit times Hz^order (for example "N^2*Hz^2"), or None when the channel unit is unknown.

Return type:

str | None

Raises:

ValueError – If order is not finite.

moment(order, *, minimum_frequency=None, maximum_frequency=None)

Integrate f**order * PSD over an explicit closed frequency band.

Parameters:
  • order (float) – Moment order. Over the full band, the zeroth moment estimates the variance of the signal (its mean square when detrend="none").

  • minimum_frequency (float | None) – Closed band limits in Hz. None selects the first or last bin.

  • maximum_frequency (float | None) – Closed band limits in Hz. None selects the first or last bin.

Returns:

The spectral moment, in moment_unit() units.

Return type:

float

Raises:

ValueError – If the band holds fewer than two bins, the limits are not finite, non-negative, and ordered, or a negative order would include 0 Hz.

dominant_peaks(count=1, *, minimum_frequency=0.0, maximum_frequency=None, include_dc=False)

Return the strongest local-maxima bins, ordered by decreasing density.

A flat-topped maximum spanning several equal bins counts as one peak, reported at its lowest-frequency bin.

Parameters:
  • count (int) – Maximum number of peaks to return.

  • minimum_frequency (float | None) – Closed search band in Hz. maximum_frequency=None searches up to the Nyquist frequency.

  • maximum_frequency (float | None) – Closed search band in Hz. maximum_frequency=None searches up to the Nyquist frequency.

  • include_dc (bool) – Whether the 0 Hz bin may be reported as a peak.

Returns:

At most count peaks; empty if the band has no local maximum.

Return type:

tuple[SpectralPeak, …]

export(path, *, overwrite=False)

Atomically write the spectrum to a CSV file.

The file has a frequency_[Hz] column and a PSD column whose header carries density_unit. Values are written with 17 significant digits.

Parameters:
  • path (str | os.PathLike) – Target file. Missing parent directories are created.

  • overwrite (bool) – Replace an existing file instead of raising FileExistsError.

Returns:

Absolute path of the written file.

Return type:

pathlib.Path

Raises:
  • FileExistsError – If path exists and overwrite is false.

  • ValueError – If path is the source result file.

plot(*, ax=None, logarithmic=False)

Plot the density against frequency using optional matplotlib.

Parameters:
  • ax (matplotlib.axes.Axes | None) – Axes to draw on; a new figure is created when omitted.

  • logarithmic (bool) – Use a logarithmic density axis.

Returns:

The axes drawn on.

Return type:

matplotlib.axes.Axes

class cabledyn.SpectralPeak(index, frequency, density)

A bin-centred local maximum; no sub-bin interpolation is implied.

index

Zero-based index of the peak bin in the spectrum arrays.

Type:

int

frequency

Centre frequency of the peak bin, in Hz.

Type:

float

density

Power spectral density in the peak bin, in the spectrum’s density unit.

Type:

float

property period

Bin-centred period in seconds, or infinity for the DC bin.

class cabledyn.CoherenceResult(channel_x, channel_y, source, start_time, end_time, sample_interval, sample_count, segment_length, overlap_samples, fft_length, segment_count, window, detrend, uniform_rtol, uniform_atol, power_floor_ratio, frequency, coherence, valid)

Magnitude-squared Welch coherence with an explicit valid-bin mask.

Usually obtained from cabledyn.TimeHistory.coherence() or cabledyn.magnitude_squared_coherence(). Bins in which either auto-spectrum falls below power_floor_ratio times its maximum carry no reliable phase information; they are marked invalid and hold NaN.

channel_x

Name of the first analysed channel.

Type:

str

channel_y

Name of the second analysed channel.

Type:

str

source

Absolute path of the result file the channels were read from.

Type:

pathlib.Path

start_time

Time of the first analysed sample, in seconds.

Type:

float

end_time

Time of the last analysed sample, in seconds.

Type:

float

sample_interval

Uniform sample interval, in seconds.

Type:

float

sample_count

Number of samples in the analysed record.

Type:

int

segment_length

Number of samples in each Welch segment.

Type:

int

overlap_samples

Number of samples shared by consecutive segments.

Type:

int

fft_length

FFT length; larger than segment_length when segments are zero-padded.

Type:

int

segment_count

Number of complete segments averaged; at least two.

Type:

int

window

Segment window, "hann" or "boxcar".

Type:

str

detrend

Per-segment detrending, "constant" (mean removal) or "none".

Type:

str

uniform_rtol

Relative tolerance used to accept the sample times as uniform.

Type:

float

uniform_atol

Absolute tolerance used to accept the sample times as uniform, in seconds.

Type:

float

power_floor_ratio

Relative auto-spectrum floor that defines valid bins, in [0, 1).

Type:

float

frequency

Read-only bin frequencies, in Hz.

Type:

numpy.ndarray

coherence

Read-only magnitude-squared coherence in [0, 1]; NaN in invalid bins.

Type:

numpy.ndarray

valid

Read-only Boolean mask of the bins whose coherence is defined.

Type:

numpy.ndarray

export(path, *, overwrite=False)

Atomically write the coherence to a CSV file.

The columns are frequency_[Hz], coherence_[-] (empty in invalid bins), and valid_[-] (1 or 0).

Parameters:
  • path (str | os.PathLike) – Target file. Missing parent directories are created.

  • overwrite (bool) – Replace an existing file instead of raising FileExistsError.

Returns:

Absolute path of the written file.

Return type:

pathlib.Path

Raises:
  • FileExistsError – If path exists and overwrite is false.

  • ValueError – If path is the source result file.

plot(*, ax=None)

Plot the coherence against frequency; invalid bins appear as gaps.

Parameters:

ax (matplotlib.axes.Axes | None) – Axes to draw on; a new figure is created when omitted.

Returns:

The axes drawn on.

Return type:

matplotlib.axes.Axes

Extreme values

block_maxima() and upcrossing_maxima() sample extremes from a record; fit_gumbel() and fit_weibull() fit a distribution to them. The fits describe the sample they are given: they do not check independence or stationarity, do not extrapolate a block length, and give no confidence interval.

cabledyn.block_maxima(history, channel, *, block_duration, start=None, stop=None, minima=False)

Return the extreme of each complete block of block_duration seconds.

Blocks start at the first selected sample and are half-open, [t0 + k T, t0 + (k + 1) T); the final block also includes a sample exactly at its end. A trailing incomplete block is discarded.

Parameters:
  • history (TimeHistory) – Record to sample.

  • channel (str) – Non-time channel whose extremes are taken.

  • block_duration (float) – Positive block length T, in seconds.

  • start (float | None) – Optional analysis window, in seconds.

  • stop (float | None) – Optional analysis window, in seconds.

  • minima (bool) – Return block minima instead of maxima.

Returns:

Read-only (n_blocks,) block extremes, in the channel unit, in time order.

Return type:

numpy.ndarray

Raises:
  • KeyError – If the table has no channel of that name.

  • ValueError – If channel is the time channel, block_duration is not finite and positive, the window is invalid, the record is shorter than one block, or a block holds no sample.

cabledyn.upcrossing_maxima(values, *, level=None)

Return the maximum between each pair of successive up-crossings of level.

level defaults to the sample mean. An up-crossing occurs between samples i and i + 1 when x[i] < level <= x[i + 1]. Samples before the first and after the last up-crossing are ignored, so only complete cycles contribute.

Parameters:
  • values (array_like) – At least three finite samples, in time order; flattened to 1-D.

  • level (float | None) – Finite crossing level, in the unit of values; None uses the sample mean.

Returns:

Read-only (n_crossings - 1,) cycle maxima, in the unit of values, in time order.

Return type:

numpy.ndarray

Raises:

ValueError – If there are fewer than three finite values, level is not finite, or fewer than two up-crossings occur.

cabledyn.fit_gumbel(maxima, *, method='mle')

Fit a Gumbel distribution to a sample of maxima.

"mle" solves the maximum-likelihood equations exactly (the scale by bisection, then the location in closed form); "moments" uses scale = s sqrt(6) / pi with the unbiased sample standard deviation s and location = mean - 0.5772 scale.

Parameters:
  • maxima (array_like) – At least two finite, not all equal, sample maxima (for example from block_maxima()); flattened to 1-D.

  • method (str) – "mle" (default) or "moments".

Returns:

Fitted location and scale, in the unit of maxima.

Return type:

GumbelFit

Raises:

ValueError – If the sample is too small, not finite, or constant, or method is unknown.

class cabledyn.GumbelFit(location, scale, sample_count, method)

Gumbel largest-extreme distribution F(x) = exp(-exp(-(x - location) / scale)).

location

Finite location (mode) parameter, in the unit of the fitted sample.

Type:

float

scale

Finite, positive scale parameter, in the unit of the fitted sample.

Type:

float

sample_count

Number of maxima fitted.

Type:

int

method

Estimator used: "mle" or "moments".

Type:

str

Raises:

ValueError – If location is not finite or scale is not finite and positive.

cdf(value)

Non-exceedance probability of value.

Parameters:

value (array_like) – Values, in the unit of the fitted sample; any shape.

Returns:

Read-only probabilities F(value) in [0, 1], with the shape of value.

Return type:

numpy.ndarray

quantile(probability)

Value with non-exceedance probability (strictly between 0 and 1).

Parameters:

probability (float) – Non-exceedance probability, strictly between 0 and 1.

Returns:

location - scale * ln(-ln(probability)), in the unit of the fitted sample.

Return type:

float

Raises:

ValueError – If probability is not strictly between 0 and 1.

most_probable_maximum(blocks=1.0)

Mode of the maximum over blocks fitted blocks, location + scale ln(blocks).

blocks = 1 gives the mode of the fitted block maximum itself. A larger count assumes independent, identically distributed blocks.

Parameters:

blocks (float) – Finite number of blocks, at least 1.

Returns:

Most probable maximum, in the unit of the fitted sample.

Return type:

float

Raises:

ValueError – If blocks is not finite or is below 1.

return_level(blocks)

Value exceeded on average once in blocks blocks (blocks > 1).

Parameters:

blocks (float) – Finite return period, in blocks, greater than 1.

Returns:

quantile(1 - 1 / blocks), in the unit of the fitted sample.

Return type:

float

Raises:

ValueError – If blocks is not finite or is not greater than 1.

cabledyn.fit_weibull(values)

Fit a two-parameter Weibull distribution by maximum likelihood.

Every value must be strictly positive. The shape solves sum(x^k ln x) / sum(x^k) - 1/k - mean(ln x) = 0, which is monotone in k, by bisection; the scale follows as mean(x^k) ** (1/k).

Parameters:

values (array_like) – At least two finite, strictly positive, not all equal values (for example from upcrossing_maxima()); flattened to 1-D.

Returns:

Fitted dimensionless shape and scale in the unit of values.

Return type:

WeibullFit

Raises:

ValueError – If the sample is too small, not finite, constant, or not strictly positive.

class cabledyn.WeibullFit(shape, scale, sample_count)

Two-parameter Weibull distribution F(x) = 1 - exp(-(x / scale) ** shape), x >= 0.

shape

Finite, positive, dimensionless shape parameter k.

Type:

float

scale

Finite, positive scale parameter, in the unit of the fitted sample.

Type:

float

sample_count

Number of values fitted.

Type:

int

Raises:

ValueError – If shape or scale is not finite and positive.

cdf(value)

Non-exceedance probability of value (zero for negative values).

Parameters:

value (array_like) – Values, in the unit of the fitted sample; any shape.

Returns:

Read-only probabilities F(value) in [0, 1], with the shape of value.

Return type:

numpy.ndarray

quantile(probability)

Value with non-exceedance probability (strictly between 0 and 1).

Parameters:

probability (float) – Non-exceedance probability, strictly between 0 and 1.

Returns:

scale * (-ln(1 - probability)) ** (1 / shape), in the unit of the fitted sample.

Return type:

float

Raises:

ValueError – If probability is not strictly between 0 and 1.

Line geometry

line_geometry() derives arc length, inclination, and a discrete curvature estimate from the node coordinates of one line. These are post-processing estimates from the output nodes; the solver’s own curvature, tension, and angle channels, where written, are authoritative.

cabledyn.line_geometry(source, *, line_id=None, time=None)

Return the node-based geometry of one line.

Parameters:
  • source (StaticProfile | LineNodeHistory | MoorDynLineHistory | array_like) – A static profile with X, Y, and Z columns, a dynamic per-line position history (CableDyn or MoorDyn), or an (n, 3) array of node coordinates in metres with n >= 2, in End-A-to-End-B order.

  • line_id (int | None) – Line to take from a static profile; required when the profile holds several lines. Not allowed for other sources.

  • time (float | None) – Snapshot time, in seconds, for a line history (linearly interpolated). Required for a line history; not allowed otherwise.

Returns:

Coordinates and arc length in metres, inclination in degrees, and curvature in 1/m, one row per node.

Return type:

LineGeometry

Raises:
  • KeyError – If line_id or a coordinate column is missing from the profile, or the history lacks node positions.

  • ValueError – If line_id or time is missing or not applicable, time is outside the record, the coordinates are not a finite (n, 3) array with n >= 2, or consecutive nodes coincide.

class cabledyn.LineGeometry(coordinates, arc_length, inclination, curvature)

Node-based geometry of one line in End-A-to-End-B order.

Arrays are read-only and have one row per node.

coordinates

(n, 3) global X, Y, Z, in metres.

Type:

numpy.ndarray

arc_length

(n,) cumulative chord length from End A, in metres.

Type:

numpy.ndarray

inclination

(n,) angle of the local tangent above the horizontal plane, in degrees (positive when the line rises towards End B), from central differences at interior nodes and one-sided differences at the ends.

Type:

numpy.ndarray

curvature

(n,) inverse radius of the circle through each interior node and its two neighbours, in 1/m; nan at the two end nodes.

Type:

numpy.ndarray

property length

Total chord length in metres.

property horizontal_span

Horizontal distance between End A and End B in metres.

property vertical_span

Height of End B above End A in metres.

property minimum_bend_radius

Smallest discrete bend radius in metres (inf for a straight line).

touchdown(seabed_z, *, tolerance=0.01, grounded_end=None)

Locate where the line lifts off a flat seabed at z = seabed_z.

A node is grounded when z <= seabed_z + tolerance. The grounded run must start at one end of the line. grounded_end ("A" or "B") chooses the end when both are grounded; by default exactly one end must be grounded.

Parameters:
  • seabed_z (float) – Global Z of the flat seabed, in metres.

  • tolerance (float) – Non-negative height above the seabed, in metres, within which a node counts as grounded.

  • grounded_end (str | None) – "A" or "B"; required only when both ends are grounded.

Returns:

The touchdown point, or None when the line does not touch the seabed at the selected end or lies on it entirely.

Return type:

Touchdown | None

Raises:

ValueError – If seabed_z or tolerance is invalid, grounded_end is not "A" or "B", or both ends are grounded and grounded_end is omitted.

export(path, *, overwrite=False)

Atomically write a unit-labelled CSV with one row per node.

The columns are Node_[-] (one-based), ArcLength_[m], X_[m], Y_[m], Z_[m], Inclination_[deg], and Curvature_[1/m].

Parameters:
  • path (str | os.PathLike) – Target CSV file. Missing parent directories are created.

  • overwrite (bool) – Replace an existing file instead of raising FileExistsError.

Returns:

Absolute path of the written file.

Return type:

pathlib.Path

Raises:

FileExistsError – If path exists and overwrite is false.

class cabledyn.Touchdown(node, arc_length, coordinates, grounded_end, grounded_length, suspended_length, layback)

Touchdown point of a line on a flat seabed.

The estimate resolves the touchdown to one output segment.

node

Zero-based index of the last grounded node before the line lifts off, counted in End-A-to-End-B order.

Type:

int

arc_length

Chord arc length from End A to the touchdown node, in metres.

Type:

float

coordinates

Read-only (3,) global X, Y, Z of the touchdown node, in metres.

Type:

numpy.ndarray

grounded_end

"A" or "B": the end whose run lies on the seabed.

Type:

str

grounded_length

Chord length from the grounded end to the touchdown node, in metres.

Type:

float

suspended_length

Chord length from the touchdown node to the suspended end, in metres.

Type:

float

layback

Horizontal distance from the touchdown node to the suspended end, in metres.

Type:

float

cabledyn.touchdown_history(source, *, seabed_z, tolerance=0.01, grounded_end=None, line_id=None, reference=None, start=None, stop=None)

Return the touchdown point of one line at every output time.

Parameters:
  • source (LineNodeHistory | MoorDynLineHistory | TimeHistory) – Node positions: a per-line position file, or a main output with L<L>N<J>px/py/pz channels (then line_id is required).

  • seabed_z (float) – Global Z of the flat seabed, in metres.

  • tolerance (float) – Non-negative height above the seabed within which a node counts as grounded, in metres.

  • grounded_end (str | None) – "A" or "B". By default the end grounded at the first sample; required when both or neither end is grounded then.

  • line_id (int | None) – Deck line identifier, for a main output (and to select the line of a multi-line reference profile).

  • reference (StaticProfile | None) – Static profile that fixes the reference TDP for the excursions; by default the first touching sample.

  • start (float | None) – Optional time window, in seconds.

  • stop (float | None) – Optional time window, in seconds.

Returns:

TDP arc length, coordinates, layback, and excursions against time.

Return type:

TouchdownHistory

Raises:
  • KeyError – If the source lacks node positions.

  • ValueError – If a setting is invalid, fewer than two nodes are available, consecutive nodes coincide, the grounded end cannot be chosen, the line never touches down, or the reference has no touchdown point.

class cabledyn.TouchdownHistory(time, touching, arc_length, coordinates, layback, excursion, arc_excursion, grounded_end, seabed_z, tolerance, reference_arc_length, source)

Touchdown point of one line at every output time.

Arrays are read-only with one row per sample. At samples where the line does not touch down at grounded_end (fully suspended, or lying on the seabed entirely) touching is false and the values are nan.

time

(n,) sample times, in seconds.

Type:

numpy.ndarray

touching

(n,) boolean: whether a touchdown point exists.

Type:

numpy.ndarray

arc_length

(n,) TDP arc length from End A, in metres.

Type:

numpy.ndarray

coordinates

(n, 3) TDP global X, Y, Z, in metres.

Type:

numpy.ndarray

layback

(n,) horizontal distance from the TDP to the suspended end, in metres.

Type:

numpy.ndarray

excursion

(n,) signed horizontal TDP displacement from the reference, in metres, positive towards the suspended end.

Type:

numpy.ndarray

arc_excursion

(n,) TDP arc length minus the reference arc length, in metres.

Type:

numpy.ndarray

grounded_end

"A" or "B".

Type:

str

seabed_z

Seabed level, in metres.

Type:

float

tolerance

Grounding tolerance, in metres.

Type:

float

reference_arc_length

Reference TDP arc length, in metres.

Type:

float

source

Result file.

Type:

pathlib.Path

statistics(quantity)

Return the minimum, maximum, and mean of a quantity over touching samples.

Parameters:

quantity (str) – "arc_length", "layback", "excursion", or "arc_excursion".

Returns:

Minimum, maximum, and mean, in metres.

Return type:

tuple[float, float, float]

Raises:

ValueError – If quantity is unknown or the line never touches down.

plot(quantity='arc_length', *, ax=None)

Plot a touchdown quantity against time.

Parameters:
  • quantity (str) – "arc_length", "layback", "excursion", or "arc_excursion".

  • ax (matplotlib.axes.Axes | None) – Axes to draw on; a new figure is created when omitted.

Returns:

The axes drawn on.

Return type:

matplotlib.axes.Axes

Raises:

ValueError – If quantity is unknown.

export(path, *, overwrite=False)

Atomically write the history as a unit-labelled CSV, one row per sample.

Samples without a touchdown point have empty fields.

Parameters:
  • path (str | os.PathLike) – Target CSV file; missing parent directories are created.

  • overwrite (bool) – Replace an existing file instead of raising FileExistsError.

Returns:

Absolute path of the written file.

Return type:

pathlib.Path

Raises:

FileExistsError – If path exists and overwrite is false.

Deck editing and case generation

DeckFile edits an existing deck while preserving everything it does not change. DeckWriter builds a new deck from Python values. generate_deck_cases() writes a family of edited decks for a batch study. It and DeckModel.save() (with rebase=True) rewrite relative ancillary paths for the new folder and copy the fixed-name MoorDyn-C kinematics files (wave_elevation.txt for 3 WaveKin, wave_frequencies.txt for 7 WaveKin, current_profile.txt for 1 Currents), which the solver reads from the deck’s own folder, next to the new decks (Python package).

class cabledyn.DeckFile(path, lines, line_endings, *, caller_driven=False, label=None)

A source-preserving CableDyn deck document.

Untouched rows, comments, bytes that are not valid UTF-8, recognized native optional sections, and ordering are retained byte-for-byte. Unknown dashed headings fail closed. An edited row is rendered canonically (single spaces between its data tokens) while its leading indentation and everything after its last data token (option commentary, description, inline comment) are kept verbatim.

Error contract:

  • DeckFormatError (a ValueError): the deck text, as read or as it would be after an edit, violates the native reader contract. A failed edit is rolled back. Messages locate the problem as <source>:<line>; after an edit the source is labelled edited copy of <path>.

  • KeyError: a selector or editor names a record, field, or option that the deck does not contain (including a column absent from that row).

  • ValueError: a malformed selector or an argument that cannot be rendered as one native token (None, whitespace, quotes, comment markers, containers).

  • TypeError: an argument of the wrong type, such as a non-Boolean caller_driven.

Construct instances with read() or from_text().

Parameters:
  • path (str | os.PathLike) – Deck path; anchors relative ancillary file paths.

  • lines (list[str]) – Deck records without their line endings.

  • line_endings (list[str]) – The line ending of each record ("" for a final unterminated record), one per entry of lines.

  • caller_driven (bool) –

    Validate for the OpenFAST coupling instead of the standalone driver

    (see DeckFile).

  • label (str | None) – Name of the source in error messages; defaults to the resolved path.

Raises:
  • TypeError – If caller_driven is not a Boolean.

  • ValueError – If lines and line_endings differ in length.

  • DeckFormatError – If the deck violates the native deck contract.

path

Absolute path of the deck. It anchors relative ancillary file paths.

Type:

pathlib.Path

caller_driven

Whether the deck is validated for the OpenFAST coupling rather than the standalone driver.

Type:

bool

Notes

caller_driven=False certifies a deck for the standalone driver cabledyn (the rules the native reader applies to every standalone entry point, together with the driver’s own dispatch rules). caller_driven=True certifies it for the OpenFAST and FAST.Farm coupling (CompMooring = 5, MooringMod = 5), where the host supplies the clock, the water depth and the water kinematics and drives the Coupled/Vessel points, bodies and rods. On that route a deck waves or wavetrain row is rejected, and a deck current row is rejected on a deck with finite-EI lines, Rigid6 bodies, rods or Turbine<J> points. The rest of the current rule depends on the host and is checked when OpenFAST initialises the module: the current is kept as a steady field when SeaState carries no waves or current and is rejected otherwise. The native C API (cabledyn.CableDyn) reads decks with the standalone rules.

classmethod read(path, *, caller_driven=False)

Read and validate a standalone or caller-driven CableDyn deck.

Bytes that are not valid UTF-8 (for example a Latin-1 character in a comment) are carried through unchanged and written back byte-exactly.

Parameters:
  • path (str | os.PathLike) – Deck file to read.

  • caller_driven (bool) – Validate for the OpenFAST coupling instead of the standalone driver (see DeckFile).

Returns:

The parsed, validated deck.

Return type:

DeckFile

Raises:

DeckFormatError – If the file cannot be read, names a reserved Windows device (on Windows), or violates the native deck contract.

classmethod from_text(text, *, path='deck.dat', caller_driven=False, label=None)

Validate deck text held in memory.

Parameters:
  • text (str) – Complete deck text.

  • path (str | os.PathLike) – Nominal deck path; anchors relative ancillary paths and the default write target directory.

  • caller_driven (bool) – Validate for the OpenFAST coupling instead of the standalone driver (see DeckFile).

  • label (str | None) – Name of the text in error messages; defaults to "<in-memory deck>".

Returns:

The parsed, validated deck.

Return type:

DeckFile

Raises:
  • TypeError – If caller_driven is not a Boolean.

  • DeckFormatError – If the text violates the native deck contract.

clone()

Return an independent editable copy.

Returns:

A deep copy; edits to it do not affect this deck.

Return type:

DeckFile

text()

Return the current complete deck text.

Returns:

Every record with its original line ending. Source bytes that are not valid UTF-8 appear as lone surrogates (surrogateescape); encode with errors="surrogateescape" to recover the original bytes. A byte-order mark that opened the source opens the text.

Return type:

str

property line_types

Data rows of the LINE TYPES section, in file order.

property points

Data rows of the POINTS section, in file order.

property lines

Data rows of the LINES section, in file order.

property sections

Data rows of the SECTIONS section, in file order.

property end_connections

Data rows of the END CONNECTIONS section, in file order.

property outputs

Output channel names from the OUTPUTS section, in file order.

property options

Every row of the OPTIONS section, in file order.

A keyword may appear more than once; the last row is the effective one.

option(keyword)

Return the effective (last) row for keyword or any native alias of it.

Matching is case-insensitive, and native aliases are equivalent: for example g and gravity, or dt and dtM.

Parameters:

keyword (str) – Option keyword or native alias.

Returns:

The last row that sets the option. Values are the deck tokens in the option’s SI unit; path-valued options are dequoted, as the native reader does.

Return type:

OptionRecord

Raises:

KeyError – If the deck sets neither the keyword nor any alias of it.

validate()

Validate the object graph without pretending to replace native physics checks.

Checks section structure, row syntax, option values, and cross-references between rows. A deck that passes can still be rejected by the solver on physical grounds.

The ancillary files a deck names (motion, bathymetry, WaterKin, Syrope, and the MoorDyn-C kinematics files) are not read here, so the checks that depend on their contents stay with the solver: for example the anchor height on a bathymetry surface, whether a WaterKin file carries waves (WaveKinMod) for vesselRAO, and whether its current doubles a current row or Currents 1.

Raises:

DeckFormatError – If the deck violates the native deck contract.

apply_many(changes)

Apply coordinated selectors transactionally, then validate the final deck.

Every selector is resolved against the deck as it was before the batch, so one selector may rename an id or name that another still addresses. Two selectors that address the same field or option (for example point.2.z and Point.2.Z) raise ValueError; on any error the deck is left unchanged.

Parameters:

changes (collections.abc.Mapping[str, object]) – {selector: value}; selectors are described in apply(). Values are in the deck’s SI units (m, kg/m, N, s).

Raises:
  • KeyError – If a selector addresses a record, field, or option the deck lacks.

  • ValueError – If a selector is malformed, two selectors address the same field or option, or a value cannot be rendered as one native token.

  • DeckFormatError – If the edited deck violates the native deck contract.

set_option(keyword, value)

Replace the value(s) of the effective row for keyword.

Scalar rows take one value; dynamic_solver and the positional waves/current forms take a sequence. The keyword, commentary, description, and inline comment of the row are kept. The option must already be present in the deck.

Parameters:
  • keyword (str) – Option keyword or native alias (case-insensitive).

  • value (object | tuple[object, ...] | list[object]) – New value, in the option’s SI unit, or a sequence of values for a multi-value row. Each value must render as one native token.

Raises:
  • KeyError – If the deck does not set the option.

  • ValueError – If a value cannot be rendered as one native token or the values do not fit the row’s form.

  • DeckFormatError – If the edited deck violates the native deck contract.

set_point(point_id, **changes)

Edit columns of the POINTS row with point_id.

Keyword names are column names, case-insensitive: id, type, x, y, z, mass, vol, cda, and ca. For example, deck.set_point(3, z=-150.0).

Parameters:
  • point_id (int) – Point identifier.

  • **changes (object) – New column values: positions in m, mass in kg, volume in m^3, cda in m^2, and ca dimensionless.

Raises:
  • KeyError – If the point or a column does not exist.

  • ValueError – If a value cannot be rendered as one native token.

  • DeckFormatError – If the edited deck violates the native deck contract.

set_line_type(line_type_name, **changes)

Edit columns of the LINE TYPES row named line_type_name (case-insensitive).

Keyword names are column names, case-insensitive: name, diam, mass, ea, ba, ei, and the hydrodynamic coefficients in the column convention the row uses (cdn, cdt, can, cat, or cd, ca, cdax, caax).

Parameters:
  • line_type_name (str) – Line-type name (case-insensitive).

  • **changes (object) – New column values: diam in m, mass in kg/m, ea in N (or a dynamic-stiffness specification), ba in N s (negative for a damping ratio), ei in N m^2, and dimensionless coefficients.

Raises:
  • KeyError – If the line type or a column does not exist.

  • ValueError – If a value cannot be rendered as one native token.

  • DeckFormatError – If the edited deck violates the native deck contract.

set_section(line_id, occurrence=1, **changes)

Edit the occurrence-th section (1-based, End A to End B) of a line.

A stock 7-column LINES row counts as a section at its position in the file, as it does natively; editing it accepts the stock column names (linetype, nodea, nodeb, length, numsegs, outputs).

Parameters:
  • line_id (int) – Line identifier.

  • occurrence (int) – One-based position of the section along the line, from End A.

  • **changes (object) – New column values, for example length in m and numsegs.

Raises:
  • KeyError – If the section or a column does not exist.

  • ValueError – If a value cannot be rendered as one native token.

  • DeckFormatError – If the edited deck violates the native deck contract.

set_end_connection(line_id, end, **changes)

Edit one END CONNECTIONS row selected by line id and end.

Keyword names are column names, case-insensitive: lineid, end, stiffness, ezx, ezy, and ezz.

Parameters:
  • line_id (int) – Line identifier.

  • end (str) – "A" or "B".

  • **changes (object) – New column values: stiffness in N m/rad (or Pinned / Rigid) and dimensionless direction components.

Raises:
  • KeyError – If the row or a column does not exist.

  • ValueError – If end or a value is invalid.

  • DeckFormatError – If the edited deck violates the native deck contract.

apply(selector, value)

Apply one selector, validating the edited deck.

Parameters:
  • selector (str) – option.KEY, point.ID.FIELD, line_type.NAME.FIELD, section.LINE.OCCURRENCE.FIELD, or end_connection.LINE.END.FIELD.

  • value (object) – New value, in the deck’s SI units; must render as one native token (or a sequence for a multi-value option).

Raises:
  • KeyError – If the selector addresses a record, field, or option the deck lacks.

  • ValueError – If the selector is malformed or the value cannot be rendered.

  • DeckFormatError – If the edited deck violates the native deck contract.

write(path, *, overwrite=False)

Validate, then atomically write the deck byte-exactly to path.

The file receives default permissions for a new file (0o666 masked by the umask). Missing parent directories are created.

Parameters:
  • path (str | os.PathLike) – Target file.

  • overwrite (bool) – Replace an existing file instead of raising FileExistsError.

Returns:

Absolute path of the written file.

Return type:

pathlib.Path

Raises:
  • FileExistsError – If path exists and overwrite is false.

  • ValueError – If path names a reserved Windows device (on Windows).

  • DeckFormatError – If the deck violates the native deck contract.

class cabledyn.deck_file.DeckRecord(index, tokens, quoted=())

One parsed table row and its zero-based source-line location.

Returned by the table properties of cabledyn.DeckFile, such as cabledyn.DeckFile.points.

index

Zero-based line number of the row in the deck text.

Type:

int

tokens

The row’s data values in column order, with surrounding quotes removed.

Type:

tuple[str, …]

quoted

Whether each token was quoted in the source.

Type:

tuple[bool, …]

class cabledyn.deck_file.OptionRecord(index, keyword, values, description, keyword_first=False, trailing=())

One option row, including positional and keyword-first native forms.

Returned by cabledyn.DeckFile.options and cabledyn.DeckFile.option().

index

Zero-based line number of the row in the deck text.

Type:

int

keyword

Option keyword as written in the deck.

Type:

str

values

Interpreted values. Path-valued options are dequoted as the native reader does.

Type:

tuple[str, …]

description

Text after the first whitespace-delimited -, if any.

Type:

str | None

keyword_first

Whether the row uses the keyword-first form, as dynamic_solver does.

Type:

bool

trailing

Raw commentary tokens that follow a value keyword pair.

Type:

tuple[str, …]

cabledyn.generate_deck_cases(base, output_directory, cases, *, overwrite=False, caller_driven=False)

Generate validated deck variants and a machine-readable provenance manifest.

Each case is a copy of base edited with DeckFile.apply_many() and written to <output_directory>/<name>.dat. Relative ancillary file paths in the deck (motion, bathymetry, WaterKin and Syrope files) are rewritten so they still resolve from the new location. The MoorDyn-C kinematics files that the solver reads by fixed name from the deck folder (wave_elevation.txt for WaveKin 3, wave_frequencies.txt for WaveKin 7, current_profile.txt for Currents 1) are copied into output_directory. A cases.json manifest records the source deck, its SHA-256 digest, and every case’s changes and digest (with the digests of the copied kinematics files it reads); cabledyn.run_study() consumes it. Every case is validated before any file is written.

Parameters:
  • base (str | os.PathLike) – Source deck.

  • output_directory (str | os.PathLike) – Directory for the generated decks and manifest; created if missing.

  • cases (collections.abc.Mapping[str, collections.abc.Mapping[str, object]]) – Case name to selector-value mapping, as accepted by DeckFile.apply_many(). Names start with a letter or digit and contain only letters, digits, _, ., and -; they must be unique ignoring case.

  • overwrite (bool) – Replace existing generated decks and manifest instead of raising FileExistsError.

  • caller_driven (bool) –

    Validate for the OpenFAST coupling instead of the standalone driver

    (see DeckFile).

Returns:

One entry per case, in the order of cases.

Return type:

tuple[GeneratedCase, …]

Raises:
  • DeckFormatError – If the base deck or an edited case violates the native deck contract, a rebased OPTIONS path would contain a space, or a fixed-name kinematics file the deck reads is missing.

  • KeyError – If a selector addresses a record, field, or option the deck lacks.

  • ValueError – If cases is empty, a case name is invalid or duplicated, a change is not JSON-serializable, or a case would replace the source deck.

  • FileExistsError – If an output exists and overwrite is false.

class cabledyn.GeneratedCase(name, deck, working_directory, changes, sha256)

A generated deck plus the working directory required by relative inputs.

Returned by cabledyn.generate_deck_cases().

name

Case name; the deck file is <name>.dat.

Type:

str

deck

Absolute path of the generated deck.

Type:

pathlib.Path

working_directory

Directory to run the deck from, so that relative ancillary files resolve.

Type:

pathlib.Path

changes

Read-only mapping of the selectors and values applied to the base deck.

Type:

collections.abc.Mapping[str, object]

sha256

SHA-256 digest of the generated deck file.

Type:

str

class cabledyn.DeckWriter(title='cabledyn deck')

Accumulates line types, points, lines, sections, and options; writes a deck.

Free text (title and option descriptions) must not contain ---, #, or !; names must be single plain tokens. text() and write() validate the complete deck with cabledyn.DeckFile and raise cabledyn.DeckFormatError when it breaks the native contract. Numbers are written in a round-trip-exact form, so reading the deck back reproduces the passed values exactly.

Parameters:

title (str) – Title line written below the deck’s first heading.

Example

>>> deck = DeckWriter(title="three-line chain mooring")
>>> deck.add_line_type("main", diam=0.333, mass=685.0, ea=3.27e9,
...                    ba=-1.0, ei=0.0, cdn=2.0, cdt=0.4, can=0.82, cat=0.27)
>>> deck.add_point(1, "Vessel", -58.0, 0.0, -14.0)
>>> deck.add_point(2, "Fixed", -837.6, 0.0, -200.0)
>>> deck.add_line(1, node_a=1, node_b=2)
>>> deck.add_section(line_id=1, line_type="main", length=850.0, num_segs=20)
>>> deck.set_option(9.80665, "g", "Gravitational acceleration (m/s^2)")
>>> deck.add_output("FairTen1")
>>> deck.write("mooring.dat")
add_line_type(name, *, diam, mass, ea, ba=0.0, ei=0.0, cdn=0.0, cdt=0.0, can=0.0, cat=0.0)

One LINE TYPES row (MoorDyn vocabulary: Diam Mass EA BA EI Cdn Cdt Can Cat).

Parameters:
  • name (str) – Line-type name referenced by add_section().

  • diam (float) – Hydrodynamic (volume-equivalent) diameter, in m.

  • mass (float) – Mass per unit length, in kg/m.

  • ea (float) – Axial stiffness, in N.

  • ba (float) – Axial damping, in N s; a negative value is a damping ratio.

  • ei (float) – Bending stiffness, in N m^2; zero for a cable without bending stiffness.

  • cdn (float) – Normal and tangential drag coefficients.

  • cdt (float) – Normal and tangential drag coefficients.

  • can (float) – Normal and tangential added-mass coefficients.

  • cat (float) – Normal and tangential added-mass coefficients.

Raises:
  • TypeError – If name is not a string.

  • ValueError – If name is not a single plain token.

add_point(point_id, ptype, x, y, z)

One POINTS row. ptype is Fixed / Coupled / Vessel / Free / Connect.

Parameters:
  • point_id (int) – Point identifier referenced by add_line().

  • ptype (str) – "Fixed", "Coupled", "Vessel", "Free", or "Connect" (case-insensitive; written as given).

  • x (float) – Point position in the global frame, in metres (z positive up).

  • y (float) – Point position in the global frame, in metres (z positive up).

  • z (float) – Point position in the global frame, in metres (z positive up).

Raises:
  • TypeError – If point_id is not an integer.

  • ValueError – If ptype is not a recognized point type.

add_line(line_id, *, node_a, node_b, outputs='-')

One LINES row: End A (fairlead-side) and End B (anchor-side) point ids.

Parameters:
  • line_id (int) – Line identifier referenced by add_section().

  • node_a (int) – Point identifier of End A (fairlead side).

  • node_b (int) – Point identifier of End B (anchor side).

  • outputs (str) – Per-line output-file flags: - for none, p for node positions, t for segment tensions, r for the range graph (for example pt).

Raises:
  • TypeError – If outputs is not a string, or an id is not an integer.

  • ValueError – If outputs is not a single plain token.

add_section(*, line_id, line_type, length, num_segs)

One SECTIONS row (sections compose a line from End A to End B).

Sections of one line are joined from End A to End B in the order they are added.

Parameters:
  • line_id (int) – Identifier of the line the section belongs to.

  • line_type (str) – Line-type name defined with add_line_type().

  • length (float) – Unstretched section length, in metres.

  • num_segs (int) – Number of segments, at least 1.

Raises:
  • TypeError – If line_type is not a string, or line_id or num_segs is not an integer.

  • ValueError – If line_type is not a single plain token or num_segs is less than 1.

add_end_connection(line_id, end, stiffness, direction)

Add a finite-EI line-end bending connection.

Parameters:
  • line_id (int) – Positive line identifier.

  • end (str) – "A" or "B" (also "EndA", "end_a", and so on; case-insensitive).

  • stiffness (float | str) – Finite, non-negative rotational stiffness in N m/rad, "Pinned" (also "Free"/"Zero"), or "Rigid" (also "Infinity"/"Inf").

  • direction (tuple[float, float, float] | list[float]) – Three finite components of the non-zero end direction in the global frame, following CableDyn’s End-A-to-End-B convention; normalized before writing.

Raises:
  • TypeError – If line_id is not an integer.

  • ValueError – If line_id is not positive, end is not A or B, that end already has a connection, stiffness is invalid, or direction is not three finite components with a non-zero norm.

set_option(value, keyword, description=None)

Add one OPTIONS row, written in the native column order value keyword.

Checking the keyword means a call with the value and keyword swapped raises instead of writing a wrong row.

Parameters:
  • value (str | float | bool) – Option value in the option’s SI unit (for example seconds for dtM, metres for WtrDpth). Strings are written verbatim and must be one plain token, numbers with str (shortest exact form), and Booleans as True/False.

  • keyword (str) – Native scalar option keyword (case-insensitive, for example dtM, TMax, WtrDpth).

  • description (str | None) – Optional one-row note on the option’s meaning, units, and choices, written after a whitespace-delimited - separator. It must not contain ---, #, or !.

Raises:
  • TypeError – If keyword is not a string, or value is not a string, number, or Boolean.

  • ValueError – If keyword is unknown, a string value is not a plain token, or description holds forbidden text.

add_output(channel)

Add one output channel; it is rendered as a quoted row in OUTPUTS.

Parameters:

channel (str) – Native output channel name, for example "FairTen1".

Raises:
  • TypeError – If channel is not a string.

  • ValueError – If channel is not a single plain token.

text(*, caller_driven=False)

Return the complete deck text after validating it with DeckFile.

Parameters:

caller_driven (bool) – Validate for the OpenFAST coupling (see DeckFile) instead of the standalone driver.

Returns:

The deck text, newline-terminated.

Return type:

str

Raises:
  • ValueError – If the deck lacks a line type, point, line, or section, or the title holds forbidden text.

  • DeckFormatError – If the deck breaks the native contract.

write(path, *, caller_driven=False)

Validate the deck, write it to path, and return the path.

An existing file is replaced.

Parameters:
  • path (str | os.PathLike) – Target file, written as ASCII with LF line endings.

  • caller_driven (bool) – Validate for the OpenFAST coupling; see text().

Returns:

path as given, not resolved.

Return type:

pathlib.Path

Raises:
  • ValueError – If the deck is incomplete or holds forbidden text.

  • DeckFormatError – If the deck breaks the native contract.

Deck object model

class cabledyn.DeckModel(*, title='CableDyn deck', path='deck.dat', caller_driven=False)

An editable, typed object model of a CableDyn deck.

Create one with new(), load(), from_text(), or from_deck_file(). Objects are plain dataclasses whose fields may be edited in place; rows refer to other objects by reference, so renaming an object never breaks the rows that use it. Structural edits go through the add_*, rename(), and remove() methods, which keep the references consistent. validate(), to_text(), and save() check the complete deck with cabledyn.DeckFile.

Parameters:
  • title (str) – Free-text title written below the deck banner.

  • path (str | os.PathLike) – Nominal deck path; relative ancillary paths (motion, bathymetry, WaterKin, Syrope files) resolve against its folder.

  • caller_driven (bool) – Validate for the OpenFAST coupling (CompMooring = 5) instead of the standalone driver; see cabledyn.DeckFile. The native C API reads decks with the standalone rules.

title

Deck title.

Type:

str

path

Absolute nominal deck path.

Type:

pathlib.Path

caller_driven

Validation route.

Type:

bool

options

The OPTIONS rows.

Type:

OptionSet

outputs

The OUTPUTS channels.

Type:

OutputList

Examples

>>> model = DeckModel.new(title="single chain")
>>> chain = model.add_line_type("chain", diam=0.252, mass=390.0, ea=1.674e9,
...                             ba=-1.0, cdn=1.37, cdt=0.64, can=1.0)
>>> fairlead = model.add_point(1, "Coupled", 0.0, 0.0, -14.0)
>>> anchor = model.add_point(2, "Fixed", 400.0, 0.0, -50.0)
>>> line = model.add_line(1, fairlead, anchor, chain, length=410.0, num_segs=41)
>>> _ = model.options.set("WtrDpth", 50.0, description="Water depth (m)")
>>> model.outputs.add("FairTen1")
>>> model.save("chain.dat")
classmethod new(*, title='CableDyn deck', path='deck.dat', caller_driven=False)

Return an empty model.

Parameters:
  • title (str) – Deck title.

  • path (str | os.PathLike) – Nominal deck path that anchors relative ancillary paths.

  • caller_driven (bool) – Validate for the OpenFAST coupling instead of the standalone driver.

Returns:

A model with no objects.

Return type:

DeckModel

classmethod load(path, *, caller_driven=False)

Read and validate a deck file into a model.

Parameters:
  • path (str | os.PathLike) – Deck file.

  • caller_driven (bool) – Validate for the OpenFAST coupling instead of the standalone driver.

Returns:

The model of the deck.

Return type:

DeckModel

Raises:

DeckFormatError – If the file cannot be read or violates the native deck contract.

classmethod from_text(text, *, path='deck.dat', caller_driven=False)

Validate deck text and return its model.

Parameters:
  • text (str) – Complete deck text.

  • path (str | os.PathLike) – Nominal deck path that anchors relative ancillary paths.

  • caller_driven (bool) – Validate for the OpenFAST coupling instead of the standalone driver.

Returns:

The model of the deck.

Return type:

DeckModel

Raises:

DeckFormatError – If the text violates the native deck contract.

classmethod from_deck_file(deck)

Build a model from a validated cabledyn.DeckFile.

Parameters:

deck (DeckFile) – A parsed deck; its path and validation route carry over.

Returns:

The model of the deck.

Return type:

DeckModel

copy()

Return an independent deep copy with its own objects.

Returns:

The copy.

Return type:

DeckModel

property line_types

LINE TYPES rows, looked up by case-insensitive name.

property rod_types

ROD TYPES rows, looked up by case-insensitive name.

property bodies

BODIES rows (Body or MoorDynBody), looked up by id.

property rods

RODS rows, looked up by id.

property turbines

TURBINES rows, looked up by turbine number.

property points

POINTS rows, looked up by id.

property lines

LINES rows with their sections, looked up by id.

property end_connections

END CONNECTIONS rows.

property equivalent_buoyancy

EQUIVALENT BUOYANCY rows.

property attachments

ATTACHMENTS rows.

property syrope_ic

SYROPE IC rows.

property failures

FAILURE rows; row i (from 1) is FailID i.

property controls

CONTROL rows.

property external_loads

EXTERNAL LOADS rows.

rod_end(rod, end)

Return end A or B of a rod, to use as a line end or point type.

Parameters:
  • rod (Rod | int) – The rod or its id.

  • end (str) – "A" or "B".

Returns:

The rod end.

Return type:

RodEnd

add_line_type(name, *, diam, mass, ea, ba=0.0, ei=0.0, cdn=0.0, cdt=0.0, can=0.0, cat=0.0, gas=None, gj=None, irt=None, irn=None)

Add a LINE TYPES row; see LineType for the fields.

Returns:

The new line type.

Return type:

LineType

Raises:

ValueError – If a line type of that name (case-insensitive) exists.

add_rod_type(name, *, diam, mass, cd=0.0, ca=0.0, cd_end=0.0, ca_end=0.0, cd_ax=None, ca_ax=None)

Add a ROD TYPES row; see RodType for the fields.

Returns:

The new rod type.

Return type:

RodType

Raises:

ValueError – If a rod type of that name (case-insensitive) exists.

add_body(body_id, type, x, y, z, *, roll=0.0, pitch=0.0, yaw=0.0, mass=0.0, volume=0.0, c33=0.0, c44=0.0, c55=0.0, cda=0.0, ca=0.0, inertia=None)

Add a CableDyn BODIES row; see Body for the fields.

Returns:

The new body.

Return type:

Body

Raises:

ValueError – If a body with body_id exists.

add_moordyn_body(body_id, type, x, y, z, *, roll=0.0, pitch=0.0, yaw=0.0, mass=0.0, cg=0.0, inertia=0.0, volume=0.0, cda=0.0, ca=0.0)

Add a 14-column MoorDyn BODIES row; see MoorDynBody.

Returns:

The new body.

Return type:

MoorDynBody

Raises:

ValueError – If a body with body_id exists.

add_rod(rod_id, rod_type, type, end_a, end_b, num_segs, *, outputs='-', body=None)

Add a RODS row; see Rod for the fields.

type may name a body directly ("Body1", "Body1Pinned") or be "Body"/"BodyPinned" together with body.

Returns:

The new rod.

Return type:

Rod

Raises:
  • KeyError – If the rod type or body does not exist.

  • ValueError – If a rod with rod_id exists.

add_turbine(turbine_id, x, y, z, *, ptfm=None)

Add a TURBINES row; see Turbine for the fields.

Returns:

The new turbine.

Return type:

Turbine

Raises:

ValueError – If the turbine number exists.

add_point(point_id, type, x, y, z, *, mass=0.0, volume=0.0, cda=0.0, ca=0.0, body=None, rod_end=None, turbine=None)

Add a POINTS row; see Point for the fields.

type may name the referenced object directly ("Body1", "Rod2A", "Turbine3") or be "Body"/"Rod"/"Turbine" together with body, rod_end, or turbine.

Returns:

The new point.

Return type:

Point

Raises:
  • KeyError – If a named body or rod does not exist.

  • ValueError – If a point with point_id exists.

add_line(line_id, end_a, end_b, line_type=None, *, length=None, num_segs=None, outputs='-', stock_row=False)

Add a LINES row, optionally with its first section.

Parameters:
  • line_id (int) – Unique line id.

  • end_a (Point | RodEnd | int | str) – End A (fairlead side) and End B (anchor side): a point, a point id, a RodEnd, or a rod-end token such as "R1A".

  • end_b (Point | RodEnd | int | str) – End A (fairlead side) and End B (anchor side): a point, a point id, a RodEnd, or a rod-end token such as "R1A".

  • line_type (LineType | str | None) – Line type of a first section; give length and num_segs too.

  • length (float | None) – First-section unstretched length, in m.

  • num_segs (int | None) – First-section element count.

  • outputs (str) – Per-line output flags (-, or p/t/r combined).

  • stock_row (bool) – Write a single-section line as a stock MoorDyn 7-column row.

Returns:

The new line.

Return type:

Line

Raises:
  • KeyError – If an end or the line type does not exist.

  • ValueError – If a line with line_id exists, or only part of the first section is given.

add_section(line, line_type, length, num_segs, *, index=None)

Add a section to a line.

Parameters:
  • line (Line | int) – The line or its id.

  • line_type (LineType | str) – The section’s line type or its name.

  • length (float) – Unstretched length, in m.

  • num_segs (int) – Element count.

  • index (int | None) – Position in the line’s section list (End A first); appended at End B when None.

Returns:

The new section.

Return type:

Section

add_end_connection(line, end, stiffness, direction)

Add an END CONNECTIONS row; see EndConnection.

Returns:

The new row.

Return type:

EndConnection

Raises:

ValueError – If end is not A or B, that line end already has a row, or direction does not hold three values.

add_equivalent_buoyancy(line_type, diam, submerged_weight)

Add an EQUIVALENT BUOYANCY row; see EquivalentBuoyancy.

Returns:

The new row.

Return type:

EquivalentBuoyancy

add_attachment(line, arc_length, *, mass=0.0, volume=0.0, cda=0.0, ca=0.0, cdax=None)

Add an ATTACHMENTS row; see Attachment.

Returns:

The new row.

Return type:

Attachment

add_syrope_ic(lines, tmax0, tmean0)

Add a SYROPE IC row; see SyropeIC.

Returns:

The new row.

Return type:

SyropeIC

add_failure(point, lines, *, fail_time=0.0, fail_tension=0.0)

Add a FAILURE row; its FailID is its position in failures.

Returns:

The new row.

Return type:

Failure

add_control(channel, lines)

Add a CONTROL row; see Control.

Returns:

The new row.

Return type:

Control

add_external_load(load_id, body, *, csys='G', force=0.0, blin=0.0, bquad=0.0)

Add an EXTERNAL LOADS row; see ExternalLoad.

Returns:

The new row.

Return type:

ExternalLoad

set_motion_file(path)

Prescribe point, rod-end, and body motion from a motionFile time series.

Removes any vesselMotion/vesselRAO row (the three are alternatives).

Parameters:

path (str | os.PathLike) – Motion file, relative to the deck folder or absolute.

set_vessel_motion(path, *, reference=None)

Move every Coupled/Vessel point rigidly with a 6-DOF vessel record.

Removes any motionFile/vesselRAO row.

Parameters:
  • path (str | os.PathLike) – vesselMotion record file.

  • reference (Sequence[float] | None) – Vessel reference point (x, y, z) in m (vesselRef); left unchanged when None.

set_vessel_rao(path, *, reference=None)

Move the vessel as the RAO response to the deck waves.

Removes any motionFile/vesselMotion row. The deck needs linear waves (a waves row, wavetrain rows, or a WaterKin file).

Parameters:
  • path (str | os.PathLike) – vesselRAO table file.

  • reference (Sequence[float] | None) – Vessel reference point (x, y, z) in m (vesselRef, the RAO origin); left unchanged when None.

clear_motion()

Remove every prescribed-motion row (motionFile, vesselMotion, vesselRAO, and vesselRef).

references(obj)

Return the rows and output channels that use obj.

Parameters:

obj (object) – A model object.

Returns:

Referring objects (lines, sections, points, rows, …) and output channel names, in deck order.

Return type:

tuple[object, …]

Raises:

DeckReferenceError – If obj is not part of this model.

remove(obj, *, cascade=False)

Remove an object from the model.

Parameters:
  • obj (object) – A model object: a type, body, rod, turbine, point, line, section, row, or an output channel name.

  • cascade (bool) – Also remove what uses obj: lines on a removed point, the rows of a removed line (a line is dropped from multi-line rows, and a row left without lines is removed), output channels that name it, and so on recursively. A line left without sections by a removed line type is removed too.

Raises:

DeckReferenceError – If obj is not part of this model, or is still referenced and cascade is false. The error lists the referrers.

rename(obj, new)

Give an object a new id (or name, for line and rod types).

Rows that use the object follow it automatically; output channels that name the object by id (FairTen<L>, Point<P>pz, Body<N>Px, Rod<N>Pz, …) are rewritten.

Parameters:
  • obj (LineType | RodType | Body | MoorDynBody | Rod | Turbine | Point | Line) – The object.

  • new (int | str) – The new id, or the new name of a line or rod type.

Raises:
  • DeckReferenceError – If obj is not part of this model.

  • ValueError – If another object of the same kind already has new.

  • TypeError – If new has the wrong type for the object.

to_text(*, validate=True)

Render the model as canonical deck text.

Parameters:

validate (bool) – Check the text with cabledyn.DeckFile before returning it.

Returns:

Newline-terminated deck text.

Return type:

str

Raises:
  • DeckReferenceError – If a row refers to an object outside this model.

  • TypeError – If a field has the wrong type.

  • ValueError – If a field cannot be written as a native token.

  • DeckFormatError – If validate is true and the deck violates the native contract.

to_deck_file()

Return the model as a validated cabledyn.DeckFile.

Returns:

The parsed deck, anchored at path and on the model’s validation route.

Return type:

DeckFile

Raises:

DeckFormatError – If the deck violates the native contract.

validate()

Validate the model with the native deck rules of cabledyn.DeckFile.

Raises:
save(path, *, overwrite=False, rebase=True)

Validate the model and write it as a deck file.

The model itself is unchanged: its path and the relative ancillary paths in it stay anchored at the original folder.

Parameters:
  • path (str | os.PathLike) – Target file; missing parent folders are created.

  • overwrite (bool) – Replace an existing file instead of raising FileExistsError.

  • rebase (bool) – Rewrite relative ancillary paths (motion, bathymetry, WaterKin, Syrope files) so they still resolve from the target folder, and copy the MoorDyn-C kinematics files the solver reads by fixed name from the deck folder (wave_elevation.txt for WaveKin 3, wave_frequencies.txt for WaveKin 7, current_profile.txt for Currents 1) into it.

Returns:

Absolute path of the written deck.

Return type:

pathlib.Path

Raises:
  • FileExistsError – If path exists and overwrite is false, or a different kinematics file of the same name is already in the target folder.

  • DeckFormatError – If the deck violates the native contract, a rebased OPTIONS path would contain a space, or a fixed-name kinematics file the deck reads is missing from path’s folder.

exception cabledyn.DeckReferenceError(message, referrers=())

An object is used by other deck objects, or belongs to another model.

Raised by DeckModel.remove() when the object is still referenced and cascade is false, and when a row names an object that is not part of the model.

referrers

The objects (and output channel names) that still use the object.

Type:

tuple[object, …]

class cabledyn.SyropeEA(settings, alpha, beta)

Syrope working-curve axial stiffness, the SYROPE:<file>|alpha|beta EA form.

settings

Syrope settings file, relative to the deck or absolute.

Type:

str

alpha

Fast-spring stiffness intercept, in N.

Type:

float

beta

Fast-spring stiffness slope on tension (dimensionless).

Type:

float

The row and object classes (LineType, Line, Section, Point, Body, Rod, Failure, EndConnection, …) are dataclasses in cabledyn.builder.

Snapshots and animation

class cabledyn.Snapshots(times, lines=<factory>, tensions=<factory>, points=<factory>, bodies=<factory>, rods=<factory>, seabed=None, water=None)

Geometry of a model at a common set of sample times.

times

(n,) strictly increasing sample times [s].

Type:

numpy.ndarray

lines

Deck line id -> node positions (n, n_nodes, 3) [m], End A first.

Type:

Mapping[int, numpy.ndarray]

tensions

Deck line id -> segment tensions (n, n_segments) [N] (may be empty).

Type:

Mapping[int, numpy.ndarray]

points

Deck point id -> position (n, 3) [m].

Type:

Mapping[int, numpy.ndarray]

bodies

Deck body id -> pose (n, 6): reference point [m] and x-y’-z’’ angles [deg].

Type:

Mapping[int, numpy.ndarray]

rods

Deck rod id -> node positions (n, n_nodes, 3) [m], End A first.

Type:

Mapping[int, numpy.ndarray]

seabed

The seabed, when known.

Type:

Seabed | None

water

The free surface, when known.

Type:

WaterSurface | None

property n_frames

Number of sample times.

index_at(time)

Index of the sample nearest to time.

frame(index)

All geometry of one sample: {"lines": {id: (n_nodes, 3)}, "points": ...}.

bounds()

Lower and upper corners (3,) of every recorded position [m].

save_npz(path, *, compress=True)

Write the snapshots to one .npz archive and return its path.

Keys: format, times, line/<id>/xyz, line/<id>/tension, point/<id>/xyz, body/<id>/pose, rod/<id>/xyz, and when known seabed/depth or seabed/x, seabed/y, seabed/depth_grid, and water/airy = [height, period, direction, depth or nan, g, ramp_time, unmodelled]. compress=False writes an uncompressed archive whose members can be read without inflating.

classmethod load_npz(path)

Read an archive written by save_npz().

classmethod from_files(root, *, deck=None)

Collect the geometry the standalone driver wrote for output root root.

Lines come from <root>.Line<L>.p.out (and tensions from .t.out), rods from <root>.Rod<N>.p.out (End A and End B), points and bodies from the Point<P>p{x,y,z} and Body<N>P/R{x,y,z} channels of <root>.out. The sample times are those of the per-line files, else of the main output; other series are interpolated linearly onto them. deck adds its seabed and water surface.

classmethod from_static(path, *, deck=None)

One frame (time 0) from a .static.out profile of every line.

class cabledyn.Recorder(model, *, tensions=True)

Sample an in-process model into Snapshots.

Call sample() whenever the model holds a state to keep (for example after every N-th step()), then snapshots(). Positions are copied into preallocated rows, so the per-sample cost is the object queries alone.

Parameters:
  • model (CableDyn) – An initialized model.

  • tensions (bool) – Also record every line’s segment tensions.

sample()

Record the model’s current state at its current time.

snapshots()

The recorded samples, with the deck’s seabed and water surface.

cabledyn.animation.record(model, dt, n_steps, *, every=1, motion=None, tensions=True)

Step model n_steps times and record every every-th state.

The initial state is always recorded. motion(t) returns the coupled kinematics (q, v, a) at time t (see step()); without it the coupled points are held (step_held()).

cabledyn.animate(snapshots, *, ax=None, interval=50.0, stride=1, seabed=True, water=True, grid=20)

Play the snapshots in a Matplotlib 3D axes; returns the FuncAnimation.

Lines and rods are drawn as polylines, points as dots and bodies as their reference points. The seabed and the water surface are drawn when known (the water surface moves with a regular Airy wave). Save the result with anim.save("run.gif") or show it with matplotlib.pyplot.show().

Parameters:
  • snapshots (Snapshots) – The geometry to play.

  • ax (mpl_toolkits.mplot3d.Axes3D, optional) – Target axes; a new figure is created when omitted.

  • interval (float) – Delay between frames [ms].

  • stride (int) – Play every stride-th sample.

  • seabed (bool) – Draw the seabed and the water surface.

  • water (bool) – Draw the seabed and the water surface.

  • grid (int) – Resolution of the seabed and water surface meshes.

class cabledyn.Seabed(depth=None, bathymetry=None)

The seabed: a flat plane at z = -depth or a bathymetry grid.

depth

Flat water depth in metres (positive), or None with a grid.

Type:

float | None

bathymetry

Structured seabed, which takes precedence over depth.

Type:

cabledyn.Bathymetry | None

elevation(x, y)

Seabed elevation z_floor(x, y) [m] (negative below still water).

grid(x_range, y_range, n=25)

Surface mesh (X, Y, Z) of shape (n, n) over the given ranges.

class cabledyn.WaterSurface(height=0.0, period=0.0, direction=0.0, depth=None, gravity=9.80665, ramp_time=0.0, unmodelled=False)

The free surface: still water, or a deck’s regular Airy wave.

height, period

Wave height [m] and period [s]; zero for still water.

Type:

float

direction

Propagation direction from +x toward +y [deg].

Type:

float

depth

Water depth for the dispersion relation [m]; None is deep water.

Type:

float | None

gravity

Gravitational acceleration [m/s^2].

Type:

float

ramp_time

Half-cosine start-up ramp of the amplitude [s] (the deck rampTime).

Type:

float

unmodelled

The deck has waves this surface does not reproduce (irregular seas and wave trains, whose random phases live in the solver, stream-function waves, or WaterKin kinematics, whose file may carry waves); the surface is then drawn as still water.

Type:

bool

The elevation is the solver's ``r(t) H/2 cos(k (x cos b + y sin b) - w t)``
with ``w^2 = g k tanh(k h)`` and the ramp ``r(t) = (1 - cos(pi t / T))/2``
for ``t < T``, else 1.
property still

Whether the surface is flat (no regular wave).

property wavenumber

Wavenumber k [rad/m] from the linear dispersion relation (0 for still water).

elevation(time, x, y)

Surface elevation eta [m] at time and horizontal points (x, y).

classmethod from_deck(deck)

The surface a deck prescribes (its waves option; still water otherwise).

Results at a time

cabledyn.line_positions(source, *, line_id=None, time=None)

Return the node positions of one line over time.

Parameters:
  • source (LinePositions | TimeHistory | OutputTable | array_like) – A LinePositions (returned unchanged), a LineNodeHistory, a MoorDynLineHistory with node positions, a main output with L<L>N<J>p[xyz] channels (only the listed nodes), a StaticProfile with X, Y, and Z columns, a static per-line Node/X(m)/Y(m)/Z(m) table, or an array: (n_nodes, 3) for a static configuration or (n_samples, n_nodes, 3) for a history, in metres. For a main output, arc lengths follow the chords between the listed nodes only.

  • line_id (int | None) – Line to take from a main output (required) or a multi-line static profile. Not allowed for per-line sources.

  • time (array_like | None) – (n_samples,) sample times, in seconds, for a 3-D array (required there); not allowed for other sources.

Returns:

Positions in End-A-to-End-B order. Array nodes are numbered from 1.

Return type:

LinePositions

Raises:
  • KeyError – If the source records no node positions for the line.

  • ValueError – If line_id or time is missing or not applicable, or the array shape is wrong.

class cabledyn.LinePositions(time, positions, node_ids, source=None)

Node positions of one line over time, in End-A-to-End-B order.

time

(n_samples,) strictly increasing sample times in seconds, or None for a static configuration (one sample).

Type:

numpy.ndarray | None

positions

(n_samples, n_nodes, 3) node coordinates in metres.

Type:

numpy.ndarray

node_ids

(n_nodes,) node numbers as the source names them (one-based for CableDyn, 0 for End A of a MoorDyn line).

Type:

numpy.ndarray

source

Result file the positions were read from, if any.

Type:

pathlib.Path | None

Raises:

ValueError – If the arrays are not finite, their shapes disagree, the line has no node, or time does not strictly increase.

property static

True for a static configuration without a time axis.

property sample_count

Number of time samples (1 for a static configuration).

property node_count

Number of nodes.

property arc_length

Read-only (n_samples, n_nodes) cumulative chord length from End A, in m.

at(time=None, *, interpolation='linear')

Return the (n_nodes, 3) node positions at one time.

Parameters:
  • time (float | None) – Time in seconds; must be None for a static configuration and given otherwise.

  • interpolation ({"linear", "nearest"}) – Linear interpolation between the bracketing samples, or the nearest sample (the earlier one on a tie).

Returns:

Read-only (n_nodes, 3) coordinates in metres.

Return type:

numpy.ndarray

Raises:

ValueError – If time is missing, not applicable, not finite, or outside the record, or interpolation is unknown.

arc_length_at(time=None, *, interpolation='linear')

Return the (n_nodes,) arc length from End A of the positions at one time.

The arc length is the cumulative chord length of the node positions returned by at(), in metres.

Raises:

ValueError – As for at().

period(start=None, stop=None)

Return the samples in the closed interval [start, stop].

A static configuration is returned unchanged.

Raises:

ValueError – If a limit is not finite, start exceeds stop, or no sample lies in the interval.

cabledyn.line_field(source, quantity, *, line_id=None)

Return one per-node or per-segment variable of one line.

Parameters:
  • source (object) – A LineNodeHistory (x, y, z), a LineSegmentHistory (tension), a main TimeHistory with node channels (tension, curvature, bend_moment, x, y, z, vx … az, declination, azimuth), a MoorDynLineHistory (x, y, z, tension, curvature, and the other MoorDyn codes spelled as MoorDyn writes them, for example vx, ax, Vx or Dmp; vx (node velocity) and Vx (other force) differ only in case, so either must be given exactly), a StaticProfile (every column other than LineID, Node, and ArcLength, in snake case, for example bend_moment), a static per-line node or segment table, a LinePositions, or a node-position array accepted by line_positions().

  • quantity (str) – Quantity name, matched ignoring case, underscores, and spaces.

  • line_id (int | None) – Line to take from a main output (required) or a multi-line static profile. Not allowed for per-line sources.

Returns:

Values of every recorded node or segment over time.

Return type:

LineField

Raises:
  • KeyError – If the source does not record quantity for the line.

  • ValueError – If line_id is missing or not applicable, or the source is not a line result.

class cabledyn.LineField(quantity, unit, location_kind, ids, time, values, source=None)

One per-node or per-segment variable of one line over time.

quantity

Canonical quantity name, for example "tension" or "z".

Type:

str

unit

Unit of the values, or None if unknown.

Type:

str | None

location_kind

"Node" or "Segment".

Type:

str

ids

(n_locations,) node or segment numbers as the source names them, in End-A-to-End-B order.

Type:

numpy.ndarray

time

(n_samples,) sample times in seconds, or None for a static result.

Type:

numpy.ndarray | None

values

(n_samples, n_locations) values.

Type:

numpy.ndarray

source

Result file the field was read from, if any.

Type:

pathlib.Path | None

Raises:

ValueError – If the arrays are not finite or their shapes disagree, the location kind is unknown, or time does not strictly increase.

property static

True for a static result without a time axis.

at(time=None, *, interpolation='linear')

Return the (n_locations,) values at one time.

Parameters:
  • time (float | None) – Time in seconds; must be None for a static result and given otherwise.

  • interpolation ({"linear", "nearest"}) – Linear interpolation between the bracketing samples, or the nearest sample (the earlier one on a tie).

Returns:

Read-only values, in unit.

Return type:

numpy.ndarray

Raises:

ValueError – If time is missing, not applicable, not finite, or outside the record, or interpolation is unknown.

period(start=None, stop=None)

Return the samples in the closed interval [start, stop].

A static result is returned unchanged.

Raises:

ValueError – If a limit is not finite, start exceeds stop, or no sample lies in the interval.

cabledyn.available_quantities(source, *, line_id=None)

Return the canonical names of the per-line variables a source records.

Parameters:
  • source (object) – Any source accepted by line_field().

  • line_id (int | None) – Line to inspect in a main output or a multi-line static profile.

Returns:

Canonical quantity names, for example ("x", "y", "z") for a position file or ("tension",) for a tension file.

Return type:

tuple[str, …]

Raises:

ValueError – If line_id is missing or not applicable, or the source is not a line result.

cabledyn.profile_at(source, quantity, time=None, *, line_id=None, interpolation='linear', positions=None)

Return one variable of one line along its arc length at one time.

The parameters are those of profiles_at() with a single quantity.

Returns:

The values against arc length (or node or segment number).

Return type:

ArcProfile

Raises:
  • KeyError – If the quantity is not recorded or positions lacks a node.

  • ValueError – If time or line_id is missing or not applicable, time is outside the record, or segment values cannot be placed.

cabledyn.profiles_at(source, quantities, time=None, *, line_id=None, interpolation='linear', positions=None)

Return several variables of one line along its arc length at one time.

Parameters:
  • source (object) – Any source accepted by line_field().

  • quantities (collections.abc.Iterable[str]) – Quantity names; see available_quantities().

  • time (float | None) – Time in seconds; None for a static source and required otherwise.

  • line_id (int | None) – Line to take from a main output or a multi-line static profile.

  • interpolation ({"linear", "nearest"}) – Linear interpolation between the bracketing samples, or the nearest sample (the earlier one on a tie).

  • positions (object | None) – Where the values lie along the line when source does not record node positions itself: a position source accepted by line_positions() (evaluated at the same time), a StaticProfile (its ArcLength column), or a mapping from node number to arc length in metres. Segment values are placed at the mid-arc of their end nodes, which needs the positions of every node. Without positions, values are placed by node or segment number.

Returns:

One profile per requested name, keyed by the name as given.

Return type:

dict[str, ArcProfile]

Raises:
  • KeyError – If a quantity is not recorded or positions lacks a node.

  • ValueError – If time or line_id is missing or not applicable, time is outside the record, or segment values cannot be placed.

class cabledyn.ArcProfile(quantity, unit, location_kind, location, ids, values, time, source=None, id_kind='Node')

One variable along one line at one time.

quantity

Canonical quantity name.

Type:

str

unit

Unit of values, or None if unknown.

Type:

str | None

location_kind

"ArcLength" (location in metres from End A), "Node", or "Segment" (location is the node or segment number).

Type:

str

location

(n,) non-decreasing locations.

Type:

numpy.ndarray

ids

(n,) node or segment numbers of the values.

Type:

numpy.ndarray

values

(n,) values.

Type:

numpy.ndarray

time

Time of the profile in seconds, or None for a static result.

Type:

float | None

source

Result file of the values, if any.

Type:

pathlib.Path | None

id_kind

"Node" or "Segment": what ids number. It must equal location_kind unless that is "ArcLength".

Type:

str

property maximum

Largest value.

property minimum

Smallest value.

plot(*, ax=None, label=None)

Plot the profile against its location.

Parameters:
  • ax (matplotlib.axes.Axes | None) – Axes to draw on; a new figure is created when omitted.

  • label (str | None) – Legend label; defaults to the quantity and time.

Returns:

The axes drawn on.

Return type:

matplotlib.axes.Axes

export(path, *, overwrite=False)

Atomically write the profile as a unit-labelled CSV.

Columns: the location (ArcLength_[m], Node_[-], or Segment_[-]), the node or segment number, and the value.

Parameters:
  • path (str | os.PathLike) – Target CSV file; missing parent directories are created.

  • overwrite (bool) – Replace an existing file instead of raising FileExistsError.

Returns:

Absolute path of the written file.

Return type:

pathlib.Path

cabledyn.line_range_graph(source, quantity, *, line_id=None, positions=None, start=None, stop=None)

Return the range graph of any per-node or per-segment variable of one line.

This extends cabledyn.node_range_graph() to every source accepted by line_field(), for example the effective tension of every segment from a per-line tension file.

Parameters:
  • source (object) – Any source accepted by line_field(), with a result file.

  • quantity (str) – Quantity name; see available_quantities().

  • line_id (int | None) – Line to take from a main output or a multi-line static profile.

  • positions (object | None) – Where the values lie along the line when source does not record node positions itself (see profiles_at()). A position history places each node at its arc length averaged over the window. Without positions, node values are placed by node number.

  • start (float | None) – Optional time window, in seconds.

  • stop (float | None) – Optional time window, in seconds.

Returns:

Minimum, maximum, and mean at each node or segment, against arc length (or node number). For a per-line source the graph’s line_id is read from the file name (<root>.Line<L>.t.out, <root>.MD.Line<N>.out), and is None when the name has none.

Return type:

RangeGraph

Raises:
  • KeyError – If the quantity is not recorded or positions lacks a node.

  • ValueError – If line_id is missing or not applicable, the window is invalid, the source has no result file, or segment values have no positions to place them.

Clearance

cabledyn.seabed_clearance(source, seabed, *, line_id=None, radius=0.0, start=None, stop=None)

Return the vertical clearance of every node of one line above the seabed.

Parameters:
  • source (object) – Node positions: any source accepted by cabledyn.line_positions().

  • seabed (float | Bathymetry) – The seabed elevation z of a flat seabed (-WtrDpth), in metres, or a Bathymetry surface.

  • line_id (int | None) – Line to take from a main output or a multi-line static profile.

  • radius (float) – Radius subtracted from the centreline clearance, for example the outer contact radius, in metres.

  • start (float | None) – Optional time window, in seconds.

  • stop (float | None) – Optional time window, in seconds.

Returns:

Clearance of every node at every sample.

Return type:

SeabedClearance

Raises:
  • KeyError – If the source records no node positions for the line.

  • ValueError – If the seabed or radius is not finite, line_id is missing or not applicable, or the window is invalid.

class cabledyn.SeabedClearance(time, node_ids, arc_length, clearance, radius=0.0, source=None, line_id=None)

Vertical clearance of every node of one line above the seabed.

time

(n_samples,) sample times in seconds, or None for a static configuration.

Type:

numpy.ndarray | None

node_ids

(n_nodes,) node numbers as the source names them.

Type:

numpy.ndarray

arc_length

(n_samples, n_nodes) deformed arc length from End A, in metres.

Type:

numpy.ndarray

clearance

(n_samples, n_nodes) clearance z - z_floor(x, y) - radius, in metres; negative where the node is below the seabed surface.

Type:

numpy.ndarray

radius

Radius subtracted from the centreline clearance, in metres.

Type:

float

source

Result file of the positions, if any.

Type:

pathlib.Path | None

line_id

Deck line identifier, when known (from line_id or the name of a per-line result file).

Type:

int | None

property minimum

Smallest clearance of any node at any sample, in metres.

property minimum_index

(sample, node) array indices of minimum (the first, if repeated).

property minimum_time

Time of minimum in seconds, or None when static.

property minimum_node

Node number of minimum.

property minimum_arc_length

Arc length from End A of minimum, in metres, at its time.

property node_minimum

(n_nodes,) smallest clearance of each node over time.

property sample_minimum

(n_samples,) smallest clearance along the line at each sample.

property location

(n_nodes,) time-mean arc length of each node, in metres.

profile(time=None, *, interpolation='linear')

Return the clearance along the line at one time.

Parameters:
  • time (float | None) – Time in seconds; None for a static configuration and required otherwise.

  • interpolation ({"linear", "nearest"}) – Linear interpolation between the bracketing samples, or the nearest sample.

Returns:

Quantity "seabed_clearance" in metres against arc length.

Return type:

ArcProfile

Raises:

ValueError – If time is missing, not applicable, or outside the record.

range_graph(line_id=None)

Return the clearance envelope along the line as a range graph.

Each node is placed at its time-mean arc length (location).

Parameters:

line_id (int | None) – Line identifier recorded in the graph; by default line_id (None when unknown).

Returns:

Quantity "clearance" in metres, with the minimum, maximum, and mean clearance of each node.

Return type:

RangeGraph

Raises:

ValueError – If the positions did not come from a result file.

plot(*, ax=None)

Plot the minimum clearance along the line against time.

A static clearance is plotted against arc length instead.

Parameters:

ax (matplotlib.axes.Axes | None) – Axes to draw on; a new figure is created when omitted.

Returns:

The axes drawn on.

Return type:

matplotlib.axes.Axes

cabledyn.line_clearance(a, b, *, line_id_a=None, line_id_b=None, radius_a=0.0, radius_b=0.0, start=None, stop=None)

Return the minimum distance between two lines at every sample.

Parameters:
  • a (object) – Node positions of each line: any source accepted by cabledyn.line_positions(). A static line is compared with every sample of the other; two histories must share their sample times.

  • b (object) – Node positions of each line: any source accepted by cabledyn.line_positions(). A static line is compared with every sample of the other; two histories must share their sample times.

  • line_id_a (int | None) – Line to take from a main output or a multi-line static profile.

  • line_id_b (int | None) – Line to take from a main output or a multi-line static profile.

  • radius_a (float) – Radii subtracted from the centreline distance, in metres.

  • radius_b (float) – Radii subtracted from the centreline distance, in metres.

  • start (float | None) – Optional time window, in seconds.

  • stop (float | None) – Optional time window, in seconds.

Returns:

Distance, closest points, and their arc lengths at every sample.

Return type:

LineClearance

Raises:
  • KeyError – If a source records no node positions.

  • ValueError – If the sample times differ, a radius is negative, line_id is missing or not applicable, or the window is invalid.

class cabledyn.LineClearance(time, distance, arc_length_a, arc_length_b, segment_a, segment_b, point_a, point_b, radius_a=0.0, radius_b=0.0)

Minimum distance between two lines at every sample.

Lines are the polylines through their nodes; the distance is the smallest segment-to-segment distance. a and b are the first and second line passed to line_clearance().

time

(n_samples,) sample times in seconds, or None when both lines are static.

Type:

numpy.ndarray | None

distance

(n_samples,) minimum centreline distance, in metres.

Type:

numpy.ndarray

arc_length_a, arc_length_b

(n_samples,) deformed arc length from End A of the closest point on each line, in metres.

Type:

numpy.ndarray

segment_a, segment_b

(n_samples,) one-based index, from End A, of the segment holding the closest point on each line.

Type:

numpy.ndarray

point_a, point_b

(n_samples, 3) closest points, in metres.

Type:

numpy.ndarray

radius_a, radius_b

Radii subtracted from the centreline distance, in metres.

Type:

float

property clearance

distance minus both radii, in metres.

Type:

(n_samples,) surface clearance

property minimum

Smallest clearance over all samples, in metres.

property minimum_index

Sample index of minimum (the first, if repeated).

property minimum_time

Time of minimum in seconds, or None when static.

property minimum_arc_length_a

Arc length on line a of the closest point at minimum_time.

property minimum_arc_length_b

Arc length on line b of the closest point at minimum_time.

plot(*, ax=None, label=None)

Plot the clearance against time.

Parameters:
  • ax (matplotlib.axes.Axes | None) – Axes to draw on; a new figure is created when omitted.

  • label (str | None) – Legend label.

Returns:

The axes drawn on.

Return type:

matplotlib.axes.Axes

Raises:

ValueError – If both lines are static.

export(path, *, overwrite=False)

Atomically write one row per sample as a unit-labelled CSV.

Parameters:
  • path (str | os.PathLike) – Target CSV file; missing parent directories are created.

  • overwrite (bool) – Replace an existing file instead of raising FileExistsError.

Returns:

Absolute path of the written file.

Return type:

pathlib.Path

cabledyn.clearance_matrix(lines, *, radius=0.0, start=None, stop=None)

Return the minimum clearance between every pair of lines.

Parameters:
  • lines (collections.abc.Mapping[str, object] | collections.abc.Sequence[object]) – Node positions of each line, keyed by name, or a sequence named "1", "2", … in order. Each is a per-line source accepted by cabledyn.line_positions() without line_id (build a cabledyn.LinePositions first for a main output).

  • radius (float | collections.abc.Mapping[str, float]) – One radius for every line, or a radius per name (missing names use zero), in metres.

  • start (float | None) – Optional time window, in seconds.

  • stop (float | None) – Optional time window, in seconds.

Returns:

Pairwise minimum clearance and the history of every pair.

Return type:

ClearanceMatrix

Raises:

ValueError – If fewer than two lines are given, or a pair cannot be compared (see line_clearance()).

class cabledyn.ClearanceMatrix(names, minimum, pairs)

Minimum clearance between every pair of a set of lines.

names

Line names, in input order.

Type:

tuple[str, …]

minimum

(n, n) symmetric matrix of the smallest clearance of each pair over all samples, in metres; nan on the diagonal.

Type:

numpy.ndarray

pairs

Clearance history of each pair (names[i], names[j]) with i < j.

Type:

collections.abc.Mapping[tuple[str, str], LineClearance]

pair(first, second)

Return the clearance history of two named lines.

The result’s a is the line listed first in names.

Raises:

KeyError – If a name is unknown or the two names are equal.

property governing

The pair with the smallest clearance, as (name_a, name_b, clearance).

export(path, *, overwrite=False)

Atomically write the minimum-clearance matrix as CSV, in metres.

The first column and the header hold the line names; the diagonal is blank.

Parameters:
  • path (str | os.PathLike) – Target CSV file; missing parent directories are created.

  • overwrite (bool) – Replace an existing file instead of raising FileExistsError.

Returns:

Absolute path of the written file.

Return type:

pathlib.Path

cabledyn.segment_distance(p1, q1, p2, q2)

Return the minimum distance between segments p1-q1 and p2-q2.

The closest points are p1 + s (q1 - p1) and p2 + t (q2 - p2) with 0 <= s, t <= 1. Zero-length segments are points. For parallel segments, one of the equally close pairs is returned. The inputs broadcast over any leading dimensions.

Parameters:
  • p1 (array_like) – End points, shape (..., 3).

  • q1 (array_like) – End points, shape (..., 3).

  • p2 (array_like) – End points, shape (..., 3).

  • q2 (array_like) – End points, shape (..., 3).

Returns:

(distance, s, t), each of the broadcast leading shape.

Return type:

tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray]

Raises:

ValueError – If a point does not have three coordinates or is not finite.

cabledyn.read_bathymetry(path)

Read a structured bathymetry file of x y depth rows.

This is the file a deck names with the bathymetryFile option. Rows may be in any order but must form one complete rectangular grid without duplicates; blank lines and #, !, or -- comments are ignored.

Parameters:

path (str | os.PathLike) – Bathymetry file.

Returns:

The grid, with x and y sorted.

Return type:

Bathymetry

Raises:
  • FileNotFoundError – If the file does not exist.

  • ValueError – If a row is not three plain numbers, a depth is not positive, or the rows do not form one complete grid.

class cabledyn.Bathymetry(x, y, depth, source=None)

A structured seabed: water depth on a rectangular x-y grid.

The seabed elevation is z_floor = -depth. Between grid points it is bilinear in each cell; outside the grid it takes the value at the nearest grid edge, as in the solver.

x

(nx,) strictly increasing grid coordinates, in metres, nx >= 2.

Type:

numpy.ndarray

y

(ny,) strictly increasing grid coordinates, in metres, ny >= 2.

Type:

numpy.ndarray

depth

(nx, ny) positive water depth below still water, in metres.

Type:

numpy.ndarray

source

File the grid was read from, if any.

Type:

pathlib.Path | None

Raises:

ValueError – If an axis has fewer than two points or does not strictly increase, depth does not have shape (nx, ny), or a value is not finite or a depth is not positive.

depth_at(x, y)

Return the water depth at points (x, y), in metres.

Parameters:
  • x (array_like) – Horizontal coordinates in metres; broadcast against each other.

  • y (array_like) – Horizontal coordinates in metres; broadcast against each other.

Returns:

Positive depth, with the broadcast shape of x and y.

Return type:

numpy.ndarray

Raises:

ValueError – If a coordinate is not finite.

floor(x, y)

Return the seabed elevation z_floor = -depth at points (x, y).

Parameters:
  • x (array_like) – Horizontal coordinates in metres; broadcast against each other.

  • y (array_like) – Horizontal coordinates in metres; broadcast against each other.

Returns:

Seabed elevation in metres (negative below still water).

Return type:

numpy.ndarray

Raises:

ValueError – If a coordinate is not finite.

Summary tables

cabledyn.channel_summary(history, channels=None, *, start=None, stop=None)

Return per-channel statistics with the time of each extreme.

Parameters:
  • history (TimeHistory) – Any time history.

  • channels (str | collections.abc.Iterable[str] | None) – One channel, several, or None for every channel except time.

  • start (float | None) – Optional time window, in seconds.

  • stop (float | None) – Optional time window, in seconds.

Returns:

One record per channel, in the requested order.

Return type:

SummaryTable[ChannelSummary]

Raises:
  • KeyError – If a channel is not in the history.

  • ValueError – If the window is invalid or empty.

cabledyn.line_summary(name, *, positions=None, tensions=None, curvature=None, seabed=None, line_id=None, radius=0.0, start=None, stop=None)

Return the tension, curvature, and seabed-clearance extremes of one line.

Parameters:
  • name (str) – Line name recorded in the summary.

  • positions (object | None) – Node positions (any source accepted by cabledyn.line_positions()), used to place extremes along the line and for the seabed clearance.

  • tensions (object | None) – A source of the tension quantity (see cabledyn.line_field()): a per-line tension file, a main output with Ten<L>N<J> channels, a MoorDyn-F line file, or a static profile.

  • curvature (object | None) – A source of the curvature quantity: a main output with Curv<L>N<J> channels, a MoorDyn-F line file with Kurv, or a static profile.

  • seabed (float | Bathymetry | None) – Seabed for the clearance (see cabledyn.seabed_clearance()); needs positions.

  • line_id (int | None) – Line to take from a main output or a multi-line static profile; used only for those sources.

  • radius (float) – Radius subtracted from the seabed clearance, in metres.

  • start (float | None) – Optional time window, in seconds.

  • stop (float | None) – Optional time window, in seconds.

Returns:

The extremes of the supplied quantities.

Return type:

LineSummary

Raises:
  • KeyError – If a source does not record its quantity for the line.

  • ValueError – If nothing is supplied, seabed is given without positions, or a window, line_id, or placement is invalid.

class cabledyn.ChannelSummary(channel, unit, count, minimum, minimum_time, maximum, maximum_time, mean, standard_deviation, rms)

Statistics of one time-history channel with the time of its extremes.

channel

Channel name.

Type:

str

unit

Channel unit, or None if unknown.

Type:

str | None

count

Number of samples.

Type:

int

minimum, maximum

Extreme values.

Type:

float

minimum_time, maximum_time

Time of the first occurrence of each extreme, in seconds.

Type:

float

mean

Arithmetic mean.

Type:

float

standard_deviation

Population standard deviation.

Type:

float

rms

Root-mean-square value.

Type:

float

class cabledyn.LineSummary(name, start_time, end_time, sample_count, maximum_tension=None, maximum_tension_time=None, maximum_tension_location=None, minimum_tension=None, minimum_tension_time=None, minimum_tension_location=None, tension_location_kind=None, maximum_curvature=None, maximum_curvature_time=None, maximum_curvature_location=None, curvature_location_kind=None, minimum_bend_radius=None, minimum_seabed_clearance=None, minimum_seabed_clearance_time=None, minimum_seabed_clearance_arc_length=None)

Extremes of one line over a run or a static configuration.

Locations are arc lengths from End A in metres when node positions are available (location_kind "ArcLength"), otherwise node or segment numbers. Times are None for a static result. Every field of a quantity that was not supplied is None. The time window is that of the first quantity summarized (tension, curvature, then clearance).

name

Line name.

Type:

str

start_time, end_time

First and last sample time summarized, in seconds.

Type:

float | None

sample_count

Number of samples summarized (1 for a static result).

Type:

int

maximum_tension, minimum_tension

Tension extremes over the line and the run, in newtons.

Type:

float | None

maximum_tension_time, minimum_tension_time

Times of the tension extremes, in seconds.

Type:

float | None

maximum_tension_location, minimum_tension_location

Locations of the tension extremes.

Type:

float | None

tension_location_kind

"ArcLength", "Node", or "Segment".

Type:

str | None

maximum_curvature

Largest curvature, in 1/m.

Type:

float | None

maximum_curvature_time

Time of the largest curvature, in seconds.

Type:

float | None

maximum_curvature_location

Location of the largest curvature.

Type:

float | None

curvature_location_kind

"ArcLength" or "Node".

Type:

str | None

minimum_bend_radius

Reciprocal of maximum_curvature, in metres (infinite for zero curvature).

Type:

float | None

minimum_seabed_clearance

Smallest node clearance above the seabed, in metres.

Type:

float | None

minimum_seabed_clearance_time

Time of the smallest clearance, in seconds.

Type:

float | None

minimum_seabed_clearance_arc_length

Arc length of the smallest clearance at that time, in metres.

Type:

float | None

class cabledyn.SummaryTable(records)

An ordered table of dataclass records of one type.

records

The records, one per row. The columns are the record’s fields.

Type:

tuple

Raises:

TypeError – If a record is not a dataclass instance or the records differ in type.

property columns

Field names of the records, in declaration order; empty for no records.

column(name)

Return the values of one field, one per record.

Raises:

KeyError – If no record field has that name.

to_records()

Return one {field: value} dictionary per record.

to_dataframe()

Return the table as a pandas DataFrame, one row per record.

Raises:

ImportError – If pandas is not installed.

export(path, *, overwrite=False)

Atomically write the table as CSV, one row per record.

Floats are written with full precision, None as a blank field.

Parameters:
  • path (str | os.PathLike) – Target CSV file; missing parent directories are created.

  • overwrite (bool) – Replace an existing file instead of raising FileExistsError.

Returns:

Absolute path of the written file.

Return type:

pathlib.Path

Raises:

ValueError – If the table has no record.

In-process coupling

These names load the CableDyn shared library on first access; see Python package for how the library is located. Array ordering, frames, and units at the coupling boundary follow Coupling boundary, and the underlying C functions are described in C API reference.

class cabledyn.CableDyn(deck=None)

One CableDyn solver instance behind the C ABI. The class is a context manager: leaving a with block calls close().

Parameters:

deck (str | os.PathLike | None) – Path of a sectioned .dat deck; see Deck format reference (.dat). When given, the deck is parsed and its static initial condition is solved immediately, as by init_deck(). None (the default) creates an uninitialised instance for a later init_deck() call.

Raises:
  • CableDynError – if the handle cannot be created or the deck fails to initialise. A failed initialisation releases the handle before the exception propagates.

  • ValueError – if the deck path contains a NUL character or, on Windows, cannot be represented in the active ANSI code page.

The coupled exchange is kinematics in, loads out. Kinematics are the position (m), velocity (m/s), and acceleration (m/s2) of every coupled point, three degrees of freedom per point. Loads are the forces (N) the lines exert on those degrees of freedom. Input arrays may be flat, shaped (n_coupled_dof,) with interleaved x, y, z values per point, or column-per-point, shaped (3, n_points). Returned arrays are always flat float64 arrays. A (3, 3) input is read column-per-point, so pass three points flat when in doubt.

Calls on one instance are serialised by an internal lock. Independent instances may be used from different threads; their deck initialisations are serialised inside the library, their steps run concurrently. dt and fluid_density must be finite real numbers (dt positive, fluid_density non-negative) and arrays real-valued; other values raise TypeError or ValueError before the library is called.

close()

Release the native handle. Calling it again is harmless.

last_error()

Return the library’s most recent diagnostic message for this instance.

Returns:

The message, or an empty string when there is none.

Return type:

str

init_deck(deck)

Initialise from a deck file: parse it, build the model, and solve the static initial condition.

Parameters:

deck (str | os.PathLike) – Path of the .dat deck. Relative ancillary files named in the deck are resolved as described in Deck format reference (.dat).

Raises:
  • CableDynError – if parsing, model construction, or the static solve fails. A failed initialisation keeps any previously initialised model.

  • ValueError – if the path contains a NUL character or, on Windows, cannot be represented in the active ANSI code page.

property initialized: bool

Whether the instance holds an initialised model.

property n_coupled_dof: int

Number of coupled degrees of freedom, three per host-driven point.

Raises:

CableDynError – if the query fails, for example on an uninitialised model.

property n_points: int

Number of stored system points. This is the number of columns expected by update_point_fluid_fields().

Raises:

CableDynError – if the query fails, for example on an uninitialised model.

property n_lines: int

Number of lines in the model.

Raises:

CableDynError – if the query fails, for example on an uninitialised model.

get_coupled_motion()

Return the current kinematics of the coupled points.

Returns:

(q, v, a): positions (m), velocities (m/s), and accelerations (m/s2), each a flat array of shape (n_coupled_dof,).

Return type:

tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray]

Raises:

CableDynError – if the call fails, for example on an uninitialised model.

update_states(q, v, a)

Transfer coupled-point kinematics to the model without advancing time. Use it when a host needs loads for trial kinematics before committing a step.

Parameters:
  • q (array_like) – Coupled-point positions (m).

  • v (array_like) – Coupled-point velocities (m/s).

  • a (array_like) – Coupled-point accelerations (m/s2).

Raises:
  • ValueError – if an array is neither flat (n_coupled_dof,) nor (3, n_coupled_dof // 3).

  • CableDynError – if the library rejects the call.

step(dt, q, v, a)

Advance one implicit time step of length dt with the coupled-point kinematics prescribed at the end of the step, t + dt.

Parameters:
  • dt (float) – Step length (s).

  • q (array_like) – Coupled-point positions at t + dt (m).

  • v (array_like) – Coupled-point velocities at t + dt (m/s).

  • a (array_like) – Coupled-point accelerations at t + dt (m/s2).

Returns:

The number of Newton iterations used.

Return type:

int

Raises:
  • ValueError – if an array has the wrong shape.

  • CableDynError – if the step fails outright. The model is left at time t.

  • ConvergenceError – if the step ends without meeting the Newton tolerance. The model has then already advanced to t + dt with its best iterate, so retrying the same step would advance time twice.

calc_output()

Return the coupled reaction loads at the current committed state.

Returns:

Forces (N) the lines exert on the coupled degrees of freedom, a flat array of shape (n_coupled_dof,).

Return type:

numpy.ndarray

Raises:

CableDynError – if the call fails.

update_point_fluid_fields(fluid_velocity, fluid_acceleration, waterline_z, fluid_density)

Prescribe external fluid kinematics at every system point. This is the interface for coupling to an external flow solver. Call it before step().

Parameters:
  • fluid_velocity (array_like) – Fluid velocity at each point (m/s), shaped (3, n_points) or flat (3 * n_points,).

  • fluid_acceleration (array_like) – Fluid acceleration at each point (m/s2), with the same shape as fluid_velocity.

  • waterline_z (array_like) – Global z coordinate of the free surface (m) at each point, shape (n_points,).

  • fluid_density (float) – Fluid density (kg/m3).

Raises:
  • ValueError – if an array has the wrong shape.

  • CableDynError – if the library rejects the fields.

property lines: tuple[cabledyn.objects.Line, ...]

The model’s lines in ascending deck id.

property points: tuple[cabledyn.objects.Point, ...]

The model’s points in solver order.

property bodies: tuple[cabledyn.objects.Body, ...]

The model’s Rigid6 bodies.

property rods: tuple[cabledyn.objects.Rod, ...]

The model’s rods.

line(line_id)
point(point_id)
body(body_id)
rod(rod_id)

Return the object with the given deck id.

Raises:

KeyError – if there is no such object.

channel(token)

Evaluate one output channel at the committed state and return its value. token uses the deck OUTPUTS vocabulary (Output files and channels), for example FairTen1, L2N5px, Curv1N3, Point4Fz, Body1Pz, or Rod2TenA; the value equals what the standalone driver writes for that channel at the same state.

Return type:

float

Raises:
  • ValueError – if the token is empty or longer than 64 characters.

  • CableDynError – if the token is malformed or names an object the model lacks.

channels(tokens)

Evaluate several channels; returns a (len(tokens),) array.

step_held(dt)

Advance one step with every coupled point held at its current position (zero velocity and acceleration); returns the Newton iteration count, as step().

property time: float

Simulation time (s): 0 after initialisation, advanced by every completed step.

property deck: pathlib.Path | None

Absolute path of the deck the model was initialised from.

Object views

The classes returned by CableDyn.lines, CableDyn.points, CableDyn.bodies and CableDyn.rods. They live in cabledyn.objects, which imports without the shared library.

Per-object views of an in-process CableDyn model.

A Line, Point, Body or Rod is a light handle on one object of the model’s inventory. Its methods read the committed solver state at the time of the call through the C ABI object queries, which use the evaluator behind the deck OUTPUTS channels and the per-line .p/.t files: a value equals what the matching output channel reports at the same step.

Views are cheap to hold and never cache state. A view becomes stale when the model is re-initialized or closed; using it then raises CableDynError.

These views describe a running model. The deck rows of the same names in cabledyn.builder (Line, Point, Body, Rod) describe deck input instead; import each family from its own module.

Every array getter accepts an optional out array, a writeable C-contiguous float64 array of the documented shape: the library writes into it directly and it is returned, so a caller polling every step allocates nothing. Without out a new array is returned; any other out raises ValueError.

class cabledyn.objects.Line(model, info, generation)

One line (mooring line or cable) of an in-process model.

Nodes run from End A (index 0) to End B, the order of the L<L>N<k> output channels (node k is array row k - 1) and of the .Line<L>.p.out files. Segments run in the same order.

property n_nodes

Node count.

property n_segments

Segment (element) count, n_nodes - 1.

property finite_ei

Whether the line carries bending stiffness (the cubic-Hermite element).

values(quantity, out=None)

Any line quantity by name.

Parameters:
  • quantity (str) – One of position, velocity, acceleration (shape (n_nodes, 3)), tension, curvature, bend_moment, declination, azimuth (shape (n_nodes,)) or segment_tension (shape (n_segments,)).

  • out (numpy.ndarray, optional) – Destination array of that shape.

node_positions(out=None)

Node positions (n_nodes, 3) [m] (the L<L>N<k>p{x,y,z} channels).

node_velocities(out=None)

Node velocities (n_nodes, 3) [m/s].

node_accelerations(out=None)

Node accelerations (n_nodes, 3) [m/s^2].

node_tensions(out=None)

Effective tension at each node (n_nodes,) [N] (Ten<L>N<k>).

The end nodes carry the line-end force magnitude (FairTen/AnchTen), interior nodes the length-weighted mean of the two adjacent segments.

segment_tensions(out=None)

Segment tensions (n_segments,) [N], as in .Line<L>.t.out.

curvature(out=None)

Curvature at each node (n_nodes,) [1/m] (Curv<L>N<k>).

bend_moment(out=None)

Bend moment magnitude at each node (n_nodes,) [N-m]; zero when EI = 0.

declination(out=None)

Declination at each node (n_nodes,) [deg] (L<L>N<k>Dec).

azimuth(out=None)

Azimuth at each node (n_nodes,) [deg] (L<L>N<k>Azi).

arc_length()

Deformed arc length of each node from End A (n_nodes,) [m].

fairlead_tension()

End A tension [N] (FairTen<L>).

anchor_tension()

End B tension [N] (AnchTen<L>).

property id

Deck id of the object.

property index

0-based position in the model’s inventory of this kind.

property name

Channel-vocabulary name, e.g. "Line3" or "Body1".

class cabledyn.objects.Point(model, info, generation)

One point (fixed, coupled, free or connect) of an in-process model.

property kind

"fixed", "coupled", "free" or "connect".

position(out=None)

Position (3,) [m] (Point<P>p{x,y,z}).

velocity(out=None)

Velocity (3,) [m/s].

force(out=None)

Resultant force of the attached lines on the point (3,) [N] (Point<P>F).

property id

Deck id of the object.

property index

0-based position in the model’s inventory of this kind.

property name

Channel-vocabulary name, e.g. "Line3" or "Body1".

class cabledyn.objects.Body(model, info, generation)

One Rigid6 body of an in-process model.

Angles are the x-y’-z’’ Euler angles of the deck convention in degrees, and angular rates are in deg/s (deg/s^2), as in the Body<N> output channels.

pose(out=None)

[x, y, z, rx, ry, rz] of the reference point [m, deg].

velocity(out=None)

[vx, vy, vz, wx, wy, wz] [m/s, deg/s].

acceleration(out=None)

[ax, ay, az, alpha_x, alpha_y, alpha_z] [m/s^2, deg/s^2].

wrench(out=None)

Net external load [Fx, Fy, Fz, Mx, My, Mz] about the reference point [N, N-m].

rotation_matrix()

Body-to-global rotation matrix (3, 3) from the x-y’-z’’ pose angles.

property id

Deck id of the object.

property index

0-based position in the model’s inventory of this kind.

property name

Channel-vocabulary name, e.g. "Line3" or "Body1".

class cabledyn.objects.Rod(model, info, generation)

One rigid rod of an in-process model. Node 0 is End A, the last node End B.

property n_nodes

Node count, NumSegs + 1.

property n_segments

Segment count (the deck NumSegs).

node_positions(out=None)

Node positions (n_nodes, 3) [m] (Rod<N>N<k>P{x,y,z}).

end_a()

End A position (3,) [m].

end_b()

End B position (3,) [m].

axis()

Unit vector from End A to End B (3,).

pose(out=None)

[x, y, z, rx, ry, 0]: End A [m] and the axis roll and pitch from vertical [deg].

velocity(out=None)

End A [vx, vy, vz, wx, wy, wz] [m/s, deg/s].

wrench(out=None)

Net load [Fx, Fy, Fz, Mx, My, Mz] about End A [N, N-m].

property id

Deck id of the object.

property index

0-based position in the model’s inventory of this kind.

property name

Channel-vocabulary name, e.g. "Line3" or "Body1".

cabledyn.abi_version()

Return the C ABI version of the loaded shared library. Importing the in-process API fails with OSError when the library’s ABI version differs from the one this package supports.

Return type:

int

cabledyn.abi_minor()

Return the extension level of ABI 1 of the loaded library: 1 when it has the object queries behind CableDyn.lines and CableDyn.channel(), 0 for an older library.

Return type:

int

cabledyn.library_path()

Return the absolute path of the loaded CableDyn shared library.

Return type:

str

cabledyn.version_string()

Return the loaded library’s human-readable version string.

Return type:

str

Exceptions

All exception classes are importable without the shared library, so in-process errors can be caught in any installation. The hierarchy is:

exception cabledyn.DriverError

Base class for standalone-driver and result-file errors.

exception cabledyn.DriverNotFoundError

No usable CableDyn driver executable could be located.

exception cabledyn.DriverExecutionError(message, *, returncode=None, stdout='', stderr='')

The native driver returned an error or did not produce its main output.

Captured streams are retained for diagnosis.

Parameters:
  • message (str) – Error message.

  • returncode (int | None) – Native exit code, or None.

  • stdout (str) – Captured output streams.

  • stderr (str) – Captured output streams.

returncode

Native exit code; None for failures that occur before process exit, such as a timeout. 0 means the run finished but its main output was missing or invalid.

Type:

int | None

stdout

Captured standard output, possibly partial.

Type:

str

stderr

Captured standard error, possibly partial.

Type:

str

exception cabledyn.OutputFormatError

A CableDyn output table is missing, truncated, or malformed.

exception cabledyn.DeckFormatError

A CableDyn input deck is structurally malformed or inconsistent.

exception cabledyn.StudyFormatError

A generated-case or completed-study manifest is malformed or unauditable.

exception cabledyn.StudyOutputError

A study ran its cases but could not write summary.csv or study.json.

The per-case native outputs and logs that were already written are kept.

exception cabledyn.CableDynError(call, status, detail)

A CableDyn C API call failed.

call: str

Name of the C function that failed, for example "CableDyn_Step".

status: int

The C ABI status code: 1 BAD_HANDLE, 2 ALLOC_FAIL, 3 BAD_INPUT, 4 SOLVE_FAIL, or 5 NOT_INITIALIZED.

detail: str

The library’s diagnostic message for the handle, possibly empty.

exception cabledyn.ConvergenceError(call, detail, *, n_iter, stalled)

An implicit step finished without meeting the Newton tolerance. A subclass of CableDynError with status 4 (SOLVE_FAIL).

The model has already advanced to t + dt and holds the best iterate found, so retrying the same step would advance time twice.

n_iter: int

Number of Newton iterations performed.

stalled: bool

Whether the line search stalled.