Temporal convergence test

Temporal convergence test#

from pathlib import Path
import json
import numpy as np
from collections import defaultdict
import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import requests

pd.options.display.max_columns = 5
headers = {
    "Accept": "application/vnd.github+json",
    "X-GitHub-Api-Version": "2022-11-28",
}
print("Get existing data from gist")
response = requests.get(
    f"https://api.github.com/gists/73fa6531f28da2b3633a7ddaca38a7cd",
    headers=headers,
)
data = json.loads(response.json()["files"]["convergence_test.json"]["content"])
Get existing data from gist
runs = set()
all_results = defaultdict(list)
spatial_convergence = []
for git_hash, d in data.items():
    runs |= set(d.keys())
    if "dx0.2_dt0.025" not in d:
        # We have not temporaø convergence data
        continue

    for key1, d1 in d.items():
        if "dx0.2" not in key1:
            continue  # Only select data with "dt0.05"
        for key, value in d1.items():
            all_results[key].append(value)
            
N = max(len(v) for v in all_results.values())
results = {}
for k, v in all_results.items():
    print(k, len(v))
    if len(v) == N:
        results[k] = v

df = pd.DataFrame(results)
df["timestamp"] = pd.to_datetime(df["timestamp"])
df
import_time 36
timestamp 36
simcardems_version 36
dt 36
dx 36
sha 36
coupling_type 18
num_cells_mechanics 36
num_vertices_mechanics 36
num_cells_ep 36
num_vertices_ep 36
create_runner_time 36
solve_time 36
APD40 36
APD50 36
APD90 36
triangulation 36
Vpeak 36
Vmin 36
dvdt_max 18
maxCa 36
ampCa 36
CaTD50 36
CaTD80 36
maxTa 36
ampTa 36
ttp_Ta 36
rt50_Ta 36
rt95_Ta 36
maxlmbda 36
minlmbda 36
ttplmbda 36
lmbdaD50 36
lmbdaD80 36
lmbdaD90 36
rt50_lmbda 36
rt95_lmbda 36
max_displacement_norm 36
min_displacement_norm 18
time_to_max_displacement_norm 36
time_to_min_displacement_norm 18
max_displacement_x 36
min_displacement_x 18
time_to_max_displacement_x 36
time_to_min_displacement_x 18
max_displacement_y 36
min_displacement_y 18
time_to_max_displacement_y 36
time_to_min_displacement_y 18
max_displacement_z 36
min_displacement_z 18
time_to_max_displacement_z 36
time_to_min_displacement_z 18
dvdt 18
CaTD90 18
rel_max_displacement_norm 18
max_displacement_perc_norm 18
rel_max_displacement_perc_norm 18
rel_max_displacement_x 18
max_displacement_perc_x 18
rel_max_displacement_perc_x 18
rel_max_displacement_y 18
max_displacement_perc_y 18
rel_max_displacement_perc_y 18
rel_max_displacement_z 18
max_displacement_perc_z 18
rel_max_displacement_perc_z 18
import_time timestamp ... max_displacement_z time_to_max_displacement_z
0 7.000000e-07 2023-10-26 09:55:30.404286 ... 0.103191 139.10
1 7.000000e-07 2023-10-26 09:55:29.253581 ... 0.104727 136.03
2 7.600000e-06 2023-10-26 09:55:49.558780 ... 0.104241 137.05
3 9.000000e-07 2023-09-24 20:53:40.724515 ... 0.095933 140.10
4 1.300000e-06 2023-09-24 20:53:48.670951 ... 0.097361 138.03
5 9.000000e-07 2023-09-24 20:54:02.914676 ... 0.096905 139.05
6 8.000000e-07 2023-09-11 12:49:36.181244 ... 0.097361 138.03
7 8.000000e-07 2023-09-11 12:49:34.416894 ... 0.095933 140.10
8 9.000000e-07 2023-09-11 12:49:33.033569 ... 0.096905 139.05
9 9.000000e-07 2023-06-27 12:42:47.509674 ... 0.097361 138.03
10 8.000000e-07 2023-06-27 12:43:10.218629 ... 0.095933 140.10
11 1.100000e-06 2023-06-27 12:42:43.474076 ... 0.096905 139.05
12 1.600000e-06 2023-06-05 10:35:21.889433 ... 0.096905 139.05
13 1.100000e-06 2023-06-05 10:34:55.025194 ... 0.097361 138.03
14 9.000000e-07 2023-06-05 10:35:11.636501 ... 0.095933 140.10
15 1.200000e-06 2023-05-23 19:54:22.684955 ... 0.095933 140.10
16 9.000000e-07 2023-05-23 19:54:33.438331 ... 0.097361 138.03
17 1.700000e-06 2023-05-23 19:54:21.676974 ... 0.096905 139.05
18 1.200000e-06 2023-05-22 18:51:19.153618 ... 0.095933 0.10
19 1.000000e-06 2023-05-22 18:51:19.693717 ... 0.097361 0.02
20 1.000000e-06 2023-05-22 18:51:20.047152 ... 0.096905 0.05
21 8.000000e-07 2023-05-16 08:34:00.664103 ... 0.095933 0.10
22 7.000000e-07 2023-05-16 08:33:55.188781 ... 0.097361 0.02
23 1.000000e-06 2023-05-16 08:33:56.392320 ... 0.096905 0.05
24 1.200000e-06 2023-05-10 07:52:46.302512 ... 0.096905 0.05
25 7.000000e-07 2023-05-10 07:52:37.970327 ... 0.095933 0.10
26 1.000000e-06 2023-05-10 07:52:39.150154 ... 0.097361 0.02
27 8.000000e-07 2023-04-12 20:33:24.760391 ... 0.097361 0.02
28 9.000000e-07 2023-04-12 20:33:25.203391 ... 0.096905 0.05
29 1.400000e-06 2023-04-12 20:33:25.396738 ... 0.095933 0.10
30 1.400000e-06 2023-04-12 17:17:47.733858 ... 0.097361 0.02
31 1.100000e-06 2023-04-12 17:17:24.396818 ... 0.096905 0.05
32 1.100000e-06 2023-04-12 17:17:23.977668 ... 0.095933 0.10
33 1.300000e-06 2023-04-12 09:53:44.010221 ... 0.097361 0.02
34 1.300000e-06 2023-04-12 09:53:34.139318 ... 0.096905 0.05
35 1.000000e-06 2023-04-12 09:53:31.939260 ... 0.095933 0.10

36 rows × 43 columns

dts = df["dt"].unique()
DT = np.median(dts)   # Choose the dt in the middle as the one to compare with
dts
array([0.1  , 0.025, 0.05 ])
def get_ylim(values):
    if np.isclose(values, 1).all():
        return (0.99, 1.01)
    y_max = np.max(values)
    y_min = np.min(values)
    d_max = y_max - 1
    d_min = 1 - y_min
    
    d = max(d_min, d_max) + 0.025
    return (1 - d, 1 + d)
columns = [c for c in df.columns if c not in ["timestamp", "simcardems_version", "sha", "dx", "dt"]]
git_hash = df["sha"]
versions = df["simcardems_version"]
dates = [t.date() for t in df["timestamp"]]

df_DT = df[df["dt"] == DT]
df_DT.sort_values(by='timestamp')
    
fig = make_subplots(
    rows=len(columns), 
    cols=1, 
    y_title="Percentage deviation from median case",
    subplot_titles=columns, 
    shared_xaxes=True
)

yranges = []
colors = ['red', 'green', 'blue']
for color, dt in zip(colors, sorted(dts)):
    df_dt = df[df["dt"] == dt]
    df_dt.sort_values(by='timestamp')
    
    git_hash = df_dt["sha"]
    versions = df_dt["simcardems_version"]
    dates = [t.date() for t in df_dt["timestamp"]]
    
    text = []
    for h,v, t in zip(git_hash, versions, dates):
        text.append("\n".join([
            f"<br>Git Hash: {h}</br>",
            f"<br>Version: {v}</br>",
            f"<br>Timestamp {t}</br>",
        ]))
 
    for i, c in enumerate(columns):
    
        y = df_dt[c].to_numpy() / df_DT[c].to_numpy()
    
        row = i + 1
        col = 1
        showlegend=i==0
        fig.add_trace(
            go.Scatter(
                x=df_dt["timestamp"], 
                y=y, 
                text=text, 
                hovertemplate="%{text}", 
                name=f"dt={dt}", 
                legendgroup=str(dt),
                showlegend=i==0,
                marker_color=color
            ),
            row=row, col=col
        )
        fig.update_yaxes(range=get_ylim(y), row=row, col=col)

fig.update_layout(
    height=7000,
    showlegend=True
)
fig.show()