Introduction¶
Montemodes is a software to calculate Monte Carlo simulations using the Metropolis algorithm. This software connects with Gaussian or Tinker to calculate the energy at each step.
How to install¶
Download the code and use :file: setup.py to install the code using :program: setuptools python module. A simple setup could be
$ setup.py install --user
the code will be installed as a python module. To check that it is properly installed you can run the :program: `python interpret and execute
import montemodes
if the module should be loaded without warnings and errors
Structure object¶
- $ Structure(coordinates=None,
- internal=None, z_matrix=None, int_label=None, atom_types=None, atomic_elements=None, atomic_numbers=None, connectivity=None, file_name=None, charge=0, multiplicity=1, int_weights=None):
Methods¶
- def get_coordinates():
- return self._coordinates.copy()
- def set_coordinates(self, coordinates):
- self._coordinates = coordinates self._number_of_atoms = None self._energy = None
- def get_internal():
- return self._internal.copy()
- def set_internal(internal):
- self._internal = internal
- def get_full_z_matrix():
- return self._full_z_matrix
- def get_z_matrix():
- return self._z_matrix
- def set_z_matrix(z_matrix):
- self._z_matrix = z_matrix
- def get_int_label():
- return self._int_label
- def set_int_label(int_label):
- self._int_label = int_label
- def get_int_dict():
self._internal_dict = {} for i, label in enumerate(self.get_int_label()[:,0]):
self._internal_dict.update({label:self.get_internal()[i, 0]})return self._internal_dict
- def get_int_weights():
- return self._int_weights
- def set_int_weights(int_weights):
- self._int_weights = int_weights
- def get_atomic_elements_with_dummy():
- return self._atomic_elements
- def get_atom_types():
- return self._atom_types
- def set_atom_types(atom_types):
- self._atom_types = atom_types
- def get_atomic_numbers():
- return self._atomic_numbers
def set_atomic_numbers(atomic_numbers):
- def get_atomic_elements(self):
- return np.array([i for i in self._atomic_elements if i != “X”], dtype=str)
def set_atomic_elements(atomic_elements):
- def get_connectivity():
- return self._connectivity
def set_connectivity(connectivity):
- def get_number_of_atoms():
- return self._number_of_atoms
- def get_number_of_internal():
- return self._number_of_internal
- def get_energy(method=None):
- return self._energy
- def get_modes(method=None):
- return self._modes
- def get_atomic_masses(self):
- return self._atomic_masses
Properties¶
@property def charge(self):
return self._charge@property def multiplicity(self):
return self._multiplicity
example¶
initial_coordinates = [[ 0.5784585, 0.7670811, 1.3587379],
[-1.7015514, -0.0389921, -0.0374715],
[ 0.5784290, -1.6512236, -0.0374715],
[ 0.5784585, 0.7670811, -1.4336809],
[ 0.0000000, 0.0000000, 0.0000000]]
initial_coordinates = np.array(initial_coordinates)
atomic_elements = ['O', 'O', 'O', 'O', 'P']
atomic_elements = np.array(atomic_elements)[None].T
molecule = Structure(coordinates=initial_coordinates,
atomic_elements=atomic_elements)
molecule.charge = 0
molecule.multiplicity = 1
MonteCarlo simulation¶
Prepare the simulation¶
Calculation method¶
The calculation method define the software to use to calculate the atomic interactions.
Two software are implemented: Gaussian09 and Tinker. To use these calculators, Gaussian and/or Tinker
should be installed in your system and the binaries (or hard links to them) should be placed in a
directory included in the $PATH environment variable with the name g09 and tinker,
respectively. Note that setting up an alias in .profile
or .bashrc
for these software will
not work.
Gaussian 09
from montecarlo.functions.method import gaussian
calculator = gaussian(methodology='pm6' [String],
internal=False [Boolean],
processors=None [Integer])
- methodology: Method label to use in Gaussian09. This argument should contain the basis set if it is necessary (Ex: B3LYP/6-31G).
- Internal: Use internal coordinates (z-matrix).
- Set number of processors to use in the :program:Gaussian09` calculation.
Tinker
from montecarlo.functions.method import tinker
calculator = tinker(parameter_set='mm3.prm' [String]):
- parameter_set: name of the force field file to use. This file should be placed in the work directory or full path should be specified
Conditions¶
Conditions object contains the parameters of the Monte Carlo simulation
from montecarlo.classes.results import Conditions
conditions = Conditions(temperature=None [Float],
number_of_cycles=100000 [Integer],
kb=0.0019872041, # kcal/mol
initial_expansion_factor=0.05 [Float],
acceptation_regulator=1.0 [Float],
number_of_values_for_average=2000 [Integer],
energy_method=calculator [Method object])
- temperature: Temperature at which the MonteCarlo simulation is calcuculated.
- number_of_cycles: Number of simulation steps
- energy_method: Calculation method object
- initial_expansion_factor: Initial factor of acceptance
- acceptation_regulator: Ratio of alteration of the factor of acceptance as a function of acceptance.
- number_of_values_for_average: Number of last simulation steps used to calculate the averaged properties.
- kb: Boltzmann constant according to the units of energy and temperature
Run the simulation¶
Montecarlo object contains all the information concerting to the simulation. This object is generated from a structure object tha contains the initial structure
from montecarlo.classes.results import MonteCarlo
simulation = MonteCarlo(structure)
To Run the simulation the calculate_MonteCarlo() is used. This function returns a MonteCarlo object that contains the results
from montecarlo.functions.montecarlo import calculate_MonteCarlo
simulation = calculate_MonteCarlo(simulation [Montecarlo type],
conditions [Conditions type],
show_text=True [Boolean],
alteration_type='cartesian' [String])
Return result [Montecarlo type]
- simulation: Initial Montecarlo object. If this object already contains information of a previous simulation, the simulation will continue adding the data of the new simulation.
- conditions: Conditions object.
- show_text: If True writes montecarlo information on screen during the simulation calculation. If False the calculation is carried out silently.
- alteration_type: Defines the way the structures are altered during each simulation step. The possible options are ‘cartesian’ ‘internal’ or ‘modes’.
The returned Montecarlo object can be used again in the calculate_MonteCarlo() function to continue the simulation.
Save results to data files¶
To save the MonteCarlo data into files some helper functions are available in
montemodes.functions.reading
Save the energy, acceptation of each simulation
write_result_to_file(result, 'test.out')
Save the trajectory into a file in xyz format
write_result_trajectory(result.trajectory, 'trajectory.xyz')
Save the full simulation objects into a file
save_to_dump(conditions, result, filename='full.obj')
Load the simulation objects from a file
load_from_dump(filename='full.obj')
Example¶
import montemodes.functions.reading as io_monte
import montemodes.functions.montecarlo as monte
import montemodes.functions.methods as method
import montemodes.classes.results as res
gaussian_calc = method.gaussian(methodology='pm6',
internal=False)
conditions = res.Conditions(temperature=500,
number_of_cycles=1000,
initial_expansion_factor=0.05,
acceptation_regulator=0.1,
number_of_values_for_average=20,
energy_method=gaussian_calc)
initial_structure = io_monte.reading_from_xyz_file('molecule.xyz')
initial_structure.charge = 0
initial_structure.multiplicity = 1
simulation = res.MonteCarlo(initial_structure)
result = monte.calculate_MonteCarlo(simulation,
conditions,
show_text=True,
alteration_type='cartesian')
io_monte.write_result_to_file(result, 'montecarlo.out')
io_monte.write_result_trajectory(result.trajectory, 'trajectory.xyz')
Symmetry and shape analysis¶
The symetry and shape analysis is calculated using the external software :program: shape, :program: symop,
and :program: symgroup. To use the interfaces to the binaries have to be placed in a directory included in the
$PATH environment variable with the name shape, symop, and symgroup, respectively.
Note that setting up an alias in .profile
or bashrc
for these software will not work.
Shape¶
To use shape interface, shape module has to be loaded by
$ module load montemodes.functions.shape as shape
The use of shape module is divided in two parts: First a shape input object is created. This shape object defines the kind of shape calculation to perform
$ input_shape = shape.Shape(code=1,
central_atom=0,
custom_atom_list=None)
- code: corresponds to the shape code available in shape manual. It depends on the number of vertices.
- central_atom: defines the atom number that will be used as central atom. Atom number uses the same rule as shape where the first atom is atom number 1. If central_atom is 0 no central atom will be defined.
- custom_atom_list: defines a list of atoms of the structure that will be used in the shape calculation. If this value is None all atoms are used.
methods¶
get_shape(structure [type Structure], input_shape [type Shape]):
Return: Float
Get the shape measure of a structure
get_shape_trajectory(trajectory [list of Structure objects], input_shape [type Shape]):
Return: List of Float
Get the shape of a list of structures
- get_info(vertices=None):
- Return: Null
Get information about available shapes. (equivalent to shape +).
example¶
$ import montemodes.functions.reading as io_monte
$ import montemodes.functions.shape as shape
$ structure = io_monte.reading_from_xyz_file('ch4.xyz')
$ input_shape = shape.Shape(code=2,
central_atom=1,
custom_atom_list=None)
$ measure = get_shape(structure, input_shape)
$ print ('The T-4 shape measure of CH4 is {}'.format(measure))
Symop¶
To use symop interface, symop module has to be loaded by
$ module load montemodes.functions.symop as symop
Likewise shape module, symop module is divided in two parts: First a symop input object is created. This symop object defines the kind of symmetry calculation to perform
$ input_symop = symop.Symop(symmetry='c 3',
label=False,
connect=False,
central_atom=0,
custom_atom_list=None)
- symmetry: corresponds to the symmetry operation to be measured.
- label : if True adds %label keyword to symop input (check symop manual for further information).
- connect : if True adds %connect keyword to symop input (check symop manual for further information).
- central_atom: defines the atom number that will be used as central atom. Atom number uses the same rule as symop where the first atom is atom number 1. If central_atom is 0 no central atom will be defined.
- custom_atom_list: defines a list of atoms of the structure that will be used in the shape calculation. If this value is None all atoms are used.
methods¶
get_symmetry(structure [type Structure], symop_input [type symop]):
Return: Float
Get the symmetry measure of a structure.
get_symmetry_trajectory(trajectory [type Structure], symop_input [type symop]):
Return: List of Float
Get the symmetry measure of a list of Structure type objects.
example¶
$ import montemodes.functions.reading as io_monte
$ import montemodes.functions.symop as symop
$ structure = io_monte.reading_from_xyz_file('ch4.xyz')
$ input_symop = symop.Symop(symmetry='c 3',
label=False,
connect=False,
central_atom=0,
custom_atom_list=[1,2,3,4])
$ measure = get_symmetry(structure, input_symop)
$ print ('The C3 symmetry measure of CH4 is {}'.format(measure))
Distortion index¶
Functions¶
The calculation of the distortion index as defined in the article: Baur WH. Acta Crystallogr Sect B Struct Crystallogr Cryst Chem. 1974;30(5):1195–215. is implemented in the functions
import montecarlo.analysis.distorsion as distorsion
distorsion.get_distortion_indices_angles(structure [Structure], 'A', 'B', 'C')
Return distortion_index [Float]
distorsion.get_distortion_indices_distances(structure [Structure] , 'A', 'B')
Return distortion_index [Float]
where structure is a Structure type object and ‘A’, ‘B’, and ‘C’ are the chemical symbol of the elements to analyze.
These functions can be called from a list of Structure type objects to return a dictionary with statistic data
dist_OPO = distorsion.get_distortion_statistic_analysis(structures [List of Structure],
distorsion.get_distortion_indices_angles [Distorsion function],
['A', 'B', 'C'],
show_plots=False)
return {'average': average [Float],
'deviation': deviation [Float]}
dist_OP = distorsion.get_distortion_statistic_analysis(structures [List of Structure],
distorsion.get_distortion_indices_distances [Distorsion function],
['A', 'B'],
show_plots=False)
return {'average': average [Float],
'deviation': deviation [Float]}
Example¶
import montemodes.functions.reading as io_monte
molecule1 = io_monte.reading_from_xyz_file('PO4_1.xyz')
molecule2 = io_monte.reading_from_xyz_file('PO4_2.xyz')
molecule3 = io_monte.reading_from_xyz_file('PO4_3.xyz')
import montemodes.analysis.distortion as distortion
di_OPO = distorsion.get_distortion_indices_angles(molecule1, 'P', 'O', 'P')
di_OP = distorsion.get_distortion_indices_distances(molecule2, 'P', 'O')
print 'results: {} {}'.format(di_OPO, di_OP)
####
structures = [molecule1, molecule2, molecule3]
stat_OPO = distorsion.get_distortion_statistic_analysis(structures,
distorsion.get_distortion_indices_angles,
['O', 'P', 'O'],
show_plots=False)
stat_OP = distorsion.get_distortion_statistic_analysis(structures,
distorsion.get_distortion_indices_distances,
['O', 'P'],
show_plots=False)
print 'averages: {} {} and deviations: {} {}'.format(stat_OP['average'], stat_OPO['average'],
stat_OP['deviation'], stat_OPO['deviation'])
Symmetry classification¶
Classify the symmetry of a list of structures is symmetry categories defined by the user
import montecarlo.analysis.symmetry_analysis
get_symmetry_analysis(structures [List of Structure Objects],
symmetry_to_analyze=None [List of Strings],
shape_to_analyze=1 [Integer],
central_atom=0 [Integer],
symmetry_threshold=0.1 [Float],
cutoff_shape=3.0 [Float],
show_plots=True [Boolean])
return {symmetry_label : percentage} [Dictionary]
- structures: List of Structure type objects to be analyzed
- symmetry_to_analyze : List of symmetry operations to classify the structures into.
- shape_to_analyze: Ideal shape of the structures
- cutoff_shape: Maximum value of shape measurement (defined in shape_to_analyze) to be accepted. Structures with a higher value will be discarded.
- symmetry_threshold: Maximum value of a symmetry measurement of a structure to consider that the structure has the measured symmetry.
- show_plots: If True, graphical data is shown. This includes histrograms showing the distribution of symmetry and shape measurements.
Exemple¶
import montemodes.functions.reading as io_monte
import montecarlo.analysis.symmetry_analysis
molecule1 = io_monte.reading_from_xyz_file('PO4_1.xyz')
molecule2 = io_monte.reading_from_xyz_file('PO4_2.xyz')
molecule3 = io_monte.reading_from_xyz_file('PO4_3.xyz')
structures = [molecule1, molecule2, molecule3]
percentage_dict = get_symmetry_analysis(structures [List of Structure Objects],
symmetry_to_analyze=['c 2', 'c 3', 's 4', 'r'],
shape_to_analyze=2,
central_atom=5,
symmetry_threshold=0.15,
cutoff_shape=5.0,
show_plots=False)
for key in percentage_dict:
print '{} : {} '.format(key, percentage_dict[key])