From a57a8eaa135edc227f1d5bf1c8b7c5cceb1e7df8 Mon Sep 17 00:00:00 2001 From: Rob Shalloo Date: Wed, 26 Apr 2023 18:52:27 +0200 Subject: [PATCH] Improve Documentation Content (#117) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Maxence Thévenet Co-authored-by: Remi Lehe --- docs/source/api/profiles/transverse/index.rst | 1 + .../api/profiles/transverse/jinc_profile.rst | 2 +- .../transverse_profile_from_data.rst | 9 +++ .../code_overview/codes_supporting_lasy.rst | 19 +++++- docs/source/code_overview/index.rst | 47 ++++++++++++- docs/source/index.rst | 22 ++++-- docs/source/user_guide/index.rst | 68 +++++++++++++++++-- .../user_guide/local_machine_install.rst | 9 --- .../transverse/hermite_gaussian_profile.py | 7 +- lasy/profiles/transverse/jinc_profile.py | 1 + .../transverse_profile_from_data.py | 60 ++++++++-------- 11 files changed, 187 insertions(+), 58 deletions(-) create mode 100644 docs/source/api/profiles/transverse/transverse_profile_from_data.rst delete mode 100644 docs/source/user_guide/local_machine_install.rst diff --git a/docs/source/api/profiles/transverse/index.rst b/docs/source/api/profiles/transverse/index.rst index 396f2d31..8414b493 100644 --- a/docs/source/api/profiles/transverse/index.rst +++ b/docs/source/api/profiles/transverse/index.rst @@ -13,3 +13,4 @@ Transverse Laser Profiles hermite_gaussian_profile super_gaussian_profile jinc_profile + transverse_profile_from_data diff --git a/docs/source/api/profiles/transverse/jinc_profile.rst b/docs/source/api/profiles/transverse/jinc_profile.rst index ec864a4b..ee021f46 100644 --- a/docs/source/api/profiles/transverse/jinc_profile.rst +++ b/docs/source/api/profiles/transverse/jinc_profile.rst @@ -1,7 +1,7 @@ Jinc Transverse Profile ================================= -Used to define a Jinc transverse laser profile (i.e., a profile described by the function :math:`2\\frac{J_1(r/w_0)}{r/w_0}`, +Used to define a Jinc transverse laser profile (i.e., a profile described by the function :math:`2 \frac{J_1(r/w_0)}{r/w_0}`, where :math:`r` is the radius and :math:`J_1` is the Bessel function of the first kind of order 1). The shape of the profile is characterised by the waist :math:`w_0`. diff --git a/docs/source/api/profiles/transverse/transverse_profile_from_data.rst b/docs/source/api/profiles/transverse/transverse_profile_from_data.rst new file mode 100644 index 00000000..5684b5f5 --- /dev/null +++ b/docs/source/api/profiles/transverse/transverse_profile_from_data.rst @@ -0,0 +1,9 @@ +Transverse Profile From Data +============================ + +This class allows the user to import an experimentally measured transverse profile into ``lasy`` + +------------ + +.. autoclass:: lasy.profiles.transverse.transverse_profile_from_data.TransverseProfileFromData + :members: diff --git a/docs/source/code_overview/codes_supporting_lasy.rst b/docs/source/code_overview/codes_supporting_lasy.rst index 6c9978da..931aac95 100644 --- a/docs/source/code_overview/codes_supporting_lasy.rst +++ b/docs/source/code_overview/codes_supporting_lasy.rst @@ -1,4 +1,17 @@ -Codes Supporting LASY Input Data -================================ +Codes Supporting LASY Data +========================== -A list of codes which support LASY Data as input. +A list of codes which support LASY Data as input: + +* Many Coming Soon! + +A list of codes currently in the process of adding support: + +* `FBPIC `_ +* `Wake-T `_ +* `WarpX `_ +* `HiPACE++ `_ + +A list of standard output formats supported by ``lasy``: + +* `openPMD `_ diff --git a/docs/source/code_overview/index.rst b/docs/source/code_overview/index.rst index 12c7dc8a..80cad1f1 100644 --- a/docs/source/code_overview/index.rst +++ b/docs/source/code_overview/index.rst @@ -1,7 +1,50 @@ Overview of the Code ==================== -What's this all about then? +``lasy`` manipulates laser pulses, and operates on the laser envelope. +It can be used to define the 3D profile of a laser pulse. +The user can define seperately the transverse and longitudinal profile of the laser pulse either from a range common analytic profiles or using experimental measurements. +Once defined the laser pulse may be propagated to a user defined location. +Finally the laser profile may be outputted to file for use as an input to a variety of different simulation tools. + +Structure +######### + +All information pertaining to the representation of the laser pulse in the code is stored in the :doc:`laser <../api/laser>` object. +This contains both the physical and computational parameters. + +The physical laser pulse parameters are defined in the laser :doc:`profile <../api/profiles/index>`. +This is typically constructed from a :doc:`combination <../api/profiles/combined_profile>` of two classes representing the :doc:`longitudinal <../api/profiles/longitudinal/index>` and :doc:`transverse <../api/profiles/transverse/index>` profiles of the laser. +Alternatively, one can define the full 3D profile in a single function, for example the :doc:`GaussianProfile <../api/profiles/gaussian>` + +The data associated with a given laser pulse is stored on a :doc:`grid <../api/utils/grid>`. +To create this grid and populate it with a laser pulse, we need to know something about the computational parmaeters being used. +For example, the metadata associated with this grid such as the coordinate system being used, lower and higher ends of the computational domain and number of points etc.. +All of this information is stored in the :doc:`box <../api/utils/box>` class. + +Once a laser :doc:`laser <../api/laser>` object has been defined, we can then propagate it forwards and backwards to see how it evolves or to set it in the right place for the beginning of a subsequent simulation. +The laser object can be :doc:`outputted <../api/utils/openpmd_output>` to a standard file format for these subsequent calculations. This allows for easy incorporation of standardised laser pulses to a range of different simulation tools. + +Coordinate Systems +################## + +In 3D (x,y,t) Cartesian coordinates, the definition used is: + +.. math:: + \begin{aligned} + E_x(x,y,t) = \operatorname{Re} \left( \mathcal{E}(x,y,t) e^{-i \omega_0t}p_x \right)\\ + E_y(x,y,t) = \operatorname{Re} \left( \mathcal{E}(x,y,t) e^{-i \omega_0t}p_y \right)\end{aligned} + + +where :math:`\operatorname{Re}` stands for real part, :math:`E_x` (resp. :math:`E_y`) is the laser electric field in the :math:`x` (resp. :math:`y`) direction, :math:`\mathcal{E}` is the complex laser envelope stored and used in lasy, :math:`\omega_0 = 2\pi c/\lambda_0` is the angular frequency defined from the laser wavelength :math:`\lambda_0` and :math:`(p_x,p_y)` is the (complex and normalized) polarization vector. + +In cylindrical coordinates, the envelope is decomposed in :math:`N_m` azimuthal modes ( see Ref. [A. Lifschitz et al., J. Comp. Phys. 228.5: 1803-1814 (2009)]). Each mode is stored on a 2D grid :math:`(r,t)`, using the following definition: + +.. math:: + \begin{aligned} + E_x (r,\theta,t) = \operatorname{Re}\left( \sum_{-N_m+1}^{N_m-1}\mathcal{E}_m(r,t) e^{-im\theta}e^{-i\omega_0t}p_x\right)\\ + E_y (r,\theta,t) = \operatorname{Re}\left( \sum_{-N_m+1}^{N_m-1}\mathcal{E}_m(r,t) e^{-im\theta}e^{-i\omega_0t}p_y\right).\end{aligned} + .. toctree:: :hidden: @@ -9,5 +52,5 @@ What's this all about then? motivation data_standards - codes_supporting_lasy laser_propagation + codes_supporting_lasy diff --git a/docs/source/index.rst b/docs/source/index.rst index ca7f4c1a..4ee6e0d0 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -6,22 +6,34 @@ LASY |release| Documentation ============================ +.. warning:: + Warning: This library is currently in development, and it is, at this stage, only meant to be used/tested by developers. + We plan on releasing the first version for general users (i.e. beta version) by summer 2023. + +``lasy`` (LAser SYmple manipulator) is a Python library that facilitates the initialization of complex laser pulses, in simulations of laser-plasma interactions. + +More specifically, ``lasy`` offers many ways to define complex laser pulses (e.g. from commonly-known analytical formulas, from experimental measurements, etc.) and offers pre-processing functionalities (e.g. propagation, re-normalization, geometry conversion). +The laser field is then exported in a standardized file, that can be read by external simulation codes. + +The code is open-source and hosted on `github `__. Contributions are welcome! + .. panels:: :card: + intro-card text-center :column: col-lg-6 col-md-6 col-sm-6 col-xs-12 p-2 d-flex --- - **User Guide** + **Getting Started** ^^^^^^^^^^^^^^ - Instructions on getting started with the code. + + New to ``lasy``? Check this out for installation instructions and a first example. +++ .. link-button:: user_guide/index :type: ref - :text: How do I LASY? + :text: More Information :classes: btn-outline-primary btn-block stretched-link --- @@ -43,7 +55,7 @@ LASY |release| Documentation **API Reference** ^^^^^^^^^^^^^^^^^ - Detailed documentation of the LASY API. + Get into the nuts and bolts of the ``lasy`` API with the documentation here. +++ @@ -57,7 +69,7 @@ LASY |release| Documentation **Tutorials** ^^^^^^^^^^^^^ - Some step by step guides to using the code and some examples. + Some step-by-step guides to using the code and some common examples which you might find useful. +++ diff --git a/docs/source/user_guide/index.rst b/docs/source/user_guide/index.rst index cfd740ce..4d54e70d 100644 --- a/docs/source/user_guide/index.rst +++ b/docs/source/user_guide/index.rst @@ -1,10 +1,68 @@ User Guide ========== -How to get started. +Installation +############ -.. toctree:: - :hidden: - :maxdepth: 4 +To install the code you will need to first clone the repository to your local machine. +Change into the new directory and then run the install command as given below. - local_machine_install +.. code-block:: bash + :caption: Installation Instructions + + git clone https://github.com/LASY-org/lasy.git + cd lasy + python3 -m pip install -v . + +More installation options and further instructions will be added in due course. + + +First Example +############# + +We will try a simple example to get familiar with the code structure and to verify the installation was successful. +Lets generate a Gaussian pulse at focus, propagate it backwards by one Rayeligh Length and then output it to file. + +.. code-block:: python + :caption: First lets load in the required functions from the library. + + from lasy.profiles.gaussian_profile import GaussianProfile + + +.. code-block:: python + :caption: Next, define the physical parameters of the laser pulse and create the laser profile object. + + wavelength = 800e-9 # Laser wavelength in meters + polarization = (1,0) # Linearly polarized in the x direction + energy = 1.5 # Energy of the laser pulse in joules + spot_size = 25e-6 # Waist of the laser pulse in meters + pulse_duration = 30e-15 # Pulse duration of the laser in seconds + t_peak = 0.0 # Location of the peak of the laser pulse in time + + laser_profile = GaussianProfile(wavelength,polarization,energy,spot_size,pulse_duration,t_peak) + +.. code-block:: python + :caption: Now create a full laser object containing the above physical parameters together with the computational settings. + + dimensions = 'rt' # Use cylindrical geometry + lo = (0,-2.5*pulse_duration) # Lower bounds of the simulation box + hi = (5*spot_size,2.5*pulse_duration) # Upper bounds of the simulation box + num_points = (300,500) # Number of points in each dimension + + laser = Laser(dimensions,lo,hi,num_points,laser_profile) + +.. code-block:: python + :caption: Propagate the laser pulse backwards by one Rayeligh length. + + z_R = 3.14159*spot_size**2/wavelength # The Rayleigh length. + laser.propagate(-z_R) + +.. code-block:: python + :caption: Output the result to file. Here we utilise the openPMD standard. + + file_prefix = 'test_output' # The file name will start with this prefix + file_format = 'h5' # Format to be used for the output file + + write_to_openpmd_file(dimensions, file_prefix, file_format, laser.field, wavelength, polarization) + +This file may now be viewed, copied, shared or used as an input to a variety of other simulation tools. diff --git a/docs/source/user_guide/local_machine_install.rst b/docs/source/user_guide/local_machine_install.rst deleted file mode 100644 index 548dc7bf..00000000 --- a/docs/source/user_guide/local_machine_install.rst +++ /dev/null @@ -1,9 +0,0 @@ -Installation on a Local Machine -=============================== - -Clone a copy of the repository to your local machine. -Navigate into the directory and then run. - -.. code-block:: bash - - python setup.py install diff --git a/lasy/profiles/transverse/hermite_gaussian_profile.py b/lasy/profiles/transverse/hermite_gaussian_profile.py index 05d4bc40..e6ee7752 100644 --- a/lasy/profiles/transverse/hermite_gaussian_profile.py +++ b/lasy/profiles/transverse/hermite_gaussian_profile.py @@ -14,9 +14,10 @@ class HermiteGaussianTransverseProfile(TransverseProfile): corresponds to: .. math:: - \\mathcal{T}(x, y) = - \\sqrt{\frac{2}{\\pi}} \\sqrt{\frac{1}{2^{n} n! w_0}}\\, - \\sqrt{\frac{1}{2^{n} n! w_0}}\\, + + \\mathcal{T}(x, y) = \\, + \\sqrt{\\frac{2}{\\pi}} \\sqrt{\\frac{1}{2^{n} n! w_0}}\\, + \\sqrt{\\frac{1}{2^{n} n! w_0}}\\, H_{n_x}\\left ( \\frac{\\sqrt{2} x}{w_0}\\right )\\, H_{n_y}\\left ( \\frac{\\sqrt{2} y}{w_0}\\right )\\, \\exp\\left( -\\frac{x^2+y^2}{w_0^2} \\right) diff --git a/lasy/profiles/transverse/jinc_profile.py b/lasy/profiles/transverse/jinc_profile.py index ffaa35bb..0b9f0d32 100644 --- a/lasy/profiles/transverse/jinc_profile.py +++ b/lasy/profiles/transverse/jinc_profile.py @@ -12,6 +12,7 @@ class JincTransverseProfile(TransverseProfile): .. math:: \\mathcal{T}(x, y) = 2\\frac{J_1(r/w_0)}{r/w_0} \\textrm{, with } r=\\sqrt{x^2+y^2} + where :math:`J_1` is the Bessel function of the first kind of order one Parameters diff --git a/lasy/profiles/transverse/transverse_profile_from_data.py b/lasy/profiles/transverse/transverse_profile_from_data.py index a8960b05..2b95a800 100644 --- a/lasy/profiles/transverse/transverse_profile_from_data.py +++ b/lasy/profiles/transverse/transverse_profile_from_data.py @@ -9,39 +9,39 @@ class TransverseProfileFromData(TransverseProfile): Derived class for transverse laser profile created using data from an experimental measurement or from the output of another code. + + + Uses user supplied data to define the transverse profile + of the laser pulse. + + The data must be supplied as a 2D numpy array of intensity + values (for example an imported camera image from an + experimental measurement). + + In the case of experimental measurements, this data + should already have some undergone some preprocessing + such as background subtraction and noise removal. + + The beam will be imported and automatically centered unless + otherwise specified. + + Parameters + ---------- + intensity_data : 2Darray of floats + The 2D transverse intensity profile of the laser pulse. + + lo, hi : list of scalars (in meters) + Lower and higher end of the physical domain of the data. + One element per direction (in this case 2) + + center_data : bool, optional + If true, the intensity data will be rolled to put the + center of mass at the center of the image. It will + also shift the x and y data axes such that (x,y) = (0,0) + is also located at the center of the image. Default is True """ def __init__(self, intensity_data, lo, hi, center_data=True): - """ - Uses user supplied data to define the transverse profile - of the laser pulse. - - The data must be supplied as a 2D numpy array of intensity - values (for example an imported cameran image from an - experimental measurement). - - In the case of experimental measurements, this data - should already have some undergone some preprocessing - such as background subtraction and noise removal. - - The beam will be imported and automatically centered unless - otherwise specified. - - Parameters: - ----------- - intensity_data: 2Darray of floats - The 2D transverse intensity profile of the laser pulse. - - lo, hi : list of scalars (in meters) - Lower and higher end of the physical domain of the data. - One element per direction (in this case 2) - - center_data : bool, optional - If true, the intensity data will be rolled to put the - center of mass at the center of the image. It will - also shift the x and y data axes such that (x,y) = (0,0) - is also located at the center of the image. Default is True - """ super().__init__() intensity_data = intensity_data.astype("float64")