source: src/Fragmentation/datacreator.cpp@ aec098

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 aec098 was 0aa122, checked in by Frederik Heber <heber@…>, 13 years ago

Updated all source files's copyright note to current year 2012.

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