LaserBeam.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <cstddef>
7 #include <pup.h>
8 #include <string>
9 
10 #include "DataStructures/Tensor/EagerMath/Magnitude.hpp"
12 #include "Domain/FaceNormal.hpp"
13 #include "Domain/Tags.hpp"
14 #include "Elliptic/BoundaryConditions/BoundaryCondition.hpp"
15 #include "Elliptic/BoundaryConditions/BoundaryConditionType.hpp"
16 #include "Options/Options.hpp"
18 #include "Utilities/Gsl.hpp"
19 #include "Utilities/TMPL.hpp"
20 
21 /// \cond
22 class DataVector;
23 /// \endcond
24 
25 namespace Elasticity::BoundaryConditions {
26 namespace detail {
27 
28 struct LaserBeamImpl {
29  struct BeamWidth {
30  using type = double;
31  static constexpr Options::String help =
32  "The width r_0 of the Gaussian beam profile, such that FWHM = 2 * "
33  "sqrt(ln 2) * r_0";
34  static type lower_bound() noexcept { return 0.0; }
35  };
36 
37  static constexpr Options::String help =
38  "A laser beam with Gaussian profile normally incident to the surface.";
39  using options = tmpl::list<BeamWidth>;
40 
41  LaserBeamImpl() = default;
42  LaserBeamImpl(const LaserBeamImpl&) noexcept = default;
43  LaserBeamImpl& operator=(const LaserBeamImpl&) noexcept = default;
44  LaserBeamImpl(LaserBeamImpl&&) noexcept = default;
45  LaserBeamImpl& operator=(LaserBeamImpl&&) noexcept = default;
46  ~LaserBeamImpl() noexcept = default;
47 
48  LaserBeamImpl(double beam_width) noexcept : beam_width_(beam_width) {}
49 
50  double beam_width() const noexcept { return beam_width_; }
51 
52  using argument_tags =
53  tmpl::list<domain::Tags::Coordinates<3, Frame::Inertial>,
56  using volume_tags = tmpl::list<>;
57 
58  void apply(gsl::not_null<tnsr::I<DataVector, 3>*> displacement,
59  gsl::not_null<tnsr::I<DataVector, 3>*> n_dot_minus_stress,
60  const tnsr::I<DataVector, 3>& x,
61  const tnsr::i<DataVector, 3>& face_normal) const noexcept;
62 
63  using argument_tags_linearized = tmpl::list<>;
64  using volume_tags_linearized = tmpl::list<>;
65 
66  static void apply_linearized(
67  gsl::not_null<tnsr::I<DataVector, 3>*> displacement,
68  gsl::not_null<tnsr::I<DataVector, 3>*> n_dot_minus_stress) noexcept;
69 
70  // NOLINTNEXTLINE
71  void pup(PUP::er& p) noexcept { p | beam_width_; }
72 
73  private:
74  double beam_width_{std::numeric_limits<double>::signaling_NaN()};
75 };
76 
77 bool operator==(const LaserBeamImpl& lhs, const LaserBeamImpl& rhs) noexcept;
78 
79 bool operator!=(const LaserBeamImpl& lhs, const LaserBeamImpl& rhs) noexcept;
80 
81 } // namespace detail
82 
83 // The following implements the registration and factory-creation mechanism
84 
85 /// \cond
86 template <typename Registrars>
87 struct LaserBeam;
88 
89 namespace Registrars {
90 struct LaserBeam {
91  template <typename Registrars>
93 };
94 } // namespace Registrars
95 /// \endcond
96 
97 /*!
98  * \brief A laser beam with Gaussian profile normally incident to the surface
99  *
100  * This boundary condition represents a laser beam with Gaussian profile that
101  * exerts pressure normal to the surface of a reflecting material. The pressure
102  * we are considering here is
103  *
104  * \f{align}
105  * n_i T^{ij} = -n^j \frac{e^{-\frac{r^2}{r_0^2}}}{\pi r_0^2}
106  * \f}
107  *
108  * where \f$n_i\f$ is the unit normal pointing _out_ of the surface, \f$r\f$ is
109  * the coordinate distance from the origin in the plane perpendicular to
110  * \f$n_i\f$ and \f$r_0\f$ is the "beam width" parameter. The pressure profile
111  * and the angle of incidence can be generalized in future work. Note that we
112  * follow the convention of \cite Lovelace2007tn and \cite Lovelace2017xyf in
113  * defining the beam width, and other publications may include a a factor of
114  * \f$\sqrt{2}\f$ in its definition.
115  *
116  * This boundary condition is used to simulate thermal noise induced in a mirror
117  * by the laser, as detailed for instance in \cite Lovelace2007tn and
118  * \cite Lovelace2017xyf. See also `Elasticity::Solutions::HalfSpaceMirror` for
119  * an analytic solution that involves this boundary condition.
120  */
121 template <typename Registrars = tmpl::list<Registrars::LaserBeam>>
123  : public elliptic::BoundaryConditions::BoundaryCondition<3, Registrars>,
124  public detail::LaserBeamImpl {
125  private:
127 
128  public:
129  LaserBeam() = default;
130  LaserBeam(const LaserBeam&) noexcept = default;
131  LaserBeam& operator=(const LaserBeam&) noexcept = default;
132  LaserBeam(LaserBeam&&) noexcept = default;
133  LaserBeam& operator=(LaserBeam&&) noexcept = default;
134  ~LaserBeam() noexcept = default;
135 
136  using LaserBeamImpl::LaserBeamImpl;
137 
138  /// \cond
139  explicit LaserBeam(CkMigrateMessage* m) noexcept : Base(m) {}
140  using PUP::able::register_constructor;
142  /// \endcond
143 
145  const noexcept override {
146  return std::make_unique<LaserBeam>(*this);
147  }
148 
149  void pup(PUP::er& p) noexcept override {
150  Base::pup(p);
151  detail::LaserBeamImpl::pup(p);
152  }
153 };
154 
155 /// \cond
156 template <typename Registrars>
157 PUP::able::PUP_ID LaserBeam<Registrars>::my_PUP_ID = 0; // NOLINT
158 /// \endcond
159 
160 } // namespace Elasticity::BoundaryConditions
domain::Tags::UnnormalizedFaceNormal
Definition: FaceNormal.hpp:112
CharmPupable.hpp
Options.hpp
FaceNormal.hpp
Tags.hpp
WRAPPED_PUPable_decl_template
#define WRAPPED_PUPable_decl_template(className)
Mark derived classes as serializable.
Definition: CharmPupable.hpp:22
Tags::Normalized
Definition: Magnitude.hpp:137
cstddef
elliptic::BoundaryConditions::BoundaryCondition
Base class for boundary conditions for elliptic systems.
Definition: BoundaryCondition.hpp:91
DataVector
Stores a collection of function values.
Definition: DataVector.hpp:46
std::numeric_limits::signaling_NaN
T signaling_NaN(T... args)
Gsl.hpp
Elasticity::BoundaryConditions::LaserBeam
A laser beam with Gaussian profile normally incident to the surface.
Definition: LaserBeam.hpp:122
TypeAliases.hpp
Options::String
const char *const String
The string used in option structs.
Definition: Options.hpp:32
std::unique_ptr< domain::BoundaryConditions::BoundaryCondition >
TMPL.hpp
gsl::not_null
Require a pointer to not be a nullptr
Definition: ReadSpecPiecewisePolynomial.hpp:13
string