An Initial Custom Action

Overview

Questions

  • How do I write a custom action in Python?

  • How do I wrap a custom action object?

  • How do I use a custom action in a simulation?

Objectives

  • Explain the steps in writing a custom action.

  • Demonstrate using a custom action in a simulation.

Writing a Custom Action

First, import hoomd.

[1]:
import hoomd

We create a single particle snapshot for initializing a simulation’s state further down.

[2]:
snap = hoomd.Snapshot()
snap.particles.N = 1
snap.particles.position[:] = [0, 0, 0]
snap.particles.types = ['A']
snap.particles.typeid[:] = [0]
snap.configuration.box = [10, 10, 10, 0, 0, 0]

Create a custom action as a subclass of hoomd.custom.Action. Here we will create an action that prints the timestep to standard out.

[3]:
class PrintTimestep(hoomd.custom.Action):

    def act(self, timestep):
        print(timestep)

We now have an action that can print out the simulation timestep. The logic of the action goes inside the act method. All actions must define this function, and it must take in the simulation timestep; this is passed in when the action is called in the HOOMD-blue run loop. (If you are wondering how to access simulation data, there is a mechanism for that which we will go over in the next section).

Let’s go ahead and create a PrintTimestep object.

[4]:
custom_action = PrintTimestep()

Wrapping Custom Actions

To let an Operations object know what kind of action our custom action is, we must wrap it in a subclass of hoomd.custom.CustomOperation. We have three options as discussed in the previous section: an updater, writer, or tuner. Since our object does not modify simulation state or an object’s hyperparameters, but writes the timestep to standard out, our action is a writer. hoomd.write.CustomWriter then is the correct class to wrap our custom action (hoomd.update.CustomUpdater and hoomd.tune.CustomTuner are for updaters and tuners respectively).

Create a CustomWriter operation that will call the custom action when triggered:

[5]:
custom_op = hoomd.write.CustomWriter(action=custom_action,
                                     trigger=hoomd.trigger.Periodic(100))

Notice that custom operations take triggers like other operations.

Using Custom Actions

To use a custom opeation we must add it to a hoomd.Operations object. Thus, the steps to use a custom action in a simuluation are 1. Instantiate the custom action object. 2. Wrap the custom action in the appropriate custom operation class. 3. Add the custom operation object to the appropriate container in a hoomd.Operations object.

[6]:
cpu = hoomd.device.CPU()
sim = hoomd.Simulation(device=cpu)

Initialize the state

[7]:
sim.create_state_from_snapshot(snap)

Add the custom action wrapped by a CustomWriter:

[8]:
sim.operations.writers.append(custom_op)

We can now run our simulation to see our custom action in work!

[9]:
sim.run(1000)
100
200
300
400
500
600
700
800
900
1000

In the next section we discuss some of the features of custom actions, before getting into non-trival examples in later sections.