QUICK-PDE: Funkcja Qiskit od ColibriTD
Funkcje Qiskit to eksperymentalna funkcjonalność dostępna dla użytkowników planów IBM Quantum® Premium Plan, Flex Plan oraz On-Prem (przez IBM Quantum Platform API). Są one w fazie wstępnego wydania i mogą ulec zmianie.
Przegląd
Solver równań różniczkowych cząstkowych (PDE) przedstawiony tutaj jest częścią naszej platformy Quantum Innovative Computing Kit (QUICK) (QUICK-PDE) i jest dostarczany jako Funkcja Qiskit. Za pomocą funkcji QUICK-PDE możesz rozwiązywać dziedzinowe równania różniczkowe cząstkowe na QPU IBM Quantum. Funkcja ta opiera się na algorytmie opisanym w artykule ColibriTD dotyczącym H-DES. Algorytm ten potrafi rozwiązywać złożone problemy wielofizyczne, zaczynając od Obliczeniowej Dynamiki Płynów (CFD) i Deformacji Materiałów (MD), a kolejne zastosowania pojawią się wkrótce.
Aby zmierzyć się z równaniami różniczkowymi, rozwiązania próbne są kodowane jako liniowe kombinacje funkcji ortogonalnych (zazwyczaj wielomianów Czebyszewa, a dokładniej z nich, gdzie to liczba Qubitów kodujących twoją funkcję), parametryzowane kątami Zmiennego Obwodu Kwantowego (VQC). Ansatz generuje stan kodujący funkcję, która jest oceniana przez obserwable, których kombinacje pozwalają na wyznaczenie funkcji we wszystkich punktach. Możesz następnie ocenić funkcję straty, w której zakodowane są równania różniczkowe, i doprecyzować kąty w pętli hybrydowej, jak pokazano poniżej. Rozwiązania próbne stopniowo zbliżają się do rzeczywistych rozwiązań, aż uzyskasz zadowalający wynik.
Oprócz tej pętli hybrydowej, możesz też łączyć ze sobą różne optymalizatory. Jest to przydatne, gdy chcesz, aby globalny optymalizator znalazł dobry zestaw kątów, a następnie bardziej precyzyjny optymalizator podążał gradientem do najlepszego zestawu sąsiednich kątów. W przypadku obliczeniowej dynamiki płynów (CFD) domyślna sekwencja optymalizacji daje najlepsze wyniki – natomiast w przypadku deformacji materiałów (MD), mimo że wartości domyślne zapewniają dobre rezultaty, możesz ją dalej konfigurować z korzyścią dla konkretnego problemu.
Zauważ, że dla każdej zmiennej funkcji określamy liczbę Qubitów (którą możesz modyfikować). Układając 10 identycznych Circuit i wyznaczając 10 identycznych obserwabli na różnych Qubitach w ramach jednego dużego Circuit, możesz ograniczać szum w procesie optymalizacji CMA, opierając się na metodzie uczenia szumu, i znacznie zmniejszyć potrzebną liczbę pomiarów.
Wejście/wyjście
Obliczeniowa Dynamika Płynów
Bezlepkowe równanie Burgersa modeluje przepływ nielepkich płynów w następujący sposób:
reprezentuje pole prędkości płynu. Ten przypadek użycia ma czasowy warunek brzegowy: możesz wybrać warunek początkowy, a następnie pozwolić systemowi się zrelaksować. Obecnie akceptowane są wyłącznie liniowe warunki początkowe: .
Argumenty równań różniczkowych CFD są na stałej siatce, jak następuje:
- jest z przedziału od 0 do 0,95 z 30 punktami próbkowania. jest z przedziału od 0 do 0,95 z krokiem 0,2375.
Deformacja Materiałów
Ten przypadek użycia dotyczy hipoelastycznej deformacji przy jednowymiarowym teście rozciągania, w którym pręt zamocowany w przestrzeni jest ciągnięty na swoim drugim końcu. Problem opisujemy w następujący sposób:
reprezentuje moduł objętościowy rozciąganego materiału, wykładnik prawa potęgowego, siłę na jednostkę masy, proporcjonalny limit naprężenia, proporcjonalny limit odkształcenia, funkcję naprężenia, a funkcję odkształcenia.
Rozważany pręt ma długość jednostkową. Ten przypadek użycia ma warunek brzegowy dla naprężenia powierzchniowego , czyli ilości pracy potrzebnej do rozciągnięcia pręta.
Argumenty równań różniczkowych MD są na stałej siatce, jak następuje:
- jest z przedziału od 0 do 1 z krokiem 0,04.
Wejście
Aby uruchomić Funkcję Qiskit QUICK-PDE, możesz dostosować następujące parametry:
| Nazwa | Typ | Opis | Specyficzny dla przypadku użycia | Przykład |
|---|---|---|---|---|
| use_case | Literal["MD", "CFD"] | Przełącznik wyboru układu równań różniczkowych do rozwiązania | Nie | "CFD" |
| parameters | dict[str, Any] | Parametry równania różniczkowego (szczegóły w następnej tabeli) | Nie | {"a": 1.0, "b": 1.0} |
| nb_qubits | Optional[dict[str, dict[str, int]]] | Liczba Qubitów na funkcję i na zmienną. Funkcja dobiera zoptymalizowane wartości, ale jeśli chcesz spróbować znaleźć lepszą kombinację, możesz nadpisać wartości domyślne | Nie | {"u": {"x": 1, "t":3}} |
| depth | Optional[dict[str, int]] | Głębokość ansatza na funkcję. Funkcja dobiera zoptymalizowane wartości, ale jeśli chcesz spróbować znaleźć lepszą kombinację, możesz nadpisać wartości domyślne | Nie | {"u": 4} |
| optimizer | Optional[list[str]] | Optymalizatory do użycia: "CMAES" z biblioteki pythonowej cma lub jeden z optymalizatorów scipy | MD | "SLSQP" |
| shots | Optional[list[int]] | Liczba pomiarów używana do uruchomienia każdego Circuit. Ponieważ potrzebnych jest kilka kroków optymalizacji, długość listy musi być równa liczbie używanych optymalizatorów (4 w przypadku CFD). Domyślnie [50_000] * nb_optimizers dla MD i [5_00, 2_000, 5_000, 10_000] dla CFD | Nie | [15_000, 30_000] |
| optimizer_options | Optional[dict[str, Any]] | Opcje przekazywane do optymalizatora. Szczegóły zależą od użytego optymalizatora; w celu uzyskania informacji szczegółowych zapoznaj się z dokumentacją używanego optymalizatora | MD | {"maxiter": 50 } |
| initialization | Optional[Literal["RANDOM", "PHYSICALLY_INFORMED"]] | Czy zacząć od losowych kątów, czy od kątów dobranych inteligentnie. Uwaga: inteligentnie dobrane kąty mogą nie działać w 100% przypadków. Domyślnie "PHYSICALLY_INFORMED". | Nie | "RANDOM" |
| backend_name | Optional[str] | Nazwa Backend do użycia. | Nie | "ibm_torino" |
| mode | Optional[Literal["job", "session", "batch"]] | Tryb wykonania do użycia. Domyślnie "job". | Nie | "job" |
Parametry równania różniczkowego (parametry fizyczne i warunek brzegowy) powinny być zgodne z podanym formatem:
| Przypadek użycia | Klucz | Typ wartości | Opis | Przykład |
|---|---|---|---|---|
| CFD | a | float | Współczynnik wartości początkowych | 1.0 |
| CFD | b | float | Przesunięcie wartości początkowych | 1.0 |
| MD | t | float | naprężenie powierzchniowe | 12.0 |
| MD | K | float | moduł objętościowy | 100.0 |
| MD | n | int | prawo potęgowe | 4.0 |
| MD | b | float | siła na jednostkę masy | 10.0 |
| MD | epsilon_0 | float | proporcjonalny limit naprężenia | 0.1 |
| MD | sigma_0 | float | proporcjonalny limit odkształcenia | 5.0 |
Wyjście
Wyjście to słownik zawierający listę punktów próbkowania oraz wartości funkcji w każdym z tych punktów:
# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib numpy qiskit-ibm-catalog
from numpy import array
solution = {
"functions": {
"u": array(
[
[0.01, 0.1, 1],
[0.02, 0.2, 2],
[0.03, 0.3, 3],
[0.04, 0.4, 4],
]
),
},
"samples": {
"t": array([0.1, 0.2, 0.3, 0.4]),
"x": array([0.5, 0.6, 0.7]),
},
}
Kształt tablicy rozwiązania zależy od próbek zmiennych:
assert len(solution["functions"]["u"].shape) == len(solution["samples"])
for col_size, samples in zip(
solution["functions"]["u"].shape, solution["samples"].values()
):
assert col_size == len(samples)
Odwzorowanie między punktami próbkowania zmiennych funkcji a wymiarami tablicy rozwiązania jest wykonywane w kolejności alfanumerycznej nazwy zmiennej. Na przykład, jeśli zmiennymi są "t" i "x", wiersz solution["functions"]["u"] reprezentuje wartości rozwiązania dla stałego "t", a kolumna solution["functions"]["u"] reprezentuje wartości rozwiązania dla stałego "x".
Poniżej przykład, jak uzyskać wartość funkcji dla konkretnego zestawu współrzędnych:
# u(t=0.2, x=0.7) == 2
assert solution["samples"]["t"][1] == 0.2
assert solution["samples"]["x"][2] == 0.7
assert solution["functions"]["u"][1, 2] == 2
Testy porównawcze
Poniższa tabela przedstawia statystyki różnych przebiegów naszej funkcji.
| Przykład | Liczba Qubitów | Inicjalizacja | Błąd | Całkowity czas (min) | Użycie środowiska uruchomieniowego (min) |
|---|---|---|---|---|---|
| Bezlepkowe równanie Burgersa | 50 | PHYSICALLY_INFORMED | 66 | 25 | |
| Hipoelastyczny 1D test rozciągania | 18 | RANDOM | 123 | 100 |
Pierwsze kroki
Wypełnij formularz, aby poprosić o dostęp do funkcji QUICK-PDE. Następnie, zakładając że masz już zapisane konto w swoim lokalnym środowisku, wybierz funkcję w następujący sposób:
from qiskit_ibm_catalog import QiskitFunctionsCatalog
catalog = QiskitFunctionsCatalog(channel="ibm_quantum_platform")
quick = catalog.load("colibritd/quick-pde")
Przykłady
Aby zacząć, wypróbuj jeden z poniższych przykładów:
Obliczeniowa Dynamika Płynów (CFD)
Gdy warunki początkowe są ustawione na , wyniki są następujące:
# launch the simulation with initial conditions u(0,x) = a*x + b
job = quick.run(use_case="cfd", physical_parameters={"a": 1.0, "b": 0.0})
Sprawdź status swojego obciążenia Funkcji Qiskit lub pobierz wyniki w następujący sposób:
print(job.status())
solution = job.result()
'QUEUED'
import numpy as np
import matplotlib.pyplot as plt
_ = plt.figure()
ax = plt.axes(projection="3d")
# plot the solution using the 3d plotting capabilities of pyplot
t, x = np.meshgrid(solution["samples"]["t"], solution["samples"]["x"])
ax.plot_surface(
t,
x,
solution["functions"]["u"],
edgecolor="royalblue",
lw=0.25,
rstride=26,
cstride=26,
alpha=0.3,
)
ax.scatter(t, x, solution["functions"]["u"], marker=".")
ax.set(xlabel="t", ylabel="x", zlabel="u(t,x)")
plt.show()

Deformacja Materiałów
Przypadek użycia deformacji materiałów wymaga parametrów fizycznych materiału i przyłożonej siły, jak następuje:
import matplotlib.pyplot as plt
# select the properties of your material
job = quick.run(
use_case="md",
physical_parameters={
"t": 12.0,
"K": 100.0,
"n": 4.0,
"b": 10.0,
"epsilon_0": 0.1,
"sigma_0": 5.0,
},
)
# plot the result
solution = job.result()
_ = plt.figure()
stress_plot = plt.subplot(211)
plt.plot(solution["samples"]["x"], solution["functions"]["u"])
strain_plot = plt.subplot(212)
plt.plot(solution["samples"]["x"], solution["functions"]["sigma"])
plt.show()
Pobieranie komunikatów o błędach
Jeśli status twojego obciążenia to ERROR, użyj job.error_message(), aby pobrać komunikat o błędzie pomocny przy debugowaniu, w następujący sposób:
job = quick.run(use_case="mdf", physical_params={})
print(job.error_message())
# or write a wrapper around it for a more human readable version
def pprint_error(job):
print("".join(eval(job.error_message())["error"]))
print("___")
pprint_error(job)
{"error": ["qiskit.exceptions.QiskitError: 'Unknown argument \"physical_params\", did you make a typo? -- https://docs.quantum.ibm.com/errors#1804'\n"]}
___
qiskit.exceptions.QiskitError: 'Unknown argument "physical_params", did you make a typo? -- https://docs.quantum.ibm.com/errors#1804'
Uzyskaj wsparcie
W celu uzyskania wsparcia skontaktuj się pod adresem qiskit-function-support@colibritd.com.
Kolejne kroki
- Wypełnij formularz, aby poprosić o dostęp do funkcji QUICK-PDE.
- Wypróbuj modelowanie przepływu nielepkiego płynu za pomocą QUICK-PDE w samouczku.
- Zapoznaj się z Jaffali, H., et al. (2025). H-DES: a Quantum-Classical Hybrid Differential Equation Solver. arXiv preprint arXiv:2410.01130.