Пример #1
0
def set_periodic_checkpoint(sim, period, checkpoint_dir='./checkpoints'):
    """
    Set up periodic checkpoints of the simulation

    The checkpoints are saved in openPMD format, in the specified
    directory, with one subdirectory per process.
    The E and B fields and particle information of each processor is saved.

    NB: Checkpoints are registered in the list `checkpoints` of the Simulation
    object `sim`, and written at the end of the PIC loop (whereas regular
    diagnostics are written at the beginning of the PIC loop).

    Parameters
    ----------
    sim: a Simulation object
       The simulation that is to be saved in checkpoints

    period: integer
       The number of PIC iteration between each checkpoint.

    checkpoint_dir: string, optional
        The path to the directory in which the checkpoints are stored
        (When running a simulation with several MPI ranks, use the
        same path for all ranks.)
    """
    # Only processor 0 creates a directory where checkpoints will be stored
    # Make sure that all processors wait until this directory is created
    # (Use the global MPI communicator instead of the `BoundaryCommunicator`
    # so that this still works in the case `use_all_ranks=False`)
    if comm.rank == 0:
        if os.path.exists(checkpoint_dir) is False:
            os.mkdir(checkpoint_dir)
    comm.barrier()

    # Choose the name of the directory: one directory per processor
    write_dir = os.path.join(checkpoint_dir, 'proc%d/' % comm.rank)

    # Register a periodic FieldDiagnostic in the diagnostics of the simulation
    # This saves only the E and B field (and their PML components, if used)
    fieldtypes = ["E", "B"]
    if sim.use_pml:
        fieldtypes += ["Er_pml", "Et_pml", "Br_pml", "Bt_pml"]
    sim.checkpoints.append(
        FieldDiagnostic(period,
                        sim.fld,
                        fieldtypes=fieldtypes,
                        write_dir=write_dir))

    # Register a periodic ParticleDiagnostic, which contains all
    # the particles which are present in the simulation
    particle_dict = {}
    for i in range(len(sim.ptcl)):
        particle_dict['species %d' % i] = sim.ptcl[i]

    if len(particle_dict) > 0:
        sim.checkpoints.append(
            ParticleDiagnostic(period, particle_dict, write_dir=write_dir))
Пример #2
0
def set_periodic_checkpoint(sim, period):
    """
    Set up periodic checkpoints of the simulation

    The checkpoints are saved in openPMD format, in the directory
    `./checkpoints`, with one subdirectory per process.
    The E and B fields and particle information of each processor is saved.

    NB: Checkpoints are registered in the list `checkpoints` of the Simulation
    object `sim`, and written at the end of the PIC loop (whereas regular
    diagnostics are written at the beginning of the PIC loop).

    Parameters
    ----------
    sim: a Simulation object
       The simulation that is to be saved in checkpoints

    period: integer
       The number of PIC iteration between each checkpoint.
    """
    # Only processor 0 creates a directory where checkpoints will be stored
    # Make sure that all processors wait until this directory is created
    # (Use the global MPI communicator instead of the `BoundaryCommunicator`
    # so that this still works in the case `use_all_ranks=False`)
    if comm.rank == 0:
        if os.path.exists('./checkpoints') is False:
            os.mkdir('./checkpoints')
    comm.barrier()

    # Choose the name of the directory: one directory per processor
    write_dir = 'checkpoints/proc%d/' % comm.rank

    # Register a periodic FieldDiagnostic in the diagnostics of the simulation
    sim.checkpoints.append(
        FieldDiagnostic(period,
                        sim.fld,
                        fieldtypes=["E", "B"],
                        write_dir=write_dir))

    # Register a periodic ParticleDiagnostic, which contains all
    # the particles which are present in the simulation
    particle_dict = {}
    for i in range(len(sim.ptcl)):
        particle_dict['species %d' % i] = sim.ptcl[i]
    sim.checkpoints.append(
        ParticleDiagnostic(period, particle_dict, write_dir=write_dir))
Пример #3
0
def restart_from_checkpoint( sim, iteration=None ):
    """
    Fills the Simulation object `sim` with data saved in a checkpoint.

    More precisely, the following data from `sim` is overwritten:

    - Current time and iteration number of the simulation
    - Position of the boundaries of the simulation box
    - Values of the field arrays
    - Size and values of the particle arrays

    Any other information (e.g. diagnostics of the simulation, presence of a
    moving window, presence of a laser antenna, etc.) need to be set by hand.

    For this reason, a successful restart will often require to modify the
    original input script that produced the checkpoint, rather than to start
    a new input script from scratch.

    NB: This function should always be called *before* the initialization
    of the moving window, since the moving window infers the position of
    particle injection from the existing particle data.

    Parameters
    ----------
    sim: a Simulation object
       The Simulation object into which the checkpoint should be loaded

    iteration: integer (optional)
       The iteration number of the checkpoint from which to restart
       If None, the latest checkpoint available will be used.
    """
    # Import openPMD-viewer
    try:
        from opmd_viewer import OpenPMDTimeSeries
    except ImportError:
        raise ImportError(
        'The package `opmd_viewer` is required to restart from checkpoints.'
        '\nPlease install it from https://github.com/openPMD/openPMD-viewer')

    # Verify that the restart is valid (only for the first processor)
    # (Use the global MPI communicator instead of the `BoundaryCommunicator`,
    # so that this also works for `use_all_ranks=False`)
    if comm.rank == 0:
        check_restart( sim, iteration )
    comm.barrier()

    # Choose the name of the directory from which to restart:
    # one directory per processor
    checkpoint_dir = 'checkpoints/proc%d/hdf5' %comm.rank
    ts = OpenPMDTimeSeries( checkpoint_dir )
    # Select the iteration, and its index
    if iteration is None:
        iteration = ts.iterations[-1]
    # Find the index of the closest iteration
    i_iteration = np.argmin( abs(np.array(ts.iterations) - iteration) )

    # Modify parameters of the simulation
    sim.iteration = iteration
    sim.time = ts.t[ i_iteration ]

    # Export available species as a list
    avail_species = ts.avail_species
    if avail_species is None:
        avail_species = []

    # Load the particles
    # Loop through the different species
    if len(avail_species) == len(sim.ptcl):
        for i in range(len(sim.ptcl)):
            name = 'species %d' %i
            load_species( sim.ptcl[i], name, ts, iteration, sim.comm )
    else:
        raise RuntimeError( \
"""Species numbers in checkpoint and simulation should be same, but
got {:d} and {:d}. Use add_new_species method to add species to
simulation or sim.ptcl = [] to remove them""".format(len(avail_species),
                                                     len(sim.ptcl)) )
    # Record position of grid before restart
    zmin_old = sim.fld.interp[0].zmin

    # Load the fields
    # Loop through the different modes
    for m in range( sim.fld.Nm ):
        # Load the fields E and B
        for fieldtype in ['E', 'B']:
            for coord in ['r', 't', 'z']:
                load_fields( sim.fld.interp[m], fieldtype,
                             coord, ts, iteration )
    # Record position after restart (`zmin` is modified by `load_fields`)
    # and shift the global domain position in the BoundaryCommunicator
    zmin_new = sim.fld.interp[0].zmin
    sim.comm.shift_global_domain_positions( zmin_new - zmin_old )