This commit is contained in:
2019-04-09 15:01:16 +02:00
commit 2f97a4c4c4
30 changed files with 2708 additions and 0 deletions

17
Pipfile Normal file
View File

@@ -0,0 +1,17 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
numpy = "*"
scipy = "*"
sympy = "*"
pytest = "*"
pandas = "*"
cachier = "*"
[dev-packages]
[requires]
python_version = "3.7"

237
Pipfile.lock generated Normal file
View File

@@ -0,0 +1,237 @@
{
"_meta": {
"hash": {
"sha256": "645ddde7fd5f497ea131e2195b311a8f0818328bbb2514c82599f6c69bdf6cda"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.7"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
"default": {
"argh": {
"hashes": [
"sha256:a9b3aaa1904eeb78e32394cd46c6f37ac0fb4af6dc488daa58971bdc7d7fcaf3",
"sha256:e9535b8c84dc9571a48999094fda7f33e63c3f1b74f3e5f3ac0105a58405bb65"
],
"version": "==0.26.2"
},
"atomicwrites": {
"hashes": [
"sha256:03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4",
"sha256:75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6"
],
"version": "==1.3.0"
},
"attrs": {
"hashes": [
"sha256:69c0dbf2ed392de1cb5ec704444b08a5ef81680a61cb899dc08127123af36a79",
"sha256:f0b870f674851ecbfbbbd364d6b5cbdff9dcedbc7f3f5e18a6891057f21fe399"
],
"version": "==19.1.0"
},
"cachier": {
"hashes": [
"sha256:2d195f2f0767f5149533987aab5a7bb0f8c2264d88a4ef440dbf09628b2a9f4b"
],
"index": "pypi",
"version": "==1.2.5"
},
"more-itertools": {
"hashes": [
"sha256:0125e8f60e9e031347105eb1682cef932f5e97d7b9a1a28d9bf00c22a5daef40",
"sha256:590044e3942351a1bdb1de960b739ff4ce277960f2425ad4509446dbace8d9d1"
],
"markers": "python_version > '2.7'",
"version": "==6.0.0"
},
"mpmath": {
"hashes": [
"sha256:fc17abe05fbab3382b61a123c398508183406fa132e0223874578e20946499f6"
],
"version": "==1.1.0"
},
"numpy": {
"hashes": [
"sha256:1980f8d84548d74921685f68096911585fee393975f53797614b34d4f409b6da",
"sha256:22752cd809272671b273bb86df0f505f505a12368a3a5fc0aa811c7ece4dfd5c",
"sha256:23cc40313036cffd5d1873ef3ce2e949bdee0646c5d6f375bf7ee4f368db2511",
"sha256:2b0b118ff547fecabc247a2668f48f48b3b1f7d63676ebc5be7352a5fd9e85a5",
"sha256:3a0bd1edf64f6a911427b608a894111f9fcdb25284f724016f34a84c9a3a6ea9",
"sha256:3f25f6c7b0d000017e5ac55977a3999b0b1a74491eacb3c1aa716f0e01f6dcd1",
"sha256:4061c79ac2230594a7419151028e808239450e676c39e58302ad296232e3c2e8",
"sha256:560ceaa24f971ab37dede7ba030fc5d8fa173305d94365f814d9523ffd5d5916",
"sha256:62be044cd58da2a947b7e7b2252a10b42920df9520fc3d39f5c4c70d5460b8ba",
"sha256:6c692e3879dde0b67a9dc78f9bfb6f61c666b4562fd8619632d7043fb5b691b0",
"sha256:6f65e37b5a331df950ef6ff03bd4136b3c0bbcf44d4b8e99135d68a537711b5a",
"sha256:7a78cc4ddb253a55971115f8320a7ce28fd23a065fc33166d601f51760eecfa9",
"sha256:80a41edf64a3626e729a62df7dd278474fc1726836552b67a8c6396fd7e86760",
"sha256:893f4d75255f25a7b8516feb5766c6b63c54780323b9bd4bc51cdd7efc943c73",
"sha256:972ea92f9c1b54cc1c1a3d8508e326c0114aaf0f34996772a30f3f52b73b942f",
"sha256:9f1d4865436f794accdabadc57a8395bd3faa755449b4f65b88b7df65ae05f89",
"sha256:9f4cd7832b35e736b739be03b55875706c8c3e5fe334a06210f1a61e5c2c8ca5",
"sha256:adab43bf657488300d3aeeb8030d7f024fcc86e3a9b8848741ea2ea903e56610",
"sha256:bd2834d496ba9b1bdda3a6cf3de4dc0d4a0e7be306335940402ec95132ad063d",
"sha256:d20c0360940f30003a23c0adae2fe50a0a04f3e48dc05c298493b51fd6280197",
"sha256:d3b3ed87061d2314ff3659bb73896e622252da52558f2380f12c421fbdee3d89",
"sha256:dc235bf29a406dfda5790d01b998a1c01d7d37f449128c0b1b7d1c89a84fae8b",
"sha256:fb3c83554f39f48f3fa3123b9c24aecf681b1c289f9334f8215c1d3c8e2f6e5b"
],
"index": "pypi",
"version": "==1.16.2"
},
"pandas": {
"hashes": [
"sha256:071e42b89b57baa17031af8c6b6bbd2e9a5c68c595bc6bf9adabd7a9ed125d3b",
"sha256:17450e25ae69e2e6b303817bdf26b2cd57f69595d8550a77c308be0cd0fd58fa",
"sha256:17916d818592c9ec891cbef2e90f98cc85e0f1e89ed0924c9b5220dc3209c846",
"sha256:2538f099ab0e9f9c9d09bbcd94b47fd889bad06dc7ae96b1ed583f1dc1a7a822",
"sha256:366f30710172cb45a6b4f43b66c220653b1ea50303fbbd94e50571637ffb9167",
"sha256:42e5ad741a0d09232efbc7fc648226ed93306551772fc8aecc6dce9f0e676794",
"sha256:4e718e7f395ba5bfe8b6f6aaf2ff1c65a09bb77a36af6394621434e7cc813204",
"sha256:4f919f409c433577a501e023943e582c57355d50a724c589e78bc1d551a535a2",
"sha256:4fe0d7e6438212e839fc5010c78b822664f1a824c0d263fd858f44131d9166e2",
"sha256:5149a6db3e74f23dc3f5a216c2c9ae2e12920aa2d4a5b77e44e5b804a5f93248",
"sha256:627594338d6dd995cfc0bacd8e654cd9e1252d2a7c959449228df6740d737eb8",
"sha256:83c702615052f2a0a7fb1dd289726e29ec87a27272d775cb77affe749cca28f8",
"sha256:8c872f7fdf3018b7891e1e3e86c55b190e6c5cee70cab771e8f246c855001296",
"sha256:90f116086063934afd51e61a802a943826d2aac572b2f7d55caaac51c13db5b5",
"sha256:a3352bacac12e1fc646213b998bce586f965c9d431773d9e91db27c7c48a1f7d",
"sha256:bcdd06007cca02d51350f96debe51331dec429ac8f93930a43eb8fb5639e3eb5",
"sha256:c1bd07ebc15285535f61ddd8c0c75d0d6293e80e1ee6d9a8d73f3f36954342d0",
"sha256:c9a4b7c55115eb278c19aa14b34fcf5920c8fe7797a09b7b053ddd6195ea89b3",
"sha256:cc8fc0c7a8d5951dc738f1c1447f71c43734244453616f32b8aa0ef6013a5dfb",
"sha256:d7b460bc316064540ce0c41c1438c416a40746fd8a4fb2999668bf18f3c4acf1"
],
"index": "pypi",
"version": "==0.24.2"
},
"pathtools": {
"hashes": [
"sha256:7c35c5421a39bb82e58018febd90e3b6e5db34c5443aaaf742b3f33d4655f1c0"
],
"version": "==0.1.2"
},
"pluggy": {
"hashes": [
"sha256:19ecf9ce9db2fce065a7a0586e07cfb4ac8614fe96edf628a264b1c70116cf8f",
"sha256:84d306a647cc805219916e62aab89caa97a33a1dd8c342e87a37f91073cd4746"
],
"version": "==0.9.0"
},
"portalocker": {
"hashes": [
"sha256:3fb35648a9e03f267e54c6186513abbd1cdd321c305502545a3550eea8b2923f",
"sha256:d98cdcdbd8c590ee4c93fb4149b2e76030ea6c36d6fdfec122e6656ebf90086f"
],
"version": "==1.4.0"
},
"py": {
"hashes": [
"sha256:64f65755aee5b381cea27766a3a147c3f15b9b6b9ac88676de66ba2ae36793fa",
"sha256:dc639b046a6e2cff5bbe40194ad65936d6ba360b52b3c3fe1d08a82dd50b5e53"
],
"version": "==1.8.0"
},
"pytest": {
"hashes": [
"sha256:592eaa2c33fae68c7d75aacf042efc9f77b27c08a6224a4f59beab8d9a420523",
"sha256:ad3ad5c450284819ecde191a654c09b0ec72257a2c711b9633d677c71c9850c4"
],
"index": "pypi",
"version": "==4.3.1"
},
"python-dateutil": {
"hashes": [
"sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb",
"sha256:c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e"
],
"version": "==2.8.0"
},
"pytz": {
"hashes": [
"sha256:32b0891edff07e28efe91284ed9c31e123d84bea3fd98e1f72be2508f43ef8d9",
"sha256:d5f05e487007e29e03409f9398d074e158d920d36eb82eaf66fb1136b0c5374c"
],
"version": "==2018.9"
},
"pyyaml": {
"hashes": [
"sha256:1adecc22f88d38052fb787d959f003811ca858b799590a5eaa70e63dca50308c",
"sha256:436bc774ecf7c103814098159fbb84c2715d25980175292c648f2da143909f95",
"sha256:460a5a4248763f6f37ea225d19d5c205677d8d525f6a83357ca622ed541830c2",
"sha256:5a22a9c84653debfbf198d02fe592c176ea548cccce47553f35f466e15cf2fd4",
"sha256:7a5d3f26b89d688db27822343dfa25c599627bc92093e788956372285c6298ad",
"sha256:9372b04a02080752d9e6f990179a4ab840227c6e2ce15b95e1278456664cf2ba",
"sha256:a5dcbebee834eaddf3fa7366316b880ff4062e4bcc9787b78c7fbb4a26ff2dd1",
"sha256:aee5bab92a176e7cd034e57f46e9df9a9862a71f8f37cad167c6fc74c65f5b4e",
"sha256:c51f642898c0bacd335fc119da60baae0824f2cde95b0330b56c0553439f0673",
"sha256:c68ea4d3ba1705da1e0d85da6684ac657912679a649e8868bd850d2c299cce13",
"sha256:e23d0cc5299223dcc37885dae624f382297717e459ea24053709675a976a3e19"
],
"version": "==5.1"
},
"scipy": {
"hashes": [
"sha256:014cb900c003b5ac81a53f2403294e8ecf37aedc315b59a6b9370dce0aa7627a",
"sha256:281a34da34a5e0de42d26aed692ab710141cad9d5d218b20643a9cb538ace976",
"sha256:588f9cc4bfab04c45fbd19c1354b5ade377a8124d6151d511c83730a9b6b2338",
"sha256:5a10661accd36b6e2e8855addcf3d675d6222006a15795420a39c040362def66",
"sha256:628f60be272512ca1123524969649a8cb5ae8b31cca349f7c6f8903daf9034d7",
"sha256:6dcc43a88e25b815c2dea1c6fac7339779fc988f5df8396e1de01610604a7c38",
"sha256:70e37cec0ac0fe95c85b74ca4e0620169590fd5d3f44765f3c3a532cedb0e5fd",
"sha256:7274735fb6fb5d67d3789ddec2cd53ed6362539b41aa6cc0d33a06c003aaa390",
"sha256:78e12972e144da47326958ac40c2bd1c1cca908edc8b01c26a36f9ffd3dce466",
"sha256:790cbd3c8d09f3a6d9c47c4558841e25bac34eb7a0864a9def8f26be0b8706af",
"sha256:79792c8fe8e9d06ebc50fe23266522c8c89f20aa94ac8e80472917ecdce1e5ba",
"sha256:865afedf35aaef6df6344bee0de391ee5e99d6e802950a237f9fb9b13e441f91",
"sha256:870fd401ec7b64a895cff8e206ee16569158db00254b2f7157b4c9a5db72c722",
"sha256:963815c226b29b0176d5e3d37fc9de46e2778ce4636a5a7af11a48122ef2577c",
"sha256:9726791484f08e394af0b59eb80489ad94d0a53bbb58ab1837dcad4d58489863",
"sha256:9de84a71bb7979aa8c089c4fb0ea0e2ed3917df3fb2a287a41aaea54bbad7f5d",
"sha256:b2c324ddc5d6dbd3f13680ad16a29425841876a84a1de23a984236d1afff4fa6",
"sha256:b86ae13c597fca087cb8c193870507c8916cefb21e52e1897da320b5a35075e5",
"sha256:ba0488d4dbba2af5bf9596b849873102d612e49a118c512d9d302ceafa36e01a",
"sha256:d78702af4102a3a4e23bb7372cec283e78f32f5573d92091aa6aaba870370fe1",
"sha256:def0e5d681dd3eb562b059d355ae8bebe27f5cc455ab7c2b6655586b63d3a8ea",
"sha256:e085d1babcb419bbe58e2e805ac61924dac4ca45a07c9fa081144739e500aa3c",
"sha256:e2cfcbab37c082a5087aba5ff00209999053260441caadd4f0e8f4c2d6b72088",
"sha256:e742f1f5dcaf222e8471c37ee3d1fd561568a16bb52e031c25674ff1cf9702d5",
"sha256:f06819b028b8ef9010281e74c59cb35483933583043091ed6b261bb1540f11cc",
"sha256:f15f2d60a11c306de7700ee9f65df7e9e463848dbea9c8051e293b704038da60",
"sha256:f31338ee269d201abe76083a990905473987371ff6f3fdb76a3f9073a361cf37",
"sha256:f6b88c8d302c3dac8dff7766955e38d670c82e0d79edfc7eae47d6bb2c186594"
],
"index": "pypi",
"version": "==1.2.1"
},
"six": {
"hashes": [
"sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c",
"sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"
],
"version": "==1.12.0"
},
"sympy": {
"hashes": [
"sha256:e1319b556207a3758a0efebae14e5e52c648fc1db8975953b05fff12b6871b54"
],
"index": "pypi",
"version": "==1.3"
},
"watchdog": {
"hashes": [
"sha256:965f658d0732de3188211932aeb0bb457587f04f63ab4c1e33eab878e9de961d"
],
"version": "==0.9.0"
}
},
"develop": {}
}

113
pub2.ipynb Normal file

File diff suppressed because one or more lines are too long

BIN
roots128.pickle Normal file

Binary file not shown.

0
src/__init__.py Normal file
View File

5
src/consts.py Normal file
View File

@@ -0,0 +1,5 @@
l = 20
T = 100
D = 0.6
H = 4

View File

86
src/runnables/compare.py Normal file
View File

@@ -0,0 +1,86 @@
import itertools
import util
from solvers import solvers, solve_explicit, solve_implicit, solve_implicit_improved, solve_crank_nicolson, \
solve_crank_nicolson_improved
from solvers.theoretical import solve_theoretical
from util import Grid
import numpy as np
def test_order(errors, next_params):
errors = dict(errors)
for params in list(errors.keys()):
if params not in errors:
continue
# chain start
param_chain = []
error_chain = []
while params in errors:
param_chain.append(params)
error_chain.append(errors[params])
del errors[params]
params = next_params(params)
if len(param_chain) < 2:
continue
print(' ', ' -> '.join(map(str, param_chain)))
e = np.array(error_chain, dtype=float)
ed = e[:-1] / e[1:]
print(' ', ' '.join([f'{i:6.2f}' for i in ed]))
def test_solver(solver, Is, Ks):
param_pairs = itertools.product(Is, Ks)
param_pairs = sorted(param_pairs, key=np.prod)
errors_mse = {}
errors_mae = {}
errors_mae_last = {}
for I, K in param_pairs:
grid = Grid(I, K)
solution = solver(grid)
if solution is None:
continue
reference = solve_theoretical(grid)
errors_mse[(I, K)] = util.mse(reference, solution)
errors_mae[(I, K)] = util.mae(reference, solution)
errors_mae_last[(I, K)] = util.mae_last(reference, solution)
print()
print()
print(solver.__name__)
print('O(h_x, h_t) MAEL SHOULD BE >=2')
test_order(errors_mae_last, next_params=lambda params: (params[0] * 2, params[1] * 2))
print(f'O(h_x, h_t^2) MAEL SHOULD BE >=4')
test_order(errors_mae_last, next_params=lambda params: (params[0] * 4, params[1] * 2))
print(f'O(h_x^2, h_t) MAEL SHOULD BE >=4')
test_order(errors_mae_last, next_params=lambda params: (params[0] * 2, params[1] * 4))
if __name__ == '__main__':
# Is = [4, 8, 16, 32, 64, 128, 256, 512]
# Ks = [4, 8, 16, 32, 64, 128, 256, 512]
# Is = [4, 8, 16, 32, 64, 128, 256, 512]
# Ks = [32, 64, 128, 256, 512, 1024, 2048, 4096]
Is = [4, 8, 16, 32, 64]
Ks = [32, 64, 128, 256, 512, 1024]
test_solver(solve_explicit, Is, Ks)
test_solver(solve_implicit, Is, Ks)
test_solver(solve_implicit_improved, Is, Ks)
test_solver(solve_crank_nicolson, Is, Ks)
test_solver(solve_crank_nicolson_improved, Is, Ks)

20
src/runnables/run_all.py Normal file
View File

@@ -0,0 +1,20 @@
import util
from solvers import solvers
from solvers.theoretical import solve_theoretical
from util import Grid
if __name__ == '__main__':
grid = Grid(16, 128)
reference = solve_theoretical(grid)
print()
print(grid)
for solver in solvers:
solution = solver(grid)
mse = util.mse(reference, solution)
mae = util.mae(reference, solution)
print(f'{solver.__name__:30} {mse:.4e} {mae:.4e}')

View File

@@ -0,0 +1,27 @@
from solvers import solvers, solve_theoretical
from util import Grid
import numpy as np
if __name__ == '__main__':
I = 16
K = 512
grid = Grid(I, K)
for solver in solvers:
solution = solver(grid)
if solution is None:
continue
print(solver.__name__)
reference = solve_theoretical(grid)
e = np.abs(reference - solution)
flat_indices = np.argsort(e, axis=None)
for index in flat_indices[-10:]:
i, j = np.unravel_index(index, e.shape)
print(f'{i:4} {j:4} {e[i, j]}')

12
src/solvers/__init__.py Normal file
View File

@@ -0,0 +1,12 @@
from solvers.crank_nicolson import solve_crank_nicolson, solve_crank_nicolson_improved
from solvers.explicit import solve_explicit
from solvers.implicit import solve_implicit, solve_implicit_improved
from solvers.theoretical import solve_theoretical
solvers = [
solve_explicit,
solve_implicit,
solve_implicit_improved,
solve_crank_nicolson,
solve_crank_nicolson_improved,
]

View File

@@ -0,0 +1,102 @@
import numpy as np
import scipy.sparse
import scipy.sparse.linalg
import consts
from util import Grid
#@cachier(stale_after=datetime.timedelta(hours=1))
def solve_crank_nicolson(grid: Grid) -> np.ndarray:
ug = np.zeros((grid.K + 1, grid.I + 1), dtype=float)
ug[0, :] = np.sin(np.pi * grid.xs / consts.l) ** 2 * 4 / 10
for k in range(1, grid.K + 1):
diags = {
-1: np.zeros(grid.I + 1, dtype=float),
0: np.zeros(grid.I + 1, dtype=float),
+1: np.zeros(grid.I + 1, dtype=float),
}
b = np.zeros(grid.I + 1, dtype=float)
# left
diags[0][0] = consts.H * grid.h_x + 1
diags[+1][0] = -1
# middle
for i in range(1, grid.I):
diags[-1][i] = grid.gamma
diags[0][i] = - 2 * grid.gamma - 2
diags[+1][i] = grid.gamma
b[i] = -(
ug[k - 1][i - 1] * grid.gamma +
ug[k - 1][i] * (-2 * grid.gamma + 2) +
ug[k - 1][i + 1] * grid.gamma
)
# right
diags[0][grid.I] = consts.H * grid.h_x + 1
diags[-1][grid.I] = -1
A = scipy.sparse.diags([
diags[-1][1:],
diags[0],
diags[+1][:-1],
], [-1, 0, 1], format='csc')
ug[k, :] = scipy.sparse.linalg.spsolve(A, b)
return ug
#@cachier(stale_after=datetime.timedelta(hours=1))
def solve_crank_nicolson_improved(grid: Grid) -> np.ndarray:
ug = np.zeros((grid.K + 1, grid.I + 1), dtype=float)
ug[0, :] = np.sin(np.pi * grid.xs / consts.l) ** 2 * 4 / 10
for k in range(1, grid.K + 1):
diags = {
-1: np.zeros(grid.I + 1, dtype=float),
0: np.zeros(grid.I + 1, dtype=float),
+1: np.zeros(grid.I + 1, dtype=float),
}
b = np.zeros(grid.I + 1, dtype=float)
# left
diags[0][0] = consts.H * grid.gamma * grid.h_x + grid.gamma + 1
diags[+1][0] = - grid.gamma
b[0] = (
(- consts.H * grid.gamma * grid.h_x - grid.gamma + 1) * ug[k - 1, 0] +
grid.gamma * ug[k - 1, 1]
)
# middle
for i in range(1, grid.I):
diags[-1][i] = grid.gamma
diags[0][i] = - 2 * grid.gamma - 2
diags[+1][i] = grid.gamma
b[i] = -(
ug[k - 1][i - 1] * grid.gamma +
ug[k - 1][i] * (-2 * grid.gamma + 2) +
ug[k - 1][i + 1] * grid.gamma
)
# right
diags[0][grid.I] = consts.H * grid.gamma * grid.h_x + grid.gamma + 1
diags[-1][grid.I] = - grid.gamma
b[grid.I] = (
(- consts.H * grid.gamma * grid.h_x - grid.gamma + 1) * ug[k - 1, grid.I] +
grid.gamma * ug[k - 1, grid.I - 1]
)
A = scipy.sparse.diags([
diags[-1][1:],
diags[0],
diags[+1][:-1],
], [-1, 0, 1], format='csc')
ug[k, :] = scipy.sparse.linalg.spsolve(A, b)
return ug

32
src/solvers/explicit.py Normal file
View File

@@ -0,0 +1,32 @@
from typing import Optional
import numpy as np
import consts
from util import Grid
#@cachier(stale_after=datetime.timedelta(hours=1))
def solve_explicit(grid: Grid) -> Optional[np.ndarray]:
if grid.gamma > 1 / 2:
return None
ug = np.zeros((grid.K + 1, grid.I + 1), dtype=float)
ug[0, :] = np.sin(np.pi * grid.xs / consts.l) ** 2 * 4 / 10
for k in range(1, grid.K + 1):
# middle
ug[k, 1: grid.I] = (
grid.gamma * ug[k - 1, 0: grid.I - 1] +
(-2 * grid.gamma + 1) * ug[k - 1, 1: grid.I] +
grid.gamma * ug[k - 1, 2: grid.I + 1]
)
# left
ug[k, 0] = ug[k, 1] / (consts.H * grid.h_x + 1)
# right
ug[k, grid.I] = ug[k, grid.I - 1] / (consts.H * grid.h_x + 1)
return ug

95
src/solvers/implicit.py Normal file
View File

@@ -0,0 +1,95 @@
import numpy as np
import scipy.sparse
import scipy.sparse.linalg
import consts
#@cachier(stale_after=datetime.timedelta(hours=1))
def solve_implicit(grid) -> np.ndarray:
ug = np.zeros((grid.K + 1, grid.I + 1), dtype=float)
ug[0, :] = np.sin(np.pi * grid.xs / consts.l) ** 2 * 4 / 10
for k in range(1, grid.K + 1):
diags = {
-1: np.zeros(grid.I + 1, dtype=float),
0: np.zeros(grid.I + 1, dtype=float),
+1: np.zeros(grid.I + 1, dtype=float),
}
b = np.zeros(grid.I + 1, dtype=float)
# left
diags[0][0] = consts.H * grid.h_x + 1
diags[+1][0] = -1
# middle
for i in range(1, grid.I):
diags[-1][i] = grid.gamma
diags[0][i] = - 2 * grid.gamma - 1
diags[+1][i] = grid.gamma
b[i] = -ug[k - 1, i]
# right
diags[-1][grid.I] = -1
diags[0][grid.I] = consts.H * grid.h_x + 1
A = scipy.sparse.diags([
diags[-1][1:],
diags[0],
diags[+1][:-1],
], [-1, 0, 1], format='csc')
ug[k, :] = scipy.sparse.linalg.spsolve(A, b)
return ug
#@cachier(stale_after=datetime.timedelta(hours=1))
def solve_implicit_improved(grid) -> np.ndarray:
ug = np.zeros((grid.K + 1, grid.I + 1), dtype=float)
ug[0, :] = np.sin(np.pi * grid.xs / consts.l) ** 2 * 4 / 10
for k in range(1, grid.K + 1):
diags = {
-1: np.zeros(grid.I + 1, dtype=float),
0: np.zeros(grid.I + 1, dtype=float),
+1: np.zeros(grid.I + 1, dtype=float),
}
b = np.zeros(grid.I + 1, dtype=float)
# left
diags[0][0] = (
2 * consts.H * grid.gamma * grid.h_x +
2 * grid.gamma +
1
)
diags[+1][0] = - 2 * grid.gamma
b[0] = ug[k - 1, 0]
# middle
for i in range(1, grid.I):
diags[-1][i] = grid.gamma
diags[0][i] = - 2 * grid.gamma - 1
diags[+1][i] = grid.gamma
b[i] = -ug[k - 1, i]
# right
diags[0][grid.I] = (
2 * consts.H * grid.gamma * grid.h_x +
2 * grid.gamma +
1
)
diags[-1][grid.I] = - 2 * grid.gamma
b[grid.I] = ug[k - 1, grid.I]
A = scipy.sparse.diags([
diags[-1][1:],
diags[0],
diags[+1][:-1],
], [-1, 0, 1], format='csc')
ug[k, :] = scipy.sparse.linalg.spsolve(A, b)
return ug

View File

@@ -0,0 +1,35 @@
import functools
import pickle
import numpy as np
from util import Grid
with open('./roots128.pickle', 'rb') as file:
roots128 = pickle.load(file)
def u_elem128(x, t, alpha_n):
x = np.float128(x)
t = np.float128(t)
alpha_n = np.float128(alpha_n)
return -4 * np.pi ** 2 * (alpha_n * np.cos(alpha_n * x / 10) + 40 * np.sin(alpha_n * x / 10)) * (
alpha_n * np.sin(2 * alpha_n) - 40 * np.cos(2 * alpha_n) + 40) * np.exp(-3 * alpha_n ** 2 * t / 500) / (
5 * (alpha_n ** 2 - np.pi ** 2) * (alpha_n ** 2 * (4 * alpha_n + np.sin(4 * alpha_n)) - 80 * alpha_n * (
np.cos(4 * alpha_n) - 1) + 6400 * alpha_n - 1600 * np.sin(4 * alpha_n)))
@functools.lru_cache(maxsize=1000000)
def u128(x, t, root_n=len(roots128)):
return sum(u_elem128(x, t, roots128[:root_n]))
#@cachier(stale_after=datetime.timedelta(hours=1))
def solve_theoretical(grid: Grid) -> np.ndarray:
ug = np.zeros((grid.K + 1, grid.I + 1), dtype=float)
for k, t in enumerate(grid.ts):
for i, x in enumerate(grid.xs):
ug[k, i] = u128(x, t, 1000)
return ug

45
src/util.py Normal file
View File

@@ -0,0 +1,45 @@
from dataclasses import dataclass, field
import numpy as np
import consts
@dataclass
class Grid:
I: int
K: int
xs: np.ndarray = field(repr=False, compare=False)
ts: np.ndarray = field(repr=False, compare=False)
h_x: float = field(repr=False, compare=False)
h_t: float = field(repr=False, compare=False)
gamma: float = field(repr=False, compare=False)
def __init__(self, I: int, K: int):
self.I = I
self.K = K
self.xs = np.linspace(0, consts.l, I + 1)
self.ts = np.linspace(0, consts.T, K + 1)
self.h_x = consts.l / I
self.h_t = consts.T / K
self.gamma = consts.D * self.h_t / (self.h_x ** 2)
def __hash__(self):
return hash((self.I, self.K))
def mse(ug1: np.ndarray, ug2: np.ndarray) -> float:
return np.mean((ug1 - ug2) ** 2)
def mae(ug1: np.ndarray, ug2: np.ndarray) -> float:
return np.max(np.abs(ug1 - ug2))
def mae_last(ug1: np.ndarray, ug2: np.ndarray) -> float:
return np.max(np.abs(ug1[-1, :] - ug2[-1, :]))

945
symbolic.ipynb Normal file

File diff suppressed because one or more lines are too long

0
test/__init__.py Normal file
View File

31
test/test_solvers.py Normal file
View File

@@ -0,0 +1,31 @@
import util
from solvers.crank_nicolson import solve_crank_nicolson, solve_crank_nicolson_improved
from solvers.explicit import solve_explicit
from solvers.implicit import solve_implicit, solve_implicit_improved
from solvers.theoretical import solve_theoretical
from util import Grid
solvers = [
solve_explicit,
solve_implicit,
solve_implicit_improved,
solve_crank_nicolson,
solve_crank_nicolson_improved,
]
def test_all():
grid = Grid(16, 128)
reference = solve_theoretical(grid)
print()
print(grid)
for solver in solvers:
solution = solver(grid)
mse = util.mse(reference, solution)
mae = util.mae(reference, solution)
print(f'{solver.__name__:30} {mse:.4e} {mae:.4e}')

BIN
Катков.docx Normal file

Binary file not shown.

BIN
Катков.pdf Normal file

Binary file not shown.

BIN
Лысый.docx Normal file

Binary file not shown.

BIN
Нелысый.docx Normal file

Binary file not shown.

View File

@@ -0,0 +1,906 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Populating the interactive namespace from numpy and matplotlib\n"
]
}
],
"source": [
"%pylab inline"
]
},
{
"cell_type": "code",
"execution_count": 112,
"metadata": {},
"outputs": [],
"source": [
"import pandas\n",
"import sympy as Ω\n",
"import matplotlib.pyplot as plt\n",
"import math\n",
"import pylab as p\n",
"import numpy as np\n",
"import decimal as d\n",
"from scipy.misc import derivative\n",
"import pickle\n",
"from tqdm import tqdm_notebook as tqdm\n",
"\n",
"from dataclasses import dataclass\n",
"\n",
"import scipy.sparse\n",
"import scipy.sparse.linalg\n",
"\n",
"import functools"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"Ω.init_printing()"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"l_float = 20\n",
"T_float = 100\n",
"\n",
"D_float = 0.6\n",
"H_float = 4"
]
},
{
"cell_type": "code",
"execution_count": 113,
"metadata": {},
"outputs": [],
"source": [
"with open('/Users/abra/projects/study/7semestr/degtyarev/roots128.pickle', 'rb') as file:\n",
" roots128 = pickle.load(file)\n",
"\n",
"roots = roots128\n",
"\n",
"def u_elem128(x, t, alpha_n):\n",
" x = np.float128(x)\n",
" t = np.float128(t)\n",
" alpha_n = np.float128(alpha_n)\n",
" return -4*np.pi**2*(alpha_n*np.cos(alpha_n*x/10) + 40*np.sin(alpha_n*x/10))*(alpha_n*np.sin(2*alpha_n) - 40*np.cos(2*alpha_n) + 40)*np.exp(-3*alpha_n**2*t/500)/(5*(alpha_n**2 - np.pi**2)*(alpha_n**2*(4*alpha_n + np.sin(4*alpha_n)) - 80*alpha_n*(np.cos(4*alpha_n) - 1) + 6400*alpha_n - 1600*np.sin(4*alpha_n)))\n",
"\n",
"@functools.lru_cache(maxsize=100000)\n",
"def u128(x, t, root_n=len(roots)):\n",
" return sum(u_elem128(x, t, roots[:root_n]))"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"@dataclass\n",
"class Grid:\n",
" I: int\n",
" K: int\n",
" \n",
" xs: ndarray\n",
" ts: ndarray\n",
" \n",
" h_x: float\n",
" h_t: float\n",
" \n",
" def __init__(self, I, K):\n",
" self.I = I\n",
" self.K = K\n",
"\n",
" self.xs = linspace(0, l_float, I + 1)\n",
" self.ts = linspace(0, T_float, K + 1)\n",
"\n",
" self.h_x = l_float / I\n",
" self.h_t = T_float / K\n",
" \n",
" self.gamma = D_float * self.h_t / (self.h_x ** 2)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"def ug_mse(ug1, ug2):\n",
" return np.mean((ug1 - ug2) ** 2)\n",
"\n",
"def ug_mae(ug1, ug2):\n",
" return np.max(np.abs(ug1 - ug2))"
]
},
{
"cell_type": "code",
"execution_count": 64,
"metadata": {},
"outputs": [],
"source": [
"n = 5000\n",
"\n",
"np.random.seed(0)\n",
"\n",
"a = np.random.uniform(0, 0.1, size=n-1)\n",
"b = np.ones(n)\n",
"c = np.random.uniform(0, 0.1, size=n-1)\n",
"\n",
"z = np.random.uniform(0, 0.1, size=n)\n",
"\n",
"A = np.zeros((n, n))\n",
"\n",
"for i in range(n):\n",
" A[i, i] = b[i]\n",
" \n",
" if i > 0:\n",
" A[i, i - 1] = a[i - 1]\n",
" \n",
" if i < n - 1:\n",
" A[i, i + 1] = c[i]"
]
},
{
"cell_type": "code",
"execution_count": 65,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1.52 s ± 78.3 ms per loop (mean ± std. dev. of 5 runs, 5 loops each)\n"
]
}
],
"source": [
"%%timeit -n 5 -r 5\n",
"np.linalg.solve(A, z)"
]
},
{
"cell_type": "code",
"execution_count": 66,
"metadata": {},
"outputs": [],
"source": [
"A_sp = scipy.sparse.diags([a, b, c], [-1, 0, 1], format='csc')"
]
},
{
"cell_type": "code",
"execution_count": 67,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"3.1 ms ± 430 µs per loop (mean ± std. dev. of 5 runs, 5 loops each)\n"
]
}
],
"source": [
"%%timeit -n 5 -r 5\n",
"scipy.sparse.linalg.spsolve(A_sp, z)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## теория"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"def calc_theoretical(grid):\n",
" ug = zeros((grid.K + 1, grid.I + 1), dtype=float)\n",
" \n",
" for k, t in enumerate(grid.ts):\n",
" for i, x in enumerate(grid.xs):\n",
" ug[k, i] = u128(x, t, 100)\n",
" \n",
" return ug"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"58.89331758385291\n"
]
}
],
"source": [
"grid = Grid(10, 50)\n",
"print(sum(calc_theoretical(grid)))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## простейшая явная схема"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"def calc_explicit(grid):\n",
" if grid.gamma > 1/2:\n",
" raise Exception('Bad gamma!')\n",
" \n",
" ug = zeros((grid.K + 1, grid.I + 1), dtype=float)\n",
"\n",
" ug[0, :] = sin(np.pi * grid.xs / l_float) ** 2 * 4 / 10\n",
"\n",
" for k in range(1, grid.K + 1):\n",
" # middle\n",
" ug[k, 1 : grid.I] = (\n",
" grid.gamma * ug[k - 1, 0 : grid.I - 1] +\n",
" (-2 * grid.gamma + 1) * ug[k - 1, 1 : grid.I] + \n",
" grid.gamma * ug[k - 1, 2 : grid.I + 1]\n",
" )\n",
"\n",
" # left\n",
" ug[k, 0] = ug[k, 1] / (H_float * grid.h_x + 1)\n",
"\n",
" # right\n",
" ug[k, grid.I] = ug[k, grid.I - 1] / (H_float * grid.h_x + 1)\n",
" \n",
" return ug"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"58.72948448630509\n",
"4.3733803061715146e-07\n"
]
}
],
"source": [
"grid = Grid(10, 50)\n",
"ug = calc_explicit(grid)\n",
"print(sum(ug))\n",
"print(ug_mse(ug, calc_theoretical(grid)))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## простейшая неявная схема"
]
},
{
"cell_type": "code",
"execution_count": 76,
"metadata": {},
"outputs": [],
"source": [
"def calc_implicit(grid):\n",
" ug = zeros((grid.K + 1, grid.I + 1), dtype=float)\n",
"\n",
" ug[0, :] = sin(np.pi * grid.xs / l_float) ** 2 * 4 / 10\n",
"\n",
" for k in range(1, grid.K + 1):\n",
" diags = {\n",
" -1: np.zeros(grid.I + 1, dtype=float),\n",
" 0: np.zeros(grid.I + 1, dtype=float),\n",
" +1: np.zeros(grid.I + 1, dtype=float),\n",
" }\n",
" b = np.zeros(grid.I + 1, dtype=float)\n",
"\n",
" # left\n",
" diags[ 0][0] = H_float + 1 / grid.h_x\n",
" diags[+1][0] = -1 / grid.h_x\n",
"\n",
" # middle\n",
" for i in range(1, grid.I):\n",
" diags[-1][i] = grid.gamma\n",
" diags[ 0][i] = - 2 * grid.gamma - 1\n",
" diags[+1][i] = grid.gamma\n",
" b[i] = -ug[k - 1, i]\n",
"\n",
" # right\n",
" diags[ 0][grid.I] = H_float + 1 / grid.h_x\n",
" diags[-1][grid.I] = -1 / grid.h_x\n",
"\n",
" A = scipy.sparse.diags([\n",
" diags[-1][1:], \n",
" diags[ 0], \n",
" diags[+1][:-1],\n",
" ], [-1, 0, 1], format='csc')\n",
" \n",
" ug[k, :] = scipy.sparse.linalg.spsolve(A, b)\n",
" \n",
" return ug"
]
},
{
"cell_type": "code",
"execution_count": 69,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"59.49556361037571\n",
"4.006492537092588e-06\n"
]
}
],
"source": [
"grid = Grid(10, 50)\n",
"ug = calc_implicit(grid)\n",
"print(sum(ug))\n",
"print(ug_mse(ug, calc_theoretical(grid)))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## схема Кранка-Николсон"
]
},
{
"cell_type": "code",
"execution_count": 79,
"metadata": {},
"outputs": [],
"source": [
"def calc_kn(grid):\n",
" ug = zeros((grid.K + 1, grid.I + 1), dtype=float)\n",
"\n",
" ug[0, :] = sin(np.pi * grid.xs / l_float) ** 2 * 4 / 10\n",
"\n",
" for k in range(1, grid.K + 1):\n",
" diags = {\n",
" -1: np.zeros(grid.I + 1, dtype=float),\n",
" 0: np.zeros(grid.I + 1, dtype=float),\n",
" +1: np.zeros(grid.I + 1, dtype=float),\n",
" }\n",
" b = np.zeros(grid.I + 1, dtype=float)\n",
"\n",
" # left\n",
" diags[ 0][0] = H_float + 1 / grid.h_x\n",
" diags[+1][0] = -1 / grid.h_x\n",
"\n",
" # middle\n",
" for i in range(1, grid.I):\n",
" diags[-1][i] = grid.gamma\n",
" diags[ 0][i] = - 2 * grid.gamma - 2\n",
" diags[+1][i] = grid.gamma\n",
" b[i] = -(\n",
" ug[k - 1][i - 1] * grid.gamma +\n",
" ug[k - 1][i] * (-2 * grid.gamma + 2) +\n",
" ug[k - 1][i + 1] * grid.gamma\n",
" )\n",
"\n",
" # right\n",
" diags[ 0][grid.I] = H_float + 1 / grid.h_x\n",
" diags[-1][grid.I] = -1 / grid.h_x\n",
"\n",
" A = scipy.sparse.diags([\n",
" diags[-1][1:], \n",
" diags[ 0], \n",
" diags[+1][:-1],\n",
" ], [-1, 0, 1], format='csc')\n",
" \n",
" ug[k, :] = scipy.sparse.linalg.spsolve(A, b)\n",
" \n",
" return ug"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.048762671501371764\n",
"5.115545125775158e-07\n"
]
}
],
"source": [
"grid = Grid(10, 50)\n",
"ug = calc_kn(grid)\n",
"print(mean(ug[-1]))\n",
"print(ug_mse(ug, calc_theoretical(grid)))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## простейшая неявная схема повышенного порядка аппроксимации"
]
},
{
"cell_type": "code",
"execution_count": 174,
"metadata": {},
"outputs": [],
"source": [
"def calc_implicit_improved(grid):\n",
" ug = zeros((grid.K + 1, grid.I + 1), dtype=float)\n",
"\n",
" ug[0, :] = sin(np.pi * grid.xs / l_float) ** 2 * 4 / 10\n",
"\n",
" for k in range(1, grid.K + 1):\n",
" diags = {\n",
" -1: np.zeros(grid.I + 1, dtype=float),\n",
" 0: np.zeros(grid.I + 1, dtype=float),\n",
" +1: np.zeros(grid.I + 1, dtype=float),\n",
" }\n",
" b = np.zeros(grid.I + 1, dtype=float)\n",
"\n",
" # left\n",
" diags[ 0][0] = (\n",
" 2 * H_float * grid.gamma * grid.h_x + \n",
" 2 * grid.gamma + \n",
" 1\n",
" )\n",
" diags[+1][0] = - 2 * grid.gamma\n",
" b[0] = ug[k - 1, 0]\n",
"\n",
" # middle\n",
" for i in range(1, grid.I):\n",
" diags[-1][i] = grid.gamma\n",
" diags[ 0][i] = - 2 * grid.gamma - 1\n",
" diags[+1][i] = grid.gamma\n",
" b[i] = -ug[k - 1, i]\n",
"\n",
" # right\n",
" diags[ 0][grid.I] = (\n",
" 2 * H_float * grid.gamma * grid.h_x + \n",
" 2 * grid.gamma + \n",
" 1\n",
" )\n",
" diags[-1][grid.I] = - 2 * grid.gamma\n",
" b[grid.I] = ug[k - 1, grid.I]\n",
"\n",
" A = scipy.sparse.diags([\n",
" diags[-1][1:], \n",
" diags[ 0], \n",
" diags[+1][:-1],\n",
" ], [-1, 0, 1], format='csc')\n",
" \n",
" ug[k, :] = scipy.sparse.linalg.spsolve(A, b)\n",
" \n",
" return ug"
]
},
{
"cell_type": "code",
"execution_count": 177,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"59.486724613775095\n",
"4.014426575945732e-06\n"
]
}
],
"source": [
"grid = Grid(10, 50)\n",
"ug = calc_implicit_improved(grid)\n",
"print(sum(ug))\n",
"print(ug_mse(ug, calc_theoretical(grid)))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Кранк-Николсон повышенного порядка аппроксимации"
]
},
{
"cell_type": "code",
"execution_count": 174,
"metadata": {},
"outputs": [],
"source": [
"def calc_kn_improved(grid):\n",
" ug = zeros((grid.K + 1, grid.I + 1), dtype=float)\n",
"\n",
" ug[0, :] = sin(np.pi * grid.xs / l_float) ** 2 * 4 / 10\n",
"\n",
" for k in range(1, grid.K + 1):\n",
" diags = {\n",
" -1: np.zeros(grid.I + 1, dtype=float),\n",
" 0: np.zeros(grid.I + 1, dtype=float),\n",
" +1: np.zeros(grid.I + 1, dtype=float),\n",
" }\n",
" b = np.zeros(grid.I + 1, dtype=float)\n",
"\n",
" # left\n",
" #diags[ 0][0] = H_float + 1 / grid.h_x\n",
" #diags[+1][0] = -1 / grid.h_x\n",
" \n",
" diags[ 0][0] = (\n",
" 2 * H_float * grid.gamma * grid.h_x + \n",
" 2 * grid.gamma + \n",
" 1\n",
" )\n",
" diags[+1][0] = - 2 * grid.gamma\n",
" b[0] = ug[k - 1, 0]\n",
"\n",
" # middle\n",
" for i in range(1, grid.I):\n",
" diags[-1][i] = grid.gamma\n",
" diags[ 0][i] = - 2 * grid.gamma - 2\n",
" diags[+1][i] = grid.gamma\n",
" b[i] = -(\n",
" ug[k - 1][i - 1] * grid.gamma +\n",
" ug[k - 1][i] * (-2 * grid.gamma + 2) +\n",
" ug[k - 1][i + 1] * grid.gamma\n",
" )\n",
"\n",
" # right\n",
" diags[ 0][grid.I] = H_float + 1 / grid.h_x\n",
" diags[-1][grid.I] = -1 / grid.h_x\n",
"\n",
" A = scipy.sparse.diags([\n",
" diags[-1][1:], \n",
" diags[ 0], \n",
" diags[+1][:-1],\n",
" ], [-1, 0, 1], format='csc')\n",
" \n",
" ug[k, :] = scipy.sparse.linalg.spsolve(A, b)\n",
" \n",
" return ug"
]
},
{
"cell_type": "code",
"execution_count": 177,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"59.486724613775095\n",
"4.014426575945732e-06\n"
]
}
],
"source": [
"grid = Grid(10, 50)\n",
"ug = calc_kn_improved(grid)\n",
"print(sum(ug))\n",
"print(ug_mse(ug, calc_theoretical(grid)))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## сравнение"
]
},
{
"cell_type": "code",
"execution_count": 128,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAO4AAAAPBAMAAAAR2O42AAAAMFBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAMpndu3bvImbNiRBUq0Qb3U6NAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADlklEQVQ4Eb2TT4hbVRTGf8nkz5u8JBN0J8jEwT906rSDFUrFYlDRjdqhIGqlTIRS0Rlq6KLKbPo2yuCmEV0IVYnakTEgBksLFiRv5a4kDnQYhdKg6LbS/zNJTc8596UdU9deeCffO/d835dz3r0A98gDC/UXiO2erNcNuXBq3zbwJz8skK6fCOGH5S+lsr6voAS4d6VerxkafT32qAENqpdZ0srhZVK3WY/rdrpIK/D6/f5NQxYokgsZDf2dHCZ7Az7jZIUfO/Eq/NyAY1LeJjsHqX6/JiKaBNHzv2CLwqFlUo4FyQO6m+wxNh2vQNuQhWxAusoH8C2zIZfxymSqPE2i5K9cEItHIMdPU10Y/e4VMbOk6SWKPDvkqa8mZSx5ee8TTeUP0axmZEAFQ+61hD/Ni9Bq/NXx10lIc938dS1nVnxrINNMim/OcpY0vYvSwH8sk6oZS9jmK1WtQMKf8jjUCvJXGpmAm3AxROc81ibfS5S1wlmQn7nbV/Wes5q7QiSlLLxK5Os/oXUleQxpuHBjGf+S+ErhyRrNIvmrYx8tyWGLfBOCrN/FvYUoaXrr9+3twJmXZaab1kBKWZzC+aa/3ipv0h+GLGT6x0lvwHiNhccaHK0R22h+Sioc+C7jfBON9D8Cdfiq568HzJPfyYIk76xICmXJRxrM+ZsONK1KERLO/nGtk5Z+xZfMIY4W1bdLXE6wWuD/LUH7lfWMPO6ji2+/wcONI6H/gG0NQiRlrGzhtm9K5F6zGkWk5rw2s3OD4XCw4eY8jSe9mW+yKnWR7/aKJZ3eZblkndX3X7U/9/EOWbsK8jfdJzPWGZxvukKiZ3fPkIVUhVhPz1UrfBf2hHKusr2RKp5cZfMdKUW+v8L3HUs6vV3iGwhxaJkUxjp7/vy1c7I91lVfX3YMWdChr+lFPNaQwe0JEyW8bq58p99mWyq037dgu/Qmf8bprWq/G0OuOCmMJXsHdD9VYuQ6MZmEIRcq8Lxe9i1a81TFKxOvxuT7lqN+x4vCVF/5lRbdELR2XL4vb8ueJDctk8JYkr0i5w8voDVDVnwNWcgfx5thJPTfYJHsVXiS0wV+43QYWbSKQlffw3hvCrThix65mj8vZ8X/9z1yUhgLTvTX2A2/T7wkV2he2IYs3D+5TU7D0v4C+YkHO3ohf5GDPSFh6p3PAzgSQnx1fY305IqM2SVVj6+mCiQfWhS1zcukjLU5+3/iW7ckZCmz5Ei9AAAAAElFTkSuQmCC\n",
"text/latex": [
"$$4.3733803061715146e-07$$"
],
"text/plain": [
"4.3733803061715146e-07"
]
},
"execution_count": 128,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ug_mse(calc_theoretical(grid), calc_explicit(grid))"
]
},
{
"cell_type": "code",
"execution_count": 169,
"metadata": {},
"outputs": [],
"source": [
"def print_comparison(Is, Ks, E, i_p, k_p, i_d, k_d):\n",
" if (\n",
" not 0 <= i_p < len(Is) or\n",
" not 0 <= k_p < len(Ks) or\n",
" not 0 <= i_p + i_d < len(Is) or\n",
" not 0 <= k_p + k_d < len(Ks) or\n",
" E[k_p, i_p] < 0 or\n",
" E[k_p + k_d, i_p + i_d] < 0\n",
" ):\n",
" return\n",
" \n",
" error_ratio = E[k_p, i_p] / E[k_p + k_d, i_p + i_d]\n",
" \n",
" I1 = Is[i_p]\n",
" I2 = Is[i_p + i_d]\n",
" K1 = Ks[k_p]\n",
" K2 = Ks[k_p + k_d]\n",
" \n",
" print(f'h_x x{I2//I1} h_t x{K2//K1} @ ({I1:5},{K1:5}): {error_ratio}')"
]
},
{
"cell_type": "code",
"execution_count": 170,
"metadata": {},
"outputs": [],
"source": [
"def compare_errors(Is, Ks, calc_function):\n",
" E = np.zeros((len(Ks), len(Is)))\n",
"\n",
" for k_p in range(len(Ks)):\n",
" for i_p in range(len(Is)):\n",
" grid = Grid(Is[i_p], Ks[k_p])\n",
"\n",
" try:\n",
" error = ug_mae(calc_function(grid), calc_theoretical(grid))\n",
" except:\n",
" error = -1\n",
"\n",
" E[k_p, i_p] = error\n",
" \n",
" for k_p in range(len(Ks)):\n",
" for i_p in range(len(Is)):\n",
" print_comparison(Is, Ks, E, i_p, k_p, +1, +1)\n",
" \n",
" for k_p in range(len(Ks)):\n",
" for i_p in range(len(Is)):\n",
" print_comparison(Is, Ks, E, i_p, k_p, +2, +1)\n",
" \n",
" for k_p in range(len(Ks)):\n",
" for i_p in range(len(Is)):\n",
" print_comparison(Is, Ks, E, i_p, k_p, +1, +2)"
]
},
{
"cell_type": "code",
"execution_count": 171,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"h_x x2 h_t x4 @ ( 16, 256): 1.919077767270527\n"
]
}
],
"source": [
"compare_errors([16, 32, 64, 128, 256], [256, 1024], calc_explicit)"
]
},
{
"cell_type": "code",
"execution_count": 172,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"h_x x2 h_t x2 @ ( 16, 16): 1.8945839194805507\n",
"h_x x2 h_t x2 @ ( 32, 16): 1.8480652483857702\n",
"h_x x2 h_t x2 @ ( 64, 16): 1.825718428756318\n",
"h_x x2 h_t x2 @ ( 128, 16): 1.8200879583854386\n",
"h_x x2 h_t x2 @ ( 16, 32): 2.011003900865954\n",
"h_x x2 h_t x2 @ ( 32, 32): 1.8852164156444766\n",
"h_x x2 h_t x2 @ ( 64, 32): 1.8445734893796497\n",
"h_x x2 h_t x2 @ ( 128, 32): 1.8438755692851074\n",
"h_x x2 h_t x2 @ ( 16, 64): 2.17619657916294\n",
"h_x x2 h_t x2 @ ( 32, 64): 1.9562383707853712\n",
"h_x x2 h_t x2 @ ( 64, 64): 1.912181287104185\n",
"h_x x2 h_t x2 @ ( 128, 64): 1.9058730801460957\n",
"h_x x2 h_t x2 @ ( 16, 128): 2.3986401861806734\n",
"h_x x2 h_t x2 @ ( 32, 128): 2.066009495516749\n",
"h_x x2 h_t x2 @ ( 64, 128): 1.9741429057474853\n",
"h_x x2 h_t x2 @ ( 128, 128): 1.955899186659026\n",
"h_x x4 h_t x2 @ ( 16, 16): 1.9431575629889533\n",
"h_x x4 h_t x2 @ ( 32, 16): 1.8496006164556726\n",
"h_x x4 h_t x2 @ ( 64, 16): 1.8261475842007147\n",
"h_x x4 h_t x2 @ ( 16, 32): 2.0776417503976705\n",
"h_x x4 h_t x2 @ ( 32, 32): 1.8918649575362794\n",
"h_x x4 h_t x2 @ ( 64, 32): 1.845407456579902\n",
"h_x x4 h_t x2 @ ( 16, 64): 2.326489502477712\n",
"h_x x4 h_t x2 @ ( 32, 64): 1.9755444903443895\n",
"h_x x4 h_t x2 @ ( 64, 64): 1.9125944713395193\n",
"h_x x4 h_t x2 @ ( 16, 128): 2.8326076010600714\n",
"h_x x4 h_t x2 @ ( 32, 128): 2.1104815578650395\n",
"h_x x4 h_t x2 @ ( 64, 128): 1.9752019588093679\n",
"h_x x2 h_t x4 @ ( 16, 16): 3.45714271998841\n",
"h_x x2 h_t x4 @ ( 32, 16): 3.396912364589268\n",
"h_x x2 h_t x4 @ ( 64, 16): 3.3648762818042726\n",
"h_x x2 h_t x4 @ ( 128, 16): 3.3552270369444783\n",
"h_x x2 h_t x4 @ ( 16, 32): 3.6798635241236157\n",
"h_x x2 h_t x4 @ ( 32, 32): 3.569646703206942\n",
"h_x x2 h_t x4 @ ( 64, 32): 3.514763487476464\n",
"h_x x2 h_t x4 @ ( 128, 32): 3.512604694405925\n",
"h_x x2 h_t x4 @ ( 16, 64): 3.8072301037478553\n",
"h_x x2 h_t x4 @ ( 32, 64): 3.780516278348026\n",
"h_x x2 h_t x4 @ ( 64, 64): 3.7380285131624063\n",
"h_x x2 h_t x4 @ ( 128, 64): 3.726890300676519\n"
]
}
],
"source": [
"compare_errors([16, 32, 64, 128, 256], [16, 32, 64, 128, 256], calc_implicit)"
]
},
{
"cell_type": "code",
"execution_count": 173,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"h_x x2 h_t x2 @ ( 16, 16): 1.7867407245342732\n",
"h_x x2 h_t x2 @ ( 32, 16): 2.0659339289789247\n",
"h_x x2 h_t x2 @ ( 64, 16): 2.206577164218172\n",
"h_x x2 h_t x2 @ ( 128, 16): 2.205398898130605\n",
"h_x x2 h_t x2 @ ( 16, 32): 1.0260466758467883\n",
"h_x x2 h_t x2 @ ( 32, 32): 1.985994321847054\n",
"h_x x2 h_t x2 @ ( 64, 32): 2.0974055723617107\n",
"h_x x2 h_t x2 @ ( 128, 32): 2.1318052621473274\n",
"h_x x2 h_t x2 @ ( 16, 64): 1.8854175495471748\n",
"h_x x2 h_t x2 @ ( 32, 64): 1.5501374544674071\n",
"h_x x2 h_t x2 @ ( 64, 64): 2.0605293935478826\n",
"h_x x2 h_t x2 @ ( 128, 64): 2.1241455078974423\n",
"h_x x2 h_t x2 @ ( 16, 128): 2.2073516657031678\n",
"h_x x2 h_t x2 @ ( 32, 128): 1.8202146022973351\n",
"h_x x2 h_t x2 @ ( 64, 128): 1.8615590435162546\n",
"h_x x2 h_t x2 @ ( 128, 128): 2.093178235555532\n",
"h_x x4 h_t x2 @ ( 16, 16): 1.5416112730228488\n",
"h_x x4 h_t x2 @ ( 32, 16): 1.9411758005230835\n",
"h_x x4 h_t x2 @ ( 64, 16): 2.132375626592411\n",
"h_x x4 h_t x2 @ ( 16, 32): 0.672923482269376\n",
"h_x x4 h_t x2 @ ( 32, 32): 1.8096548816821525\n",
"h_x x4 h_t x2 @ ( 64, 32): 2.0030692793517577\n",
"h_x x4 h_t x2 @ ( 16, 64): 2.09685316770308\n",
"h_x x4 h_t x2 @ ( 32, 64): 1.3513796667001667\n",
"h_x x4 h_t x2 @ ( 64, 64): 1.9355394149338634\n",
"h_x x4 h_t x2 @ ( 16, 128): 5.089679627450866\n",
"h_x x4 h_t x2 @ ( 32, 128): 2.07031910687416\n",
"h_x x4 h_t x2 @ ( 64, 128): 1.8247920519286784\n",
"h_x x2 h_t x4 @ ( 16, 16): 5.410544492760973\n",
"h_x x2 h_t x4 @ ( 32, 16): 4.755334696107873\n",
"h_x x2 h_t x4 @ ( 64, 16): 4.925531450048806\n",
"h_x x2 h_t x4 @ ( 128, 16): 4.865081194253896\n",
"h_x x2 h_t x4 @ ( 16, 32): 1.4301343984858494\n",
"h_x x2 h_t x4 @ ( 32, 32): 4.6940709147810455\n",
"h_x x2 h_t x4 @ ( 64, 32): 4.742894620222057\n",
"h_x x2 h_t x4 @ ( 128, 32): 4.7415271368204355\n",
"h_x x2 h_t x4 @ ( 16, 64): 1.4883710757235502\n",
"h_x x2 h_t x4 @ ( 32, 64): 2.537069293873301\n",
"h_x x2 h_t x4 @ ( 64, 64): 4.399957273891053\n",
"h_x x2 h_t x4 @ ( 128, 64): 4.733335280216436\n"
]
}
],
"source": [
"compare_errors([16, 32, 64, 128, 256], [16, 32, 64, 128, 256], calc_kn)"
]
},
{
"cell_type": "code",
"execution_count": 181,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"h_x x2 h_t x2 @ ( 32, 128): 2.038390823677269\n",
"h_x x2 h_t x2 @ ( 64, 128): 1.9736276882133699\n",
"h_x x2 h_t x2 @ ( 32, 256): 2.1614872398503246\n",
"h_x x2 h_t x2 @ ( 64, 256): 2.025328231523804\n",
"h_x x2 h_t x2 @ ( 32, 512): 2.373745419372439\n",
"h_x x2 h_t x2 @ ( 64, 512): 2.0878950429120877\n",
"h_x x2 h_t x2 @ ( 32, 1024): 2.713172301556474\n",
"h_x x2 h_t x2 @ ( 64, 1024): 2.185936854335897\n",
"h_x x4 h_t x2 @ ( 32, 128): 2.1195416132190292\n",
"h_x x4 h_t x2 @ ( 32, 256): 2.330981592342115\n",
"h_x x4 h_t x2 @ ( 32, 512): 2.7365187229137757\n",
"h_x x4 h_t x2 @ ( 32, 1024): 3.543382713251337\n",
"h_x x2 h_t x4 @ ( 32, 128): 3.8282183811233788\n",
"h_x x2 h_t x4 @ ( 64, 128): 3.8442015881699336\n",
"h_x x2 h_t x4 @ ( 32, 256): 3.9146871029344097\n",
"h_x x2 h_t x4 @ ( 64, 256): 3.921190229218736\n",
"h_x x2 h_t x4 @ ( 32, 512): 3.973114349424527\n",
"h_x x2 h_t x4 @ ( 64, 512): 3.958967998390918\n"
]
}
],
"source": [
"compare_errors([32, 64, 128], [128, 256, 512, 1024, 2048], calc_implicit_improved)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"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.7.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

Binary file not shown.

Binary file not shown.