Vlasiator ebf0dd394 on dev (v5.4.0 + 1054 commits)
Loading...
Searching...
No Matches
backgroundfield.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 "../common.h"
24#include "../definitions.h"
25#include "../parameters.h"
26#include "cmath"
27#include "backgroundfield.h"
28#include "phiprof.hpp"
29
30//FieldFunction should be initialized
32 const FieldFunction& bgFunction,
34 fsgrids::technicalspan technical,
36 bool append
37 ) {
38 /*if we do not add a new background to the existing one we first put everything to zero*/
39 if (append == false) {
40 setBackgroundFieldToZero(fsgrid, technical, bgb);
41 }
42 const size_t numCells = fsgrid.getNumCells();
43 phiprof::Timer bgTimer {"set Background field"};
44 {
45 //these are doubles, as the averaging functions copied from Gumics
46 //use internally doubles. In any case, it should provide more
47 //accurate results also for float simulations
48 const double accuracy = 1e-17;
49 unsigned int faceCoord1[3];
50 unsigned int faceCoord2[3];
51
52 //the coordinates of the edges face with a normal in the third coordinate direction, stored here to enable looping
53 faceCoord1[0] = 1;
54 faceCoord2[0] = 2;
55 faceCoord1[1] = 0;
56 faceCoord2[1] = 2;
57 faceCoord1[2] = 0;
58 faceCoord2[2] = 1;
59
60 int loopTopId {phiprof::initializeTimer("loop-top")};
61 int loopFaceId {phiprof::initializeTimer("loop-face-averages")};
62 int loopVolumeId {phiprof::initializeTimer("loop-volume-averages")};
63
64 // These are threaded now that the dipole field is threadsafe
65 fsgrid.parallel_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
66 phiprof::initializeTimer("setBackgroundField-loop"), technical,
67 [& /*=,&fsgrid,&bgFunction*/](const fsgrid::Coordinates &coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
68 const std::array<Real, 3> start = coordinates.getPhysicalCoords(stencil.i, stencil.j, stencil.k);
69 const std::array<Real, 3> gridSpacing = coordinates.physicalGridSpacing;
70 const std::array end = {
71 start[0] + gridSpacing[0],
72 start[1] + gridSpacing[1],
73 start[2] + gridSpacing[2],
74 };
75
76 auto& field = bgb[stencil.ooo()];
77 // Face averages
78 for (uint fComponent = 0; fComponent < 3; fComponent++) {
79 T3DFunction valueFunction =
80 std::bind(bgFunction, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
81 (coordinate)fComponent, 0, (coordinate)0);
82 field[fsgrids::bgbfield::BGBX + fComponent] +=
83 surfaceAverage(valueFunction, (coordinate)fComponent, accuracy, start,
84 gridSpacing[faceCoord1[fComponent]], gridSpacing[faceCoord2[fComponent]]);
85
86 // Compute derivatives. Note that we scale by gridSpacing[] as the arrays are assumed to contain differences, not true derivatives!
87 T3DFunction derivFunction1 =
88 std::bind(bgFunction, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
89 (coordinate)fComponent, 1, (coordinate)faceCoord1[fComponent]);
90 field[fsgrids::bgbfield::dBGBxdy + 2 * fComponent] +=
91 gridSpacing[faceCoord1[fComponent]] *
92 surfaceAverage(derivFunction1, (coordinate)fComponent, accuracy, start,
93 gridSpacing[faceCoord1[fComponent]], gridSpacing[faceCoord2[fComponent]]);
94
95 T3DFunction derivFunction2 =
96 std::bind(bgFunction, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
97 (coordinate)fComponent, 1, (coordinate)faceCoord2[fComponent]);
98 field[fsgrids::bgbfield::dBGBxdy + 1 + 2 * fComponent] +=
99 gridSpacing[faceCoord2[fComponent]] *
100 surfaceAverage(derivFunction2, (coordinate)fComponent, accuracy, start,
101 gridSpacing[faceCoord1[fComponent]], gridSpacing[faceCoord2[fComponent]]);
102 }
103
104 // Volume averages
105 for (uint fComponent = 0; fComponent < 3; fComponent++) {
106 T3DFunction valueFunction =
107 std::bind(bgFunction, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
108 (coordinate)fComponent, 0, (coordinate)0);
109 field[fsgrids::bgbfield::BGBXVOL + fComponent] += volumeAverage(valueFunction, accuracy, start, end);
110
111 // Compute derivatives. Note that we scale by gridSpacing[] as the arrays are assumed to contain differences, not true derivatives!
112 for (uint dComponent = 0; dComponent < 3; dComponent++) {
113 T3DFunction derivFunction =
114 std::bind(bgFunction, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
115 (coordinate)fComponent, 1, (coordinate)dComponent);
116 field[fsgrids::bgbfield::dBGBXVOLdx + 3 * fComponent + dComponent] +=
117 gridSpacing[dComponent] * volumeAverage(derivFunction, accuracy, start, end);
118 }
119 }
120 });
121 }
122 bgTimer.stop(numCells, "Spatial Cells");
123 // TODO
124 // Compute divergence and curl of volume averaged field and check that both are zero.
125}
126
129 fsgrids::technicalspan technical,
131) {
132 fsgrid.parallel_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
133 phiprof::initializeTimer("setBackgroundFieldToZero"), technical,
134 [=](const fsgrid::Coordinates &coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
135 for (size_t i = 0; i < bgb[stencil.ooo()].size(); i++) {
136 bgb[stencil.ooo()][i] = 0.0;
137 }
138 });
139}
for i
Definition Dispersion.m:24
void setBackgroundFieldToZero(FieldSolverGrid &fsgrid, fsgrids::technicalspan technical, fsgrids::bgbspan bgb)
void setBackgroundField(const FieldFunction &bgFunction, fsgrids::bgbspan bgb, fsgrids::technicalspan technical, FieldSolverGrid &fsgrid, bool append)
const uint32_t cuint
Definition definitions.h:50
fsgrid::FsGrid< FS_STENCIL_WIDTH > FieldSolverGrid
Definition definitions.h:78
std::function< double(double x, double y, double z, coordinate component, unsigned int derivative, coordinate dcomponent)> FieldFunction
std::function< double(double, double, double)> T3DFunction
Definition functions.hpp:32
coordinate
Definition functions.hpp:28
double volumeAverage(const T3DFunction &f1, double accuracy, const std::array< double, 3 > &r1, const std::array< double, 3 > &r2)
double surfaceAverage(const T3DFunction &f1, coordinate face, double accuracy, const std::array< double, 3 > &r1, double L1, double L2)
@ BGBXVOL
Definition common.h:378
@ dBGBXVOLdx
Definition common.h:390
@ BGBX
Definition common.h:375
@ dBGBxdy
Definition common.h:384
std::span< technical > technicalspan
Definition common.h:452
std::span< std::array< Real, bgbfield::N_BGB > > bgbspan
Definition common.h:444