1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
/* Copyright 2019 Andrew Myers, Axel Huebl, David Grote
* Luca Fedeli, Maxence Thevenet, Remi Lehe
* Weiqun Zhang
*
* This file is part of WarpX.
*
* License: BSD-3-Clause-LBNL
*/
#ifndef WARPX_LaserParticleContainer_H_
#define WARPX_LaserParticleContainer_H_
#include "Evolve/WarpXDtType.H"
#include "Laser/LaserProfiles.H"
#include "WarpXParticleContainer.H"
#include <AMReX_Extension.H>
#include <AMReX_Random.H>
#include <AMReX_REAL.H>
#include <AMReX_RealBox.H>
#include <AMReX_Vector.H>
#include <AMReX_BaseFwd.H>
#include <AMReX_AmrCoreFwd.H>
#include <limits>
#include <memory>
#include <string>
/**
* The main method to inject a laser pulse in WarpX is to use an artificial
* antenna: particles evenly distributed in a given plane (one particle per
* cell) move at each iteration and deposit a current J onto the grid, which
* in turns creates an electromagnetic field on the grid. The particles'
* displacements are prescribed to create the field requested by the user.
*
* These artificial particles are contained in the LaserParticleContainer.
* LaserParticleContainer derives directly from WarpXParticleContainer. It
* requires a DepositCurrent function, but no FieldGather function.
*/
class LaserParticleContainer
: public WarpXParticleContainer
{
public:
LaserParticleContainer (amrex::AmrCore* amr_core, int ispecies, const std::string& name);
virtual ~LaserParticleContainer () {}
virtual void InitData () final;
/**
* \brief Method to initialize runtime attributes. Does nothing for LaserParticleContainer.
*/
virtual void DefaultInitializeRuntimeAttributes (
amrex::ParticleTile<NStructReal, NStructInt, NArrayReal,
NArrayInt,amrex::PinnedArenaAllocator>& /*pinned_tile*/,
const int /*n_external_attr_real*/,
const int /*n_external_attr_int*/,
const amrex::RandomEngine& /*engine*/) override final {}
virtual void ReadHeader (std::istream& is) final;
virtual void WriteHeader (std::ostream& os) const final;
virtual void Evolve (int lev,
const amrex::MultiFab&, const amrex::MultiFab&, const amrex::MultiFab&,
const amrex::MultiFab&, const amrex::MultiFab&, const amrex::MultiFab&,
amrex::MultiFab& jx, amrex::MultiFab& jy, amrex::MultiFab& jz,
amrex::MultiFab*, amrex::MultiFab*, amrex::MultiFab*,
amrex::MultiFab* rho, amrex::MultiFab* crho,
const amrex::MultiFab*, const amrex::MultiFab*, const amrex::MultiFab*,
const amrex::MultiFab*, const amrex::MultiFab*, const amrex::MultiFab*,
amrex::Real t, amrex::Real dt, DtType a_dt_type=DtType::Full,
bool skip_deposition=false) final;
virtual void PushP (int lev, amrex::Real dt,
const amrex::MultiFab& ,
const amrex::MultiFab& ,
const amrex::MultiFab& ,
const amrex::MultiFab& ,
const amrex::MultiFab& ,
const amrex::MultiFab& ) final;
virtual void PostRestart () final;
void calculate_laser_plane_coordinates (const WarpXParIter& pti, const int np,
amrex::Real * AMREX_RESTRICT const pplane_Xp,
amrex::Real * AMREX_RESTRICT const pplane_Yp);
void update_laser_particle (WarpXParIter& pti, const int np, amrex::ParticleReal * AMREX_RESTRICT const puxp,
amrex::ParticleReal * AMREX_RESTRICT const puyp,
amrex::ParticleReal * AMREX_RESTRICT const puzp,
amrex::ParticleReal const * AMREX_RESTRICT const pwp,
amrex::Real const * AMREX_RESTRICT const amplitude,
const amrex::Real dt);
protected:
std::string m_laser_name;
private:
// runtime paramters
amrex::Vector<amrex::Real> m_position; //! Coordinates of one of the point of the antenna
amrex::Vector<amrex::Real> m_nvec; //! Normal of the plane of the antenna
amrex::Vector<amrex::Real> m_p_X;// ! Polarization
amrex::Real m_e_max = std::numeric_limits<amrex::Real>::quiet_NaN();
amrex::Real m_wavelength = std::numeric_limits<amrex::Real>::quiet_NaN();
amrex::Real m_Z0_lab = 0; // Position of the antenna in the lab frame
long m_min_particles_per_mode = 4;
// computed using runtime parameters
amrex::Vector<amrex::Real> m_p_Y;
amrex::Vector<amrex::Real> m_u_X;
amrex::Vector<amrex::Real> m_u_Y;
amrex::Real m_weight = std::numeric_limits<amrex::Real>::quiet_NaN();
amrex::Real m_mobility = std::numeric_limits<amrex::Real>::quiet_NaN();
// laser particle domain
amrex::RealBox m_laser_injection_box;
// Theoretical position of the antenna. Used if do_continuous_injection=1.
// Track the position of the antenna until it enters the simulation domain.
amrex::Vector<amrex::Real> m_updated_position;
void ComputeSpacing (int lev, amrex::Real& Sx, amrex::Real& Sy) const;
void ComputeWeightMobility (amrex::Real Sx, amrex::Real Sy);
void InitData (int lev);
// Inject the laser antenna during the simulation, if it started
// outside of the simulation domain and enters it.
void ContinuousInjection(const amrex::RealBox& injection_box) override;
// Update position of the antenna
void UpdateContinuousInjectionPosition(amrex::Real dt) override;
// Unique (smart) pointer to the laser profile
std::unique_ptr<WarpXLaserProfiles::ILaserProfile> m_up_laser_profile;
// Flag to disable the laser (e.g., if e_max is 0)
bool m_enabled = true;
};
#endif
|