source: src/Fragmentation/datacreator.cpp@ dcbb5d

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 dcbb5d was 94d5ac6, checked in by Frederik Heber <heber@…>, 12 years ago

FIX: As we use GSL internally, we are as of now required to use GPL v2 license.

  • GNU Scientific Library is used at every place in the code, especially the sub-package LinearAlgebra is based on it which in turn is used really everywhere in the remainder of MoleCuilder. Hence, we have to use the GPL license for the whole of MoleCuilder. In effect, GPL's COPYING was present all along and stated the terms of the GPL v2 license.
  • Hence, I added the default GPL v2 disclaimer to every source file and removed the note about a (actually missing) LICENSE file.
  • also, I added a help-redistribute action which again gives the disclaimer of the GPL v2.
  • also, I changed in the disclaimer that is printed at every program start in builder_init.cpp.
  • TEST: Added check on GPL statement present in every module to test CodeChecks project-disclaimer.
  • Property mode set to 100755
File size: 36.5 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010-2012 University of Bonn. All rights reserved.
5 *
6 *
7 * This file is part of MoleCuilder.
8 *
9 * MoleCuilder is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * MoleCuilder is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23/** \file datacreator.cpp
24 *
25 * Declarations of assisting functions in creating data and plot files.
26 *
27 */
28
29//============================ INCLUDES ===========================
30
31// include config.h
32#ifdef HAVE_CONFIG_H
33#include <config.h>
34#endif
35
36#include "CodePatterns/MemDebug.hpp"
37
38#include <fstream>
39#include <sstream>
40#include <iomanip>
41
42#include "CodePatterns/Log.hpp"
43#include "CodePatterns/Verbose.hpp"
44#include "LinearAlgebra/defs.hpp"
45#include "Helpers/defs.hpp"
46#include "datacreator.hpp"
47#include "Fragmentation/EnergyMatrix.hpp"
48#include "Fragmentation/ForceMatrix.hpp"
49#include "Fragmentation/HessianMatrix.hpp"
50#include "Fragmentation/KeySetsContainer.hpp"
51
52using namespace std;
53
54//=========================== FUNCTIONS============================
55
56/** Opens a file with \a *filename in \a *dir.
57 * \param output file handle on return
58 * \param *dir directory
59 * \param *filename name of file
60 * \return true if file has been opened
61 */
62bool OpenOutputFile(ofstream &output, const char *dir, const char *filename)
63{
64 stringstream name;
65 name << dir << "/" << filename;
66 output.open(name.str().c_str(), ios::out);
67 if (output == NULL) {
68 LOG(0, "Unable to open " << name.str() << " for writing, is directory correct?");
69 return false;
70 }
71 return true;
72};
73
74/** Opens a file for appending with \a *filename in \a *dir.
75 * \param output file handle on return
76 * \param *dir directory
77 * \param *filename name of file
78 * \return true if file has been opened
79 */
80bool AppendOutputFile(ofstream &output, const char *dir, const char *filename)
81{
82 stringstream name;
83 name << dir << "/" << filename;
84 output.open(name.str().c_str(), ios::app);
85 if (output == NULL) {
86 LOG(0, "Unable to open " << name.str() << " for writing, is directory correct?");
87 return false;
88 }
89 return true;
90};
91
92/** Plots an energy vs. order.
93 * \param &Fragments EnergyMatrix class containing matrix values
94 * \param KeySets KeySetContainer class holding bond KeySetContainer::Order
95 * \param *prefix prefix in filename (without ending)
96 * \param *msg message to be place in first line as a comment
97 * \return true if file was written successfully
98 */
99bool CreateDataEnergyOrder(class EnergyMatrix &Fragments, class KeySetsContainer &KeySets, const char *dir, const char *prefix, const char *msg, const char *datum)
100{
101 stringstream filename;
102 ofstream output;
103
104 filename << prefix << ".dat";
105 if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
106 LOG(0, msg);
107 output << "# " << msg << ", created on " << datum;
108 output << "#Order\tFrag.No.\t" << Fragments.Header[Fragments.MatrixCounter] << endl;
109 for (int BondOrder=0;BondOrder<KeySets.Order;BondOrder++) {
110 for(int i=KeySets.FragmentsPerOrder[BondOrder];i--;) {
111 for(int j=Fragments.RowCounter[ KeySets.OrderSet[BondOrder][i] ];j--;)
112 for(int k=Fragments.ColumnCounter[ KeySets.OrderSet[BondOrder][i] ];k--;)
113 Fragments.Matrix[Fragments.MatrixCounter][j][k] += Fragments.Matrix[ KeySets.OrderSet[BondOrder][i] ][j][k];
114 }
115 output << BondOrder+1 << "\t" << KeySets.FragmentsPerOrder[BondOrder];
116 for (int l=0;l<Fragments.ColumnCounter[Fragments.MatrixCounter];l++)
117 output << scientific << "\t" << Fragments.Matrix[Fragments.MatrixCounter][ Fragments.RowCounter[Fragments.MatrixCounter]-1 ][l];
118 output << endl;
119 }
120 output.close();
121 return true;
122};
123
124/** Plots an energy error vs. order.
125 * \param &Energy EnergyMatrix class containing reference values (in MatrixCounter matrix)
126 * \param &Fragments EnergyMatrix class containing matrix values
127 * \param KeySets KeySetContainer class holding bond KeySetContainer::Order
128 * \param *prefix prefix in filename (without ending)
129 * \param *msg message to be place in first line as a comment
130 * \return true if file was written successfully
131 */
132bool CreateDataDeltaEnergyOrder(class EnergyMatrix &Energy, class EnergyMatrix &Fragments, class KeySetsContainer &KeySets, const char *dir, const char *prefix, const char *msg, const char *datum)
133{
134 stringstream filename;
135 ofstream output;
136
137 filename << prefix << ".dat";
138 if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
139 LOG(0, msg);
140 output << "# " << msg << ", created on " << datum;
141 output << "#Order\tFrag.No.\t" << Fragments.Header[Fragments.MatrixCounter] << endl;
142 Fragments.SetLastMatrix(Energy.Matrix[Energy.MatrixCounter],0);
143 for (int BondOrder=0;BondOrder<KeySets.Order;BondOrder++) {
144 for(int i=KeySets.FragmentsPerOrder[BondOrder];i--;) {
145 for(int j=Fragments.RowCounter[ KeySets.OrderSet[BondOrder][i] ];j--;)
146 for(int k=Fragments.ColumnCounter[ KeySets.OrderSet[BondOrder][i] ];k--;)
147 Fragments.Matrix[Fragments.MatrixCounter][j][k] -= Fragments.Matrix[ KeySets.OrderSet[BondOrder][i] ][j][k];
148 }
149 output << BondOrder+1 << "\t" << KeySets.FragmentsPerOrder[BondOrder];
150 for (int l=0;l<Fragments.ColumnCounter[Energy.MatrixCounter];l++)
151 if (fabs(Energy.Matrix[Energy.MatrixCounter][ Energy.RowCounter[Energy.MatrixCounter]-1 ][l]) < MYEPSILON)
152 output << scientific << "\t" << Fragments.Matrix[Fragments.MatrixCounter][ Fragments.RowCounter[Fragments.MatrixCounter]-1 ][l];
153 else
154 output << scientific << "\t" << (Fragments.Matrix[Fragments.MatrixCounter][ Fragments.RowCounter[Fragments.MatrixCounter]-1 ][l] / Energy.Matrix[Energy.MatrixCounter][ Energy.RowCounter[Energy.MatrixCounter]-1 ][l]);
155 output << endl;
156 }
157 output.close();
158 return true;
159};
160
161/** Plot forces vs. order.
162 * \param &Fragments ForceMatrix class containing matrix values
163 * \param KeySets KeySetContainer class holding bond KeySetContainer::Order
164 * \param *prefix prefix in filename (without ending)
165 * \param *msg message to be place in first line as a comment
166 * \param *datum current date and time
167 * \return true if file was written successfully
168 */
169bool CreateDataForcesOrder(class ForceMatrix &Fragments, class KeySetsContainer &KeySets, const char *dir, const char *prefix,const char *msg, const char *datum, void (*CreateForce)(class MatrixContainer &, int))
170{
171 stringstream filename;
172 ofstream output;
173
174 filename << prefix << ".dat";
175 if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
176 LOG(0, msg);
177 output << "# " << msg << ", created on " << datum;
178 output << "# Order\tFrag.No.\t" << Fragments.Header[Fragments.MatrixCounter] << endl;
179 Fragments.SetLastMatrix(0.,0);
180 for (int BondOrder=0;BondOrder<KeySets.Order;BondOrder++) {
181 Fragments.SumSubForces(Fragments, KeySets, BondOrder, 1.);
182 output << BondOrder+1 << "\t" << KeySets.FragmentsPerOrder[BondOrder];
183 CreateForce(Fragments, Fragments.MatrixCounter);
184 for (int l=0;l<Fragments.ColumnCounter[Fragments.MatrixCounter];l++)
185 output << scientific << "\t" << Fragments.Matrix[Fragments.MatrixCounter][ Fragments.RowCounter[Fragments.MatrixCounter] ][l];
186 output << endl;
187 }
188 output.close();
189 return true;
190};
191
192/** Plot forces error vs. order.
193 * \param &Force ForceMatrix containing reference values (in MatrixCounter matrix)
194 * \param &Fragments ForceMatrix class containing matrix values
195 * \param KeySets KeySetContainer class holding bond KeySetContainer::Order
196 * \param *prefix prefix in filename (without ending)
197 * \param *msg message to be place in first line as a comment
198 * \param *datum current date and time
199 * \return true if file was written successfully
200 */
201bool CreateDataDeltaForcesOrder(class ForceMatrix &Force, class ForceMatrix &Fragments, class KeySetsContainer &KeySets, const char *dir, const char *prefix, const char *msg, const char *datum, void (*CreateForce)(class MatrixContainer &, int))
202{
203 stringstream filename;
204 ofstream output;
205
206 filename << prefix << ".dat";
207 if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
208 LOG(0, msg);
209 output << "# " << msg << ", created on " << datum;
210 output << "# Order\tFrag.No.\t" << Fragments.Header[Fragments.MatrixCounter] << endl;
211 Fragments.SetLastMatrix(Force.Matrix[Force.MatrixCounter],0);
212 for (int BondOrder=0;BondOrder<KeySets.Order;BondOrder++) {
213 Fragments.SumSubForces(Fragments, KeySets, BondOrder, -1.);
214 output << BondOrder+1 << "\t" << KeySets.FragmentsPerOrder[BondOrder];
215 CreateForce(Fragments, Fragments.MatrixCounter);
216 for (int l=0;l<Fragments.ColumnCounter[Fragments.MatrixCounter];l++)
217 output << scientific << "\t" << Fragments.Matrix[Fragments.MatrixCounter][ Fragments.RowCounter[Fragments.MatrixCounter] ][l];
218 output << endl;
219 }
220 output.close();
221 return true;
222};
223
224/** Plot forces error vs. vs atom vs. order.
225 * \param &Force ForceMatrix containing reference values (in MatrixCounter matrix)
226 * \param &Fragments ForceMatrix class containing matrix values
227 * \param KeySets KeySetContainer class holding bond KeySetContainer::Order
228 * \param *prefix prefix in filename (without ending)
229 * \param *msg message to be place in first line as a comment
230 * \param *datum current date and time
231 * \return true if file was written successfully
232 */
233bool CreateDataDeltaForcesOrderPerAtom(class ForceMatrix &Force, class ForceMatrix &Fragments, class KeySetsContainer &KeySets, const char *dir, const char *prefix, const char *msg, const char *datum)
234{
235 stringstream filename;
236 ofstream output;
237 double norm = 0.;
238
239 filename << prefix << ".dat";
240 if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
241 LOG(0, msg);
242 output << "# " << msg << ", created on " << datum;
243 output << "# AtomNo\t" << Fragments.Header[Fragments.MatrixCounter] << endl;
244 Fragments.SetLastMatrix(Force.Matrix[Force.MatrixCounter], 0);
245 for (int BondOrder=0;BondOrder<KeySets.Order;BondOrder++) {
246 //LOG(0, "Current order is " << BondOrder << ".");
247 Fragments.SumSubForces(Fragments, KeySets, BondOrder, -1.);
248 // errors per atom
249 output << endl << "#Order\t" << BondOrder+1 << endl;
250 for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) {
251 output << Fragments.Indices[Fragments.MatrixCounter][j] << "\t";
252 for (int l=0;l<Fragments.ColumnCounter[ Fragments.MatrixCounter ];l++) {
253 if (((l+1) % 3) == 0) {
254 norm = 0.;
255 for (int m=0;m<NDIM;m++)
256 norm += Force.Matrix[Force.MatrixCounter][ j ][l+m]*Force.Matrix[Force.MatrixCounter][ j ][l+m];
257 norm = sqrt(norm);
258 }
259// if (norm < MYEPSILON)
260 output << scientific << Fragments.Matrix[Fragments.MatrixCounter][ j ][l] << "\t";
261// else
262// output << scientific << (Fragments.Matrix[Fragments.MatrixCounter][ j ][l] / norm) << "\t";
263 }
264 output << endl;
265 }
266 output << endl;
267 }
268 output.close();
269 return true;
270};
271
272/** Plot forces error vs. vs atom vs. order.
273 * \param &Fragments ForceMatrix class containing matrix values
274 * \param KeySets KeySetContainer class holding bond KeySetContainer::Order
275 * \param *prefix prefix in filename (without ending)
276 * \param *msg message to be place in first line as a comment
277 * \param *datum current date and time
278 * \return true if file was written successfully
279 */
280bool CreateDataForcesOrderPerAtom(class ForceMatrix &Fragments, class KeySetsContainer &KeySets, const char *dir, const char *prefix, const char *msg, const char *datum)
281{
282 stringstream filename;
283 ofstream output;
284
285 filename << prefix << ".dat";
286 if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
287 LOG(0, msg);
288 output << "# " << msg << ", created on " << datum;
289 output << "# AtomNo\t" << Fragments.Header[Fragments.MatrixCounter] << endl;
290 for (int BondOrder=0;BondOrder<KeySets.Order;BondOrder++) {
291 //LOG(0, "Current order is " << BondOrder << ".");
292 Fragments.SumSubForces(Fragments, KeySets, BondOrder, 1.);
293 // errors per atom
294 output << endl << "#Order\t" << BondOrder+1 << endl;
295 for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) {
296 output << Fragments.Indices[Fragments.MatrixCounter][j] << "\t";
297 for (int l=0;l<Fragments.ColumnCounter[ Fragments.MatrixCounter ];l++)
298 output << scientific << Fragments.Matrix[Fragments.MatrixCounter][ j ][l] << "\t";
299 output << endl;
300 }
301 output << endl;
302 }
303 output.close();
304 return true;
305};
306
307
308/** Plot hessian error vs. vs atom vs. order.
309 * \param &Hessian HessianMatrix containing reference values (in MatrixCounter matrix)
310 * \param &Fragments HessianMatrix class containing matrix values
311 * \param KeySets KeySetContainer class holding bond KeySetContainer::Order
312 * \param *prefix prefix in filename (without ending)
313 * \param *msg message to be place in first line as a comment
314 * \param *datum current date and time
315 * \return true if file was written successfully
316 */
317bool CreateDataDeltaHessianOrderPerAtom(class HessianMatrix &Hessian, class HessianMatrix &Fragments, class KeySetsContainer &KeySets, const char *dir, const char *prefix, const char *msg, const char *datum)
318{
319 stringstream filename;
320 ofstream output;
321
322 filename << prefix << ".dat";
323 if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
324 LOG(0, msg);
325 output << "# " << msg << ", created on " << datum;
326 output << "# AtomNo\t" << Fragments.Header[Fragments.MatrixCounter] << endl;
327 Fragments.SetLastMatrix(Hessian.Matrix[Hessian.MatrixCounter], 0);
328 for (int BondOrder=0;BondOrder<KeySets.Order;BondOrder++) {
329 //LOG(0, "Current order is " << BondOrder << ".");
330 Fragments.SumSubHessians(Fragments, KeySets, BondOrder, -1.);
331 // errors per atom
332 output << endl << "#Order\t" << BondOrder+1 << endl;
333 for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) {
334 output << Fragments.Indices[Fragments.MatrixCounter][j] << "\t";
335 for (int l=0;l<Fragments.ColumnCounter[ Fragments.MatrixCounter ];l++) {
336 output << scientific << Fragments.Matrix[Fragments.MatrixCounter][ j ][l] << "\t";
337 }
338 output << endl;
339 }
340 output << endl;
341 }
342 output.close();
343 return true;
344};
345
346/** Plot hessian error vs. vs atom vs. order in the frobenius norm.
347 * \param &Hessian HessianMatrix containing reference values (in MatrixCounter matrix)
348 * \param &Fragments HessianMatrix class containing matrix values
349 * \param KeySets KeySetContainer class holding bond KeySetContainer::Order
350 * \param *prefix prefix in filename (without ending)
351 * \param *msg message to be place in first line as a comment
352 * \param *datum current date and time
353 * \return true if file was written successfully
354 */
355bool CreateDataDeltaFrobeniusOrderPerAtom(class HessianMatrix &Hessian, class HessianMatrix &Fragments, class KeySetsContainer &KeySets, const char *dir, const char *prefix, const char *msg, const char *datum)
356{
357 stringstream filename;
358 ofstream output;
359 double norm = 0;
360 double tmp;
361
362 filename << prefix << ".dat";
363 if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
364 LOG(0, msg);
365 output << "# " << msg << ", created on " << datum;
366 output << "# AtomNo\t";
367 Fragments.SetLastMatrix(Hessian.Matrix[Hessian.MatrixCounter], 0);
368 for (int BondOrder=0;BondOrder<KeySets.Order;BondOrder++) {
369 output << "Order" << BondOrder+1 << "\t";
370 }
371 output << endl;
372 output << Fragments.RowCounter[ Fragments.MatrixCounter ] << "\t";
373 for (int BondOrder=0;BondOrder<KeySets.Order;BondOrder++) {
374 //LOG(0, "Current order is " << BondOrder << ".");
375 Fragments.SumSubHessians(Fragments, KeySets, BondOrder, -1.);
376 // frobenius norm of errors per atom
377 norm = 0.;
378 for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) {
379 for (int l=0;l<Fragments.ColumnCounter[ Fragments.MatrixCounter ];l++) {
380 tmp = Fragments.Matrix[Fragments.MatrixCounter][ j ][l];
381 norm += tmp*tmp;
382 }
383 }
384 output << scientific << sqrt(norm)/(Fragments.RowCounter[ Fragments.MatrixCounter ]*Fragments.ColumnCounter[ Fragments.MatrixCounter] ) << "\t";
385 }
386 output << endl;
387 output.close();
388 return true;
389};
390
391/** Plot hessian error vs. vs atom vs. order.
392 * \param &Fragments HessianMatrix class containing matrix values
393 * \param KeySets KeySetContainer class holding bond KeySetContainer::Order
394 * \param *prefix prefix in filename (without ending)
395 * \param *msg message to be place in first line as a comment
396 * \param *datum current date and time
397 * \return true if file was written successfully
398 */
399bool CreateDataHessianOrderPerAtom(class HessianMatrix &Fragments, class KeySetsContainer &KeySets, const char *dir, const char *prefix, const char *msg, const char *datum)
400{
401 stringstream filename;
402 ofstream output;
403
404 filename << prefix << ".dat";
405 if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
406 LOG(0, msg);
407 output << "# " << msg << ", created on " << datum;
408 output << "# AtomNo\t" << Fragments.Header[ Fragments.MatrixCounter ] << endl;
409 Fragments.SetLastMatrix(0., 0);
410 for (int BondOrder=0;BondOrder<KeySets.Order;BondOrder++) {
411 //LOG(0, "Current order is " << BondOrder << ".");
412 Fragments.SumSubHessians(Fragments, KeySets, BondOrder, 1.);
413 // errors per atom
414 output << endl << "#Order\t" << BondOrder+1 << endl;
415 for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) {
416 output << Fragments.Indices[Fragments.MatrixCounter][j] << "\t";
417 for (int l=0;l<Fragments.ColumnCounter[ Fragments.MatrixCounter ];l++)
418 output << scientific << Fragments.Matrix[Fragments.MatrixCounter][ j ][l] << "\t";
419 output << endl;
420 }
421 output << endl;
422 }
423 output.close();
424 return true;
425};
426
427/** Plot matrix vs. fragment.
428 */
429bool CreateDataFragment(class MatrixContainer &Fragment, class KeySetsContainer &KeySets, const char *dir, const char *prefix, const char *msg, const char *datum, void (*CreateFragment)(class MatrixContainer &, int))
430{
431 stringstream filename;
432 ofstream output;
433
434 filename << prefix << ".dat";
435 if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
436 LOG(0, msg);
437 output << "# " << msg << ", created on " << datum << endl;
438 output << "#Order\tFrag.No.\t" << Fragment.Header[ Fragment.MatrixCounter ] << endl;
439 for (int BondOrder=0;BondOrder<KeySets.Order;BondOrder++) {
440 for(int i=0;i<KeySets.FragmentsPerOrder[BondOrder];i++) {
441 output << BondOrder+1 << "\t" << KeySets.OrderSet[BondOrder][i]+1;
442 CreateFragment(Fragment, KeySets.OrderSet[BondOrder][i]);
443 for (int l=0;l<Fragment.ColumnCounter[ KeySets.OrderSet[BondOrder][i] ];l++)
444 output << scientific << "\t" << Fragment.Matrix[ KeySets.OrderSet[BondOrder][i] ][ Fragment.RowCounter[ KeySets.OrderSet[BondOrder][i] ] ][l];
445 output << endl;
446 }
447 }
448 output.close();
449 return true;
450};
451
452/** Copies fragment energy values into last matrix of \a Matrix with greatest total energy.
453 * \param &Matrix MatrixContainer with all fragment energy values
454 * \param &KeySets KeySetsContainer with associations of each fragment to a bond order
455 * \param BondOrder current bond order
456 */
457void CreateMaxFragmentOrder(class MatrixContainer &Fragments, class KeySetsContainer &KeySets, int BondOrder)
458{
459 for(int j=Fragments.RowCounter[ Fragments.MatrixCounter ];j--;) {
460 for(int i=KeySets.FragmentsPerOrder[BondOrder];i--;) {
461 if (fabs(Fragments.Matrix[ Fragments.MatrixCounter ][j][1]) < fabs(Fragments.Matrix[ KeySets.OrderSet[BondOrder][i] ][j][1])) {
462 for (int k=Fragments.ColumnCounter[ Fragments.MatrixCounter ];k--;)
463 Fragments.Matrix[ Fragments.MatrixCounter ][j][k] = Fragments.Matrix[ KeySets.OrderSet[BondOrder][i] ][j][k];
464 }
465 }
466 }
467};
468
469/** Copies fragment energy values into last matrix of \a Matrix with smallest total energy.
470 * \param &Matrix MatrixContainer with all fragment energy values
471 * \param &KeySets KeySetsContainer with associations of each fragment to a bond order
472 * \param BondOrder current bond order
473 */
474void CreateMinFragmentOrder(class MatrixContainer &Fragments, class KeySetsContainer &KeySets, int BondOrder)
475{
476 for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) {
477 int i=0;
478 do { // first get a minimum value unequal to 0
479 for (int k=Fragments.ColumnCounter[ Fragments.MatrixCounter ];k--;)
480 Fragments.Matrix[ Fragments.MatrixCounter ][j][k] = Fragments.Matrix[ KeySets.OrderSet[BondOrder][i] ][j][k];
481 i++;
482 } while ((fabs(Fragments.Matrix[ Fragments.MatrixCounter ][j][1]) < MYEPSILON) && (i<KeySets.FragmentsPerOrder[BondOrder]));
483 for(;i<KeySets.FragmentsPerOrder[BondOrder];i++) { // then find lowest
484 if (fabs(Fragments.Matrix[ Fragments.MatrixCounter ][j][1]) > fabs(Fragments.Matrix[ KeySets.OrderSet[BondOrder][i] ][j][1])) {
485 for (int k=Fragments.ColumnCounter[ Fragments.MatrixCounter ];k--;)
486 Fragments.Matrix[ Fragments.MatrixCounter ][j][k] = Fragments.Matrix[ KeySets.OrderSet[BondOrder][i] ][j][k];
487 }
488 }
489 }
490};
491
492/** Plot matrix vs. fragment.
493 */
494bool CreateDataFragmentOrder(class MatrixContainer &Fragment, class KeySetsContainer &KeySets, const char *dir, const char *prefix, const char *msg, const char *datum, void (*CreateFragmentOrder)(class MatrixContainer &, class KeySetsContainer &, int))
495{
496 stringstream filename;
497 ofstream output;
498
499 filename << prefix << ".dat";
500 if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
501 LOG(0, msg);
502 output << "# " << msg << ", created on " << datum;
503 output << "#Order\tFrag.No.\t" << Fragment.Header[ Fragment.MatrixCounter ] << endl;
504 // max
505 for (int BondOrder=0;BondOrder<KeySets.Order;BondOrder++) {
506 Fragment.SetLastMatrix(0.,0);
507 CreateFragmentOrder(Fragment, KeySets, BondOrder);
508 output << BondOrder+1 << "\t" << KeySets.FragmentsPerOrder[BondOrder];
509 for (int l=0;l<Fragment.ColumnCounter[ Fragment.MatrixCounter ];l++)
510 output << scientific << "\t" << Fragment.Matrix[ Fragment.MatrixCounter ][ Fragment.RowCounter[ Fragment.MatrixCounter ]-1 ][l];
511 output << endl;
512 }
513 output.close();
514 return true;
515};
516
517/** Takes last but one row and copies into final row.
518 * \param Energy MatrixContainer with matrix values
519 * \param MatrixNumber the index for the ForceMatrix::matrix array
520 */
521void CreateEnergy(class MatrixContainer &Energy, int MatrixNumber)
522{
523 for(int k=0;k<Energy.ColumnCounter[MatrixNumber];k++)
524 Energy.Matrix[MatrixNumber][ Energy.RowCounter[MatrixNumber] ] [k] = Energy.Matrix[MatrixNumber][ Energy.RowCounter[MatrixNumber]-1 ] [k];
525};
526
527/** Scans forces for the minimum in magnitude.
528 * Results are stored in the matrix ForceMatrix::MatrixCounter of \a Force.
529 * \param Force ForceMatrix class containing matrix values
530 * \param MatrixNumber the index for the ForceMatrix::matrix array
531 */
532void CreateMinimumForce(class MatrixContainer &Force, int MatrixNumber)
533{
534 for (int l=Force.ColumnCounter[MatrixNumber];l--;)
535 Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l] = 0.;
536 for (int l=5;l<Force.ColumnCounter[MatrixNumber];l+=3) {
537 double stored = 0;
538 int k=0;
539 do {
540 for (int m=NDIM;m--;) {
541 stored += Force.Matrix[MatrixNumber][ k ][l+m]
542 * Force.Matrix[MatrixNumber][ k ][l+m];
543 Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l+m] = Force.Matrix[MatrixNumber][ k ][l+m];
544 }
545 k++;
546 } while ((fabs(stored) < MYEPSILON) && (k<Force.RowCounter[MatrixNumber]));
547 for (;k<Force.RowCounter[MatrixNumber];k++) {
548 double tmp = 0;
549 for (int m=NDIM;m--;)
550 tmp += Force.Matrix[MatrixNumber][ k ][l+m]
551 * Force.Matrix[MatrixNumber][ k ][l+m];
552 if ((fabs(tmp) > MYEPSILON) && (tmp < stored)) { // current force is greater than stored
553 for (int m=NDIM;m--;)
554 Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l+m] = Force.Matrix[MatrixNumber][ k ][l+m];
555 stored = tmp;
556 }
557 }
558 }
559};
560
561/** Scans forces for the mean in magnitude.
562 * Results are stored in the matrix ForceMatrix::MatrixCounter of \a Force.
563 * \param Force ForceMatrix class containing matrix values
564 * \param MatrixNumber the index for the ForceMatrix::matrix array
565 */
566void CreateMeanForce(class MatrixContainer &Force, int MatrixNumber)
567{
568 int divisor = 0;
569 for (int l=Force.ColumnCounter[MatrixNumber];l--;)
570 Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l] = 0.;
571 for (int l=5;l<Force.ColumnCounter[MatrixNumber];l+=3) {
572 double tmp = 0;
573 for (int k=Force.RowCounter[MatrixNumber];k--;) {
574 double norm = 0.;
575 for (int m=NDIM;m--;)
576 norm += Force.Matrix[MatrixNumber][ k ][l+m]
577 * Force.Matrix[MatrixNumber][ k ][l+m];
578 tmp += sqrt(norm);
579 if (fabs(norm) > MYEPSILON) divisor++;
580 }
581 tmp /= (double)divisor;
582 Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l] = tmp;
583 }
584};
585
586/** Scans forces for the maximum in magnitude.
587 * Results are stored in the matrix ForceMatrix::MatrixCounter of \a Force.
588 * \param Force ForceMatrix class containing matrix values
589 * \param MatrixNumber the index for the ForceMatrix::matrix array
590 */
591void CreateMaximumForce(class MatrixContainer &Force, int MatrixNumber)
592{
593 for (int l=5;l<Force.ColumnCounter[MatrixNumber];l+=3) {
594 double stored = 0;
595 for (int k=Force.RowCounter[MatrixNumber];k--;) {
596 double tmp = 0;
597 for (int m=NDIM;m--;)
598 tmp += Force.Matrix[MatrixNumber][ k ][l+m]
599 * Force.Matrix[MatrixNumber][ k ][l+m];
600 if (tmp > stored) { // current force is greater than stored
601 for (int m=NDIM;m--;)
602 Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l+m] = Force.Matrix[MatrixNumber][ k ][l+m];
603 stored = tmp;
604 }
605 }
606 }
607};
608
609/** Leaves the Force.Matrix as it is.
610 * \param Force ForceMatrix class containing matrix values
611 * \param MatrixNumber the index for the ForceMatrix::matrix array
612*/
613void CreateSameForce(class MatrixContainer &Force, int MatrixNumber)
614{
615 // does nothing
616};
617
618/** Adds vectorwise all forces.
619 * Results are stored in the matrix ForceMatrix::MatrixCounter of \a Force.
620 * \param Force ForceMatrix class containing matrix values
621 * \param MatrixNumber the index for the ForceMatrix::matrix array
622 */
623void CreateVectorSumForce(class MatrixContainer &Force, int MatrixNumber)
624{
625 for (int l=Force.ColumnCounter[MatrixNumber];l--;)
626 Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l] = 0.;
627 for (int l=0;l<Force.ColumnCounter[MatrixNumber];l++) {
628 for (int k=Force.RowCounter[MatrixNumber];k--;)
629 Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l] += Force.Matrix[MatrixNumber][k][l];
630 }
631};
632
633/** Writes the standard pyxplot header info.
634 * \param keycolumns number of columns of the key
635 * \param *key position of key
636 * \param *logscale axis for logscale
637 * \param *extraline extra set lines if desired
638 * \param mxtics small tics at ...
639 * \param xtics large tics at ...
640 * \param *xlabel label for x axis
641 * \param *ylabel label for y axis
642 */
643void CreatePlotHeader(ofstream &output, const char *prefix, const int keycolumns, const char *key, const char *logscale, const char *extraline, const int mxtics, const int xtics, const char *xlabel, const char *ylabel)
644{
645 //output << "#!/home/heber/build/pyxplot/pyxplot" << endl << endl;
646 output << "reset" << endl;
647 output << "set keycolumns "<< keycolumns << endl;
648 output << "set key " << key << endl;
649 output << "set mxtics "<< mxtics << endl;
650 output << "set xtics "<< xtics << endl;
651 if (logscale != NULL)
652 output << "set logscale " << logscale << endl;
653 if (extraline != NULL)
654 output << extraline << endl;
655 output << "set xlabel '" << xlabel << "'" << endl;
656 output << "set ylabel '" << ylabel << "'" << endl;
657 output << "set terminal eps color" << endl;
658 output << "set output '"<< prefix << ".eps'" << endl;
659};
660
661/** Creates the pyxplotfile for energy data.
662 * \param Matrix MatrixContainer with matrix values
663 * \param KeySets contains bond order
664 * \param *dir directory
665 * \param *prefix prefix for all filenames (without ending)
666 * \param keycolumns number of columns of the key
667 * \param *key position of key
668 * \param logscale axis for logscale
669 * \param mxtics small tics at ...
670 * \param xtics large tics at ...
671 * \param xlabel label for x axis
672 * \param xlabel label for x axis
673 * \param *xrange xrange
674 * \param *yrange yrange
675 * \param *xargument number of column to plot against (x axis)
676 * \param uses using string for plot command
677 * \param (*CreatePlotLines) function reference that writes a single plot line
678 * \return true if file was written successfully
679 */
680bool CreatePlotOrder(class MatrixContainer &Matrix, const class KeySetsContainer &KeySets, const char *dir, const char *prefix, const int keycolumns, const char *key, const char *logscale, const char *extraline, const int mxtics, const int xtics, const char *xlabel, const char *ylabel, const char *xrange, const char *yrange, const char *xargument, const char *uses, void (*CreatePlotLines)(ofstream &, class MatrixContainer &, const char *, const char *, const char *))
681{
682 stringstream filename;
683 ofstream output;
684
685 filename << prefix << ".pyx";
686 if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
687 CreatePlotHeader(output, prefix, keycolumns, key, logscale, extraline, mxtics, xtics, xlabel, ylabel);
688 output << "plot " << xrange << " " << yrange << " \\" << endl;
689 CreatePlotLines(output, Matrix, prefix, xargument, uses);
690 output.close();
691 return true;
692};
693
694/** Writes plot lines for absolute energies.
695 * \param output file handler
696 * \param Energy MatrixContainer with matrix values
697 * \param *prefix prefix of data file
698 * \param *xargument number of column to plot against (x axis)
699 * \param *uses uses command
700 */
701void AbsEnergyPlotLine(ofstream &output, class MatrixContainer &Energy, const char *prefix, const char *xargument, const char *uses)
702{
703 stringstream line(Energy.Header[ Energy.MatrixCounter ]);
704 string token;
705
706 getline(line, token, '\t');
707 for (int i=2; i<= Energy.ColumnCounter[Energy.MatrixCounter];i++) {
708 getline(line, token, '\t');
709 while (token[0] == ' ') // remove leading white spaces
710 token.erase(0,1);
711 output << "'" << prefix << ".dat' title '" << token << "' using " << xargument << ":(abs($" << i+2 << ")) " << uses;
712 if (i != (Energy.ColumnCounter[Energy.MatrixCounter]))
713 output << ", \\";
714 output << endl;
715 }
716};
717
718/** Writes plot lines for energies.
719 * \param output file handler
720 * \param Energy MatrixContainer with matrix values
721 * \param *prefix prefix of data file
722 * \param *xargument number of column to plot against (x axis)
723 * \param *uses uses command
724 */
725void EnergyPlotLine(ofstream &output, class MatrixContainer &Energy, const char *prefix, const char *xargument, const char *uses)
726{
727 stringstream line(Energy.Header[Energy.MatrixCounter]);
728 string token;
729
730 getline(line, token, '\t');
731 for (int i=1; i<= Energy.ColumnCounter[Energy.MatrixCounter];i++) {
732 getline(line, token, '\t');
733 while (token[0] == ' ') // remove leading white spaces
734 token.erase(0,1);
735 output << "'" << prefix << ".dat' title '" << token << "' using " << xargument << ":" << i+2 << " " << uses;
736 if (i != (Energy.ColumnCounter[Energy.MatrixCounter]))
737 output << ", \\";
738 output << endl;
739 }
740};
741
742/** Writes plot lines for absolute force magnitudes.
743 * \param output file handler
744 * \param Force MatrixContainer with matrix values
745 * \param *prefix prefix of data file
746 * \param *xargument number of column to plot against (x axis)
747 * \param *uses uses command
748 */
749void ForceMagnitudePlotLine(ofstream &output, class MatrixContainer &Force, const char *prefix, const char *xargument, const char *uses)
750{
751 stringstream line(Force.Header[Force.MatrixCounter]);
752 string token;
753
754 getline(line, token, '\t');
755 getline(line, token, '\t');
756 getline(line, token, '\t');
757 getline(line, token, '\t');
758 getline(line, token, '\t');
759 for (int i=7; i< Force.ColumnCounter[Force.MatrixCounter];i+=NDIM) {
760 getline(line, token, '\t');
761 while (token[0] == ' ') // remove leading white spaces
762 token.erase(0,1);
763 token.erase(token.length(), 1); // kill residual index char (the '0')
764 output << "'" << prefix << ".dat' title '" << token << "' using " << xargument << ":(sqrt($" << i+1 << "*$" << i+1 << "+$" << i+2 << "*$" << i+2 << "+$" << i+3 << "*$" << i+3 << ")) " << uses;
765 if (i != (Force.ColumnCounter[Force.MatrixCounter]-1))
766 output << ", \\";
767 output << endl;
768 getline(line, token, '\t');
769 getline(line, token, '\t');
770 }
771};
772
773/** Writes plot lines for first component of force vector.
774 * \param output file handler
775 * \param Force MatrixContainer with matrix values
776 * \param *prefix prefix of data file
777 * \param *xargument number of column to plot against (x axis)
778 * \param *uses uses command
779 */
780void AbsFirstForceValuePlotLine(ofstream &output, class MatrixContainer &Force, const char *prefix, const char *xargument, const char *uses)
781{
782 stringstream line(Force.Header[Force.MatrixCounter]);
783 string token;
784
785 getline(line, token, '\t');
786 getline(line, token, '\t');
787 getline(line, token, '\t');
788 getline(line, token, '\t');
789 getline(line, token, '\t');
790 for (int i=7; i< Force.ColumnCounter[Force.MatrixCounter];i+=NDIM) {
791 getline(line, token, '\t');
792 while (token[0] == ' ') // remove leading white spaces
793 token.erase(0,1);
794 token.erase(token.length(), 1); // kill residual index char (the '0')
795 output << "'" << prefix << ".dat' title '" << token << "' using " << xargument << ":(abs($" << i+1 << ")) " << uses;
796 if (i != (Force.ColumnCounter[Force.MatrixCounter]-1))
797 output << ", \\";
798 output << endl;
799 getline(line, token, '\t');
800 getline(line, token, '\t');
801 }
802};
803
804/** Writes plot lines for force vector as boxes with a fillcolor.
805 * \param output file handler
806 * \param Force MatrixContainer with matrix values
807 * \param *prefix prefix of data file
808 * \param *xargument number of column to plot against (x axis)
809 * \param *uses uses command
810 */
811void BoxesForcePlotLine(ofstream &output, class MatrixContainer &Force, const char *prefix, const char *xargument, const char *uses)
812{
813 stringstream line(Force.Header[Force.MatrixCounter]);
814 const char *fillcolor[5] = {"black", "red", "blue", "green", "cyan"};
815 string token;
816
817 getline(line, token, '\t');
818 getline(line, token, '\t');
819 getline(line, token, '\t');
820 getline(line, token, '\t');
821 getline(line, token, '\t');
822 for (int i=7; i< Force.ColumnCounter[Force.MatrixCounter];i+=NDIM) {
823 getline(line, token, '\t');
824 while (token[0] == ' ') // remove leading white spaces
825 token.erase(0,1);
826 token.erase(token.length(), 1); // kill residual index char (the '0')
827 output << "'" << prefix << ".dat' title '" << token << "' using ($" << xargument << "+" << fixed << setprecision(1) << (double)((i-7)/3)*0.2 << "):(sqrt($" << i+1 << "*$" << i+1 << "+$" << i+2 << "*$" << i+2 << "+$" << i+3 << "*$" << i+3 << ")) " << uses << " " << fillcolor[(i-7)/3];
828 if (i != (Force.ColumnCounter[Force.MatrixCounter]-1))
829 output << ", \\";
830 output << endl;
831 getline(line, token, '\t');
832 getline(line, token, '\t');
833 }
834};
835
836/** Writes plot lines for first force vector component as boxes with a fillcolor.
837 * \param output file handler
838 * \param Force MatrixContainer with matrix values
839 * \param *prefix prefix of data file
840 * \param *xargument number of column to plot against (x axis)
841 * \param *uses uses command
842 */
843void BoxesFirstForceValuePlotLine(ofstream &output, class MatrixContainer &Force, const char *prefix, const char *xargument, const char *uses)
844{
845 stringstream line(Force.Header[Force.MatrixCounter]);
846 const char *fillcolor[5] = {"black", "red", "blue", "green", "cyan"};
847 string token;
848
849 getline(line, token, '\t');
850 getline(line, token, '\t');
851 getline(line, token, '\t');
852 getline(line, token, '\t');
853 getline(line, token, '\t');
854 for (int i=7; i< Force.ColumnCounter[Force.MatrixCounter];i+=NDIM) {
855 getline(line, token, '\t');
856 while (token[0] == ' ') // remove leading white spaces
857 token.erase(0,1);
858 token.erase(token.length(), 1); // kill residual index char (the '0')
859 output << "'" << prefix << ".dat' title '" << token << "' using ($" << xargument << "+" << fixed << setprecision(1) << (double)((i-7)/3)*0.2 << "):" << i+1 << " " << uses << " " << fillcolor[(i-7)/3];
860 if (i != (Force.ColumnCounter[Force.MatrixCounter]-1))
861 output << ", \\";
862 output << endl;
863 getline(line, token, '\t');
864 getline(line, token, '\t');
865 }
866};
Note: See TracBrowser for help on using the repository browser.