Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reuse mesh when saving to VTX #2738

Merged
merged 56 commits into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
b7600f6
Complimentary typo fixes
massimiliano-leoni Aug 3, 2023
b0c77bf
Allow to reuse mesh when saving to VTX
massimiliano-leoni Aug 3, 2023
afb18f6
Merge remote-tracking branch 'origin/main' into mleoni/VTXReuseMesh
garth-wells Aug 24, 2023
7b9801c
Style updates
garth-wells Aug 24, 2023
c1d8b0a
Simplification
garth-wells Aug 24, 2023
cefb34d
Improve code
garth-wells Aug 24, 2023
3357f5d
Improve code
garth-wells Aug 24, 2023
9838aad
More improvements
garth-wells Aug 24, 2023
3227596
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Sep 14, 2023
de64ca5
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Sep 19, 2023
eed942e
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Sep 20, 2023
aeaf35d
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Oct 4, 2023
af0f374
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Oct 11, 2023
b7ad933
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Oct 16, 2023
10fddf2
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Oct 17, 2023
b86093e
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Oct 23, 2023
ab1ed17
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Oct 25, 2023
aedc24e
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Oct 26, 2023
5f14aa9
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Oct 29, 2023
539d51f
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Oct 31, 2023
1b98c23
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Nov 5, 2023
eff128f
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Nov 14, 2023
50ea557
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Nov 16, 2023
9662732
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Nov 18, 2023
fd60bd2
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Nov 23, 2023
6016881
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Dec 4, 2023
c1e227e
Complimentary typo fixes
massimiliano-leoni Dec 4, 2023
9f98a71
Add functionality to Python interface
massimiliano-leoni Dec 4, 2023
69c6861
Merge branch 'mleoni/VTXReuseMesh' of github.com:massimiliano-leoni/d…
massimiliano-leoni Dec 4, 2023
2f29a0b
Fixed Python interface
massimiliano-leoni Dec 4, 2023
f26033f
Flake8
massimiliano-leoni Dec 4, 2023
92b052b
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Dec 5, 2023
a1709e7
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Dec 11, 2023
552764a
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Dec 15, 2023
1ad2843
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Jan 4, 2024
5c8d843
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Jan 4, 2024
2df616d
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Jan 4, 2024
0467900
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Jan 8, 2024
7510c4f
Added unit test for mesh reuse
massimiliano-leoni Jan 8, 2024
bd4ade7
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Jan 8, 2024
77e6972
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Jan 9, 2024
dfbae84
Guessing a python test
massimiliano-leoni Jan 9, 2024
9736299
Merge branch 'mleoni/VTXReuseMesh' of github.com:massimiliano-leoni/d…
massimiliano-leoni Jan 9, 2024
8262b27
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Jan 10, 2024
ed57733
Add check in python test
massimiliano-leoni Jan 10, 2024
4f30d11
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Jan 12, 2024
b71c1a4
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Jan 12, 2024
dfc7993
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Jan 15, 2024
8aa8ec9
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Jan 16, 2024
4412e6b
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Jan 18, 2024
9255cd4
Merge branch 'FEniCS:main' into mleoni/VTXReuseMesh
massimiliano-leoni Jan 22, 2024
546b6b7
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Jan 23, 2024
70305cd
Merge branch 'main' into mleoni/VTXReuseMesh
massimiliano-leoni Jan 24, 2024
3aaa4e0
Linting
massimiliano-leoni Jan 24, 2024
2c6da43
Merge branch 'mleoni/VTXReuseMesh' of github.com:massimiliano-leoni/d…
massimiliano-leoni Jan 24, 2024
c4c3278
Linting
massimiliano-leoni Jan 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cpp/demo/interpolation-io/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ void interpolate_scalar(std::shared_ptr<mesh::Mesh<U>> mesh,
#endif
}

// This function interpolations a function is a H(curl) finite element
// This function interpolates a function in a H(curl) finite element
// space. To visualise the function, it interpolates the H(curl) finite
// element function in a discontinuous Lagrange space and outputs the
// Lagrange finite element function to a VTX file for visualisation.
Expand Down
4 changes: 2 additions & 2 deletions cpp/dolfinx/fem/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -707,8 +707,8 @@ FunctionSpace<T> create_functionspace(

/// @brief Create a FunctionSpace from UFC data.
/// @param[in] fptr Pointer to a ufcx_function_space_create function.
/// @param[in] function_name Name of a function whose function space to
/// create. Function name is the name of Python variable for
/// @param[in] function_name Name of a function whose function space is to
/// create. Function name is the name of the Python variable for
/// ufl.Coefficient, ufl.TrialFunction or ufl.TestFunction as defined in
/// the UFL file.
/// @param[in] mesh Mesh
Expand Down
94 changes: 78 additions & 16 deletions cpp/dolfinx/io/ADIOS2Writers.h
Original file line number Diff line number Diff line change
Expand Up @@ -780,8 +780,9 @@ void vtx_write_mesh(adios2::IO& io, adios2::Engine& engine,
/// @param[in] engine The ADIOS2 engine object
/// @param[in] V The function space
template <std::floating_point T>
void vtx_write_mesh_from_space(adios2::IO& io, adios2::Engine& engine,
const fem::FunctionSpace<T>& V)
std::pair<std::vector<std::int64_t>, std::vector<std::uint8_t>>
vtx_write_mesh_from_space(adios2::IO& io, adios2::Engine& engine,
const fem::FunctionSpace<T>& V)
{
auto mesh = V.mesh();
assert(mesh);
Expand Down Expand Up @@ -839,9 +840,18 @@ void vtx_write_mesh_from_space(adios2::IO& io, adios2::Engine& engine,
engine.Put(ghost, x_ghost.data());

engine.PerformPuts();
return {std::move(x_id), std::move(x_ghost)};
}
} // namespace impl_vtx

/// Mesh reuse policy
enum class VTXMeshPolicy
{
update, ///< Re-write the mesh to file upon every write of a fem::Function
jhale marked this conversation as resolved.
Show resolved Hide resolved
reuse ///< Write the mesh to file only the first time a fem::Function is
///< written to file
};

/// @brief Writer for meshes and functions using the ADIOS2 VTX format,
/// see
/// https://adios2.readthedocs.io/en/latest/ecosystem/visualization.html#using-vtk-and-paraview.
Expand All @@ -865,7 +875,8 @@ class VTXWriter : public ADIOS2Writer
VTXWriter(MPI_Comm comm, const std::filesystem::path& filename,
std::shared_ptr<const mesh::Mesh<T>> mesh,
std::string engine = "BPFile")
: ADIOS2Writer(comm, filename, "VTX mesh writer", engine), _mesh(mesh)
: ADIOS2Writer(comm, filename, "VTX mesh writer", engine), _mesh(mesh),
_mesh_reuse_policy(VTXMeshPolicy::update)
{
// Define VTK scheme attribute for mesh
std::string vtk_scheme = impl_vtx::create_vtk_schema({}, {}).str();
Expand All @@ -883,12 +894,16 @@ class VTXWriter : public ADIOS2Writer
/// element family and degree, and degree-of-freedom map (up to the
/// blocksize) must be the same for all functions.
/// @param[in] engine ADIOS2 engine type.
/// @param[in] mesh_policy Controls if the mesh is written to file at
/// the first time step only or is re-written (updated) at each time
/// step.
/// @note This format supports arbitrary degree meshes.
VTXWriter(MPI_Comm comm, const std::filesystem::path& filename,
const typename adios2_writer::U<T>& u,
std::string engine = "BPFile")
const typename adios2_writer::U<T>& u, std::string engine,
VTXMeshPolicy mesh_policy = VTXMeshPolicy::update)
: ADIOS2Writer(comm, filename, "VTX function writer", engine),
_mesh(impl_adios2::extract_common_mesh<T>(u)), _u(u)
_mesh(impl_adios2::extract_common_mesh<T>(u)),
_mesh_reuse_policy(mesh_policy), _u(u)
{
if (u.empty())
throw std::runtime_error("VTXWriter fem::Function list is empty.");
Expand Down Expand Up @@ -960,6 +975,27 @@ class VTXWriter : public ADIOS2Writer
impl_adios2::define_attribute<std::string>(*_io, "vtk.xml", vtk_scheme);
}

/// @brief Create a VTX writer for a list of fem::Functions using
/// the default ADIOS2 engine.
///
/// This format supports arbitrary degree meshes.
///
/// @param[in] comm The MPI communicator to open the file on
/// @param[in] filename Name of output file
/// @param[in] u List of functions. The functions must (1) share the
/// same mesh and (2) be (discontinuous) Lagrange functions. The
/// element family and degree must be the same for all functions.
/// @param[in] mesh_policy Controls if the mesh is written to file at
/// the first time step only or is re-written (updated) at each time
/// step.
/// @note This format supports arbitrary degree meshes.
VTXWriter(MPI_Comm comm, const std::filesystem::path& filename,
const typename adios2_writer::U<T>& u,
VTXMeshPolicy mesh_policy = VTXMeshPolicy::update)
: VTXWriter(comm, filename, u, "BPFile", mesh_policy)
{
}
massimiliano-leoni marked this conversation as resolved.
Show resolved Hide resolved

// Copy constructor
VTXWriter(const VTXWriter&) = delete;

Expand All @@ -975,14 +1011,15 @@ class VTXWriter : public ADIOS2Writer
// Copy assignment
VTXWriter& operator=(const VTXWriter&) = delete;

/// @brief Write data with a given time
/// @param[in] t The time step
/// @brief Write data with a given time stamp.
/// @param[in] t Time stamp to associate with output.
void write(double t)
{
assert(_io);
assert(_engine);
adios2::Variable var_step
= impl_adios2::define_variable<double>(*_io, "step");

assert(_engine);
_engine->BeginStep();
_engine->template Put<double>(var_step, t);

Expand All @@ -991,18 +1028,37 @@ class VTXWriter : public ADIOS2Writer
impl_vtx::vtx_write_mesh(*_io, *_engine, *_mesh);
else
{
// Write a single mesh for functions as they share finite element
std::visit(
[&](auto& u) {
impl_vtx::vtx_write_mesh_from_space(*_io, *_engine,
*u->function_space());
},
_u[0]);
if (_mesh_reuse_policy == VTXMeshPolicy::update
or !(_io->template InquireVariable<std::int64_t>("connectivity")))
{
// Write a single mesh for functions as they share finite
// element
std::tie(_x_id, _x_ghost) = std::visit(
[&](auto& u)
{
return impl_vtx::vtx_write_mesh_from_space(*_io, *_engine,
*u->function_space());
},
_u[0]);
}
else
{
// Node global ids
adios2::Variable orig_id = impl_adios2::define_variable<std::int64_t>(
*_io, "vtkOriginalPointIds", {}, {}, {_x_id.size()});
_engine->Put(orig_id, _x_id.data());
adios2::Variable ghost = impl_adios2::define_variable<std::uint8_t>(
*_io, "vtkGhostType", {}, {}, {_x_ghost.size()});
_engine->Put(ghost, _x_ghost.data());
_engine->PerformPuts();
}

// Write function data for each function to file
for (auto& v : _u)
{
std::visit(
[&](auto& u) { impl_vtx::vtx_write_data(*_io, *_engine, *u); }, v);
}
}

_engine->EndStep();
Expand All @@ -1011,6 +1067,12 @@ class VTXWriter : public ADIOS2Writer
private:
std::shared_ptr<const mesh::Mesh<T>> _mesh;
adios2_writer::U<T> _u;

// Control whether the mesh is written to file once or at every time
// step
VTXMeshPolicy _mesh_reuse_policy;
std::vector<std::int64_t> _x_id;
std::vector<std::uint8_t> _x_ghost;
};

/// Type deduction
Expand Down
2 changes: 1 addition & 1 deletion python/dolfinx/fem/petsc.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ def assemble_matrix_mat(A: PETSc.Mat, a: Form, bcs: typing.List[DirichletBC] = [
def assemble_matrix_nest(a: typing.List[typing.List[Form]],
bcs: typing.List[DirichletBC] = [], mat_types=[],
diagonal: float = 1.0, constants=None, coeffs=None) -> PETSc.Mat:
"""Create a nested matrix and assembled bilinear forms into the matrix.
"""Create a nested matrix and assemble bilinear forms into the matrix.

Args:
a: Rectangular (list-of-lists) array for bilinear forms.
Expand Down
5 changes: 3 additions & 2 deletions python/dolfinx/io/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@
if _cpp.common.has_adios2:
# FidesWriter and VTXWriter require ADIOS2
from dolfinx.io.utils import (FidesMeshPolicy, FidesWriter, # noqa: F401
VTXWriter)
__all__ = __all__ + ["FidesWriter", "VTXWriter", "FidesMeshPolicy"]
VTXMeshPolicy, VTXWriter)
__all__ = __all__ + ["FidesWriter", "VTXWriter", "FidesMeshPolicy",
"VTXMeshPolicy"]
15 changes: 11 additions & 4 deletions python/dolfinx/io/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ def _extract_cpp_functions(functions: typing.Union[typing.List[Function], Functi

# FidesWriter and VTXWriter require ADIOS2
if _cpp.common.has_adios2:
from dolfinx.cpp.io import FidesMeshPolicy # noqa F401
__all__ = __all__ + ["FidesWriter", "VTXWriter", "FidesMeshPolicy"]
from dolfinx.cpp.io import FidesMeshPolicy, VTXMeshPolicy # noqa F401
__all__ = __all__ + ["FidesWriter", "VTXWriter", "FidesMeshPolicy",
"VTXMeshPolicy"]

class VTXWriter:
"""Writer for VTX files, using ADIOS2 to create the files.
Expand All @@ -54,7 +55,8 @@ class VTXWriter:

def __init__(self, comm: _MPI.Comm, filename: typing.Union[str, Path],
output: typing.Union[Mesh, Function, typing.List[Function]],
engine: str = "BPFile"):
engine: str = "BPFile",
mesh_policy: VTXMeshPolicy = VTXMeshPolicy.update):
"""Initialize a writer for outputting data in the VTX format.

Args:
Expand All @@ -65,6 +67,11 @@ def __init__(self, comm: _MPI.Comm, filename: typing.Union[str, Path],
(discontinuous Lagrange Functions.
engine: ADIOS2 engine to use for output. See
ADIOS2 documentation for options.
mesh_policy: Controls if the mesh is written to file at
the first time step only when a ``Function`` is
written to file, or is re-written (updated) at each
time step. Has an effect only for ``Function``
output.

Note:
All Functions for output must share the same mesh and
Expand All @@ -90,7 +97,7 @@ def __init__(self, comm: _MPI.Comm, filename: typing.Union[str, Path],
except (NotImplementedError, TypeError, AttributeError):
# Input is a single function or a list of functions
self._cpp_object = _vtxwriter(comm, filename, _extract_cpp_functions(
output), engine) # type: ignore[arg-type]
output), engine, mesh_policy) # type: ignore[arg-type]

def __enter__(self):
return self
Expand Down
2 changes: 1 addition & 1 deletion python/dolfinx/la.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ def norm(self, type=_cpp.la.Norm.l2) -> np.floating:
"""Compute a norm of the vector.

Args:
type: Norm type to computed.
type: Norm type to compute.

Returns:
Computed norm.
Expand Down
11 changes: 8 additions & 3 deletions python/dolfinx/wrappers/io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,13 @@ void declare_vtx_writer(nb::module_& m, std::string type)
const dolfinx::fem::Function<std::complex<float>, T>>,
std::shared_ptr<const dolfinx::fem::Function<
std::complex<double>, T>>>>& u,
std::string engine) {
std::string engine, dolfinx::io::VTXMeshPolicy policy) {
new (self)
dolfinx::io::VTXWriter<T>(comm.get(), filename, u, engine);
dolfinx::io::VTXWriter<T>(comm.get(), filename, u, engine, policy);
},
nb::arg("comm"), nb::arg("filename"), nb::arg("u"),
nb::arg("engine"))
nb::arg("engine") = "BPFile",
nb::arg("policy") = dolfinx::io::VTXMeshPolicy::update)
.def("close", [](dolfinx::io::VTXWriter<T>& self) { self.close(); })
.def(
"write",
Expand Down Expand Up @@ -338,6 +339,10 @@ void io(nb::module_& m)
nb::enum_<dolfinx::io::FidesMeshPolicy>(m, "FidesMeshPolicy")
.value("update", dolfinx::io::FidesMeshPolicy::update)
.value("reuse", dolfinx::io::FidesMeshPolicy::reuse);

nb::enum_<dolfinx::io::VTXMeshPolicy>(m, "VTXMeshPolicy")
.value("update", dolfinx::io::VTXMeshPolicy::update)
.value("reuse", dolfinx::io::VTXMeshPolicy::reuse);
#endif

declare_vtx_writer<float>(m, "float32");
Expand Down
Loading