************************* Hybrid QM/MM calculations ************************* Now that we have seen how to carry out quantum and classical calculations within ChemShell, we can look at how to combine them to perform hybrid QM/MM calculations. NB: as is conventional in the scientific literature we use the term QM/MM loosely to include any kind of hybrid quantum and classical calculation, regardless of whether it specifically uses a molecular mechanics forcefield for the classical part or not. QM/MM calculations can be characterised by their level of embedding: mechanical, electrostatic or polarised. In this tutorial, we will look at the first two types which are the most commonly used. We will meet polarised embedding in later tutorials where shell model potentials are used. The examples in this tutorial are in ``samples/qmmm_gulp/``. Mechanical embedding ==================== In a mechanical embedding calculation, the QM part of the calculation is not directly affected by the MM part, and is performed as if the system is in the gas phase. The coupling of the QM and MM parts of the system is achieved purely at the MM level through assigning partial charges to the QM centres which interact electrostically with the MM centres. These charges may be already known from the forcefield definition, or may have to be derived. In our example ``mech_butanol.nwchem.py`` and equivalents, we re-use the butanol molecule and forcefield we saw defined in the previous tutorial. However, in this case we define both a QM and MM calculation:: # Define QM and MM parts of the calculation my_qm = NWChem(method="dft", functional="blyp", basis="3-21g") my_mm = GULP(ff=ff, molecule=True) As you can see, this is no different from the individual QM and MM calculations we have run before. In order to combine the two in a hybrid QM/MM calculation, we next create a ``QMMM()`` object which defines the coupling between the QM and MM parts:: # Define the combined QM/MM calculation my_qmmm = QMMM(frag=my_mol, qm_region=range(5), qm=my_qm, mm=my_mm, embedding="mechanical") Here we specify the QM and MM parts by passing the corresponding objects to the ``qm=`` and ``mm=`` options. The QM region must also be defined as a python list. Here we have used python's ``range`` command to create a list of atoms 0-4. We also select the type of embedding to be used, in this case mechanical. Finally, we request an energy minimisation with DL-FIND. Here we pass the ``QMMM`` object ``my_qmmm`` to the ``Opt()`` definition, rather than any of the individual QM and MM parts:: # Request an energy minimisation my_opt = Opt(theory=my_qmmm, algorithm="lbfgs", tolerance=0.0003, maxcycle=300, maxene=400, trustradius="energy") my_opt.run() Notice when DL-FIND runs that each step now consists of a QM and MM calculation, and the individual and combined QM/MM energies are reported along the way, e.g.:: ********************************************************************** QM energy = -115.026242573788 a.u. MM energy = -0.002321958949 a.u. QM/MM total energy = -115.028564532737 a.u. ********************************************************************** You may find at times that either the QM or MM energy is rising during the optimisation, as it is the combined QM/MM total energy that is minimised. Electrostatic embedding ======================= The next level of embedding is known as electrostatic embedding, where the MM partial charges enter the QM Hamiltonian and so directly polarise the QM subsystem. This relies on the QM program used supporting calculations with additional point charges, but support for this is now almost universal. One issue with electrostatic embedding is that the MM centres can overpolarise the QM subsystem through their proximity to link atoms that are added into the QM calculation wherever a covalent bond is broken. ChemShell handles this situation automatically through a "charge shift" scheme to reduce the polarisation effect - for details see the ChemShell publications. In practical terms, you do not need to worry about this complexities when setting up the calculation. All that needs to be changed is the ``QMMM()`` definition as in our example ``elec_butanol.nwchem.py``:: # Define the combined QM/MM calculation my_qmmm = QMMM(frag=my_mol, qm_region=range(5), qm=my_qm, mm=my_mm, embedding="electrostatic", coupling="covalent") Here ``embedding="electrostatic"`` specifies that electrostatic embedding should be used, and ``coupling="covalent"`` specifies that the system is covalently bonded and so the charge shift scheme should be implemented wherever a bond is broken. We will look at ionic systems, which are treated differently, in later tutorials. Please note that the energies from calculations run at different levels of embedding cannot be directly compared, so you should not expect for example that an electrostatic embedding energy will necessarily be lower than a mechanical embedding energy calculated on the same system.