Перейти до основного вмісту

QUICK-PDE: функція Qiskit від ColibriTD

примітка

Функції Qiskit — це експериментальна можливість, доступна користувачам IBM Quantum® Premium Plan, Flex Plan та On-Prem (через IBM Quantum Platform API) Plan. Вони перебувають у статусі попереднього релізу та можуть змінюватись.

Огляд

Розв'язувач диференціальних рівнянь у частинних похідних (PDE), представлений тут, є частиною нашої платформи Quantum Innovative Computing Kit (QUICK) (QUICK-PDE) і запакований як функція Qiskit. За допомогою функції QUICK-PDE ти можеш розв'язувати предметно-орієнтовані диференціальні рівняння в частинних похідних на QPU IBM Quantum. Ця функція базується на алгоритмі, описаному в статті ColibriTD про H-DES. Цей алгоритм може розв'язувати складні мультифізичні задачі, починаючи з обчислювальної гідродинаміки (CFD) та деформації матеріалів (MD), і незабаром з'являться нові варіанти використання.

Щоб впоратися з диференціальними рівняннями, пробні розв'язки кодуються як лінійні комбінації ортогональних функцій (зазвичай поліноми Чебишева, і конкретніше 2n2^n таких, де nn — кількість кубітів, що кодують твою функцію), параметризовані кутами Змінного Квантового Ланцюга (VQC). Анзац генерує стан, що кодує функцію, яку обчислюють спостережувані величини, комбінації яких дозволяють обчислити функцію у всіх точках. Потім ти можеш обчислити функцію втрат, у якій закодовано диференціальні рівняння, та налаштувати кути в гібридному циклі, як показано нижче. Пробні розв'язки поступово наближаються до фактичних розв'язків, доки не буде досягнуто задовільного результату.

Робочий процес функції QUICK-PDE

На додаток до цього гібридного циклу, ти також можеш поєднувати різні оптимізатори в ланцюжок. Це корисно, коли потрібно, щоб глобальний оптимізатор знайшов хороший набір кутів, а потім точніший оптимізатор пішов за градієнтом до найкращого набору сусідніх кутів. У випадку обчислювальної гідродинаміки (CFD) стандартна послідовність оптимізації дає найкращі результати — але у випадку деформації матеріалів (MD), хоча стандартні налаштування і дають хороші результати, ти можеш налаштувати її додатково для переваг, специфічних для конкретної задачі.

Зауваж, що для кожної змінної функції ми вказуємо кількість кубітів (з якою ти можеш експериментувати). Стекуючи 10 ідентичних схем та обчислюючи 10 ідентичних спостережуваних на різних кубітах в одній великій схемі, ти можеш знижувати шуми в процесі CMA-оптимізації, спираючись на метод навчання шумів, та значно зменшити потрібну кількість знімків (shots).

Вхідні/вихідні дані

Обчислювальна гідродинаміка

Невʼязке рівняння Бюргерса моделює потік невʼязкої рідини таким чином:

ut+uux=0,\frac{\partial u}{\partial t} + u\frac{\partial u}{\partial x} = 0,

uu представляє поле швидкості рідини. Цей варіант використання має часову граничну умову: ти можеш задати початкову умову, а потім дозволити системі розслабитись. Наразі єдиними прийнятними початковими умовами є лінійні функції: ax+bax + b.

Аргументи диференціальних рівнянь CFD знаходяться на фіксованій сітці, таким чином:

  • tt знаходиться між 0 і 0.95 з 30 точками вибірки. xx знаходиться між 0 і 0.95 з кроком 0.2375.

Деформація матеріалів

Цей варіант використання зосереджений на гіпопружній деформації з одновимірним випробуванням на розтяг, у якому стержень, закріплений в просторі, тягнуть за інший кінець. Ми описуємо задачу таким чином:

uσ3K23ϵ0(σσ03)n=0u' - \frac{\sigma}{3K} - \frac{2}{\sqrt{3}}\epsilon_0\left(\frac{\sigma'}{\sigma_0\sqrt{3}}\right)^n = 0

σb=0,\sigma' - b = 0,

KK представляє об'ємний модуль матеріалу, що розтягується, nn — показник степеневого закону, bb — силу на одиницю маси, ϵ0\epsilon_0 — межу пропорційного напруження, σ0\sigma_0 — межу пропорційної деформації, uu — функцію напруження, а σ\sigma — функцію деформації.

Розглянутий стержень має одиничну довжину. Цей варіант використання має граничну умову для поверхневого напруження tt, тобто кількість роботи, необхідної для розтягування стержня.

Аргументи диференціальних рівнянь MD знаходяться на фіксованій сітці, таким чином:

  • xx знаходиться між 0 і 1 з кроком 0.04.

Вхідні дані

Щоб запустити функцію Qiskit QUICK-PDE, ти можеш налаштувати такі параметри:

НазваТипОписСпецифічний для варіантуПриклад
use_caseLiteral["MD", "CFD"]Перемикач для вибору системи диференціальних рівнянь для розв'язанняНі"CFD"
parametersdict[str, Any]Параметри диференціального рівняння (докладніше дивись у наступній таблиці)Ні{"a": 1.0, "b": 1.0}
nb_qubitsOptional[dict[str, dict[str, int]]]Кількість кубітів на функцію та на змінну. Функція вибирає оптимізовані значення, але якщо ти хочеш спробувати знайти кращу комбінацію, можеш перевизначити стандартні значенняНі{"u": {"x": 1, "t":3}}
depthOptional[dict[str, int]]Глибина анзацу на функцію. Функція вибирає оптимізовані значення, але якщо ти хочеш спробувати знайти кращу комбінацію, можеш перевизначити стандартні значенняНі{"u": 4}
optimizerOptional[list[str]]Оптимізатори для використання: або "CMAES" з бібліотеки Python cma, або один з оптимізаторів scipyMD"SLSQP"
shotsOptional[list[int]]Кількість знімків для запуску кожної схеми. Оскільки потрібно кілька кроків оптимізації, довжина списку має дорівнювати кількості використовуваних оптимізаторів (4 для CFD). За замовчуванням [50_000] * nb_optimizers для MD і [5_00, 2_000, 5_000, 10_000] для CFDНі[15_000, 30_000]
optimizer_optionsOptional[dict[str, Any]]Параметри для передачі оптимізатору. Деталі цього вхідного значення залежать від використовуваного оптимізатора; для подробиць звертайся до документації відповідного оптимізатораMD{"maxiter": 50 }
initializationOptional[Literal["RANDOM", "PHYSICALLY_INFORMED"]]Чи починати з випадкових кутів, чи з розумно обраних. Зауваж, що розумно обрані кути можуть не спрацювати в 100% випадків. За замовчуванням "PHYSICALLY_INFORMED".Ні"RANDOM"
backend_nameOptional[str]Ім'я бекенду для використання.Ні"ibm_torino"
modeOptional[Literal["job", "session", "batch"]]Режим виконання для використання. За замовчуванням "job".Ні"job"

Параметри диференціального рівняння (фізичні параметри та гранична умова) мають відповідати такому формату:

ВаріантКлючТип значенняОписПриклад
CFDafloatКоефіцієнт початкових значень uu1.0
CFDbfloatЗміщення початкових значень uu1.0
MDtfloatповерхневе напруження12.0
MDKfloatоб'ємний модуль100.0
MDnintстепеневий закон4.0
MDbfloatсила на одиницю маси10.0
MDepsilon_0floatмежа пропорційного напруження0.1
MDsigma_0floatмежа пропорційної деформації5.0

Вихідні дані

Вихідні дані — це словник зі списком точок вибірки, а також значеннями функцій у кожній з цих точок:

# 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]),
},
}

Форма масиву розв'язку залежить від вибірок змінних:

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)

Відображення між точками вибірки змінних функції та виміром масиву розв'язку виконується в алфавітно-числовому порядку імені змінної. Наприклад, якщо змінними є "t" і "x", рядок solution["functions"]["u"] представляє значення розв'язку для фіксованого "t", а стовпець solution["functions"]["u"] представляє значення розв'язку для фіксованого "x".

Нижче наведено приклад того, як отримати значення функції для конкретного набору координат:

# 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

Бенчмарки

У наступній таблиці представлено статистику різних запусків нашої функції.

ПрикладКількість кубітівІніціалізаціяПохибкаЗагальний час (хв)Використання середовища виконання (хв)
Невʼязке рівняння Бюргерса50PHYSICALLY_INFORMED10210^{-2}6625
Гіпопружне одновимірне розтягнення18RANDOM10210^{-2}123100

Початок роботи

Заповни форму для запиту доступу до функції QUICK-PDE. Потім, якщо ти вже зберіг свій обліковий запис у локальному середовищі, вибери функцію таким чином:

from qiskit_ibm_catalog import QiskitFunctionsCatalog

catalog = QiskitFunctionsCatalog(channel="ibm_quantum_platform")

quick = catalog.load("colibritd/quick-pde")

Приклади

Щоб розпочати, спробуй один із наступних прикладів:

Обчислювальна гідродинаміка (CFD)

Коли початкові умови задані як u(0,x)=xu(0,x) = x, результати такі:

# 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})

Перевір статус або отримай результати навантаження своєї функції Qiskit таким чином:

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()

Вихідні дані попередньої комірки коду

Деформація матеріалів

Варіант використання деформації матеріалів вимагає фізичних параметрів твого матеріалу та прикладеної сили, таким чином:

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()

Вихідні дані попередньої комірки коду

Отримання повідомлень про помилки

Якщо статус твого навантаження — ERROR, використай job.error_message(), щоб отримати повідомлення про помилку для налагодження, таким чином:

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'

Отримати підтримку

Для підтримки звертайся на qiskit-function-support@colibritd.com.

Наступні кроки

Рекомендації