source: src/units/particle/interpolation.cpp@ e271f0

Last change on this file since e271f0 was fcf7f6, checked in by Julian Iseringhausen <isering@…>, 14 years ago

vmg: Added license files and headers (GPLv3).

git-svn-id: https://svn.version.fz-juelich.de/scafacos/trunk@1812 5161e1c8-67bf-11de-9fd5-51895aff932f

  • Property mode set to 100644
File size: 4.7 KB
Line 
1/*
2 * vmg - a versatile multigrid solver
3 * Copyright (C) 2012 Institute for Numerical Simulation, University of Bonn
4 *
5 * vmg is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * vmg is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifdef HAVE_CONFIG_H
20#include <config.h>
21#endif
22
23#include <vector>
24
25#include "base/helper.hpp"
26#include "base/index.hpp"
27#include "base/vector.hpp"
28#include "grid/grid.hpp"
29#include "units/particle/interpolation.hpp"
30#include "units/particle/particle.hpp"
31
32using namespace VMG;
33
34Particle::Interpolation::Interpolation(const int& degree) :
35 deg(degree),
36 deg_1(degree+1),
37 buffer(degree+1),
38 buffer_diff(degree)
39{
40 coeff = new vmg_float[Helper::intpow(deg_1, 3)];
41 coeff_buffer = new vmg_float[deg_1];
42 for (int i=0; i<degree; ++i)
43 buffer_diff[i].resize(i+1);
44}
45
46Particle::Interpolation::~Interpolation()
47{
48 delete [] coeff;
49 delete [] coeff_buffer;
50}
51
52void Particle::Interpolation::ComputeCoefficients(const Grid& grid, const Index& index)
53{
54 Index i;
55
56 const Index begin = index - deg/2 - 1;
57
58 h = grid.Extent().MeshWidth();
59
60 for (i[0]=0; i[0]<deg_1; ++i[0])
61 for (i[1]=0; i[1]<deg_1; ++i[1])
62 for (i[2]=0; i[2]<deg_1; ++i[2])
63 _access_coeff(i) = grid.GetVal(i+begin);
64
65 pos_begin = grid.Extent().Begin()
66 + (begin - grid.Local().Begin() + grid.Global().LocalBegin()) * grid.Extent().MeshWidth();
67
68 // compute coefficients x-direction
69 for (i=0; i[1]<deg_1; ++i[1])
70 for (i[2]=0; i[2]<deg_1; ++i[2])
71 _compute_coefficients_1d(i, 0);
72
73 // compute coefficients y-direction
74 for (i=0; i[0]<deg_1; ++i[0])
75 for (i[2]=0; i[2]<deg_1; ++i[2])
76 _compute_coefficients_1d(i, 1);
77
78 // compute coefficients z-direction
79 for (i=0; i[0]<deg_1; ++i[0])
80 for (i[1]=0; i[1]<deg_1; ++i[1])
81 _compute_coefficients_1d(i, 2);
82}
83
84void Particle::Interpolation::_compute_coefficients_1d(const Index& index, const unsigned int& direction)
85{
86 vmg_float power = 1.0;
87 unsigned long faculty = 1;
88 int c;
89 Index i;
90
91 for (i=index, c=0; c<deg_1; ++i[direction], ++c)
92 coeff_buffer[c] = _access_coeff(i);
93
94 i=index;
95 ++i[direction];
96 for (c=1; c<deg_1; ++i[direction], ++c) {
97 for (int j=0; j<deg_1-c; ++j)
98 coeff_buffer[j] = coeff_buffer[j+1] - coeff_buffer[j];
99 faculty *= c;
100 power *= h[direction];
101 _access_coeff(i) = coeff_buffer[0] / (faculty*power);
102 }
103}
104
105void Particle::Interpolation::Evaluate(Particle& p)
106{
107 Vector offset;
108
109 const Vector& pos = p.Pos();
110 vmg_float& pot = p.Pot();
111 Vector& field = p.Field();
112
113 pot = 0.0;
114 field = 0.0;
115
116 buffer[0] = 1.0;
117 offset = pos - pos_begin;
118 for (int i=1; i<deg_1; ++i) {
119 buffer[i] = buffer[i-1] * offset;
120 offset -= h;
121 }
122
123 offset = pos - pos_begin;
124 for (int i=0; i<deg; ++i) {
125 for (int j=0; j<i; ++j)
126 buffer_diff[i][j] = buffer_diff[i-1][j] * offset;
127 buffer_diff[i][i] = buffer[i];
128 offset -= h;
129 }
130
131 for (int i=1; i<deg; ++i)
132 for (int j=1; j<=i; ++j)
133 buffer_diff[i][0] += buffer_diff[i][j];
134
135 for (int i=0; i<deg_1; ++i)
136 for (int j=0; j<deg_1; ++j)
137 for (int k=0; k<deg_1; ++k)
138 pot += _access_coeff(i,j,k) * buffer[i][0] * buffer[j][1] * buffer[k][2];
139
140 for (int i=0; i<deg_1; ++i)
141 for (int j=0; j<deg_1; ++j)
142 for (int k=0; k<deg; ++k) {
143 field[0] -= _access_coeff(k+1, i, j) * buffer[i][1] * buffer[j][2] * buffer_diff[k][0][0];
144 field[1] -= _access_coeff(i, k+1, j) * buffer[i][0] * buffer[j][2] * buffer_diff[k][0][1];
145 field[2] -= _access_coeff(i, j, k+1) * buffer[i][0] * buffer[j][1] * buffer_diff[k][0][2];
146 }
147
148}
149
150vmg_float Particle::Interpolation::EvaluatePotentialLR(const Particle& p)
151{
152 vmg_float result = 0.0;
153 Vector prod, offset;
154 Index i;
155
156 const Vector& pos = p.Pos();
157
158 prod[0] = 1.0;
159 offset[0] = pos[0] - pos_begin[0];
160 for (i[0]=0; i[0]<deg_1; ++i[0]) {
161 prod[1] = prod[0];
162 offset[1] = pos[1] - pos_begin[1];
163 for (i[1]=0; i[1]<deg_1; ++i[1]) {
164 prod[2] = prod[1];
165 offset[2] = pos[2] - pos_begin[2];
166 for (i[2]=0; i[2]<deg_1; ++i[2]) {
167 result += _access_coeff(i) * prod[2];
168 prod[2] *= offset[2];
169 offset[2] -= h[2];
170 }
171 prod[1] *= offset[1];
172 offset[1] -= h[1];
173 }
174 prod[0] *= offset[0];
175 offset[0] -= h[0];
176 }
177
178 return result;
179}
Note: See TracBrowser for help on using the repository browser.