Vlasiator ebf0dd394 on dev (v5.4.0 + 1054 commits)
Loading...
Searching...
No Matches
field.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#include <vector>
24#include <Eigen/Dense>
25
26#define Vec3d Eigen::Vector3d
27
28#include "boundaries.h"
29#include "particleparameters.h"
30
31// A 3D cartesian vector field with suitable interpolation properties for
32// particle pushing
33struct Field
34{
35 // Time at which this field is "valid"
36 double time;
37
38 // Mesh spacing
39 double dx[3];
40
41 // Information about spatial dimensions (like extent, boundaries, etc)
43
44 // The actual field data
45 std::vector<double> data;
46
47 // Constructor (primarily here to make sure boundaries are properly initialized as zero)
49 for(int i=0; i<3; i++) {
50 dimension[i] = nullptr;
51 }
52 }
53
54 double* getCellRef(int x, int y, int z) {
55
56 if(dimension[2]->cells == 1) {
57 // Equatorial plane
58 return &(data[4*(y*dimension[0]->cells+x)]);
59 } else {
60 // General 3d case
61 return &(data[4*(z*dimension[0]->cells*dimension[1]->cells + y*dimension[0]->cells + x)]);
62 }
63 }
64
65 Vec3d getCell(int x, int y, int z) {
66
67 // Map these cell coordinates using the boundaries
68 x = dimension[0]->cellCoordinate(x);
69 y = dimension[1]->cellCoordinate(y);
70 z = dimension[2]->cellCoordinate(z);
71
72 double* cell = getCellRef(x,y,z);
73 return {cell[0],cell[1],cell[2]};
74 }
75
76 // Round-Brace indexing: indexing by physical location, with interpolation
77 virtual Vec3d operator()(Vec3d v) {
79
80 int32_t index[3];
81 Vec3d fract;
82
83 for(int i=0; i<3; i++) {
84 v[i] -= min[i];
85 v[i] /= dx[i];
86 index[i] = (int32_t)std::trunc(v[i]);
87 fract[i] = v[i] - (double)std::trunc(v[i]);
88 }
89
90 if(dimension[2]->cells <= 1) {
91 // Equatorial plane
92 Vec3d interp[4];
93 interp[0] = getCell(index[0],index[1],index[2]);
94 interp[1] = getCell(index[0]+1,index[1],index[2]);
95 interp[2] = getCell(index[0],index[1]+1,index[2]);
96 interp[3] = getCell(index[0]+1,index[1]+1,index[2]);
97
98 return fract[0]*(fract[1]*interp[3]+(1.-fract[1])*interp[1])
99 + (1.-fract[0])*(fract[1]*interp[2]+(1.-fract[1])*interp[0]);
100 } else if (dimension[1]->cells <= 1) {
101 // Polar plane
102 Vec3d interp[4];
103
104 interp[0] = getCell(index[0],index[1],index[2]);
105 interp[1] = getCell(index[0]+1,index[1],index[2]);
106 interp[2] = getCell(index[0],index[1],index[2]+1);
107 interp[3] = getCell(index[0]+1,index[1],index[2]+1);
108
109 return fract[0]*(fract[2]*interp[3]+(1.-fract[2])*interp[1])
110 + (1.-fract[0])*(fract[2]*interp[2]+(1.-fract[2])*interp[0]);
111 } else {
112 // Proper 3D
113 Vec3d interp[8];
114 interp[0] = getCell(index[0],index[1],index[2]);
115 interp[1] = getCell(index[0]+1,index[1],index[2]);
116 interp[2] = getCell(index[0],index[1]+1,index[2]);
117 interp[3] = getCell(index[0]+1,index[1]+1,index[2]);
118 interp[4] = getCell(index[0],index[1],index[2]+1);
119 interp[5] = getCell(index[0]+1,index[1],index[2]+1);
120 interp[6] = getCell(index[0],index[1]+1,index[2]+1);
121 interp[7] = getCell(index[0]+1,index[1]+1,index[2]+1);
122 return fract[2] * (
123 fract[0]*(fract[1]*interp[3]+(1.-fract[1])*interp[1])
124 + (1.-fract[0])*(fract[1]*interp[2]+(1.-fract[1])*interp[0]))
125 + (1.-fract[2]) * (
126 fract[0]*(fract[1]*interp[7]+(1.-fract[1])*interp[5])
127 + (1.-fract[0])*(fract[1]*interp[6]+(1.-fract[1])*interp[4]));
128 }
129
130 }
131 virtual Vec3d operator()(double x, double y, double z) {
132 Vec3d v(x,y,z);
133 return operator()(v);
134 }
135
136};
137
138// Linear Temporal interpolation between two input fields
141 double t;
142
143 /* Constructor:
144 * Inputs are the two fields to interpolate between
145 * and the current time.
146 */
147 Interpolated_Field(Field& _a, Field& _b, float _t) : a(_a),b(_b),t(_t) {
148 }
149
150 virtual Vec3d operator()(Vec3d v) {
151 Vec3d aval=a(v);
152 Vec3d bval=b(v);
153
154 double fract = (t - a.time)/(b.time-a.time);
155 return fract*bval + (1.-fract)*aval;
156 }
157};
for i
Definition Dispersion.m:24
#define Vec3d
Definition field.h:26
#define index(i, j, k)
virtual Vec3d operator()(double x, double y, double z)
Definition field.h:131
Field()
Definition field.h:48
double dx[3]
Definition field.h:39
std::vector< double > data
Definition field.h:45
double * getCellRef(int x, int y, int z)
Definition field.h:54
virtual Vec3d operator()(Vec3d v)
Definition field.h:77
Vec3d getCell(int x, int y, int z)
Definition field.h:65
Boundary * dimension[3]
Definition field.h:42
double time
Definition field.h:36
Interpolated_Field(Field &_a, Field &_b, float _t)
Definition field.h:147
virtual Vec3d operator()(Vec3d v)
Definition field.h:150
static ARCH_HOSTDEV VecSimple< T > min(VecSimple< T > const &l, VecSimple< T > const &r)