Script Editor

Table of Contents

Script Editor

The Script Editor tool is used to add customization to scripts that cannot be achieved with the NanoLanguage scripter. For instance, you might want to

  • change the labeling of the physical properties.

  • print out physical properties with better formatting or precision than provided by the NanoLanguage function nlPrint().

  • loop over a range for one of the DFT parameters, e.g. the mesh cut-off, to make sure your calculation has converged with respect to this parameter.

  • loop over a geometry parameter to create a potential energy scan.

The Script Editor is launched by drag-and-dropping a script (full NanoLanguage scripts, configurations, or method scripts stored in the form of a NanoLanguage script) from your file browser onto the Script Editor icon in the toolbar. This launches an editor application.

[Important] Important

Be aware that editing any script created by the builders or the NanoLanguage scripter can corrupt the script and make the tools behave in an unpredictable way when you try to read them by drag-and-dropping them on other tools.

In short, we cannot guarantee that an edited script will be compatible with any of the VNL tools.

[Note] Note

If you want to edit a configuration hand built with the Molecular Builder tool, a convenient short-cut rather than creating the configuration on disk could be to use drag-and-drop between tools; i.e. build the molecule in the Molecular Builder, drag-and-drop from the Molecular Builder drag-and-drop box onto the Script Editor icon, edit your configuration, and save the new configuration.

Examples

In this section, we will give a few illustrative, yet simple, examples of how you can edit a script to get the most out of NanoLanguage. It is assumed that you are familiar with basic NanoLanguage and have accomplished the first mini-tutorial in the Getting started — a small tutorial chapter.

Loop over mesh cut-offs

In this example, we will

  • Change the label of one of the calculated properties.

  • Create a loop over several mesh cut-offs to see when the calculation converges with respect to this parameter.

The first steps in this example follow the mini-tutorial closely, but here we use a water molecule instead of a hydrogen molecule.

  1. Build a water molecule with the Molecular Builder.

  2. Drag-and-drop the configuration from the Molecular Builder to the NanoLanguage scripter.

  3. Specify a name for the VNL file under the Analysis tab, e.g. water.vnl.

  4. Specify that you want to calculate the Total energy under the Analysis tab.

  5. Left-click Save to save the script.

  6. Drag-and-drop the script icon from your file browser onto the script editor icon on the Toolbar.

You should now have a script that looks like this

from ATK.KohnSham import *
from ATK.MPI import processIsMaster

# Generate time stamp
if processIsMaster():
    import os, sys, time
    if os.name == 'nt':
        os_info =  ['Windows']+list(sys.getwindowsversion())
    else:
        os_info =  os.uname()
    print '#',time.ctime()
    print '#',reduce(lambda x,y: x+' '+y, os_info, '') + '\n'

# Opening vnlfile
if processIsMaster(): file = VNLFile('water.vnl')

# Define elements
elements = [Oxygen,   Hydrogen, Hydrogen]

# Define coordinates
coordinates = [[  5.55111512e-17,   5.31783268e-06,   6.67710550e-02],
               [  5.55111512e-17,  -7.63505696e-01,  -5.29907692e-01],
               [  5.55111512e-17,   7.63421284e-01,  -5.29973667e-01]]*Angstrom

# Set up configuration
molecule_configuration = MoleculeConfiguration(elements,coordinates)
if processIsMaster(): nlPrint(molecule_configuration)
if processIsMaster(): file.addToSample(molecule_configuration, 'molecule_configuration')

######################################################################
# Parameters
######################################################################
exchange_correlation_type = LDA.PZ

iteration_mixing_parameters = iterationMixingParameters(
    algorithm = IterationMixing.Pulay,
    diagonal_mixing_parameter = 0.1,
    quantity = IterationMixing.Hamiltonian,
    history_steps = 6
)

eigenstate_occupation_parameters = eigenstateOccupationParameters(
    temperature = 300.0*Kelvin
)

electron_density_parameters = electronDensityParameters(
    mesh_cutoff = 150.0*Rydberg
)

basis_set_parameters = basisSetParameters(
    type = DoubleZetaPolarized,
    radial_sampling_dr = 0.001*Bohr,
    energy_shift = 0.01*Rydberg,
    delta_rinn = 0.8,
    v0 = 40.0*Rydberg,
    charge = 0.0,
    split_norm = 0.15
)

poisson_equation_parameters = poissonEquationParameters(padding_factor = 0.1)

iteration_control_parameters = iterationControlParameters(
    tolerance = 1e-05,
    criterion = IterationControl.TotalEnergy,
    max_steps = 100
)

two_center_integral_parameters = twoCenterIntegralParameters(
    cutoff = 2500.0*Rydberg,
    points = 1024
)

######################################################################
# Initialize self-consistent field calculation
######################################################################
kohnsham_method = KohnShamMethod(
    exchange_correlation_type = exchange_correlation_type,
    iteration_mixing_parameters = iteration_mixing_parameters,
    eigenstate_occupation_parameters = eigenstate_occupation_parameters,
    electron_density_parameters = electron_density_parameters,
    basis_set_parameters = basis_set_parameters,
    iteration_control_parameters = iteration_control_parameters,
    two_center_integral_parameters = two_center_integral_parameters,
    poisson_equation_parameters = poisson_equation_parameters
)
if processIsMaster(): nlPrint(kohnsham_method)

runtime_parameters = runtimeParameters(
    verbosity_level = 10,
    checkpoint_filename = None
)

# Perform self-consistent field calculation
scf = executeSelfConsistentCalculation(
    molecule_configuration,
    kohnsham_method,
    runtime_parameters = runtime_parameters
)

######################################################################
# Calculate physical properties
######################################################################
# Set verbosity level so that all energy components are printed
import ATK
verbosity_level=ATK.verbosityLevel()
ATK.setVerbosityLevel(10)
total_energy = calculateTotalEnergy(self_consistent_calculation = scf)
ATK.setVerbosityLevel(verbosity_level)

if processIsMaster(): nlPrint(total_energy,'Total energy')
if processIsMaster(): file.addToSample(total_energy, 'molecule_configuration', 'Total energy')

Use the Script Editor and add the following changes

  1. Add the line

    for cutoff in range(50,251,25)

    before the line starting with exchange_correlation_type=.

    This will create a loop that sets the variable cutoff from 50 to 250 in steps of 25.

  2. Indent every line after that line with for four space characters.

  3. Change the numerical value of the variable mesh_cutoff (150.0*Rydberg) to the variable defined in step 1.

  4. Add the line

    label="Total Energy (mesh_cutoff=%d)"%cutoff

    before the last line.

    This creates a unique label for the calculation of each value of mesh_cutoff, e.g. Total Energy (mesh_cutoff=50).

  5. Change 'Total energy' to label on the last line.

    This will output the value of the variable label defined in step 4, e.g.

    Total Energy (mesh_cutoff=50)

After the changes, your script should look something like this

from ATK.KohnSham import *
from ATK.MPI import processIsMaster

# Generate time stamp
if processIsMaster():
    import os, sys, time
    if os.name == 'nt':
        os_info =  ['Windows']+list(sys.getwindowsversion())
    else:
        os_info =  os.uname()
    print '#',time.ctime()
    print '#',reduce(lambda x,y: x+' '+y, os_info, '') + '\n'

# Opening vnlfile
if processIsMaster(): file = VNLFile('water.vnl')

# Define elements
elements = [Oxygen,   Hydrogen, Hydrogen]

# Define coordinates
coordinates = [[  5.55111512e-17,   5.31783268e-06,   6.67710550e-02],
               [  5.55111512e-17,  -7.63505696e-01,  -5.29907692e-01],
               [  5.55111512e-17,   7.63421284e-01,  -5.29973667e-01]]*Angstrom

# Set up configuration
molecule_configuration = MoleculeConfiguration(elements,coordinates)
if processIsMaster(): nlPrint(molecule_configuration)
if processIsMaster(): file.addToSample(molecule_configuration, 'molecule_configuration')

######################################################################
# Parameters
######################################################################
for cutoff in range(50,251,25):
    exchange_correlation_type = LDA.PZ
    
    iteration_mixing_parameters = iterationMixingParameters(
        algorithm = IterationMixing.Pulay,
        diagonal_mixing_parameter = 0.1,
        quantity = IterationMixing.Hamiltonian,
        history_steps = 6
    )
    
    eigenstate_occupation_parameters = eigenstateOccupationParameters(
        temperature = 300.0*Kelvin
    )
    
    electron_density_parameters = electronDensityParameters(
        mesh_cutoff = cutoff*Rydberg
    )
    
    basis_set_parameters = basisSetParameters(
        type = DoubleZetaPolarized,
        radial_sampling_dr = 0.001*Bohr,
        energy_shift = 0.01*Rydberg,
        delta_rinn = 0.8,
        v0 = 40.0*Rydberg,
        charge = 0.0,
        split_norm = 0.15
    )
    
    poisson_equation_parameters = poissonEquationParameters(padding_factor = 0.1)
    
    iteration_control_parameters = iterationControlParameters(
        tolerance = 1e-05,
        criterion = IterationControl.TotalEnergy,
        max_steps = 100
    )
    
    two_center_integral_parameters = twoCenterIntegralParameters(
        cutoff = 2500.0*Rydberg,
        points = 1024
    )
    
    ######################################################################
    # Initialize self-consistent field calculation
    ######################################################################
    kohnsham_method = KohnShamMethod(
        exchange_correlation_type = exchange_correlation_type,
        iteration_mixing_parameters = iteration_mixing_parameters,
        eigenstate_occupation_parameters = eigenstate_occupation_parameters,
        electron_density_parameters = electron_density_parameters,
        basis_set_parameters = basis_set_parameters,
        iteration_control_parameters = iteration_control_parameters,
        two_center_integral_parameters = two_center_integral_parameters,
        poisson_equation_parameters = poisson_equation_parameters
    )
    if processIsMaster(): nlPrint(kohnsham_method)
    
    runtime_parameters = runtimeParameters(
        verbosity_level = 10,
        checkpoint_filename = None
    )
    
    # Perform self-consistent field calculation
    scf = executeSelfConsistentCalculation(
        molecule_configuration,
        kohnsham_method,
        runtime_parameters = runtime_parameters
    )
    
    ######################################################################
    # Calculate physical properties
    ######################################################################
    # Set verbosity level so that all energy components are printed
    import ATK
    verbosity_level=ATK.verbosityLevel()
    ATK.setVerbosityLevel(10)
    total_energy = calculateTotalEnergy(self_consistent_calculation = scf)
    ATK.setVerbosityLevel(verbosity_level)
    
    if processIsMaster(): nlPrint(total_energy,'Total energy')
    label="Total Energy (mesh_cutoff=%d)"%cutoff
    if processIsMaster(): file.addToSample(total_energy, 'molecule_configuration', label)

If you run the script and plot the calculated energies as a function of the mesh cut-off, you will a plot similar to

Since the water molecule is a comparatively simple system, its total energy converges nicely already with a moderate mesh cut-off. In this case, 100 Ry seems to be sufficient. This is not necessarily true for other systems or physical properties. Therefore, we strongly suggest that you also perform convergence studies both for the system itself as well as the physical properties you are interested in.

[Note] Note

In most cases, it is less relevant how the absolute energy depends on a calculation parameter, such as the mesh cut-off. For the total energy, you usually want to see how an energy difference converges with the parameter.