Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
f682c57
- updated license on page
ptuemmler Nov 3, 2025
9579e5a
- added draft tags
ptuemmler Nov 5, 2025
9fa3854
- added fractional derivatives app
ptuemmler Nov 5, 2025
fd5b165
- added first vector calculus app, namely for gradients!
ptuemmler Nov 7, 2025
1fa605f
improved function inputs
ptuemmler Nov 8, 2025
fcced31
added curl and gradient apps to nabla demonstration
ptuemmler Nov 8, 2025
dd8f376
added sliders for axis limits
ptuemmler Nov 16, 2025
c4b0274
- finished minkowski app
ptuemmler Nov 17, 2025
f0de7cd
- updated some templates
ptuemmler Nov 17, 2025
0bbb698
Merge branch 'main' into main
ptuemmler Nov 17, 2025
55d7fe2
Merge remote-tracking branch 'origin/main'
ptuemmler Nov 21, 2025
5d41e98
started adding minkowski applet for twin paradox
ptuemmler Nov 21, 2025
c86fca7
removed redundant '@reactive.calc'
ptuemmler Nov 21, 2025
174bff7
removed redundant color definition
ptuemmler Nov 21, 2025
446b53f
fixed typo preventing app from loading
ptuemmler Nov 21, 2025
897ab9c
embedded twin paradox minkowski app
ptuemmler Nov 21, 2025
5963e06
added doppler app to minkowski
ptuemmler Nov 22, 2025
8b471d9
improved motion minkowski app
ptuemmler Nov 22, 2025
cb1de1f
improved motion minkowski app
ptuemmler Nov 22, 2025
bcb58f0
improved motion minkowski app
ptuemmler Nov 22, 2025
23c096b
started working on a lagrange point app
ptuemmler Nov 22, 2025
95d7775
got side-tracked and added a simple orbital integrator using rk4
ptuemmler Nov 23, 2025
393ddb9
- updated xlimit
ptuemmler Nov 24, 2025
d162855
- added lightcones
ptuemmler Nov 24, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions docs/apps/FourierTransforms/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,6 @@

def server(input, output, session):
click_data = reactive.value(None)
blue = 'navy'
red = 'firebrick'

x_axis = np.linspace(-20, 20, 1024)
freq_axis = np.fft.fftfreq(len(x_axis), d=(x_axis[1] - x_axis[0]))
Expand Down
16 changes: 16 additions & 0 deletions docs/apps/LagrangianPoints/app.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
authors:
- ptuemmler
categories:
- Physics
tags:
- Draft
date: 2025-11-23
hide:
- toc
---

# Lagrangian Points
<!-- more -->
{{embed_app("100%", "830px")}}
Underlying potential taken from: [https://doi.org/10.1086/381315](https://doi.org/10.1086/381315)
68 changes: 68 additions & 0 deletions docs/apps/LagrangianPoints/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import numpy as np
import plotly.graph_objects as go
from shiny import App, Inputs, Outputs, Session, render, ui

app_ui = ui.page_sidebar(
ui.sidebar(
ui.input_slider("q", "Mass Ratio (q)", min=0.0, max=1.0, value=0.05, step=0.01),
# ui.input_slider("x", "x", min=0.0, max=2.0, value=1.0, step=0.01),
ui.input_dark_mode(id='dark_mode'),
),
ui.output_ui("plot")
)

def server(input: Inputs, output: Outputs, session: Session):
@render.ui
def plot():
# Set template based on dark mode
if input.dark_mode() == "dark":
template = "plotly_dark"
else:
template = "plotly_white"

fig = go.Figure()
# Add isosurface representing the potential field
x, y = np.meshgrid(np.linspace(-2, 2, 256),
np.linspace(-2, 2, 256))
z = np.zeros_like(x)

q = input.q()
# x_pos = input.x()
values = (x - q/(1+q))**2 + y**2 + 2/((1+q)*np.sqrt(x**2 + y**2 + z**2)) + 2*q/((1+q)*np.sqrt((x-1)**2 + y**2 + z**2))


values -= np.min(values)
min_value = 1.5
values[values > min_value] = np.nan # Mask values above a certain threshold

fig.add_trace(go.Surface(
contours = {
"z": {"show": True, "start": -min_value, "end": 0.01, "size": 0.05}
},
x=x,
y=y,
z=-values, # Offset for better visibility
colorscale='turbo',
colorbar_title_text='f(x,y)',
showscale=True,
hoverinfo='skip'
))

# Set layout
fig.update_layout(
template=template,
scene=dict(
xaxis_title='X-axis',
yaxis_title='Y-axis',
zaxis_title='Z-axis',
xaxis_showspikes=False,
yaxis_showspikes=False,
zaxis_showspikes=False,
),
height=700,
margin=dict(l=0, r=0, t=0, b=0),
)

return ui.HTML(fig.to_html())

app = App(app_ui, server)
2 changes: 2 additions & 0 deletions docs/apps/LagrangianPoints/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
numpy
plotly
4 changes: 3 additions & 1 deletion docs/apps/MinkowskiSpaceTime/app.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ draft: true
---
# Minkowski Space-Time
<!-- more -->
{{embed_app("100%", "800px")}}
{{embed_app("100%", "800px", "stationary")}}
{{embed_app("100%", "800px", "doppler")}}
{{embed_app("100%", "800px", "motion")}}
151 changes: 151 additions & 0 deletions docs/apps/MinkowskiSpaceTime/doppler/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap, Normalize
import numpy as np
import pandas as pd
from shiny import App, render, ui, reactive

berlin_cmap = [[0.621082, 0.690182, 0.999507],[0.612157, 0.689228, 0.995374],[0.603202, 0.688250, 0.991239],[0.594200, 0.687257, 0.987092],[0.585165, 0.686248, 0.982922],[0.576088, 0.685222, 0.978733],[0.566961, 0.684166, 0.974524],[0.557791, 0.683098, 0.970288],[0.548590, 0.681992, 0.966016],[0.539327, 0.680859, 0.961704],[0.530034, 0.679691, 0.957350],[0.520687, 0.678484, 0.952942],[0.511295, 0.677230, 0.948466],[0.501863, 0.675908, 0.943923],[0.492368, 0.674526, 0.939297],[0.482832, 0.673075, 0.934574],[0.473239, 0.671530, 0.929751],[0.463610, 0.669898, 0.924806],[0.453931, 0.668152, 0.919735],[0.444213, 0.666275, 0.914518],[0.434440, 0.664271, 0.909136],[0.424645, 0.662120, 0.903586],[0.414818, 0.659791, 0.897845],[0.404975, 0.657289, 0.891905],[0.395137, 0.654579, 0.885750],[0.385296, 0.651674, 0.879368],[0.375493, 0.648536, 0.872757],[0.365742, 0.645164, 0.865903],[0.356059, 0.641552, 0.858801],[0.346453, 0.637692, 0.851451],[0.336982, 0.633574, 0.843855],[0.327642, 0.629189, 0.836017],[0.318487, 0.624551, 0.827937],[0.309539, 0.619657, 0.819628],[0.300784, 0.614497, 0.811108],[0.292309, 0.609115, 0.802379],[0.284098, 0.603485, 0.793470],[0.276205, 0.597634, 0.784386],[0.268595, 0.591580, 0.775143],[0.261308, 0.585335, 0.765780],[0.254368, 0.578908, 0.756296],[0.247753, 0.572328, 0.746719],[0.241464, 0.565596, 0.737066],[0.235515, 0.558748, 0.727351],[0.229842, 0.551802, 0.717600],[0.224503, 0.544750, 0.707805],[0.219485, 0.537628, 0.697998],[0.214694, 0.530433, 0.688190],[0.210172, 0.523193, 0.678377],[0.205889, 0.515897, 0.668578],[0.201771, 0.508598, 0.658787],[0.197878, 0.501258, 0.649030],[0.194172, 0.493903, 0.639287],[0.190556, 0.486541, 0.629572],[0.187112, 0.479181, 0.619898],[0.183752, 0.471826, 0.610241],[0.180500, 0.464474, 0.600622],[0.177365, 0.457117, 0.591037],[0.174264, 0.449788, 0.581483],[0.171224, 0.442474, 0.571966],[0.168242, 0.435172, 0.562486],[0.165292, 0.427884, 0.553021],[0.162439, 0.420608, 0.543603],[0.159545, 0.413370, 0.534210],[0.156739, 0.406147, 0.524856],[0.153905, 0.398932, 0.515524],[0.151122, 0.391757, 0.506230],[0.148346, 0.384591, 0.496972],[0.145641, 0.377462, 0.487751],[0.142879, 0.370343, 0.478544],[0.140138, 0.363257, 0.469389],[0.137466, 0.356204, 0.460239],[0.134777, 0.349162, 0.451147],[0.132079, 0.342150, 0.442085],[0.129401, 0.335173, 0.433042],[0.126735, 0.328195, 0.424036],[0.124090, 0.321259, 0.415071],[0.121456, 0.314347, 0.406144],[0.118899, 0.307460, 0.397234],[0.116316, 0.300608, 0.388376],[0.113731, 0.293781, 0.379546],[0.111187, 0.286980, 0.370748],[0.108613, 0.280217, 0.362004],[0.106159, 0.273497, 0.353280],[0.103670, 0.266776, 0.344594],[0.101183, 0.260108, 0.335952],[0.098776, 0.253467, 0.327342],[0.096347, 0.246850, 0.318783],[0.094059, 0.240264, 0.310267],[0.091788, 0.233727, 0.301758],[0.089506, 0.227245, 0.293318],[0.087341, 0.220800, 0.284914],[0.085142, 0.214360, 0.276576],[0.083069, 0.207981, 0.268249],[0.081098, 0.201631, 0.259992],[0.079130, 0.195361, 0.251781],[0.077286, 0.189136, 0.243589],[0.075571, 0.182943, 0.235502],[0.073993, 0.176835, 0.227434],[0.072410, 0.170785, 0.219433],[0.071045, 0.164795, 0.211500],[0.069767, 0.158901, 0.203628],[0.068618, 0.153040, 0.195818],[0.067560, 0.147319, 0.188124],[0.066665, 0.141671, 0.180452],[0.065923, 0.136076, 0.172917],[0.065339, 0.130695, 0.165458],[0.064911, 0.125349, 0.158169],[0.064636, 0.120132, 0.150946],[0.064517, 0.115070, 0.143889],[0.064554, 0.110222, 0.136957],[0.064749, 0.105427, 0.130230],[0.065100, 0.100849, 0.123569],[0.065383, 0.096469, 0.117170],[0.065574, 0.092338, 0.111008],[0.065892, 0.088201, 0.104982],[0.066388, 0.084134, 0.099288],[0.067108, 0.080051, 0.093829],[0.068193, 0.076099, 0.088470],[0.069720, 0.072283, 0.083025],[0.071639, 0.068654, 0.077544],[0.073978, 0.065058, 0.072110],[0.076596, 0.061657, 0.066651],[0.079637, 0.058550, 0.061133],[0.082963, 0.055666, 0.055745],[0.086537, 0.052997, 0.050336],[0.090315, 0.050699, 0.045040],[0.094260, 0.048753, 0.039773],[0.098319, 0.047041, 0.034683],[0.102458, 0.045624, 0.030074],[0.106732, 0.044705, 0.026012],[0.110986, 0.043972, 0.022379],[0.115245, 0.043596, 0.019150],[0.119547, 0.043567, 0.016299],[0.123812, 0.043861, 0.013797],[0.128105, 0.044459, 0.011588],[0.132315, 0.045229, 0.009531],[0.136451, 0.046164, 0.007895],[0.140635, 0.047374, 0.006502],[0.144884, 0.048634, 0.005327],[0.149230, 0.049836, 0.004346],[0.153685, 0.050997, 0.003537],[0.158309, 0.052130, 0.002882],[0.163014, 0.053218, 0.002363],[0.167811, 0.054240, 0.001963],[0.172736, 0.055172, 0.001669],[0.177801, 0.056018, 0.001469],[0.182863, 0.056820, 0.001340],[0.188058, 0.057574, 0.001262],[0.193233, 0.058514, 0.001226],[0.198463, 0.059550, 0.001227],[0.203778, 0.060501, 0.001260],[0.209092, 0.061486, 0.001322],[0.214470, 0.062710, 0.001412],[0.219897, 0.063823, 0.001529],[0.225345, 0.065027, 0.001675],[0.230856, 0.066297, 0.001853],[0.236422, 0.067645, 0.002068],[0.242016, 0.069092, 0.002325],[0.247681, 0.070458, 0.002632],[0.253390, 0.071986, 0.002998],[0.259176, 0.073640, 0.003435],[0.264997, 0.075237, 0.003955],[0.270934, 0.076965, 0.004571],[0.276928, 0.078822, 0.005301],[0.283017, 0.080819, 0.006161],[0.289196, 0.082879, 0.007171],[0.295466, 0.085075, 0.008349],[0.301858, 0.087460, 0.009726],[0.308387, 0.089912, 0.011455],[0.315024, 0.092530, 0.013324],[0.321806, 0.095392, 0.015413],[0.328738, 0.098396, 0.017780],[0.335805, 0.101580, 0.020449],[0.343036, 0.104977, 0.023440],[0.350413, 0.108640, 0.026771],[0.357947, 0.112564, 0.030456],[0.365629, 0.116658, 0.034571],[0.373470, 0.120971, 0.039115],[0.381463, 0.125606, 0.043693],[0.389583, 0.130457, 0.048471],[0.397845, 0.135474, 0.053136],[0.406220, 0.140795, 0.057848],[0.414690, 0.146274, 0.062715],[0.423229, 0.151979, 0.067685],[0.431837, 0.157906, 0.073044],[0.440444, 0.164028, 0.078620],[0.449085, 0.170269, 0.084644],[0.457704, 0.176666, 0.090869],[0.466314, 0.183213, 0.097335],[0.474900, 0.189888, 0.104064],[0.483420, 0.196677, 0.111039],[0.491910, 0.203516, 0.118190],[0.500322, 0.210433, 0.125501],[0.508690, 0.217425, 0.132983],[0.516977, 0.224432, 0.140623],[0.525197, 0.231543, 0.148349],[0.533349, 0.238624, 0.156261],[0.541440, 0.245755, 0.164233],[0.549481, 0.252923, 0.172265],[0.557462, 0.260091, 0.180403],[0.565378, 0.267255, 0.188640],[0.573272, 0.274461, 0.196924],[0.581112, 0.281673, 0.205237],[0.588920, 0.288894, 0.213625],[0.596716, 0.296114, 0.222054],[0.604484, 0.303345, 0.230529],[0.612228, 0.310617, 0.239052],[0.619976, 0.317867, 0.247618],[0.627708, 0.325132, 0.256189],[0.635438, 0.332443, 0.264815],[0.643173, 0.339745, 0.273490],[0.650917, 0.347064, 0.282179],[0.658661, 0.354395, 0.290887],[0.666419, 0.361751, 0.299640],[0.674194, 0.369121, 0.308415],[0.681975, 0.376518, 0.317219],[0.689783, 0.383920, 0.326043],[0.697596, 0.391354, 0.334929],[0.705434, 0.398794, 0.343796],[0.713288, 0.406271, 0.352720],[0.721158, 0.413757, 0.361662],[0.729054, 0.421259, 0.370618],[0.736968, 0.428796, 0.379616],[0.744900, 0.436349, 0.388639],[0.752851, 0.443923, 0.397680],[0.760831, 0.451512, 0.406747],[0.768821, 0.459124, 0.415838],[0.776844, 0.466756, 0.424962],[0.784879, 0.474407, 0.434092],[0.792935, 0.482080, 0.443269],[0.801009, 0.489763, 0.452465],[0.809110, 0.497486, 0.461672],[0.817222, 0.505207, 0.470910],[0.825358, 0.512962, 0.480170],[0.833517, 0.520732, 0.489445],[0.841692, 0.528527, 0.498763],[0.849885, 0.536335, 0.508096],[0.858092, 0.544161, 0.517448],[0.866324, 0.552013, 0.526825],[0.874568, 0.559879, 0.536218],[0.882829, 0.567761, 0.545643],[0.891110, 0.575670, 0.555082],[0.899407, 0.583585, 0.564550],[0.907716, 0.591530, 0.574038],[0.916031, 0.599492, 0.583552],[0.924368, 0.607473, 0.593095],[0.932714, 0.615460, 0.602649],[0.941076, 0.623483, 0.612229],[0.949447, 0.631512, 0.621832],[0.957832, 0.639563, 0.631467],[0.966219, 0.647628, 0.641113],[0.974619, 0.655718, 0.650792],[0.983030, 0.663823, 0.660487],[0.991448, 0.671939, 0.670216],[0.999873, 0.680072, 0.679950]]
#Taken from F. Crameri's scientific-colour-maps version 8.0.1. https://doi.org/10.5281/zenodo.1243862 (included by default in newer matplotlib versions)
berlin = LinearSegmentedColormap.from_list('berlin', berlin_cmap, N=256)
max_iterations = 1e6


app_ui = ui.page_sidebar(
ui.sidebar(
ui.input_slider(
"velocity",
"Velocity (units of c)",
min=-0.9,
max=0.9,
value=0.5,
step=0.01,
animate=True
),
ui.input_slider("period", "Period of signal (self time)", min=1, max=3, value=2, step=0.1, animate=True),
ui.input_radio_buttons("signal_type", "Signal type", choices={"ping": "ping", "periodic": "periodic"}, selected="periodic", inline=True),
ui.input_dark_mode(id='dark_mode'),
open='always'
),
ui.output_plot(
"plot",
click=True,
width="100%", height="700px"
),
)


def lorentz_transform(x, t, v):
c = 1 # velocity of light v will be in units of c
gamma = 1 / (1 - (v**2 / c**2))**0.5
x_prime = gamma * (x + v * t)
t_prime = gamma * (t + (v * x) / c**2)
return x_prime, t_prime


def mirrored(maxval, inc=1):
x = np.arange(inc, maxval, inc)
return np.r_[-x[::-1], 0, x]


def server(input, output, session):
tlimits = (-10, 10)
points_per_period = 12
color_norm = Normalize(vmin=-1, vmax=1)

@render.plot()
def plot():
if input.dark_mode() == "dark":
style_label = 'dark_background'
blue = 'lightsteelblue'
red = 'lightcoral'
cmap = berlin
else:
style_label = 'seaborn-v0_8'
blue = 'navy'
red = 'firebrick'
cmap = plt.get_cmap('RdBu_r')

with plt.style.context(style_label):
fig, ax = plt.subplot_mosaic([['minkowski', 'sender'], ['minkowski', 'receiver']])

v = input.velocity()
period = input.period()

signal_times = mirrored(tlimits[1], inc=period)
if input.signal_type() == 'ping':
signal_amplitude = np.ones_like(signal_times)
else: # input.signal_type() == 'periodic':
signal_times = np.linspace(signal_times[0], signal_times[-1], points_per_period * (len(signal_times) - 1) + 1)
signal_amplitude = np.cos(2 * np.pi * signal_times / period)

for indx, signal in enumerate(signal_times):

if input.signal_type() == 'ping':
color = 'grey'
else: # input.signal_type() == 'periodic':
# Color line according to amplitude by mapping to colormap between -1 and 1
color = cmap(color_norm(signal_amplitude[indx]))

ax['sender'].plot([signal, signal], [0, signal_amplitude[indx]], color=color)

ct_axis_transformed, x_axis_transformed = lorentz_transform(signal, 0, v)

sign = np.sign(signal) * np.sign(v)

intersection = ct_axis_transformed + sign * x_axis_transformed

# Extend signal to receiver worldline with slope 1
ax['minkowski'].plot([x_axis_transformed , 0], [ct_axis_transformed, intersection], color=color)
ax['receiver'].plot([intersection, intersection], [0, signal_amplitude[indx]], color=color)


ax['minkowski'].axvline(0, color=blue, label='Reciever worldline')
ax['minkowski'].axline((0, 0), slope=np.tan(np.pi/2 - np.atan(v)), color=red, label='Sender worldline')

ax['sender'].axhline(0, color=red)
ax['sender'].axvline(0, color=red)
ax['receiver'].axhline(0, color=blue)
ax['receiver'].axvline(0, color=blue)

ax['sender'].set_title("Sender Frame (in motion)")
ax['receiver'].set_title("Receiver Frame (at rest)")
ax['minkowski'].set_title("Minkowski Spacetime Diagram")

ax['sender'].set_xlabel("sender self time in seconds")
ax['sender'].set_ylabel("signal amplitude")
ax['receiver'].set_xlabel("receiver self time in seconds")
ax['receiver'].set_ylabel("signal amplitude")
#
ax['minkowski'].set_xlabel("x in light-seconds")
ax['minkowski'].set_ylabel("ct in light-seconds")
ax['minkowski'].set_aspect('equal')

# # Add self time ticks according to x lims of sender and receiver plots
# sender_xticks = ax['sender'].get_xticks()
# for time in sender_xticks:
# sign = np.sign(time) * np.sign(v)
# ct_axis_transformed, x_axis_transformed = lorentz_transform(time, 0, v)
# if sign < 0:
# ax['minkowski'].text(x_axis_transformed, ct_axis_transformed, f'τ={time:.0f}s ', color=red, verticalalignment='center',
# horizontalalignment='right', )
# else:
# ax['minkowski'].text(x_axis_transformed, ct_axis_transformed, f' τ={time:.0f}s', color=red, verticalalignment='center',
# horizontalalignment='left')
#
# receiver_xticks = ax['receiver'].get_xticks()
# for time in receiver_xticks:
# sign = np.sign(time) * np.sign(v)
# if sign > 0:
# ax['minkowski'].text(0, time, f'τ={time:.0f}s ', color=blue, verticalalignment='center',
# horizontalalignment='right', )
# else:
# ax['minkowski'].text(0, time, f' τ={time:.0f}s', color=blue, verticalalignment='center',
# horizontalalignment='left')

xlims = ax['minkowski'].get_xlim()
new_lim = max(5, xlims[1])
ax['minkowski'].set_xlim(-new_lim, new_lim)
return fig


app = App(app_ui, server, debug=True)
Loading