""".. _h2o_structure_opt: Structure optimization: :mol:`H_2O` =================================== Let's calculate the structure of the :mol:`H_2O` molecule. Part of this tutorial is exercise-based, so refer back to what you learnt from :ref:`introductionexample` and :ref:`atomscalculators`. Suggested solutions to the exercises are found after each exercise, but try solving them youself first! """ # %% # .. admonition:: Exercise # # Create an :class:`~ase.Atoms` object representing an :mol:`H_2O` # molecule by providing chemical symbols and a guess for the positions. # Visualize it, making sure the molecule is V shaped. # # Solution: import matplotlib.pyplot as plt from ase import Atoms from ase.visualize.plot import plot_atoms atoms = Atoms('HOH', positions=[[0, 0, -1], [0, 1, 0], [0, 0, 1]]) atoms.center(vacuum=3.0) fig, ax = plt.subplots() plot_atoms(atoms, ax, rotation='10x,60y,0z') ax.set_axis_off() # %% # .. admonition:: Exercise # # Run a self-consistent calculation of the approximate :mol:`H_2O` molecule # using GPAW. # # Solution: from gpaw import GPAW calc = GPAW(mode='lcao', basis='dzp', txt='gpaw.txt') atoms.calc = calc # %% # Optimizers # ---------- # We will next want to optimize the geometry. # ASE provides :mod:`several optimization algorithms ` # that can run on top of :class:`~ase.Atoms` equipped with a calculator: # # .. admonition:: Exercise # # Run a structure optimization, thus calculating the equilibrium # geometry of :mol:`H_2O`. # # Solution: from ase.optimize import BFGS opt = BFGS(atoms, trajectory='opt.traj', logfile='opt.log') opt.run(fmax=0.05) # %% # The ``trajectory`` keyword above ensures that the trajectory of intermediate # geometries is written to :file:`opt.traj`. # # .. admonition:: Exercise # # Visualize the output trajectory and play it as an animation. # Use the mouse to drag a box around and select the three atoms — # this will display the angles between them. # What is H–O–H angle of :mol:`H_2O`? # # Solution: # # .. code-block:: python # # from ase.io import read # from ase.visualize import view # # atoms = read('opt.traj', ':') # view(atoms) # %% # Note that the above will open in a separate graphical window. # As always in ASE, we can do things programmatically, too, # if we know the right incantations: from ase.io import read atoms = read('opt.traj', ':') print(atoms[-1].get_angle(0, 1, 2)) print(atoms[-1].get_angle(2, 0, 1)) print(atoms[-1].get_angle(1, 2, 0)) # %% # The documentation on the :class:`~ase.Atoms` object provides # a long list of methods. # # G2 molecule dataset # ------------------- # # ASE knows many common molecules, so we did not really need to type in # all the molecular coordinates ourselves. As luck would have it, the # :func:`ase.build.molecule` function does exactly what we need: from ase.build import molecule atoms = molecule('H2O', vacuum=3.0) fig, ax = plt.subplots() plot_atoms(atoms, ax, rotation='10x,60y,0z') ax.set_axis_off() # %% # This function returns a molecule from the G2 test set, which is nice # if we remember the exact name of that molecule, in this case :mol:`'H_2O'`. # In case we don't have all the molecule names memorized, we can work # with the G2 test set using the more general :mod:`ase.collections.g2` # module: from ase.collections import g2 print(g2.names) # These are the molecule names atoms = g2['CH3CH2OH'] # %% # To visualize the selected molecule as well as all 162 systems, run # # .. code-block:: python # # view(atoms) # view(g2) # %% # Use another calculator # ---------------------- # # We could equally well substitute # another calculator, often accessed through imports like ``from # ase.calculators.emt import EMT`` or ``from ase.calculators.aims import # Aims``. For a list, see :mod:`ase.calculators` or run:: # # $ ase info --calculators