{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "8cfa587b",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Crear una función Qiskit para la simulación química\"\n",
        "description: \"Aprenda a implementar y ejecutar la plantilla del flujo de trabajo químico\"\n",
        "---\n",
        "\n",
        "<span id=\"build-and-run-a-qiskit-function-template-for-electronic-structure-simulation-with-an-implicit-solvent-model\" />\n",
        "\n",
        "# Crear y ejecutar una plantilla de Qiskit Function para la simulación de la estructura electrónica con un modelo de disolvente implícito\n",
        "\n",
        "{/* cspell:ignore pvdz, fcisolver, avas, ncas, nelecas, ecore, chkfile, fcivec, hcore, ncore, myci, sqdvec, myeps, mymethod, mysolvmethod, myavas, mcscf, MCSCF, chkfile, prqs */}\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f9bfec87",
      "metadata": {
        "tags": [
          "version-info"
        ]
      },
      "source": [
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f3a337d1",
      "metadata": {},
      "source": [
        "Esta plantilla, desarrollada en colaboración con la Clínica Cleveland, consiste en un flujo de trabajo para calcular la energía de estado fundamental y la energía libre de solvatación de una molécula en un disolvente implícito [\\[1\\]](#references). Estas simulaciones se basan en el método de diagonalización cuántica basado en muestras (SQD) [\\[2-6\\]](#references) y en el modelo continuo polarizable del formalismo de ecuaciones integrales (IEF-PCM) del disolvente [\\[7\\]](#references).\n",
        "\n",
        "Para ver una guía paso a paso de este mismo flujo de trabajo con un ejemplo práctico, consulta el tutorial «[Cálculos con disolvente implícito utilizando Qiskit Serverless](/docs/tutorials/implicit-solvent-calculations) ».\n",
        "\n",
        "Esta guía utiliza la plantilla con una molécula de metanol como soluto, cuya estructura electrónica se simula explícitamente, y agua como disolvente, aproximada como un medio dieléctrico continuo. Para tener en cuenta los [efectos de correlación de electrones](https://onlinelibrary.wiley.com/doi/epdf/10.1002/ijch.202100111) en el metanol, manteniendo el equilibrio entre el coste computacional y la precisión, sólo incluimos los orbitales $\\sigma$, $\\sigma^{*}$, y de par solitario en el espacio activo simulado con SQD IEF-PCM. Esta selección de orbitales se realiza con el [método del espacio activo de valencia atómica (AVAS](https://github.com/pyscf/pyscf.github.io/blob/master/examples/mcscf/43-avas.py) ) utilizando los componentes orbitales atómicos C2s\\[,2p], O2s\\[,2p] y \\[H1s], lo que da como resultado el espacio activo de 14 electrones y 12 orbitales ( 14e,12o ). Los orbitales de referencia se calculan con Hartree Fock de envolvente cerrada utilizando el conjunto de bases cc-pvdz.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "25d18ba5",
      "metadata": {},
      "source": [
        "<span id=\"workflow-introduction\" />\n",
        "\n",
        "## Introducción al flujo de trabajo\n",
        "\n",
        "Esta guía interactiva muestra cómo cargar esta plantilla de función en Qiskit Serverless y ejecutar una carga de trabajo de ejemplo. La plantilla está estructurada como un patrón Qiskit con cuatro pasos:\n",
        "\n",
        "<span id=\"1-collect-input-and-map-the-problem\" />\n",
        "\n",
        "#### 1. Recopilar información y analizar el problema\n",
        "\n",
        "Este paso toma como entrada la geometría de la molécula, el espacio activo seleccionado, el modelo de solvatación, las opciones LUCJ y las opciones SQD. A continuación, produce el archivo PySCF Checkpoint, que contiene los datos Hartree-Fock (HF) IEF-PCM. Estos datos se utilizarán en la parte SQD del flujo de trabajo. Para la parte LUCJ del flujo de trabajo, la sección de entrada también genera los datos HF en fase gaseosa, que se almacenan internamente en formato PySCF FCIDUMP.\n",
        "\n",
        "Se toma como entrada la información de la simulación de fase gaseosa HF y la definición del espacio activo. Es importante destacar que también utiliza la información definida por el usuario en la sección de entrada relativa a la supresión de errores, el número de disparos, el nivel de optimización del transpilador de circuitos y la disposición de los qubits.\n",
        "\n",
        "Genera integrales de uno y dos electrones dentro del espacio activo definido. A continuación, las integrales se utilizan para realizar cálculos CCSD clásicos, que devuelven t2 amplitudes que utilizamos para parametrizar el circuito LUCJ.\n",
        "\n",
        "<span id=\"2-optimize-the-circuit\" />\n",
        "\n",
        "#### 2. Optimizar el circuito\n",
        "\n",
        "A continuación, el circuito LUCJ se transpila a un circuito ISA para el hardware de destino. A continuación, se instancia una primitiva Sampler con un conjunto predeterminado de opciones de mitigación de errores para gestionar la ejecución.\n",
        "\n",
        "<span id=\"3-execute-the-circuit\" />\n",
        "\n",
        "#### 3. Ejecutar el circuito\n",
        "\n",
        "Los cálculos LUCJ devuelven las cadenas de bits de cada medida, donde estas cadenas de bits corresponden a configuraciones de electrones del sistema estudiado. A continuación, las cadenas de bits se utilizan como entrada para el postprocesamiento.\n",
        "\n",
        "<span id=\"4-post-process-by-using-sqd\" />\n",
        "\n",
        "#### 4. Procesamiento posterior mediante SQD\n",
        "\n",
        "Este paso final toma como entrada el archivo PySCF Checkpoint que contiene la información HF IEF-PCM, las cadenas de bits que representan las configuraciones de electrones predichas por LUCJ y las opciones SQD definidas por el usuario y seleccionadas en la sección de entrada. Como salida, produce la energía total SQD IEF-PCM del lote de menor energía y la correspondiente energía libre de solvatación.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4832ef18",
      "metadata": {},
      "source": [
        "<span id=\"options\" />\n",
        "\n",
        "### Opciones\n",
        "\n",
        "Para esta plantilla debe especificar las opciones para generar el circuito LUCJ, y los parámetros de ejecución SQD.\n",
        "\n",
        "<span id=\"lucj-options\" />\n",
        "\n",
        "#### Opciones LUCJ\n",
        "\n",
        "Cuando se ejecuta el circuito cuántico LUCJ, se produce un conjunto de muestras que representan los estados base computacionales de la distribución de probabilidad del sistema molecular. Para equilibrar la profundidad del circuito LUCJ y su expresividad, los qubits correspondientes a los orbitales de espín con el espín opuesto tienen las puertas de dos qubits aplicadas entre ellos cuando estos qubits son vecinos a través de un único qubit ancilla. Para implementar este enfoque en el hardware IBM con una topología heavy-hex, los qubits que representan los orbitales de espín con el mismo espín se conectan a través de una topología de línea donde cada línea adopta una forma de zig-zag debido a la conectividad heavy-hex del hardware de destino, mientras que los qubits que representan los orbitales de espín con el espín opuesto sólo tienen una conexión en cada cuarto qubit.\n",
        "\n",
        "<Accordion>\n",
        "  <AccordionItem title=\"Haga clic para ampliar y obtener más detalles sobre las opciones necesarias:\">\n",
        "    El usuario debe proporcionar la matriz `initial_layout` correspondiente a los qubits que satisfacen este [patrón *en zig-zag*](https://pubs.rsc.org/en/content/articlehtml/2023/sc/d3sc02516k) en la sección `lucj_options` de la función SQD IEF-PCM. En el caso de las simulaciones SQD IEF-PCM ( 14e,12o )/cc-pvdz de metanol, elegimos la disposición inicial de qubits correspondiente a la diagonal principal del QPU de Eagle R3. Aquí, los 12 primeros elementos de la matriz `initial_layout` `[0, 14, 18, 19, 20, 33, 39, 40, 41, 53, 60, 61, ...]` corresponden a los orbitales de espín alfa. Los 12 últimos elementos `[... 2, 3, 4, 15, 22, 23, 24, 34, 43, 44, 45, 54]` corresponden a orbitales de espín beta.\n",
        "\n",
        "    Es importante que el usuario determine el `number_of_shots`, que corresponde al número de mediciones en el circuito LUCJ. El número de disparos tiene que ser suficientemente grande porque el primer paso del procedimiento S-CORE se basa en las muestras del sector de partículas derecho para obtener la aproximación inicial a la distribución del número de ocupación del estado basal.\n",
        "\n",
        "    El número de disparos depende en gran medida del sistema y del hardware, pero los estudios SQD [no covalentes](https://arxiv.org/abs/2410.09209), [basados en fragmentos](https://arxiv.org/abs/2411.09861) y [con disolventes implícitos](https://pubs.acs.org/doi/10.1021/acs.jpcb.5c01030) sugieren que se puede alcanzar la precisión química siguiendo estas directrices:\n",
        "\n",
        "    * 20.000 - 200.000 disparos para sistemas con menos de 16 orbitales moleculares (32 orbitales de espín)\n",
        "    * 200.000 disparos para sistemas con 16 - 18 orbitales moleculares\n",
        "    * 200.000 - 2.000.000 disparos para sistemas con más de 18 orbitales moleculares\n",
        "\n",
        "    El número de simulaciones necesarias depende del número de orbitales de espín del sistema estudiado y del tamaño del espacio de Hilbert correspondiente al espacio activo seleccionado dentro de dicho sistema. Por lo general, los casos con espacios de Hilbert más pequeños requieren menos iteraciones. Otras opciones disponibles de LUCJ son [el nivel de optimización del transpilador de circuitos](https://docs.quantum.ibm.com/guides/set-optimization) y [las opciones de supresión de errores](https://docs.quantum.ibm.com/guides/error-mitigation-and-suppression-techniques). Ten en cuenta que estas opciones también influyen en el número de disparos necesarios y en la precisión resultante.\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e2b46498",
      "metadata": {},
      "source": [
        "<span id=\"sqd-options\" />\n",
        "\n",
        "#### Opciones SQD\n",
        "\n",
        "Algunas opciones importantes en las simulaciones SQD son `sqd_iterations`, `number_of_batches` y `samples_per_batch`. En general, el menor número de muestras por lote puede contrarrestarse con más lotes (`number_of_batches`) y más iteraciones de S-CORE (`sqd_iterations`). Con más lotes podemos muestrear más variaciones de los subespacios configuracionales. Dado que el lote de menor energía se toma como solución para la energía del estado fundamental del sistema, un mayor número de lotes puede mejorar los resultados gracias a mejores estadísticas. Las iteraciones adicionales de S-CORE permiten recuperar más configuraciones a partir de la distribución LUCJ original si el número de muestras en el sector de partículas correcto es bajo. Esto puede permitir reducir el número de muestras por lote.\n",
        "\n",
        "<Accordion>\n",
        "  <AccordionItem title=\"Haga clic para ampliar y obtener más información sobre cómo configurar las opciones SQD:\">\n",
        "    Una estrategia alternativa es utilizar más muestras por lote, lo que garantiza que la mayoría de las muestras LUCJ iniciales en el espacio de partículas correcto se utilicen durante el procedimiento S-CORE, y que los subespacios individuales encapsulen una variedad suficiente de configuraciones de electrones. A su vez, esto reduce el número de pasos necesarios de S-CORE, donde sólo se necesitan dos o tres iteraciones de SQD si el número de muestras por lote es lo suficientemente grande. Sin embargo, un mayor número de muestras por lote se traduce en un mayor coste computacional de cada paso de diagonalización. Por lo tanto, el equilibrio entre la precisión y el coste computacional en las simulaciones SQD puede lograrse eligiendo `sqd_iterations`, `number_of_batches`, y `samples_per_batch` de forma óptima.\n",
        "\n",
        "    El [estudio SQD IEF-PCM](https://pubs.acs.org/doi/10.1021/acs.jpcb.5c01030) muestra que cuando se utilizan tres iteraciones de S-CORE, se puede alcanzar la precisión química siguiendo estas directrices:\n",
        "\n",
        "    * 600 muestras por lote en metanol Simulaciones SQD IEF-PCM ( 14e,12o )\n",
        "    * 1500 muestras por lote en simulaciones SQD IEF-PCM con metilamina ( 14e,13o )\n",
        "    * 6000 muestras por lote en agua Simulaciones SQD IEF-PCM ( 8e,23o )\n",
        "    * 16000 muestras por lote en etanol Simulaciones SQD IEF-PCM ( 20e,18o )\n",
        "\n",
        "    Al igual que el número necesario de disparos en LUCJ, el número necesario de muestras por lote utilizado en el procedimiento S-CORE depende en gran medida del sistema y del hardware. Los ejemplos anteriores pueden utilizarse para estimar el punto inicial de la referencia del número necesario de muestras por lote. El tutorial sobre la evaluación comparativa sistemática del número necesario de muestras por lote puede consultarse [aquí](https://qiskit.github.io/qiskit-addon-sqd/how_tos/choose_subspace_dimension.html).\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "998a0f25",
      "metadata": {},
      "source": [
        "<span id=\"deploy-and-execute-the-template-sqd-ief-pcm-function\" />\n",
        "\n",
        "## Implementar y ejecutar la función SQD IEF-PCM de la plantilla\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "6c92ac84",
      "metadata": {
        "vscode": {
          "languageId": "plaintext"
        }
      },
      "source": [
        "<span id=\"authentication\" />\n",
        "\n",
        "### Autenticación\n",
        "\n",
        "Utilice `qiskit-ibm-catalog` para autenticarse en `QiskitServerless` con su clave API (token), que puede encontrar en el panel de control de [IBM Quantum Platform](). Esto permite instanciar el cliente sin servidor para cargar o ejecutar la función seleccionada:\n",
        "\n",
        "```python\n",
        "from qiskit_ibm_catalog import QiskitServerless\n",
        "\n",
        "serverless = QiskitServerless(\n",
        "    channel=\"ibm_quantum_platform\",\n",
        "    instance=\"INSTANCE_CRN\",\n",
        "    # For `token`, use the 44-character API_KEY you created\n",
        "    # and saved from the IBM Quantum Platform Home dashboard\n",
        "    token=\"YOUR_API_KEY\"\n",
        ")\n",
        "```\n",
        "\n",
        "Opcionalmente, utilice `save_account()` para guardar sus credenciales en un entorno local (consulte la guía [Configure su cuenta IBM Cloud](/docs/guides/cloud-setup#cloud-save) ). Tenga en cuenta que esto escribe sus credenciales en el mismo archivo que [`QiskitRuntimeService.save_account()`](/docs/api/qiskit-ibm-runtime/qiskit-runtime-service#save_account):\n",
        "\n",
        "```python\n",
        "QiskitServerless.save_account(token=\"YOUR_API_KEY\",\n",
        "    channel=\"ibm_quantum_platform\", instance=\"INSTANCE_CRN\")\n",
        "```\n",
        "\n",
        "Si la [cuenta está guardada](/docs/guides/save-credentials), no es necesario proporcionar el token para autenticarse:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "9276e2d4",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_ibm_catalog import QiskitServerless\n",
        "\n",
        "serverless = QiskitServerless()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e1f99d80",
      "metadata": {
        "vscode": {
          "languageId": "plaintext"
        }
      },
      "source": [
        "<span id=\"upload-the-template\" />\n",
        "\n",
        "### Subir la plantilla\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "3e0e8cc8",
      "metadata": {
        "vscode": {
          "languageId": "plaintext"
        }
      },
      "source": [
        "Para cargar una Función Qiskit personalizada, primero debe instanciar un objeto `QiskitFunction` que defina el código fuente de la función. El título le permitirá identificar la función una vez que esté en el grupo remoto. El principal punto de entrada es el archivo que contiene `if __name__ == \"__main__\"`. Si su flujo de trabajo requiere archivos fuente adicionales, puede definir un directorio de trabajo que se cargará junto con el punto de entrada.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "77b2b9b6",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "QiskitFunction(sqd_pcm_template)\n"
          ]
        }
      ],
      "source": [
        "from qiskit_ibm_catalog import QiskitFunction\n",
        "\n",
        "template = QiskitFunction(\n",
        "    title=\"sqd_pcm_template\",\n",
        "    entrypoint=\"sqd_pcm_entrypoint.py\",\n",
        "    # all files in `working_dir` will be uploaded\n",
        "    working_dir=\"./source_files/\",\n",
        "    dependencies=[\n",
        "        \"ffsim==0.0.54\",\n",
        "        \"pyscf==2.9.0\",\n",
        "        \"qiskit_addon_sqd==0.10.0\",\n",
        "    ],\n",
        ")\n",
        "print(template)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "72854f5a",
      "metadata": {},
      "source": [
        "Una vez que la instancia esté lista, súbela a serverless:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "59e7fdb5",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "QiskitFunction(sqd_pcm_template)"
            ]
          },
          "execution_count": 3,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "serverless.upload(template)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ac7d8764",
      "metadata": {
        "vscode": {
          "languageId": "plaintext"
        }
      },
      "source": [
        "Para comprobar si el programa se ha cargado correctamente, utilice `serverless.list()`:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "03a91030",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "[QiskitFunction(sqd_pcm_template),\n",
              " QiskitFunction(hamiltonian_simulation_template)]"
            ]
          },
          "execution_count": 4,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "serverless.list()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "99408586",
      "metadata": {},
      "source": [
        "<span id=\"load-and-run-the-template-remotely\" />\n",
        "\n",
        "## Cargar y ejecutar la plantilla de forma remota\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "62b37d7a",
      "metadata": {},
      "source": [
        "La plantilla de la función se ha cargado, por lo que se puede ejecutar de forma remota con Qiskit Serverless. En primer lugar, cargue la plantilla por su nombre:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "854d12cf",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "QiskitFunction(sqd_pcm_template)\n"
          ]
        }
      ],
      "source": [
        "template = serverless.load(\"sqd_pcm_template\")\n",
        "print(template)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "fa2dc721",
      "metadata": {
        "vscode": {
          "languageId": "plaintext"
        }
      },
      "source": [
        "A continuación, ejecute la plantilla con las entradas a nivel de dominio para SQD-IEF PCM. Este ejemplo especifica una carga de trabajo basada en metanol.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "a1719ab1",
      "metadata": {},
      "outputs": [],
      "source": [
        "molecule = {\n",
        "    \"atom\": \"\"\"\n",
        "    O -0.04559 -0.75076 -0.00000;\n",
        "    C -0.04844 0.65398 -0.00000;\n",
        "    H 0.85330 -1.05128 -0.00000;\n",
        "    H -1.08779 0.98076 -0.00000;\n",
        "    H 0.44171 1.06337 0.88811;\n",
        "    H 0.44171 1.06337 -0.88811\n",
        "    \"\"\",  # Must be specified\n",
        "    \"basis\": \"cc-pvdz\",  # default is \"sto-3g\"\n",
        "    \"spin\": 0,  # default is 0\n",
        "    \"charge\": 0,  # default is 0\n",
        "    \"verbosity\": 0,  # default is 0\n",
        "    \"number_of_active_orb\": 12,  # Must be specified\n",
        "    \"number_of_active_alpha_elec\": 7,  # Must be specified\n",
        "    \"number_of_active_beta_elec\": 7,  # Must be specified\n",
        "    \"avas_selection\": [\n",
        "        \"%d O %s\" % (k, x) for k in [0] for x in [\"2s\", \"2px\", \"2py\", \"2pz\"]\n",
        "    ]\n",
        "    + [\"%d C %s\" % (k, x) for k in [1] for x in [\"2s\", \"2px\", \"2py\", \"2pz\"]]\n",
        "    + [\"%d H 1s\" % k for k in [2, 3, 4, 5]],  # default is None\n",
        "}\n",
        "\n",
        "solvent_options = {\n",
        "    # See https://manual.q-chem.com/5.4/topic_pcm-em.html for all methods\n",
        "    \"method\": \"IEF-PCM\",  # other available methods are COSMO, C-PCM, SS(V)PE\n",
        "    \"eps\": 78.3553,  # value for water\n",
        "}\n",
        "\n",
        "lucj_options = {\n",
        "    \"initial_layout\": [\n",
        "        0,\n",
        "        14,\n",
        "        18,\n",
        "        19,\n",
        "        20,\n",
        "        33,\n",
        "        39,\n",
        "        40,\n",
        "        41,\n",
        "        53,\n",
        "        60,\n",
        "        61,\n",
        "        2,\n",
        "        3,\n",
        "        4,\n",
        "        15,\n",
        "        22,\n",
        "        23,\n",
        "        24,\n",
        "        34,\n",
        "        43,\n",
        "        44,\n",
        "        45,\n",
        "        54,\n",
        "    ],\n",
        "    \"dynamical_decoupling_choice\": True,\n",
        "    \"twirling_choice\": True,\n",
        "    \"number_of_shots\": 200000,\n",
        "    \"optimization_level\": 2,\n",
        "}\n",
        "\n",
        "sqd_options = {\n",
        "    \"sqd_iterations\": 3,\n",
        "    \"number_of_batches\": 10,\n",
        "    \"samples_per_batch\": 1000,\n",
        "    \"max_davidson_cycles\": 200,\n",
        "}\n",
        "\n",
        "backend_name = \"ibm_sherbrooke\""
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "01c0667c",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "39f8fb70-79b2-43ca-b723-84e6b6135821\n"
          ]
        }
      ],
      "source": [
        "job = template.run(\n",
        "    backend_name=backend_name,\n",
        "    molecule=molecule,\n",
        "    solvent_options=solvent_options,\n",
        "    lucj_options=lucj_options,\n",
        "    sqd_options=sqd_options,\n",
        ")\n",
        "print(job.job_id)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a9101a94",
      "metadata": {},
      "source": [
        "Compruebe el estado detallado del trabajo:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 18,
      "id": "4385a34f",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "time = 2.35, status = DONE\n"
          ]
        }
      ],
      "source": [
        "import time\n",
        "\n",
        "t0 = time.time()\n",
        "status = job.status()\n",
        "if status == \"QUEUED\":\n",
        "    print(f\"time = {time.time()-t0:.2f}, status = QUEUED\")\n",
        "while True:\n",
        "    status = job.status()\n",
        "    if status == \"QUEUED\":\n",
        "        continue\n",
        "    print(f\"time = {time.time()-t0:.2f}, status = {status}\")\n",
        "    if status == \"DONE\" or status == \"ERROR\":\n",
        "        break"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4adc5293",
      "metadata": {},
      "source": [
        "Mientras se ejecuta el trabajo, puede recuperar los registros creados a partir de las salidas de `logger.info` . Estos pueden proporcionar información procesable sobre el progreso del flujo de trabajo SQD IEF-PCM. Por ejemplo, las mismas conexiones orbitales de espín, o la profundidad de dos qubits del circuito ISA final destinado a la ejecución en hardware.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "a5b1f190",
      "metadata": {},
      "outputs": [],
      "source": [
        "print(job.logs())"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ba179114",
      "metadata": {},
      "source": [
        "La llamada al resultado del trabajo bloquea el resto del programa hasta que el resultado esté disponible. Una vez realizado el trabajo, puedes recuperar los resultados. Estos incluyen la energía libre de solvatación, así como información sobre el lote de energía más bajo, el valor de energía más bajo y otra información útil como la duración total del solver.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "id": "3500adce",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "{'total_energy_hist': array([[-115.14768518, -115.1368396 , -114.19181692, -115.13745429,\n",
              "         -115.1445012 , -114.19673326, -115.1547003 , -114.20563866,\n",
              "         -115.13748344, -115.14764974],\n",
              "        [-115.15768392, -115.15850126, -115.15857275, -115.15770916,\n",
              "         -115.15801684, -115.15822125, -115.15833521, -115.15844051,\n",
              "         -115.15735538, -115.15862354],\n",
              "        [-115.15795148, -115.15847925, -115.15856677, -115.15811156,\n",
              "         -115.15815602, -115.15785171, -115.1583672 , -115.1585533 ,\n",
              "         -115.15833528, -115.15808791]]),\n",
              " 'spin_squared_value_hist': array([[5.37327508e-03, 1.32981759e-02, 1.36214922e-02, 8.84413615e-03,\n",
              "         7.26723578e-03, 1.94875195e-02, 3.03153152e-03, 6.07543106e-03,\n",
              "         1.04951849e-02, 5.36529204e-03],\n",
              "        [6.39397528e-04, 1.36814350e-04, 9.09054260e-05, 5.99361358e-04,\n",
              "         3.64261739e-04, 2.54905866e-04, 2.32540370e-04, 1.53181990e-04,\n",
              "         7.23519739e-04, 6.80737671e-05],\n",
              "        [4.53776416e-04, 1.63043449e-04, 1.05317263e-04, 3.82912836e-04,\n",
              "         3.41047803e-04, 5.18620393e-04, 2.06819142e-04, 1.17086537e-04,\n",
              "         2.32357159e-04, 4.26071537e-04]]),\n",
              " 'solvation_free_energy_hist': array([[-0.00725018, -0.00743955, -0.01132905, -0.0073377 , -0.00722221,\n",
              "         -0.01136705, -0.00719279, -0.01072829, -0.00733404, -0.00725961],\n",
              "        [-0.00719252, -0.00718315, -0.00718074, -0.00719325, -0.00717703,\n",
              "         -0.00718391, -0.00718354, -0.00717928, -0.00719887, -0.0071801 ],\n",
              "        [-0.00719351, -0.00718255, -0.00718198, -0.00718429, -0.00718349,\n",
              "         -0.00718329, -0.0071882 , -0.00718363, -0.00718549, -0.00718814]]),\n",
              " 'occupancy_hist': [[array([0.99712298, 0.99278936, 0.99083163, 0.97328469, 0.98959809,\n",
              "          0.98922134, 0.720333  , 0.25683194, 0.01939338, 0.02840332,\n",
              "          0.00946988, 0.0327204 ]),\n",
              "   array([0.99712298, 0.99278936, 0.99083163, 0.97328469, 0.98959809,\n",
              "          0.98922134, 0.720333  , 0.25683194, 0.01939338, 0.02840332,\n",
              "          0.00946988, 0.0327204 ])],\n",
              "  [array([0.9959042 , 0.9922607 , 0.99018862, 0.99265843, 0.98927447,\n",
              "          0.9900833 , 0.99403876, 0.00989025, 0.01120814, 0.01137717,\n",
              "          0.01152871, 0.01158725]),\n",
              "   array([0.9959042 , 0.9922607 , 0.99018862, 0.99265843, 0.98927447,\n",
              "          0.9900833 , 0.99403876, 0.00989025, 0.01120814, 0.01137717,\n",
              "          0.01152871, 0.01158725])],\n",
              "  [array([0.99590079, 0.99222193, 0.99016753, 0.99265045, 0.98927264,\n",
              "          0.99007179, 0.99407207, 0.00986684, 0.01125181, 0.01141439,\n",
              "          0.01150733, 0.01160243]),\n",
              "   array([0.99590079, 0.99222193, 0.99016753, 0.99265045, 0.98927264,\n",
              "          0.99007179, 0.99407207, 0.00986684, 0.01125181, 0.01141439,\n",
              "          0.01150733, 0.01160243])]],\n",
              " 'lowest_energy_batch': 2,\n",
              " 'lowest_energy_value': -115.1585667736213,\n",
              " 'solvation_free_energy': -0.007181981952470838,\n",
              " 'sci_solver_total_duration': 493.997501373291,\n",
              " 'metadata': {'resources_usage': {'RUNNING: MAPPING': {'CPU_TIME': 6.080063343048096},\n",
              "   'RUNNING: OPTIMIZING_FOR_HARDWARE': {'CPU_TIME': 1.999896764755249},\n",
              "   'RUNNING: WAITING_FOR_QPU': {'CPU_TIME': 6.2850868701934814},\n",
              "   'RUNNING: EXECUTING_QPU': {'QPU_TIME': 21.639373540878296},\n",
              "   'RUNNING: POST_PROCESSING': {'CPU_TIME': 495.40831995010376}},\n",
              "  'num_iterations_executed': 3}}"
            ]
          },
          "execution_count": 16,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "result = job.result()\n",
        "\n",
        "result"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "94a2c921",
      "metadata": {},
      "source": [
        "Ten en cuenta que los metadatos de los resultados incluyen un resumen del uso de recursos que te permite estimar mejor el tiempo de QPU y CPU necesario para cada carga de trabajo (este ejemplo se ejecutó en un dispositivo ficticio, por lo que los tiempos reales de uso de recursos pueden diferir).\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "49d0b26d",
      "metadata": {
        "vscode": {
          "languageId": "plaintext"
        }
      },
      "source": [
        "Una vez finalizada la tarea, estará disponible toda la salida de registro.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 17,
      "id": "ddcba564",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "2025-06-27 08:42:41,358\tINFO job_manager.py:531 -- Runtime env is setting up.\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:42:45,015: Starting runtime service\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:42:45,621: Backend: ibm_sherbrooke\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:42:46,809: Initializing molecule object\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:42:51,599: Performing CCSD\n",
            "Parsing /tmp/ray/session_2025-06-27_08-42-13_898146_1/runtime_resources/working_dir_files/_ray_pkg_4bc93dcc58c04b91/output_sqd_pcm/2025-06-27_08-42-45.fcidump.txt\n",
            "Overwritten attributes  get_ovlp get_hcore  of <class 'pyscf.scf.hf_symm.SymAdaptedRHF'>\n",
            "/usr/local/lib/python3.11/site-packages/pyscf/gto/mole.py:1293: UserWarning: Function mol.dumps drops attribute energy_nuc because it is not JSON-serializable\n",
            "  warnings.warn(msg)\n",
            "/usr/local/lib/python3.11/site-packages/pyscf/gto/mole.py:1293: UserWarning: Function mol.dumps drops attribute intor_symmetric because it is not JSON-serializable\n",
            "  warnings.warn(msg)\n",
            "converged SCF energy = -115.049680672847\n",
            "E(CCSD) = -115.1519910037652  E_corr = -0.1023103309180226\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:42:51,694: Same spin orbital connections: [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9), (9, 10), (10, 11)]\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:42:51,694: Opposite spin orbital connections: [(0, 0), (4, 4), (8, 8)]\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:42:53,718: Optimization level: 2, ops: OrderedDict([('rz', 2438), ('sx', 1496), ('ecr', 766), ('x', 185), ('measure', 24), ('barrier', 1)]), depth: 391\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:42:53,736: Two-qubit gate depth: 94\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:42:53,737: Submitting sampler job\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:42:54,273: Job ID: d1f5j3lqbivc73ebqpj0\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:42:54,313: Job Status: QUEUED\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:43:24,813: Starting configuration recovery iteration 0\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:43:24,841: Batch 0 subspace dimension: 531441\n",
            "2025-06-27 08:43:24,844\tINFO worker.py:1588 -- Using address 172.17.16.124:6379 set in the environment variable RAY_ADDRESS\n",
            "2025-06-27 08:43:24,847\tINFO worker.py:1723 -- Connecting to existing Ray cluster at address: 172.17.16.124:6379...\n",
            "2025-06-27 08:43:24,876\tINFO worker.py:1908 -- Connected to Ray cluster. View the dashboard at \u001b[1m\u001b[32mhttp://172.17.16.124:8265 \u001b[39m\u001b[22m\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:43:24,945: Batch 1 subspace dimension: 519841\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:43:24,950: Batch 2 subspace dimension: 543169\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:43:24,955: Batch 3 subspace dimension: 532900\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:43:24,960: Batch 4 subspace dimension: 534361\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:43:24,964: Batch 5 subspace dimension: 531441\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:43:24,969: Batch 6 subspace dimension: 540225\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:43:24,974: Batch 7 subspace dimension: 524176\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:43:24,979: Batch 8 subspace dimension: 537289\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:43:24,983: Batch 9 subspace dimension: 540225\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:48:09,006: Lowest energy batch: 6\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:48:09,007: Lowest energy value: -115.15470029849135\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:48:09,007: Corresponding g_solv value: -0.0071927910374866375\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:48:09,007: -----------------------------------\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:48:09,007: Starting configuration recovery iteration 1\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:48:40,564: Batch 0 subspace dimension: 413449\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:48:40,572: Batch 1 subspace dimension: 399424\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:48:40,578: Batch 2 subspace dimension: 438244\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:48:40,583: Batch 3 subspace dimension: 422500\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:48:40,589: Batch 4 subspace dimension: 409600\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:48:40,596: Batch 5 subspace dimension: 404496\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:48:40,601: Batch 6 subspace dimension: 410881\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:48:40,605: Batch 7 subspace dimension: 442225\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:48:40,611: Batch 8 subspace dimension: 409600\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:48:40,618: Batch 9 subspace dimension: 405769\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:49:54,917: Lowest energy batch: 9\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:49:54,917: Lowest energy value: -115.15862353596414\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:49:54,917: Corresponding g_solv value: -0.0071800982859467006\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:49:54,918: -----------------------------------\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:49:54,918: Starting configuration recovery iteration 2\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:50:25,501: Batch 0 subspace dimension: 399424\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:50:25,508: Batch 1 subspace dimension: 412164\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:50:25,514: Batch 2 subspace dimension: 432964\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:50:25,519: Batch 3 subspace dimension: 400689\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:50:25,524: Batch 4 subspace dimension: 432964\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:50:25,529: Batch 5 subspace dimension: 418609\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:50:25,533: Batch 6 subspace dimension: 418609\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:50:25,538: Batch 7 subspace dimension: 425104\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:50:25,543: Batch 8 subspace dimension: 404496\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:50:25,548: Batch 9 subspace dimension: 429025\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:51:37,900: Lowest energy batch: 2\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:51:37,900: Lowest energy value: -115.1585667736213\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:51:37,901: Corresponding g_solv value: -0.007181981952470838\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:51:37,901: -----------------------------------\n",
            "sqd_pcm_entrypoint.run_function:INFO:2025-06-27 08:51:37,901: SCI_solver totally takes: 493.997501373291 seconds\n",
            "\n"
          ]
        }
      ],
      "source": [
        "print(job.logs())"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "bf0750f3",
      "metadata": {},
      "source": [
        "<span id=\"cite-this-project\" />\n",
        "\n",
        "## Citar este proyecto\n",
        "\n",
        "Si utilizas la plantilla SQD IEF-PCM en tu investigación, consulta el [repositorio](https://github.com/qiskit-community/qiskit-function-templates/tree/main/chemistry/sqd_pcm#citing-this-project) para obtener información detallada sobre cómo citarla.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d7cc1cb2",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Próximos pasos\n",
        "\n",
        "<Admonition type=\"info\" title=\"Recomendaciones\">\n",
        "  * Sigue el tutorial [«Cálculos de disolventes implícitos con Qiskit Serverless »](/docs/tutorials/implicit-solvent-calculations) para ver un ejemplo práctico de este mismo flujo de trabajo\n",
        "  * Consulte la guía sobre cómo crear una plantilla de función para [la simulación hamiltoniana](/docs/guides/function-template-hamiltonian-simulation)\n",
        "  * Consulte los archivos fuente de esta plantilla en [GitHub](https://github.com/qiskit-community/qiskit-function-templates/tree/main/chemistry/sqd_pcm)\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "aabba015",
      "metadata": {},
      "source": [
        "<span id=\"references\" />\n",
        "\n",
        "#### Referencias\n",
        "\n",
        "\\[1] Danil Kaliakin, Akhil Shajan, Fangchun Liang y Kenneth M. Merz Jr. [Implicit Solvent Sample-Based Quantum Diagonalization](https://pubs.acs.org/doi/10.1021/acs.jpcb.5c01030), The Journal of Physical Chemistry B, 2025, DOI: 10.1021/acs.jpcb.5c01030\n",
        "\n",
        "\\[2] Javier Robledo-Moreno, et al., [Chemistry Beyond Exact Solutions on a Quantum-Centric Supercomputer](https://arxiv.org/abs/2405.05068), arXiv:2405.05068 \\[quant-ph].\n",
        "\n",
        "\\[3] Jeffery Yu, et al., [Quantum-Centric Algorithm for Sample-Based Krylov Diagonalization](https://arxiv.org/abs/2501.09702), arXiv:2501.09702 \\[quant-ph].\n",
        "\n",
        "\\[4] Keita Kanno, et al., [Quantum-Selected Configuration Interaction: classical diagonalization of Hamiltonians in subspaces selected by quantum](https://arxiv.org/abs/2302.11320) computers, arXiv:2302.11320 \\[quant-ph].\n",
        "\n",
        "\\[5] Kenji Sugisaki, et al., [Hamiltonian simulation-based quantum-selected configuration interaction for large-scale electronic structure calculations with a quantum computer](https://arxiv.org/abs/2412.07218), arXiv:2412.07218 \\[quant-ph].\n",
        "\n",
        "\\[6] Mathias Mikkelsen, Yuya O. Nakagawa, [Quantum-selected configuration interaction with time-evolved state](https://arxiv.org/abs/2412.13839), arXiv:2412.13839 \\[quant-ph].\n",
        "\n",
        "\\[7] Herbert, John M. [Dielectric continuum methods for quantum chemistry. WIREs Computational Molecular Science](https://wires.onlinelibrary.wiley.com/doi/10.1002/wcms.1519), 2021, 11, 1759-0876.\n",
        "\n",
        "\\[8] Saki, A. A.; Barison, S.; Fuller, B.; Garrison, J. R.; Glick, J. R.; Johnson, C.; Mezzacapo, A.; Robledo-Moreno, J.; Rossmannek, M.; Schweigert, P. et al. Complemento Qiskit: diagonalización cuántica basada en muestras, 2024; [https://github.com/Qiskit/qiskit-addon-sqd](https://github.com/Qiskit/qiskit-addon-sqd)\n",
        "\n",
        "\\[9] Asun, Q.; Zhang, X.; Banerjee, S.; Bao, P.; Barbry, M.; Blunt, N. S.; Bogdanov, N. A.; Booth, G. H.; Chen, J.; Cui, Z.-H. PySCF: Python -simulaciones basadas en el marco de la química, 2025; [https://github.com/pyscf/pyscf](https://github.com/pyscf/pyscf)\n",
        "\n",
        "\\[10] Kevin J. Sung; et al., FFSIM: simulaciones más rápidas de circuitos cuánticos fermiónicos, 2024. [https://github.com/qiskit-community/ffsim](https://github.com/qiskit-community/ffsim)\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "id": "a1b8767d",
      "source": "© IBM Corp., 2017-2026"
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "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"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}