Export outputs¶
The Dataset
output format is a standard object from Xarray and all methods from Xarray’s manual can be used to manipulate and export it.
On top of that, Capytaine provides some wrappers functions to simplify the export into a NetCDF file, as well as into other formats more specific to hydrodynamics.
Exporting hydrodynamic dataset¶
NetCDF format¶
The xarray dataset produced by assemble_dataset
(or fill_dataset
) has a structure close to the NetCDF file format and can easily be saved to this format by export_dataset()
:
cpt.export_dataset("path/to/dataset.nc", dataset, format="netcdf")
Note
The netCDF standard does not handle complex numbers.
Capytaine is using a non-standard representation of complex numbers by
transforming all complex-valued arrays of shape (...)
into real-valued
arrays of shape (..., 2)`
using the functions
separate_complex_values()
and
merge_complex_values()
(done automatically by
export_dataset()
).
See also https://github.com/PlasmaFAIR/nc-complex for more context and alternatives.
Note
Exporting more outputs such as pressure field on the hull in a NetCDF file is considered in the future. See https://github.com/capytaine/capytaine/issues/520 for examples of such outputs.
Wamit format¶
The hydrodynamic results from a Capytaine xarray.Dataset
can be exported into WAMIT-compatible text files (.1
, .3
, .3fk
, .3sc
, .hst
) using:
cpt.export_dataset("problem_name", dataset, format="wamit", exports=("1", "3", "3fk", "3sc", "hst"))
This will produce the following files (depending on the fields present in the dataset and the flags passed to the optional exports
argument):
problem_name.1
for added mass and radiation damping coefficients,problem_name.3
for total excitation forces (Froude-Krylov + diffraction),problem_name.3fk
for Froude-Krylov forces only,problem_name.3sc
for diffraction forces only.problem_name.hst
for hydrostatics results (if supported)
Invalid or unavailable exports are skipped with a warning.
The length scale used for normalization in WAMIT data is taken by default as \(1\) meter.
Note
These exports require that the forward_speed
in the dataset is zero.
If not, a ValueError
is raised to avoid exporting inconsistent results.
Nemoh format¶
The following code will write files named RadiationCoefficients.tec
and ExcitationForce.tec
in a format roughly matching the one of Nemoh 2:
cpt.export_dataset("path/to/result_dir/", dataset, format="nemoh")
This feature is still experimental. Please report issues encountered with this.
Excel format¶
Export to Excel format is not currently built in export_dataset()
.
This section is meant to show an example of exporting to a format that is not explicitly implemented in Capytaine.
We use here the openpyxl
library (that can be installed with pip install openpyxl
) to export a dataset to Excel format:
dataset[["added_mass", "radiation_damping"]].to_dataframe().to_excel("radiation_data.xlsx")
from capytaine.io.xarray import separate_complex_values
separate_complex_values(dataset[["Froude_Krylov_force", "diffraction_force"]]).to_dataframe().to_excel("diffraction_data.xlsx")
For convenience, the radiation and diffraction data have been stored in separate files.
Since this export method poorly supports complex number, the separate_complex_values
has been used to transform them to a pair of real numbers, as discussed for NetCDF export above.
Saving the rotation center of rigid bodies in NetCDF files¶
Saving rotation hydrodynamic coefficients without explicitly defining the rotation axes can be ambiguous and can lead to confusion downstream. While this is not done automatically by Capytaine at the moment, it can be added to the dataset manually. The example below, which is an extension of the Quickstart example, saves the rotation centers of a multibody problem in a way that is understood notably by BEMRosetta:
import numpy as np
import xarray as xr
import capytaine as cpt
body_1 = cpt.FloatingBody(
mesh=cpt.mesh_sphere(center=(0, 0, 0)),
dofs=cpt.rigid_body_dofs(rotation_center=(0, 0, 0)),
center_of_mass=(0, 0, 0),
name="my_sphere",
)
body_1.inertia_matrix = body_1.compute_rigid_body_inertia()
body_1.hydrostatic_stiffness = body_1.immersed_part().compute_hydrostatic_stiffness()
# If you have several rigid bodies, copy the code above to define "body_2", "body_3", etc.
list_of_bodies = [body_1] # Replace "[body_1]" by "[body_1, body_2, body_3]" for multibody problem.
all_bodies = cpt.FloatingBody.join_bodies(*list_of_bodies).immersed_part()
# Set up parameters
test_matrix = xr.Dataset({
"omega": np.linspace(0.1, 2.0, 20), # Can also specify "period", "wavelength" or "wavenumber"
"wave_direction": np.linspace(0, np.pi, 3),
"radiating_dof": list(all_bodies.dofs),
})
# Do the resolution
solver = cpt.BEMSolver()
dataset = solver.fill_dataset(test_matrix, all_bodies)
dataset.coords["rigid_body_component"] = [body.name for body in list_of_bodies]
dataset["rotation_center"] = (["rigid_body_component", "point_coordinates"], [body.rotation_center for body in list_of_bodies])
dataset["center_of_mass"] = (["rigid_body_component", "point_coordinates"], [body.center_of_mass for body in list_of_bodies])
# Export to NetCDF file
cpt.export_dataset("dataset.nc", dataset, format="netcdf")
The support for this in Capytaine should be improved in the future.
Saving the hydrostatics data of rigid body(ies) in Nemoh’s format¶
For a rigid body, or a set of several rigid bodies, the following information can be saved as written by Nemoh’s and read by BEMIO to produce .h5
files for WEC-Sim:
Hydrostatic stiffness matrix,
Centre of gravity,
Centre of buoyancy,
Displacement volume
They are stored in two files (Hydrostatics.dat
and KH.dat
) for each body, using the following syntax:
from capytaine.io.legacy import export_hydrostatics
export_hydrostatics("directory_to_save_hydrostatics_data", body)
for a single rigid body or, e.g.,:
from capytaine.io.legacy import export_hydrostatics
export_hydrostatics("directory_to_save_hydrostatics_data", [body_1, body_2, body_3])
for several rigid bodies.
In order to use this function, please ensure that the body’s centre of gravity has been defined correctly and the following methods have been called on the FloatingBody
object before passing it to export_hydrostatics
:
body.add_all_rigid_body_dofs()
body.inertia_matrix = body.compute_rigid_body_inertia()
body.hydrostatic_stiffness = body.compute_hydrostatic_stiffness()