loganbvh / py-tdgl

2D time-dependent Ginzburg-Landau in Python
MIT License
31 stars 12 forks source link

Append new solution to seed solution #80

Open diazlcarlos98 opened 2 weeks ago

diazlcarlos98 commented 2 weeks ago

I would like to study the dynamics of the vortex lattice as the field is increased as a step function. This can easily be done if I define a time dependent field such as

def step_function(x, y, z, *, t, tmax, step_size, final = 1.2):
    if t < tmax:
        return final * np.trunc(t / step_size) * step_size / (tmax - step_size)
    return final

tmax = 3000
final = 1.5
step_size=250
t_dependence = tdgl.Parameter(step_function, tmax=tmax, step_size=step_size, final=final, time_dependent=True)
increasing_vector_potential = tdgl.sources.ConstantField(1., field_units=field_units, length_units=length_units) * t_dependence
options = tdgl.SolverOptions(
    skip_time=0,
    solve_time=3000,
    save_every=200,
    field_units=field_units,
    output_file=os.path.join(tempdir.name, "increasing-field.h5"),
)
solution = tdgl.solve(device, options, decreasing_vector_potential)

The problem is that having a time dependent field greatly increases the runtime. My assumption is that at each step the spatial link variables are recomputed. Since the field remains constant within each step (in terms of the increase of the filed, not simulation time steps), I was able to work my way around this issue by solving the equations one step at a time, using the previous solution as the starting point at each new step:

step_size = 250
tmax = 3000
steps = int(np.ceil(tmax / step_size))
final = 1.5
options = tdgl.SolverOptions(
    skip_time=0,
    solve_time=step_size,
    save_every=200,
    field_units=field_units,
    output_file=os.path.join(tempdir.name, "increasing-field-steps.h5"),
)
for step in range(steps):
    b_z = (final / (steps - 1)) * step
    field = tdgl.sources.ConstantField(b_z, field_units=field_units, length_units=length_units)
    if step == 0:
        solution = tdgl.solve(device, options, applied_vector_potential=b_z)
    else:
        solution = tdgl.solve(device, options, applied_vector_potential=b_z, seed_solution=solution)

By doing this, I decreased the runtime from 63 minutes to only 8! The only problem, though, is that if I want to create an animation, it will only do so for the last step of the solution rather than the solution as a whole. I wanted to know if it would be possible to have an option to append the new solution to the previous one for this matter.

Thank you for your time and attention and thank you for creating this package!

loganbvh commented 2 weeks ago

Hi Carlos, this is a good suggestion. I will work on implementing this when I have time (in the next week or two). In the meantime, you can use ffmpeg to concatenate animations together. From a terminal:

ffmpeg -f concat -safe 0 -i input_files.txt -c copy output_file.mp4

input_files.txt is a plain text file with the names of the existing animations you'd like to concatenate:

# input_files.txt
file 'animation-0.mp4'
file 'animation-1.mp4'
file 'animation-2.mp4'

More detailed instructions here https://trac.ffmpeg.org/wiki/Concatenate