Langkau ke kandungan utama

Model cecair tidak likat yang mengalir menggunakan QUICK-PDE

Nota

Qiskit Functions ialah ciri eksperimental yang hanya tersedia untuk pengguna Pelan Premium IBM Quantum®, Pelan Flex, dan Pelan On-Prem (melalui IBM Quantum Platform API). Ia dalam status keluaran pratonton dan boleh berubah.

Anggaran penggunaan: 50 minit pada pemproses Heron r2. (NOTA: Ini anggaran sahaja. Masa jalan sebenar anda mungkin berbeza.)

Perhatikan bahawa masa pelaksanaan fungsi ini biasanya melebihi 20 minit, jadi anda mungkin mahu membahagikan tutorial ini kepada dua bahagian: yang pertama, di mana anda membacanya dan melancarkan kerja-kerja, dan yang kedua beberapa jam kemudian (bagi memberi masa yang cukup untuk kerja-kerja selesai), untuk menggunakan hasil kerja tersebut.

Latar Belakang​

Tutorial ini bertujuan mengajar pada peringkat pengenalan bagaimana menggunakan fungsi QUICK-PDE untuk menyelesaikan masalah berbilang fizik yang kompleks pada QPU Heron R2 156Q menggunakan H-DES (Hybrid Differential Equation Solver) ColibriTD. Algoritma asasnya diterangkan dalam kertas H-DES. Perhatikan bahawa penyelesai ini juga boleh menyelesaikan persamaan tidak linear.

Masalah berbilang fizik - termasuk dinamik cecair, resapan haba, dan ubah bentuk bahan, antara lain - boleh diterangkan secara menyeluruh menggunakan Persamaan Pembezaan Separa (Partial Differential Equations, PDE).

Masalah-masalah sedemikian sangat relevan untuk pelbagai industri dan merupakan cabang penting dalam matematik gunaan. Walau bagaimanapun, menyelesaikan PDE bersepadu berbilang pemboleh ubah tidak linear dengan alat klasik masih mencabar disebabkan keperluan sumber yang bertambah secara eksponen.

Fungsi ini sesuai untuk persamaan dengan kerumitan dan pemboleh ubah yang semakin meningkat, dan merupakan langkah pertama untuk membuka kemungkinan yang pernah dianggap tidak dapat diselesaikan. Untuk menerangkan sepenuhnya masalah yang dimodelkan oleh PDE, adalah perlu untuk mengetahui syarat awal dan syarat sempadan. Ini boleh mengubah dengan ketara penyelesaian PDE dan laluan untuk mencari penyelesaiannya.

Tutorial ini mengajar anda cara untuk:

  1. Tentukan parameter fungsi syarat awal.
  2. Laraskan bilangan qubit (digunakan untuk mengekod fungsi persamaan pembezaan), kedalaman, dan bilangan shot.
  3. Jalankan QUICK-PDE untuk menyelesaikan persamaan pembezaan yang mendasari.

Keperluan​

Sebelum memulakan tutorial ini, pastikan anda telah memasang perkara berikut:

  • Qiskit SDK v2.0 atau lebih baharu (pip install qiskit)
  • Qiskit Functions Catalog (pip install qiskit-ibm-catalog)
  • Matplotlib (pip install matplotlib)
  • Akses kepada fungsi QUICK-PDE. Isi borang untuk meminta akses.

Persediaan​

Sahkan diri menggunakan kunci API anda dan pilih fungsi seperti berikut:

# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib numpy qiskit-ibm-catalog
import numpy as np
import matplotlib.pyplot as plt
from qiskit_ibm_catalog import QiskitFunctionsCatalog

catalog = QiskitFunctionsCatalog(
channel="ibm_quantum_platform",
instance="INSTANCE_CRN",
token="YOUR_API_KEY", # Use the 44-character API_KEY you created and saved from the IBM Quantum Platform Home dashboard
)

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

Langkah 1: Tetapkan sifat masalah yang hendak diselesaikan​

Tutorial ini merangkumi pengalaman pengguna dari dua perspektif: masalah fizikal yang ditentukan oleh syarat awal, dan komponen algoritma dalam menyelesaikan contoh dinamik cecair pada komputer kuantum.

Dinamik Cecair Berkomputer (Computational Fluid Dynamics, CFD) mempunyai pelbagai aplikasi yang luas, dan oleh itu penting untuk mengkaji dan menyelesaikan PDE yang mendasarinya. Satu keluarga PDE yang penting ialah persamaan Navier-Stokes, iaitu sistem persamaan pembezaan separa tidak linear yang menerangkan gerakan cecair. Persamaan ini sangat relevan untuk masalah saintifik dan aplikasi kejuruteraan.

Dalam keadaan tertentu, persamaan Navier-Stokes menjadi persamaan Burgers', iaitu persamaan perolakan-resapan yang menerangkan fenomena yang berlaku dalam dinamik cecair, dinamik gas, dan akustik tidak linear, antara lain, dengan memodelkan sistem penyebaran.

Versi satu dimensi persamaan ini bergantung pada dua pemboleh ubah: t∈R≥0t \in \mathbb{R}_{\geq 0} yang memodelkan dimensi masa, x∈Rx \in \mathbb{R} yang mewakili dimensi ruang. Bentuk umum persamaan ini dipanggil persamaan Burgers' likat dan berbunyi:

∂u∂t+u∂u∂x=ν∂2u∂2x,\frac{\partial u}{\partial t} + u \frac{\partial u}{\partial x} = \nu \frac{\partial^2 u}{\partial^2 x},

di mana u(x,t)u(x,t) ialah medan laju cecair pada kedudukan xx dan masa tt yang diberikan, dan ν\nu ialah kelikatan cecair. Kelikatan ialah sifat penting cecair yang mengukur rintangannya terhadap gerakan atau ubah bentuk bergantung kadar, dan oleh itu ia memainkan peranan penting dalam penentuan dinamik cecair. Apabila kelikatan cecair adalah sifar (ν\nu = 0), persamaan ini menjadi persamaan pemuliharaan yang boleh membentuk ketidakselanjaran (gelombang kejutan), disebabkan oleh kekurangan rintangan dalamnya. Dalam kes ini, persamaan ini dipanggil persamaan Burgers' tidak likat dan merupakan kes khas persamaan gelombang tidak linear.

Secara teknikalnya, aliran tidak likat tidak berlaku di alam semula jadi, tetapi apabila memodelkan aliran aerodinamik, disebabkan oleh kesan pengangkutan yang kecil, menggunakan penerangan tidak likat bagi masalah itu boleh berguna. Menakjubkan, lebih daripada 70% teori aerodinamik berkaitan dengan aliran tidak likat.

Tutorial ini menggunakan persamaan Burgers' tidak likat sebagai contoh CFD untuk diselesaikan pada QPU IBM® menggunakan QUICK-PDE, yang diberikan oleh persamaan:

∂u∂t+u∂u∂x=0\frac{\partial u}{\partial t} + u\frac{\partial u}{\partial x} = 0

Syarat awal untuk masalah ini ditetapkan kepada fungsi linear: u(t=0,x)=ax+b, with a,b∈Ru(t=0,x) = ax + b,\text{ with }a,b\in\mathbb{R} di mana aa dan bb ialah pemalar sewenang-wenangnya yang mempengaruhi bentuk penyelesaian. Anda boleh melaraskan aa dan bb dan melihat bagaimana ia mempengaruhi proses penyelesaian dan penyelesaiannya.

job = quick.run(
use_case="cfd",
physical_parameters={"a": 1.0, "b": 1.0},
)
print(job.result())
{'functions': {'u': array([[1.        , 0.96112378, 0.9230742 , 0.88616096, 0.85058445,
0.81644741, 0.78376878, 0.75249908, 0.72253689, 0.69374562,
0.66597013, 0.63905258, 0.61284684, 0.58723093, 0.56211691,
0.53745752, 0.51324915, 0.48953036, 0.46637547, 0.44388257,
0.4221554 , 0.40127848, 0.38128488, 0.36211604, 0.34357308,
0.32525895, 0.30651089, 0.28632252, 0.26325504, 0.23533692],
[1.2375 , 1.19267729, 1.14850734, 1.10544526, 1.06382155,
1.02385326, 0.98565757, 0.94926734, 0.91464784, 0.88171402,
0.85034771, 0.82041411, 0.79177677, 0.76431068, 0.73791248,
0.71250742, 0.68805224, 0.66453346, 0.64196021, 0.62035121,
0.59971506, 0.5800232 , 0.56117499, 0.54295419, 0.52497612,
0.50662498, 0.48698059, 0.4647339 , 0.43809065, 0.40466247],
[1.475 , 1.4242308 , 1.37394048, 1.32472956, 1.27705866,
1.23125911, 1.18754636, 1.1460356 , 1.10675879, 1.06968242,
1.03472529, 1.00177563, 0.9707067 , 0.94139043, 0.91370806,
0.88755732, 0.86285533, 0.83953655, 0.81754494, 0.79681986,
0.77727473, 0.75876792, 0.74106511, 0.72379234, 0.70637915,
0.687991 , 0.66745028, 0.64314527, 0.61292625, 0.57398802],
[1.7125 , 1.65578431, 1.59937362, 1.54401386, 1.49029576,
1.43866495, 1.38943515, 1.34280386, 1.29886974, 1.25765082,
1.21910288, 1.18313715, 1.14963664, 1.11847019, 1.08950364,
1.06260722, 1.03765842, 1.01453964, 0.99312968, 0.97328851,
0.95483439, 0.93751264, 0.92095522, 0.90463049, 0.88778219,
0.86935702, 0.84791997, 0.82155665, 0.78776186, 0.74331358],
[1.95 , 1.88733782, 1.82480676, 1.76329816, 1.70353287,
1.6460708 , 1.59132394, 1.53957212, 1.49098069, 1.44561922,
1.40348046, 1.36449867, 1.32856657, 1.29554994, 1.26529921,
1.23765712, 1.21246152, 1.18954273, 1.16871442, 1.14975716,
1.13239406, 1.11625736, 1.10084533, 1.08546864, 1.06918523,
1.05072304, 1.02838966, 0.99996803, 0.96259746, 0.91263913]])}, 'samples': {'t': array([0. , 0.03275862, 0.06551724, 0.09827586, 0.13103448,
0.1637931 , 0.19655172, 0.22931034, 0.26206897, 0.29482759,
0.32758621, 0.36034483, 0.39310345, 0.42586207, 0.45862069,
0.49137931, 0.52413793, 0.55689655, 0.58965517, 0.62241379,
0.65517241, 0.68793103, 0.72068966, 0.75344828, 0.7862069 ,
0.81896552, 0.85172414, 0.88448276, 0.91724138, 0.95 ]), 'x': array([0. , 0.2375, 0.475 , 0.7125, 0.95 ])}}

Langkah 2 (jika perlu): Optimumkan masalah untuk pelaksanaan perkakasan kuantum​

Secara lalai, penyelesai menggunakan parameter yang dimaklumkan secara fizikal, iaitu parameter Circuit awal untuk bilangan qubit dan kedalaman tertentu yang akan digunakan penyelesai kami sebagai permulaan.

Shot juga merupakan sebahagian daripada parameter dengan nilai lalai, memandangkan penalaan halusnya adalah penting.

Bergantung pada konfigurasi yang cuba diselesaikan, parameter algoritma untuk mencapai penyelesaian yang memuaskan mungkin perlu disesuaikan; contohnya, ia mungkin memerlukan lebih atau kurang qubit setiap pemboleh ubah tt dan xx, bergantung pada aa dan bb. Berikut melaraskan bilangan qubit setiap fungsi setiap pemboleh ubah, kedalaman setiap fungsi, dan bilangan shot.

Anda juga boleh melihat cara menentukan Backend dan mod pelaksanaan.

Selain itu, parameter yang dimaklumkan secara fizikal mungkin mengarahkan proses pengoptimuman ke arah yang salah; dalam kes itu, anda boleh melumpuhkannya dengan menetapkan strategi initialization kepada "RANDOM".

job_2 = quick.run(
use_case="cfd",
physical_parameters={"a": 0.5, "b": 0.25},
nb_qubits={"u": {"t": 2, "x": 1}},
depth={"u": 3},
shots=[500, 2500, 5000, 10000],
initialization="RANDOM",
backend="ibm_kingston",
mode="session",
)
print(job_2.result())
{'functions': {'u': array([[0.25      , 0.24856543, 0.24687708, 0.2449444 , 0.24277686,
0.24038389, 0.23777496, 0.23495952, 0.23194702, 0.22874691,
0.22536866, 0.22182171, 0.21811551, 0.21425952, 0.2102632 ,
0.20613599, 0.20188736, 0.19752675, 0.19306361, 0.18850741,
0.18386759, 0.1791536 , 0.17437491, 0.16954096, 0.16466122,
0.15974512, 0.15480213, 0.1498417 , 0.14487328, 0.13990632],
[0.36875 , 0.36681313, 0.36457201, 0.36203594, 0.35921422,
0.35611615, 0.35275103, 0.34912817, 0.34525687, 0.34114643,
0.33680614, 0.33224532, 0.32747327, 0.32249928, 0.31733266,
0.31198271, 0.30645873, 0.30077002, 0.29492589, 0.28893564,
0.28280857, 0.27655397, 0.27018116, 0.26369944, 0.2571181 ,
0.25044645, 0.24369378, 0.23686941, 0.22998264, 0.22304275],
[0.4875 , 0.48506084, 0.48226695, 0.47912748, 0.47565158,
0.47184841, 0.46772711, 0.46329683, 0.45856672, 0.45354594,
0.44824363, 0.44266894, 0.43683103, 0.43073904, 0.42440212,
0.41782942, 0.4110301 , 0.4040133 , 0.39678818, 0.38936388,
0.38174955, 0.37395435, 0.36598742, 0.35785791, 0.34957498,
0.34114777, 0.33258544, 0.32389713, 0.315092 , 0.30617919],
[0.60625 , 0.60330854, 0.59996188, 0.59621902, 0.59208895,
0.58758067, 0.58270318, 0.57746549, 0.57187658, 0.56594545,
0.55968112, 0.55309256, 0.54618879, 0.53897879, 0.53147158,
0.52367614, 0.51560147, 0.50725658, 0.49865046, 0.48979211,
0.48069053, 0.47135472, 0.46179367, 0.45201638, 0.44203186,
0.4318491 , 0.42147709, 0.41092485, 0.40020136, 0.38931562],
[0.725 , 0.72155625, 0.71765682, 0.71331056, 0.70852631,
0.70331293, 0.69767926, 0.69163414, 0.68518643, 0.67834497,
0.6711186 , 0.66351618, 0.65554655, 0.64721855, 0.63854104,
0.62952285, 0.62017284, 0.61049986, 0.60051274, 0.59022035,
0.57963151, 0.56875509, 0.55759992, 0.54617486, 0.53448874,
0.52255042, 0.51036875, 0.49795257, 0.48531072, 0.47245205]])}, 'samples': {'t': array([0. , 0.03275862, 0.06551724, 0.09827586, 0.13103448,
0.1637931 , 0.19655172, 0.22931034, 0.26206897, 0.29482759,
0.32758621, 0.36034483, 0.39310345, 0.42586207, 0.45862069,
0.49137931, 0.52413793, 0.55689655, 0.58965517, 0.62241379,
0.65517241, 0.68793103, 0.72068966, 0.75344828, 0.7862069 ,
0.81896552, 0.85172414, 0.88448276, 0.91724138, 0.95 ]), 'x': array([0. , 0.2375, 0.475 , 0.7125, 0.95 ])}}

Langkah 3: Bandingkan prestasi algoritma​

Anda boleh membandingkan proses penumpuan penyelesaian kami (HDES) bagi job_2 dengan prestasi algoritma dan penyelesai rangkaian neural bermaklum fizik (physics-informed neural networks, PINN) (lihat kertas dan repositori GitHub yang berkaitan).

Dalam contoh output job_2 (pendekatan berasaskan kuantum), hanya 13 parameter (12 parameter Circuit ditambah 1 parameter penskalaan) dioptimumkan dengan penyelesai klasik. Proses penumpuan adalah seperti berikut:

optimizers:
CMA: {'ftarget': np.float64(0.1), 'verb_disp': 10, 'maxiter': 100}
CMA: {'ftarget': np.float64(0.005), 'verb_disp': 10, 'maxiter': 20}
CMA: {'ftarget': np.float64(0.0025), 'verb_disp': 10, 'maxiter': 30}
CMA: {'ftarget': np.float64(0.0005), 'verb_disp': 10, 'maxiter': 10}

500 shots
================== CMA =================
option: {'ftarget': np.float64(0.1), 'verb_disp': 10, 'maxiter': 100}
0/100, loss: 0.02456641

1000 shots
================== CMA =================
option: {'ftarget': np.float64(0.005), 'verb_disp': 10, 'maxiter': 20}
0/20, loss: 0.03641833
1/20, loss: 0.02461719
2/20, loss: 0.0283689
3/20, loss: 0.009898383
4/20, loss: 0.04454522
5/20, loss: 0.007019971
6/20, loss: 0.00811147
7/20, loss: 0.01592619
8/20, loss: 0.00764708
9/20, loss: 0.01401516
10/20, loss: 0.01767467
11/20, loss: 0.01220387

5000 shots
================== CMA =================
option: {'ftarget': np.float64(0.0025), 'verb_disp': 10, 'maxiter': 30}
0/30, loss: 0.01024792
1/30, loss: 0.004343748
2/30, loss: 0.01450951
3/30, loss: 0.008591284
4/30, loss: 0.00266414
5/30, loss: 0.007923613
6/30, loss: 0.02023853
7/30, loss: 0.01031438
8/30, loss: 0.009513116
9/30, loss: 0.008132266
10/30, loss: 0.005787766
11/30, loss: 0.00390582

10000 shots
================== CMA =================
option: {'ftarget': np.float64(0.0005), 'verb_disp': 10, 'maxiter': 10}
0/10, loss: 0.002386168
1/10, loss: 0.004024823
2/10, loss: 0.001311999
3/10, loss: 0.003433991
4/10, loss: 0.002339664
5/10, loss: 0.002978438
6/10, loss: 0.005458391
7/10, loss: 0.002026701
8/10, loss: 0.00207467
9/10, loss: 0.001947627
final_loss: 0.00151994463476429

Maknanya, kerugian di bawah 0.0015 boleh dicapai selepas 28 lelaran, dan dengan mengoptimumkan hanya beberapa parameter klasik.

Kini kita boleh membandingkan perkara yang sama dengan penyelesaian PINN menggunakan konfigurasi lalai yang dicadangkan dalam kertas menggunakan pengoptimum berasaskan kecerunan. Setara dengan Circuit kami yang mempunyai 13 parameter untuk dioptimumkan ialah rangkaian neural, yang memerlukan sekurang-kurangnya lapan lapisan dengan 20 neuron, dan oleh itu melibatkan pengoptimuman 3021 parameter. Kemudian, kerugian sasaran dicapai pada Langkah 315, loss: 0.0014988397.

Graf menunjukkan data PINN berbanding dengan fungsi HDES-Qiskit.

Kini, memandangkan kita ingin membuat perbandingan yang adil, kita sepatutnya menggunakan pengoptimum yang sama dalam kedua-dua kes. Bilangan lelaran terendah yang kami jumpa untuk 12 lapisan dengan 20 neuron = 4701 parameter:

(10_w,20)-aCMA-ES (mu_w=5.9,w_1=27%) in dimension 4701 (seed=351961)
Iterat #Fevals function value axis ratio sigma min&max std t[m:s]
1 20 5.398521572351456e-02 1.0e+00 9.98e-03 1e-02 1e-02 0:02.3
2 40 5.444650724530220e-02 1.0e+00 9.97e-03 1e-02 1e-02 0:05.1
3 60 4.447407275438309e-02 1.0e+00 9.95e-03 1e-02 1e-02 0:08.2
4 80 2.068969979882240e-02 1.0e+00 9.94e-03 1e-02 1e-02 0:11.7
6 120 1.028892211616039e-02 1.0e+00 9.91e-03 1e-02 1e-02 0:20.1
7 140 5.140972323715687e-03 1.0e+00 9.90e-03 1e-02 1e-02 0:25.4
9 180 3.811701666563749e-03 1.0e+00 9.87e-03 1e-02 1e-02 0:37.4
10 200 3.189878538250923e-03 1.0e+00 9.85e-03 1e-02 1e-02 0:44.2
12 240 2.547040116041899e-03 1.0e+00 9.83e-03 1e-02 1e-02 0:59.7
14 280 2.166548743844032e-03 1.0e+00 9.80e-03 1e-02 1e-02 1:18.0
15 300 1.783065614290535e-03 1.0e+00 9.79e-03 1e-02 1e-02 1:28.4
16 320 2.045844215899706e-03 1.0e+00 9.78e-03 1e-02 1e-02 1:39.8
Stopping early: loss 0.001405 <= target 0.0015
CMA-ES finished. Best loss: 0.001404788694344461

Anda boleh melakukan perkara yang sama dengan data anda dari job_2, dan plot perbandingan dengan penyelesaian PINN.

# check the loss function and compare between the two approaches
print(job_2.logs())

Langkah 4: Gunakan keputusan​

Dengan penyelesaian yang dah dapat, kau boleh pilih nak buat apa dengannya. Berikut menunjukkan cara untuk plot keputusan tersebut.

solution = job.result()

# Plot the solution of the second simulation job_2
_ = 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, marker=".")
ax.set(xlabel="t", ylabel="x", zlabel="u(t,x)")

plt.show()

Output of the previous code cell

Perhatikan perbezaan syarat awal untuk simulasi kedua dan kesannya terhadap keputusan:

solution_2 = job_2.result()

# Plot the solution of the second simulation job_2
_ = plt.figure()
ax = plt.axes(projection="3d")

# plot the solution using the 3d plotting capabilities of pyplot
t, x = np.meshgrid(solution_2["samples"]["t"], solution_2["samples"]["x"])
ax.plot_surface(
t,
x,
solution_2["functions"]["u"],
edgecolor="royalblue",
lw=0.25,
rstride=26,
cstride=26,
alpha=0.3,
)
ax.scatter(t, x, solution_2, marker=".")
ax.set(xlabel="t", ylabel="x", zlabel="u(t,x)")

plt.show()

Output of the previous code cell

Tinjauan tutorial​

Tolong luangkan masa seminit untuk bagi maklum balas tentang tutorial ni. Pandangan kau akan bantu kami tambah baik kandungan dan pengalaman pengguna:

Pautan ke tinjauan

Note: This survey is provided by IBM Quantum and relates to the original English content. To give feedback on doQumentation's website, translations, or code execution, please open a GitHub issue.

Source: IBM Quantum docs — updated 27 Apr 2026
English version on doQumentation — updated 7 Mei 2026
This translation based on the English version of 9 Apr 2026