https://mooseframework.inl.gov
FourierNoise.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #include "FourierNoise.h"
11 #include "MooseRandom.h"
12 #include "FEProblemBase.h"
13 #include "libmesh/utility.h"
14 
15 registerMooseObject("PhaseFieldApp", FourierNoise);
16 
19 {
21  params.addClassDescription("Generate noise from a fourier series");
22  params.addRequiredParam<Real>("lambda",
23  "Wavelength cut off (set to about twice the interfacial width)");
24  params.addParam<unsigned int>(
25  "num_terms",
26  "Number of random fourier series terms (this will result in non-periodic noise). Omit this "
27  "parameter to obtain a periodic noise distribution.");
28  params.addParam<unsigned int>("seed", 12455, "Random number generator seed");
29  return params;
30 }
31 
33  : Function(parameters),
34  _lambda(getParam<Real>("lambda")),
35  _fe_problem(*getCheckedPointerParam<FEProblemBase *>("_fe_problem_base"))
36 {
37  MooseRandom rng;
38  rng.seed(0, getParam<unsigned int>("seed"));
39 
40  if (isParamValid("num_terms"))
41  {
42  // random terms
43  _series.resize(getParam<unsigned int>("num_terms"));
44  const Real scale = 2.0 * (2.0 * libMesh::pi) / _lambda;
45 
46  // check
47  if (_series.empty())
48  paramError("num_terms",
49  "If specifying the number of terms, supply a number greater than zero.");
50 
51  // fill terms
52  for (auto & f : _series)
53  {
54  // get a vector with length <= 0.5
55  Real r2;
56  do
57  {
58  const Real x = rng.rand(0) - 0.5;
59  const Real y = rng.rand(0) - 0.5;
60  f.k = RealVectorValue(x, y, 0.0);
61  r2 = f.k.norm_sq();
62  } while (r2 > 0.25);
63 
64  // scale maximum to a wavelength of lambda
65  f.k *= scale;
66 
67  f.c = rng.randNormal(0, 0.0, 1.0);
68  f.s = rng.randNormal(0, 0.0, 1.0);
69  }
70  }
71  else
72  {
73  // k-space grid resulting in periodic noise
75  if (!mesh.isRegularOrthogonal())
76  mooseError("Periodic Fourier Noise requires a regular orthogonal mesh.");
77 
78  const Real dx = 2.0 * libMesh::pi / mesh.dimensionWidth(0);
79  const Real dy = 2.0 * libMesh::pi / mesh.dimensionWidth(1);
80  const Real rmax = 2.0 * libMesh::pi / _lambda;
81 
82  const int xmax = rmax / dx;
83  const int ymax = rmax / dy;
84 
85  const Real rmax2 = rmax * rmax;
86  for (int x = 0; x < xmax; ++x)
87  for (int y = -ymax; y < ymax; ++y)
88  if (x > 0 || y > 0)
89  {
90  SeriesItem f;
91  f.k = RealVectorValue(x * dx, y * dy, 0.0);
92  if (f.k.norm_sq() <= rmax2)
93  {
94  f.c = rng.randNormal(0, 0.0, 1.0);
95  f.s = rng.randNormal(0, 0.0, 1.0);
96  _series.push_back(f);
97  }
98  }
99  }
100 
101  _scale = std::sqrt(1.0 / _series.size());
102 }
103 
104 Real
105 FourierNoise::value(Real, const Point & p) const
106 {
107  Real v = 0.0;
108  for (const auto & f : _series)
109  v += f.s * std::sin(p * f.k) + f.c * std::cos(p * f.k);
110  return v * _scale;
111 }
112 
113 ADReal
114 FourierNoise::value(const ADReal &, const ADPoint & p) const
115 {
116  ADReal v = 0.0;
117  for (const auto & f : _series)
118  v += f.s * std::sin(p * f.k) + f.c * std::cos(p * f.k);
119  return v * _scale;
120 }
registerMooseObject("PhaseFieldApp", FourierNoise)
FEProblemBase & _fe_problem
FEProblem pointer for obtaining the current mesh.
Definition: FourierNoise.h:51
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void scale(MeshBase &mesh, const Real xs, const Real ys=0., const Real zs=0.)
void seed(std::size_t i, unsigned int seed)
MeshBase & mesh
const std::vector< double > y
DualNumber< Real, DNDerivativeType, true > ADReal
void addRequiredParam(const std::string &name, const std::string &doc_string)
Real randNormal(std::size_t i, Real mean, Real sigma)
bool isParamValid(const std::string &name) const
virtual Real value(Real, const Point &p) const override
Definition: FourierNoise.C:105
const Real _lambda
selected lower lengthscale for the noise cut-off
Definition: FourierNoise.h:42
const std::vector< double > x
Real f(Real x)
Test function for Brents method.
static InputParameters validParams()
Definition: FourierNoise.C:18
std::vector< SeriesItem > _series
Fourier series terms.
Definition: FourierNoise.h:45
void paramError(const std::string &param, Args... args) const
FourierNoise(const InputParameters &parameters)
Definition: FourierNoise.C:32
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
static const std::string v
Definition: NS.h:84
Real _scale
amplitude factor
Definition: FourierNoise.h:48
virtual MooseMesh & mesh() override
void mooseError(Args &&... args) const
void addClassDescription(const std::string &doc_string)
Generate noise using random fourier series coefficients.
Definition: FourierNoise.h:19
Real rand(std::size_t i)
static InputParameters validParams()
const Real pi