LASY-org / lasy

https://lasydoc.readthedocs.io
Other
29 stars 23 forks source link

API #24

Open MaxThevenet opened 1 year ago

MaxThevenet commented 1 year ago

In the current implementation, the central class is Laser, which contains the laser profile parameters, one grid where the laser is defined and will also contain the propagator. The current API would be: The current one

 box = Box()
 laser = GaussianLaser(box, ) # or any class derived from Laser
 laser.propagate()
 laser.write_to_file()

Manuel raised the point that, in this way, class Laser (and its derived classes) contain a mix of numerical and physical parameters, while the laser (understand: laser profile) should only contain physical properties. So we discussed a few ways to abstract the laser profile so it can be defined with physical parameters only. This is made complicated by the variety of profiles: some profiles, e.g. from experiments, are actually only defined on a grid, so there would be some interpolation between this grid and the propagator one. Suggestions would be: The simulation-like This is close to the current one, just separating the laser profile. Also, in the snippet below, Lasy could be Laser. This may be a good improvement to the current one, but still has some limitation (having multiple grids, propagators, geometries etc. will not be naturally supported, but ofc can be done with multiple lasy instances).

laser_profile = GaussianLaserProfile(...)
box = Box()
grid = Grid(box)
propagator = Propagator()
lasy = Lasy(laser_profile, grid, propagator, ...)
lasy.propagate() # or evaluate
lasy.rt_to_xyt()
lasy.write_to_file()

(if box and grid are initialised inside Lasy/Laser, it is very close to the current one, with just the laser profile explicitly separated.) The object-oriented one

laser = GaussianLaser(...)
grid = Grid(dim='xyt') # 3D cartesian
propagator = Propagator(laser, grid) # only propagator has a grid
propagator.propagate()
write_to_file(laser, grid, propagator) # not sure if write_to_file naturally belongs to a class

grid_rz = Grid(dim='rt') # 2D cylindrical
propagator_rz = Propagator(laser, grid_rz)
propagator_rz.propagate()
write_to_file(laser, grid_rz, propagator_rz)

Here are points that we should consider in the discussion:

MKirchen commented 1 year ago

Some alternative (more detailed) example for the simulation-like API:

# Laser definition (purely physics-related properties)
long_profile = GaussianChirpedLongitudinalProfile(tau, ...) # Longitudinal profile
trans_profile = GaussianTransverseProfile(w0, ...)  # Transverse profile
laser_profile = ParaxialApproximationLaser(long_profile, trans_profile, E_laser, ...) # Combined profile

# Create numerical Grid to evaluate and propagate laser on
grid = Cartesian3DGrid(xmin, xmax, dx, t=0) # Set up a grid (can also be cylindrical)
propagator = PSATDPropagator() # Initialize numerical Propagator

# Create laser object
laser = Laser(laser_profile, grid, propagator, ...)

# Propagate and export to file
laser.propagate(t=1000.e-15) # will propagate to t
laser.export('openpmd') # will save a standardized openpmd file at current t

# Interactive evaluation
Ex, Ey = laser.evaluate(x, y, z, t=1000.e-15, quantity=['Ex', 'Ey']) # will automatically propagate to t and return fields

# Run diagnostics
laser.get_spectrum(plot=True)
MKirchen commented 1 year ago

Slightly changed version based on our discussion during the meeting on 06.12.2022:

# Laser definition (purely physics-related properties)
long_profile = GaussianChirpedLongitudinalProfile(tau, ...) # Longitudinal profile
trans_profile = GaussianTransverseProfile(w0, ...)  # Transverse profile
laser_profile = ParaxialApproximationLaser(long_profile, trans_profile, E_laser, ...) # Combined profile

# Create lasy object that serves as a "simulation-like" object
lasy = Lasy(xmin, xmax, dx, t=0, dim='xyz', propagator='psatd', ...) # Internally creates grid and propagator objects

# Add a laser (could also add other elements in the future, e.g. a non-linear optic)
laser = lasy.add_laser(laser_profile)

# Propagate and export to file
lasy.propagate(t=1000.e-15) # will propagate to t
lasy.export('openpmd') # will save a standardized openpmd file at current t

# Interactive evaluation
Ex, Ey = lasy.evaluate(x, y, z, t=1000.e-15, quantity=['Ex', 'Ey']) # will automatically propagate to t and return fields

# Run diagnostics
lasy.get_spectrum(plot=True)