source: src/base/interpolate_polynomial.cpp@ 39a6d9

Last change on this file since 39a6d9 was 1a92cf, checked in by Julian Iseringhausen <isering@…>, 14 years ago

vmg: Prepared force calculation.

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

  • Property mode set to 100644
File size: 4.8 KB
Line 
1#ifdef HAVE_CONFIG_H
2#include <config.h>
3#endif
4
5#include <vector>
6
7#include "base/helper.hpp"
8#include "base/index.hpp"
9#include "base/interpolate_polynomial.hpp"
10#include "base/vector.hpp"
11#include "grid/grid.hpp"
12
13using namespace VMG;
14
15InterpolatePolynomial::InterpolatePolynomial(const unsigned int& degree) :
16 deg(degree),
17 deg_1(degree+1),
18 buffer(degree+1),
19 buffer_diff(degree)
20{
21 coeff = new vmg_float[Helper::intpow(deg_1, 3)];
22 coeff_buffer = new vmg_float[deg_1];
23 for (int i=0; i<degree; ++i)
24 buffer_diff[i].resize(i+1);
25}
26
27InterpolatePolynomial::~InterpolatePolynomial()
28{
29 delete [] coeff;
30 delete [] coeff_buffer;
31}
32
33void InterpolatePolynomial::ComputeCoefficients(const Grid& grid, const Index& index)
34{
35 Index i;
36
37 const Index begin = index - (static_cast<int>(deg_1)-1)/2 - 1;
38
39 h = grid.Extent().MeshWidth();
40
41 for (i[0]=0; i[0]<deg_1; ++i[0])
42 for (i[1]=0; i[1]<deg_1; ++i[1])
43 for (i[2]=0; i[2]<deg_1; ++i[2])
44 _access_coeff(i) = grid.GetVal(i+begin);
45
46 pos_begin = grid.Extent().Begin()
47 + (begin - grid.Local().Begin() + grid.Global().LocalBegin()) * grid.Extent().MeshWidth();
48
49 // compute coefficients x-direction
50 for (i=0; i[1]<deg_1; ++i[1])
51 for (i[2]=0; i[2]<deg_1; ++i[2])
52 _compute_coefficients_1d(i, 0);
53
54 // compute coefficients y-direction
55 for (i=0; i[0]<deg_1; ++i[0])
56 for (i[2]=0; i[2]<deg_1; ++i[2])
57 _compute_coefficients_1d(i, 1);
58
59 // compute coefficients z-direction
60 for (i=0; i[0]<deg_1; ++i[0])
61 for (i[1]=0; i[1]<deg_1; ++i[1])
62 _compute_coefficients_1d(i, 2);
63}
64
65void InterpolatePolynomial::_compute_coefficients_1d(const Index& index, const unsigned int& direction)
66{
67 vmg_float power = 1.0;
68 unsigned long faculty = 1;
69 unsigned int c;
70 Index i;
71
72 for (i=index, c=0; c<deg_1; ++i[direction], ++c)
73 coeff_buffer[c] = _access_coeff(i);
74
75 i=index;
76 ++i[direction];
77 for (c=1; c<deg_1; ++i[direction], ++c) {
78 for (unsigned int j=0; j<deg_1-c; ++j)
79 coeff_buffer[j] = coeff_buffer[j+1] - coeff_buffer[j];
80 faculty *= c;
81 power *= h[direction];
82 _access_coeff(i) = coeff_buffer[0] / (faculty*power);
83 }
84}
85
86vmg_float InterpolatePolynomial::Evaluate(const Vector& pos)
87{
88 vmg_float result = 0.0;
89 Vector prod, offset;
90 Index i;
91
92 prod[0] = 1.0;
93 offset[0] = pos[0] - pos_begin[0];
94 for (i[0]=0; i[0]<deg_1; ++i[0]) {
95 prod[1] = prod[0];
96 offset[1] = pos[1] - pos_begin[1];
97 for (i[1]=0; i[1]<deg_1; ++i[1]) {
98 prod[2] = prod[1];
99 offset[2] = pos[2] - pos_begin[2];
100 for (i[2]=0; i[2]<deg_1; ++i[2]) {
101 result += _access_coeff(i) * prod[2];
102 prod[2] *= offset[2];
103 offset[2] -= h[2];
104 }
105 prod[1] *= offset[1];
106 offset[1] -= h[1];
107 }
108 prod[0] *= offset[0];
109 offset[0] -= h[0];
110 }
111
112 return result;
113}
114
115void InterpolatePolynomial::Evaluate(const Vector& pos, vmg_float& pot, Vector& field)
116{
117 Vector offset;
118
119 pot = 0.0;
120 field = 0.0;
121
122 buffer[0] = 1.0;
123 offset = pos - pos_begin;
124 for (int i=1; i<deg_1; ++i) {
125 buffer[i] = buffer[i-1] * offset;
126 offset -= h;
127 }
128
129 offset = pos - pos_begin;
130 for (int i=0; i<deg; ++i) {
131 for (int j=0; j<i; ++j)
132 buffer_diff[i][j] = buffer_diff[i-1][j] * offset;
133 buffer_diff[i][i] = buffer[i];
134 offset -= h;
135 }
136
137 for (int i=1; i<deg; ++i)
138 for (int j=1; j<=i; ++j)
139 buffer_diff[i][0] += buffer_diff[i][j];
140
141 for (int i=0; i<deg_1; ++i)
142 for (int j=0; j<deg_1; ++j)
143 for (int k=0; k<deg_1; ++k)
144 pot += _access_coeff(i,j,k) * buffer[i][0] * buffer[j][1] * buffer[k][2];
145
146 for (int i=0; i<deg_1; ++i)
147 for (int j=0; j<deg_1; ++j)
148 for (int k=0; k<deg; ++k) {
149 field[0] -= _access_coeff(k+1, i, j) * buffer[i][1] * buffer[j][2] * buffer_diff[k][0][0];
150 field[1] -= _access_coeff(i, k+1, j) * buffer[i][0] * buffer[j][2] * buffer_diff[k][0][1];
151 field[2] -= _access_coeff(i, j, k+1) * buffer[i][0] * buffer[j][1] * buffer_diff[k][0][2];
152 }
153
154}
155
156Vector InterpolatePolynomial::EvaluateNegGradient(const Vector& pos)
157{
158 Vector offset, result;
159
160 buffer[0] = 1.0;
161 offset = pos - pos_begin;
162 for (int i=1; i<deg_1; ++i) {
163 buffer[i] = buffer[i-1] * offset;
164 offset -= h;
165 }
166
167 offset = pos - pos_begin;
168 for (int i=0; i<deg; ++i) {
169 for (int j=0; j<i; ++j)
170 buffer_diff[i][j] = buffer_diff[i-1][j] * offset;
171 buffer_diff[i][i] = buffer[i];
172 offset -= h;
173 }
174
175 for (int i=1; i<deg; ++i)
176 for (int j=1; j<=i; ++j)
177 buffer_diff[i][0] += buffer_diff[i][j];
178
179 for (int i=0; i<deg_1; ++i)
180 for (int j=0; j<deg_1; ++j)
181 for (int k=0; k<deg; ++k) {
182 result[0] -= _access_coeff(k+1, i, j) * buffer[i][1] * buffer[j][2] * buffer_diff[k][0][0];
183 result[1] -= _access_coeff(i, k+1, j) * buffer[i][0] * buffer[j][2] * buffer_diff[k][0][1];
184 result[2] -= _access_coeff(i, j, k+1) * buffer[i][0] * buffer[j][1] * buffer_diff[k][0][2];
185 }
186
187 return result;
188}
Note: See TracBrowser for help on using the repository browser.