# 1.5 signac-flow Ideal Gas Example

This notebook contains a minimal example for running a signac-flow project from scratch. The example demonstrates how to compare an ideal gas with a Lennard-Jones fluid by calculating a p-V phase diagram.

## Before you start

Make sure you installed signac and signac-flow, e.g., with:

conda install -c conda-forge signac signac-flow

[1]:

import flow
import numpy as np
import signac

# Enter the signac project directory
project = signac.init_project("projects/tutorial-signac-flow")


We want to generate a pressure-volume (p-V) phase diagram for an ideal gas.

We define a function to calculate the result for a given state point:

[2]:

def V_idg(N, p, kT):
return N * kT / p


For this demonstration we will specialize a flow.FlowProject to manage our simple workflow.

The workflow will contain one label and one operation. - The label function allows us to label our jobs in the project status. This is especially important for understanding the state of large projects with expensive operations. - The operation function compute_volume is defined with a postcondition and will act on each job. This operation is eligible for execution if its postcondition is unmet (False).

[3]:

class MyProject(flow.FlowProject):
pass

@MyProject.label
def estimated(job):
return "V" in job.document

@MyProject.post(estimated)
@MyProject.operation
def compute_volume(job):
job.document["V"] = V_idg(**job.statepoint())


We need to use the get_project() class method to get a project handle for this special project class.

[4]:

project = MyProject.get_project("projects/tutorial-signac-flow")


Now it’s time to actually generate some data! Let’s initialize the data space!

[5]:

for p in np.linspace(0.5, 5.0, 10):
sp = dict(N=1728, kT=1.0, p=float(p))
job = project.open_job(sp)
print(job.id)
job.init()

a14ee3104f26974b22bb84f62500c84d
55d4d6ebbc04a1f8a259a2c5de197328
4b299db86ff480f92e520eac91112108
26e2f19b5b211edb80ebe60a5a62bd75
75c10d0fa7a4f4b4742ce5e9c119e8bd
46859989efcfd89653fa65db2375884b
f3f3c351f81acd2140edd239b9183af4
b38e30524c2c36e3ebfe50481eb91992
bb277ac022ce744d38f9e87c1fabe08c
6f9bc79d670e42d4a40041ce7be9cdaf


The print_status() function allows to get a quick overview of our project’s status:

[6]:

project.print_status(detailed=True)


Overview: 10 jobs/aggregates, 10 jobs/aggregates with eligible operations.

label
-------

operation/group      number of eligible jobs  submission status
-----------------  -------------------------  -------------------
compute_volume                            10  [U]: 10

Detailed View:

job id                            operation/group     labels
--------------------------------  ------------------  --------
26e2f19b5b211edb80ebe60a5a62bd75  compute_volume [U]
46859989efcfd89653fa65db2375884b  compute_volume [U]
4b299db86ff480f92e520eac91112108  compute_volume [U]
55d4d6ebbc04a1f8a259a2c5de197328  compute_volume [U]
6f9bc79d670e42d4a40041ce7be9cdaf  compute_volume [U]
75c10d0fa7a4f4b4742ce5e9c119e8bd  compute_volume [U]
a14ee3104f26974b22bb84f62500c84d  compute_volume [U]
b38e30524c2c36e3ebfe50481eb91992  compute_volume [U]
bb277ac022ce744d38f9e87c1fabe08c  compute_volume [U]
f3f3c351f81acd2140edd239b9183af4  compute_volume [U]

[U]:unknown [R]:registered [I]:inactive [S]:submitted [H]:held [Q]:queued [A]:active [E]:error [GR]:group_registered [GI]:group_inactive [GS]:group_submitted [GH]:group_held [GQ]:group_queued [GA]:group_active [GE]:group_error



The next cell will attempt to execute all operations by cycling through jobs and operations until no next operations are defined anymore.

We limit the max. number of cycles to prevent accidental infinite loops, the number of cycles is arbitrary.

[7]:

project.run(num_passes=3)


Let’s double check the project status.

[8]:

project.print_status(detailed=True)


Overview: 10 jobs/aggregates, 0 jobs/aggregates with eligible operations.

label      ratio
---------  ----------------------------------------------------------
estimated  |████████████████████████████████████████| 10/10 (100.00%)

operation/group
-----------------

Detailed View:

job id                            operation/group    labels
--------------------------------  -----------------  ---------
26e2f19b5b211edb80ebe60a5a62bd75  [ ]                estimated
46859989efcfd89653fa65db2375884b  [ ]                estimated
4b299db86ff480f92e520eac91112108  [ ]                estimated
55d4d6ebbc04a1f8a259a2c5de197328  [ ]                estimated
6f9bc79d670e42d4a40041ce7be9cdaf  [ ]                estimated
75c10d0fa7a4f4b4742ce5e9c119e8bd  [ ]                estimated
a14ee3104f26974b22bb84f62500c84d  [ ]                estimated
b38e30524c2c36e3ebfe50481eb91992  [ ]                estimated
bb277ac022ce744d38f9e87c1fabe08c  [ ]                estimated
f3f3c351f81acd2140edd239b9183af4  [ ]                estimated

[U]:unknown [R]:registered [I]:inactive [S]:submitted [H]:held [Q]:queued [A]:active [E]:error [GR]:group_registered [GI]:group_inactive [GS]:group_submitted [GH]:group_held [GQ]:group_queued [GA]:group_active [GE]:group_error



After running all operations we can make a brief examination of the collected data.

[9]:

for job in project:
print(job.statepoint()["p"], job.document.get("V"))

3.0 576.0
1.5 1152.0
4.5 384.0
2.5 691.2
3.5 493.7142857142857
2.0 864.0
5.0 345.6
0.5 3456.0
4.0 432.0
1.0 1728.0


For a better presentation of the results we need to aggregate all results and sort them by pressure.

[10]:

%matplotlib inline

from matplotlib import pyplot as plt

V = {}

for job in project:
V[job.statepoint()["p"]] = job.document["V"]

p = sorted(V.keys())
V = [V[p_] for p_ in p]
print(V)

plt.plot(p, V, label="idG")
plt.xlabel(r"pressure [$\epsilon / \sigma^3$]")
plt.ylabel(r"volume [$\sigma^3$]")
plt.legend()
plt.show()

[3456.0, 1728.0, 1152.0, 864.0, 691.2, 576.0, 493.7142857142857, 432.0, 384.0, 345.6]


Uncomment and execute the following line to remove all data and start over.

[11]:

# %rm -r projects/tutorial-signac-flow/workspace