Vlasiator ebf0dd394 on dev (v5.4.0 + 1054 commits)
Loading...
Searching...
No Matches
distribution.h
Go to the documentation of this file.
1#pragma once
2/*
3 * This file is part of Vlasiator.
4 * Copyright 2010-2016 Finnish Meteorological Institute
5 *
6 * For details of usage, see the COPYING file and read the "Rules of the Road"
7 * at http://www.physics.helsinki.fi/vlasiator/
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 */
23
24#include <random>
25#include "particles.h"
26#include "particleparameters.h"
27#include "physconst.h"
28
29/* virtual base of particle distributions */
31{
32 public:
33 Distribution(std::default_random_engine& _rand, Real _mass, Real _charge)
34 : mass(_mass), charge(_charge),rand(_rand) {};
35 Distribution(std::default_random_engine& _rand);
36 virtual Particle next_particle() = 0;
37 protected:
39 std::default_random_engine& rand;
40};
41
42
43/* Thermal maxwell-boltzmann distribution */
45{
46 public:
47 /* Constructor where all parameters are explicitly given */
48 Maxwell_Boltzmann(std::default_random_engine& _rand,Real _mass, Real _charge, Real kT) :
49 Distribution(_rand,_mass,_charge),
51
52 /* Constructor that fishes parameters from the parameter-class by itself */
53 Maxwell_Boltzmann(std::default_random_engine& _rand);
54 virtual Particle next_particle();
55 private:
56 std::normal_distribution<Real> velocity_distribution;
57};
58
59/* Monoenergetic isotropic particles */
61{
62 public:
63 Monoenergetic(std::default_random_engine& _rand,Real _mass, Real _charge, Real _vel) :
64 Distribution(_rand, _mass, _charge),
65 vel(_vel) {
66 }
67 Monoenergetic(std::default_random_engine& _rand);
68
70 /* Sphere point-picking to get isotropic direction (from wolfram Mathworld) */
71 Real u,v;
72 u = 2.*direction_random(rand)-1.;
73 v = direction_random(rand) * 2. * M_PI;
74
75 Vec3d dir(sqrt(1-u*u) * cos(v),
76 sqrt(1-u*u) * sin(v),
77 u);
78 return Particle(mass, charge, Vec3d(0.,0.,0.), vel*dir);
79 }
80 private:
81
82 std::uniform_real_distribution<Real> direction_random;
84
85};
86
87/* Kappa distributions as taken from the CSA code */
88class Kappa : public Distribution
89{
90 public:
91 Kappa(std::default_random_engine& _rand, Real _mass, Real _charge, Real _w0, Real _maxw0)
92 : Distribution(_rand,_mass,_charge),w0(_w0),maxw0(_maxw0) {}
93
94 Kappa(std::default_random_engine& _rand) : Distribution(_rand) {
95 maxw0=50;
96 }
97
99
100 Real vel = w0 * find_v_for_r(r(rand));
101
102 /* Sphere point-picking to get isotropic direction (from wolfram Mathworld) */
103 Real u,v;
104 u = 2.*r(rand)-1.;
105 v = r(rand) * 2. * M_PI;
106
107 Vec3d dir(sqrt(1-u*u) * cos(v),
108 sqrt(1-u*u) * sin(v),
109 u);
110 return Particle(mass, charge, Vec3d(0.,0.,0.), vel*dir);
111 }
112
113 protected:
114 std::uniform_real_distribution<Real> r;
115 std::vector<Real> lookup;
116 const static int lookup_size = 65536;
119
120 virtual void generate_lookup() = 0;
121
123
124};
125
126/* Kappa = 6 version */
127class Kappa6 : public Kappa
128{
129
130 public:
131 Kappa6(std::default_random_engine& _rand, double _mass, double _charge, double _w0, double _maxw0)
132 : Kappa(_rand,_mass,_charge,_w0,_maxw0){
134 }
135 Kappa6(std::default_random_engine& _rand);
136
137 private:
138 virtual void generate_lookup() {
139 double prefix = (512. * sqrt(2./3.))/(63.*M_PI);
140
141 for(int i=0; i<lookup_size; i++) {
142 double vkappa = (maxw0/lookup_size)*i;
143 double under = vkappa*vkappa + 6.;
144
145 lookup.push_back( prefix*(-23328.*vkappa/(pow(under,6.))
146 + 1944. * vkappa/(5. *pow(under,5.))
147 + 729. * vkappa/(10.*pow(under,4.))
148 + 567. * vkappa/(40.*pow(under,3.))
149 + 189. * vkappa/(64.*under*under)
150 + 189. * vkappa/(256.*under)
151 + (63. * sqrt(3./2.)) * atan2(vkappa,sqrt(6.))/256.));
152 }
153
154 }
155};
156
157/* Kappa = 2 version */
158class Kappa2 : public Kappa
159{
160 public:
161 Kappa2(std::default_random_engine& _rand, double _mass, double _charge, double _w0, double _maxw0)
162 : Kappa(_rand,_mass,_charge,_w0,_maxw0){
164 }
165 Kappa2(std::default_random_engine& _rand);
166
167 private:
168 virtual void generate_lookup() {
169 double prefix = 4./M_PI * sqrt(2.);
170
171 for(int i=0; i<lookup_size; i++) {
172 double vkappa = (maxw0/lookup_size)*i;
173 double under = vkappa*vkappa + 2.;
174
175 lookup.push_back( prefix*(
176 - 2. * vkappa/(under*under)
177 + vkappa/(2.*under)
178 + atan2(vkappa,sqrt(2.))/(2.*sqrt(2.))
179 )
180 );
181 }
182
183 }
184};
185
186template<typename T> Distribution* createDistribution(std::default_random_engine& rand) {
187 return new T(rand);
188}
for i
Definition Dispersion.m:24
sqrt(1.0+vA *vA/(c *c))) % Ion-acoustic wave cS
std::default_random_engine & rand
virtual Particle next_particle()=0
Distribution(std::default_random_engine &_rand, Real _mass, Real _charge)
virtual void generate_lookup()
Kappa2(std::default_random_engine &_rand, double _mass, double _charge, double _w0, double _maxw0)
virtual void generate_lookup()
Kappa6(std::default_random_engine &_rand, double _mass, double _charge, double _w0, double _maxw0)
virtual void generate_lookup()=0
Real w0
std::vector< Real > lookup
Real find_v_for_r(Real rand)
std::uniform_real_distribution< Real > r
virtual Particle next_particle()
static const int lookup_size
Kappa(std::default_random_engine &_rand, Real _mass, Real _charge, Real _w0, Real _maxw0)
Kappa(std::default_random_engine &_rand)
Real maxw0
Maxwell_Boltzmann(std::default_random_engine &_rand, Real _mass, Real _charge, Real kT)
std::normal_distribution< Real > velocity_distribution
virtual Particle next_particle()
virtual Particle next_particle()
Monoenergetic(std::default_random_engine &_rand, Real _mass, Real _charge, Real _vel)
std::uniform_real_distribution< Real > direction_random
float Real
Definition definitions.h:41
Distribution * createDistribution(std::default_random_engine &rand)
#define Vec3d