diff --git a/documentation/tutorials/14-Using_ASE_calcs.ipynb b/documentation/tutorials/14-Using_ASE_calcs.ipynb new file mode 100644 index 0000000..d83191b --- /dev/null +++ b/documentation/tutorials/14-Using_ASE_calcs.ipynb @@ -0,0 +1,210 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 14 - Using External ASE Objects (Calculators/Optimizers)\n", + "\n", + "### In this tutorial we will learn how to use external ASE calculators and optimizers within the architector framework.\n", + "\n", + "**(A)** Using arbitrary methods to perform energy/relaxations.\n", + "\n", + "**(B)** How to use example ASE calculator (MACE-MP-0) within Architector complex construction.\n", + "\n", + "**(C)** How to use arbirtrary ASE optimizers within Architector." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To get started - make sure to install the MACE-MP-0 package and model:\n", + "\n", + "See: https://github.com/ACEsuit/mace" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Now, load in the correct functions and model\n", + "from architector import build_complex, view_structures, convert_io_molecule\n", + "from mace.calculators import mace_mp # Import Mace ASE calculator\n", + "calc = mace_mp(model=\"medium\", dispersion=True,\n", + " default_dtype=\"float32\") # Instantiate the MACE calculator\n", + "from architector.io_calc import CalcExecutor # Calculation executor interface.\n", + "import numpy as np" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, Let's generate a structure (UFF) for an arbitary SMILES string and distort the coordinates by a random distance:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "arb_smiles = 'c1ccccc1CON'\n", + "mol = convert_io_molecule(arb_smiles)\n", + "mol.ase_atoms.set_positions(mol.ase_atoms.get_positions() + np.random.random(mol.ase_atoms.get_positions().shape) / 2)\n", + "view_structures(mol)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, To relax this structure we can use the `CalcExeuctor` interface with MACE-MP-0:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from ase.optimize import BFGS\n", + "out = CalcExecutor(mol,\n", + " relax=True, # Optimize the molecule\n", + " method='custom', # Use arbirtrary method.\n", + " calculator=calc, # Set the calc to be MACE-MP-0\n", + " ase_opt_method=BFGS, # Set ASE optimizer\n", + " save_trajectories=True, # Save the trajectories\n", + " debug=True) # Show the printout to verify it is using the methods asked for." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Now we can view the relaxation trajectory in its entirety\n", + "print('Relaxed')\n", + "view_structures(out.mol)\n", + "print('Trajectory')\n", + "view_structures(out.trajectory, trajectory=True, interval=600)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Also, the energy and initial energies, and any errors are stored in the output object\n", + "for key, val in out.__dict__.items():\n", + " if (key != 'parameters') and (key not in out.__dict__['parameters']):\n", + " print(key, ':', val)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## (B) Using arbirtrary ASE calculators to perform energy evaluations.\n", + "\n", + "Here, we can directly pluging calculators to the full architector search:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "inputDict = {'core':{'metal':'Fe','coreCN':6}, # Specify metal coordination number (CN)\n", + " 'ligands':['water']*6, # Specify what is filling the coordination environment\n", + " 'parameters':{'calculator':calc, # Assign ASE calculator \n", + " 'assemble_method':'UFF', # Use UFF for assembly\n", + " 'full_method':'custom'}} # Give 'custom' as a flag to use alternative calculator\n", + "fe_h2o_6_out = build_complex(inputDict); # Now just build using the dictionary!\n", + "view_structures(fe_h2o_6_out)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that Architector will assign the unpaired electrons to the ASE atoms object in the atoms\n", + "`initial magnetic moments` and the charges in the `initial charges` placeholders.\n", + "\n", + "Implementation of calculators may differ on whether this works or not." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## (C) Using arbirtrary ASE calculators to perform energy evaluations.\n", + "\n", + "Here, we can directly use other ASE optimizers as well, the default is LBFGSLineSearch. So Let's USE BFGS." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "inputDict = {'core':{'metal':'Fe','coreCN':1}, # Specify metal coordination number (CN)\n", + " 'ligands':['water'], # Specify what is filling the coordination environment\n", + " 'parameters':{'ase_opt_method':BFGS, # Directly pass the optimizer object\n", + " 'debug':True # Use debug to show that it is using BFGS instead of LBFGSLineSearch\n", + " }} \n", + "fe_h2o_out = build_complex(inputDict); # Now just build using the dictionary!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "view_structures(fe_h2o_out)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Summary: In this tutorial we learned how to use external ASE calculators and optimizers within the architector framework. Including:\n", + "\n", + "**(A)** Using arbitrary methods to perform energy/relaxations.\n", + "\n", + "**(B)** How to use example ASE calculator (MACE-MP-0) within Architector complex construction.\n", + "\n", + "**(C)** How to use arbirtrary ASE optimizers within Architector." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.12" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +}