https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
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 {
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
104Real
105FourierNoise::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
113ADReal
114FourierNoise::value(const ADReal &, const ADPoint & p) const
115{
116 using std::sin, std::cos;
117
118 ADReal v = 0.0;
119 for (const auto & f : _series)
120 v += f.s * sin(p * f.k) + f.c * cos(p * f.k);
121 return v * _scale;
122}
DualNumber< Real, DNDerivativeType, true > ADReal
Real f(Real x)
Test function for Brents method.
const std::vector< double > y
const std::vector< double > x
registerMooseObject("PhaseFieldApp", FourierNoise)
const Real p
const double v
Real scale
virtual MooseMesh & mesh() override
Generate noise using random fourier series coefficients.
Real _scale
amplitude factor
virtual Real value(Real, const Point &p) const override
static InputParameters validParams()
const Real _lambda
selected lower lengthscale for the noise cut-off
FourierNoise(const InputParameters &parameters)
std::vector< SeriesItem > _series
Fourier series terms.
FEProblemBase & _fe_problem
FEProblem pointer for obtaining the current mesh.
static InputParameters validParams()
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
void paramError(const std::string &param, Args... args) const
void mooseError(Args &&... args) const
bool isParamValid(const std::string &name) const
void seed(std::size_t i, unsigned int seed)
Real rand(std::size_t i)
Real randNormal(std::size_t i, Real mean, Real sigma)
MeshBase & mesh
const Real pi
RealVectorValue k
k-vector