Open In Colab

4819296bbe9f4ac48d4e6cb6031276ad

Tutorial: Interpolating simulation fields in time

[1]:
try:
    from google.colab import drive
    %pip install -Uq git+https://github.com/seap-udea/fargopy
except ImportError:
    print("Not running in Colab, skipping installation")
    %load_ext autoreload
    %autoreload 2
!mkdir -p ./gallery/

Not running in Colab, skipping installation

In this notebook, we illustrate how to interpolate between snapshots, ie. in the time direction, data from FARGO3D

With the interpolated data, we can generate enhanced plots and animations that provide deeper insights into the simulation results. This allows for better visualization and understanding of the physical phenomena represented in the data.

Before starting

If you are in Google Colab, install the latest version of the package:

For this tutorial you will need the following external modules and tools:

[2]:
import fargopy as fp
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from celluloid import Camera
from tqdm import tqdm
from IPython.display import HTML
Running FARGOpy version 1.1.1.
NOTE: Since alpha versions (<=0.X.X) a major refactor has been done in versions 1.1.X.
Please check the documentation for more information.

Let’s FARGOpy

Download, for instance, the 3D simulation of a disk with a Jovian planet:

[3]:
PATH = fp.Simulation.download_precomputed('p3disoj')
sim = fp.Simulation(output_dir=PATH)
Precomputed output directory '/tmp/p3disoj' already exist
Your simulation is now connected with '/Users/jzuluaga/fargo3d/'
Now you are connected with output directory '/tmp/p3disoj'
Found a variables.par file in '/tmp/p3disoj', loading properties
Loading variables
85 variables loaded
Simulation in 3 dimensions
Loading domain in spherical coordinates:
        Variable phi: 128 [[0, np.float64(-3.117048960983623)], [-1, np.float64(3.117048960983623)]]
        Variable r: 64 [[0, np.float64(0.5078125)], [-1, np.float64(1.4921875)]]
        Variable theta: 32 [[0, np.float64(1.4231400767948967)], [-1, np.float64(1.5684525767948965)]]
Number of snapshots in output directory: 11
Planets found in summary.dat
  Name: Jupiter, Initial pos: [1.0, 0.001, 0.0], Mass: 0.001

Now we can load multiples fields as a list from specific snapshots:

[4]:
fields_interp = sim.load_field(
    fields='gasdens',
    slice='phi=0',
    snapshot=(0,10)
)
Xrot = fields_interp.var1_mesh[0]  # X mesh
Yrot = fields_interp.var2_mesh[0]  # Y mesh
Zrot = fields_interp.var3_mesh[0]  # Z mesh

Time Interpolation

1D + Time

Lets see the time interpolatión in action:

[14]:
fields = sim.load_field(
    fields='gasdens',
    slice="phi=0,theta= 89 deg",
    snapshot=[0,10])

xsim = fields.var1_mesh[0]
ysim = fields.var2_mesh[0]
zsim = fields.var3_mesh[0]
rsim = np.sqrt(xsim**2 + ysim**2 + zsim**2)

times = np.linspace(0, 1.0, 100)  # 100 timesteps
[15]:
snap_table = fields.snapshot_time_table
snapshots = snap_table["Snapshot"].values
norm_times = snap_table["Normalized_time"].values

times = np.linspace(0, 1.0, 100)  # 100 timesteps
tolerance = (norm_times[1] - norm_times[0])

plt.ioff()
fig, axs = plt.subplots(1, 1, figsize=(8, 6))
camera = Camera(fig)

for t in times:

    fp.Plot.fargopy_mark(axs)
    rmin = sim.domains.r.min()
    rmax = sim.domains.r.max()
    rhosim = fields.gasdens_mesh[0]

    rs=np.linspace(rmin, rmax, 100)
    dens = fields.evaluate(field='gasdens',time=t, var1=rs)
    axs.plot(rs, dens, color='orangered', label='Space-time interpolated data')
    idx = np.argmin(np.abs(norm_times - t))
    if np.abs(norm_times[idx] - t) < tolerance:
        snap = int(snapshots[idx])
        fields = sim.load_field(
            fields='gasdens',
            slice="phi=0,theta=1.56",
            snapshot=snap
        )
        r = np.sqrt(fields.var1_mesh[0]**2+fields.var2_mesh[0]**2+fields.var3_mesh[0]**2)
        rhosim = fields.gasdens_mesh[0]
        axs.scatter(rsim, rhosim, color='dodgerblue', label=f'Simulated data')
    axs.set_xlabel('$x$ [au]')
    axs.set_ylabel(r'$\rho$ [g/cm]')
    axs.text(0.03, 0.98, f'Normalized time: {t:.2f}',
              transform=axs.transAxes, ha='left', va='top',
                fontsize=12, bbox=dict(facecolor='white', alpha=0.7, edgecolor='none'))
    handles, labels = axs.get_legend_handles_labels()
    by_label = dict(zip(labels, handles))
    axs.legend(by_label.values(), by_label.keys())
    axs.grid(0.3)
    camera.snap()

plt.ion()
animation = camera.animate(interval=150, blit=False)
animation.save('gallery/fargopy-tutorial-interpolation_4.gif', writer='pillow') # Save animation

print(f"Generating animation (it may take a while, go for a coffee)...")
HTML(animation.to_jshtml())
Generating animation (it may take a while, go for a coffee)...
[15]:

2D + Time

Now we can obtain the density at any point in space and at any moment in time, allowing us to observe its temporal evolution in greater detail.

[5]:
steps=100 # Number of time steps for the interpolation
times= np.linspace(0, 1.0, steps)

Let’s create an animation to visualize this behavior dynamically.

[6]:
plt.ioff()
fig,axs = plt.subplots(1,1,figsize=(6,6))
cmap = 'Spectral_r'
camera = Camera(fig)

xmin,xmax = fields_interp.var1_mesh[0].min(), fields_interp.var1_mesh[0].max()
zmin,zmax = fields_interp.var3_mesh[0].min(), fields_interp.var3_mesh[0].max()

axs.set_xlim(xmin, xmax)
axs.set_ylim(zmin, zmax)
axs.set_xlabel('$x$ [au]')
axs.set_ylabel('$z$ [au]')

fp.Plot.fargopy_mark(axs)

times= np.linspace(0, 1.0, 100)

for t in tqdm(times):

    dens = fields_interp.evaluate(
        time=t,
        var1=Xrot,
        var3=Zrot
    )

    dens = np.log10(dens * sim.URHO)
    pc = axs.contourf(Xrot, Zrot, dens, cmap=cmap, levels=100)
    axs.contour(Xrot, Zrot, dens, levels=20, colors='k', linewidths=0.5)
    axs.text(0.03, 0.98, f'Normalized time: {t:.2f}',transform=axs.transAxes,
              ha='left', va='top', fontsize=12, bbox=dict(facecolor='white', alpha=0.7, edgecolor='none'))


    camera.snap()

plt.colorbar(pc, ax=axs, label=f'Gas Density Log($g/cm^3$)')
plt.ion()

animation = camera.animate(interval=100,blit=True)
animation.save('gallery/fargopy-tutorial-interpolation.gif', writer='pillow')

print(f"Generating animation (it may takes a while, go for a coffee)...")
HTML(animation.to_jshtml())
100%|██████████| 100/100 [00:02<00:00, 42.92it/s]
Generating animation (it may takes a while, go for a coffee)...
[6]:
../_images/examples_fargopy-tutorial-time_interpolation_22_3.png

Let’s see an azimutal plot:

[7]:
fields_interp = sim.load_field(
    fields='gasdens',
    slice='r=[0.8,1.2],phi=[-25 deg,25 deg],theta=1.56',
    snapshot=(0,10)
)
Xrot = fields_interp.var1_mesh[0]  # X mesh
Yrot = fields_interp.var2_mesh[0]  # Y mesh

xmin,xmax = fields_interp.var1_mesh[0].min(), fields_interp.var1_mesh[0].max()
ymin,ymax = fields_interp.var2_mesh[0].min(), fields_interp.var2_mesh[0].max()

Animate it!

[8]:
plt.ioff()

fig,axs = plt.subplots(1,1,figsize=(6,6))
cmap = 'Spectral_r'
camera = Camera(fig)

axs.set_xlim(xmin, xmax)
axs.set_ylim(ymin, ymax)
axs.set_xlabel('$x$ [au]')
axs.set_ylabel('$y$ [au]')

fp.Plot.fargopy_mark(axs)

fields= sim.load_field(
    fields='gasdens',
    slice='r=[0.8,1.2],phi=[-25 deg,25 deg],theta=1.56',
    snapshot=(0,10))

times= np.linspace(0, 1.0, 100)

for t in tqdm(times):

    dens = fields_interp.evaluate(
        time=t,
        var1=Xrot,
        var2=Yrot
    )

    dens = np.log10(dens * sim.URHO)
    pc = axs.contourf(Xrot, Yrot, dens, cmap=cmap, levels=100)
    axs.contour(Xrot, Yrot, dens, levels=20, colors='k', linewidths=0.5)
    axs.text(0.03, 0.98, f'Normalized time: {t:.2f}',transform=axs.transAxes,
              ha='left', va='top', fontsize=12, bbox=dict(facecolor='white', alpha=0.7, edgecolor='none'))


    camera.snap()

plt.colorbar(pc, ax=axs, label=f'Gas Density Log($g/cm^3$)')
plt.ion()
animation = camera.animate(interval=100,blit=True)
animation.save('gallery/fargopy-tutorial-interpolation_9.gif', writer='pillow', fps=10)

print(f"Generating animation (it may takes a while, go for a coffee)...")
HTML(animation.to_jshtml())
100%|██████████| 100/100 [00:01<00:00, 81.06it/s]
Generating animation (it may takes a while, go for a coffee)...
[8]:

Powered by fargopy. For more examples see fargopy GitHub repo.

Jorge I. Zuluaga, Alejandro Murillo-González and Matías Montesinos © 2023-present