source: src/Jobs/WindowGrid_converter.cpp@ d93d2c

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults AddingActions_SaveParseParticleParameters Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_ParticleName_to_Atom Adding_StructOpt_integration_tests AtomFragments Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator CombiningParticlePotentialParsing Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_BoundInBox_CenterInBox_MoleculeActions Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_PopActions Fix_QtFragmentList_sorted_selection Fix_Restrictedkeyset_FragmentMolecule Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns Fix_fitting_potentials Fixes ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion FragmentAction_writes_AtomFragments FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity ImplicitCharges IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix MoreRobust_FragmentAutomation ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PdbParser_setsAtomName PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks Rewrite_FitPartialCharges RotateToPrincipalAxisSystem_UndoRedo SaturateAtoms_findBestMatching SaturateAtoms_singleDegree StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg Switchable_LogView ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps TremoloParser_setsAtomName Ubuntu_1604_changes stable
Last change on this file since d93d2c was 17e4fd, checked in by Frederik Heber <heber@…>, 9 years ago

Added new option DoSmearElectronicCharges to FragmentationAutomationAction.

  • this uses ChargeSmearer: is prepared in InterfaceVMGJob and used in WindowGrid_converter.
  • VMGJob and VMGFragmentController need to pass along the DoSmearCharges option from the command-line.
  • Property mode set to 100644
File size: 14.8 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2012 University of Bonn. All rights reserved.
5 * Copyright (C) 2013 Frederik Heber. All rights reserved.
6 * Please see the COPYING file or "Copyright notice" in builder.cpp for details.
7 *
8 *
9 * This file is part of MoleCuilder.
10 *
11 * MoleCuilder is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation, either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * MoleCuilder is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
23 */
24
25/*
26 * WindowGrid_converter.cpp
27 *
28 * Created on: Dec 20, 2012
29 * Author: heber
30 */
31
32
33// include config.h
34#ifdef HAVE_CONFIG_H
35#include <config.h>
36#endif
37
38#include "grid/grid.hpp"
39
40#include "WindowGrid_converter.hpp"
41
42#include "CodePatterns/MemDebug.hpp"
43
44#include <iostream>
45#include <iterator>
46#include <limits>
47
48#include "CodePatterns/Assert.hpp"
49#include "CodePatterns/Log.hpp"
50
51#include "Fragmentation/Summation/SetValues/SamplingGrid.hpp"
52#include "Jobs/ChargeSmearer.hpp"
53
54void WindowGrid_converter::addGridOntoWindow(
55 VMG::Grid &grid,
56 SamplingGrid &window,
57 const double prefactor,
58 const bool OpenBoundaryConditions)
59{
60#ifndef NDEBUG
61 for(size_t index=0;index<3;++index) {
62 ASSERT( window.begin[index] >= window.begin_window[index],
63 "InterfaceVMGJob::addGridOntoWindow() - given grid starts earlier than window in component "
64 +toString(index)+".");
65 ASSERT( window.end[index] <= window.end_window[index],
66 "InterfaceVMGJob::addGridOntoWindow() - given grid ends later than window in component "
67 +toString(index)+".");
68 }
69#endif
70 // the only issue are indices
71 const size_t gridpoints_axis = window.getGridPointsPerAxis();
72 size_t pre_offset[3];
73 size_t post_offset[3];
74 size_t length[3];
75 size_t total[3];
76 const double round_offset =
77 (std::numeric_limits<size_t>::round_style == std::round_toward_zero) ?
78 0.5 : 0.; // need offset to get to round_toward_nearest behavior
79 for(size_t index=0;index<3;++index) {
80 const double delta = (double)gridpoints_axis/(window.end[index] - window.begin[index]);
81 // delta is conversion factor from box length to discrete length, i.e. number of points
82 pre_offset[index] = delta*(window.begin[index] - window.begin_window[index])+round_offset;
83 length[index] = delta*(window.end[index] - window.begin[index])+round_offset;
84 post_offset[index] = delta*(window.end_window[index] - window.end[index])+round_offset;
85 total[index] = delta*(window.end_window[index] - window.begin_window[index])+round_offset;
86 // total is used as safe-guard against loss due to discrete conversion
87 ASSERT( pre_offset[index]+post_offset[index]+length[index] == total[index],
88 "InterfaceVMGJob::addGridOntoWindow() - pre, post, and length don't sum up to total for "
89 +toString(index)+"th component.");
90 }
91#ifndef NDEBUG
92 const size_t calculated_size = length[0]*length[1]*length[2];
93// const size_t given_size = std::distance(grid_begin, grid_end);
94// ASSERT( calculated_size == given_size,
95// "InterfaceVMGJob::addGridOntoWindow() - not enough sampled values given: "
96// +toString(calculated_size)+" != "+toString(given_size)+".");
97 ASSERT( calculated_size <= window.sampled_grid.size(),
98 "InterfaceVMGJob::addGridOntoWindow() - not enough sampled values available: "
99 +toString(calculated_size)+" <= "+toString(window.sampled_grid.size())+".");
100 const size_t total_size = total[0]*total[1]*total[2];
101 ASSERT( total_size == window.sampled_grid.size(),
102 "InterfaceVMGJob::addGridOntoWindow() - total size is not equal to number of present points: "
103 +toString(total_size)+" != "+toString(window.sampled_grid.size())+".");
104#endif
105 size_t N[3];
106 SamplingGrid::sampledvalues_t::iterator griditer = window.sampled_grid.begin();
107 std::advance(griditer, pre_offset[0]*total[1]*total[2]);
108
109 VMG::Grid::iterator copyiter = grid.Iterators().Local().Begin();
110 const VMG::Index size = grid.Local().Size();
111 if (OpenBoundaryConditions)
112 for(N[0]=(size_t)0; N[0] < (size_t)size[0]/(size_t)4; ++N[0])
113 for(N[1]=(size_t)0; N[1] < (size_t)size[1]; ++N[1])
114 for(N[2]=(size_t)0; N[2] < (size_t)size[2]; ++N[2]) {
115 ASSERT( copyiter != grid.Iterators().Local().End(),
116 "InterfaceVMGJob::addGridOntoWindow() - copyiter is already at end of window.");
117 ++copyiter;
118 }
119 for(N[0]=(size_t)0; N[0] < length[0]; ++N[0]) {
120 std::advance(griditer, pre_offset[1]*total[2]);
121 if (OpenBoundaryConditions)
122 for(N[1]=(size_t)0; N[1] < (size_t)size[1]/(size_t)4; ++N[1])
123 for(N[2]=(size_t)0; N[2] < (size_t)size[2]; ++N[2]) {
124 ASSERT( copyiter != grid.Iterators().Local().End(),
125 "InterfaceVMGJob::addGridOntoWindow() - copyiter is already at end of window.");
126 ++copyiter;
127 }
128 for(N[1]=(size_t)0; N[1] < length[1]; ++N[1]) {
129 std::advance(griditer, pre_offset[2]);
130 if (OpenBoundaryConditions)
131 for(N[2]=(size_t)0; N[2] < (size_t)size[2]/(size_t)4; ++N[2]) {
132 ASSERT( copyiter != grid.Iterators().Local().End(),
133 "InterfaceVMGJob::addGridOntoWindow() - copyiter is already at end of window.");
134 ++copyiter;
135 }
136 for(N[2]=(size_t)0; N[2] < length[2]; ++N[2]) {
137 ASSERT( griditer != window.sampled_grid.end(),
138 "InterfaceVMGJob::addGridOntoWindow() - griditer is already at end of window.");
139 ASSERT( copyiter != grid.Iterators().Local().End(),
140 "InterfaceVMGJob::addGridOntoWindow() - copyiter is already at end of window.");
141 *griditer++ += prefactor*grid(*copyiter++);
142 }
143 std::advance(griditer, post_offset[2]);
144 if (OpenBoundaryConditions)
145 for(N[2]=(size_t)0; N[2] < (size_t)size[2] - (size_t)size[2]/(size_t)4 - length[2]; ++N[2]) {
146 ASSERT( copyiter != grid.Iterators().Local().End(),
147 "InterfaceVMGJob::addGridOntoWindow() - copyiter is already at end of window.");
148 ++copyiter;
149 }
150 }
151 std::advance(griditer, post_offset[1]*total[2]);
152 if (OpenBoundaryConditions)
153 for(N[1]=(size_t)0; N[1] < (size_t)size[1] - (size_t)size[1]/(size_t)4 - length[1]; ++N[1])
154 for(N[2]=(size_t)0; N[2] < (size_t)size[2]; ++N[2]) {
155 ASSERT( copyiter != grid.Iterators().Local().End(),
156 "InterfaceVMGJob::addGridOntoWindow() - copyiter is already at end of window.");
157 ++copyiter;
158 }
159 }
160 if (OpenBoundaryConditions)
161 for(N[0]=(size_t)0; N[0] < (size_t)size[0] - (size_t)size[0]/(size_t)4 - length[0]; ++N[0])
162 for(N[1]=(size_t)0; N[1] < (size_t)size[1]; ++N[1])
163 for(N[2]=(size_t)0; N[2] < (size_t)size[2]; ++N[2]) {
164 ASSERT( copyiter != grid.Iterators().Local().End(),
165 "InterfaceVMGJob::addGridOntoWindow() - copyiter is already at end of window.");
166 ++copyiter;
167 }
168#ifndef NDEBUG
169 std::advance(griditer, post_offset[0]*total[1]*total[2]);
170 ASSERT( griditer == window.sampled_grid.end(),
171 "InterfaceVMGJob::addGridOntoWindow() - griditer is not at end of window.");
172 ASSERT( copyiter == grid.Iterators().Local().End(),
173 "InterfaceVMGJob::addGridOntoWindow() - copyiter is not at end of window.");
174#endif
175}
176
177void WindowGrid_converter::addWindowOntoGrid(
178 VMG::Grid& window,
179 const SamplingGrid &grid,
180 const double prefactor,
181 const bool OpenBoundaryConditions,
182 const bool DoSmearCharges)
183{
184#ifndef NDEBUG
185 for(size_t index=0;index<3;++index) {
186 ASSERT( grid.begin_window[index] >= grid.begin[index],
187 "InterfaceVMGJob::addWindowOntoGrid() - given window starts earlier than grid in component "
188 +toString(index)+".");
189 ASSERT( grid.end_window[index] <= grid.end[index],
190 "InterfaceVMGJob::addWindowOntoGrid() - given window ends later than grid in component "
191 +toString(index)+".");
192 }
193#endif
194 // the only issue are indices
195 const size_t gridpoints_axis = grid.getGridPointsPerAxis();
196 size_t pre_offset[3];
197 size_t post_offset[3];
198 size_t length[3];
199 size_t total[3];
200 const double round_offset =
201 (std::numeric_limits<size_t>::round_style == std::round_toward_zero) ?
202 0.5 : 0.; // need offset to get to round_toward_nearest behavior
203 for(size_t index=0;index<3;++index) {
204 const double delta = (double)gridpoints_axis/(grid.end[index] - grid.begin[index]);
205 // delta is conversion factor from box length to discrete length, i.e. number of points
206 pre_offset[index] = delta*(grid.begin_window[index] - grid.begin[index])+round_offset;
207 length[index] = delta*(grid.end_window[index] - grid.begin_window[index])+round_offset;
208 post_offset[index] = delta*(grid.end[index] - grid.end_window[index])+round_offset;
209 total[index] = delta*(grid.end[index] - grid.begin[index])+round_offset;
210 // total is used as safe-guard against loss due to discrete conversion
211 ASSERT( pre_offset[index]+post_offset[index]+length[index] == total[index],
212 "InterfaceVMGJob::addWindowOntoGrid() - pre, post, and length don't sum up to total for "
213 +toString(index)+"th component.");
214 }
215#ifndef NDEBUG
216 const size_t calculated_size = length[0]*length[1]*length[2];
217 ASSERT( calculated_size == grid.sampled_grid.size(),
218 "InterfaceVMGJob::addWindowOntoGrid() - not enough sampled values given: "
219 +toString(calculated_size)+" != "+toString(grid.sampled_grid.size())+".");
220// ASSERT( calculated_size <= given_size,
221// "InterfaceVMGJob::addWindowOntoGrid() - not enough sampled values available: "
222// +toString(calculated_size)+" <= "+toString(given_size)+".");
223// const size_t total_size = total[0]*total[1]*total[2];
224// ASSERT( total_size == given_size,
225// "InterfaceVMGJob::addWindowOntoGrid() - total size is not equal to number of present points: "
226// +toString(total_size)+" != "+toString(given_size)+".");
227#endif
228 size_t N[3];
229 // in open boundary case grid.Local() contains more than just the inner area. The grid
230 // is actually twice as large to allow for the FV discretization to work. Hence, we first
231 // have to seek our starting point ... see VMG::Grid::GetSpatialPos()
232 if (OpenBoundaryConditions) {
233 const VMG::Index size = window.Local().Size();
234// const VMG::Index boundary1size = window.Local().BoundarySize1();
235// const VMG::Index boundary2size = window.Local().BoundarySize2();
236// const VMG::Index halo1size = window.Local().HaloSize1();
237// const VMG::Index halo2size = window.Local().HaloSize2();
238 // this mimicks VMG::GridIndexTranslations::EndOffset()
239 const size_t off = OpenBoundaryConditions ? 1 : 0;
240 for (size_t i=0;i<3;++i)
241 pre_offset[i] += ((size_t)size[i] - off) / 4;
242 for (size_t i=0;i<3;++i)
243 total[i] = ((size_t)size[i]);
244 for (size_t i=0;i<3;++i)
245 post_offset[i] = ((size_t)size[i]) - pre_offset[i] - length[i];
246 }
247
248 /// reset grid to zero everywhere
249
250 VMG::Grid::iterator griditer = window.Iterators().Local().Begin();
251// griditer.advance(pre_offset[0]*total[1]*total[2]);
252 for(N[0]=0; N[0] < total[0]; ++N[0])
253 for(N[1]=0; N[1] < total[1]; ++N[1])
254 for(N[2]=0; N[2] < total[2]; ++N[2]) {
255 ASSERT( griditer != window.Iterators().Local().End(),
256 "InterfaceVMGJob::addWindowOntoGrid() - griditer is already at end of window.");
257 window(*griditer++) = 0.;
258 }
259
260#ifndef NDEBUG
261 ASSERT( griditer == window.Iterators().Local().End(),
262 "InterfaceVMGJob::addWindowOntoGrid() - griditer is not at end of window.");
263#endif
264
265 /// then apply charges onto grid
266
267 griditer = window.Iterators().Local().Begin();
268 SamplingGrid::sampledvalues_t::const_iterator copyiter = grid.sampled_grid.begin();
269 const ChargeSmearer &smearer = ChargeSmearer::getInstance();
270 // NOTE: GridIterator::operator+=()'s implementation in vmg is broken. DON'T USE!
271// griditer += pre_offset[0] * total[1] * total[2];
272 for(N[0]=0; N[0] < pre_offset[0]; ++N[0])
273 for(N[1]=0; N[1] < total[1]; ++N[1])
274 for(N[2]=0; N[2] < total[2]; ++N[2]) {
275 ASSERT( griditer != window.Iterators().Local().End(),
276 "InterfaceVMGJob::addWindowOntoGrid() - griditer is already at end of window.");
277 griditer++;
278 }
279 for(N[0]=0; N[0] < length[0]; ++N[0]) {
280// griditer += pre_offset[1] * total[2];
281 for(N[1]=0; N[1] < pre_offset[1]; ++N[1])
282 for(N[2]=0; N[2] < total[2]; ++N[2]) {
283 ASSERT( griditer != window.Iterators().Local().End(),
284 "InterfaceVMGJob::addWindowOntoGrid() - griditer is already at end of window.");
285 griditer++;
286 }
287 for(N[1]=0; N[1] < length[1]; ++N[1]) {
288// griditer += pre_offset[2];
289 for(N[2]=0; N[2] < pre_offset[2]; ++N[2]) {
290 griditer++;
291 }
292
293 for(N[2]=0; N[2] < length[2]; ++N[2]) {
294 ASSERT( griditer != window.Iterators().Local().End(),
295 "InterfaceVMGJob::addWindowOntoGrid() - griditer is already at end of window.");
296 ASSERT( copyiter != grid.sampled_grid.end(),
297 "InterfaceVMGJob::addWindowOntoGrid() - griditer is already at end of window.");
298 // either smear out charges or not.
299 if (DoSmearCharges) {
300 smearer(window, griditer++, prefactor*(*copyiter++));
301 } else {
302 window(*griditer++) += prefactor*(*copyiter++);
303 }
304 }
305// griditer += post_offset[2];
306 for(N[2]=0; N[2] < post_offset[2]; ++N[2]) {
307 ASSERT( griditer != window.Iterators().Local().End(),
308 "InterfaceVMGJob::addWindowOntoGrid() - griditer is already at end of window.");
309 griditer++;
310 }
311 }
312// griditer += post_offset[1] * total[2];
313 for(N[1]=0; N[1] < post_offset[1]; ++N[1])
314 for(N[2]=0; N[2] < total[2]; ++N[2]) {
315 ASSERT( griditer != window.Iterators().Local().End(),
316 "InterfaceVMGJob::addWindowOntoGrid() - griditer is already at end of window.");
317 griditer++;
318 }
319 }
320// griditer += post_offset[0] * total[1] * total[2];
321 for(N[0]=0; N[0] < post_offset[0]; ++N[0])
322 for(N[1]=0; N[1] < total[1]; ++N[1])
323 for(N[2]=0; N[2] < total[2]; ++N[2]) {
324 ASSERT( griditer != window.Iterators().Local().End(),
325 "InterfaceVMGJob::addWindowOntoGrid() - griditer is already at end of window.");
326 griditer++;
327 }
328#ifndef NDEBUG
329 ASSERT( griditer == window.Iterators().Local().End(),
330 "InterfaceVMGJob::addWindowOntoGrid() - griditer is not at end of window.");
331 ASSERT( copyiter == grid.sampled_grid.end(),
332 "InterfaceVMGJob::addWindowOntoGrid() - copyiter is not at end of window.");
333#endif
334
335 // LOG(2, "DEBUG: Grid after adding other is " << grid << ".");
336}
Note: See TracBrowser for help on using the repository browser.