From 0b73733c04ee1669f35b6c5cef161a81ed58f614 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Sat, 14 Sep 2024 00:24:54 +0200 Subject: [PATCH] Add alloy design example --- _toc.yml | 1 + book/inverse-alloy-design.ipynb | 678 +++++++++++++++++++++ environment.yml | 1 + langsim/tools/simulation_complex_alloys.py | 123 ++++ setup.py | 1 + 5 files changed, 804 insertions(+) create mode 100644 book/inverse-alloy-design.ipynb create mode 100644 langsim/tools/simulation_complex_alloys.py diff --git a/_toc.yml b/_toc.yml index f4fa2b0..36578d6 100644 --- a/_toc.yml +++ b/_toc.yml @@ -5,5 +5,6 @@ chapters: - file: book/first_agent.ipynb - file: book/energy_volume_curve.ipynb - file: book/demonstration.ipynb +- file: book/inverse-alloy-design.ipynb - file: book/Literature.md - file: book/Developer.md \ No newline at end of file diff --git a/book/inverse-alloy-design.ipynb b/book/inverse-alloy-design.ipynb new file mode 100644 index 0000000..4c094e6 --- /dev/null +++ b/book/inverse-alloy-design.ipynb @@ -0,0 +1,678 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a3fb43db-e147-4245-8c60-cbbb8fd349a6", + "metadata": {}, + "source": [ + "# Inverse Alloy Design\n", + "Inverse prediction of material properties is a key challenge in materials science. For the example the dependence of the bulk modulus on the concentration of an alloy, is typically evaluated by computing the bulk modulus for a given concentration. But the relevant material property is the bulk modulus, so we would like to predict the concentration which is required to achieve a specific bulk modulus. \n", + "\n", + "To demonstrate the application of LLMs for inverse alloy design, we extended the calculation of bulk moduli to complex alloys in solid solution. For computational efficiency we use 32-atom special quasi-random structures (SQS) to simulate solid solutions. " + ] + }, + { + "cell_type": "markdown", + "id": "cd197ca4-4184-48fc-9102-816118c6cb8a", + "metadata": {}, + "source": [ + "## Python Functions\n", + "Three python functions are defined, the `get_complex_alloy_bulk_structure()` function which creates the solid solution structure of the complex alloy by linear interpolation of the nearest neighbor distance, the `get_atom_dict_equilibrated_structure()` function which calculates the equilibrum volume and the `get_bulk_modulus()` function to compute the bulk modulus. All these functions are already included in the `LangSim` package to accelerate inverse alloy design." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "195a9cf8-8146-4ef7-b3ba-aee2bc045dbe", + "metadata": {}, + "outputs": [], + "source": [ + "from langsim.tools.simulation_atomistics import get_atom_dict_equilibrated_structure, get_bulk_modulus\n", + "from langsim.tools.simulation_complex_alloys import get_complex_alloy_bulk_structure" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "e47ad133-7a13-4248-91d1-b7bae906d5f1", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "e23ca046be824fb4aa5cb36ee75f290f", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "
\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "atoms_dict = get_complex_alloy_bulk_structure.invoke({\n",
+    "    \"element_lst\": [\"Ag\", \"Cu\", \"Au\"],\n",
+    "    \"concentration_lst\": [0.33, 0.33],\n",
+    "})"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "id": "b0c39b32-9000-485b-b8e6-0728d60a57d7",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "       Step     Time          Energy          fmax\n",
+      "LBFGS:    0 00:21:19        1.007380        0.896836\n",
+      "LBFGS:    1 00:21:19        0.903343        0.780359\n",
+      "LBFGS:    2 00:21:19        0.544874        0.264546\n",
+      "LBFGS:    3 00:21:19        0.527220        0.258248\n",
+      "LBFGS:    4 00:21:19        0.509179        0.241072\n",
+      "LBFGS:    5 00:21:19        0.491373        0.153396\n",
+      "LBFGS:    6 00:21:19        0.480369        0.112176\n",
+      "LBFGS:    7 00:21:19        0.475807        0.107402\n",
+      "LBFGS:    8 00:21:19        0.472776        0.099382\n",
+      "LBFGS:    9 00:21:19        0.468296        0.091074\n",
+      "LBFGS:   10 00:21:19        0.464523        0.081476\n",
+      "LBFGS:   11 00:21:19        0.462265        0.074352\n",
+      "LBFGS:   12 00:21:19        0.460756        0.069380\n",
+      "LBFGS:   13 00:21:19        0.458932        0.062557\n",
+      "LBFGS:   14 00:21:19        0.456936        0.053164\n",
+      "LBFGS:   15 00:21:19        0.455497        0.049564\n",
+      "LBFGS:   16 00:21:19        0.454711        0.045882\n",
+      "LBFGS:   17 00:21:19        0.454131        0.039608\n",
+      "LBFGS:   18 00:21:20        0.453530        0.031722\n",
+      "LBFGS:   19 00:21:20        0.453062        0.027557\n",
+      "LBFGS:   20 00:21:20        0.452794        0.028205\n",
+      "LBFGS:   21 00:21:20        0.452590        0.030223\n",
+      "LBFGS:   22 00:21:20        0.452320        0.032576\n",
+      "LBFGS:   23 00:21:20        0.451992        0.035186\n",
+      "LBFGS:   24 00:21:20        0.451695        0.037190\n",
+      "LBFGS:   25 00:21:20        0.451456        0.038254\n",
+      "LBFGS:   26 00:21:20        0.451201        0.039005\n",
+      "LBFGS:   27 00:21:20        0.450873        0.040006\n",
+      "LBFGS:   28 00:21:20        0.450541        0.041303\n",
+      "LBFGS:   29 00:21:20        0.450292        0.042402\n",
+      "LBFGS:   30 00:21:20        0.450084        0.043042\n",
+      "LBFGS:   31 00:21:20        0.449810        0.043279\n",
+      "LBFGS:   32 00:21:20        0.449411        0.042772\n",
+      "LBFGS:   33 00:21:20        0.448950        0.041127\n",
+      "LBFGS:   34 00:21:20        0.448534        0.046974\n",
+      "LBFGS:   35 00:21:20        0.448140        0.049969\n",
+      "LBFGS:   36 00:21:20        0.447635        0.039648\n",
+      "LBFGS:   37 00:21:20        0.446978        0.034771\n",
+      "LBFGS:   38 00:21:20        0.446364        0.037596\n",
+      "LBFGS:   39 00:21:20        0.445960        0.038526\n",
+      "LBFGS:   40 00:21:20        0.445677        0.037374\n",
+      "LBFGS:   41 00:21:20        0.445383        0.024933\n",
+      "LBFGS:   42 00:21:20        0.445088        0.021148\n",
+      "LBFGS:   43 00:21:20        0.444895        0.021190\n",
+      "LBFGS:   44 00:21:20        0.444795        0.018651\n",
+      "LBFGS:   45 00:21:21        0.444714        0.015303\n",
+      "LBFGS:   46 00:21:21        0.444616        0.011254\n",
+      "LBFGS:   47 00:21:21        0.444533        0.015541\n",
+      "LBFGS:   48 00:21:21        0.444488        0.014752\n",
+      "LBFGS:   49 00:21:21        0.444465        0.010743\n",
+      "LBFGS:   50 00:21:21        0.444443        0.006767\n",
+      "LBFGS:   51 00:21:21        0.444422        0.004974\n",
+      "LBFGS:   52 00:21:21        0.444409        0.004430\n",
+      "LBFGS:   53 00:21:21        0.444404        0.004274\n",
+      "LBFGS:   54 00:21:21        0.444399        0.004181\n",
+      "LBFGS:   55 00:21:21        0.444393        0.004022\n",
+      "LBFGS:   56 00:21:21        0.444386        0.003805\n",
+      "LBFGS:   57 00:21:21        0.444381        0.003912\n",
+      "LBFGS:   58 00:21:21        0.444376        0.003875\n",
+      "LBFGS:   59 00:21:21        0.444371        0.003459\n",
+      "LBFGS:   60 00:21:21        0.444365        0.003489\n",
+      "LBFGS:   61 00:21:21        0.444360        0.003123\n",
+      "LBFGS:   62 00:21:21        0.444357        0.003040\n",
+      "LBFGS:   63 00:21:21        0.444353        0.002993\n",
+      "LBFGS:   64 00:21:21        0.444348        0.002835\n",
+      "LBFGS:   65 00:21:21        0.444343        0.002883\n",
+      "LBFGS:   66 00:21:21        0.444339        0.002867\n",
+      "LBFGS:   67 00:21:21        0.444337        0.002907\n",
+      "LBFGS:   68 00:21:21        0.444334        0.002801\n",
+      "LBFGS:   69 00:21:21        0.444331        0.002609\n",
+      "LBFGS:   70 00:21:21        0.444327        0.003175\n",
+      "LBFGS:   71 00:21:21        0.444325        0.002719\n",
+      "LBFGS:   72 00:21:22        0.444324        0.001757\n",
+      "LBFGS:   73 00:21:22        0.444323        0.001392\n",
+      "LBFGS:   74 00:21:22        0.444322        0.001152\n",
+      "LBFGS:   75 00:21:22        0.444322        0.000907\n",
+      "LBFGS:   76 00:21:22        0.444321        0.000924\n",
+      "LBFGS:   77 00:21:22        0.444321        0.000726\n",
+      "LBFGS:   78 00:21:22        0.444321        0.000631\n",
+      "LBFGS:   79 00:21:22        0.444321        0.000614\n",
+      "LBFGS:   80 00:21:22        0.444321        0.000591\n",
+      "LBFGS:   81 00:21:22        0.444321        0.000572\n",
+      "LBFGS:   82 00:21:22        0.444321        0.000559\n",
+      "LBFGS:   83 00:21:22        0.444321        0.000542\n",
+      "LBFGS:   84 00:21:22        0.444321        0.000523\n",
+      "LBFGS:   85 00:21:22        0.444320        0.000508\n",
+      "LBFGS:   86 00:21:22        0.444320        0.000500\n",
+      "LBFGS:   87 00:21:22        0.444320        0.000491\n",
+      "LBFGS:   88 00:21:22        0.444320        0.000542\n",
+      "LBFGS:   89 00:21:22        0.444320        0.000564\n",
+      "LBFGS:   90 00:21:22        0.444320        0.000672\n",
+      "LBFGS:   91 00:21:22        0.444320        0.000644\n",
+      "LBFGS:   92 00:21:22        0.444320        0.000640\n",
+      "LBFGS:   93 00:21:22        0.444320        0.000569\n",
+      "LBFGS:   94 00:21:22        0.444319        0.000639\n",
+      "LBFGS:   95 00:21:22        0.444319        0.000737\n",
+      "LBFGS:   96 00:21:22        0.444319        0.000730\n",
+      "LBFGS:   97 00:21:23        0.444319        0.000647\n",
+      "LBFGS:   98 00:21:23        0.444319        0.000511\n",
+      "LBFGS:   99 00:21:23        0.444319        0.000500\n",
+      "LBFGS:  100 00:21:23        0.444318        0.000429\n",
+      "LBFGS:  101 00:21:23        0.444318        0.000358\n",
+      "LBFGS:  102 00:21:23        0.444318        0.000393\n",
+      "LBFGS:  103 00:21:23        0.444318        0.000426\n",
+      "LBFGS:  104 00:21:23        0.444318        0.000400\n",
+      "LBFGS:  105 00:21:23        0.444318        0.000449\n",
+      "LBFGS:  106 00:21:23        0.444318        0.000392\n",
+      "LBFGS:  107 00:21:23        0.444318        0.000295\n",
+      "LBFGS:  108 00:21:23        0.444318        0.000330\n",
+      "LBFGS:  109 00:21:23        0.444318        0.000318\n",
+      "LBFGS:  110 00:21:23        0.444318        0.000187\n",
+      "LBFGS:  111 00:21:23        0.444318        0.000156\n",
+      "LBFGS:  112 00:21:23        0.444318        0.000146\n",
+      "LBFGS:  113 00:21:23        0.444318        0.000136\n",
+      "LBFGS:  114 00:21:23        0.444318        0.000137\n",
+      "LBFGS:  115 00:21:23        0.444318        0.000125\n",
+      "LBFGS:  116 00:21:23        0.444318        0.000121\n",
+      "LBFGS:  117 00:21:23        0.444318        0.000116\n",
+      "LBFGS:  118 00:21:23        0.444318        0.000114\n",
+      "LBFGS:  119 00:21:23        0.444318        0.000113\n",
+      "LBFGS:  120 00:21:23        0.444318        0.000091\n",
+      "LBFGS:  121 00:21:23        0.444318        0.000092\n",
+      "LBFGS:  122 00:21:23        0.444318        0.000088\n",
+      "LBFGS:  123 00:21:23        0.444318        0.000074\n",
+      "LBFGS:  124 00:21:24        0.444318        0.000078\n",
+      "LBFGS:  125 00:21:24        0.444318        0.000076\n",
+      "LBFGS:  126 00:21:24        0.444318        0.000080\n",
+      "LBFGS:  127 00:21:24        0.444318        0.000091\n",
+      "LBFGS:  128 00:21:24        0.444318        0.000084\n",
+      "LBFGS:  129 00:21:24        0.444318        0.000073\n",
+      "LBFGS:  130 00:21:24        0.444318        0.000061\n",
+      "LBFGS:  131 00:21:24        0.444318        0.000056\n",
+      "LBFGS:  132 00:21:24        0.444318        0.000049\n",
+      "LBFGS:  133 00:21:24        0.444318        0.000044\n",
+      "LBFGS:  134 00:21:24        0.444318        0.000044\n",
+      "LBFGS:  135 00:21:24        0.444318        0.000032\n",
+      "LBFGS:  136 00:21:24        0.444318        0.000030\n",
+      "LBFGS:  137 00:21:24        0.444318        0.000026\n",
+      "LBFGS:  138 00:21:24        0.444318        0.000030\n",
+      "LBFGS:  139 00:21:24        0.444318        0.000027\n",
+      "LBFGS:  140 00:21:24        0.444318        0.000021\n",
+      "LBFGS:  141 00:21:24        0.444318        0.000016\n",
+      "LBFGS:  142 00:21:24        0.444318        0.000011\n",
+      "LBFGS:  143 00:21:24        0.444318        0.000010\n",
+      "LBFGS:  144 00:21:24        0.444318        0.000010\n",
+      "LBFGS:  145 00:21:24        0.444318        0.000009\n",
+      "LBFGS:  146 00:21:24        0.444318        0.000006\n",
+      "LBFGS:  147 00:21:24        0.444318        0.000005\n",
+      "LBFGS:  148 00:21:24        0.444318        0.000005\n",
+      "LBFGS:  149 00:21:24        0.444318        0.000004\n",
+      "LBFGS:  150 00:21:24        0.444318        0.000003\n",
+      "LBFGS:  151 00:21:25        0.444318        0.000002\n",
+      "LBFGS:  152 00:21:25        0.444318        0.000002\n",
+      "LBFGS:  153 00:21:25        0.444318        0.000002\n",
+      "LBFGS:  154 00:21:25        0.444318        0.000002\n",
+      "LBFGS:  155 00:21:25        0.444318        0.000001\n",
+      "LBFGS:  156 00:21:25        0.444318        0.000001\n",
+      "LBFGS:  157 00:21:25        0.444318        0.000001\n",
+      "LBFGS:  158 00:21:25        0.444318        0.000001\n",
+      "LBFGS:  159 00:21:25        0.444318        0.000001\n",
+      "LBFGS:  160 00:21:25        0.444318        0.000001\n",
+      "LBFGS:  161 00:21:25        0.444318        0.000001\n",
+      "LBFGS:  162 00:21:25        0.444318        0.000001\n",
+      "LBFGS:  163 00:21:25        0.444318        0.000001\n",
+      "LBFGS:  164 00:21:25        0.444318        0.000001\n",
+      "LBFGS:  165 00:21:25        0.444318        0.000001\n",
+      "LBFGS:  166 00:21:25        0.444318        0.000001\n",
+      "LBFGS:  167 00:21:25        0.444318        0.000001\n"
+     ]
+    }
+   ],
+   "source": [
+    "atoms_equilibrated_dict = get_atom_dict_equilibrated_structure.invoke({\n",
+    "    \"atom_dict\": atoms_dict, \n",
+    "    \"calculator_str\": \"emt\",\n",
+    "})"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "id": "cfe597a4-b563-41f6-8ca4-966d2ff2cade",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "130.37777754206886"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "get_bulk_modulus.invoke({\n",
+    "    \"atom_dict\": atoms_equilibrated_dict, \n",
+    "    \"calculator_str\": \"emt\"\n",
+    "})"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "b0f82c61-0098-4316-ba98-88bc5f24d6d3",
+   "metadata": {},
+   "source": [
+    "## Agent\n",
+    "The agent follows the same [custom agent](https://python.langchain.com/v0.1/docs/modules/agents/how_to/custom_agent/) langchain tutorial like the previous examples. This highlights that no complex modifications to the prompt are required."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "id": "5e8704fa-5a34-4f8a-9c42-d81fbc197d45",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from getpass import getpass"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "id": "8bd2aa7d-335c-4f51-a5d0-363d339c9e73",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from langchain.agents import AgentExecutor\n",
+    "from langchain.agents.format_scratchpad.openai_tools import format_to_openai_tool_messages\n",
+    "from langchain.agents.output_parsers.openai_tools import OpenAIToolsAgentOutputParser\n",
+    "from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder\n",
+    "from langchain_openai import ChatOpenAI"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "id": "1a294773-f33b-4708-9a08-09fb495da43c",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdin",
+     "output_type": "stream",
+     "text": [
+      "Enter your OpenAI Token: ········\n"
+     ]
+    }
+   ],
+   "source": [
+    "OPENAI_API_KEY = getpass(prompt='Enter your OpenAI Token:')\n",
+    "llm = ChatOpenAI(model=\"gpt-4o\", temperature=0, openai_api_key=OPENAI_API_KEY)\n",
+    "tools = [get_complex_alloy_bulk_structure, get_atom_dict_equilibrated_structure, get_bulk_modulus]\n",
+    "prompt = ChatPromptTemplate.from_messages(\n",
+    "    [\n",
+    "        (\n",
+    "            \"system\",\n",
+    "            \"You are very powerful assistant, but don't know current events. For each query vailidate that it contains a chemical element and otherwise cancel.\",\n",
+    "        ),\n",
+    "        (\"user\", \"{input}\"),\n",
+    "        MessagesPlaceholder(variable_name=\"agent_scratchpad\"),\n",
+    "    ]\n",
+    ")\n",
+    "agent = (\n",
+    "    {\n",
+    "        \"input\": lambda x: x[\"input\"],\n",
+    "        \"agent_scratchpad\": lambda x: format_to_openai_tool_messages(\n",
+    "            x[\"intermediate_steps\"]\n",
+    "        ),\n",
+    "    }\n",
+    "    | prompt\n",
+    "    | llm.bind_tools(tools)\n",
+    "    | OpenAIToolsAgentOutputParser()\n",
+    ")\n",
+    "agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "abba152d-81d4-4400-96b3-a3e860608089",
+   "metadata": {},
+   "source": [
+    "## Dialog\n",
+    "Finally, the agent is tasked to find the alloy concentration of an Copper Gold alloy which matches the bulk modulus of 145GPa with in an error bound of 2GPa. In addition, it received the hint to use linear interpolation rather than random sampling or other strategies to find the desired concentration.  "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "id": "5539e01a-e755-419c-92b9-19b8b386afbc",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\n",
+      "\n",
+      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
+      "\u001b[32;1m\u001b[1;3m\n",
+      "Invoking: `get_complex_alloy_bulk_structure` with `{'element_lst': ['Cu'], 'concentration_lst': [1.0], 'number_of_atoms': 32, 'crystal_structure': 'fcc'}`\n",
+      "responded: Sure, let's start by validating the presence of chemical elements in your query. You mentioned Copper (Cu) and Gold (Au), which are valid chemical elements.\n",
+      "\n",
+      "Next, we'll use linear interpolation to estimate the concentration of a Cu-Au alloy with a bulk modulus around 145 GPa using the EMT simulation code. We'll then validate this prediction by computing the bulk modulus and iterating until we achieve the desired accuracy.\n",
+      "\n",
+      "### Step 1: Define the initial concentrations and compute their bulk moduli\n",
+      "\n",
+      "We'll start with two initial concentrations:\n",
+      "1. Pure Copper (100% Cu, 0% Au)\n",
+      "2. Pure Gold (0% Cu, 100% Au)\n",
+      "\n",
+      "Let's compute the bulk moduli for these initial concentrations using the EMT simulation code.\n",
+      "\n",
+      "\u001b[0m\u001b[36;1m\u001b[1;3mnumbers=[13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13] positions=[[0.0, 0.0, 0.0], [0.0, 1.805, 1.805], [1.805, 0.0, 1.805], [1.805, 1.805, 0.0], [0.0, 0.0, 3.61], [0.0, 1.805, 5.415], [1.805, 0.0, 5.415], [1.805, 1.805, 3.61], [0.0, 3.61, 0.0], [0.0, 5.415, 1.805], [1.805, 3.61, 1.805], [1.805, 5.415, 0.0], [0.0, 3.61, 3.61], [0.0, 5.415, 5.415], [1.805, 3.61, 5.415], [1.805, 5.415, 3.61], [3.61, 0.0, 0.0], [3.61, 1.805, 1.805], [5.415, 0.0, 1.805], [5.415, 1.805, 0.0], [3.61, 0.0, 3.61], [3.61, 1.805, 5.415], [5.415, 0.0, 5.415], [5.415, 1.805, 3.61], [3.61, 3.61, 0.0], [3.61, 5.415, 1.805], [5.415, 3.61, 1.805], [5.415, 5.415, 0.0], [3.61, 3.61, 3.61], [3.61, 5.415, 5.415], [5.415, 3.61, 5.415], [5.415, 5.415, 3.61]] cell=[[7.22, 0.0, 0.0], [0.0, 7.22, 0.0], [0.0, 0.0, 7.22]] pbc=[True, True, True]\u001b[0m\u001b[32;1m\u001b[1;3m\n",
+      "Invoking: `get_complex_alloy_bulk_structure` with `{'element_lst': ['Au'], 'concentration_lst': [1.0], 'number_of_atoms': 32, 'crystal_structure': 'fcc'}`\n",
+      "responded: Sure, let's start by validating the presence of chemical elements in your query. You mentioned Copper (Cu) and Gold (Au), which are valid chemical elements.\n",
+      "\n",
+      "Next, we'll use linear interpolation to estimate the concentration of a Cu-Au alloy with a bulk modulus around 145 GPa using the EMT simulation code. We'll then validate this prediction by computing the bulk modulus and iterating until we achieve the desired accuracy.\n",
+      "\n",
+      "### Step 1: Define the initial concentrations and compute their bulk moduli\n",
+      "\n",
+      "We'll start with two initial concentrations:\n",
+      "1. Pure Copper (100% Cu, 0% Au)\n",
+      "2. Pure Gold (0% Cu, 100% Au)\n",
+      "\n",
+      "Let's compute the bulk moduli for these initial concentrations using the EMT simulation code.\n",
+      "\n",
+      "\u001b[0m\u001b[36;1m\u001b[1;3mnumbers=[13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13] positions=[[0.0, 0.0, 0.0], [0.0, 2.04, 2.04], [2.04, 0.0, 2.04], [2.04, 2.04, 0.0], [0.0, 0.0, 4.08], [0.0, 2.04, 6.12], [2.04, 0.0, 6.12], [2.04, 2.04, 4.08], [0.0, 4.08, 0.0], [0.0, 6.12, 2.04], [2.04, 4.08, 2.04], [2.04, 6.12, 0.0], [0.0, 4.08, 4.08], [0.0, 6.12, 6.12], [2.04, 4.08, 6.12], [2.04, 6.12, 4.08], [4.08, 0.0, 0.0], [4.08, 2.04, 2.04], [6.12, 0.0, 2.04], [6.12, 2.04, 0.0], [4.08, 0.0, 4.08], [4.08, 2.04, 6.12], [6.12, 0.0, 6.12], [6.12, 2.04, 4.08], [4.08, 4.08, 0.0], [4.08, 6.12, 2.04], [6.12, 4.08, 2.04], [6.12, 6.12, 0.0], [4.08, 4.08, 4.08], [4.08, 6.12, 6.12], [6.12, 4.08, 6.12], [6.12, 6.12, 4.08]] cell=[[8.16, 0.0, 0.0], [0.0, 8.16, 0.0], [0.0, 0.0, 8.16]] pbc=[True, True, True]\u001b[0m\u001b[32;1m\u001b[1;3m\n",
+      "Invoking: `get_atom_dict_equilibrated_structure` with `{'atom_dict': {'numbers': [29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29], 'positions': [[0.0, 0.0, 0.0], [0.0, 1.805, 1.805], [1.805, 0.0, 1.805], [1.805, 1.805, 0.0], [0.0, 0.0, 3.61], [0.0, 1.805, 5.415], [1.805, 0.0, 5.415], [1.805, 1.805, 3.61], [0.0, 3.61, 0.0], [0.0, 5.415, 1.805], [1.805, 3.61, 1.805], [1.805, 5.415, 0.0], [0.0, 3.61, 3.61], [0.0, 5.415, 5.415], [1.805, 3.61, 5.415], [1.805, 5.415, 3.61], [3.61, 0.0, 0.0], [3.61, 1.805, 1.805], [5.415, 0.0, 1.805], [5.415, 1.805, 0.0], [3.61, 0.0, 3.61], [3.61, 1.805, 5.415], [5.415, 0.0, 5.415], [5.415, 1.805, 3.61], [3.61, 3.61, 0.0], [3.61, 5.415, 1.805], [5.415, 3.61, 1.805], [5.415, 5.415, 0.0], [3.61, 3.61, 3.61], [3.61, 5.415, 5.415], [5.415, 3.61, 5.415], [5.415, 5.415, 3.61]], 'cell': [[7.22, 0.0, 0.0], [0.0, 7.22, 0.0], [0.0, 0.0, 7.22]], 'pbc': [True, True, True]}, 'calculator_str': 'emt'}`\n",
+      "\n",
+      "\n",
+      "\u001b[0m       Step     Time          Energy          fmax\n",
+      "LBFGS:    0 00:21:46       -0.181808        0.160183\n",
+      "LBFGS:    1 00:21:46       -0.182901        0.158188\n",
+      "LBFGS:    2 00:21:46       -0.225134        0.004528\n",
+      "LBFGS:    3 00:21:46       -0.225168        0.000123\n",
+      "LBFGS:    4 00:21:46       -0.225168        0.000000\n",
+      "\u001b[33;1m\u001b[1;3mnumbers=[29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29] positions=[[6.761801057876339e-16, 2.4178592947955473e-15, -3.696205154607726e-15], [2.362265601281247e-15, 1.7949128008674702, 1.794912800867473], [1.794912800867468, 6.295993829604061e-15, 1.7949128008674684], [1.7949128008674664, 1.7949128008674673, 2.178736226937247e-15], [-4.052659683212801e-15, -7.250244798076016e-16, 3.589825601734939], [1.9048356294552537e-15, 1.7949128008674733, 5.384738402602442], [1.794912800867467, 8.597570995802812e-15, 5.384738402602447], [1.794912800867472, 1.7949128008674635, 3.5898256017349444], [9.298328874081624e-16, 3.589825601734933, -3.323078787730939e-15], [-3.041708126507229e-15, 5.384738402602446, 1.7949128008674713], [1.7949128008674673, 3.589825601734951, 1.7949128008674664], [1.7949128008674717, 5.384738402602446, 4.766586294737296e-15], [6.043692340833827e-15, 3.5898256017349484, 3.589825601734948], [3.067145173531617e-15, 5.384738402602432, 5.384738402602436], [1.794912800867466, 3.5898256017349444, 5.384738402602436], [1.7949128008674617, 5.384738402602442, 3.58982560173494], [3.5898256017349275, 5.841702500885102e-15, -9.874153064309176e-16], [3.5898256017349386, 1.7949128008674704, 1.7949128008674662], [5.384738402602439, -7.622611728751917e-16, 1.794912800867471], [5.384738402602442, 1.7949128008674675, 2.500162875281997e-15], [3.5898256017349386, 2.502593039137387e-15, 3.5898256017349426], [3.5898256017349413, 1.7949128008674726, 5.384738402602438], [5.3847384026024345, 8.606035168920653e-16, 5.384738402602437], [5.384738402602433, 1.794912800867463, 3.5898256017349404], [3.589825601734946, 3.5898256017349426, -1.7390314304769608e-15], [3.589825601734946, 5.384738402602441, 1.7949128008674675], [5.384738402602442, 3.5898256017349497, 1.7949128008674708], [5.384738402602438, 5.384738402602439, 8.989257719002385e-16], [3.5898256017349524, 3.589825601734952, 3.589825601734947], [3.5898256017349346, 5.384738402602433, 5.38473840260243], [5.384738402602431, 3.5898256017349417, 5.3847384026024345], [5.384738402602436, 5.384738402602435, 3.589825601734939]] cell=[[7.1796512034698905, 9.5626712638785e-17, -6.159891355103644e-17], [9.5626712638785e-17, 7.17965120346989, 1.1161347749589607e-16], [-6.159891355103644e-17, 1.1161347749589607e-16, 7.1796512034698905]] pbc=[True, True, True]\u001b[0m\u001b[32;1m\u001b[1;3m\n",
+      "Invoking: `get_atom_dict_equilibrated_structure` with `{'atom_dict': {'numbers': [79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79], 'positions': [[0.0, 0.0, 0.0], [0.0, 2.04, 2.04], [2.04, 0.0, 2.04], [2.04, 2.04, 0.0], [0.0, 0.0, 4.08], [0.0, 2.04, 6.12], [2.04, 0.0, 6.12], [2.04, 2.04, 4.08], [0.0, 4.08, 0.0], [0.0, 6.12, 2.04], [2.04, 4.08, 2.04], [2.04, 6.12, 0.0], [0.0, 4.08, 4.08], [0.0, 6.12, 6.12], [2.04, 4.08, 6.12], [2.04, 6.12, 4.08], [4.08, 0.0, 0.0], [4.08, 2.04, 2.04], [6.12, 0.0, 2.04], [6.12, 2.04, 0.0], [4.08, 0.0, 4.08], [4.08, 2.04, 6.12], [6.12, 0.0, 6.12], [6.12, 2.04, 4.08], [4.08, 4.08, 0.0], [4.08, 6.12, 2.04], [6.12, 4.08, 2.04], [6.12, 6.12, 0.0], [4.08, 4.08, 4.08], [4.08, 6.12, 6.12], [6.12, 4.08, 6.12], [6.12, 6.12, 4.08]], 'cell': [[8.16, 0.0, 0.0], [0.0, 8.16, 0.0], [0.0, 0.0, 8.16]], 'pbc': [True, True, True]}, 'calculator_str': 'emt'}`\n",
+      "\n",
+      "\n",
+      "\u001b[0m       Step     Time          Energy          fmax\n",
+      "LBFGS:    0 00:21:46        0.083403        0.308859\n",
+      "LBFGS:    1 00:21:46        0.079361        0.301843\n",
+      "LBFGS:    2 00:21:46       -0.004187        0.012561\n",
+      "LBFGS:    3 00:21:46       -0.004324        0.000480\n",
+      "LBFGS:    4 00:21:46       -0.004325        0.000001\n",
+      "\u001b[33;1m\u001b[1;3mnumbers=[79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79] positions=[[-1.1519732493423534e-14, -4.902671923156848e-15, -3.691244571156717e-15], [-3.3083661695160288e-15, 2.028082836101837, 2.0280828361018366], [2.0280828361018353, -7.266830256967577e-15, 2.028082836101836], [2.028082836101835, 2.0280828361018326, -3.4869213003831076e-15], [-1.1809075014158814e-15, -1.7534273740802401e-15, 4.056165672203671], [-1.2936452033234147e-15, 2.028082836101836, 6.084248508305483], [2.0280828361018344, 1.0859220153152102e-15, 6.084248508305481], [2.028082836101836, 2.0280828361018353, 4.056165672203671], [-4.212746448640245e-15, 4.056165672203668, -2.488512553310913e-15], [-2.595176344938955e-15, 6.084248508305482, 2.028082836101836], [2.0280828361018357, 4.056165672203668, 2.028082836101835], [2.028082836101834, 6.084248508305484, -3.88520256151608e-15], [3.0730356068103296e-15, 4.05616567220367, 4.0561656722036705], [-2.5181968161173974e-16, 6.084248508305483, 6.0842485083054845], [2.028082836101837, 4.056165672203671, 6.084248508305483], [2.028082836101835, 6.08424850830548, 4.0561656722036705], [4.056165672203667, -3.1698249517704123e-15, -1.875758814596068e-15], [4.056165672203672, 2.0280828361018353, 2.0280828361018357], [6.084248508305481, -4.234210017286284e-15, 2.028082836101836], [6.084248508305482, 2.0280828361018353, -3.3188348477751644e-15], [4.056165672203665, -4.1636148734447415e-15, 4.056165672203671], [4.0561656722036705, 2.0280828361018357, 6.084248508305482], [6.084248508305485, -3.553000959590537e-15, 6.084248508305483], [6.084248508305481, 2.0280828361018344, 4.056165672203671], [4.056165672203667, 4.056165672203669, -3.2761394733216216e-15], [4.05616567220367, 6.084248508305483, 2.028082836101835], [6.084248508305481, 4.056165672203667, 2.0280828361018357], [6.084248508305481, 6.0842485083054845, -4.359711787996257e-15], [4.0561656722036705, 4.056165672203667, 4.05616567220367], [4.056165672203672, 6.084248508305484, 6.084248508305485], [6.084248508305482, 4.0561656722036705, 6.084248508305484], [6.084248508305481, 6.0842485083054845, 4.056165672203671]] cell=[[8.112331344407348, 9.540810667674625e-17, 4.2647505813391163e-17], [9.540810667674625e-17, 8.112331344407348, 4.591294021663726e-17], [4.2647505813391163e-17, 4.591294021663726e-17, 8.112331344407348]] pbc=[True, True, True]\u001b[0m\u001b[32;1m\u001b[1;3m\n",
+      "Invoking: `get_bulk_modulus` with `{'atom_dict': {'numbers': [29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29], 'positions': [[6.761801057876339e-16, 2.4178592947955473e-15, -3.696205154607726e-15], [2.362265601281247e-15, 1.7949128008674702, 1.794912800867473], [1.794912800867468, 6.295993829604061e-15, 1.7949128008674684], [1.7949128008674664, 1.7949128008674673, 2.178736226937247e-15], [-4.052659683212801e-15, -7.250244798076016e-16, 3.589825601734939], [1.9048356294552537e-15, 1.7949128008674733, 5.384738402602442], [1.794912800867467, 8.597570995802812e-15, 5.384738402602447], [1.794912800867472, 1.7949128008674635, 3.5898256017349444], [9.298328874081624e-16, 3.589825601734933, -3.323078787730939e-15], [-3.041708126507229e-15, 5.384738402602446, 1.7949128008674713], [1.7949128008674673, 3.589825601734951, 1.7949128008674664], [1.7949128008674717, 5.384738402602446, 4.766586294737296e-15], [6.043692340833827e-15, 3.5898256017349484, 3.589825601734948], [3.067145173531617e-15, 5.384738402602432, 5.384738402602436], [1.794912800867466, 3.5898256017349444, 5.384738402602436], [1.7949128008674617, 5.384738402602442, 3.58982560173494], [3.5898256017349275, 5.841702500885102e-15, -9.874153064309176e-16], [3.5898256017349386, 1.7949128008674704, 1.7949128008674662], [5.384738402602439, -7.622611728751917e-16, 1.794912800867471], [5.384738402602442, 1.7949128008674675, 2.500162875281997e-15], [3.5898256017349386, 2.502593039137387e-15, 3.5898256017349426], [3.5898256017349413, 1.7949128008674726, 5.384738402602438], [5.3847384026024345, 8.606035168920653e-16, 5.384738402602437], [5.384738402602433, 1.794912800867463, 3.5898256017349404], [3.589825601734946, 3.5898256017349426, -1.7390314304769608e-15], [3.589825601734946, 5.384738402602441, 1.7949128008674675], [5.384738402602442, 3.5898256017349497, 1.7949128008674708], [5.384738402602438, 5.384738402602439, 8.989257719002385e-16], [3.5898256017349524, 3.589825601734952, 3.589825601734947], [3.5898256017349346, 5.384738402602433, 5.38473840260243], [5.384738402602431, 3.5898256017349417, 5.3847384026024345], [5.384738402602436, 5.384738402602435, 3.589825601734939]], 'cell': [[7.1796512034698905, 9.5626712638785e-17, -6.159891355103644e-17], [9.5626712638785e-17, 7.17965120346989, 1.1161347749589607e-16], [-6.159891355103644e-17, 1.1161347749589607e-16, 7.1796512034698905]], 'pbc': [True, True, True]}, 'calculator_str': 'emt'}`\n",
+      "\n",
+      "\n",
+      "\u001b[0m\u001b[38;5;200m\u001b[1;3m134.48270768727988\u001b[0m\u001b[32;1m\u001b[1;3m\n",
+      "Invoking: `get_bulk_modulus` with `{'atom_dict': {'numbers': [79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79], 'positions': [[-1.1519732493423534e-14, -4.902671923156848e-15, -3.691244571156717e-15], [-3.3083661695160288e-15, 2.028082836101837, 2.0280828361018366], [2.0280828361018353, -7.266830256967577e-15, 2.028082836101836], [2.028082836101835, 2.0280828361018326, -3.4869213003831076e-15], [-1.1809075014158814e-15, -1.7534273740802401e-15, 4.056165672203671], [-1.2936452033234147e-15, 2.028082836101836, 6.084248508305483], [2.0280828361018344, 1.0859220153152102e-15, 6.084248508305481], [2.028082836101836, 2.0280828361018353, 4.056165672203671], [-4.212746448640245e-15, 4.056165672203668, -2.488512553310913e-15], [-2.595176344938955e-15, 6.084248508305482, 2.028082836101836], [2.0280828361018357, 4.056165672203668, 2.028082836101835], [2.028082836101834, 6.084248508305484, -3.88520256151608e-15], [3.0730356068103296e-15, 4.05616567220367, 4.0561656722036705], [-2.5181968161173974e-16, 6.084248508305483, 6.0842485083054845], [2.028082836101837, 4.056165672203671, 6.084248508305483], [2.028082836101835, 6.08424850830548, 4.0561656722036705], [4.056165672203667, -3.1698249517704123e-15, -1.875758814596068e-15], [4.056165672203672, 2.0280828361018353, 2.0280828361018357], [6.084248508305481, -4.234210017286284e-15, 2.028082836101836], [6.084248508305482, 2.0280828361018353, -3.3188348477751644e-15], [4.056165672203665, -4.1636148734447415e-15, 4.056165672203671], [4.0561656722036705, 2.0280828361018357, 6.084248508305482], [6.084248508305485, -3.553000959590537e-15, 6.084248508305483], [6.084248508305481, 2.0280828361018344, 4.056165672203671], [4.056165672203667, 4.056165672203669, -3.2761394733216216e-15], [4.05616567220367, 6.084248508305483, 2.028082836101835], [6.084248508305481, 4.056165672203667, 2.0280828361018357], [6.084248508305481, 6.0842485083054845, -4.359711787996257e-15], [4.0561656722036705, 4.056165672203667, 4.05616567220367], [4.056165672203672, 6.084248508305484, 6.084248508305485], [6.084248508305482, 4.0561656722036705, 6.084248508305484], [6.084248508305481, 6.0842485083054845, 4.056165672203671]], 'cell': [[8.112331344407348, 9.540810667674625e-17, 4.2647505813391163e-17], [9.540810667674625e-17, 8.112331344407348, 4.591294021663726e-17], [4.2647505813391163e-17, 4.591294021663726e-17, 8.112331344407348]], 'pbc': [True, True, True]}, 'calculator_str': 'emt'}`\n",
+      "\n",
+      "\n",
+      "\u001b[0m\u001b[38;5;200m\u001b[1;3m173.83830457333295\u001b[0m\u001b[32;1m\u001b[1;3m\n",
+      "Invoking: `get_complex_alloy_bulk_structure` with `{'element_lst': ['Cu', 'Au'], 'concentration_lst': [0.738, 0.262], 'number_of_atoms': 32, 'crystal_structure': 'fcc'}`\n",
+      "responded: The bulk moduli for the pure elements are as follows:\n",
+      "- Pure Copper (100% Cu, 0% Au): 134.48 GPa\n",
+      "- Pure Gold (0% Cu, 100% Au): 173.84 GPa\n",
+      "\n",
+      "### Step 2: Linear Interpolation\n",
+      "\n",
+      "Using linear interpolation, we can estimate the concentration of Cu and Au that would give us a bulk modulus around 145 GPa.\n",
+      "\n",
+      "The linear interpolation formula is:\n",
+      "\\[ B = B_{\\text{Cu}} \\cdot x + B_{\\text{Au}} \\cdot (1 - x) \\]\n",
+      "where:\n",
+      "- \\( B \\) is the target bulk modulus (145 GPa)\n",
+      "- \\( B_{\\text{Cu}} \\) is the bulk modulus of pure Copper (134.48 GPa)\n",
+      "- \\( B_{\\text{Au}} \\) is the bulk modulus of pure Gold (173.84 GPa)\n",
+      "- \\( x \\) is the concentration of Copper\n",
+      "\n",
+      "Rearranging the formula to solve for \\( x \\):\n",
+      "\\[ x = \\frac{B - B_{\\text{Au}}}{B_{\\text{Cu}} - B_{\\text{Au}}} \\]\n",
+      "\n",
+      "Substituting the values:\n",
+      "\\[ x = \\frac{145 - 173.84}{134.48 - 173.84} \\approx 0.738 \\]\n",
+      "\n",
+      "So, the estimated concentration is approximately 73.8% Copper and 26.2% Gold.\n",
+      "\n",
+      "### Step 3: Validate the Prediction\n",
+      "\n",
+      "Let's create a Cu-Au alloy with 73.8% Cu and 26.2% Au and compute its bulk modulus to validate our prediction.\n",
+      "\n",
+      "\u001b[0m\u001b[36;1m\u001b[1;3mnumbers=[29, 29, 29, 29, 29, 79, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 79, 79, 29, 79, 29, 29, 29, 29, 79, 29, 79, 79, 79, 29, 29] positions=[[0.0, 0.0, 0.0], [0.0, 1.86375, 1.86375], [1.86375, 0.0, 1.86375], [1.86375, 1.86375, 0.0], [0.0, 0.0, 3.7275], [0.0, 1.86375, 5.5912500000000005], [1.86375, 0.0, 5.5912500000000005], [1.86375, 1.86375, 3.7275], [0.0, 3.7275, 0.0], [0.0, 5.5912500000000005, 1.86375], [1.86375, 3.7275, 1.86375], [1.86375, 5.5912500000000005, 0.0], [0.0, 3.7275, 3.7275], [0.0, 5.5912500000000005, 5.5912500000000005], [1.86375, 3.7275, 5.5912500000000005], [1.86375, 5.5912500000000005, 3.7275], [3.7275, 0.0, 0.0], [3.7275, 1.86375, 1.86375], [5.5912500000000005, 0.0, 1.86375], [5.5912500000000005, 1.86375, 0.0], [3.7275, 0.0, 3.7275], [3.7275, 1.86375, 5.5912500000000005], [5.5912500000000005, 0.0, 5.5912500000000005], [5.5912500000000005, 1.86375, 3.7275], [3.7275, 3.7275, 0.0], [3.7275, 5.5912500000000005, 1.86375], [5.5912500000000005, 3.7275, 1.86375], [5.5912500000000005, 5.5912500000000005, 0.0], [3.7275, 3.7275, 3.7275], [3.7275, 5.5912500000000005, 5.5912500000000005], [5.5912500000000005, 3.7275, 5.5912500000000005], [5.5912500000000005, 5.5912500000000005, 3.7275]] cell=[[7.455, 0.0, 0.0], [0.0, 7.455, 0.0], [0.0, 0.0, 7.455]] pbc=[True, True, True]\u001b[0m\u001b[32;1m\u001b[1;3m\n",
+      "Invoking: `get_atom_dict_equilibrated_structure` with `{'atom_dict': {'numbers': [29, 29, 29, 29, 29, 79, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 79, 79, 29, 79, 29, 29, 29, 29, 79, 29, 79, 79, 79, 29, 29], 'positions': [[0.0, 0.0, 0.0], [0.0, 1.86375, 1.86375], [1.86375, 0.0, 1.86375], [1.86375, 1.86375, 0.0], [0.0, 0.0, 3.7275], [0.0, 1.86375, 5.5912500000000005], [1.86375, 0.0, 5.5912500000000005], [1.86375, 1.86375, 3.7275], [0.0, 3.7275, 0.0], [0.0, 5.5912500000000005, 1.86375], [1.86375, 3.7275, 1.86375], [1.86375, 5.5912500000000005, 0.0], [0.0, 3.7275, 3.7275], [0.0, 5.5912500000000005, 5.5912500000000005], [1.86375, 3.7275, 5.5912500000000005], [1.86375, 5.5912500000000005, 3.7275], [3.7275, 0.0, 0.0], [3.7275, 1.86375, 1.86375], [5.5912500000000005, 0.0, 1.86375], [5.5912500000000005, 1.86375, 0.0], [3.7275, 0.0, 3.7275], [3.7275, 1.86375, 5.5912500000000005], [5.5912500000000005, 0.0, 5.5912500000000005], [5.5912500000000005, 1.86375, 3.7275], [3.7275, 3.7275, 0.0], [3.7275, 5.5912500000000005, 1.86375], [5.5912500000000005, 3.7275, 1.86375], [5.5912500000000005, 5.5912500000000005, 0.0], [3.7275, 3.7275, 3.7275], [3.7275, 5.5912500000000005, 5.5912500000000005], [5.5912500000000005, 3.7275, 5.5912500000000005], [5.5912500000000005, 5.5912500000000005, 3.7275]], 'cell': [[7.455, 0.0, 0.0], [0.0, 7.455, 0.0], [0.0, 0.0, 7.455]], 'pbc': [True, True, True]}, 'calculator_str': 'emt'}`\n",
+      "\n",
+      "\n",
+      "\u001b[0m       Step     Time          Energy          fmax\n",
+      "LBFGS:    0 00:22:32        0.850844        1.736425\n",
+      "LBFGS:    1 00:22:32        0.635428        1.213269\n",
+      "LBFGS:    2 00:22:32        0.227974        0.370944\n",
+      "LBFGS:    3 00:22:32        0.185397        0.317658\n",
+      "LBFGS:    4 00:22:32        0.164019        0.284805\n",
+      "LBFGS:    5 00:22:32        0.148797        0.176572\n",
+      "LBFGS:    6 00:22:32        0.140858        0.116491\n",
+      "LBFGS:    7 00:22:32        0.138416        0.089204\n",
+      "LBFGS:    8 00:22:32        0.136854        0.086968\n",
+      "LBFGS:    9 00:22:32        0.134539        0.082794\n",
+      "LBFGS:   10 00:22:33        0.132702        0.078528\n",
+      "LBFGS:   11 00:22:33        0.131632        0.075375\n",
+      "LBFGS:   12 00:22:33        0.130942        0.072777\n",
+      "LBFGS:   13 00:22:33        0.130170        0.068744\n",
+      "LBFGS:   14 00:22:33        0.129368        0.062870\n",
+      "LBFGS:   15 00:22:33        0.128751        0.056881\n",
+      "LBFGS:   16 00:22:33        0.128324        0.052238\n",
+      "LBFGS:   17 00:22:33        0.127919        0.047877\n",
+      "LBFGS:   18 00:22:33        0.127476        0.042926\n",
+      "LBFGS:   19 00:22:33        0.127083        0.038244\n",
+      "LBFGS:   20 00:22:33        0.126763        0.036082\n",
+      "LBFGS:   21 00:22:33        0.126430        0.032395\n",
+      "LBFGS:   22 00:22:34        0.126021        0.032316\n",
+      "LBFGS:   23 00:22:34        0.125623        0.034318\n",
+      "LBFGS:   24 00:22:34        0.125339        0.034476\n",
+      "LBFGS:   25 00:22:34        0.125133        0.036248\n",
+      "LBFGS:   26 00:22:34        0.124908        0.037445\n",
+      "LBFGS:   27 00:22:34        0.124638        0.038273\n",
+      "LBFGS:   28 00:22:34        0.124388        0.038470\n",
+      "LBFGS:   29 00:22:34        0.124180        0.038053\n",
+      "LBFGS:   30 00:22:34        0.123942        0.037095\n",
+      "LBFGS:   31 00:22:34        0.123580        0.035246\n",
+      "LBFGS:   32 00:22:34        0.123080        0.044708\n",
+      "LBFGS:   33 00:22:34        0.122550        0.047592\n",
+      "LBFGS:   34 00:22:34        0.122084        0.047047\n",
+      "LBFGS:   35 00:22:34        0.121637        0.044571\n",
+      "LBFGS:   36 00:22:34        0.121144        0.036345\n",
+      "LBFGS:   37 00:22:34        0.120680        0.038705\n",
+      "LBFGS:   38 00:22:34        0.120372        0.040605\n",
+      "LBFGS:   39 00:22:35        0.120189        0.030889\n",
+      "LBFGS:   40 00:22:35        0.120032        0.026606\n",
+      "LBFGS:   41 00:22:35        0.119881        0.020319\n",
+      "LBFGS:   42 00:22:35        0.119780        0.014394\n",
+      "LBFGS:   43 00:22:35        0.119724        0.013753\n",
+      "LBFGS:   44 00:22:35        0.119681        0.011448\n",
+      "LBFGS:   45 00:22:35        0.119633        0.008851\n",
+      "LBFGS:   46 00:22:35        0.119592        0.012077\n",
+      "LBFGS:   47 00:22:35        0.119568        0.009679\n",
+      "LBFGS:   48 00:22:35        0.119552        0.008307\n",
+      "LBFGS:   49 00:22:35        0.119534        0.008039\n",
+      "LBFGS:   50 00:22:35        0.119513        0.007670\n",
+      "LBFGS:   51 00:22:35        0.119494        0.009649\n",
+      "LBFGS:   52 00:22:36        0.119478        0.008279\n",
+      "LBFGS:   53 00:22:36        0.119461        0.007303\n",
+      "LBFGS:   54 00:22:36        0.119436        0.009732\n",
+      "LBFGS:   55 00:22:36        0.119404        0.010922\n",
+      "LBFGS:   56 00:22:36        0.119377        0.009074\n",
+      "LBFGS:   57 00:22:36        0.119359        0.008053\n",
+      "LBFGS:   58 00:22:36        0.119345        0.008081\n",
+      "LBFGS:   59 00:22:36        0.119329        0.006755\n",
+      "LBFGS:   60 00:22:36        0.119316        0.005922\n",
+      "LBFGS:   61 00:22:36        0.119308        0.004193\n",
+      "LBFGS:   62 00:22:36        0.119303        0.004142\n",
+      "LBFGS:   63 00:22:36        0.119298        0.004002\n",
+      "LBFGS:   64 00:22:36        0.119293        0.003031\n",
+      "LBFGS:   65 00:22:37        0.119290        0.002407\n",
+      "LBFGS:   66 00:22:37        0.119288        0.002046\n",
+      "LBFGS:   67 00:22:37        0.119287        0.001554\n",
+      "LBFGS:   68 00:22:37        0.119286        0.001448\n",
+      "LBFGS:   69 00:22:37        0.119285        0.001153\n",
+      "LBFGS:   70 00:22:37        0.119284        0.001072\n",
+      "LBFGS:   71 00:22:37        0.119284        0.000840\n",
+      "LBFGS:   72 00:22:37        0.119284        0.000698\n",
+      "LBFGS:   73 00:22:37        0.119284        0.000686\n",
+      "LBFGS:   74 00:22:37        0.119284        0.000678\n",
+      "LBFGS:   75 00:22:37        0.119284        0.000670\n",
+      "LBFGS:   76 00:22:37        0.119283        0.000659\n",
+      "LBFGS:   77 00:22:37        0.119283        0.000646\n",
+      "LBFGS:   78 00:22:37        0.119283        0.000636\n",
+      "LBFGS:   79 00:22:38        0.119283        0.000628\n",
+      "LBFGS:   80 00:22:38        0.119283        0.000618\n",
+      "LBFGS:   81 00:22:38        0.119283        0.000601\n",
+      "LBFGS:   82 00:22:38        0.119283        0.000577\n",
+      "LBFGS:   83 00:22:38        0.119283        0.000654\n",
+      "LBFGS:   84 00:22:38        0.119283        0.000651\n",
+      "LBFGS:   85 00:22:38        0.119283        0.000795\n",
+      "LBFGS:   86 00:22:38        0.119282        0.000859\n",
+      "LBFGS:   87 00:22:38        0.119282        0.000803\n",
+      "LBFGS:   88 00:22:38        0.119282        0.000839\n",
+      "LBFGS:   89 00:22:38        0.119282        0.000741\n",
+      "LBFGS:   90 00:22:38        0.119282        0.000765\n",
+      "LBFGS:   91 00:22:38        0.119281        0.000746\n",
+      "LBFGS:   92 00:22:39        0.119281        0.000629\n",
+      "LBFGS:   93 00:22:39        0.119281        0.000664\n",
+      "LBFGS:   94 00:22:39        0.119281        0.000592\n",
+      "LBFGS:   95 00:22:39        0.119281        0.000592\n",
+      "LBFGS:   96 00:22:39        0.119281        0.000479\n",
+      "LBFGS:   97 00:22:39        0.119281        0.000406\n",
+      "LBFGS:   98 00:22:39        0.119281        0.000373\n",
+      "LBFGS:   99 00:22:39        0.119281        0.000346\n",
+      "LBFGS:  100 00:22:39        0.119281        0.000307\n",
+      "LBFGS:  101 00:22:39        0.119281        0.000187\n",
+      "LBFGS:  102 00:22:39        0.119281        0.000177\n",
+      "LBFGS:  103 00:22:39        0.119281        0.000134\n",
+      "LBFGS:  104 00:22:39        0.119281        0.000116\n",
+      "LBFGS:  105 00:22:39        0.119281        0.000113\n",
+      "LBFGS:  106 00:22:39        0.119281        0.000110\n",
+      "LBFGS:  107 00:22:40        0.119281        0.000107\n",
+      "LBFGS:  108 00:22:40        0.119281        0.000102\n",
+      "LBFGS:  109 00:22:40        0.119281        0.000094\n",
+      "LBFGS:  110 00:22:40        0.119281        0.000086\n",
+      "LBFGS:  111 00:22:40        0.119281        0.000095\n",
+      "LBFGS:  112 00:22:40        0.119281        0.000083\n",
+      "LBFGS:  113 00:22:40        0.119281        0.000085\n",
+      "LBFGS:  114 00:22:40        0.119281        0.000084\n",
+      "LBFGS:  115 00:22:40        0.119281        0.000086\n",
+      "LBFGS:  116 00:22:40        0.119281        0.000080\n",
+      "LBFGS:  117 00:22:40        0.119281        0.000088\n",
+      "LBFGS:  118 00:22:40        0.119281        0.000088\n",
+      "LBFGS:  119 00:22:41        0.119281        0.000082\n",
+      "LBFGS:  120 00:22:41        0.119281        0.000075\n",
+      "LBFGS:  121 00:22:41        0.119281        0.000064\n",
+      "LBFGS:  122 00:22:41        0.119281        0.000049\n",
+      "LBFGS:  123 00:22:41        0.119281        0.000039\n",
+      "LBFGS:  124 00:22:41        0.119281        0.000028\n",
+      "LBFGS:  125 00:22:41        0.119281        0.000022\n",
+      "LBFGS:  126 00:22:41        0.119281        0.000022\n",
+      "LBFGS:  127 00:22:41        0.119281        0.000017\n",
+      "LBFGS:  128 00:22:41        0.119281        0.000012\n",
+      "LBFGS:  129 00:22:41        0.119281        0.000011\n",
+      "LBFGS:  130 00:22:41        0.119281        0.000009\n",
+      "LBFGS:  131 00:22:41        0.119281        0.000007\n",
+      "LBFGS:  132 00:22:41        0.119281        0.000006\n",
+      "LBFGS:  133 00:22:41        0.119281        0.000005\n",
+      "LBFGS:  134 00:22:41        0.119281        0.000003\n",
+      "LBFGS:  135 00:22:41        0.119281        0.000003\n",
+      "LBFGS:  136 00:22:42        0.119281        0.000002\n",
+      "LBFGS:  137 00:22:42        0.119281        0.000002\n",
+      "LBFGS:  138 00:22:42        0.119281        0.000002\n",
+      "LBFGS:  139 00:22:42        0.119281        0.000001\n",
+      "LBFGS:  140 00:22:42        0.119281        0.000001\n",
+      "LBFGS:  141 00:22:42        0.119281        0.000001\n",
+      "LBFGS:  142 00:22:42        0.119281        0.000001\n",
+      "LBFGS:  143 00:22:42        0.119281        0.000001\n",
+      "LBFGS:  144 00:22:42        0.119281        0.000001\n",
+      "\u001b[33;1m\u001b[1;3mnumbers=[29, 29, 29, 29, 29, 79, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 79, 79, 29, 79, 29, 29, 29, 29, 79, 29, 79, 79, 79, 29, 29] positions=[[0.04933470712955112, 0.02109176537232389, -0.01967024283085893], [0.041579504812358066, 1.9088577659280117, 1.8688730294125662], [1.752947421274659, 0.007526428339998962, 1.8517532011139288], [1.8132130906465895, 1.8661478216831633, -0.01784244928916533], [0.04748547786621053, -0.020045283932604206, 3.7756177495554053], [-0.0006018901567626618, 1.8736867197334097, 5.617193997590088], [1.804574043998281, 0.010851782866484224, 5.657710719719834], [1.7731654464037412, 1.8819326479586218, 3.7386336366455337], [0.039552993504144825, 3.6959770763006046, 0.017776397613823235], [0.04840115439863405, 5.564642489727186, 1.9188661967585896], [1.7680763572557747, 3.7292103823796086, 1.8588427639189269], [1.7325353269624666, 5.59308251357397, 0.003056155635368118], [0.004654847952851257, 3.7518900373660466, 3.7400575489959946], [0.03889253080556578, 5.593750323434761, 5.584486681639527], [1.7954545994565017, 3.727956573480123, 5.648208793522534], [1.7741310581586869, 5.588772412001776, 3.7575664234787243], [3.6490240478830405, 0.027440786984275888, -0.028921384342673242], [3.6395180264749665, 1.893810604343441, 1.789926731024888], [5.642858747915597, 0.025339570446485105, 1.882335192327549], [5.5450198935243105, 1.8954144238432549, -0.016542359350911574], [3.6397242052516603, 0.05590157416851766, 3.7976325332676186], [3.6785357223885677, 1.8696881631736721, 5.6923719821366765], [5.556746717587128, 0.008536828960749188, 5.631374089317995], [5.582675167104445, 1.8835809079374604, 3.754222023149186], [3.645993437854674, 3.7031592029268756, -0.03855435278344386], [3.6092608939315145, 5.578267082713666, 1.8280449092602735], [5.594269383403506, 3.7098061022730966, 1.8856940882802502], [5.637965822810118, 5.548952975307969, -0.017723601383752525], [3.67413598874531, 3.686370766547991, 3.794166674224155], [3.625736297202185, 5.602353088582559, 5.68504075133503], [5.559995421283887, 3.7173900980063936, 5.622212588063477], [5.58551811349664, 5.583524538752662, 3.7782335646476275]] cell=[[7.365300830054032, -0.005528509379133711, 0.0027880865511100764], [-0.0056227719031778966, 7.466154059861727, 0.004759868442992488], [0.00285315496106562, 0.004780130449931503, 7.495839047727933]] pbc=[True, True, True]\u001b[0m\u001b[32;1m\u001b[1;3m\n",
+      "Invoking: `get_bulk_modulus` with `{'atom_dict': {'numbers': [29, 29, 29, 29, 29, 79, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 79, 79, 29, 79, 29, 29, 29, 29, 79, 29, 79, 79, 79, 29, 29], 'positions': [[0.04933470712955112, 0.02109176537232389, -0.01967024283085893], [0.041579504812358066, 1.9088577659280117, 1.8688730294125662], [1.752947421274659, 0.007526428339998962, 1.8517532011139288], [1.8132130906465895, 1.8661478216831633, -0.01784244928916533], [0.04748547786621053, -0.020045283932604206, 3.7756177495554053], [-0.0006018901567626618, 1.8736867197334097, 5.617193997590088], [1.804574043998281, 0.010851782866484224, 5.657710719719834], [1.7731654464037412, 1.8819326479586218, 3.7386336366455337], [0.039552993504144825, 3.6959770763006046, 0.017776397613823235], [0.04840115439863405, 5.564642489727186, 1.9188661967585896], [1.7680763572557747, 3.7292103823796086, 1.8588427639189269], [1.7325353269624666, 5.59308251357397, 0.003056155635368118], [0.004654847952851257, 3.7518900373660466, 3.7400575489959946], [0.03889253080556578, 5.593750323434761, 5.584486681639527], [1.7954545994565017, 3.727956573480123, 5.648208793522534], [1.7741310581586869, 5.588772412001776, 3.7575664234787243], [3.6490240478830405, 0.027440786984275888, -0.028921384342673242], [3.6395180264749665, 1.893810604343441, 1.789926731024888], [5.642858747915597, 0.025339570446485105, 1.882335192327549], [5.5450198935243105, 1.8954144238432549, -0.016542359350911574], [3.6397242052516603, 0.05590157416851766, 3.7976325332676186], [3.6785357223885677, 1.8696881631736721, 5.6923719821366765], [5.556746717587128, 0.008536828960749188, 5.631374089317995], [5.582675167104445, 1.8835809079374604, 3.754222023149186], [3.645993437854674, 3.7031592029268756, -0.03855435278344386], [3.6092608939315145, 5.578267082713666, 1.8280449092602735], [5.594269383403506, 3.7098061022730966, 1.8856940882802502], [5.637965822810118, 5.548952975307969, -0.017723601383752525], [3.67413598874531, 3.686370766547991, 3.794166674224155], [3.625736297202185, 5.602353088582559, 5.68504075133503], [5.559995421283887, 3.7173900980063936, 5.622212588063477], [5.58551811349664, 5.583524538752662, 3.7782335646476275]], 'cell': [[7.365300830054032, -0.005528509379133711, 0.0027880865511100764], [-0.0056227719031778966, 7.466154059861727, 0.004759868442992488], [0.00285315496106562, 0.004780130449931503, 7.495839047727933]], 'pbc': [True, True, True]}, 'calculator_str': 'emt'}`\n",
+      "\n",
+      "\n",
+      "\u001b[0m\u001b[38;5;200m\u001b[1;3m145.58000452590966\u001b[0m\u001b[32;1m\u001b[1;3mThe computed bulk modulus for the Cu-Au alloy with 73.8% Copper and 26.2% Gold is approximately 145.58 GPa, which is within the desired range of 145 GPa ± 2 GPa.\n",
+      "\n",
+      "### Summary\n",
+      "- **Target Bulk Modulus:** 145 GPa\n",
+      "- **Computed Bulk Modulus:** 145.58 GPa\n",
+      "- **Concentration:** 73.8% Copper (Cu) and 26.2% Gold (Au)\n",
+      "\n",
+      "The prediction has been validated successfully, and the computed bulk modulus falls within the specified uncertainty range.\u001b[0m\n",
+      "\n",
+      "\u001b[1m> Finished chain.\u001b[0m\n"
+     ]
+    }
+   ],
+   "source": [
+    "lst = list(agent_executor.stream({\"input\": \"Using linear interpolation find the concentration of an Copper Gold Alloy with a bulk modulus around 145 GPa with an error of plus or minus 2 GPa using the EMT simulation code. Validate your prediction by computing the bulk modulus and do not stop until you calculate the bulk modulus with the defined uncertainty.\"}))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "ad9b452d-3080-49d4-baf0-b13a71fa3fad",
+   "metadata": {},
+   "source": [
+    "## Summary\n",
+    "This example highlights the application of generative models for materials science. While the three previous examples could also be addressed by computing the material properties for all unaries, store them in a database and provide them to the user when requested, this is no longer possible for the space of binary or even ternary alloys. Just like a student the LLM is capable to apply an abstract concept of linear interpolation to the prediction of the concentration related to a bulk modulus of 140GPa."
+   ]
+  }
+ ],
+ "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.12.5"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/environment.yml b/environment.yml
index a2eb4dc..3bca1b8 100644
--- a/environment.yml
+++ b/environment.yml
@@ -13,3 +13,4 @@ dependencies:
   - mendeleev =0.17.0
   - lxml =4.9.4
   - ipython =8.25.0
+  - sqsgenerator =0.3
\ No newline at end of file
diff --git a/langsim/tools/simulation_complex_alloys.py b/langsim/tools/simulation_complex_alloys.py
new file mode 100644
index 0000000..5d86eac
--- /dev/null
+++ b/langsim/tools/simulation_complex_alloys.py
@@ -0,0 +1,123 @@
+from typing import List
+
+from ase.atoms import Atoms
+from ase.build import bulk
+from ase.data import reference_states, atomic_numbers
+from langchain.tools import tool
+import numpy as np
+import structuretoolkit as stk
+
+from langsim.tools.simulation_atomistics import AtomsDict
+
+
+def _get_element_dict(element_lst: List[str], concentration_lst: List[float], number_of_atoms: int) -> dict:
+    element_dict = {
+        el: int(np.round(c * number_of_atoms))
+        for el, c in zip(element_lst[:-1], concentration_lst[:-1])
+    }
+    element_dict[element_lst[-1]] = number_of_atoms-sum(element_dict.values())
+    return element_dict
+
+
+def _get_alloy_concentration(element_lst: List[str], concentration_lst: List[float], number_of_atoms: int) -> dict:
+    if sum(concentration_lst) > 1:
+        raise ValueError()
+    elif sum(concentration_lst) < 1 and len(concentration_lst)+1 == len(element_lst):
+        concentration_lst.append(1-sum(concentration_lst))
+        return _get_element_dict(
+            element_lst=element_lst,
+            concentration_lst=concentration_lst,
+            number_of_atoms=number_of_atoms,
+        )
+    elif sum(concentration_lst) == 1 and len(concentration_lst) == len(element_lst):
+        return _get_element_dict(
+            element_lst=element_lst,
+            concentration_lst=concentration_lst,
+            number_of_atoms=number_of_atoms,
+        )
+    else:
+        raise ValueError()
+
+
+def _get_nn_distance(symmetry: str, a: float, **kwargs) -> float:
+    if symmetry.lower() == "fcc":
+        return (a * np.sqrt(2))/2
+    elif symmetry.lower() == "bcc":
+        return (a * np.sqrt(3))/4
+    else:
+        raise ValueError()
+
+
+def _get_lattice_constant(symmetry: str, nn_distance: float) -> float:
+    if symmetry.lower() == "fcc":
+        return (2 * nn_distance) / np.sqrt(2)
+    elif symmetry.lower() == "bcc":
+        return (4 * nn_distance) / np.sqrt(3)
+    else:
+        raise ValueError()
+
+
+def _get_template(crystal_structure: str, a:float, number_of_atoms: int):
+    if crystal_structure.lower() == "fcc":
+        structure = bulk("Al", a=a, cubic=True)
+    elif crystal_structure.lower() == "bcc":
+        structure = bulk("Fe", a=a, cubic=True)
+    else:
+        raise ValueError()
+
+    i = 1
+    structure_template = structure.copy()
+    while len(structure) < number_of_atoms:
+        structure = structure_template.repeat([i, i, i])
+        i+=1
+    return structure
+
+
+def _get_structure(element_lst: List[str], concentration_lst: List[float], number_of_atoms: int, crystal_structure:str) -> Atoms:
+    number_of_atoms= len(_get_template(crystal_structure=crystal_structure, a=1.0, number_of_atoms=number_of_atoms))
+    if len(element_lst) == 1 + sum([c == 0 for c in concentration_lst]):
+        return _get_template(
+            crystal_structure=crystal_structure,
+            a=reference_states[atomic_numbers[element_lst[0]]]["a"],
+            number_of_atoms=number_of_atoms
+        )
+    else:
+        element_dict = _get_alloy_concentration(
+            element_lst=element_lst,
+            concentration_lst=concentration_lst,
+            number_of_atoms=number_of_atoms,
+        )
+        a = _get_lattice_constant(
+            symmetry=crystal_structure,
+            nn_distance=sum({
+                el: n * _get_nn_distance(**reference_states[atomic_numbers[el]]) / number_of_atoms
+                for el, n in element_dict.items()
+            }.values()),
+        )
+        structure_template = _get_template(crystal_structure=crystal_structure, a=a, number_of_atoms=number_of_atoms)
+        structure_template.set_chemical_symbols([list(element_dict.keys())[0]] * number_of_atoms)
+        return stk.build.sqs_structures(
+            structure=structure_template,
+            mole_fractions={el: n/ number_of_atoms for el, n in element_dict.items()},
+            objective=0.0,
+            iterations=1e6,
+            output_structures=1,
+        )[0]
+
+
+@tool
+def get_complex_alloy_bulk_structure(element_lst: List[str], concentration_lst: List[float], number_of_atoms: int = 32, crystal_structure:str = "fcc") -> AtomsDict:
+    """
+    Returns bulk structure atoms dictionary for a given list of chemical elements and their corresponding concentration
+
+    Args:
+        element_lst (List[str]): list of chemical elements
+        concentration_lst (List[float]): list of concentrations of the corresponding chemical elements
+        number_of_atoms (int): number of atoms in the structure - optional - by default 32
+        crystal_structure (str): atomic crystal structure of the solid solution - by default "fcc" - face centered cubic
+
+    Returns:
+        AtomsDict: DataClass representing the atomic structure required to equilibrate the structure
+    """
+    atoms = _get_structure(element_lst=element_lst, concentration_lst=concentration_lst, number_of_atoms=number_of_atoms, crystal_structure=crystal_structure)
+    return AtomsDict(**{k: v.tolist() for k, v in atoms.todict().items()})
diff --git a/setup.py b/setup.py
index 0aaf2f8..13a1063 100644
--- a/setup.py
+++ b/setup.py
@@ -19,6 +19,7 @@
     ],
     extras_require={
         "mace": ["mace==0.3.5"],
+        "alloy": ["sqsgenerator==0.3"],
         "ipython": [
             "ipython==6.2.0",
             "langchain-experimental==0.0.61",