source: src/units/particle/interpolation.cpp@ 50fc1f3

Last change on this file since 50fc1f3 was a72216, checked in by Olaf Lenz <olenz@…>, 13 years ago

Fixed permissions.

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

  • Property mode set to 100644
File size: 4.6 KB
RevLine 
[fcf7f6]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
[716da7]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"
[f003a9]29#include "units/particle/interpolation.hpp"
30#include "units/particle/particle.hpp"
[716da7]31
[ef94e7]32#include "mg.hpp"
33#include "comm/comm.hpp"
34
[716da7]35using namespace VMG;
36
[cd0fed]37Particle::Interpolation::Interpolation(const int& degree) :
[1a92cf]38 deg(degree),
[716da7]39 deg_1(degree+1),
[1a92cf]40 buffer(degree+1),
41 buffer_diff(degree)
[716da7]42{
43 coeff = new vmg_float[Helper::intpow(deg_1, 3)];
[1a92cf]44 coeff_buffer = new vmg_float[deg_1];
45 for (int i=0; i<degree; ++i)
46 buffer_diff[i].resize(i+1);
[716da7]47}
48
[f003a9]49Particle::Interpolation::~Interpolation()
[716da7]50{
51 delete [] coeff;
[1a92cf]52 delete [] coeff_buffer;
[716da7]53}
54
[f003a9]55void Particle::Interpolation::ComputeCoefficients(const Grid& grid, const Index& index)
[716da7]56{
57 Index i;
58
[ef94e7]59 const Index begin = index - deg/2;
[716da7]60
61 h = grid.Extent().MeshWidth();
62
63 for (i[0]=0; i[0]<deg_1; ++i[0])
64 for (i[1]=0; i[1]<deg_1; ++i[1])
65 for (i[2]=0; i[2]<deg_1; ++i[2])
66 _access_coeff(i) = grid.GetVal(i+begin);
67
68 pos_begin = grid.Extent().Begin()
69 + (begin - grid.Local().Begin() + grid.Global().LocalBegin()) * grid.Extent().MeshWidth();
70
71 // compute coefficients x-direction
72 for (i=0; i[1]<deg_1; ++i[1])
73 for (i[2]=0; i[2]<deg_1; ++i[2])
74 _compute_coefficients_1d(i, 0);
75
76 // compute coefficients y-direction
77 for (i=0; i[0]<deg_1; ++i[0])
78 for (i[2]=0; i[2]<deg_1; ++i[2])
79 _compute_coefficients_1d(i, 1);
80
81 // compute coefficients z-direction
82 for (i=0; i[0]<deg_1; ++i[0])
83 for (i[1]=0; i[1]<deg_1; ++i[1])
84 _compute_coefficients_1d(i, 2);
85}
86
[f003a9]87void Particle::Interpolation::_compute_coefficients_1d(const Index& index, const unsigned int& direction)
[716da7]88{
89 vmg_float power = 1.0;
90 unsigned long faculty = 1;
[cd0fed]91 int c;
[716da7]92 Index i;
93
94 for (i=index, c=0; c<deg_1; ++i[direction], ++c)
[1a92cf]95 coeff_buffer[c] = _access_coeff(i);
[716da7]96
97 i=index;
98 ++i[direction];
99 for (c=1; c<deg_1; ++i[direction], ++c) {
[cd0fed]100 for (int j=0; j<deg_1-c; ++j)
[1a92cf]101 coeff_buffer[j] = coeff_buffer[j+1] - coeff_buffer[j];
[716da7]102 faculty *= c;
103 power *= h[direction];
[1a92cf]104 _access_coeff(i) = coeff_buffer[0] / (faculty*power);
[716da7]105 }
106}
107
[f003a9]108void Particle::Interpolation::Evaluate(Particle& p)
[1a92cf]109{
[ef94e7]110 const Vector& pos = p.Pos();
111 vmg_float& pot = p.Pot();
112 Vector& field = p.Field();
[f003a9]113
[ef94e7]114 pot = 0.0;
115 field = 0.0;
[1a92cf]116
[ef94e7]117 Vector offset = pos - pos_begin;
[1a92cf]118 buffer[0] = 1.0;
119 for (int i=0; i<deg; ++i) {
[ef94e7]120 buffer[i+1] = buffer[i] * offset;
[1a92cf]121 for (int j=0; j<i; ++j)
122 buffer_diff[i][j] = buffer_diff[i-1][j] * offset;
123 buffer_diff[i][i] = buffer[i];
124 offset -= h;
125 }
126
127 for (int i=1; i<deg; ++i)
128 for (int j=1; j<=i; ++j)
129 buffer_diff[i][0] += buffer_diff[i][j];
130
131 for (int i=0; i<deg_1; ++i)
132 for (int j=0; j<deg_1; ++j)
133 for (int k=0; k<deg_1; ++k)
134 pot += _access_coeff(i,j,k) * buffer[i][0] * buffer[j][1] * buffer[k][2];
135
136 for (int i=0; i<deg_1; ++i)
137 for (int j=0; j<deg_1; ++j)
138 for (int k=0; k<deg; ++k) {
139 field[0] -= _access_coeff(k+1, i, j) * buffer[i][1] * buffer[j][2] * buffer_diff[k][0][0];
140 field[1] -= _access_coeff(i, k+1, j) * buffer[i][0] * buffer[j][2] * buffer_diff[k][0][1];
141 field[2] -= _access_coeff(i, j, k+1) * buffer[i][0] * buffer[j][1] * buffer_diff[k][0][2];
142 }
143}
144
[f003a9]145vmg_float Particle::Interpolation::EvaluatePotentialLR(const Particle& p)
[716da7]146{
[f003a9]147 vmg_float result = 0.0;
148 Vector prod, offset;
149 Index i;
[716da7]150
[f003a9]151 const Vector& pos = p.Pos();
[1a92cf]152
[f003a9]153 prod[0] = 1.0;
154 offset[0] = pos[0] - pos_begin[0];
155 for (i[0]=0; i[0]<deg_1; ++i[0]) {
156 prod[1] = prod[0];
157 offset[1] = pos[1] - pos_begin[1];
158 for (i[1]=0; i[1]<deg_1; ++i[1]) {
159 prod[2] = prod[1];
160 offset[2] = pos[2] - pos_begin[2];
161 for (i[2]=0; i[2]<deg_1; ++i[2]) {
162 result += _access_coeff(i) * prod[2];
163 prod[2] *= offset[2];
164 offset[2] -= h[2];
[716da7]165 }
[f003a9]166 prod[1] *= offset[1];
167 offset[1] -= h[1];
168 }
169 prod[0] *= offset[0];
170 offset[0] -= h[0];
171 }
[716da7]172
173 return result;
174}
Note: See TracBrowser for help on using the repository browser.