source: molecuilder/src/datacreator.cpp@ 25e17e9

Last change on this file since 25e17e9 was 075729, checked in by Frederik Heber <heber@…>, 15 years ago

Merge branch 'Analysis_PairCorrelation' into StructureRefactoring

Conflicts:

molecuilder/src/Makefile.am
molecuilder/src/World.cpp
molecuilder/src/World.hpp
molecuilder/src/boundary.cpp
molecuilder/src/builder.cpp
molecuilder/src/log.cpp
molecuilder/src/moleculelist.cpp
molecuilder/src/periodentafel.cpp
molecuilder/src/tesselation.cpp
molecuilder/src/unittests/AnalysisCorrelationToSurfaceUnitTest.cpp
molecuilder/src/unittests/Makefile.am
molecuilder/src/unittests/bondgraphunittest.cpp
molecuilder/src/unittests/gslvectorunittest.cpp
molecuilder/src/unittests/logunittest.cpp
molecuilder/src/unittests/tesselation_boundarytriangleunittest.hpp
molecuilder/src/vector.cpp
molecuilder/tests/Tesselations/defs.in

Conflicts have been many and too numerous to listen here, just the few general cases

  • new molecule() replaced by World::getInstance().createMolecule()
  • new atom() replaced by World::getInstance().createAtom() where appropriate.
  • Some DoLog()s added interfered with changes to the message produced by Log() << Verbose(.) << ...
  • DoLog() has been erroneously added to TestRunner.cpp as well, there cout is appropriate
  • ...

Additionally, there was a bug in atom::clone(), sort was set to atom::nr of the atom to clone not of the clone itself. This caused a failure of the fragmentation.

This merge has been fully checked from a clean build directory with subsequent configure,make all install and make check.
It configures, compiles and runs all test cases and the test suite without errors.

Signed-off-by: Frederik Heber <heber@…>

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