Vlasiator ebf0dd394 on dev (v5.4.0 + 1054 commits)
Loading...
Searching...
No Matches
cpu_acc_transform.cpp
Go to the documentation of this file.
1/*
2 * This file is part of Vlasiator.
3 * Copyright 2010-2016 Finnish Meteorological Institute
4 *
5 * For details of usage, see the COPYING file and read the "Rules of the Road"
6 * at http://www.physics.helsinki.fi/vlasiator/
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22
23#include "../object_wrapper.h"
25
26#include "cpu_acc_transform.hpp"
27
28using namespace std;
29using namespace spatial_cell;
30using namespace Eigen;
31
32
33
43 const uint popID)
44{
45 const Real Bx = spatial_cell->parameters[CellParams::BGBXVOL]+spatial_cell->parameters[CellParams::PERBXVOL];
46 const Real By = spatial_cell->parameters[CellParams::BGBYVOL]+spatial_cell->parameters[CellParams::PERBYVOL];
47 const Real Bz = spatial_cell->parameters[CellParams::BGBZVOL]+spatial_cell->parameters[CellParams::PERBZVOL];
48 const Eigen::Matrix<Real,3,1> B(Bx,By,Bz);
49 const Real B_mag = B.norm() + 1e-30;
50 const Real gyro_period = 2 * M_PI * getObjectWrapper().particleSpecies[popID].mass
51 / (getObjectWrapper().particleSpecies[popID].charge * B_mag);
52
53 // Set maximum timestep limit for this cell, based on a maximum allowed rotation angle
54 spatial_cell->set_max_v_dt(popID,fabs(gyro_period)*(P::maxSlAccelerationRotation/360.0));
55}
56
57
65
66Eigen::Transform<Real,3,Eigen::Affine> compute_acceleration_transformation(
68 const uint popID,
69 const Real& dt) {
70 // total field
71 const Real Bx = spatial_cell->parameters[CellParams::BGBXVOL]+spatial_cell->parameters[CellParams::PERBXVOL];
72 const Real By = spatial_cell->parameters[CellParams::BGBYVOL]+spatial_cell->parameters[CellParams::PERBYVOL];
73 const Real Bz = spatial_cell->parameters[CellParams::BGBZVOL]+spatial_cell->parameters[CellParams::PERBZVOL];
74
75 // read in derivatives need for curl of B (only perturbed, curl of background field is always 0!)
76 const Real dBXdy = spatial_cell->derivativesBVOL[bvolderivatives::dPERBXVOLdy];
77 const Real dBXdz = spatial_cell->derivativesBVOL[bvolderivatives::dPERBXVOLdz];
78 const Real dBYdx = spatial_cell->derivativesBVOL[bvolderivatives::dPERBYVOLdx];
79
80 const Real dBYdz = spatial_cell->derivativesBVOL[bvolderivatives::dPERBYVOLdz];
81 const Real dBZdx = spatial_cell->derivativesBVOL[bvolderivatives::dPERBZVOLdx];
82 const Real dBZdy = spatial_cell->derivativesBVOL[bvolderivatives::dPERBZVOLdy];
83
84 const Eigen::Matrix<Real,3,1> B(Bx,By,Bz);
85 Eigen::Matrix<Real,3,1> unit_B(B.normalized());
86
87 // If B equals zero then gyro_period and unit_B are NAN.
88 // Guard against that by adding epsilons:
89 const Real B_mag = B.norm() + 1e-30;
90 if (B_mag < 1e-28) {
91 unit_B(0,0) = 0; unit_B(1,0) = 0; unit_B(2,0) = 1;
92 }
93
94 const Real gyro_period
95 = 2 * M_PI * getObjectWrapper().particleSpecies[popID].mass
96 / (getObjectWrapper().particleSpecies[popID].charge * B_mag);
97
98 // scale rho for hall term, if user requests
99 const Real EPSILON = 1e10 * numeric_limits<Real>::min();
100 const Real rhoq = spatial_cell->parameters[CellParams::RHOQ_V] + EPSILON;
101 const Real hallRhoq = (rhoq <= Parameters::hallMinimumRhoq ) ? Parameters::hallMinimumRhoq : rhoq ;
102 const Real hallPrefactor = 1.0 / (physicalconstants::MU_0 * hallRhoq );
103
104 Eigen::Matrix<Real,3,1> bulk_velocity(spatial_cell->parameters[CellParams::VX_V],
105 spatial_cell->parameters[CellParams::VY_V],
106 spatial_cell->parameters[CellParams::VZ_V]);
107
108 // compute total transformation
109 Transform<Real,3,Affine> total_transform(Matrix<Real, 4, 4>::Identity()); //CONTINUE
110
111 unsigned int bulk_velocity_substeps; // in this many substeps we iterate forward bulk velocity when the complete transformation is computed (0.1 deg per substep).
112 bulk_velocity_substeps = std::abs(dt) / std::abs(gyro_period*(0.1/360.0));
113 if (bulk_velocity_substeps < 1) bulk_velocity_substeps=1;
114
115 const Real substeps_radians = -(2.0*M_PI*dt/gyro_period)/bulk_velocity_substeps; // how many radians each substep is.
116 const Real substeps_dt=dt/bulk_velocity_substeps;
117 Eigen::Matrix<Real,3,1> EgradPe(
121
122 for (uint i=0; i<bulk_velocity_substeps; ++i) {
123 // rotation origin is the point through which we place our rotation axis (direction of which is unitB).
124 // first add bulk velocity (using the total transform computed this far.
125 Eigen::Matrix<Real,3,1> rotation_pivot(total_transform*bulk_velocity);
126
127 //include lorentzHallTerm (we should include, always)
128 rotation_pivot[0]-= hallPrefactor*(dBZdy - dBYdz);
129 rotation_pivot[1]-= hallPrefactor*(dBXdz - dBZdx);
130 rotation_pivot[2]-= hallPrefactor*(dBYdx - dBXdy);
131
132 // add to transform matrix the small rotation around pivot
133 // when added like this, and not using *= operator, the transformations
134 // are in the correct order
135 total_transform = Translation<Real,3>(-rotation_pivot)*total_transform;
136 total_transform = AngleAxis<Real>(substeps_radians,unit_B)*total_transform;
137 total_transform = Translation<Real,3>(rotation_pivot)*total_transform;
138
139 // Electron pressure gradient term
141 total_transform=Translation<Real,3>( (std::abs(getObjectWrapper().particleSpecies[popID].charge)/getObjectWrapper().particleSpecies[popID].mass) * EgradPe * substeps_dt) * total_transform;
142 }
143 }
144
145 return total_transform;
146}
for i
Definition Dispersion.m:24
dt
Definition Dispersion.m:39
void updateAccelerationMaxdt(SpatialCell *spatial_cell, const uint popID)
Eigen::Transform< Real, 3, Eigen::Affine > compute_acceleration_transformation(const SpatialCell *spatial_cell, const uint popID, const Real &dt)
float Real
Definition definitions.h:41
ObjectWrapper & getObjectWrapper()
Definition main.cpp:33
const Real MU_0
Definition common.h:570
std::vector< species::Species > particleSpecies
static uint ohmGradPeTerm
Definition parameters.h:144
static Real maxSlAccelerationRotation
Definition parameters.h:156
static Real hallMinimumRhoq
Definition parameters.h:161