Vlasiator ebf0dd394 on dev (v5.4.0 + 1054 commits)
Loading...
Searching...
No Matches
backgroundfield.h
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#ifndef BACKGROUNDFIELD_H
24#define BACKGROUNDFIELD_H
25
26#include "fieldfunction.hpp"
27#include "integratefunction.hpp"
28#include "../definitions.h"
29#include "../common.h"
30#include "fsgrid.hpp"
31#include "phiprof.hpp"
32#include <span>
33
35 const FieldFunction& bgFunction,
37 fsgrids::technicalspan technical,
39 bool append=false
40);
41
44 fsgrids::technicalspan technical,
46);
47
54template<long unsigned int numFields> void setPerturbedFieldToZero(
56 fsgrids::technicalspan technical,
57 std::span<std::array<Real, numFields>> b,
58 int offset=fsgrids::bfield::PERBX
59) {
60 fsgrid.parallel_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
61 phiprof::initializeTimer("setPerturbedFieldToZero"), technical,
62 [=](const fsgrid::Coordinates &coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
63 // This is still N_BFIELD (==3) instead of numFields
64 for (size_t j = 0; j < fsgrids::bfield::N_BFIELD; ++j) {
65 b[stencil.ooo()][offset + j] = 0.0;
66 }
67 });
68}
69
70
78template<long unsigned int numFields> void setPerturbedField(
79 const FieldFunction& bfFunction,
80 std::span<std::array<Real, numFields>> b,
81 fsgrids::technicalspan technical,
83 int offset=fsgrids::bfield::PERBX,
84 bool append=false
85) {
86 /*if we do not add a new background to the existing one we first put everything to zero*/
87 if (append == false) {
88 setPerturbedFieldToZero(fsgrid, technical, b, offset);
89 }
90
91 //these are doubles, as the averaging functions copied from Gumics
92 //use internally doubles. In any case, it should provide more
93 //accurate results also for float simulations
94 const double accuracy = 1e-17;
95 unsigned int faceCoord1[3];
96 unsigned int faceCoord2[3];
97
98 //the coordinates of the edges face with a normal in the third coordinate direction, stored here to enable looping
99 faceCoord1[0] = 1;
100 faceCoord2[0] = 2;
101 faceCoord1[1] = 0;
102 faceCoord2[1] = 2;
103 faceCoord1[2] = 0;
104 faceCoord2[2] = 1;
105
106
107 // These are threaded now that the stuff around here is threadsafe
108 fsgrid.parallel_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
109 phiprof::initializeTimer("setPerturbedField-loop"), technical,
110 [& /*=, &bfFunction*/](const fsgrid::Coordinates &coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
111 const std::array<Real, 3> start = coordinates.getPhysicalCoords(stencil.i, stencil.j, stencil.k);
112 const std::array<Real, 3> gridSpacing = coordinates.physicalGridSpacing;
113 auto& field = b[stencil.ooo()];
114
115 // Face averages
116 for (uint fComponent = 0; fComponent < 3; fComponent++) {
117 T3DFunction valueFunction = std::bind(bfFunction, std::placeholders::_1, std::placeholders::_2,
118 std::placeholders::_3, (coordinate)fComponent, 0, (coordinate)0);
119 field[offset + fComponent] += // offset defaults to fsgrids::bfield::PERBX
120 surfaceAverage(valueFunction, (coordinate)fComponent, accuracy, start,
121 gridSpacing[faceCoord1[fComponent]], gridSpacing[faceCoord2[fComponent]]);
122 }
123 // Derivatives or volume averages are not calculated for the perBField
124 });
125}
126
127#endif
void setPerturbedField(const FieldFunction &bfFunction, std::span< std::array< Real, numFields > > b, fsgrids::technicalspan technical, FieldSolverGrid &fsgrid, int offset=fsgrids::bfield::PERBX, bool append=false)
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=false)
void setPerturbedFieldToZero(FieldSolverGrid &fsgrid, fsgrids::technicalspan technical, std::span< std::array< Real, numFields > > b, int offset=fsgrids::bfield::PERBX)
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
const int j
double surfaceAverage(const T3DFunction &f1, coordinate face, double accuracy, const std::array< double, 3 > &r1, double L1, double L2)
std::span< technical > technicalspan
Definition common.h:452
std::span< std::array< Real, bgbfield::N_BGB > > bgbspan
Definition common.h:444
@ N_BFIELD
Definition common.h:278
@ PERBX
Definition common.h:275