Running open-Qmin (Python interface)

Running open-Qmin (Python interface)

Using tools/runHelper.py, you can define command-line parameters through a Python dictionary runHelper.params. These, along with any default parameters you didn’t change, are converted by runHelper.get_runcmd() into a command-line string that calls build/openQmin.out.

The dictionary keys of runHelper.params are the same as the long forms (appearing after the --s) of the command-line flags seen when you run build/openQmin.out --help, with the following exceptions:

  • help itself is not a key in runHelper.params

  • Parameters 'whole_Lx', 'whole_Ly', and 'whole_Lz', which define the system size before subdivision over MPI ranks, override 'Lx', 'Ly', and 'Lz' by default. If you want to use 'Lx', 'Ly', 'Lz' instead (which give the system size on each rank), you can pass do_partition=False to runHelper.get_runcmd().

  • --boxL (or -l) for specifying cubic box size is not used here to avoid ambiguity.

In the example below, we’ll make use of an example boundaryFile that we created in the page on Boundary conditions (Python interface) and the example initialConfigurationFiles that we created in the page on Initialization (Python interface).

Notice that the main open-Qmin directory path, assigned to runHelper.directory, is automatically prepended to the filepaths for imported and exported data. This directory path should be either an absolute path or relative to where you’ll be running the command.

from sys import path
path.append("../tools/")  # <-- replace with your path to runHelper.py

import runHelper

runHelper.directory = "../" # path to open-Qmin main directory
runHelper.mpi_num_processes = 2  # set to 1 for non-MPI run

runHelper.params["boundaryFile"] = "ceiling_and_wavy_floor.txt"
runHelper.params["initialConfigurationFile"] = "my_init_file"

# choose a location and filename-prefix for this run's results
runHelper.params["saveFile"] = "data/my_example_run"
runHelper.params["iterations"] = 500  # max number of minimization timesteps

# system size BEFORE subdivision across MPI ranks:
runHelper.params["whole_Lx"] = 50
runHelper.params["whole_Ly"] = 50
runHelper.params["whole_Lz"] = 50

runcmd = runHelper.get_runcmd()  # generate command-line string
print(runcmd)
mpirun -n 2 ../build/openQmin.out --initializationSwitch 0 --GPU -1 --phaseConstantA -0.172 --phaseConstantB -2.12 --phaseConstantC 1.73 --deltaT 0.0005 --fTarget 1e-12 --iterations 500 --randomSeed -1 --L1 4.64 --L2 0.0 --L3 0.0 --L4 0.0 --L6 0.0 --Lx 25 --Ly 50 --Lz 50 --initialConfigurationFile ../my_init_file --boundaryFile ../ceiling_and_wavy_floor.txt --saveFile ../data/my_example_run --linearSpacedSaving -1 --logSpacedSaving -1 --stride 1 --hFieldX 0 --hFieldY 0 --hFieldZ 0 --hFieldMu0 1 --hFieldChi 1 --hFieldDeltaChi 0.5 --eFieldX 0 --eFieldY 0 --eFieldZ 0 --eFieldEpsilon0 1 --eFieldEpsilon 1 --eFieldDeltaEpsilon 0.5

We can run open-Qmin with these options by any of the following routes:

  • Call runHelper.run(), which executes the result of runHelper.get_runcmd()

  • Copy and paste the string into a terminal

  • Use the runcmd string in a Python script via import os; os.system(runcmd)

  • Run as shell command in a Jupyter notebook with !{runcmd}

runHelper.run()
lattice divisions: {2, 1, 1}
loading state...
loading state...
reading file with 2 objects
reading boundary type 0 with 5.300000 0.530000 and 26307 entries
reading file with 2 objects
reading boundary type 0 with 5.300000 0.530000 and 26307 entries
object with 26307 sites created
object with 26307 sites created
there are now 1 boundary objects known to the configuration... last object had 13154 sites and 3232 surface sites 
reading boundary type 1 with 5.300000 0.530000 and 2500 entries
there are now 1 boundary objects known to the configuration... last object had 13153 sites and 3230 surface sites 
reading boundary type 1 with 5.300000 0.530000 and 2500 entries
object with 2500 sites created
there are now 2 boundary objects known to the configuration... last object had 1250 sites and 1350 surface sites 
object with 2500 sites created
there are now 2 boundary objects known to the configuration... last object had 1250 sites and 1351 surface sites 
fire finished: step 500 max force:5.49e-05 	power: 0.942	 alpha 0.99	 dt 0.045125 	scaling 0.198 
fire finished: step 500 max force:5.49e-05 	power: 0.942	 alpha 0.99	 dt 0.045125 	scaling 0.198 
-10473.051366 1161.068999 138.666443 0.000000 0.000000
minimized to 5.49259e-05	 E=-0.190674	
-10473.177387 1161.444290 143.526968 0.000000 0.000000
minimized to 5.49259e-05	 E=-0.190674	

Let’s take a look at the result. Here we’re using openViewMin, a visualization environment under development for use with open-Qmin. This project is not yet publicly available, so if you want to help test it out, please contact Daniel Beller at d.a.beller [at] jhu.edu.

# NOTE: Running this cell requires using openViewMin's auto-generated Python environment "openViewMin-env" as the kernel for the Jupyter notebook.

path.append("../../openviewmin/") # <-- replace with your path to openViewMin

import openViewMin
import glob

# collect all files from this run
savedFiles = glob.glob("../data/my_example_run_*") 
# generate plot off-screen
nplot = openViewMin.NematicPlot(savedFiles, off_screen=True, window_size=(800, 800))
# rotate plane of director glyphs to y-normal
nplot.update_filter("director_plane", {"normal":[0,1,0]}, update_self_actor=True)
# reduce lighting intensity a bit
nplot.set_lights_intensity(0.6)
# display in notebook
nplot_p3js = nplot.to_pythreejs()
nplot.close()
['../data/my_example_run_x1y0z0.txt', '../data/my_example_run_x0y0z0.txt'] -> ../data/my_example_run.txt
display(nplot_p3js)