\hypertarget{tutorials_user_tutorial}{}\doxysection{User Tutorial}\label{tutorials_user_tutorial}
In this tutorial we will use an M\+DI driver to perform a simple {\itshape  Ab Initio } Molecular Dynamics (A\+I\+MD) simulation, using Quantum E\+S\+P\+R\+E\+S\+SO (QE) to calculate forces and L\+A\+M\+M\+PS to update the atomic coordinates each time step. L\+A\+M\+M\+PS is a code that simulates chemical systems using molecular mechanics (MM) force fields, which are computationally very efficient to evaluate and can be used for lengthy dynamics simulations of large systems. Quantum E\+S\+P\+R\+E\+S\+SO is a code that runs quantum mechanics (QM) calculations, which are much more computationally expensive, but can be applied much more straigtforwardly to chemically reactive systems and other specific use cases. MM codes like L\+A\+M\+M\+PS often offer time integration features that are not widely available in QM codes, so it can be desirable to be able to mix the time integration functionality of an MM code with the force evaluation functionality of a QM code.

Although we will be using QE and L\+A\+M\+M\+PS as the M\+DI engines in this tutorial, you could do similar calculations using other M\+DI engines. A list of codes that support M\+DI can be found \mbox{\hyperlink{mdi_ecosystem}{here}}, along with instructions on how to compile them with M\+DI support.\hypertarget{tutorials_tutorial_engine_compile}{}\doxysubsection{Compiling the Driver and Engines}\label{tutorials_tutorial_engine_compile}
The hardest part of getting an M\+DI calculation working is often getting all the necessary codes compiled. Computational chemistry software packages tend to be complex, often with numerous dependencies that can themselves be challenging to compile. You {\itshape  could } try to compile the codes manually by following the specific compile process for each code, and the next section will offer some guidance for this process; however, this tutorial will also describe an easier way to get the codes compiled using containers.\hypertarget{tutorials_manual_compile}{}\doxysubsubsection{The Hard Way\+: Manually Compile the Engines}\label{tutorials_manual_compile}
As mention earlier, manually compiling computational chemistry software can be challenging. Depending on your computational environment, you can easily spend days trying to get certain codes operating properly. This section will offer an overview of the manual compile process for the codes used in this tutorial, but you may wish to consider skipping to the next section, which describes an easier way to get started with your first M\+DI calculations.

First, compile both \mbox{\hyperlink{mdi_ecosystem_ecosystem_qe}{QE}} and \mbox{\hyperlink{mdi_ecosystem_ecosystem_lammps}{L\+A\+M\+M\+PS}} (or your preferred QM and MM packages) with M\+DI support by following the \mbox{\hyperlink{mdi_ecosystem_ecosystem_overview}{instructions provided}}.

After you\textquotesingle{}ve finished compiling the engines, you can download and compile the A\+I\+MD driver with the following commands\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{git clone git@github.com:MolSSI/MDI\_AIMD\_Driver.git}
\DoxyCodeLine{mkdir MDI\_AIMD\_Driver/build}
\DoxyCodeLine{cd MDI\_AIMD\_Driver/build}
\DoxyCodeLine{cmake ..}
\DoxyCodeLine{make}
\end{DoxyCode}


In {\ttfamily M\+D\+I\+\_\+\+A\+I\+M\+D\+\_\+\+Driver/tests/locations} there are several single-\/line text files, each of which is intended to indicate the location of one of the codes you installed above. Edit each of them so that they provide the absolute path to the corresponding code\textquotesingle{}s executable.\hypertarget{tutorials_container_compile}{}\doxysubsubsection{The Easy(er) Way\+: Compile Using M\+D\+I Mechanic}\label{tutorials_container_compile}
M\+DI provides a support tool, called M\+DI Mechanic, which can help you avoid the need to figure out how to compile various QM and MM codes yourself. M\+DI Mechanic automatically builds Docker images from recipes you provide it, allowing you to compile and run all the codes you need for this tutorial in a self-\/contained, portable environment. Before continuing, you\textquotesingle{}ll need to install and launch Docker Desktop.

You can now install M\+DI Mechanic with\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{pip install mdimechanic}
\end{DoxyCode}


You can download the M\+DI Mechanic recipe you need with\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{git clone https:\textcolor{comment}{//github.com/MolSSI-\/MDI/MDI\_AIMD\_Driver\_container.git}}
\end{DoxyCode}


This recipe contains instructions for building QE, L\+A\+M\+M\+PS, and the M\+D\+I\+\_\+\+A\+I\+M\+D\+\_\+\+Driver code within a self-\/contained Docker environment. To build the recipes, do\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{cd MDI\_AIMD\_Driver\_container}
\DoxyCodeLine{mdimechanic build}
\end{DoxyCode}


This is likely to take a significant amount of time to complete, as QE and L\+A\+M\+M\+PS are both large codes. Once it has successfully finished, you can start working in the environment it has created using\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{mdimechanic interactive}
\end{DoxyCode}


This will start an interactive container session. If you\textquotesingle{}re not familiar with Docker or containerization, you may wish to read a bit about these tools. Otherwise, you can think about the \char`\"{}mdimechanic interactive\char`\"{} session as being similar to logging onto a remote computer via ssh -\/ except that in the case of containers, the computer you are \char`\"{}logging into\char`\"{} is actually running as a self-\/contained environment on your local machine. While you are in the interactive session, you can run tests and other calculations within the containerized environment. Any changes you make to the environment while within the interactive session are transient, and will be discarded upon exiting the session (exception\+: any changes to files or subdirectories within the directory where mdimechanic.\+yml is located will be preserved upon exiting the interactive session).

For more information about M\+DI Mechanic, please see the \href{https://github.com/MolSSI-MDI/MDI_Mechanic/blob/master/docs/getting_started.rst}{\texttt{ M\+DI Mechanic Getting Started Guide}}.

While in the interactive session, you can find the compiled codes in subdirectories of the \char`\"{}/repo/build\char`\"{} directory. Go ahead and check that now\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{cd /repo/build}
\DoxyCodeLine{ls}
\end{DoxyCode}


You should see subdirectories for L\+A\+M\+M\+PS, QE, and the M\+D\+I\+\_\+\+A\+I\+M\+D\+\_\+\+Driver code.\hypertarget{tutorials_user_run}{}\doxysubsection{Running the Simulation}\label{tutorials_user_run}
We will now run a simple A\+I\+MD simulation.

There is a simple test calculation in {\ttfamily M\+D\+I\+\_\+\+A\+I\+M\+D\+\_\+\+Driver/tests/water}. Within this directory, the {\ttfamily data} subdirectory contains standard input files for L\+A\+M\+M\+PS and QE. The input files correspond to a small water box of 8 water molecules. They are exactly like any non-\/\+M\+DI input files for their respective codes, except for {\ttfamily data/lammps.\+in}. At the end of {\ttfamily data/lammps.\+in} is a command that tells L\+A\+M\+M\+PS it should begin running as an M\+DI engine\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{...}
\DoxyCodeLine{mdi engine}
\end{DoxyCode}


There are two scripts associated with the water test\+: {\ttfamily tcp.\+sh} and {\ttfamily mpi.\+sh}. The {\ttfamily tcp.\+sh} script will run the simulation using the T\+C\+P/\+IP method for communicating between the driver and the engines. It consists of the following code\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{preprocessor}{\#location of required codes}}
\DoxyCodeLine{DRIVER\_LOC=\$(cat ../locations/MDI\_AIMD\_Driver)}
\DoxyCodeLine{LAMMPS\_LOC=\$(cat ../locations/LAMMPS)}
\DoxyCodeLine{QE\_LOC=\$(cat ../locations/QE)}
\DoxyCodeLine{}
\DoxyCodeLine{\#remove old files}
\DoxyCodeLine{\textcolor{keywordflow}{if} [ -\/d work ]; then}
\DoxyCodeLine{  rm -\/r work}
\DoxyCodeLine{fi}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{preprocessor}{\#create work directory}}
\DoxyCodeLine{cp -\/r data work}
\DoxyCodeLine{cd work}
\DoxyCodeLine{}
\DoxyCodeLine{cd work}
\DoxyCodeLine{\$\{QE\_LOC\} -\/mdi \textcolor{stringliteral}{"-\/role ENGINE -\/name QM -\/method TCP -\/port 8021 -\/hostname localhost"} -\/in qe.in > qe.out \&}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{preprocessor}{\#launch LAMMPS}}
\DoxyCodeLine{\$\{LAMMPS\_LOC\} -\/mdi \textcolor{stringliteral}{"-\/role ENGINE -\/name MM -\/method TCP -\/port 8021 -\/hostname localhost"} -\/in lammps.in > lammps.out \&}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{preprocessor}{\#launch driver}}
\DoxyCodeLine{\$\{DRIVER\_LOC\} -\/mdi \textcolor{stringliteral}{"-\/role DRIVER -\/name driver -\/method TCP -\/port 8021"} \&}
\DoxyCodeLine{}
\DoxyCodeLine{wait}
\end{DoxyCode}


The first few lines simply read the location of the codes from the files in M\+D\+I\+\_\+\+A\+I\+M\+D\+\_\+\+Driver/tests/locations and copy the L\+A\+M\+M\+PS and QE input files into a subdirectory called {\ttfamily work}. Then the script launches QE. The QE launch command is exactly the same as a normal run of QE, except for the addition of a {\ttfamily -\/mdi} option. This option provides information to the M\+DI Library regarding how the codes will communicate with one another. Its argument is a string, which itself consists of a series of options that are read by the M\+DI Library. In this case, it provides the following options\+:


\begin{DoxyItemize}
\item role\+: Indicates whether this code will run as an {\ttfamily E\+N\+G\+I\+NE} or a {\ttfamily D\+R\+I\+V\+ER}.
\item name\+: Identifies the purpose of this engine. Each M\+DI driver will expect its engines to be named according to a particular standard. The M\+D\+I\+\_\+\+A\+I\+M\+D\+\_\+\+Driver engine expects one of the engines to be named \char`\"{}\+Q\+M\char`\"{} and the other to be named \char`\"{}\+M\+M\char`\"{}.
\item method\+: The communication method used to transfer information between the driver and the engines.
\item port\+: The port number that the driver will be listening over. Only used if the method is {\ttfamily T\+CP}.
\item hostname\+: The host name of the driver. Only used by engines and if the method is {\ttfamily T\+CP}.
\end{DoxyItemize}

Note the presence of an ampersand (\char`\"{}\&\char`\"{}) at the end of each run command, which causes the codes to run in the background. Without doing this, the script would launch QE and would wait until QE terminated before ever launching L\+A\+M\+M\+PS and the driver, leading to an indefinite hang. Finally, the wait command at the end ensures that the driver and the engines are permitted to terminate before the script terminates.

You can now execute the {\ttfamily tcp.\+sh} script, which should print out the energies of L\+A\+M\+M\+PS and QE for several timesteps of a short A\+I\+MD simulation.

If you compiled everything (QE, L\+A\+M\+M\+PS, M\+D\+I\+\_\+\+A\+I\+M\+D\+\_\+\+Driver, and the internal copies of the M\+DI Library) with M\+PI or are using the M\+DI Mechanic build, you can also execute the {\ttfamily mpi.\+sh} script, which will run the same simulation using M\+PI for the inter-\/code communication. The {\ttfamily mpi.\+sh} script redirects the driver\textquotesingle{}s output to a file called {\ttfamily work/driver.\+out} . The output produced by QE and L\+A\+M\+M\+PS can be found in {\ttfamily work/qe.\+out} and {\ttfamily work/lammps.\+out}, respectively.\hypertarget{tutorials_aimd_tutorial}{}\doxysection{Driver Development Tutorial}\label{tutorials_aimd_tutorial}
Please complete the \mbox{\hyperlink{tutorials_user_tutorial}{User Tutorial}} before starting this tutorial.

In this tutorial we will set up a simple driver for running {\itshape  Ab Initio } Molecular Dynamics (A\+I\+MD) simulations. We will use a quantum chemistry (QM) code to compute the forces, while using a molecular mechanics (MM) code to propagate the atomic coordinates each time step.\hypertarget{tutorials_requirements_sec}{}\doxysubsection{Creating a New Project}\label{tutorials_requirements_sec}
The easiest way to start work on a new driver is to use the M\+DI Driver Cookiecutter, which will automatically do most of the preparatory work for you. Using the cookiecutter will require that you have Python and Cookiecutter on your machine. If you do not already have Python installed, follow the directions on the \href{https://www.python.org/}{\texttt{ Python Website}} and install both Python and the {\ttfamily pip} installer tool. To install Cookiecutter, type\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{pip install cookiecutter}
\end{DoxyCode}


If you are running on an external machine and do not have write permission to the system directories, you may need to add the {\ttfamily --user} option\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{pip install -\/-\/user cookiecutter}
\end{DoxyCode}


Now use Cookiecutter to create a new driver project\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{cookiecutter git@github.com:MolSSI/MDI\_Driver\_Cookiecutter.git}
\end{DoxyCode}


When prompted for the {\ttfamily repo\+\_\+name}, type {\ttfamily aimd}, and then when prompted to select a language, type {\ttfamily 1} for C++. This will create a new directory called {\ttfamily aimd} and populate it with some of the things you will need for the driver, including a copy of the M\+DI Library. The overall directory structure is\+: 
\begin{DoxyCode}{0}
\DoxyCodeLine{.}
\DoxyCodeLine{└── aimd}
\DoxyCodeLine{    ├── CMakeLists.txt}
\DoxyCodeLine{    ├── aimd}
\DoxyCodeLine{        ├── CMakeLists.txt}
\DoxyCodeLine{        ├── STUBS\_MPI}
\DoxyCodeLine{        │   └── mpi.h}
\DoxyCodeLine{        └── aimd.cpp}
\DoxyCodeLine{        └── mdi}
\DoxyCodeLine{            ...}
\end{DoxyCode}
\hypertarget{tutorials_writing_sec}{}\doxysubsection{Writing the Driver}\label{tutorials_writing_sec}
Open the file called {\ttfamily aimd.\+cpp}. It contains the following code\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{preprocessor}{\#include <iostream>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include <mpi.h>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include <stdexcept>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include <string.h>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include "mdi.h"}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keyword}{using namespace }std;}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keywordtype}{int} main(\textcolor{keywordtype}{int} argc, \textcolor{keywordtype}{char} **argv) \{}
\DoxyCodeLine{}
\DoxyCodeLine{  \textcolor{comment}{// Initialize the MPI environment}}
\DoxyCodeLine{  MPI\_Comm world\_comm;}
\DoxyCodeLine{  MPI\_Init(\&argc, \&argv);}
\DoxyCodeLine{}
\DoxyCodeLine{  \textcolor{comment}{// Initialize MDI}}
\DoxyCodeLine{  \textcolor{keywordflow}{if} ( \mbox{\hyperlink{mdi_8c_a9f26d9f67413c6c194a2f5e4bd69b911}{MDI\_Init}}(\&argc, \&argv) ) \{}
\DoxyCodeLine{    \textcolor{keywordflow}{throw} std::runtime\_error(\textcolor{stringliteral}{"The MDI library was not initialized correctly."});}
\DoxyCodeLine{  \}}
\DoxyCodeLine{}
\DoxyCodeLine{  \textcolor{comment}{// Confirm that MDI was initialized successfully}}
\DoxyCodeLine{  \textcolor{keywordtype}{int} initialized\_mdi;}
\DoxyCodeLine{  \textcolor{keywordflow}{if} ( \mbox{\hyperlink{mdi_8c_a82aaa736f9d174c7663ad80a97089767}{MDI\_Initialized}}(\&initialized\_mdi) ) \{}
\DoxyCodeLine{    \textcolor{keywordflow}{throw} std::runtime\_error(\textcolor{stringliteral}{"MDI\_Initialized failed."});}
\DoxyCodeLine{  \}}
\DoxyCodeLine{  \textcolor{keywordflow}{if} ( ! initialized\_mdi ) \{}
\DoxyCodeLine{    \textcolor{keywordflow}{throw} std::runtime\_error(\textcolor{stringliteral}{"MDI not initialized: did you provide the -\/mdi option?."});}
\DoxyCodeLine{  \}}
\DoxyCodeLine{}
\DoxyCodeLine{  \textcolor{comment}{// Get the correct MPI intra-\/communicator for this code}}
\DoxyCodeLine{  \textcolor{keywordflow}{if} ( \mbox{\hyperlink{mdi_8c_a1792db6705a7032640af46d5b05d23f4}{MDI\_MPI\_get\_world\_comm}}(\&world\_comm) ) \{}
\DoxyCodeLine{    \textcolor{keywordflow}{throw} std::runtime\_error(\textcolor{stringliteral}{"MDI\_MPI\_get\_world\_comm failed."});}
\DoxyCodeLine{  \}}
\DoxyCodeLine{}
\DoxyCodeLine{  \textcolor{comment}{// Connect to the engines}}
\DoxyCodeLine{  \textcolor{comment}{// <YOUR CODE GOES HERE>}}
\DoxyCodeLine{}
\DoxyCodeLine{  \textcolor{comment}{// Perform the simulation}}
\DoxyCodeLine{  \textcolor{comment}{// <YOUR CODE GOES HERE>}}
\DoxyCodeLine{}
\DoxyCodeLine{  \textcolor{comment}{// Send the "EXIT" command to each of the engines}}
\DoxyCodeLine{  \textcolor{comment}{// <YOUR CODE GOES HERE>}}
\DoxyCodeLine{}
\DoxyCodeLine{  \textcolor{comment}{// Synchronize all MPI ranks}}
\DoxyCodeLine{  MPI\_Barrier(world\_comm);}
\DoxyCodeLine{  MPI\_Finalize();}
\DoxyCodeLine{}
\DoxyCodeLine{  \textcolor{keywordflow}{return} 0;}
\DoxyCodeLine{\}}
\end{DoxyCode}


The first few lines of code simply initialize both M\+PI and and M\+DI. Don\textquotesingle{}t worry if you don\textquotesingle{}t have access to an M\+PI library -\/ the code will just fall back to a set of dummy M\+PI functions provided in {\ttfamily S\+T\+U\+B\+S\+\_\+\+M\+PI}. The call to the {\ttfamily \mbox{\hyperlink{mdi_8c_a1792db6705a7032640af46d5b05d23f4}{M\+D\+I\+\_\+\+M\+P\+I\+\_\+get\+\_\+world\+\_\+comm()}}} function obtains from M\+DI an M\+PI intra-\/communicator that spans all M\+PI ranks associated with the driver. This call is important when using the M\+PI protocol for M\+DI communication, because in that context, M\+P\+I\+\_\+\+C\+O\+M\+M\+\_\+\+W\+O\+R\+LD spans all ranks associated with both the driver and the engine(s). In general, an M\+D\+I-\/enabled code should call {\ttfamily \mbox{\hyperlink{mdi_8c_a1792db6705a7032640af46d5b05d23f4}{M\+D\+I\+\_\+\+M\+P\+I\+\_\+get\+\_\+world\+\_\+comm()}}} immediately after calling {\ttfamily \mbox{\hyperlink{mdi_8c_a9f26d9f67413c6c194a2f5e4bd69b911}{M\+D\+I\+\_\+\+Init()}}}, and the resulting M\+PI intra-\/communicator should be used instead of M\+P\+I\+\_\+\+C\+O\+M\+M\+\_\+\+W\+O\+R\+LD throughout the remainder of the code.

After initializing M\+DI, we need to connect the driver to its engines. For this particular tutorial, we will use a QM engine to calculate forces and an MM engine to update the atomic coordinates each timestep. In the M\+DI standard, engines request a connection to a driver. The driver will need to call the {\ttfamily \mbox{\hyperlink{mdi_8c_a91c05f57c87bd5ca8aad65d2d6c3ca72}{M\+D\+I\+\_\+\+Accept\+\_\+communicator()}}} function to accept each connection. The general format of this functional call looks like this\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{MDI\_Comm comm;}
\DoxyCodeLine{\mbox{\hyperlink{mdi_8c_a91c05f57c87bd5ca8aad65d2d6c3ca72}{MDI\_Accept\_communicator}}(\&comm);}
\end{DoxyCode}


This will assign a new M\+DI communicator to {\ttfamily comm}, which functions very similarly to an M\+PI communicator and is used in certain M\+DI function calls to identify which engine is expected to send/receive data to/from the driver. Our A\+I\+MD driver will connect to two different engines, so we will be calling {\ttfamily \mbox{\hyperlink{mdi_8c_a91c05f57c87bd5ca8aad65d2d6c3ca72}{M\+D\+I\+\_\+\+Accept\+\_\+communicator()}}} twice. We don\textquotesingle{}t know the order in which the engines will request a connection to the driver, so we will need some way to determine which engine is the QM code and which engine is the MM code.

This can be accomplished through the use of the "{\ttfamily $<$N\+A\+ME"} command. The entire M\+DI standard is built around the idea that drivers can send \char`\"{}commands\char`\"{} to engines, each of which is defined by the M\+DI standard and has a specific outcome. The "{\ttfamily $<$N\+A\+ME"} command tells the engine to send the driver a string of length {\ttfamily M\+D\+I\+\_\+\+N\+A\+M\+E\+\_\+\+L\+E\+N\+G\+TH} that identifies the engine. The end-\/user is responsible for indicating the name of each engine at runtime, using the {\ttfamily -\/name} command line argument that was described in the \mbox{\hyperlink{tutorials_user_tutorial}{User Tutorial}}. As authors of a driver, we will need to decide what we expect each of the engines to be named and clearly document that decision for the benefit of the end-\/users. For the purpose of this tutorial, we will expect the quantum mechanics code to be called \char`\"{}\+Q\+M\char`\"{} and the molecular mechanics code to be named \char`\"{}\+M\+M\char`\"{}.

Sending the "{\ttfamily $<$N\+A\+ME"} command to an engine and then receiving the engine\textquotesingle{}s name can be done as follows\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keywordtype}{char}* code\_name = \textcolor{keyword}{new} \textcolor{keywordtype}{char}[\mbox{\hyperlink{mdi_8c_a8ca47e903a62de4298767ef3d446901d}{MDI\_NAME\_LENGTH}}];}
\DoxyCodeLine{\mbox{\hyperlink{mdi_8c_a3fa5769d2a6d0ad305fdaa12b048056e}{MDI\_Send\_command}}(\textcolor{stringliteral}{"<NAME"}, comm);}
\DoxyCodeLine{\mbox{\hyperlink{mdi_8c_ab73f32323a155011fcc184866215ba03}{MDI\_Recv}}(code\_name, \mbox{\hyperlink{mdi_8c_a8ca47e903a62de4298767ef3d446901d}{MDI\_NAME\_LENGTH}}, \mbox{\hyperlink{mdi_8c_a508f568d6a6cba24d6015347d6c1469e}{MDI\_CHAR}}, comm);}
\end{DoxyCode}


The following code accepts connections from two engines and assigns the communicator from the engine named \char`\"{}\+M\+M\char`\"{} to {\ttfamily mm\+\_\+comm} and assigns the communicator from the engine named \char`\"{}\+Q\+M\char`\"{} to {\ttfamily qm\+\_\+comm}. Replace the comment that reads "{\ttfamily // Connect to the engines}" with\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{comment}{// Connect to the engines}}
\DoxyCodeLine{MDI\_Comm mm\_comm = \mbox{\hyperlink{mdi_8c_a01e277b0239a7304055c883adb759280}{MDI\_COMM\_NULL}};}
\DoxyCodeLine{MDI\_Comm qm\_comm = \mbox{\hyperlink{mdi_8c_a01e277b0239a7304055c883adb759280}{MDI\_COMM\_NULL}};}
\DoxyCodeLine{\textcolor{keywordtype}{int} nengines = 2;}
\DoxyCodeLine{\textcolor{keywordflow}{for} (\textcolor{keywordtype}{int} iengine=0; iengine < nengines; iengine++) \{}
\DoxyCodeLine{  MDI\_Comm comm;}
\DoxyCodeLine{  \mbox{\hyperlink{mdi_8c_a91c05f57c87bd5ca8aad65d2d6c3ca72}{MDI\_Accept\_communicator}}(\&comm);}
\DoxyCodeLine{}
\DoxyCodeLine{  \textcolor{comment}{// Determine the name of this engine}}
\DoxyCodeLine{  \textcolor{keywordtype}{char}* engine\_name = \textcolor{keyword}{new} \textcolor{keywordtype}{char}[\mbox{\hyperlink{mdi_8c_a8ca47e903a62de4298767ef3d446901d}{MDI\_NAME\_LENGTH}}];}
\DoxyCodeLine{  \mbox{\hyperlink{mdi_8c_a3fa5769d2a6d0ad305fdaa12b048056e}{MDI\_Send\_command}}(\textcolor{stringliteral}{"<NAME"}, comm);}
\DoxyCodeLine{  \mbox{\hyperlink{mdi_8c_ab73f32323a155011fcc184866215ba03}{MDI\_Recv}}(engine\_name, \mbox{\hyperlink{mdi_8c_a8ca47e903a62de4298767ef3d446901d}{MDI\_NAME\_LENGTH}}, \mbox{\hyperlink{mdi_8c_a508f568d6a6cba24d6015347d6c1469e}{MDI\_CHAR}}, comm);}
\DoxyCodeLine{}
\DoxyCodeLine{  cout << \textcolor{stringliteral}{"Engine name: "} << engine\_name << endl;}
\DoxyCodeLine{}
\DoxyCodeLine{  \textcolor{keywordflow}{if} ( strcmp(engine\_name, \textcolor{stringliteral}{"MM"}) == 0 ) \{}
\DoxyCodeLine{    \textcolor{keywordflow}{if} ( mm\_comm != \mbox{\hyperlink{mdi_8c_a01e277b0239a7304055c883adb759280}{MDI\_COMM\_NULL}} ) \{}
\DoxyCodeLine{  \textcolor{keywordflow}{throw} runtime\_error(\textcolor{stringliteral}{"Accepted a communicator from a second MM engine."});}
\DoxyCodeLine{    \}}
\DoxyCodeLine{    mm\_comm = comm;}
\DoxyCodeLine{  \}}
\DoxyCodeLine{  \textcolor{keywordflow}{else} \textcolor{keywordflow}{if} ( strcmp(engine\_name, \textcolor{stringliteral}{"QM"}) == 0 ) \{}
\DoxyCodeLine{    \textcolor{keywordflow}{if} ( qm\_comm != \mbox{\hyperlink{mdi_8c_a01e277b0239a7304055c883adb759280}{MDI\_COMM\_NULL}} ) \{}
\DoxyCodeLine{  \textcolor{keywordflow}{throw} runtime\_error(\textcolor{stringliteral}{"Accepted a communicator from a second QM engine."});}
\DoxyCodeLine{    \}}
\DoxyCodeLine{    qm\_comm = comm;}
\DoxyCodeLine{  \}}
\DoxyCodeLine{  \textcolor{keywordflow}{else} \{}
\DoxyCodeLine{    \textcolor{keywordflow}{throw} runtime\_error(\textcolor{stringliteral}{"Unrecognized engine name."});}
\DoxyCodeLine{  \}}
\DoxyCodeLine{}
\DoxyCodeLine{  \textcolor{keyword}{delete}[] engine\_name;}
\DoxyCodeLine{\}}
\end{DoxyCode}


We are now ready to use M\+DI to orchestrate an A\+I\+MD simulation. In broad terms, during each dynamics iteration we will send a set of atomic coordinates from the MM engine to the QM engine, order the QM engine to send the driver the corresponding atomic forces, send those forces to the MM engine, and order the MM engine to perform a time step.

Keep in mind that the driver doesn\textquotesingle{}t know anything about the simulated system beyond what it can query by sending M\+DI commands. M\+DI engines initialize basic information about the system using whatever input file format the engine\textquotesingle{}s developer chose. When the MM and QM engines are launched, they will each read their standard input files, perform basic initialization tasks, and then request a connection to the driver. The driver can request information about the engine\textquotesingle{}s system by sending certain M\+DI commands. For example, to determine the number of atoms in the MM engine\textquotesingle{}s system, you could do\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{comment}{// Receive the number of atoms from the MM engine}}
\DoxyCodeLine{\textcolor{keywordtype}{int} natoms;}
\DoxyCodeLine{\mbox{\hyperlink{mdi_8c_a3fa5769d2a6d0ad305fdaa12b048056e}{MDI\_Send\_command}}(\textcolor{stringliteral}{"<NATOMS"}, mm\_comm);}
\DoxyCodeLine{\mbox{\hyperlink{mdi_8c_ab73f32323a155011fcc184866215ba03}{MDI\_Recv}}(\&natoms, 1, \mbox{\hyperlink{mdi_8c_ab88e0bb1563ba9fa73ffc49a704e43ad}{MDI\_INT}}, mm\_comm);}
\end{DoxyCode}


Similarly, to learn the coordinates of the atoms in the MM engine\textquotesingle{}s system, you could do\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{comment}{// Receive the coordinates from the MM engine}}
\DoxyCodeLine{\textcolor{keywordtype}{double} coords[3*natoms];}
\DoxyCodeLine{\mbox{\hyperlink{mdi_8c_a3fa5769d2a6d0ad305fdaa12b048056e}{MDI\_Send\_command}}(\textcolor{stringliteral}{"<COORDS"}, mm\_comm);}
\DoxyCodeLine{\mbox{\hyperlink{mdi_8c_ab73f32323a155011fcc184866215ba03}{MDI\_Recv}}(\&coords, 3*natoms, \mbox{\hyperlink{mdi_8c_a3d0c16831c941e5b870461394bfe5c82}{MDI\_DOUBLE}}, mm\_comm);}
\end{DoxyCode}


You could then update the coordinates of the QM engine\textquotesingle{}s system\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{comment}{// Send the coordinates to the QM engine}}
\DoxyCodeLine{\mbox{\hyperlink{mdi_8c_a3fa5769d2a6d0ad305fdaa12b048056e}{MDI\_Send\_command}}(\textcolor{stringliteral}{">COORDS"}, qm\_comm);}
\DoxyCodeLine{\mbox{\hyperlink{mdi_8c_a7bebce6d5fa91ee99a34fdcc5dcaedea}{MDI\_Send}}(\&coords, 3*natoms, \mbox{\hyperlink{mdi_8c_a3d0c16831c941e5b870461394bfe5c82}{MDI\_DOUBLE}}, qm\_comm);}
\end{DoxyCode}


\begin{DoxyNote}{Note}
As we will discuss later in \mbox{\hyperlink{tutorials_tutorials_using_sec}{Using the Driver}}, this driver assumes that the engines have both been initialized with the same number of atoms, the same atom types and ordering of atom types, and the same cell dimensions.
\end{DoxyNote}
The following code will handle all of the work associated with driving an A\+I\+MD simulation Replace the comment that reads "{\ttfamily // Perform the simulation}" with\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{comment}{// Perform the simulation}}
\DoxyCodeLine{\textcolor{keywordtype}{int} niterations = 10;  \textcolor{comment}{// Number of MD iterations}}
\DoxyCodeLine{\textcolor{keywordtype}{int} natoms;}
\DoxyCodeLine{\textcolor{keywordtype}{double} qm\_energy;}
\DoxyCodeLine{\textcolor{keywordtype}{double} mm\_energy;}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{comment}{// Receive the number of atoms from the MM engine}}
\DoxyCodeLine{\mbox{\hyperlink{mdi_8c_a3fa5769d2a6d0ad305fdaa12b048056e}{MDI\_Send\_command}}(\textcolor{stringliteral}{"<NATOMS"}, mm\_comm);}
\DoxyCodeLine{\mbox{\hyperlink{mdi_8c_ab73f32323a155011fcc184866215ba03}{MDI\_Recv}}(\&natoms, 1, \mbox{\hyperlink{mdi_8c_ab88e0bb1563ba9fa73ffc49a704e43ad}{MDI\_INT}}, mm\_comm);}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{comment}{// Allocate the arrays for the coordinates and forces}}
\DoxyCodeLine{\textcolor{keywordtype}{double} coords[3*natoms];}
\DoxyCodeLine{\textcolor{keywordtype}{double} forces[3*natoms];}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{comment}{// Have the MM engine initialize a new MD simulation}}
\DoxyCodeLine{\mbox{\hyperlink{mdi_8c_a3fa5769d2a6d0ad305fdaa12b048056e}{MDI\_Send\_command}}(\textcolor{stringliteral}{"@INIT\_MD"}, mm\_comm);}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{comment}{// Perform each iteration of the simulation}}
\DoxyCodeLine{\textcolor{keywordflow}{for} (\textcolor{keywordtype}{int} iiteration = 0; iiteration < niterations; iiteration++) \{}
\DoxyCodeLine{}
\DoxyCodeLine{  \textcolor{comment}{// Receive the coordinates from the MM engine}}
\DoxyCodeLine{  \mbox{\hyperlink{mdi_8c_a3fa5769d2a6d0ad305fdaa12b048056e}{MDI\_Send\_command}}(\textcolor{stringliteral}{"<COORDS"}, mm\_comm);}
\DoxyCodeLine{  \mbox{\hyperlink{mdi_8c_ab73f32323a155011fcc184866215ba03}{MDI\_Recv}}(\&coords, 3*natoms, \mbox{\hyperlink{mdi_8c_a3d0c16831c941e5b870461394bfe5c82}{MDI\_DOUBLE}}, mm\_comm);}
\DoxyCodeLine{}
\DoxyCodeLine{  \textcolor{comment}{// Send the coordinates to the QM engine}}
\DoxyCodeLine{  \mbox{\hyperlink{mdi_8c_a3fa5769d2a6d0ad305fdaa12b048056e}{MDI\_Send\_command}}(\textcolor{stringliteral}{">COORDS"}, qm\_comm);}
\DoxyCodeLine{  \mbox{\hyperlink{mdi_8c_a7bebce6d5fa91ee99a34fdcc5dcaedea}{MDI\_Send}}(\&coords, 3*natoms, \mbox{\hyperlink{mdi_8c_a3d0c16831c941e5b870461394bfe5c82}{MDI\_DOUBLE}}, qm\_comm);}
\DoxyCodeLine{}
\DoxyCodeLine{  \textcolor{comment}{// Have the MM engine proceed to the @FORCES node}}
\DoxyCodeLine{  \mbox{\hyperlink{mdi_8c_a3fa5769d2a6d0ad305fdaa12b048056e}{MDI\_Send\_command}}(\textcolor{stringliteral}{"@FORCES"}, mm\_comm);}
\DoxyCodeLine{}
\DoxyCodeLine{  \textcolor{comment}{// Get the QM energy}}
\DoxyCodeLine{  \mbox{\hyperlink{mdi_8c_a3fa5769d2a6d0ad305fdaa12b048056e}{MDI\_Send\_command}}(\textcolor{stringliteral}{"<ENERGY"}, qm\_comm);}
\DoxyCodeLine{  \mbox{\hyperlink{mdi_8c_ab73f32323a155011fcc184866215ba03}{MDI\_Recv}}(\&qm\_energy, 1, \mbox{\hyperlink{mdi_8c_a3d0c16831c941e5b870461394bfe5c82}{MDI\_DOUBLE}}, qm\_comm);}
\DoxyCodeLine{}
\DoxyCodeLine{  \textcolor{comment}{// Get the MM energy}}
\DoxyCodeLine{  \mbox{\hyperlink{mdi_8c_a3fa5769d2a6d0ad305fdaa12b048056e}{MDI\_Send\_command}}(\textcolor{stringliteral}{"<ENERGY"}, mm\_comm);}
\DoxyCodeLine{  \mbox{\hyperlink{mdi_8c_ab73f32323a155011fcc184866215ba03}{MDI\_Recv}}(\&mm\_energy, 1, \mbox{\hyperlink{mdi_8c_a3d0c16831c941e5b870461394bfe5c82}{MDI\_DOUBLE}}, mm\_comm);}
\DoxyCodeLine{}
\DoxyCodeLine{  \textcolor{comment}{// Receive the forces from the QM engine}}
\DoxyCodeLine{  \mbox{\hyperlink{mdi_8c_a3fa5769d2a6d0ad305fdaa12b048056e}{MDI\_Send\_command}}(\textcolor{stringliteral}{"<FORCES"}, qm\_comm);}
\DoxyCodeLine{  \mbox{\hyperlink{mdi_8c_ab73f32323a155011fcc184866215ba03}{MDI\_Recv}}(\&forces, 3*natoms, \mbox{\hyperlink{mdi_8c_a3d0c16831c941e5b870461394bfe5c82}{MDI\_DOUBLE}}, qm\_comm);}
\DoxyCodeLine{}
\DoxyCodeLine{  \textcolor{comment}{// Send the forces to the MM engine}}
\DoxyCodeLine{  \mbox{\hyperlink{mdi_8c_a3fa5769d2a6d0ad305fdaa12b048056e}{MDI\_Send\_command}}(\textcolor{stringliteral}{">FORCES"}, mm\_comm);}
\DoxyCodeLine{  \mbox{\hyperlink{mdi_8c_a7bebce6d5fa91ee99a34fdcc5dcaedea}{MDI\_Send}}(\&forces, 3*natoms, \mbox{\hyperlink{mdi_8c_a3d0c16831c941e5b870461394bfe5c82}{MDI\_DOUBLE}}, mm\_comm);}
\DoxyCodeLine{}
\DoxyCodeLine{  \textcolor{comment}{// Have the MM engine proceed to the @COORDS node, which completes the timestep}}
\DoxyCodeLine{  \mbox{\hyperlink{mdi_8c_a3fa5769d2a6d0ad305fdaa12b048056e}{MDI\_Send\_command}}(\textcolor{stringliteral}{"@COORDS"}, mm\_comm);}
\DoxyCodeLine{}
\DoxyCodeLine{  cout << \textcolor{stringliteral}{"timestep: "} << iiteration << \textcolor{stringliteral}{" "} << mm\_energy << \textcolor{stringliteral}{" "} << qm\_energy << endl;}
\DoxyCodeLine{\}}
\end{DoxyCode}


The above code does the following\+:
\begin{DoxyEnumerate}
\item Queries the number of atoms from the MM engine and allocates appropriately sized arrays for the coordinates and forces
\item Orders the MM engine to initialize a new MD simulation
\item Begins an iterative loop over MD iterations
\begin{DoxyEnumerate}
\item Receives the atomic coordinates from the MM engine and updates the QM engine with them
\item Receives the energy of the QM and MM systems
\item Receives the atomic forces from the QM engine and sends them to the MM engine
\item Orders the MM engine update the atomic coordinates
\end{DoxyEnumerate}
\end{DoxyEnumerate}

Finally, we should send an M\+DI command to cause the engines to exit. Replace the comment that reads "{\ttfamily // Send the \char`\"{}\+E\+X\+I\+T\char`\"{} command to each of the engines}" with the following\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{comment}{// Send the "EXIT" command to each of the engines}}
\DoxyCodeLine{\mbox{\hyperlink{mdi_8c_a3fa5769d2a6d0ad305fdaa12b048056e}{MDI\_Send\_command}}(\textcolor{stringliteral}{"EXIT"}, mm\_comm);}
\DoxyCodeLine{\mbox{\hyperlink{mdi_8c_a3fa5769d2a6d0ad305fdaa12b048056e}{MDI\_Send\_command}}(\textcolor{stringliteral}{"EXIT"}, qm\_comm);}
\end{DoxyCode}
\hypertarget{tutorials_compile_sec}{}\doxysubsection{Driver Compilation}\label{tutorials_compile_sec}
The cookiecutter came with everything you need to build with C\+Make. To compile, simply navigate to the directory where you want the driver to be built, then do the following, replacing "$<${\ttfamily driver\+\_\+top\+\_\+directory$>$"} with the path to top directory of your driver repository.


\begin{DoxyCode}{0}
\DoxyCodeLine{cmake <driver\_top\_directory>}
\DoxyCodeLine{make}
\end{DoxyCode}
\hypertarget{tutorials_tutorials_using_sec}{}\doxysubsection{Using the Driver}\label{tutorials_tutorials_using_sec}
To test the driver, you will need access to a QM engine and an MM engine. The \mbox{\hyperlink{tutorials_user_tutorial}{User Tutorial}} describes how to compile QE and L\+A\+M\+M\+PS for this purpose.

You will also need appropriate input files for a test simulation. The test files in the M\+D\+I\+\_\+\+A\+I\+M\+D\+\_\+\+Driver repository (see the \mbox{\hyperlink{tutorials_user_tutorial}{User Tutorial}}) will work fine, as will the scripts. You can simply edit M\+D\+I\+\_\+\+A\+I\+M\+D\+\_\+\+Driver/tests/locations/\+M\+D\+I\+\_\+\+A\+I\+M\+D\+\_\+\+Driver to point to your new repository and run the scripts in the manner described in the \mbox{\hyperlink{tutorials_user_tutorial}{User Tutorial}}.\hypertarget{tutorials_final_notes}{}\doxysubsection{Final Notes}\label{tutorials_final_notes}
Note that although we used QE as the QM code and L\+A\+M\+M\+PS as the MM code, we swap out QE for any QM engine with M\+DI support or L\+A\+M\+M\+PS for any MM engine with M\+DI support. Furthermore, nothing about our A\+I\+MD driver strictly requires that the code named \char`\"{}\+Q\+M\char`\"{} actually corresponds to a quantum mechanics code. You could, for example, use L\+A\+M\+M\+PS as the QM code, while another instance of L\+A\+M\+M\+PS serves as the MM code. Doing so would allow you to run a calculation that will produce to same results as simply running an MD simulation entirely within a single instance of L\+A\+M\+M\+PS. Although not generally useful for production runs, this can be a good way to benchmark the cost of the computational overhead introduced by using our driver as a middleman between two codes.

In other cases, it may be desirable to use two different MM codes as the engines if, for example, you wish to use a force field from one MM code and a thermostat from another MM code. The only requirement on the engines is that the \char`\"{}\+Q\+M\char`\"{} code supports all of the M\+DI commands sent by the A\+I\+MD driver to the \char`\"{}\+Q\+M\char`\"{} engine, and that the \char`\"{}\+M\+M\char`\"{} code supports all of the M\+DI commands sent by the A\+I\+MD driver to the \char`\"{}\+M\+M\char`\"{} engine. 