source: ThirdParty/vmg/src/units/particle/interpolation.cpp@ be848d

Action_Thermostats Add_AtomRandomPerturbation Add_SelectAtomByNameAction Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_StructOpt_integration_tests AutomationFragmentation_failures Candidate_v1.6.1 ChangeBugEmailaddress ChemicalSpaceEvaluator EmpiricalPotential_contain_HomologyGraph_documentation Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph Fix_Verbose_Codepatterns ForceAnnealing_oldresults ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion Gui_displays_atomic_force_velocity IndependentFragmentGrids_IntegrationTest JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks StoppableMakroAction TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps
Last change on this file since be848d was 7faa5c, checked in by Frederik Heber <heber@…>, 8 years ago

Merge commit 'de061d9d851257a04e924d4472df4523d33bb08b' as 'ThirdParty/vmg'

  • 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 <libvmg_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
32#include "mg.hpp"
33#include "comm/comm.hpp"
34
35using namespace VMG;
36
37Particle::Interpolation::Interpolation(const int& degree) :
38 deg(degree),
39 deg_1(degree+1),
40 buffer(degree+1),
41 buffer_diff(degree)
42{
43 coeff = new vmg_float[Helper::intpow(deg_1, 3)];
44 coeff_buffer = new vmg_float[deg_1];
45 for (int i=0; i<degree; ++i)
46 buffer_diff[i].resize(i+1);
47}
48
49Particle::Interpolation::~Interpolation()
50{
51 delete [] coeff;
52 delete [] coeff_buffer;
53}
54
55void Particle::Interpolation::ComputeCoefficients(const Grid& grid, const Index& index)
56{
57 Index i;
58
59 const Index begin = index - deg/2;
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.Global().GlobalBegin()) * 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
87void Particle::Interpolation::_compute_coefficients_1d(const Index& index, const unsigned int& direction)
88{
89 vmg_float power = 1.0;
90 unsigned long faculty = 1;
91 int c;
92 Index i;
93
94 for (i=index, c=0; c<deg_1; ++i[direction], ++c)
95 coeff_buffer[c] = _access_coeff(i);
96
97 i=index;
98 ++i[direction];
99 for (c=1; c<deg_1; ++i[direction], ++c) {
100 for (int j=0; j<deg_1-c; ++j)
101 coeff_buffer[j] = coeff_buffer[j+1] - coeff_buffer[j];
102 faculty *= c;
103 power *= h[direction];
104 _access_coeff(i) = coeff_buffer[0] / (faculty*power);
105 }
106}
107
108void Particle::Interpolation::Evaluate(Particle& p)
109{
110 const Vector& pos = p.Pos();
111 vmg_float& pot = p.Pot();
112 Vector& field = p.Field();
113
114 pot = 0.0;
115 field = 0.0;
116
117 Vector offset = pos - pos_begin;
118 buffer[0] = 1.0;
119 for (int i=0; i<deg; ++i) {
120 buffer[i+1] = buffer[i] * offset;
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
145vmg_float Particle::Interpolation::EvaluatePotentialLR(const Particle& p)
146{
147 vmg_float result = 0.0;
148 Vector prod, offset;
149 Index i;
150
151 const Vector& pos = p.Pos();
152
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];
165 }
166 prod[1] *= offset[1];
167 offset[1] -= h[1];
168 }
169 prod[0] *= offset[0];
170 offset[0] -= h[0];
171 }
172
173 return result;
174}
Note: See TracBrowser for help on using the repository browser.