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
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"
Generated
+237
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
View File
File diff suppressed because one or more lines are too long
BIN
View File
Binary file not shown.
View File
+5
View File
@@ -0,0 +1,5 @@
l = 20
T = 100
D = 0.6
H = 4
View File
+86
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
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}')
+27
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
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,
]
+102
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
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
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
+35
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
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
View File
File diff suppressed because one or more lines are too long
View File
+31
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
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
+906
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.