{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "f7d9993f",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"QUICK-PDE – Eine Qiskit-Funktion von ColibriTD\"\n",
        "description: \"Die QUICK-PDE-Funktion löst domänenspezifische partielle Differentialgleichungen mithilfe des H-DES-Algorithmus „ ColibriTD's “, der komplexe multiphysikalische Probleme lösen kann.\"\n",
        "---\n",
        "\n",
        "{/* cspell:ignore CMAES, Hypoelastic, edgecolor, royalblue, rstride, cstride, colibritd, xlabel, ylabel, zlabel, Jaffali, Pressureless, Colorplot, viridis, fontsize, fontweight */}\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2f87f5f0",
      "metadata": {},
      "source": [
        "<span id=\"quick-pde-a-qiskit-function-by-colibritd\" />\n",
        "\n",
        "# QUICK-PDE: Eine Qiskit-Funktion von ColibriTD\n",
        "\n",
        "*Siehe [API-Referenz](/docs/api/functions/colibritd-pde)*\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9cd91354",
      "metadata": {
        "tags": [
          "version-info"
        ]
      },
      "source": [
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "01701579",
      "metadata": {},
      "source": [
        "<Admonition type=\"note\">\n",
        "  Qiskit-Funktionen sind eine experimentelle Funktion, die den Nutzern des IBM Quantum® Premium Plans, des Flex Plans und des On-Prem-Plans (über IBM Quantum Platform API) zur Verfügung steht. Sie befinden sich im Status einer Vorabversion und können sich noch ändern.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "dde95705",
      "metadata": {},
      "source": [
        "<span id=\"overview\" />\n",
        "\n",
        "## Übersicht\n",
        "\n",
        "Der hier vorgestellte Solver für partielle Differentialgleichungen (PDE) ist Teil unserer Quantum Innovative Computing Kit (QUICK)-Plattform (QUICK-PDE) und als Qiskit-Funktion verfügbar. Mit der QUICK-PDE-Funktion können Sie domänenspezifische partielle Differentialgleichungen auf IBM Quantum QPUs lösen. Diese Funktion basiert auf dem Algorithmus, der in [der Beschreibung von H-DES](https://arxiv.org/abs/2410.01130) unter ColibriTD's beschrieben ist. Dieser Algorithmus kann komplexe multiphysikalische Probleme lösen, angefangen bei der numerischen Strömungsmechanik (CFD) und Materialverformung (MD) bis hin zu weiteren Anwendungsfällen, die in Kürze folgen werden.\n",
        "\n",
        "Um die Differentialgleichungen zu lösen, werden die Versuchslösungen als Linearkombinationen orthogonaler Funktionen kodiert (typischerweise Tschebyscheff-Polynome, genauer gesagt $2^n$, wobei $n$ die Anzahl der Qubits ist, die Ihre Funktion kodieren), die durch die Winkel eines variablen Quantenkreises (VQC) parametrisiert sind. Der Ansatz erzeugt einen Zustand, der die Funktion kodiert, die durch Beobachtungswerte ausgewertet wird, deren Kombinationen es ermöglichen, die Funktion in allen Punkten auszuwerten. Sie können dann die Verlustfunktion, in der die Differentialgleichungen kodiert sind, auswerten und die Winkel in einer hybriden Schleife fein abstimmen, wie im Folgenden gezeigt. Die Probelösungen nähern sich schrittweise den tatsächlichen Lösungen an, bis Sie ein zufriedenstellendes Ergebnis erzielen.\n",
        "\n",
        "![Arbeitsablauf der QUICK-PDE-Funktion](https://quantum.cloud.ibm.com/docs/images/guides/colibritd-equation-solver/diagram.svg)\n",
        "\n",
        "Zusätzlich zu dieser hybriden Schleife können Sie auch verschiedene Optimierer miteinander verketten. Dies ist nützlich, wenn Sie eine globale Optimierung wünschen, um einen guten Satz von Winkeln zu finden, und dann eine feiner abgestimmte Optimierung, um einem Gradienten zum besten Satz von benachbarten Winkeln zu folgen. Im Falle der numerischen Strömungsmechanik (CFD) liefert die Standardoptimierungssequenz die besten Ergebnisse. Im Falle der Materialverformung (MD) liefert die Standardsequenz zwar gute Ergebnisse, aber Sie können sie weiter konfigurieren, um problemspezifische Vorteile zu erzielen.\n",
        "\n",
        "Beachten Sie, dass wir für jede Variable der Funktion die Anzahl der Qubits angeben (mit denen Sie spielen können). Durch das Stapeln von 10 identischen Schaltkreisen und die Auswertung der 10 identischen Observablen auf verschiedenen Qubits in einem großen Schaltkreis kann man im Rahmen des CMA-Optimierungsprozesses mit Hilfe der Noise-Learner-Methode das Rauschen reduzieren und die Anzahl der benötigten Schüsse erheblich verringern.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "be28949c",
      "metadata": {},
      "source": [
        "<span id=\"computational-fluid-dynamics\" />\n",
        "\n",
        "### Numerische Strömungsmechanik\n",
        "\n",
        "**Die nichtviskose Burgers-Gleichung** modelliert die Strömung nichtviskoser Fluide wie folgt:\n",
        "\n",
        "$\\frac{\\partial u}{\\partial t} + u\\frac{\\partial u}{\\partial x} = 0,$\n",
        "\n",
        "$u$ stellt das Strömungsgeschwindigkeitsfeld dar. Dieser Anwendungsfall weist eine zeitliche Randbedingung auf: Sie können die Anfangsbedingung festlegen und das System anschließend sich selbst überlassen. Derzeit sind als Anfangsbedingungen ausschließlich lineare Funktionen zulässig: $ax + b$. Die analytische Lösung lautet:\n",
        "\n",
        "$u(t, x) = \\frac{ax + b}{at + 1}.$\n",
        "\n",
        "**Die drucklosen Euler-Gleichungen** modellieren die Strömung eines kompressiblen, inviskosen Fluids mit Dämpfung wie folgt:\n",
        "\n",
        "$\\frac{\\partial g}{\\partial t} + u\\frac{\\partial g}{\\partial x} + g\\frac{\\partial u}{\\partial x} = 0,$\n",
        "\n",
        "$u\\frac{\\partial g}{\\partial t} + g\\frac{\\partial u}{\\partial t} + u^2\\frac{\\partial g}{\\partial x} + 2gu\\frac{\\partial u}{\\partial x} + \\frac{\\mu}{(1+t)^{\\lambda}} g u = 0,$\n",
        "\n",
        "$g$ steht für das Dichtefeld, $u$ für das Geschwindigkeitsfeld und $\\mu$ für einen Dämpfungskoeffizienten. In unserer Formulierung setzen wir $\\lambda = 1$ an, sodass dieser im Folgenden nicht als Parameter verwendet wird. Dieser Anwendungsfall weist zeitliche Randbedingungen auf: $g(0, x) = e^{-x}$ und $u(0, x) = x$. Die analytische Lösung lautet:\n",
        "\n",
        "$g(t, x) = \\frac{1-\\mu}{(1+t)^{1-\\mu} - \\mu} \\exp\\!\\left(\\frac{(\\mu-1)\\, x}{(1+t)^{1-\\mu} - \\mu}\\right),$\n",
        "\n",
        "$u(t, x) = \\frac{(1-\\mu)\\, x}{\\left((1+t)^{1-\\mu} - \\mu\\right)(1+t)^{\\mu}}.$\n",
        "\n",
        "Die Argumente für die CFD-Differentialgleichungen sind auf einem festen Gitter wie folgt:\n",
        "\n",
        "* $t$ liegt zwischen 0 und 0.95 mit 41 Messpunkten. $x$ liegt zwischen 0 und 0.95 mit 41 Messpunkten.\n",
        "\n",
        "<span id=\"material-deformation\" />\n",
        "\n",
        "### Materialverformung\n",
        "\n",
        "Dieser Anwendungsfall konzentriert sich auf **die hypoelastische Verformung im Rahmen eines eindimensionalen Zugversuchs**, bei dem ein im Raum festgelegter Stab an seinem anderen Ende gezogen wird. Wir beschreiben das Problem wie folgt:\n",
        "\n",
        "$u' - \\frac{\\sigma}{3K} - \\frac{2}{\\sqrt{3}}\\epsilon_0\\left(\\frac{\\sigma'}{\\sigma_0\\sqrt{3}}\\right)^n = 0,$\n",
        "\n",
        "$\\sigma' - b = 0,$\n",
        "\n",
        "$K$ steht für den Volumenmodul des gedehnten Materials, $n$ für den Exponenten eines Potenzgesetzes, $b$ für die Kraft pro Masseneinheit, $\\epsilon_0$ für die Grenze der proportionalen Spannung, $\\sigma_0$ für die Grenze der proportionalen Dehnung, $u$ für die Spannungsfunktion und $\\sigma$ für die Dehnungsfunktion. Die analytische Lösung lautet:\n",
        "\n",
        "$\\sigma(x) = \\sigma_0 - bx,$\n",
        "\n",
        "$u(x) = -\\frac{3^{-(3+n)/2}}{2bK(1+n)\\,\\sigma_0^{n}}\\Biggl[3^{(1+n)/2}b^2\\sigma_0^n(1+n)x^2 - 2\\cdot 3^{(1+n)/2}b\\sigma_0^n(1+n)\\sigma_0 x - 12\\epsilon_0 K\\sigma_0^{1+n}$\n",
        "$- 12b\\epsilon_0 K\\sigma_0^n x\\left(\\frac{-bx+\\sigma_0}{\\sigma_0}\\right)^n + 12\\epsilon_0 K\\sigma_0^{n+1}\\left(\\frac{-bx+\\sigma_0}{\\sigma_0}\\right)^n - 12\\epsilon_0 K \\sigma_0^{1+n}\\Biggr],$\n",
        "\n",
        "wobei $\\sigma_0 = g(0)$ die Randbedingung für die Dehnung am Punkt $x=0$ ist.\n",
        "\n",
        "Der betrachtete Stab ist von einheitlicher Länge. Für diesen Anwendungsfall gibt es eine Randbedingung für die Oberflächenspannung $t$, d. h. den Arbeitsaufwand, der erforderlich ist, um den Stab zu dehnen.\n",
        "\n",
        "Die Argumente für die Differentialgleichungen von MD sind auf einem festen Gitter wie folgt:\n",
        "\n",
        "* $x$ liegt zwischen 0 und 1 und umfasst 30 Messpunkte.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b34fe075",
      "metadata": {},
      "source": [
        "<span id=\"benchmarks\" />\n",
        "\n",
        "## Benchmarks\n",
        "\n",
        "Die folgende Tabelle enthält Statistiken zu verschiedenen Durchläufen unserer Funktion.\n",
        "\n",
        "| Beispiel                         | Anzahl der Qubits | Initialisierung       | Fehler    | Gesamtzeit (Min.) | Laufzeitverbrauch (min) |\n",
        "| -------------------------------- | ----------------- | --------------------- | --------- | ----------------- | ----------------------- |\n",
        "| Unviskose Burgers'sche Gleichung | 50                | `PHYSICALLY_INFORMED` | $10^{-2}$ | 66                | 25 GB                   |\n",
        "| Drucklose Euler-Gleichungen      | 70                | `PHYSICALLY_INFORMED` | $10^{-2}$ | 48                | 34                      |\n",
        "| Hypoelastischer 1D Zugversuch    | 18.               | `RANDOM`              | $10^{-2}$ | 123               | 100                     |\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "73390a19",
      "metadata": {},
      "source": [
        "<span id=\"get-started\" />\n",
        "\n",
        "## Erste Schritte\n",
        "\n",
        "Füllen Sie das [Formular](https://forms.cloud.microsoft/e/3Wi9cbjQPK) aus, um Zugriff auf die QUICK-PDE-Funktion zu beantragen. Angenommen, Sie haben [Ihr Konto](/docs/guides/functions-get-started#install-qiskit-functions-catalog-client) bereits in Ihrer lokalen Umgebung gespeichert, wählen Sie die Funktion wie folgt aus:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "95a715d2",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_ibm_catalog import QiskitFunctionsCatalog\n",
        "\n",
        "catalog = QiskitFunctionsCatalog(\n",
        "    channel=\"ibm_cloud / ibm_quantum_platform\",\n",
        "    instance=\"USER_CRN / HGP\",\n",
        "    token=\"USER_API_KEY / IQP_API_TOKEN\",\n",
        ")\n",
        "\n",
        "catalog = QiskitFunctionsCatalog(channel=\"ibm_quantum_platform\")\n",
        "\n",
        "# Verify that you have access to the function\n",
        "catalog.list()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "4ec04623",
      "metadata": {},
      "outputs": [],
      "source": [
        "quick = catalog.load(\"colibritd/quick-pde\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e8837f5f",
      "metadata": {},
      "source": [
        "<span id=\"examples\" />\n",
        "\n",
        "## Beispiele\n",
        "\n",
        "Probieren Sie für den Anfang eines der folgenden Beispiele aus:\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "446ac943",
      "metadata": {},
      "source": [
        "<span id=\"inviscid-burgers-equation-cfd\" />\n",
        "\n",
        "### Die Gleichung von Inviscid Burgers (CFD)\n",
        "\n",
        "Für die Burgers-Gleichung ergeben sich bei folgenden Anfangsbedingungen: $u(0,x) = x$ folgende Ergebnisse:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "d56e1440",
      "metadata": {},
      "outputs": [],
      "source": [
        "# launch the simulation with initial conditions u(0,x) = a*x + b\n",
        "job = quick.run(\n",
        "    use_case=\"CFD_BURGER\", physical_parameters={\"a\": 1.0, \"b\": 0.0}\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "03998691",
      "metadata": {},
      "source": [
        "Überprüfen Sie [den Status](/docs/guides/functions-get-started#check-job-status) Ihrer Qiskit-Funktions-Workload oder rufen Sie [die Ergebnisse](/docs/guides/functions-get-started#retrieve-results) wie folgt ab:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "856fe992",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Print the ID so you can use it later, if necessary\n",
        "print(job.job_id)\n",
        "print(job.status())\n",
        "solution = job.result()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "c42aba9b",
      "metadata": {},
      "outputs": [],
      "source": [
        "import numpy as np\n",
        "import matplotlib.pyplot as plt\n",
        "\n",
        "\n",
        "def plot_result_3d(result):\n",
        "    fig = plt.figure()\n",
        "    ax = fig.add_subplot(projection=\"3d\")\n",
        "\n",
        "    t, x = np.meshgrid(result[\"samples\"][\"t\"], result[\"samples\"][\"x\"])\n",
        "\n",
        "    ax.plot_surface(\n",
        "        t,\n",
        "        x,\n",
        "        result[\"functions\"][\"u\"],\n",
        "        edgecolor=\"royalblue\",\n",
        "        lw=0.25,\n",
        "        rstride=26,\n",
        "        cstride=26,\n",
        "        alpha=0.3,\n",
        "    )\n",
        "    ax.scatter(t, x, result[\"functions\"][\"u\"], marker=\".\")\n",
        "    ax.set(xlabel=\"t\", ylabel=\"x\", zlabel=\"u(t,x)\")\n",
        "\n",
        "    plt.show()\n",
        "\n",
        "\n",
        "# Call\n",
        "plot_result_3d(solution)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4408d52e",
      "metadata": {},
      "source": [
        "<span id=\"pressureless-eulers-equation-cfd\" />\n",
        "\n",
        "### Drucklose Euler-Gleichung (CFD)\n",
        "\n",
        "Für die Eulergleichung ergeben sich bei den Anfangsbedingungen $g(0, x) = e^{-x}$ und $u(0, x) = x$ sowie für die gegebenen Werte $\\mu$ (hier: $\\mu = 0.1$ ) und $\\lambda = 1$ folgende Ergebnisse:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "e0412513",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Launches the solving for an arbitrary mu\n",
        "job = quick.run(use_case=\"CFD_EULER\", physical_parameters={\"mu\": 0.1})\n",
        "\n",
        "solution = job.result()\n",
        "\n",
        "\n",
        "# Colorplot function\n",
        "def plot_result_2d(result):\n",
        "    fig, axes = plt.subplots(1, 2, figsize=(14, 5))\n",
        "\n",
        "    configs = {\n",
        "        \"g\": {\"cmap\": \"viridis\", \"title\": \"g(t, x)\"},\n",
        "        \"u\": {\"cmap\": \"plasma\", \"title\": \"u(t, x)\"},\n",
        "    }\n",
        "\n",
        "    t = result[\"samples\"][\"t\"]\n",
        "    x = result[\"samples\"][\"x\"]\n",
        "\n",
        "    for ax, (field, cfg) in zip(axes, configs.items()):\n",
        "        v = result[\"functions\"][field]\n",
        "\n",
        "        im = ax.contourf(t, x, v, levels=50, cmap=cfg[\"cmap\"])\n",
        "        fig.colorbar(im, ax=ax, label=cfg[\"title\"])\n",
        "\n",
        "        ax.set_xlabel(\"t\")\n",
        "        ax.set_ylabel(\"x\")\n",
        "        ax.set_title(cfg[\"title\"], fontsize=13, fontweight=\"bold\")\n",
        "\n",
        "    plt.tight_layout()\n",
        "    plt.show()\n",
        "\n",
        "\n",
        "plot_result_2d(solution)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "dbbd4509",
      "metadata": {},
      "source": [
        "<span id=\"material-deformation\" />\n",
        "\n",
        "### Materialverformung\n",
        "\n",
        "Für den Anwendungsfall \"Materialverformung\" werden die physikalischen Parameter Ihres Materials und die angewandte Kraft wie folgt benötigt:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "a568e325",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Select the properties of your material\n",
        "job = quick.run(\n",
        "    use_case=\"MD\",\n",
        "    physical_parameters={\n",
        "        \"t\": 12.0,\n",
        "        \"K\": 100.0,\n",
        "        \"n\": 4.0,\n",
        "        \"b\": 10.0,\n",
        "        \"epsilon_0\": 0.1,\n",
        "        \"sigma_0\": 5.0,\n",
        "    },\n",
        ")\n",
        "\n",
        "# Plot the result\n",
        "solution = job.result()\n",
        "\n",
        "_ = plt.figure()\n",
        "stress_plot = plt.subplot(211)\n",
        "plt.plot(solution[\"samples\"][\"x\"], solution[\"functions\"][\"u\"])\n",
        "strain_plot = plt.subplot(212)\n",
        "plt.plot(solution[\"samples\"][\"x\"], solution[\"functions\"][\"sigma\"])\n",
        "\n",
        "plt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f1cfa869",
      "metadata": {},
      "source": [
        "Im Folgenden finden Sie ein Beispiel dafür, wie Sie den Funktionswert für einen bestimmten Koordinatensatz ermitteln können:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "c5193114",
      "metadata": {},
      "outputs": [],
      "source": [
        "# u(t=0.2, x=0.7) == 2\n",
        "assert solution[\"samples\"][\"t\"][1] == 0.2\n",
        "assert solution[\"samples\"][\"x\"][2] == 0.7\n",
        "assert solution[\"functions\"][\"u\"][1, 2] == 2"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "04236c83",
      "metadata": {},
      "source": [
        "<span id=\"fetch-error-messages\" />\n",
        "\n",
        "## Fehlermeldungen abrufen\n",
        "\n",
        "Wenn Ihr Workload-Status `ERROR` lautet, verwenden Sie `job.error_message()` , um die Fehlermeldung zur Fehlersuche abzurufen, wie folgt:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "90c6de7c",
      "metadata": {},
      "outputs": [],
      "source": [
        "job = quick.run(use_case=\"MD\", physical_params={})\n",
        "\n",
        "print(job.error_message())\n",
        "\n",
        "\n",
        "# A wrapper can also be used for a more human readable version\n",
        "def pprint_error(job):\n",
        "    print(\"\".join(eval(job.error_message())[\"error\"]))\n",
        "\n",
        "\n",
        "print(\"___\")\n",
        "pprint_error(job)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e9ec2e67",
      "metadata": {},
      "source": [
        "<span id=\"get-support\" />\n",
        "\n",
        "## Unterstützung anfordern\n",
        "\n",
        "Für Support wenden Sie sich bitte an [qiskit-function-support@colibritd.com](mailto:qiskit-function-support@colibritd.com).\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5a6a25c8",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Nächste Schritte\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Empfehlungen\">\n",
        "  * Füllen Sie das Formular aus, um [Zugriff auf die QUICK-PDE-Funktion zu beantragen](https://forms.cloud.microsoft/e/3Wi9cbjQPK).\n",
        "  * Rufen Sie die [API-Referenz](/docs/api/functions/colibritd-pde) für diese Qiskit-Funktion auf.\n",
        "  * Versuchen Sie die Modellierung einer fließenden, nicht viskosen Flüssigkeit mit QUICK-PDE im [Tutorial](/docs/tutorials/colibritd-pde).\n",
        "  * Rezension [Jaffali, H., et al. (2025).  H-DES: Ein quanten-klassischer Hybrid-Differentialgleichungslöser. arXiv Vorabdruck arXiv:2410.01130](https://arxiv.org/abs/2410.01130).\n",
        "</Admonition>\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
}