Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Conformational search

Conformational search aims to identify the possible three-dimensional arrangements of a molecule by exploring its torsional degrees of freedom. For small and rigid molecules, a systematic enumeration of all rotatable bond combinations is feasible and guarantees complete coverage of the conformational space. However, as the number of rotatable bonds grows, the combinatorial explosion of possible conformations makes systematic search computationally intractable for larger and more flexible systems.

For small molecules, VeloxChem provides the ConformerGenerator class, which performs a systematic search by enumerating all combinations of rotatable bond angles, followed by MM energy minimization of each generated structure, yielding a ranked list of low-energy conformers.

For larger and more flexible systems, VeloxChem offers an MD-based conformational sampling approach through the conformational_sampling method of the OpenMMDynamics class. By running a high-temperature MD simulation, the molecule can overcome torsional barriers and broadly explore its conformational space. Snapshots collected along the trajectory are energy-minimized and, optionally, filtered to retain only unique conformers, providing a diverse and representative ensemble of structures.

import veloxchem as vlx
molecule = vlx.Molecule.read_smiles(
    "CC1([C@@H](N2[C@H](S1)[C@@H](C2=O)NC(=O)CC3=CC=CC=C3)C(=O)O)C")  
molecule.show(atom_indices=True)
Loading...

The ConformerGenerator class can generate all possible conformations and minimize them with MM.

conf = vlx.ConformerGenerator()
conformers_dict = conf.generate(molecule)

The lowest conformer can be displayed

conf.show_global_minimum()
Global minimum conformer with energy -247.407 kJ/mol
Loading...

And more conformers can be diplayed

conf.show_conformers(number=3)
Conformer 1 with energy -247.407 kJ/mol
Loading...
Conformer 2 with energy -243.576 kJ/mol
Loading...
Conformer 3 with energy -242.980 kJ/mol
Loading...
Loading...

Once a force field has been derived with the MMForceFieldGenerator and the system has been initialized with the OpenMMDynamics class; the conformational_sampling function can be used to extract conformers from the MD simulation at high temperature. The user can define a number of snapshots that will be optimized and save. In addition, those snapshots can be filtered to avoid that the same conformer is present multiple timess by using the option unique_conformers.

conformers_dict = opm_dyn.conformational_sampling(
                                ensemble='NVT', 
                                temperature=1000, 
                                timestep=2.0, 
                                nsteps=100000, 
                                snapshots=500,
                                unique_conformers=True,
                                qm_driver=None,
                                basis=None,
                                constraints=None)
<Figure size 800x400 with 1 Axes>
opm_dyn.show_conformers(number=3)
* Info * 
Conformation 1: Energy: 1617.202 kJ/mol, Weight: 0.3124                                                         
Loading...
* Info * 
Conformation 2: Energy: 1617.256 kJ/mol, Weight: 0.3057                                                         
Loading...
* Info * 
Conformation 3: Energy: 1617.828 kJ/mol, Weight: 0.2431                                                         
Loading...
# Write it to an XYZ file
conformers_dict['molecules'][0].write_xyz_file('tq-polymer-0.xyz')

When dealing with multiple molecules simultaneously, VeloxChem supports a multi-molecule conformational search. This approach automatically generates force fields for each molecule and employs the OpenMMDynamics driver with a centroid restraint force to prevent molecules from drifting apart during a high-temperature MD simulation. A user-defined number of snapshots are then energy-minimized to yield a representative set of low-energy conformers.

Load your molecules and create a list containing those molecules.

mol1 = vlx.Molecule.read_smiles('C([C@@H]1[C@H]([C@@H]([C@H](C(O1)O)O)O)O)O')
mol2 = vlx.Molecule.read_smiles('O')
mol3 = vlx.Molecule.read_smiles('O')

molecules = [mol1, mol2, mol3]

Initiate and run the conformational search for multiple molecules.

omm = vlx.OpenMMDynamics()
conformer_dict = omm.conformational_sampling_multiple(molecules, 
                                                      temperature = 800, 
                                                      nsteps = 100000, 
                                                      snapshots = 40,
                                                      lowest_conformations = 3)

Show the structures

for mol, e in zip(conformer_dict['molecules'], conformer_dict['energies']):
    mol.show()
    print(f"{e:.2f} kJ/mol")
Loading...
127.28 kJ/mol
Loading...
129.94 kJ/mol
Loading...
135.53 kJ/mol