File: snapshot_checkpoint.py

package info (click to toggle)
adios4dolfinx 0.10.0.post0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 536 kB
  • sloc: python: 4,180; sh: 24; makefile: 7
file content (82 lines) | stat: -rw-r--r-- 2,727 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# # Snapshot checkpoint (non-persistent)
# The checkpoint method described in [Writing function checkpoints](./writing_functions_checkpoint)
# are *N-to-M*, meaning that you can write them out on N-processes and read them in on M processes.
#
# As discussed in that chapter, these checkpoints need to be associated with a mesh.
# This is because the function is defined on a specific function space, which in turn is
# defined on a specific mesh.
#
# However, there are certain scenarios where you simply want to store a checkpoint associated
# with the current mesh, that should only be possible to use during this simulation.
# An example use-case is when running an iterative solver, and wanting a fall-back mechanism that
# does not require extra RAM.

# In this example, we will demonstrate how to write a
# {py:func}`snapshot checkpoint<adios4dolfinx.snapshot_checkpoint>` to disk.

# First we define a {py:class}`function<dolfinx.fem.Function>` `f` that we want to represent in
# the {py:class}`function space<dolfinx.fem.FunctionSpace>`.

# +
import logging
from pathlib import Path

import ipyparallel as ipp


def f(x):
    import numpy as np

    return np.sin(x[0]) + 0.1 * x[1]


# -

# Next, we create a mesh and an appropriate function space and read and write from file.
# Note that for both these operations, we use {py:func}`adios4dolfinx.snapshot_checkpoint`,
# with different read and write modes.


def read_write_snapshot(filename: Path):
    from mpi4py import MPI

    import dolfinx
    import numpy as np

    import adios4dolfinx

    mesh = dolfinx.mesh.create_unit_cube(MPI.COMM_WORLD, 3, 7, 4)
    V = dolfinx.fem.functionspace(mesh, ("Lagrange", 5))
    u = dolfinx.fem.Function(V)
    u.interpolate(f)
    u.name = "Current_solution"
    # Next, we store the solution to file
    adios4dolfinx.snapshot_checkpoint(u, filename, adios4dolfinx.adios2_helpers.adios2.Mode.Write)

    # Next, we create a new function and load the solution into it
    u_new = dolfinx.fem.Function(V)
    u_new.name = "Read_solution"
    adios4dolfinx.snapshot_checkpoint(
        u_new, filename, adios4dolfinx.adios2_helpers.adios2.Mode.Read
    )

    # Next, we verify that the solution is correct
    np.testing.assert_allclose(u_new.x.array, u.x.array, atol=np.finfo(float).eps)

    print(f"{MPI.COMM_WORLD.rank + 1}/{MPI.COMM_WORLD.size}: Successfully wrote and read snapshot")


# +

mesh_file = Path("snapshot.bp")

with ipp.Cluster(engines="mpi", n=3, log_level=logging.ERROR) as cluster:
    cluster[:].push({"f": f})
    query = cluster[:].apply_async(
        read_write_snapshot,
        mesh_file,
    )
    query.wait()
    assert query.successful(), query.error
    print("".join(query.stdout))
# -