Changeset 36ec71


Ignore:
Timestamp:
Jul 24, 2009, 10:38:32 AM (16 years ago)
Author:
Frederik Heber <heber@…>
Branches:
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
Children:
d30402
Parents:
042f82 (diff), 51c910 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
git-author:
Frederik Heber <heber@…> (07/23/09 14:23:32)
git-committer:
Frederik Heber <heber@…> (07/24/09 10:38:32)
Message:

Merge branch 'master' into ConcaveHull

Conflicts:

molecuilder/src/analyzer.cpp
molecuilder/src/bond.cpp
molecuilder/src/boundary.cpp
molecuilder/src/boundary.hpp
molecuilder/src/builder.cpp
molecuilder/src/config.cpp
molecuilder/src/datacreator.cpp
molecuilder/src/datacreator.hpp
molecuilder/src/defs.hpp
molecuilder/src/ellipsoid.cpp
molecuilder/src/joiner.cpp
molecuilder/src/molecules.cpp
molecuilder/src/molecules.hpp
molecuilder/src/parser.cpp
molecuilder/src/parser.hpp

merges:

compilation fixes:

Location:
src
Files:
1 added
17 edited

Legend:

Unmodified
Added
Removed
  • src/Makefile.am

    r042f82 r36ec71  
    1010
    1111
    12 #EXTRA_DIST = ${molecuilder_DATA}
     12EXTRA_DIST = ${molecuilder_DATA}
  • src/analyzer.cpp

    r042f82 r36ec71  
    2525  periodentafel *periode = NULL; // and a period table of all elements
    2626  EnergyMatrix Energy;
     27  EnergyMatrix EnergyFragments;
     28  ForceMatrix Force;
     29  ForceMatrix ForceFragments;
     30  HessianMatrix Hessian;
     31  HessianMatrix HessianFragments;
    2732  EnergyMatrix Hcorrection;
    28   ForceMatrix Force;
     33  EnergyMatrix HcorrectionFragments;
    2934  ForceMatrix Shielding;
    3035  ForceMatrix ShieldingPAS;
     36  ForceMatrix Chi;
     37  ForceMatrix ChiPAS;
    3138  EnergyMatrix Time;
    32   EnergyMatrix EnergyFragments;
    33   EnergyMatrix HcorrectionFragments;
    34   ForceMatrix ForceFragments;
    3539  ForceMatrix ShieldingFragments;
    3640  ForceMatrix ShieldingPASFragments;
     41  ForceMatrix ChiFragments;
     42  ForceMatrix ChiPASFragments;
    3743  KeySetsContainer KeySet;
    3844  ofstream output;
     
    4955  stringstream yrange;
    5056  char *dir = NULL;
    51   bool Hcorrected = true;
     57  bool NoHessian = false;
     58  bool NoTime = false;
     59  bool NoHCorrection = true;
    5260  int counter;
    5361
     
    8391  // ------------- Parse through all Fragment subdirs --------
    8492  if (!Energy.ParseFragmentMatrix(argv[1], dir, EnergySuffix,0,0)) return 1;
    85   Hcorrected = Hcorrection.ParseFragmentMatrix(argv[1], "", HCORRECTIONSUFFIX,0,0);
     93  if (!Hcorrection.ParseFragmentMatrix(argv[1], "", HCORRECTIONSUFFIX,0,0)) {
     94    NoHCorrection = true;
     95    cout << "No HCorrection file found, skipping these." << endl;
     96  }
     97 
    8698  if (!Force.ParseFragmentMatrix(argv[1], dir, ForcesSuffix,0,0)) return 1;
    87   if (!Time.ParseFragmentMatrix(argv[1], dir, TimeSuffix, 10,1)) return 1;
     99  if (!Hessian.ParseFragmentMatrix(argv[1], dir, HessianSuffix,0,0)) {
     100    NoHessian = true;
     101    cout << "No Hessian file found, skipping these." << endl;
     102  }
     103  if (!Time.ParseFragmentMatrix(argv[1], dir, TimeSuffix, 10,1)) {
     104    NoTime = true;
     105    cout << "No speed file found, skipping these." << endl;
     106  }
    88107  if (periode != NULL) { // also look for PAS values
    89108    if (!Shielding.ParseFragmentMatrix(argv[1], dir, ShieldingSuffix, 1, 0)) return 1;
    90109    if (!ShieldingPAS.ParseFragmentMatrix(argv[1], dir, ShieldingPASSuffix, 1, 0)) return 1;
     110    if (!Chi.ParseFragmentMatrix(argv[1], dir, ChiSuffix, 1, 0)) return 1;
     111    if (!ChiPAS.ParseFragmentMatrix(argv[1], dir, ChiPASSuffix, 1, 0)) return 1;
    91112  }
    92113
    93114  // ---------- Parse the TE Factors into an array -----------------
    94115  if (!Energy.ParseIndices()) return 1;
    95   if (Hcorrected) Hcorrection.ParseIndices();
     116  if (!NoHCorrection) Hcorrection.ParseIndices();
    96117
    97118  // ---------- Parse the Force indices into an array ---------------
    98119  if (!Force.ParseIndices(argv[1])) return 1;
    99120  if (!ForceFragments.AllocateMatrix(Force.Header, Force.MatrixCounter, Force.RowCounter, Force.ColumnCounter)) return 1;
    100   if (!ForceFragments.ParseIndices(argv[1])) return 1;
     121  if (!ForceFragments.InitialiseIndices((class MatrixContainer *)&Force)) return 1;
     122
     123  // ---------- Parse hessian indices into an array -----------------
     124  if (!NoHessian) {
     125    if (!Hessian.InitialiseIndices((class MatrixContainer *)&Force)) return 1;
     126    if (!HessianFragments.AllocateMatrix(Hessian.Header, Hessian.MatrixCounter, Hessian.RowCounter, Hessian.ColumnCounter)) return 1;
     127    if (!HessianFragments.InitialiseIndices((class MatrixContainer *)&Force)) return 1;
     128  }
    101129
    102130  // ---------- Parse the shielding indices into an array ---------------
     
    108136    if(!ShieldingFragments.ParseIndices(argv[1])) return 1;
    109137    if(!ShieldingPASFragments.ParseIndices(argv[1])) return 1;
     138    if(!Chi.ParseIndices(argv[1])) return 1;
     139    if(!ChiPAS.ParseIndices(argv[1])) return 1;
     140    if (!ChiFragments.AllocateMatrix(Chi.Header, Chi.MatrixCounter, Chi.RowCounter, Chi.ColumnCounter)) return 1;
     141    if (!ChiPASFragments.AllocateMatrix(ChiPAS.Header, ChiPAS.MatrixCounter, ChiPAS.RowCounter, ChiPAS.ColumnCounter)) return 1;
     142    if(!ChiFragments.ParseIndices(argv[1])) return 1;
     143    if(!ChiPASFragments.ParseIndices(argv[1])) return 1;
    110144  }
    111145
     
    116150  // ---------- Parse fragment files created by 'joiner' into an array -------------
    117151  if (!EnergyFragments.ParseFragmentMatrix(argv[1], dir, EnergyFragmentSuffix,0,0)) return 1;
    118   if (Hcorrected) HcorrectionFragments.ParseFragmentMatrix(argv[1], dir, HcorrectionFragmentSuffix,0,0);
     152  if (!NoHCorrection)
     153    HcorrectionFragments.ParseFragmentMatrix(argv[1], dir, HcorrectionFragmentSuffix,0,0);
    119154  if (!ForceFragments.ParseFragmentMatrix(argv[1], dir, ForceFragmentSuffix,0,0)) return 1;
     155  if (!NoHessian)
     156    if (!HessianFragments.ParseFragmentMatrix(argv[1], dir, HessianFragmentSuffix,0,0)) return 1;
    120157  if (periode != NULL) { // also look for PAS values
    121158    if (!ShieldingFragments.ParseFragmentMatrix(argv[1], dir, ShieldingFragmentSuffix, 1, 0)) return 1;
    122159    if (!ShieldingPASFragments.ParseFragmentMatrix(argv[1], dir, ShieldingPASFragmentSuffix, 1, 0)) return 1;
     160    if (!ChiFragments.ParseFragmentMatrix(argv[1], dir, ChiFragmentSuffix, 1, 0)) return 1;
     161    if (!ChiPASFragments.ParseFragmentMatrix(argv[1], dir, ChiPASFragmentSuffix, 1, 0)) return 1;
    123162  }
    124163
     
    129168  filename << argv[3] << "/" << "energy-forces.all";
    130169  output.open(filename.str().c_str(), ios::out);
    131   output << endl << "Total Energy" << endl << "==============" << endl << Energy.Header << endl;
     170  output << endl << "Total Energy" << endl << "==============" << endl << Energy.Header[Energy.MatrixCounter] << endl;
    132171  for(int j=0;j<Energy.RowCounter[Energy.MatrixCounter];j++) {
    133     for(int k=0;k<Energy.ColumnCounter;k++)
     172    for(int k=0;k<Energy.ColumnCounter[Energy.MatrixCounter];k++)
    134173      output << scientific << Energy.Matrix[ Energy.MatrixCounter ][j][k] << "\t";
    135174    output << endl;
    136175  }
    137176  output << endl;
    138 
    139   output << endl << "Total Forces" << endl << "===============" << endl << Force.Header << endl;
     177 
     178  output << endl << "Total Forces" << endl << "===============" << endl << Force.Header[Force.MatrixCounter] << endl;
    140179  for(int j=0;j<Force.RowCounter[Force.MatrixCounter];j++) {
    141     for(int k=0;k<Force.ColumnCounter;k++)
     180    for(int k=0;k<Force.ColumnCounter[Force.MatrixCounter];k++)
    142181      output << scientific << Force.Matrix[ Force.MatrixCounter ][j][k] << "\t";
    143182    output << endl;
     
    145184  output << endl;
    146185
     186  if (!NoHessian) {
     187    output << endl << "Total Hessian" << endl << "===============" << endl << Hessian.Header[Hessian.MatrixCounter] << endl;
     188    for(int j=0;j<Hessian.RowCounter[Hessian.MatrixCounter];j++) {
     189      for(int k=0;k<Hessian.ColumnCounter[Hessian.MatrixCounter];k++)
     190        output << scientific << Hessian.Matrix[ Hessian.MatrixCounter ][j][k] << "\t";
     191      output << endl;
     192    }
     193    output << endl;
     194  }
     195
    147196  if (periode != NULL) { // also look for PAS values
    148     output << endl << "Total Shieldings" << endl << "===============" << endl << Shielding.Header << endl;
     197    output << endl << "Total Shieldings" << endl << "===============" << endl << Shielding.Header[Hessian.MatrixCounter] << endl;
    149198    for(int j=0;j<Shielding.RowCounter[Shielding.MatrixCounter];j++) {
    150       for(int k=0;k<Shielding.ColumnCounter;k++)
     199      for(int k=0;k<Shielding.ColumnCounter[Shielding.MatrixCounter];k++)
    151200        output << scientific << Shielding.Matrix[ Shielding.MatrixCounter ][j][k] << "\t";
    152201      output << endl;
    153202    }
    154203    output << endl;
    155 
    156     output << endl << "Total Shieldings PAS" << endl << "===============" << endl << ShieldingPAS.Header << endl;
     204 
     205    output << endl << "Total Shieldings PAS" << endl << "===============" << endl << ShieldingPAS.Header[ShieldingPAS.MatrixCounter] << endl;
    157206    for(int j=0;j<ShieldingPAS.RowCounter[ShieldingPAS.MatrixCounter];j++) {
    158       for(int k=0;k<ShieldingPAS.ColumnCounter;k++)
     207      for(int k=0;k<ShieldingPAS.ColumnCounter[ShieldingPAS.MatrixCounter];k++)
    159208        output << scientific << ShieldingPAS.Matrix[ ShieldingPAS.MatrixCounter ][j][k] << "\t";
    160209      output << endl;
    161210    }
    162211    output << endl;
    163   }
    164 
    165   output << endl << "Total Times" << endl << "===============" << endl << Time.Header << endl;
    166   for(int j=0;j<Time.RowCounter[Time.MatrixCounter];j++) {
    167     for(int k=0;k<Time.ColumnCounter;k++) {
    168       output << scientific << Time.Matrix[ Time.MatrixCounter ][j][k] << "\t";
    169     }
    170     output << endl;
    171   }
    172   output << endl;
     212
     213    output << endl << "Total Chis" << endl << "===============" << endl << Chi.Header[Chi.MatrixCounter] << endl;
     214    for(int j=0;j<Chi.RowCounter[Chi.MatrixCounter];j++) {
     215      for(int k=0;k<Chi.ColumnCounter[Chi.MatrixCounter];k++)
     216        output << scientific << Chi.Matrix[ Chi.MatrixCounter ][j][k] << "\t";
     217      output << endl;
     218    }
     219    output << endl;
     220 
     221    output << endl << "Total Chis PAS" << endl << "===============" << endl << ChiPAS.Header[ChiPAS.MatrixCounter] << endl;
     222    for(int j=0;j<ChiPAS.RowCounter[ChiPAS.MatrixCounter];j++) {
     223      for(int k=0;k<ChiPAS.ColumnCounter[ChiPAS.MatrixCounter];k++)
     224        output << scientific << ChiPAS.Matrix[ ChiPAS.MatrixCounter ][j][k] << "\t";
     225      output << endl;
     226    }
     227    output << endl;
     228  }
     229 
     230  if (!NoTime) {
     231    output << endl << "Total Times" << endl << "===============" << endl << Time.Header[Time.MatrixCounter] << endl;
     232    for(int j=0;j<Time.RowCounter[Time.MatrixCounter];j++) {
     233      for(int k=0;k<Time.ColumnCounter[Time.MatrixCounter];k++) {
     234        output << scientific << Time.Matrix[ Time.MatrixCounter ][j][k] << "\t";
     235      }
     236      output << endl;
     237    }
     238    output << endl;
     239  }
    173240  output.close();
    174   for(int k=0;k<Time.ColumnCounter;k++)
    175     Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter] ][k] = Time.Matrix[ Time.MatrixCounter ][Time.RowCounter[Time.MatrixCounter]-1][k];
     241  if (!NoTime)
     242    for(int k=0;k<Time.ColumnCounter[Time.MatrixCounter];k++)
     243      Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter] ][k] = Time.Matrix[ Time.MatrixCounter ][Time.RowCounter[Time.MatrixCounter]-1][k];
    176244
    177245  // +++++++++++++++ ANALYZING ++++++++++++++++++++++++++++++
     
    183251  // +++++++++++++++++++++++++++++++++++++++ Plotting Simtime vs Bond Order
    184252  // +++++++++++++++++++++++++++++++++++++++ Plotting Delta Simtime vs Bond Order
    185   if (!OpenOutputFile(output, argv[3], "SimTime-Order.dat" )) return false;
    186   if (!OpenOutputFile(output2, argv[3], "DeltaSimTime-Order.dat" )) return false;
    187   for(int j=Time.RowCounter[Time.MatrixCounter];j--;)
    188     for(int k=Time.ColumnCounter;k--;) {
    189       Time.Matrix[ Time.MatrixCounter ][j][k] = 0.;
    190     }
    191   counter = 0;
    192   output << "#Order\tFrag.No.\t" << Time.Header << endl;
    193   output2 << "#Order\tFrag.No.\t" << Time.Header << endl;
    194   for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
    195     for(int i=KeySet.FragmentsPerOrder[BondOrder];i--;)
    196       for(int j=Time.RowCounter[Time.MatrixCounter];j--;)
    197         for(int k=Time.ColumnCounter;k--;) {
    198           Time.Matrix[ Time.MatrixCounter ][j][k] += Time.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k];
    199         }
    200     counter += KeySet.FragmentsPerOrder[BondOrder];
    201     output << BondOrder+1 << "\t" << counter;
    202     output2 << BondOrder+1 << "\t" << counter;
    203     for(int k=0;k<Time.ColumnCounter;k++) {
    204       output << "\t" << scientific << Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter]-1 ][k];
    205       if (fabs(Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter] ][k]) > MYEPSILON)
    206         output2 << "\t" << scientific << Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter]-1 ][k] / Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter] ][k];
    207       else
    208         output2 << "\t" << scientific << Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter]-1 ][k];
    209     }
    210     output << endl;
    211     output2 << endl;
    212   }
    213   output.close();
    214   output2.close();
     253  if (!NoTime) {
     254    if (!OpenOutputFile(output, argv[3], "SimTime-Order.dat" )) return false;
     255    if (!OpenOutputFile(output2, argv[3], "DeltaSimTime-Order.dat" )) return false;
     256    for(int j=Time.RowCounter[Time.MatrixCounter];j--;)
     257      for(int k=Time.ColumnCounter[Time.MatrixCounter];k--;) {
     258        Time.Matrix[ Time.MatrixCounter ][j][k] = 0.;
     259      }
     260    counter = 0;
     261    output << "#Order\tFrag.No.\t" << Time.Header[Time.MatrixCounter] << endl;
     262    output2 << "#Order\tFrag.No.\t" << Time.Header[Time.MatrixCounter] << endl;
     263    for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
     264      for(int i=KeySet.FragmentsPerOrder[BondOrder];i--;)
     265        for(int j=Time.RowCounter[Time.MatrixCounter];j--;)
     266          for(int k=Time.ColumnCounter[Time.MatrixCounter];k--;) {
     267            Time.Matrix[ Time.MatrixCounter ][j][k] += Time.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k];
     268          }
     269      counter += KeySet.FragmentsPerOrder[BondOrder];
     270      output << BondOrder+1 << "\t" << counter;
     271      output2 << BondOrder+1 << "\t" << counter;
     272      for(int k=0;k<Time.ColumnCounter[Time.MatrixCounter];k++) {
     273        output << "\t" << scientific << Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter]-1 ][k];
     274        if (fabs(Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter] ][k]) > MYEPSILON)
     275          output2 << "\t" << scientific << Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter]-1 ][k] / Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter] ][k];
     276        else
     277          output2 << "\t" << scientific << Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter]-1 ][k];
     278      }
     279      output << endl;
     280      output2 << endl;
     281    }
     282    output.close();
     283    output2.close();
     284  }
     285
     286  if (!NoHessian) {
     287    // +++++++++++++++++++++++++++++++++++++++ Plotting deviation in hessian to full QM
     288    if (!CreateDataDeltaHessianOrderPerAtom(Hessian, HessianFragments, KeySet, argv[3], "DeltaHessian_xx-Order", "Plot of error between approximated hessian and full hessian versus the Bond Order", datum)) return 1;
     289
     290    if (!CreateDataDeltaFrobeniusOrderPerAtom(Hessian, HessianFragments, KeySet, argv[3], "DeltaFrobeniusHessian_xx-Order", "Plot of error between approximated hessian and full hessian in the frobenius norm versus the Bond Order", datum)) return 1;
     291
     292    // ++++++++++++++++++++++++++++++++++++++Plotting Hessian vs. Order
     293    if (!CreateDataHessianOrderPerAtom(HessianFragments, KeySet, argv[3], "Hessian_xx-Order", "Plot of approximated hessian versus the Bond Order", datum)) return 1;
     294    if (!AppendOutputFile(output, argv[3], "Hessian_xx-Order.dat" )) return false;
     295    output << endl << "# Full" << endl;
     296    for(int j=0;j<Hessian.RowCounter[Hessian.MatrixCounter];j++) {
     297      output << j << "\t";
     298      for(int k=0;k<Hessian.ColumnCounter[Force.MatrixCounter];k++)
     299        output << scientific <<  Hessian.Matrix[ Hessian.MatrixCounter ][j][k] << "\t";
     300      output << endl;
     301    }
     302    output.close();
     303  }
    215304
    216305  // +++++++++++++++++++++++++++++++++++++++ Plotting shieldings
    217 
    218306  if (periode != NULL) { // also look for PAS values
    219307    if (!CreateDataDeltaForcesOrderPerAtom(ShieldingPAS, ShieldingPASFragments, KeySet, argv[3], "DeltaShieldingsPAS-Order", "Plot of error between approximated shieldings and full shieldings versus the Bond Order", datum)) return 1;
     
    223311    for(int j=0;j<ShieldingPAS.RowCounter[ShieldingPAS.MatrixCounter];j++) {
    224312      output << j << "\t";
    225       for(int k=0;k<ShieldingPAS.ColumnCounter;k++)
     313      for(int k=0;k<ShieldingPAS.ColumnCounter[ShieldingPAS.MatrixCounter];k++)
    226314        output << scientific <<  ShieldingPAS.Matrix[ ShieldingPAS.MatrixCounter ][j][k] << "\t"; //*(((k>1) && (k<6))? 1.e6 : 1.) << "\t";
    227315      output << endl;
    228316    }
    229   }
    230   output.close();
     317    output.close();
     318    if (!CreateDataDeltaForcesOrderPerAtom(ChiPAS, ChiPASFragments, KeySet, argv[3], "DeltaChisPAS-Order", "Plot of error between approximated Chis and full Chis versus the Bond Order", datum)) return 1;
     319    if (!CreateDataForcesOrderPerAtom(ChiPASFragments, KeySet, argv[3], "ChisPAS-Order", "Plot of approximated Chis versus the Bond Order", datum)) return 1;
     320    if (!AppendOutputFile(output, argv[3], "ChisPAS-Order.dat" )) return false;
     321    output << endl << "# Full" << endl;
     322    for(int j=0;j<ChiPAS.RowCounter[ChiPAS.MatrixCounter];j++) {
     323      output << j << "\t";
     324      for(int k=0;k<ChiPAS.ColumnCounter[ChiPAS.MatrixCounter];k++)
     325        output << scientific <<  ChiPAS.Matrix[ ChiPAS.MatrixCounter ][j][k] << "\t"; //*(((k>1) && (k<6))? 1.e6 : 1.) << "\t";
     326      output << endl;
     327    }
     328    output.close();
     329  }
    231330
    232331
     
    255354  for(int j=0;j<Force.RowCounter[Force.MatrixCounter];j++) {
    256355    output << j << "\t";
    257     for(int k=0;k<Force.ColumnCounter;k++)
     356    for(int k=0;k<Force.ColumnCounter[Force.MatrixCounter];k++)
    258357      output << scientific <<  Force.Matrix[ Force.MatrixCounter ][j][k] << "\t";
    259358    output << endl;
     
    303402  Fragmentxrange << "[0:" << KeySet.FragmentCounter+1 << "]";
    304403  yrange.str("[1e-8:1e+1]");
    305 
    306   // +++++++++++++++++++++++++++++++++++++++ Plotting Simtime vs Bond Order
    307   if (!CreatePlotOrder(Time, KeySet, argv[3], "SimTime-Order", 1, "below", "y", "",  1, 1, "bond order k", "Evaluation time [s]", Orderxrange.str().c_str(), "", "1" , "with linespoints", EnergyPlotLine)) return 1;
    308 
     404 
     405  if (!NoTime) {
     406    // +++++++++++++++++++++++++++++++++++++++ Plotting Simtime vs Bond Order
     407    if (!CreatePlotOrder(Time, KeySet, argv[3], "SimTime-Order", 1, "below", "y", "",  1, 1, "bond order k", "Evaluation time [s]", Orderxrange.str().c_str(), "", "1" , "with linespoints", EnergyPlotLine)) return 1;
     408  }
     409 
    309410  // +++++++++++++++++++++++++++++++++++++++ Plotting deviation in energy to full QM
    310411  if (!CreatePlotOrder(Energy, KeySet, argv[3], "DeltaEnergies-Order", 1, "outside", "y", "",  1, 1, "bond order k", "absolute error in energy [Ht]", Orderxrange.str().c_str(), yrange.str().c_str(), "1" , "with linespoints", AbsEnergyPlotLine)) return 1;
     
    403504    }
    404505    output << "'ShieldingsPAS-Order.dat' index " << KeySet.Order << " title 'Full' using ($1+" << step*(double)KeySet.Order << "):7 with boxes" << endl;
    405     output.close();
    406     output2.close();
     506    output2.close(); 
     507
     508    if(!OpenOutputFile(output, argv[3], "ChisPAS-Order.pyx")) return 1;
     509    if(!OpenOutputFile(output2, argv[3], "DeltaChisPAS-Order.pyx")) return 1;
     510    CreatePlotHeader(output, "ChisPAS-Order", 1, "top right", NULL, NULL,  1, 5, "nuclei index", "iso chemical Chi value [ppm]");
     511    CreatePlotHeader(output2, "DeltaChisPAS-Order", 1, "top right", NULL, NULL,  1, 5, "nuclei index", "iso chemical Chi value [ppm]");
     512    output << "set boxwidth " << step << endl;
     513    output << "plot [0:" << ChiPAS.RowCounter[ChiPAS.MatrixCounter]+10 << "]\\" << endl;
     514    output2 << "plot [0:" << ChiPAS.RowCounter[ChiPAS.MatrixCounter]+10 << "]\\" << endl;
     515    for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
     516      output << "'ChisPAS-Order.dat' index " << BondOrder << " title 'Order " << BondOrder+1 << "' using ($1+" << step*(double)BondOrder << "):7 with boxes, \\" << endl;
     517      output2 << "'DeltaChisPAS-Order.dat' index " << BondOrder << " title 'Order " << BondOrder+1 << "' using ($1):7 with linespoints";
     518      if (BondOrder-1 != KeySet.Order)
     519        output2 << ", \\" << endl;
     520    }
     521    output << "'ChisPAS-Order.dat' index " << KeySet.Order << " title 'Full' using ($1+" << step*(double)KeySet.Order << "):7 with boxes" << endl;
     522    output.close(); 
     523    output2.close(); 
     524
     525    if(!OpenOutputFile(output, argv[3], "ChisPAS-Order.pyx")) return 1;
     526    if(!OpenOutputFile(output2, argv[3], "DeltaChisPAS-Order.pyx")) return 1;
     527    CreatePlotHeader(output, "ChisPAS-Order", 1, "top right", NULL, NULL,  1, 5, "nuclei index", "iso chemical Chi value [ppm]");
     528    CreatePlotHeader(output2, "DeltaChisPAS-Order", 1, "top right", NULL, NULL,  1, 5, "nuclei index", "iso chemical Chi value [ppm]");
     529    output << "set boxwidth " << step << endl;
     530    output << "plot [0:" << ChiPAS.RowCounter[ChiPAS.MatrixCounter]+10 << "]\\" << endl;
     531    output2 << "plot [0:" << ChiPAS.RowCounter[ChiPAS.MatrixCounter]+10 << "]\\" << endl;
     532    for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
     533      output << "'ChisPAS-Order.dat' index " << BondOrder << " title 'Order " << BondOrder+1 << "' using ($1+" << step*(double)BondOrder << "):7 with boxes, \\" << endl;
     534      output2 << "'DeltaChisPAS-Order.dat' index " << BondOrder << " title 'Order " << BondOrder+1 << "' using ($1):7 with linespoints";
     535      if (BondOrder-1 != KeySet.Order)
     536        output2 << ", \\" << endl;
     537    }
     538    output << "'ChisPAS-Order.dat' index " << KeySet.Order << " title 'Full' using ($1+" << step*(double)KeySet.Order << "):7 with boxes" << endl;
     539    output.close(); 
     540    output2.close(); 
    407541  }
    408542
  • src/atom.cpp

    r042f82 r36ec71  
    8989};
    9090
    91 ostream & operator << (ostream &ost, atom &a)
     91ostream & operator << (ostream &ost, const atom &a)
    9292{
    9393  ost << "[" << a.Name << "|" << &a << "]";
  • src/bond.cpp

    r042f82 r36ec71  
    8282};
    8383
    84 ostream & operator << (ostream &ost, bond &b)
     84ostream & operator << (ostream &ost, const bond &b)
    8585{
    8686  ost << "[" << b.leftatom->Name << " <" << b.BondDegree << "(H" << b.HydrogenBond << ")>" << b.rightatom->Name << "]";
     
    9898  if(rightatom == Atom)
    9999    return leftatom;
     100  cerr << "Bond " << *this << " does not contain atom " << *Atom << "!" << endl;
    100101  return NULL;
    101102};
  • src/boundary.cpp

    r042f82 r36ec71  
    1010#define DoSingleStepOutput 0
    1111#define DoTecplotOutput 1
    12 #define DoRaster3DOutput 0
     12#define DoRaster3DOutput 1
    1313#define DoVRMLOutput 1
    1414#define TecplotSuffix ".dat"
     
    4545void BoundaryPointSet::AddLine(class BoundaryLineSet *line)
    4646{
    47   cout << Verbose(6) << "Adding line " << *line << " to " << *this << "." << endl;
     47  cout << Verbose(6) << "Adding " << *this << " to line " << *line << "."
     48      << endl;
    4849  if (line->endpoints[0] == this)
    4950    {
  • src/builder.cpp

    r042f82 r36ec71  
    282282    case 'a':
    283283      cout << Verbose(0) << "Centering atoms in config file on origin." << endl;
    284       mol->CenterOrigin((ofstream *)&cout, &x);
     284      mol->CenterOrigin((ofstream *)&cout);
    285285      break;
    286286    case 'b':
    287287      cout << Verbose(0) << "Centering atoms in config file on center of gravity." << endl;
    288       mol->CenterGravity((ofstream *)&cout, &x);
     288      mol->CenterPeriodic((ofstream *)&cout);
    289289      break;
    290290    case 'c':
     
    295295      }
    296296      mol->CenterEdge((ofstream *)&cout, &x);  // make every coordinate positive
    297       mol->Translate(&y); // translate by boundary
     297      mol->Center.AddVector(&y); // translate by boundary
    298298      helper.CopyVector(&y);
    299299      helper.Scale(2.);
     
    307307        cin >> x.x[i];
    308308      }
     309      // update Box of atoms by boundary
     310      mol->SetBoxDimension(&x);
    309311      // center
    310312      mol->CenterInBox((ofstream *)&cout);
    311       // update Box of atoms by boundary
    312       mol->SetBoxDimension(&x);
    313313      break;
    314314  }
     
    463463      cin >> tmp1;
    464464      first = mol->start;
    465       while(first->next != mol->end) {
    466         first = first->next;
     465      second = first->next;
     466      while(second != mol->end) {
     467        first = second;
     468        second = first->next;
    467469        if (first->x.DistanceSquared((const Vector *)&second->x) > tmp1*tmp1) // distance to first above radius ...
    468470          mol->RemoveAtom(first);
     
    472474      cout << Verbose(0) << "Which axis is it: ";
    473475      cin >> axis;
    474       cout << Verbose(0) << "Left inward boundary: ";
     476      cout << Verbose(0) << "Lower boundary: ";
    475477      cin >> tmp1;
    476       cout << Verbose(0) << "Right inward boundary: ";
     478      cout << Verbose(0) << "Upper boundary: ";
    477479      cin >> tmp2;
    478480      first = mol->start;
    479       while(first->next != mol->end) {
    480         first = first->next;
    481         if ((first->x.x[axis] > tmp2) || (first->x.x[axis] < tmp1)) // out of boundary ...
     481      second = first->next;
     482      while(second != mol->end) {
     483        first = second;
     484        second = first->next;
     485        if ((first->x.x[axis] < tmp1) || (first->x.x[axis] > tmp2)) {// out of boundary ...
     486          //cout << "Atom " << *first << " with " << first->x.x[axis] << " on axis " << axis << " is out of bounds [" << tmp1 << "," << tmp2 << "]." << endl;
    482487          mol->RemoveAtom(first);
     488        }
    483489      }
    484490      break;
     
    644650  cout << Verbose(0) << "all else - go back" << endl;
    645651  cout << Verbose(0) << "===============================================" << endl;
    646   if (molecules->NumberOfActiveMolecules() > 0)
     652  if (molecules->NumberOfActiveMolecules() > 1)
    647653    cout << Verbose(0) << "WARNING: There is more than one molecule active! Atoms will be added to each." << endl;
    648654  cout << Verbose(0) << "INPUT: ";
     
    655661
    656662    case 'a': // add atom
    657       for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) {
     663      for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
     664        if ((*ListRunner)->ActiveFlag) {
    658665        mol = *ListRunner;
    659666        cout << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl;
     
    663670
    664671    case 'b': // scale a bond
    665       for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) {
     672      for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
     673        if ((*ListRunner)->ActiveFlag) {
    666674        mol = *ListRunner;
    667675        cout << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl;
     
    685693
    686694    case 'c': // unit scaling of the metric
    687       for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) {
     695      for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
     696        if ((*ListRunner)->ActiveFlag) {
    688697        mol = *ListRunner;
    689698        cout << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl;
     
    701710
    702711    case 'l': // measure distances or angles
    703       for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) {
     712      for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
     713        if ((*ListRunner)->ActiveFlag) {
    704714        mol = *ListRunner;
    705715        cout << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl;
     
    709719
    710720    case 'r': // remove atom
    711       for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) {
     721      for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
     722        if ((*ListRunner)->ActiveFlag) {
    712723        mol = *ListRunner;
    713724        cout << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl;
     
    717728
    718729    case 'u': // change an atom's element
    719       for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) {
     730      for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
     731        if ((*ListRunner)->ActiveFlag) {
    720732        int Z;
    721733        mol = *ListRunner;
     
    761773  cout << Verbose(0) << "all else - go back" << endl;
    762774  cout << Verbose(0) << "===============================================" << endl;
    763   if (molecules->NumberOfActiveMolecules() > 0)
     775  if (molecules->NumberOfActiveMolecules() > 1)
    764776    cout << Verbose(0) << "WARNING: There is more than one molecule active! Atoms will be added to each." << endl;
    765777  cout << Verbose(0) << "INPUT: ";
     
    772784
    773785    case 'd': // duplicate the periodic cell along a given axis, given times
    774       for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) {
     786      for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
     787        if ((*ListRunner)->ActiveFlag) {
    775788        mol = *ListRunner;
    776789        cout << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl;
     
    830843
    831844    case 'g': // center the atoms
    832       for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) {
     845      for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
     846        if ((*ListRunner)->ActiveFlag) {
    833847        mol = *ListRunner;
    834848        cout << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl;
     
    838852
    839853    case 'i': // align all atoms
    840       for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) {
     854      for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
     855        if ((*ListRunner)->ActiveFlag) {
    841856        mol = *ListRunner;
    842857        cout << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl;
     
    846861
    847862    case 'm': // mirror atoms along a given axis
    848       for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) {
     863      for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
     864        if ((*ListRunner)->ActiveFlag) {
    849865        mol = *ListRunner;
    850866        cout << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl;
     
    854870
    855871    case 'o': // create the connection matrix
    856       {
     872      for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
     873        if ((*ListRunner)->ActiveFlag) {
    857874        double bonddistance;
    858875        clock_t start,end;
     
    868885
    869886    case 't': // translate all atoms
    870      for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) {
     887      for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
     888        if ((*ListRunner)->ActiveFlag) {
    871889        mol = *ListRunner;
    872890        cout << Verbose(0) << "Current molecule is: " << mol->IndexNr << "\t" << mol->name << endl;
    873891        cout << Verbose(0) << "Enter translation vector." << endl;
    874892        x.AskPosition(mol->cell_size,0);
    875         mol->Translate((const Vector *)&x);
     893        mol->Center.AddVector((const Vector *)&x);
    876894     }
    877895     break;
     
    895913{
    896914  char choice;  // menu choice char
    897   Vector Center;
     915  Vector center;
    898916  int nr, count;
    899917  molecule *mol = NULL;
    900   char filename[MAXSTRINGSIZE];
    901 
    902   cout << Verbose(0) << "==========Edit MOLECULES=====================" << endl;
     918
     919  cout << Verbose(0) << "==========EDIT MOLECULES=====================" << endl;
    903920  cout << Verbose(0) << "c - create new molecule" << endl;
    904921  cout << Verbose(0) << "l - load molecule from xyz file" << endl;
    905922  cout << Verbose(0) << "n - change molecule's name" << endl;
    906923  cout << Verbose(0) << "N - give molecules filename" << endl;
    907   cout << Verbose(0) << "p - parse xyz file into molecule" << endl;
     924  cout << Verbose(0) << "p - parse atoms in xyz file into molecule" << endl;
    908925  cout << Verbose(0) << "r - remove a molecule" << endl;
    909926  cout << Verbose(0) << "all else - go back" << endl;
     
    921938      break;
    922939
    923     case 'l': // laod from XYZ file
    924       cout << Verbose(0) << "Format should be XYZ with: ShorthandOfElement\tX\tY\tZ" << endl;
    925       mol = new molecule(periode);
    926       do {
    927         cout << Verbose(0) << "Enter file name: ";
     940    case 'l': // load from XYZ file
     941      {
     942        char filename[MAXSTRINGSIZE];
     943        cout << Verbose(0) << "Format should be XYZ with: ShorthandOfElement\tX\tY\tZ" << endl;
     944        mol = new molecule(periode);
     945        do {
     946          cout << Verbose(0) << "Enter file name: ";
     947          cin >> filename;
     948        } while (!mol->AddXYZFile(filename));
     949        mol->SetNameFromFilename(filename);
     950        // center at set box dimensions
     951        mol->CenterEdge((ofstream *)&cout, &center);
     952        mol->cell_size[0] = center.x[0];
     953        mol->cell_size[1] = 0;
     954        mol->cell_size[2] = center.x[1];
     955        mol->cell_size[3] = 0;
     956        mol->cell_size[4] = 0;
     957        mol->cell_size[5] = center.x[2];
     958        molecules->insert(mol);
     959      }
     960      break;
     961
     962    case 'n':
     963      {
     964        char filename[MAXSTRINGSIZE];
     965        do {
     966          cout << Verbose(0) << "Enter index of molecule: ";
     967          cin >> nr;
     968          mol = molecules->ReturnIndex(nr);
     969        } while (mol == NULL);
     970        cout << Verbose(0) << "Enter name: ";
    928971        cin >> filename;
    929       } while (!mol->AddXYZFile(filename));
    930       mol->SetNameFromFilename(filename);
    931       // center at set box dimensions
    932       mol->CenterEdge((ofstream *)&cout, &Center);
    933       mol->cell_size[0] = Center.x[0];
    934       mol->cell_size[1] = 0;
    935       mol->cell_size[2] = Center.x[1];
    936       mol->cell_size[3] = 0;
    937       mol->cell_size[4] = 0;
    938       mol->cell_size[5] = Center.x[2];
    939       molecules->insert(mol);
    940       break;
    941 
    942     case 'n':
    943       do {
    944         cout << Verbose(0) << "Enter index of molecule: ";
    945         cin >> nr;
    946         mol = molecules->ReturnIndex(nr);
    947       } while (mol != NULL);
    948       cout << Verbose(0) << "Enter name: ";
    949       cin >> filename;
    950       strcpy(mol->name, filename);
     972        strcpy(mol->name, filename);
     973      }
    951974      break;
    952975
    953976    case 'N':
    954       do {
    955         cout << Verbose(0) << "Enter index of molecule: ";
    956         cin >> nr;
    957         mol = molecules->ReturnIndex(nr);
    958       } while (mol != NULL);
    959       cout << Verbose(0) << "Enter name: ";
    960       cin >> filename;
    961       mol->SetNameFromFilename(filename);
     977      {
     978        char filename[MAXSTRINGSIZE];
     979        do {
     980          cout << Verbose(0) << "Enter index of molecule: ";
     981          cin >> nr;
     982          mol = molecules->ReturnIndex(nr);
     983        } while (mol == NULL);
     984        cout << Verbose(0) << "Enter name: ";
     985        cin >> filename;
     986        mol->SetNameFromFilename(filename);
     987      }
    962988      break;
    963989
    964990    case 'p': // parse XYZ file
    965       mol = NULL;
    966       do {
    967         cout << Verbose(0) << "Enter index of molecule: ";
    968         cin >> nr;
    969         mol = molecules->ReturnIndex(nr);
    970       } while (mol == NULL);
    971       cout << Verbose(0) << "Format should be XYZ with: ShorthandOfElement\tX\tY\tZ" << endl;
    972       do {
    973         cout << Verbose(0) << "Enter file name: ";
    974         cin >> filename;
    975       } while (!mol->AddXYZFile(filename));
    976       mol->SetNameFromFilename(filename);
     991      {
     992        char filename[MAXSTRINGSIZE];
     993        mol = NULL;
     994        do {
     995          cout << Verbose(0) << "Enter index of molecule: ";
     996          cin >> nr;
     997          mol = molecules->ReturnIndex(nr);
     998        } while (mol == NULL);
     999        cout << Verbose(0) << "Format should be XYZ with: ShorthandOfElement\tX\tY\tZ" << endl;
     1000        do {
     1001          cout << Verbose(0) << "Enter file name: ";
     1002          cin >> filename;
     1003        } while (!mol->AddXYZFile(filename));
     1004        mol->SetNameFromFilename(filename);
     1005      }
    9771006      break;
    9781007
     
    9811010      cin >> nr;
    9821011      count = 1;
    983       MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin();
    984       for(; ((ListRunner != molecules->ListOfMolecules.end()) && (count < nr)); ListRunner++);
    985       mol = *ListRunner;
    986       if (count == nr) {
    987         molecules->ListOfMolecules.erase(ListRunner);
    988         delete(mol);
    989       }
     1012      for( MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
     1013        if (nr == (*ListRunner)->IndexNr) {
     1014          mol = *ListRunner;
     1015          molecules->ListOfMolecules.erase(ListRunner);
     1016          delete(mol);
     1017        }
    9901018      break;
    9911019  }
     
    10021030
    10031031  cout << Verbose(0) << "===========MERGE MOLECULES=====================" << endl;
     1032  cout << Verbose(0) << "a - simple add of one molecule to another" << endl;
    10041033  cout << Verbose(0) << "e - embedding merge of two molecules" << endl;
    10051034  cout << Verbose(0) << "m - multi-merge of all molecules" << endl;
     
    10161045      break;
    10171046
     1047    case 'a':
     1048      {
     1049        int src, dest;
     1050        molecule *srcmol = NULL, *destmol = NULL;
     1051        {
     1052          do {
     1053            cout << Verbose(0) << "Enter index of destination molecule: ";
     1054            cin >> dest;
     1055            destmol = molecules->ReturnIndex(dest);
     1056          } while ((destmol == NULL) && (dest != -1));
     1057          do {
     1058            cout << Verbose(0) << "Enter index of source molecule to add from: ";
     1059            cin >> src;
     1060            srcmol = molecules->ReturnIndex(src);
     1061          } while ((srcmol == NULL) && (src != -1));
     1062          if ((src != -1) && (dest != -1))
     1063            molecules->SimpleAdd(srcmol, destmol);
     1064        }
     1065      }
     1066      break;
     1067
    10181068    case 'e':
     1069      cout << Verbose(0) << "Not implemented yet." << endl;
    10191070      break;
    10201071
    10211072    case 'm':
     1073      {
     1074        int nr;
     1075        molecule *mol = NULL;
     1076        do {
     1077          cout << Verbose(0) << "Enter index of molecule to merge into: ";
     1078          cin >> nr;
     1079          mol = molecules->ReturnIndex(nr);
     1080        } while ((mol == NULL) && (nr != -1));
     1081        if (nr != -1) {
     1082          int N = molecules->ListOfMolecules.size()-1;
     1083          int *src = new int(N);
     1084          for(MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
     1085            if ((*ListRunner)->IndexNr != nr)
     1086              src[N++] = (*ListRunner)->IndexNr;       
     1087          molecules->SimpleMultiMerge(mol, src, N);
     1088          delete[](src);
     1089        }
     1090      }
    10221091      break;
    10231092
    10241093    case 's':
     1094      cout << Verbose(0) << "Not implemented yet." << endl;
    10251095      break;
    10261096
    10271097    case 't':
     1098      {
     1099        int src, dest;
     1100        molecule *srcmol = NULL, *destmol = NULL;
     1101        {
     1102          do {
     1103            cout << Verbose(0) << "Enter index of destination molecule: ";
     1104            cin >> dest;
     1105            destmol = molecules->ReturnIndex(dest);
     1106          } while ((destmol == NULL) && (dest != -1));
     1107          do {
     1108            cout << Verbose(0) << "Enter index of source molecule to merge into: ";
     1109            cin >> src;
     1110            srcmol = molecules->ReturnIndex(src);
     1111          } while ((srcmol == NULL) && (src != -1));
     1112          if ((src != -1) && (dest != -1))
     1113            molecules->SimpleMerge(srcmol, destmol);
     1114        }
     1115      }
    10281116      break;
    10291117  }
     
    11251213  molecule *mol = new molecule(periode);
    11261214
    1127   // merge all molecules in MoleculeListClass into this molecule
     1215  // translate each to its center and merge all molecules in MoleculeListClass into this molecule
    11281216  int N = molecules->ListOfMolecules.size();
    11291217  int *src = new int(N);
    11301218  N=0;
    1131   for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
     1219  for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) {
    11321220    src[N++] = (*ListRunner)->IndexNr;
     1221    (*ListRunner)->Translate(&(*ListRunner)->Center);
     1222  }
    11331223  molecules->SimpleMultiAdd(mol, src, N);
     1224  delete[](src);
     1225  // ... and translate back
     1226  for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) {
     1227    (*ListRunner)->Center.Scale(-1.);
     1228    (*ListRunner)->Translate(&(*ListRunner)->Center);
     1229    (*ListRunner)->Center.Scale(-1.);
     1230  }
    11341231
    11351232  cout << Verbose(0) << "Storing configuration ... " << endl;
     
    11371234  mol->CalculateOrbitals(*configuration);
    11381235  configuration->InitMaxMinStopStep = configuration->MaxMinStopStep = configuration->MaxPsiDouble;
    1139   strcpy(filename, ConfigFileName);
    11401236  if (ConfigFileName != NULL) { // test the file name
    1141     output.open(ConfigFileName, ios::trunc);
     1237    strcpy(filename, ConfigFileName);
     1238    output.open(filename, ios::trunc);
    11421239  } else if (strlen(configuration->configname) != 0) {
    11431240    strcpy(filename, configuration->configname);
     
    12271324  // simply create a new molecule, wherein the config file is loaded and the manipulation takes place
    12281325  molecule *mol = new molecule(periode);
     1326  mol->ActiveFlag = true;
    12291327  molecules->insert(mol);
    12301328
     
    12571355            cout << "\t-m <0/1>\tCalculate (0)/ Align in(1) PAS with greatest EV along z axis." << endl;
    12581356            cout << "\t-n\tFast parsing (i.e. no trajectories are looked for)." << endl;
    1259             cout << "\t-N\tGet non-convex-envelope." << endl;
     1357            cout << "\t-N <radius> <file>\tGet non-convex-envelope." << endl;
    12601358            cout << "\t-o <out>\tGet volume of the convex envelope (and store to tecplot file)." << endl;
    12611359            cout << "\t-p <file>\tParse given xyz file and create raw config file from it." << endl;
    12621360            cout << "\t-P <file>\tParse given forces file and append as an MD step to config file via Verlet." << endl;
     1361            cout << "\t-L <step0> <step1> <prefix>\tStore a linear interpolation between two configurations <step0> and <step1> into single config files with prefix <prefix> and as Trajectories into the current config file." << endl;
    12631362            cout << "\t-r\t\tConvert file from an old pcp syntax." << endl;
     1363            cout << "\t-R\t\tRemove all atoms out of sphere around a given one." << endl;
    12641364            cout << "\t-t x1 x2 x3\tTranslate all atoms by this vector (x1,x2,x3)." << endl;
    12651365            cout << "\t-T x1 x2 x3\tTranslate periodically all atoms by this vector (x1,x2,x3)." << endl;
     
    15041604              }
    15051605              break;
     1606            case 'L':
     1607              ExitFlag = 1;
     1608              SaveFlag = true;
     1609              cout << Verbose(1) << "Linear interpolation between configuration " << argv[argptr] << " and " << argv[argptr+1] << "." << endl;
     1610              if (!mol->LinearInterpolationBetweenConfiguration((ofstream *)&cout, atoi(argv[argptr]), atoi(argv[argptr+1]), argv[argptr+2], configuration))
     1611                cout << Verbose(2) << "Could not store " << argv[argptr+2] << " files." << endl;
     1612              else
     1613                cout << Verbose(2) << "Steps created and " << argv[argptr+2] << " files stored." << endl;
     1614              argptr+=3;
     1615              break;
    15061616            case 'P':
    15071617              ExitFlag = 1;
     
    15121622                SaveFlag = true;
    15131623                cout << Verbose(1) << "Parsing forces file and Verlet integrating." << endl;
    1514                 if (!mol->VerletForceIntegration(argv[argptr], configuration.Deltat, configuration.GetIsAngstroem()))
     1624                if (!mol->VerletForceIntegration((ofstream *)&cout, argv[argptr], configuration))
    15151625                  cout << Verbose(2) << "File not found." << endl;
    15161626                else
    15171627                  cout << Verbose(2) << "File found and parsed." << endl;
    15181628                argptr+=1;
     1629              }
     1630              break;
     1631            case 'R':
     1632              ExitFlag = 1;
     1633              if ((argptr+1 >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])))  {
     1634                ExitFlag = 255;
     1635                cerr << "Not enough or invalid arguments given for removing atoms: -R <id> <distance>" << endl;
     1636              } else {
     1637                SaveFlag = true;
     1638                cout << Verbose(1) << "Removing atoms around " << argv[argptr] << " with radius " << argv[argptr+1] << "." << endl;
     1639                double tmp1 = atof(argv[argptr+1]);
     1640                atom *third = mol->FindAtom(atoi(argv[argptr]));
     1641                atom *first = mol->start;
     1642                if ((third != NULL) && (first != mol->end)) {
     1643                  atom *second = first->next;
     1644                  while(second != mol->end) {
     1645                    first = second;
     1646                    second = first->next;
     1647                    if (first->x.DistanceSquared((const Vector *)&third->x) > tmp1*tmp1) // distance to first above radius ...
     1648                      mol->RemoveAtom(first);
     1649                  }
     1650                } else {
     1651                  cerr << "Removal failed due to missing atoms on molecule or wrong id." << endl;
     1652                }
     1653                argptr+=2;
    15191654              }
    15201655              break;
     
    15331668                argptr+=3;
    15341669              }
    1535               break;
    15361670            case 'T':
    15371671              ExitFlag = 1;
     
    15831717              } else {
    15841718                SaveFlag = true;
     1719                j = -1;
    15851720                cout << Verbose(1) << "Centering atoms in config file within given simulation box." << endl;
    15861721                for (int i=0;i<6;i++) {
     
    16091744                for (int i=0;i<NDIM;i++) {
    16101745                  j += i+1;
    1611                   x.x[i] = atof(argv[argptr++]);
     1746                  x.x[i] = atof(argv[argptr+i]);
    16121747                  mol->cell_size[j] += x.x[i]*2.;
    16131748                }
     
    16191754              ExitFlag = 1;
    16201755              SaveFlag = true;
    1621               cout << Verbose(1) << "Centering atoms in origin." << endl;
    1622               mol->CenterOrigin((ofstream *)&cout, &x);
     1756              cout << Verbose(1) << "Centering atoms on edge and setting box dimensions." << endl;
     1757              x.Zero();
     1758              mol->CenterEdge((ofstream *)&cout, &x);
    16231759              mol->SetBoxDimension(&x);
    16241760              argptr+=0;
     
    18021938  string line;
    18031939  char *ConfigFileName = NULL;
    1804   int j, count;
     1940  int j;
    18051941
    18061942  // =========================== PARSE COMMAND LINE OPTIONS ====================================
     
    18441980    cout << Verbose(0) << "============Menu===============================" << endl;
    18451981    cout << Verbose(0) << "a - set molecule (in)active" << endl;
    1846     cout << Verbose(0) << "e - edit new molecules" << endl;
     1982    cout << Verbose(0) << "e - edit molecules (load, parse, save)" << endl;
    18471983    cout << Verbose(0) << "g - globally manipulate atoms in molecule" << endl;
    18481984    cout << Verbose(0) << "M - Merge molecules" << endl;
     
    18631999          cout << "Enter index of molecule: ";
    18642000          cin >> j;
    1865           count = 1;
    1866           MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin();
    1867           for(; ((ListRunner != molecules->ListOfMolecules.end()) && (count < j)); ListRunner++);
    1868           if (count == j)
    1869             (*ListRunner)->ActiveFlag = !(*ListRunner)->ActiveFlag;
     2001          for(MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
     2002            if ((*ListRunner)->IndexNr == j)
     2003              (*ListRunner)->ActiveFlag = !(*ListRunner)->ActiveFlag;
    18702004        }
    18712005        break;
  • src/config.cpp

    r042f82 r36ec71  
    169169  configpath = (char *) MallocString(sizeof(char)*MAXSTRINGSIZE,"config constructor: configpath");
    170170  configname = (char *) MallocString(sizeof(char)*MAXSTRINGSIZE,"config constructor: configname");
     171  ThermostatImplemented = (int *) Malloc((MaxThermostats)*(sizeof(int)), "config constructor: *ThermostatImplemented");
     172  ThermostatNames = (char **) Malloc((MaxThermostats)*(sizeof(char *)), "config constructor: *ThermostatNames");
     173  for (int j=0;j<MaxThermostats;j++)
     174    ThermostatNames[j] = (char *) MallocString(12*(sizeof(char)), "config constructor: ThermostatNames[]");
     175  Thermostat = 4;
     176  alpha = 0.;
     177  ScaleTempStep = 25;
     178  TempFrequency = 2.5;
    171179  strcpy(mainname,"pcp");
    172180  strcpy(defaultpath,"not specified");
     
    175183  configname[0]='\0';
    176184  basis = "3-21G";
     185
     186  strcpy(ThermostatNames[0],"None");
     187  ThermostatImplemented[0] = 1;
     188  strcpy(ThermostatNames[1],"Woodcock");
     189  ThermostatImplemented[1] = 1;
     190  strcpy(ThermostatNames[2],"Gaussian");
     191  ThermostatImplemented[2] = 1;
     192  strcpy(ThermostatNames[3],"Langevin");
     193  ThermostatImplemented[3] = 1;
     194  strcpy(ThermostatNames[4],"Berendsen");
     195  ThermostatImplemented[4] = 1;
     196  strcpy(ThermostatNames[5],"NoseHoover");
     197  ThermostatImplemented[5] = 1;
    177198
    178199  FastParsing = false;
     
    187208  DoFullCurrent=0;
    188209  DoWannier=0;
     210  DoConstrainedMD=0;
    189211  CommonWannier=0;
    190212  SawtoothStart=0.01;
     
    195217
    196218  MaxOuterStep=0;
    197   Deltat=1;
     219  Deltat=0.01;
    198220  OutVisStep=10;
    199221  OutSrcStep=5;
     
    247269  Free((void **)&configpath, "config::~config: *configpath");
    248270  Free((void **)&configname, "config::~config: *configname");
     271  Free((void **)&ThermostatImplemented, "config::~config: *ThermostatImplemented");
     272  for (int j=0;j<MaxThermostats;j++)
     273    Free((void **)&ThermostatNames[j], "config::~config: *ThermostatNames[]");
     274  Free((void **)&ThermostatNames, "config::~config: **ThermostatNames");
    249275};
     276
     277/** Readin of Thermostat related values from parameter file.
     278 * \param *source parameter file
     279 */
     280void config::InitThermostats(ifstream *source)
     281{
     282  char *thermo = MallocString(12, "IonsInitRead: thermo");
     283  int verbose = 0;
     284
     285  // read desired Thermostat from file along with needed additional parameters
     286  if (ParseForParameter(verbose,source,"Thermostat", 0, 1, 1, string_type, thermo, 1, optional)) {
     287    if (strcmp(thermo, ThermostatNames[0]) == 0) { // None
     288      if (ThermostatImplemented[0] == 1) {
     289        Thermostat = None;
     290      } else {
     291        cout << Verbose(1) << "Warning: " << ThermostatNames[0] << " thermostat not implemented, falling back to None." << endl;
     292        Thermostat = None;
     293      }
     294    } else if (strcmp(thermo, ThermostatNames[1]) == 0) { // Woodcock
     295      if (ThermostatImplemented[1] == 1) {
     296        Thermostat = Woodcock;
     297        ParseForParameter(verbose,source,"Thermostat", 0, 2, 1, int_type, &ScaleTempStep, 1, critical); // read scaling frequency
     298      } else {
     299        cout << Verbose(1) << "Warning: " << ThermostatNames[0] << " thermostat not implemented, falling back to None." << endl;
     300        Thermostat = None;
     301      }
     302    } else if (strcmp(thermo, ThermostatNames[2]) == 0) { // Gaussian
     303      if (ThermostatImplemented[2] == 1) {
     304        Thermostat = Gaussian;
     305        ParseForParameter(verbose,source,"Thermostat", 0, 2, 1, int_type, &ScaleTempStep, 1, critical); // read collision rate
     306      } else {
     307        cout << Verbose(1) << "Warning: " << ThermostatNames[0] << " thermostat not implemented, falling back to None." << endl;
     308        Thermostat = None;
     309      }
     310    } else if (strcmp(thermo, ThermostatNames[3]) == 0) { // Langevin
     311      if (ThermostatImplemented[3] == 1) {
     312        Thermostat = Langevin;
     313        ParseForParameter(verbose,source,"Thermostat", 0, 2, 1, double_type, &TempFrequency, 1, critical); // read gamma
     314        if (ParseForParameter(verbose,source,"Thermostat", 0, 3, 1, double_type, &alpha, 1, optional)) {
     315          cout << Verbose(2) << "Extended Stochastic Thermostat detected with interpolation coefficient " << alpha << "." << endl;
     316        } else {
     317          alpha = 1.;
     318        }
     319      } else {
     320        cout << Verbose(1) << "Warning: " << ThermostatNames[0] << " thermostat not implemented, falling back to None." << endl;
     321        Thermostat = None;
     322      }
     323    } else if (strcmp(thermo, ThermostatNames[4]) == 0) { // Berendsen
     324      if (ThermostatImplemented[4] == 1) {
     325        Thermostat = Berendsen;
     326        ParseForParameter(verbose,source,"Thermostat", 0, 2, 1, double_type, &TempFrequency, 1, critical); // read \tau_T
     327      } else {
     328        cout << Verbose(1) << "Warning: " << ThermostatNames[0] << " thermostat not implemented, falling back to None." << endl;
     329        Thermostat = None;
     330      }
     331    } else if (strcmp(thermo, ThermostatNames[5]) == 0) { // Nose-Hoover
     332      if (ThermostatImplemented[5] == 1) {
     333        Thermostat = NoseHoover;
     334        ParseForParameter(verbose,source,"Thermostat", 0, 2, 1, double_type, &HooverMass, 1, critical); // read Hoovermass
     335        alpha = 0.;
     336      } else {
     337        cout << Verbose(1) << "Warning: " << ThermostatNames[0] << " thermostat not implemented, falling back to None." << endl;
     338        Thermostat = None;
     339      }
     340    } else {
     341      cout << Verbose(1) << " Warning: thermostat name was not understood!" << endl;
     342      Thermostat = None;
     343    }
     344  } else {
     345    if ((MaxOuterStep > 0) && (TargetTemp != 0))
     346      cout << Verbose(2) <<  "No thermostat chosen despite finite temperature MD, falling back to None." << endl;
     347    Thermostat = None;
     348  }
     349  Free((void **)&thermo, "InitThermostats: thermo");
     350};
     351
    250352
    251353/** Displays menu for editing each entry of the config file.
     
    597699void config::Load(char *filename, periodentafel *periode, molecule *mol)
    598700{
     701  ifstream *file = new ifstream(filename);
     702  if (file == NULL) {
     703    cerr << "ERROR: config file " << filename << " missing!" << endl;
     704    return;
     705  }
    599706  RetrieveConfigPathAndName(filename);
    600707
     
    614721  int verbose = 0;
    615722  double value[3];
    616 
     723 
     724  InitThermostats(file);
     725 
    617726  /* Namen einlesen */
    618727
     
    667776    if (config::SawtoothStart > 1.) config::SawtoothStart = 1.;
    668777  }
    669 
     778 
     779  if (ParseForParameter(verbose,FileBuffer,"DoConstrainedMD", 0, 1, 1, int_type, &(config::DoConstrainedMD), 1, optional))
     780    if (config::DoConstrainedMD < 0)
     781      config::DoConstrainedMD = 0;
    670782  ParseForParameter(verbose,FileBuffer,"MaxOuterStep", 0, 1, 1, int_type, &(config::MaxOuterStep), 1, critical);
    671783  if (!ParseForParameter(verbose,FileBuffer,"Deltat", 0, 1, 1, double_type, &(config::Deltat), 1, optional))
     
    11681280    *output << "DoPerturbation\t" << config::DoPerturbation << "\t# Do perturbation calculate and determine susceptibility and shielding" << endl;
    11691281    *output << "DoFullCurrent\t" << config::DoFullCurrent << "\t# Do full perturbation" << endl;
     1282    *output << "DoConstrainedMD\t" << config::DoConstrainedMD << "\t# Do perform a constrained (>0, relating to current MD step) instead of unconstrained (0) MD" << endl;
     1283    *output << "Thermostat\t" << ThermostatNames[Thermostat] << "\t";
     1284    switch(Thermostat) {
     1285      default:
     1286      case None:
     1287        break;
     1288      case Woodcock:
     1289        *output << ScaleTempStep;
     1290        break;
     1291      case Gaussian:
     1292        *output << ScaleTempStep;
     1293        break;
     1294      case Langevin:
     1295        *output << TempFrequency << "\t" << alpha;
     1296        break;
     1297      case Berendsen:
     1298        *output << TempFrequency;
     1299        break;
     1300      case NoseHoover:
     1301        *output << HooverMass;
     1302        break;
     1303    };
     1304    *output << "\t# Which Thermostat and its parameters to use in MD case." << endl;
    11701305    *output << "CommonWannier\t" << config::CommonWannier << "\t# Put virtual centers at indivual orbits, all common, merged by variance, to grid point, to cell center" << endl;
    11711306    *output << "SawtoothStart\t" << config::SawtoothStart << "\t# Absolute value for smooth transition at cell border " << endl;
     
    13051440  *output << ")" << endl;
    13061441  *output << "basis<GaussianBasisSet>: (" << endl;
    1307   *output << "\tname = \""<< basis << "\"" << endl;
     1442  *output << "\tname = \"" << basis << "\"" << endl;
    13081443  *output << "\tmolecule = $:molecule" << endl;
    13091444  *output << ")" << endl;
  • src/datacreator.cpp

    r042f82 r36ec71  
    6363  cout << msg << endl;
    6464  output << "# " << msg << ", created on " << datum;
    65   output << "#Order\tFrag.No.\t" << Fragments.Header << endl;
     65  output << "#Order\tFrag.No.\t" << Fragments.Header[Fragments.MatrixCounter] << endl;
    6666  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
    6767    for(int i=KeySet.FragmentsPerOrder[BondOrder];i--;) {
    6868      for(int j=Fragments.RowCounter[ KeySet.OrderSet[BondOrder][i] ];j--;)
    69         for(int k=Fragments.ColumnCounter;k--;)
     69        for(int k=Fragments.ColumnCounter[ KeySet.OrderSet[BondOrder][i] ];k--;)
    7070          Fragments.Matrix[Fragments.MatrixCounter][j][k] += Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k];
    7171    }
    7272    output << BondOrder+1 << "\t" << KeySet.FragmentsPerOrder[BondOrder];
    73     for (int l=0;l<Fragments.ColumnCounter;l++)
     73    for (int l=0;l<Fragments.ColumnCounter[Fragments.MatrixCounter];l++)
    7474      output << scientific << "\t" << Fragments.Matrix[Fragments.MatrixCounter][ Fragments.RowCounter[Fragments.MatrixCounter]-1 ][l];
    7575    output << endl;
     
    9696  cout << msg << endl;
    9797  output << "# " << msg << ", created on " << datum;
    98   output << "#Order\tFrag.No.\t" << Fragments.Header << endl;
     98  output << "#Order\tFrag.No.\t" << Fragments.Header[Fragments.MatrixCounter] << endl;
    9999  Fragments.SetLastMatrix(Energy.Matrix[Energy.MatrixCounter],0);
    100100  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
    101101    for(int i=KeySet.FragmentsPerOrder[BondOrder];i--;) {
    102102      for(int j=Fragments.RowCounter[ KeySet.OrderSet[BondOrder][i] ];j--;)
    103         for(int k=Fragments.ColumnCounter;k--;)
     103        for(int k=Fragments.ColumnCounter[ KeySet.OrderSet[BondOrder][i] ];k--;)
    104104          Fragments.Matrix[Fragments.MatrixCounter][j][k] -= Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k];
    105105    }
    106106    output << BondOrder+1 << "\t" << KeySet.FragmentsPerOrder[BondOrder];
    107     for (int l=0;l<Fragments.ColumnCounter;l++)
     107    for (int l=0;l<Fragments.ColumnCounter[Energy.MatrixCounter];l++)
    108108      if (fabs(Energy.Matrix[Energy.MatrixCounter][ Energy.RowCounter[Energy.MatrixCounter]-1 ][l]) < MYEPSILON)
    109109        output << scientific << "\t" << Fragments.Matrix[Fragments.MatrixCounter][ Fragments.RowCounter[Fragments.MatrixCounter]-1 ][l];
     
    133133  cout << msg << endl;
    134134  output << "# " << msg << ", created on " << datum;
    135   output << "# Order\tFrag.No.\t" << Fragments.Header << endl;
     135  output << "# Order\tFrag.No.\t" << Fragments.Header[Fragments.MatrixCounter] << endl;
    136136  Fragments.SetLastMatrix(0.,0);
    137137  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
     
    139139    output << BondOrder+1 << "\t" << KeySet.FragmentsPerOrder[BondOrder];
    140140    CreateForce(Fragments, Fragments.MatrixCounter);
    141     for (int l=0;l<Fragments.ColumnCounter;l++)
     141    for (int l=0;l<Fragments.ColumnCounter[Fragments.MatrixCounter];l++)
    142142       output << scientific << "\t" << Fragments.Matrix[Fragments.MatrixCounter][ Fragments.RowCounter[Fragments.MatrixCounter] ][l];
    143143    output << endl;
     
    165165  cout << msg << endl;
    166166  output << "# " << msg << ", created on " << datum;
    167   output << "# Order\tFrag.No.\t" << Fragments.Header << endl;
     167  output << "# Order\tFrag.No.\t" << Fragments.Header[Fragments.MatrixCounter] << endl;
    168168  Fragments.SetLastMatrix(Force.Matrix[Force.MatrixCounter],0);
    169169  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
     
    171171    output << BondOrder+1 << "\t" << KeySet.FragmentsPerOrder[BondOrder];
    172172    CreateForce(Fragments, Fragments.MatrixCounter);
    173     for (int l=0;l<Fragments.ColumnCounter;l++)
     173    for (int l=0;l<Fragments.ColumnCounter[Fragments.MatrixCounter];l++)
    174174       output << scientific << "\t" << Fragments.Matrix[Fragments.MatrixCounter][ Fragments.RowCounter[Fragments.MatrixCounter] ][l];
    175175    output << endl;
     
    198198  cout << msg << endl;
    199199  output << "# " << msg << ", created on " << datum;
    200   output << "# AtomNo\t" << Fragments.Header << endl;
     200  output << "# AtomNo\t" << Fragments.Header[Fragments.MatrixCounter] << endl;
    201201  Fragments.SetLastMatrix(Force.Matrix[Force.MatrixCounter], 0);
    202202  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
     
    207207    for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) {
    208208      output << Fragments.Indices[Fragments.MatrixCounter][j] << "\t";
    209       for (int l=0;l<Fragments.ColumnCounter;l++) {
     209      for (int l=0;l<Fragments.ColumnCounter[ Fragments.MatrixCounter ];l++) {
    210210        if (((l+1) % 3) == 0) {
    211211          norm = 0.;
     
    213213            norm += Force.Matrix[Force.MatrixCounter][ j ][l+m]*Force.Matrix[Force.MatrixCounter][ j ][l+m];
    214214          norm = sqrt(norm);
    215         }
     215        }                                                                                                   
    216216//        if (norm < MYEPSILON)
    217217          output << scientific << Fragments.Matrix[Fragments.MatrixCounter][ j ][l] << "\t";
     
    244244  cout << msg << endl;
    245245  output << "# " << msg << ", created on " << datum;
    246   output << "# AtomNo\t" << Fragments.Header << endl;
     246  output << "# AtomNo\t" << Fragments.Header[Fragments.MatrixCounter] << endl;
    247247  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
    248248    //cout << "Current order is " << BondOrder << "." << endl;
     
    252252    for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) {
    253253      output << Fragments.Indices[Fragments.MatrixCounter][j] << "\t";
    254       for (int l=0;l<Fragments.ColumnCounter;l++)
     254      for (int l=0;l<Fragments.ColumnCounter[ Fragments.MatrixCounter ];l++)
    255255        output << scientific << Fragments.Matrix[Fragments.MatrixCounter][ j ][l] << "\t";
    256256      output << endl;
     
    262262};
    263263
     264
     265/** Plot hessian error vs. vs atom vs. order.
     266 * \param &Hessian HessianMatrix containing reference values (in MatrixCounter matrix)
     267 * \param &Fragments HessianMatrix class containing matrix values
     268 * \param KeySet KeySetContainer class holding bond KeySetContainer::Order
     269 * \param *prefix prefix in filename (without ending)
     270 * \param *msg message to be place in first line as a comment
     271 * \param *datum current date and time
     272 * \return true if file was written successfully
     273 */
     274bool CreateDataDeltaHessianOrderPerAtom(class HessianMatrix &Hessian, class HessianMatrix &Fragments, class KeySetsContainer &KeySet, const char *dir, const char *prefix, const char *msg, const char *datum)
     275{
     276  stringstream filename;
     277  ofstream output;
     278
     279  filename << prefix << ".dat";
     280  if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
     281  cout << msg << endl;
     282  output << "# " << msg << ", created on " << datum;
     283  output << "# AtomNo\t" << Fragments.Header[Fragments.MatrixCounter] << endl;
     284  Fragments.SetLastMatrix(Hessian.Matrix[Hessian.MatrixCounter], 0);
     285  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
     286    //cout << "Current order is " << BondOrder << "." << endl;
     287    Fragments.SumSubHessians(Fragments, KeySet, BondOrder, -1.);
     288    // errors per atom
     289    output << endl << "#Order\t" << BondOrder+1 << endl;
     290    for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) {
     291      output << Fragments.Indices[Fragments.MatrixCounter][j] << "\t";
     292      for (int l=0;l<Fragments.ColumnCounter[ Fragments.MatrixCounter ];l++) {
     293        output << scientific << Fragments.Matrix[Fragments.MatrixCounter][ j ][l] << "\t";
     294      }
     295      output << endl;
     296    }
     297    output << endl;
     298  }
     299  output.close();
     300  return true;
     301};
     302
     303/** Plot hessian error vs. vs atom vs. order in the frobenius norm.
     304 * \param &Hessian HessianMatrix containing reference values (in MatrixCounter matrix)
     305 * \param &Fragments HessianMatrix class containing matrix values
     306 * \param KeySet KeySetContainer class holding bond KeySetContainer::Order
     307 * \param *prefix prefix in filename (without ending)
     308 * \param *msg message to be place in first line as a comment
     309 * \param *datum current date and time
     310 * \return true if file was written successfully
     311 */
     312bool CreateDataDeltaFrobeniusOrderPerAtom(class HessianMatrix &Hessian, class HessianMatrix &Fragments, class KeySetsContainer &KeySet, const char *dir, const char *prefix, const char *msg, const char *datum)
     313{
     314  stringstream filename;
     315  ofstream output;
     316  double norm = 0;
     317  double tmp;
     318
     319  filename << prefix << ".dat";
     320  if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
     321  cout << msg << endl;
     322  output << "# " << msg << ", created on " << datum;
     323  output << "# AtomNo\t";
     324  Fragments.SetLastMatrix(Hessian.Matrix[Hessian.MatrixCounter], 0);
     325  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
     326    output << "Order" << BondOrder+1 << "\t";
     327  }
     328  output << endl;
     329  output << Fragments.RowCounter[ Fragments.MatrixCounter ] << "\t";
     330  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
     331    //cout << "Current order is " << BondOrder << "." << endl;
     332    Fragments.SumSubHessians(Fragments, KeySet, BondOrder, -1.);
     333    // frobenius norm of errors per atom
     334    norm = 0.;
     335    for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) {
     336      for (int l=0;l<Fragments.ColumnCounter[ Fragments.MatrixCounter ];l++) {
     337        tmp = Fragments.Matrix[Fragments.MatrixCounter][ j ][l];
     338        norm += tmp*tmp;
     339      }
     340    }
     341    output << scientific << sqrt(norm)/(Fragments.RowCounter[ Fragments.MatrixCounter ]*Fragments.ColumnCounter[ Fragments.MatrixCounter] ) << "\t";
     342  }
     343  output << endl;
     344  output.close();
     345  return true;
     346};
     347
     348/** Plot hessian error vs. vs atom vs. order.
     349 * \param &Fragments HessianMatrix class containing matrix values
     350 * \param KeySet KeySetContainer class holding bond KeySetContainer::Order
     351 * \param *prefix prefix in filename (without ending)
     352 * \param *msg message to be place in first line as a comment
     353 * \param *datum current date and time
     354 * \return true if file was written successfully
     355 */
     356bool CreateDataHessianOrderPerAtom(class HessianMatrix &Fragments, class KeySetsContainer &KeySet, const char *dir, const char *prefix, const char *msg, const char *datum)
     357{
     358  stringstream filename;
     359  ofstream output;
     360
     361  filename << prefix << ".dat";
     362  if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
     363  cout << msg << endl;
     364  output << "# " << msg << ", created on " << datum;
     365  output << "# AtomNo\t" << Fragments.Header[ Fragments.MatrixCounter ] << endl;
     366  Fragments.SetLastMatrix(0., 0);
     367  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
     368    //cout << "Current order is " << BondOrder << "." << endl;
     369    Fragments.SumSubHessians(Fragments, KeySet, BondOrder, 1.);
     370    // errors per atom
     371    output << endl << "#Order\t" << BondOrder+1 << endl;
     372    for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) {
     373      output << Fragments.Indices[Fragments.MatrixCounter][j] << "\t";
     374      for (int l=0;l<Fragments.ColumnCounter[ Fragments.MatrixCounter ];l++)
     375        output << scientific << Fragments.Matrix[Fragments.MatrixCounter][ j ][l] << "\t";
     376      output << endl;
     377    }
     378    output << endl;
     379  }
     380  output.close();
     381  return true;
     382};
     383
    264384/** Plot matrix vs. fragment.
    265385 */
     
    273393  cout << msg << endl;
    274394  output << "# " << msg << ", created on " << datum << endl;
    275   output << "#Order\tFrag.No.\t" << Fragment.Header << endl;
     395  output << "#Order\tFrag.No.\t" << Fragment.Header[ Fragment.MatrixCounter ] << endl;
    276396  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
    277397    for(int i=0;i<KeySet.FragmentsPerOrder[BondOrder];i++) {
    278398      output << BondOrder+1 << "\t" << KeySet.OrderSet[BondOrder][i]+1;
    279399      CreateFragment(Fragment, KeySet.OrderSet[BondOrder][i]);
    280       for (int l=0;l<Fragment.ColumnCounter;l++)
     400      for (int l=0;l<Fragment.ColumnCounter[ KeySet.OrderSet[BondOrder][i] ];l++)
    281401        output << scientific << "\t" << Fragment.Matrix[ KeySet.OrderSet[BondOrder][i] ][ Fragment.RowCounter[ KeySet.OrderSet[BondOrder][i] ] ][l];
    282402      output << endl;
     
    297417    for(int i=KeySet.FragmentsPerOrder[BondOrder];i--;) {
    298418      if (fabs(Fragments.Matrix[ Fragments.MatrixCounter ][j][1]) < fabs(Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][1])) {
    299         for (int k=Fragments.ColumnCounter;k--;)
     419        for (int k=Fragments.ColumnCounter[ Fragments.MatrixCounter ];k--;)
    300420          Fragments.Matrix[ Fragments.MatrixCounter ][j][k] = Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k];
    301421      }
     
    314434    int i=0;
    315435    do {  // first get a minimum value unequal to 0
    316       for (int k=Fragments.ColumnCounter;k--;)
     436      for (int k=Fragments.ColumnCounter[ Fragments.MatrixCounter ];k--;)
    317437        Fragments.Matrix[ Fragments.MatrixCounter ][j][k] = Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k];
    318438      i++;
     
    320440    for(;i<KeySet.FragmentsPerOrder[BondOrder];i++) { // then find lowest
    321441      if (fabs(Fragments.Matrix[ Fragments.MatrixCounter ][j][1]) > fabs(Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][1])) {
    322         for (int k=Fragments.ColumnCounter;k--;)
     442        for (int k=Fragments.ColumnCounter[ Fragments.MatrixCounter ];k--;)
    323443          Fragments.Matrix[ Fragments.MatrixCounter ][j][k] = Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k];
    324444      }
     
    338458  cout << msg << endl;
    339459  output << "# " << msg << ", created on " << datum;
    340   output << "#Order\tFrag.No.\t" << Fragment.Header << endl;
     460  output << "#Order\tFrag.No.\t" << Fragment.Header[ Fragment.MatrixCounter ] << endl;
    341461  // max
    342462  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
     
    344464    CreateFragmentOrder(Fragment, KeySet, BondOrder);
    345465    output << BondOrder+1 << "\t" << KeySet.FragmentsPerOrder[BondOrder];
    346     for (int l=0;l<Fragment.ColumnCounter;l++)
     466    for (int l=0;l<Fragment.ColumnCounter[ Fragment.MatrixCounter ];l++)
    347467      output << scientific << "\t" << Fragment.Matrix[ Fragment.MatrixCounter ][ Fragment.RowCounter[ Fragment.MatrixCounter ]-1 ][l];
    348468    output << endl;
     
    358478void CreateEnergy(class MatrixContainer &Energy, int MatrixNumber)
    359479{
    360   for(int k=0;k<Energy.ColumnCounter;k++)
     480  for(int k=0;k<Energy.ColumnCounter[MatrixNumber];k++)
    361481    Energy.Matrix[MatrixNumber][ Energy.RowCounter[MatrixNumber] ] [k] =  Energy.Matrix[MatrixNumber][ Energy.RowCounter[MatrixNumber]-1 ] [k];
    362482};
     
    369489void CreateMinimumForce(class MatrixContainer &Force, int MatrixNumber)
    370490{
    371   for (int l=Force.ColumnCounter;l--;)
     491  for (int l=Force.ColumnCounter[MatrixNumber];l--;)
    372492    Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l] = 0.;
    373   for (int l=5;l<Force.ColumnCounter;l+=3) {
     493  for (int l=5;l<Force.ColumnCounter[MatrixNumber];l+=3) {
    374494    double stored = 0;
    375495    int k=0;
     
    404524{
    405525  int divisor = 0;
    406   for (int l=Force.ColumnCounter;l--;)
     526  for (int l=Force.ColumnCounter[MatrixNumber];l--;)
    407527    Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l] = 0.;
    408   for (int l=5;l<Force.ColumnCounter;l+=3) {
     528  for (int l=5;l<Force.ColumnCounter[MatrixNumber];l+=3) {
    409529    double tmp = 0;
    410530    for (int k=Force.RowCounter[MatrixNumber];k--;) {
     
    428548void CreateMaximumForce(class MatrixContainer &Force, int MatrixNumber)
    429549{
    430   for (int l=5;l<Force.ColumnCounter;l+=3) {
     550  for (int l=5;l<Force.ColumnCounter[MatrixNumber];l+=3) {
    431551    double stored = 0;
    432552    for (int k=Force.RowCounter[MatrixNumber];k--;) {
     
    460580void CreateVectorSumForce(class MatrixContainer &Force, int MatrixNumber)
    461581{
    462   for (int l=Force.ColumnCounter;l--;)
     582  for (int l=Force.ColumnCounter[MatrixNumber];l--;)
    463583    Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l] = 0.;
    464   for (int l=0;l<Force.ColumnCounter;l++) {
     584  for (int l=0;l<Force.ColumnCounter[MatrixNumber];l++) {
    465585    for (int k=Force.RowCounter[MatrixNumber];k--;)
    466586      Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l] += Force.Matrix[MatrixNumber][k][l];
     
    538658void AbsEnergyPlotLine(ofstream &output, class MatrixContainer &Energy, const char *prefix, const char *xargument, const char *uses)
    539659{
    540   stringstream line(Energy.Header);
     660  stringstream line(Energy.Header[ Energy.MatrixCounter ]);
    541661  string token;
    542662
    543663  getline(line, token, '\t');
    544   for (int i=2; i<= Energy.ColumnCounter;i++) {
     664  for (int i=2; i<= Energy.ColumnCounter[Energy.MatrixCounter];i++) {
    545665    getline(line, token, '\t');
    546666    while (token[0] == ' ') // remove leading white spaces
    547667      token.erase(0,1);
    548668    output << "'" << prefix << ".dat' title '" << token << "' using " << xargument << ":(abs($" << i+2 << ")) " << uses;
    549     if (i != (Energy.ColumnCounter))
     669    if (i != (Energy.ColumnCounter[Energy.MatrixCounter]))
    550670      output << ", \\";
    551671    output << endl;
     
    562682void EnergyPlotLine(ofstream &output, class MatrixContainer &Energy, const char *prefix, const char *xargument, const char *uses)
    563683{
    564   stringstream line(Energy.Header);
     684  stringstream line(Energy.Header[Energy.MatrixCounter]);
    565685  string token;
    566686
    567687  getline(line, token, '\t');
    568   for (int i=1; i<= Energy.ColumnCounter;i++) {
     688  for (int i=1; i<= Energy.ColumnCounter[Energy.MatrixCounter];i++) {
    569689    getline(line, token, '\t');
    570690    while (token[0] == ' ') // remove leading white spaces
    571691      token.erase(0,1);
    572692    output << "'" << prefix << ".dat' title '" << token << "' using " << xargument << ":" << i+2 << " " << uses;
    573     if (i != (Energy.ColumnCounter))
     693    if (i != (Energy.ColumnCounter[Energy.MatrixCounter]))
    574694      output << ", \\";
    575695    output << endl;
     
    586706void ForceMagnitudePlotLine(ofstream &output, class MatrixContainer &Force, const char *prefix, const char *xargument, const char *uses)
    587707{
    588   stringstream line(Force.Header);
     708  stringstream line(Force.Header[Force.MatrixCounter]);
    589709  string token;
    590710
     
    594714  getline(line, token, '\t');
    595715  getline(line, token, '\t');
    596   for (int i=7; i< Force.ColumnCounter;i+=NDIM) {
     716  for (int i=7; i< Force.ColumnCounter[Force.MatrixCounter];i+=NDIM) {
    597717    getline(line, token, '\t');
    598718    while (token[0] == ' ') // remove leading white spaces
     
    600720    token.erase(token.length(), 1);  // kill residual index char (the '0')
    601721    output << "'" << prefix << ".dat' title '" << token << "' using " << xargument << ":(sqrt($" << i+1 << "*$" << i+1 << "+$" << i+2 << "*$" << i+2 << "+$" << i+3 << "*$" << i+3 << ")) " << uses;
    602     if (i != (Force.ColumnCounter-1))
     722    if (i != (Force.ColumnCounter[Force.MatrixCounter]-1))
    603723      output << ", \\";
    604724    output << endl;
     
    617737void AbsFirstForceValuePlotLine(ofstream &output, class MatrixContainer &Force, const char *prefix, const char *xargument, const char *uses)
    618738{
    619   stringstream line(Force.Header);
     739  stringstream line(Force.Header[Force.MatrixCounter]);
    620740  string token;
    621741
     
    625745  getline(line, token, '\t');
    626746  getline(line, token, '\t');
    627   for (int i=7; i< Force.ColumnCounter;i+=NDIM) {
     747  for (int i=7; i< Force.ColumnCounter[Force.MatrixCounter];i+=NDIM) {
    628748    getline(line, token, '\t');
    629749    while (token[0] == ' ') // remove leading white spaces
     
    631751    token.erase(token.length(), 1);  // kill residual index char (the '0')
    632752    output << "'" << prefix << ".dat' title '" << token << "' using " << xargument << ":(abs($" << i+1 << ")) " << uses;
    633     if (i != (Force.ColumnCounter-1))
     753    if (i != (Force.ColumnCounter[Force.MatrixCounter]-1))
    634754      output << ", \\";
    635755    output << endl;
     
    648768void BoxesForcePlotLine(ofstream &output, class MatrixContainer &Force, const char *prefix, const char *xargument, const char *uses)
    649769{
    650   stringstream line(Force.Header);
    651   const char *fillcolor[5] = {"black", "red", "blue", "green", "cyan"};
     770  stringstream line(Force.Header[Force.MatrixCounter]);
     771  char *fillcolor[5] = {"black", "red", "blue", "green", "cyan"};
    652772  string token;
    653773
     
    657777  getline(line, token, '\t');
    658778  getline(line, token, '\t');
    659   for (int i=7; i< Force.ColumnCounter;i+=NDIM) {
     779  for (int i=7; i< Force.ColumnCounter[Force.MatrixCounter];i+=NDIM) {
    660780    getline(line, token, '\t');
    661781    while (token[0] == ' ') // remove leading white spaces
     
    663783    token.erase(token.length(), 1);  // kill residual index char (the '0')
    664784    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];
    665     if (i != (Force.ColumnCounter-1))
     785    if (i != (Force.ColumnCounter[Force.MatrixCounter]-1))
    666786      output << ", \\";
    667787    output << endl;
     
    680800void BoxesFirstForceValuePlotLine(ofstream &output, class MatrixContainer &Force, const char *prefix, const char *xargument, const char *uses)
    681801{
    682   stringstream line(Force.Header);
    683   const char *fillcolor[5] = {"black", "red", "blue", "green", "cyan"};
     802  stringstream line(Force.Header[Force.MatrixCounter]);
     803  char *fillcolor[5] = {"black", "red", "blue", "green", "cyan"};
    684804  string token;
    685805
     
    689809  getline(line, token, '\t');
    690810  getline(line, token, '\t');
    691   for (int i=7; i< Force.ColumnCounter;i+=NDIM) {
     811  for (int i=7; i< Force.ColumnCounter[Force.MatrixCounter];i+=NDIM) {
    692812    getline(line, token, '\t');
    693813    while (token[0] == ' ') // remove leading white spaces
     
    695815    token.erase(token.length(), 1);  // kill residual index char (the '0')
    696816    output << "'" << prefix << ".dat' title '" << token << "' using ($" << xargument << "+" << fixed << setprecision(1) << (double)((i-7)/3)*0.2 << "):" << i+1 << " " << uses << " " << fillcolor[(i-7)/3];
    697     if (i != (Force.ColumnCounter-1))
     817    if (i != (Force.ColumnCounter[Force.MatrixCounter]-1))
    698818      output << ", \\";
    699819    output << endl;
  • src/datacreator.hpp

    r042f82 r36ec71  
    2525bool CreateDataForcesOrderPerAtom(class ForceMatrix &Fragments, class KeySetsContainer &KeySet, const char *dir, const char *prefix, const char *msg, const char *datum);
    2626bool CreateDataDeltaForcesOrder(class ForceMatrix &Force, class ForceMatrix &Fragments, class KeySetsContainer &KeySet, const char *dir, const char *prefix, const char *msg, const char *datum, void (*CreateForce)(class MatrixContainer &, int));
    27 bool CreateDataDeltaForcesOrderPerAtom(class ForceMatrix &Force, class ForceMatrix &Fragments, class KeySetsContainer &KeySet, const char *dir, const char *prefix, const char *msg, const char *datum);
     27bool CreateDataDeltaForcesOrderPerAtom(class ForceMatrix &Force, class ForceMatrix &Fragments, class KeySetsContainer &KeySet, const char *dir, const char *prefix, const char *msg, const char *datum);
     28bool CreateDataHessianOrderPerAtom(class HessianMatrix &Fragments, class KeySetsContainer &KeySet, const char *dir, const char *prefix, const char *msg, const char *datum);
     29bool CreateDataDeltaHessianOrderPerAtom(class HessianMatrix &Hessian, class HessianMatrix &Fragments, class KeySetsContainer &KeySet, const char *dir, const char *prefix, const char *msg, const char *datum);
     30bool CreateDataDeltaFrobeniusOrderPerAtom(class HessianMatrix &Hessian, class HessianMatrix &Fragments, class KeySetsContainer &KeySet, const char *dir, const char *prefix, const char *msg, const char *datum);
    2831bool CreateDataFragment(class MatrixContainer &ForceFragments, class KeySetsContainer &KeySet, const char *dir, const char *prefix, const char *msg, const char *datum, void (*CreateForce)(class MatrixContainer &, int));
    2932bool CreateDataFragmentOrder(class MatrixContainer &Fragment, class KeySetsContainer &KeySet, const char *dir, const char *prefix, const char *msg, const char *datum, void (*CreateFragmentOrder)(class MatrixContainer &, class KeySetsContainer &, int));
  • src/defs.hpp

    r042f82 r36ec71  
    1616#define BONDTHRESHOLD 0.5   //!< CSD threshold in bond check which is the width of the interval whose center is the sum of the covalent radii
    1717#define AtomicEnergyToKelvin 315774.67  //!< conversion factor from atomic energy to kelvin via boltzmann factor
     18#define KelvinToAtomicTemperature 3.1668152e-06    //!< conversion factor for Kelvin to atomic temperature (Hartree over k_B)
     19#define KelvinToeV 8.6173422e-05                   //!< conversion factor for Kelvin to Ht (k_B * T = energy), thus Boltzmann constant in eV/K
     20#define AtomicMassUnitsToeV 931494088.        //!< conversion factor for atomic weight in units to mass in eV
     21#define AtomicMassUnitsToHt 34480864.        //!< conversion factor for atomic weight in units to mass in Ht (protonmass/electronmass * electron_mass_in_Ht
     22#define ElectronMass_Ht 18778.865            //!< electron mass in Ht
     23#define ElectronMass_eV 510998.903           //!< electron mass in eV
     24#define Units2Electronmass (AtomicMassUnitsToeV/ElectronMass_eV) //!< atomic mass unit in eV/ electron mass in eV = 1 822.88863
     25#define Atomictime2Femtoseconds 0.024188843     //!< Atomictime in fs
     26
    1827#define VERSIONSTRING "v1.0"
    1928
  • src/graph.cpp

    r042f82 r36ec71  
    77using namespace std;
    88
     9#include "graph.hpp"
    910
    10 #include <iostream>
    11 #include <list>
    12 #include <vector>
     11/***************************************** Implementations for graph classes ********************************/
    1312
    14 /***************************************** Functions for class graph ********************************/
     13/** Constructor of class Graph.
     14 */
     15Graph::Graph()
     16{
     17};
    1518
     19/** Destructor of class Graph.
     20 * Destructor does release memory for nodes and edges contained in its lists as well.
     21 */
     22Graph::~Graph()
     23{
     24};
    1625
     26/** Constructor of class SubGraph.
     27 */
     28SubGraph::SubGraph()
     29{
     30};
     31
     32/** Destructor of class SubGraph.
     33 * Note that destructor does not deallocate either nodes or edges! (this is done by its subgraph!)
     34 */
     35SubGraph::~SubGraph()
     36{
     37};
     38
     39/** Constructor of class Node.
     40 */
     41Node::Node()
     42{
     43};
     44
     45/** Destructor of class Node.
     46 */
     47Node::~Node()
     48{
     49};
     50
     51/** Constructor of class Edge.
     52 */
     53Edge::Edge()
     54{
     55};
     56
     57/** Destructor of class Edge.
     58 */
     59Edge::~Edge()
     60{
     61};
     62
  • src/joiner.cpp

    r042f82 r36ec71  
    1919  periodentafel *periode = NULL; // and a period table of all elements
    2020  EnergyMatrix Energy;
     21  EnergyMatrix EnergyFragments;
     22 
    2123  EnergyMatrix Hcorrection;
     24  EnergyMatrix HcorrectionFragments;
     25 
    2226  ForceMatrix Force;
    23   EnergyMatrix EnergyFragments;
    24   EnergyMatrix HcorrectionFragments;
    2527  ForceMatrix ForceFragments;
     28
     29  HessianMatrix Hessian;
     30  HessianMatrix HessianFragments;
     31 
    2632  ForceMatrix Shielding;
    2733  ForceMatrix ShieldingPAS;
    2834  ForceMatrix ShieldingFragments;
    2935  ForceMatrix ShieldingPASFragments;
    30   KeySetsContainer KeySet;
     36  ForceMatrix Chi;
     37  ForceMatrix ChiPAS;
     38  ForceMatrix ChiFragments;
     39  ForceMatrix ChiPASFragments;
     40  KeySetsContainer KeySet; 
    3141  stringstream prefix;
    3242  char *dir = NULL;
    33   bool Hcorrected = true;
     43  bool NoHCorrection = false;
     44  bool NoHessian = false;
    3445
    3546  cout << "Joiner" << endl;
     
    6172  // ------------- Parse through all Fragment subdirs --------
    6273  if (!Energy.ParseFragmentMatrix(argv[1], dir, EnergySuffix, 0,0)) return 1;
    63   Hcorrected = Hcorrection.ParseFragmentMatrix(argv[1], "", HCORRECTIONSUFFIX, 0,0);
     74  if (!Hcorrection.ParseFragmentMatrix(argv[1], "", HCORRECTIONSUFFIX, 0,0)) {
     75    NoHCorrection = true;
     76    cout << "No HCorrection matrices found, skipping these." << endl;
     77  }
    6478  if (!Force.ParseFragmentMatrix(argv[1], dir, ForcesSuffix, 0,0)) return 1;
     79  if (!Hessian.ParseFragmentMatrix(argv[1], dir, HessianSuffix, 0,0)) {
     80    NoHessian = true;
     81    cout << "No hessian matrices found, skipping these." << endl;
     82  }
    6583  if (periode != NULL) { // also look for PAS values
    6684    if (!Shielding.ParseFragmentMatrix(argv[1], dir, ShieldingSuffix, 1, 0)) return 1;
    6785    if (!ShieldingPAS.ParseFragmentMatrix(argv[1], dir, ShieldingPASSuffix, 1, 0)) return 1;
     86    if (!Chi.ParseFragmentMatrix(argv[1], dir, ChiSuffix, 1, 0)) return 1;
     87    if (!ChiPAS.ParseFragmentMatrix(argv[1], dir, ChiPASSuffix, 1, 0)) return 1;
    6888  }
    6989
    7090  // ---------- Parse the TE Factors into an array -----------------
    71   if (!Energy.ParseIndices()) return 1;
    72   if (Hcorrected) Hcorrection.ParseIndices();
    73 
     91  if (!Energy.InitialiseIndices()) return 1;
     92  if (!NoHCorrection)
     93    Hcorrection.InitialiseIndices();
     94 
    7495  // ---------- Parse the Force indices into an array ---------------
    7596  if (!Force.ParseIndices(argv[1])) return 1;
    7697
     98  // ---------- Parse the Hessian (=force) indices into an array ---------------
     99  if (!NoHessian)
     100    if (!Hessian.InitialiseIndices((class MatrixContainer *)&Force)) return 1;
     101
    77102  // ---------- Parse the shielding indices into an array ---------------
    78103  if (periode != NULL) { // also look for PAS values
    79104    if(!Shielding.ParseIndices(argv[1])) return 1;
    80105    if(!ShieldingPAS.ParseIndices(argv[1])) return 1;
     106    if(!Chi.ParseIndices(argv[1])) return 1;
     107    if(!ChiPAS.ParseIndices(argv[1])) return 1;
    81108  }
    82109
     
    85112
    86113  if (!KeySet.ParseManyBodyTerms()) return 1;
     114
    87115  if (!EnergyFragments.AllocateMatrix(Energy.Header, Energy.MatrixCounter, Energy.RowCounter, Energy.ColumnCounter)) return 1;
    88   if (Hcorrected)  HcorrectionFragments.AllocateMatrix(Hcorrection.Header, Hcorrection.MatrixCounter, Hcorrection.RowCounter, Hcorrection.ColumnCounter);
     116  if (!NoHCorrection) 
     117    HcorrectionFragments.AllocateMatrix(Hcorrection.Header, Hcorrection.MatrixCounter, Hcorrection.RowCounter, Hcorrection.ColumnCounter);
    89118  if (!ForceFragments.AllocateMatrix(Force.Header, Force.MatrixCounter, Force.RowCounter, Force.ColumnCounter)) return 1;
     119  if (!NoHessian)
     120    if (!HessianFragments.AllocateMatrix(Hessian.Header, Hessian.MatrixCounter, Hessian.RowCounter, Hessian.ColumnCounter)) return 1;
    90121  if (periode != NULL) { // also look for PAS values
    91122    if (!ShieldingFragments.AllocateMatrix(Shielding.Header, Shielding.MatrixCounter, Shielding.RowCounter, Shielding.ColumnCounter)) return 1;
    92123    if (!ShieldingPASFragments.AllocateMatrix(ShieldingPAS.Header, ShieldingPAS.MatrixCounter, ShieldingPAS.RowCounter, ShieldingPAS.ColumnCounter)) return 1;
     124    if (!ChiFragments.AllocateMatrix(Chi.Header, Chi.MatrixCounter, Chi.RowCounter, Chi.ColumnCounter)) return 1;
     125    if (!ChiPASFragments.AllocateMatrix(ChiPAS.Header, ChiPAS.MatrixCounter, ChiPAS.RowCounter, ChiPAS.ColumnCounter)) return 1;
    93126  }
    94127
     
    96129  if(!Energy.SetLastMatrix(0., 0)) return 1;
    97130  if(!Force.SetLastMatrix(0., 2)) return 1;
     131  if (!NoHessian)
     132    if (!Hessian.SetLastMatrix(0., 0)) return 1;
    98133  if (periode != NULL) { // also look for PAS values
    99134    if(!Shielding.SetLastMatrix(0., 2)) return 1;
    100135    if(!ShieldingPAS.SetLastMatrix(0., 2)) return 1;
     136    if(!Chi.SetLastMatrix(0., 2)) return 1;
     137    if(!ChiPAS.SetLastMatrix(0., 2)) return 1;
    101138  }
    102139
     
    108145    cout << "Summing energy of order " << BondOrder+1 << " ..." << endl;
    109146    if (!EnergyFragments.SumSubManyBodyTerms(Energy, KeySet, BondOrder)) return 1;
    110     if (Hcorrected) {
     147    if (!NoHCorrection) {
    111148      HcorrectionFragments.SumSubManyBodyTerms(Hcorrection, KeySet, BondOrder);
    112149      if (!Energy.SumSubEnergy(EnergyFragments, &HcorrectionFragments, KeySet, BondOrder, 1.)) return 1;
    113       if (Hcorrected) Hcorrection.SumSubEnergy(HcorrectionFragments, NULL, KeySet, BondOrder, 1.);
    114     } else
     150      Hcorrection.SumSubEnergy(HcorrectionFragments, NULL, KeySet, BondOrder, 1.);
     151    } else 
    115152      if (!Energy.SumSubEnergy(EnergyFragments, NULL, KeySet, BondOrder, 1.)) return 1;
    116153    // --------- sum up Forces --------------------
     
    118155    if (!ForceFragments.SumSubManyBodyTerms(Force, KeySet, BondOrder)) return 1;
    119156    if (!Force.SumSubForces(ForceFragments, KeySet, BondOrder, 1.)) return 1;
     157    // --------- sum up Hessian --------------------
     158    if (!NoHessian) {
     159      cout << "Summing Hessian of order " << BondOrder+1 << " ..." << endl;
     160      if (!HessianFragments.SumSubManyBodyTerms(Hessian, KeySet, BondOrder)) return 1;
     161      if (!Hessian.SumSubHessians(HessianFragments, KeySet, BondOrder, 1.)) return 1;
     162    }
    120163    if (periode != NULL) { // also look for PAS values
    121       cout << "Summing shieldings of order " << BondOrder+1 << " ..." << endl;
     164      cout << "Summing shieldings and susceptibilities of order " << BondOrder+1 << " ..." << endl;
    122165      if (!ShieldingFragments.SumSubManyBodyTerms(Shielding, KeySet, BondOrder)) return 1;
    123166      if (!Shielding.SumSubForces(ShieldingFragments, KeySet, BondOrder, 1.)) return 1;
    124167      if (!ShieldingPASFragments.SumSubManyBodyTerms(ShieldingPAS, KeySet, BondOrder)) return 1;
    125168      if (!ShieldingPAS.SumSubForces(ShieldingPASFragments, KeySet, BondOrder, 1.)) return 1;
     169      if (!ChiFragments.SumSubManyBodyTerms(Chi, KeySet, BondOrder)) return 1;
     170      if (!Chi.SumSubForces(ChiFragments, KeySet, BondOrder, 1.)) return 1;
     171      if (!ChiPASFragments.SumSubManyBodyTerms(ChiPAS, KeySet, BondOrder)) return 1;
     172      if (!ChiPAS.SumSubForces(ChiPASFragments, KeySet, BondOrder, 1.)) return 1;
    126173    }
    127174
     
    134181    // forces
    135182    if (!Force.WriteLastMatrix(argv[1], (prefix.str()).c_str(), ForcesSuffix)) return 1;
     183    // hessian
     184    if (!NoHessian)
     185      if (!Hessian.WriteLastMatrix(argv[1], (prefix.str()).c_str(), HessianSuffix)) return 1;
    136186    // shieldings
    137187    if (periode != NULL) { // also look for PAS values
    138188      if (!Shielding.WriteLastMatrix(argv[1], (prefix.str()).c_str(), ShieldingSuffix)) return 1;
    139189      if (!ShieldingPAS.WriteLastMatrix(argv[1], (prefix.str()).c_str(), ShieldingPASSuffix)) return 1;
     190      if (!Chi.WriteLastMatrix(argv[1], (prefix.str()).c_str(), ChiSuffix)) return 1;
     191      if (!ChiPAS.WriteLastMatrix(argv[1], (prefix.str()).c_str(), ChiPASSuffix)) return 1;
    140192    }
    141193  }
     
    144196  prefix << dir << EnergyFragmentSuffix;
    145197  if (!EnergyFragments.WriteTotalFragments(argv[1], (prefix.str()).c_str())) return 1;
    146   if (Hcorrected) {
     198  if (!NoHCorrection) {
    147199    prefix.str(" ");
    148200    prefix << dir << HcorrectionFragmentSuffix;
     
    153205  if (!ForceFragments.WriteTotalFragments(argv[1], (prefix.str()).c_str())) return 1;
    154206  if (!CreateDataFragment(EnergyFragments, KeySet, argv[1], FRAGMENTPREFIX ENERGYPERFRAGMENT, "fragment energy versus the Fragment No", "today", CreateEnergy)) return 1;
     207  if (!NoHessian) {
     208    prefix.str(" ");
     209    prefix << dir << HessianFragmentSuffix;
     210    if (!HessianFragments.WriteTotalFragments(argv[1], (prefix.str()).c_str())) return 1;
     211  }
    155212  if (periode != NULL) { // also look for PAS values
    156213    prefix.str(" ");
     
    160217    prefix << dir << ShieldingPASFragmentSuffix;
    161218    if (!ShieldingPASFragments.WriteTotalFragments(argv[1], (prefix.str()).c_str())) return 1;
     219    prefix.str(" ");
     220    prefix << dir << ChiFragmentSuffix;
     221    if (!ChiFragments.WriteTotalFragments(argv[1], (prefix.str()).c_str())) return 1;
     222    prefix.str(" ");
     223    prefix << dir << ChiPASFragmentSuffix;
     224    if (!ChiPASFragments.WriteTotalFragments(argv[1], (prefix.str()).c_str())) return 1;
    162225  }
    163226
    164227  // write last matrices as fragments into central dir (not subdir as above), for analyzer to know index bounds
    165228  if (!Energy.WriteLastMatrix(argv[1], dir, EnergyFragmentSuffix)) return 1;
    166   if (Hcorrected) Hcorrection.WriteLastMatrix(argv[1], dir, HcorrectionFragmentSuffix);
     229  if (!NoHCorrection) Hcorrection.WriteLastMatrix(argv[1], dir, HcorrectionFragmentSuffix);
    167230  if (!Force.WriteLastMatrix(argv[1], dir, ForceFragmentSuffix)) return 1;
     231  if (!NoHessian)
     232    if (!Hessian.WriteLastMatrix(argv[1], dir, HessianFragmentSuffix)) return 1;
    168233  if (periode != NULL) { // also look for PAS values
    169234    if (!Shielding.WriteLastMatrix(argv[1], dir, ShieldingFragmentSuffix)) return 1;
    170235    if (!ShieldingPAS.WriteLastMatrix(argv[1], dir, ShieldingPASFragmentSuffix)) return 1;
     236    if (!Chi.WriteLastMatrix(argv[1], dir, ChiFragmentSuffix)) return 1;
     237    if (!ChiPAS.WriteLastMatrix(argv[1], dir, ChiPASFragmentSuffix)) return 1;
    171238  }
    172239
  • src/moleculelist.cpp

    r042f82 r36ec71  
    3535 * \return true - add successful
    3636 */
    37 bool MoleculeListClass::insert(molecule *mol)
     37void MoleculeListClass::insert(molecule *mol)
    3838{
    3939  mol->IndexNr = MaxIndex++;
    4040  ListOfMolecules.push_back(mol);
    41   return true;
    4241};
    4342
     
    128127  atom *Walker = NULL;
    129128  int Counts[MAX_ELEMENTS];
     129  double size=0;
     130  Vector Origin;
    130131
    131132  // header
    132   *out << "Index\tName\tNo.Atoms\tformula" << endl;
     133  *out << "Index\tName\t\tAtoms\tFormula\tCenter\tSize" << endl;
    133134  cout << Verbose(0) << "-----------------------------------------------" << endl;
    134135  if (ListOfMolecules.size() == 0)
    135136    *out << "\tNone" << endl;
    136137  else {
     138    Origin.Zero();
    137139    for (MoleculeList::iterator ListRunner = ListOfMolecules.begin(); ListRunner != ListOfMolecules.end(); ListRunner++) {
    138140      // reset element counts
    139141      for (int j = 0; j<MAX_ELEMENTS;j++)
    140142        Counts[j] = 0;
    141       // count atoms per element
     143      // count atoms per element and determine size of bounding sphere
     144      size=0.;
    142145      Walker = (*ListRunner)->start;
    143146      while (Walker->next != (*ListRunner)->end) {
    144147        Walker = Walker->next;
    145148        Counts[Walker->type->Z]++;
     149        if (Walker->x.DistanceSquared(&Origin) > size)
     150          size = Walker->x.DistanceSquared(&Origin);
    146151      }
    147152      // output Index, Name, number of atoms, chemical formula
    148153      *out << ((*ListRunner)->ActiveFlag ? "*" : " ") << (*ListRunner)->IndexNr << "\t" << (*ListRunner)->name << "\t\t" << (*ListRunner)->AtomCount << "\t";
    149154      Elemental = (*ListRunner)->elemente->end;
    150       while(Elemental != (*ListRunner)->elemente->start) {
     155      while(Elemental->previous != (*ListRunner)->elemente->start) {
    151156        Elemental = Elemental->previous;
    152157        if (Counts[Elemental->Z] != 0)
    153158          *out << Elemental->symbol << Counts[Elemental->Z];
    154159      }
    155       *out << endl;
     160      // Center and size
     161      *out << "\t" << (*ListRunner)->Center << "\t" << sqrt(size) << endl;
    156162    }
    157163  }
     
    164170molecule * MoleculeListClass::ReturnIndex(int index)
    165171{
    166   int count = 1;
    167   MoleculeList::iterator ListRunner = ListOfMolecules.begin();
    168   for(; ((ListRunner != ListOfMolecules.end()) && (count < index)); ListRunner++);
    169   if (count == index)
    170     return (*ListRunner);
    171   else
    172     return NULL;
     172  for(MoleculeList::iterator ListRunner = ListOfMolecules.begin(); ListRunner != ListOfMolecules.end(); ListRunner++)
     173    if ((*ListRunner)->IndexNr == index)
     174      return (*ListRunner);
     175  return NULL;
    173176};
    174177
     
    565568 * \param *configuration standard configuration to attach atoms in fragment molecule to.
    566569 * \param *SortIndex Index to map from the BFS labeling to the sequence how of Ion_Type in the config
     570 * \param DoPeriodic true - call ScanForPeriodicCorrection, false - don't
     571 * \param DoCentering true - call molecule::CenterEdge(), false - don't
    567572 * \return true - success (each file was written), false - something went wrong.
    568573 */
    569 bool MoleculeListClass::OutputConfigForListOfFragments(ofstream *out,
    570     config *configuration, int *SortIndex)
     574bool MoleculeListClass::OutputConfigForListOfFragments(ofstream *out, config *configuration, int *SortIndex)
    571575{
    572576  ofstream outputFragment;
  • src/molecules.cpp

    r042f82 r36ec71  
    6363  cell_size[1] = cell_size[3] = cell_size[4]= 0.;
    6464  strcpy(name,"none");
     65  IndexNr  = -1;
     66  ActiveFlag = false;
    6567};
    6668
     
    602604 * \param *filename filename
    603605 */
    604 void molecule::SetNameFromFilename(char *filename)
     606void molecule::SetNameFromFilename(const char *filename)
    605607{
    606608  int length = 0;
    607609  char *molname = strrchr(filename, '/')+sizeof(char);  // search for filename without dirs
    608   char *endname = strrchr(filename, '.');
     610  char *endname = strchr(molname, '.');
    609611  if ((endname == NULL) || (endname < molname))
    610612    length = strlen(molname);
     
    612614    length = strlen(molname) - strlen(endname);
    613615  strncpy(name, molname, length);
     616  name[length]='\0';
    614617};
    615618
     
    669672        }
    670673      }
    671       // matrix multiply
    672       x.MatrixMultiplication(M);
    673       ptr->x.CopyVector(&x);
    674674    }
    675675  }
     
    710710    max->AddVector(min);
    711711    Translate(min);
     712    Center.Zero();
    712713  }
    713714  delete(min);
     
    719720 * \param *center return vector for translation vector
    720721 */
    721 void molecule::CenterOrigin(ofstream *out, Vector *center)
     722void molecule::CenterOrigin(ofstream *out)
    722723{
    723724  int Num = 0;
    724725  atom *ptr = start->next;  // start at first in list
    725726
    726   for(int i=NDIM;i--;) // zero center vector
    727     center->x[i] = 0.;
     727  Center.Zero();
    728728
    729729  if (ptr != end) {   //list not empty?
     
    731731      ptr = ptr->next;
    732732      Num++;
    733       center->AddVector(&ptr->x);
    734     }
    735     center->Scale(-1./Num); // divide through total number (and sign for direction)
    736     Translate(center);
     733      Center.AddVector(&ptr->x);
     734    }
     735    Center.Scale(-1./Num); // divide through total number (and sign for direction)
     736    Translate(&Center);
     737    Center.Zero();
    737738  }
    738739};
     
    799800 * \param *center return vector for translation vector
    800801 */
    801 void molecule::CenterGravity(ofstream *out, Vector *center)
    802 {
    803   if (center == NULL) {
    804     DetermineCenter(*center);
    805     Translate(center);
    806     delete(center);
    807   } else {
    808     Translate(center);
    809   }
    810 };
     802void molecule::CenterPeriodic(ofstream *out)
     803{
     804  DeterminePeriodicCenter(Center);
     805};
     806
     807
     808/** Centers the center of gravity of the atoms at (0,0,0).
     809 * \param *out output stream for debugging
     810 * \param *center return vector for translation vector
     811 */
     812void molecule::CenterAtVector(ofstream *out, Vector *newcenter)
     813{
     814  Center.CopyVector(newcenter);
     815};
     816
    811817
    812818/** Scales all atoms by \a *factor.
     
    911917
    912918/** Determines center of molecule (yet not considering atom masses).
    913  * \param Center reference to return vector
    914  */
    915 void molecule::DetermineCenter(Vector &Center)
     919 * \param center reference to return vector
     920 */
     921void molecule::DeterminePeriodicCenter(Vector &center)
    916922{
    917923  atom *Walker = start;
     
    987993  Vector *CenterOfGravity = DetermineCenterOfGravity(out);
    988994
    989   CenterGravity(out, CenterOfGravity);
     995  CenterPeriodic(out);
    990996
    991997  // reset inertia tensor
     
    10831089};
    10841090
     1091/** Evaluates the potential energy used for constrained molecular dynamics.
     1092 * \f$V_i^{con} = c^{bond} \cdot | r_{P(i)} - R_i | + sum_{i \neq j} C^{min} \cdot \frac{1}{C_{ij}} + C^{inj} \Bigl (1 - \theta \bigl (\prod_{i \neq j} (P(i) - P(j)) \bigr ) \Bigr )\f$
     1093 *     where the first term points to the target in minimum distance, the second is a penalty for trajectories lying too close to each other (\f$C_{ij}$ is minimum distance between
     1094 *     trajectories i and j) and the third term is a penalty for two atoms trying to each the same target point.
     1095 * Note that for the second term we have to solve the following linear system:
     1096 * \f$-c_1 \cdot n_1 + c_2 \cdot n_2 + C \cdot n_3 = - p_2 + p_1\f$, where \f$c_1\f$, \f$c_2\f$ and \f$C\f$ are constants,
     1097 * offset vector \f$p_1\f$ in direction \f$n_1\f$, offset vector \f$p_2\f$ in direction \f$n_2\f$,
     1098 * \f$n_3\f$ is the normal vector to both directions. \f$C\f$ would be the minimum distance between the two lines.
     1099 * \sa molecule::MinimiseConstrainedPotential(), molecule::VerletForceIntegration()
     1100 * \param *out output stream for debugging
     1101 * \param *PermutationMap gives target ptr for each atom, array of size molecule::AtomCount (this is "x" in \f$ V^{con}(x) \f$ )
     1102 * \param startstep start configuration (MDStep in molecule::trajectories)
     1103 * \param endstep end configuration (MDStep in molecule::trajectories)
     1104 * \param *constants constant in front of each term
     1105 * \param IsAngstroem whether coordinates are in angstroem (true) or bohrradius (false)
     1106 * \return potential energy
     1107 * \note This routine is scaling quadratically which is not optimal.
     1108 * \todo There's a bit double counting going on for the first time, bu nothing to worry really about.
     1109 */
     1110double molecule::ConstrainedPotential(ofstream *out, atom **PermutationMap, int startstep, int endstep, double *constants, bool IsAngstroem)
     1111{
     1112  double result = 0., tmp, Norm1, Norm2;
     1113  atom *Walker = NULL, *Runner = NULL, *Sprinter = NULL;
     1114  Vector trajectory1, trajectory2, normal, TestVector;
     1115  gsl_matrix *A = gsl_matrix_alloc(NDIM,NDIM);
     1116  gsl_vector *x = gsl_vector_alloc(NDIM);
     1117
     1118  // go through every atom
     1119  Walker = start;
     1120  while (Walker->next != end) {
     1121    Walker = Walker->next;
     1122    // first term: distance to target
     1123    Runner = PermutationMap[Walker->nr];   // find target point
     1124    tmp = (Trajectories[Walker].R.at(startstep).Distance(&Trajectories[Runner].R.at(endstep)));
     1125    tmp *= IsAngstroem ? 1. : 1./AtomicLengthToAngstroem;
     1126    result += constants[0] * tmp;
     1127    //*out << Verbose(4) << "Adding " << tmp*constants[0] << "." << endl;
     1128   
     1129    // second term: sum of distances to other trajectories
     1130    Runner = start;
     1131    while (Runner->next != end) {
     1132      Runner = Runner->next;
     1133      if (Runner == Walker) // hence, we only go up to the Walker, not beyond (similar to i=0; i<j; i++)
     1134        break;
     1135      // determine normalized trajectories direction vector (n1, n2)
     1136      Sprinter = PermutationMap[Walker->nr];   // find first target point
     1137      trajectory1.CopyVector(&Trajectories[Sprinter].R.at(endstep));
     1138      trajectory1.SubtractVector(&Trajectories[Walker].R.at(startstep));
     1139      trajectory1.Normalize();
     1140      Norm1 = trajectory1.Norm();
     1141      Sprinter = PermutationMap[Runner->nr];   // find second target point
     1142      trajectory2.CopyVector(&Trajectories[Sprinter].R.at(endstep));
     1143      trajectory2.SubtractVector(&Trajectories[Runner].R.at(startstep));
     1144      trajectory2.Normalize();
     1145      Norm2 = trajectory1.Norm();
     1146      // check whether either is zero()
     1147      if ((Norm1 < MYEPSILON) && (Norm2 < MYEPSILON)) {
     1148        tmp = Trajectories[Walker].R.at(startstep).Distance(&Trajectories[Runner].R.at(startstep));
     1149      } else if (Norm1 < MYEPSILON) {
     1150        Sprinter = PermutationMap[Walker->nr];   // find first target point
     1151        trajectory1.CopyVector(&Trajectories[Sprinter].R.at(endstep));  // copy first offset
     1152        trajectory1.SubtractVector(&Trajectories[Runner].R.at(startstep));  // subtract second offset
     1153        trajectory2.Scale( trajectory1.ScalarProduct(&trajectory2) ); // trajectory2 is scaled to unity, hence we don't need to divide by anything
     1154        trajectory1.SubtractVector(&trajectory2);   // project the part in norm direction away
     1155        tmp = trajectory1.Norm();  // remaining norm is distance
     1156      } else if (Norm2 < MYEPSILON) {
     1157        Sprinter = PermutationMap[Runner->nr];   // find second target point
     1158        trajectory2.CopyVector(&Trajectories[Sprinter].R.at(endstep));  // copy second offset
     1159        trajectory2.SubtractVector(&Trajectories[Walker].R.at(startstep));  // subtract first offset
     1160        trajectory1.Scale( trajectory2.ScalarProduct(&trajectory1) ); // trajectory1 is scaled to unity, hence we don't need to divide by anything
     1161        trajectory2.SubtractVector(&trajectory1);   // project the part in norm direction away
     1162        tmp = trajectory2.Norm();  // remaining norm is distance
     1163      } else if ((fabs(trajectory1.ScalarProduct(&trajectory2)/Norm1/Norm2) - 1.) < MYEPSILON) { // check whether they're linear dependent
     1164//        *out << Verbose(3) << "Both trajectories of " << *Walker << " and " << *Runner << " are linear dependent: ";
     1165//        *out << trajectory1;
     1166//        *out << " and ";
     1167//        *out << trajectory2;
     1168        tmp = Trajectories[Walker].R.at(startstep).Distance(&Trajectories[Runner].R.at(startstep));
     1169//        *out << " with distance " << tmp << "." << endl;
     1170      } else { // determine distance by finding minimum distance
     1171//        *out << Verbose(3) << "Both trajectories of " << *Walker << " and " << *Runner << " are linear independent ";
     1172//        *out << endl;
     1173//        *out << "First Trajectory: ";
     1174//        *out << trajectory1 << endl;
     1175//        *out << "Second Trajectory: ";
     1176//        *out << trajectory2 << endl;
     1177        // determine normal vector for both
     1178        normal.MakeNormalVector(&trajectory1, &trajectory2);
     1179        // print all vectors for debugging
     1180//        *out << "Normal vector in between: ";
     1181//        *out << normal << endl;
     1182        // setup matrix
     1183        for (int i=NDIM;i--;) {
     1184          gsl_matrix_set(A, 0, i, trajectory1.x[i]);
     1185          gsl_matrix_set(A, 1, i, trajectory2.x[i]);
     1186          gsl_matrix_set(A, 2, i, normal.x[i]);
     1187          gsl_vector_set(x,i, (Trajectories[Walker].R.at(startstep).x[i] - Trajectories[Runner].R.at(startstep).x[i]));
     1188        }
     1189        // solve the linear system by Householder transformations
     1190        gsl_linalg_HH_svx(A, x);
     1191        // distance from last component
     1192        tmp = gsl_vector_get(x,2);
     1193//        *out << " with distance " << tmp << "." << endl;
     1194        // test whether we really have the intersection (by checking on c_1 and c_2)
     1195        TestVector.CopyVector(&Trajectories[Runner].R.at(startstep));
     1196        trajectory2.Scale(gsl_vector_get(x,1));
     1197        TestVector.AddVector(&trajectory2);
     1198        normal.Scale(gsl_vector_get(x,2));
     1199        TestVector.AddVector(&normal);
     1200        TestVector.SubtractVector(&Trajectories[Walker].R.at(startstep));
     1201        trajectory1.Scale(gsl_vector_get(x,0));
     1202        TestVector.SubtractVector(&trajectory1);
     1203        if (TestVector.Norm() < MYEPSILON) {
     1204//          *out << Verbose(2) << "Test: ok.\tDistance of " << tmp << " is correct." << endl; 
     1205        } else {
     1206//          *out << Verbose(2) << "Test: failed.\tIntersection is off by ";
     1207//          *out << TestVector;
     1208//          *out << "." << endl; 
     1209        }
     1210      }
     1211      // add up
     1212      tmp *= IsAngstroem ? 1. : 1./AtomicLengthToAngstroem;
     1213      if (fabs(tmp) > MYEPSILON) {
     1214        result += constants[1] * 1./tmp;
     1215        //*out << Verbose(4) << "Adding " << 1./tmp*constants[1] << "." << endl;
     1216      }
     1217    }
     1218     
     1219    // third term: penalty for equal targets
     1220    Runner = start;
     1221    while (Runner->next != end) {
     1222      Runner = Runner->next;
     1223      if ((PermutationMap[Walker->nr] == PermutationMap[Runner->nr]) && (Walker->nr < Runner->nr)) {
     1224        Sprinter = PermutationMap[Walker->nr];
     1225//        *out << *Walker << " and " << *Runner << " are heading to the same target at ";
     1226//        *out << Trajectories[Sprinter].R.at(endstep);
     1227//        *out << ", penalting." << endl;
     1228        result += constants[2];
     1229        //*out << Verbose(4) << "Adding " << constants[2] << "." << endl;
     1230      }
     1231    }
     1232  }
     1233 
     1234  return result;
     1235};
     1236
     1237void PrintPermutationMap(ofstream *out, atom **PermutationMap, int Nr)
     1238{
     1239  stringstream zeile1, zeile2;
     1240  int *DoubleList = (int *) Malloc(Nr*sizeof(int), "PrintPermutationMap: *DoubleList");
     1241  int doubles = 0;
     1242  for (int i=0;i<Nr;i++)
     1243    DoubleList[i] = 0;
     1244  zeile1 << "PermutationMap: ";
     1245  zeile2 << "                ";
     1246  for (int i=0;i<Nr;i++) {
     1247    DoubleList[PermutationMap[i]->nr]++;
     1248    zeile1 << i << " ";
     1249    zeile2 << PermutationMap[i]->nr << " ";
     1250  }
     1251  for (int i=0;i<Nr;i++)
     1252    if (DoubleList[i] > 1)
     1253    doubles++;
     1254 // *out << "Found " << doubles << " Doubles." << endl;
     1255  Free((void **)&DoubleList, "PrintPermutationMap: *DoubleList");
     1256//  *out << zeile1.str() << endl << zeile2.str() << endl;
     1257};
     1258
     1259/** Minimises the extra potential for constrained molecular dynamics and gives forces and the constrained potential energy.
     1260 * We do the following:
     1261 *  -# Generate a distance list from all source to all target points
     1262 *  -# Sort this per source point
     1263 *  -# Take for each source point the target point with minimum distance, use this as initial permutation
     1264 *  -# check whether molecule::ConstrainedPotential() is greater than injective penalty
     1265 *     -# If so, we go through each source point, stepping down in the sorted target point distance list and re-checking potential.
     1266 *  -# Next, we only apply transformations that keep the injectivity of the permutations list.
     1267 *  -# Hence, for one source point we step down the ladder and seek the corresponding owner of this new target
     1268 *     point and try to change it for one with lesser distance, or for the next one with greater distance, but only
     1269 *     if this decreases the conditional potential.
     1270 *  -# finished.
     1271 *  -# Then, we calculate the forces by taking the spatial derivative, where we scale the potential to such a degree,
     1272 *     that the total force is always pointing in direction of the constraint force (ensuring that we move in the
     1273 *     right direction).
     1274 *  -# Finally, we calculate the potential energy and return.
     1275 * \param *out output stream for debugging
     1276 * \param **PermutationMap on return: mapping between the atom label of the initial and the final configuration
     1277 * \param startstep current MD step giving initial position between which and \a endstep we perform the constrained MD (as further steps are always concatenated)
     1278 * \param endstep step giving final position in constrained MD
     1279 * \param IsAngstroem whether coordinates are in angstroem (true) or bohrradius (false)
     1280 * \sa molecule::VerletForceIntegration()
     1281 * \return potential energy (and allocated **PermutationMap (array of molecule::AtomCount ^2)
     1282 * \todo The constrained potential's constants are set to fixed values right now, but they should scale based on checks of the system in order
     1283 *       to ensure they're properties (e.g. constants[2] always greater than the energy of the system).
     1284 * \bug this all is not O(N log N) but O(N^2)
     1285 */
     1286double molecule::MinimiseConstrainedPotential(ofstream *out, atom **&PermutationMap, int startstep, int endstep, bool IsAngstroem)
     1287{
     1288  double Potential, OldPotential, OlderPotential;
     1289  PermutationMap = (atom **) Malloc(AtomCount*sizeof(atom *), "molecule::MinimiseConstrainedPotential: **PermutationMap");
     1290  DistanceMap **DistanceList = (DistanceMap **) Malloc(AtomCount*sizeof(DistanceMap *), "molecule::MinimiseConstrainedPotential: **DistanceList");
     1291  DistanceMap::iterator *DistanceIterators = (DistanceMap::iterator *) Malloc(AtomCount*sizeof(DistanceMap::iterator), "molecule::MinimiseConstrainedPotential: *DistanceIterators");
     1292  int *DoubleList = (int *) Malloc(AtomCount*sizeof(int), "molecule::MinimiseConstrainedPotential: *DoubleList");
     1293  DistanceMap::iterator *StepList = (DistanceMap::iterator *) Malloc(AtomCount*sizeof(DistanceMap::iterator), "molecule::MinimiseConstrainedPotential: *StepList");
     1294  double constants[3];
     1295  int round;
     1296  atom *Walker = NULL, *Runner = NULL, *Sprinter = NULL;
     1297  DistanceMap::iterator Rider, Strider;
     1298 
     1299  /// Minimise the potential
     1300  // set Lagrange multiplier constants
     1301  constants[0] = 10.;
     1302  constants[1] = 1.;
     1303  constants[2] = 1e+7;    // just a huge penalty
     1304  // generate the distance list
     1305  *out << Verbose(1) << "Creating the distance list ... " << endl;
     1306  for (int i=AtomCount; i--;) {
     1307    DoubleList[i] = 0;  // stores for how many atoms in startstep this atom is a target in endstep
     1308    DistanceList[i] = new DistanceMap;    // is the distance sorted target list per atom
     1309    DistanceList[i]->clear();
     1310  }
     1311  *out << Verbose(1) << "Filling the distance list ... " << endl;
     1312  Walker = start;
     1313  while (Walker->next != end) {
     1314    Walker = Walker->next;
     1315    Runner = start;
     1316    while(Runner->next != end) {
     1317      Runner = Runner->next;
     1318      DistanceList[Walker->nr]->insert( DistancePair(Trajectories[Walker].R.at(startstep).Distance(&Trajectories[Runner].R.at(endstep)), Runner) );
     1319    }
     1320  }
     1321  // create the initial PermutationMap (source -> target)
     1322  Walker = start;
     1323  while (Walker->next != end) {
     1324    Walker = Walker->next;
     1325    StepList[Walker->nr] = DistanceList[Walker->nr]->begin();    // stores the step to the next iterator that could be a possible next target
     1326    PermutationMap[Walker->nr] = DistanceList[Walker->nr]->begin()->second;   // always pick target with the smallest distance
     1327    DoubleList[DistanceList[Walker->nr]->begin()->second->nr]++;            // increase this target's source count (>1? not injective)
     1328    DistanceIterators[Walker->nr] = DistanceList[Walker->nr]->begin();    // and remember which one we picked
     1329    *out << *Walker << " starts with distance " << DistanceList[Walker->nr]->begin()->first << "." << endl;
     1330  }
     1331  *out << Verbose(1) << "done." << endl;
     1332  // make the PermutationMap injective by checking whether we have a non-zero constants[2] term in it
     1333  *out << Verbose(1) << "Making the PermutationMap injective ... " << endl;
     1334  Walker = start;
     1335  DistanceMap::iterator NewBase;
     1336  OldPotential = fabs(ConstrainedPotential(out, PermutationMap, startstep, endstep, constants, IsAngstroem));
     1337  while ((OldPotential) > constants[2]) {
     1338    PrintPermutationMap(out, PermutationMap, AtomCount);
     1339    Walker = Walker->next;
     1340    if (Walker == end) // round-robin at the end
     1341      Walker = start->next;
     1342    if (DoubleList[DistanceIterators[Walker->nr]->second->nr] <= 1)  // no need to make those injective that aren't
     1343      continue;
     1344    // now, try finding a new one
     1345    NewBase = DistanceIterators[Walker->nr];  // store old base
     1346    do {
     1347      NewBase++;  // take next further distance in distance to targets list that's a target of no one
     1348    } while ((DoubleList[NewBase->second->nr] != 0) && (NewBase != DistanceList[Walker->nr]->end()));
     1349    if (NewBase != DistanceList[Walker->nr]->end()) {
     1350      PermutationMap[Walker->nr] = NewBase->second;
     1351      Potential = fabs(ConstrainedPotential(out, PermutationMap, startstep, endstep, constants, IsAngstroem));
     1352      if (Potential > OldPotential) { // undo
     1353        PermutationMap[Walker->nr] = DistanceIterators[Walker->nr]->second;
     1354      } else {  // do
     1355        DoubleList[DistanceIterators[Walker->nr]->second->nr]--;  // decrease the old entry in the doubles list
     1356        DoubleList[NewBase->second->nr]++;    // increase the old entry in the doubles list
     1357        DistanceIterators[Walker->nr] = NewBase;
     1358        OldPotential = Potential;
     1359        *out << Verbose(3) << "Found a new permutation, new potential is " << OldPotential << "." << endl;
     1360      }
     1361    }
     1362  }
     1363  for (int i=AtomCount; i--;) // now each single entry in the DoubleList should be <=1
     1364    if (DoubleList[i] > 1) {
     1365      cerr << "Failed to create an injective PermutationMap!" << endl;
     1366      exit(1);
     1367    }
     1368  *out << Verbose(1) << "done." << endl;
     1369  Free((void **)&DoubleList, "molecule::MinimiseConstrainedPotential: *DoubleList");
     1370  // argument minimise the constrained potential in this injective PermutationMap
     1371  *out << Verbose(1) << "Argument minimising the PermutationMap, at current potential " << OldPotential << " ... " << endl;
     1372  OldPotential = 1e+10;
     1373  round = 0;
     1374  do {
     1375    *out << "Starting round " << ++round << " ... " << endl;
     1376    OlderPotential = OldPotential;
     1377    do {
     1378      Walker = start;
     1379      while (Walker->next != end) { // pick one
     1380        Walker = Walker->next;
     1381        PrintPermutationMap(out, PermutationMap, AtomCount);
     1382        Sprinter = DistanceIterators[Walker->nr]->second;   // store initial partner
     1383        Strider = DistanceIterators[Walker->nr];  //remember old iterator
     1384        DistanceIterators[Walker->nr] = StepList[Walker->nr]; 
     1385        if (DistanceIterators[Walker->nr] == DistanceList[Walker->nr]->end()) {// stop, before we run through the list and still on
     1386          DistanceIterators[Walker->nr] == DistanceList[Walker->nr]->begin();
     1387          break;
     1388        }
     1389        //*out << Verbose(2) << "Current Walker: " << *Walker << " with old/next candidate " << *Sprinter << "/" << *DistanceIterators[Walker->nr]->second << "." << endl;
     1390        // find source of the new target
     1391        Runner = start->next;
     1392        while(Runner != end) { // find the source whose toes we might be stepping on (Walker's new target should be in use by another already)
     1393          if (PermutationMap[Runner->nr] == DistanceIterators[Walker->nr]->second) {
     1394            //*out << Verbose(2) << "Found the corresponding owner " << *Runner << " to " << *PermutationMap[Runner->nr] << "." << endl;
     1395            break;
     1396          }
     1397          Runner = Runner->next;
     1398        }
     1399        if (Runner != end) { // we found the other source
     1400          // then look in its distance list for Sprinter
     1401          Rider = DistanceList[Runner->nr]->begin();
     1402          for (; Rider != DistanceList[Runner->nr]->end(); Rider++)
     1403            if (Rider->second == Sprinter)
     1404              break;
     1405          if (Rider != DistanceList[Runner->nr]->end()) { // if we have found one
     1406            //*out << Verbose(2) << "Current Other: " << *Runner << " with old/next candidate " << *PermutationMap[Runner->nr] << "/" << *Rider->second << "." << endl;
     1407            // exchange both
     1408            PermutationMap[Walker->nr] = DistanceIterators[Walker->nr]->second; // put next farther distance into PermutationMap
     1409            PermutationMap[Runner->nr] = Sprinter;  // and hand the old target to its respective owner
     1410            PrintPermutationMap(out, PermutationMap, AtomCount);
     1411            // calculate the new potential
     1412            //*out << Verbose(2) << "Checking new potential ..." << endl;
     1413            Potential = ConstrainedPotential(out, PermutationMap, startstep, endstep, constants, IsAngstroem);
     1414            if (Potential > OldPotential) { // we made everything worse! Undo ...
     1415              //*out << Verbose(3) << "Nay, made the potential worse: " << Potential << " vs. " << OldPotential << "!" << endl;
     1416              //*out << Verbose(3) << "Setting " << *Runner << "'s source to " << *DistanceIterators[Runner->nr]->second << "." << endl;
     1417              // Undo for Runner (note, we haven't moved the iteration yet, we may use this)
     1418              PermutationMap[Runner->nr] = DistanceIterators[Runner->nr]->second;
     1419              // Undo for Walker
     1420              DistanceIterators[Walker->nr] = Strider;  // take next farther distance target
     1421              //*out << Verbose(3) << "Setting " << *Walker << "'s source to " << *DistanceIterators[Walker->nr]->second << "." << endl;
     1422              PermutationMap[Walker->nr] = DistanceIterators[Walker->nr]->second;
     1423            } else {
     1424              DistanceIterators[Runner->nr] = Rider;  // if successful also move the pointer in the iterator list
     1425              *out << Verbose(3) << "Found a better permutation, new potential is " << Potential << " vs." << OldPotential << "." << endl;
     1426              OldPotential = Potential;
     1427            }
     1428            if (Potential > constants[2]) {
     1429              cerr << "ERROR: The two-step permutation procedure did not maintain injectivity!" << endl;
     1430              exit(255);
     1431            }
     1432            //*out << endl;
     1433          } else {
     1434            cerr << "ERROR: " << *Runner << " was not the owner of " << *Sprinter << "!" << endl;
     1435            exit(255);
     1436          }
     1437        } else {
     1438          PermutationMap[Walker->nr] = DistanceIterators[Walker->nr]->second; // new target has no source!
     1439        }
     1440        StepList[Walker->nr]++; // take next farther distance target
     1441      }
     1442    } while (Walker->next != end);
     1443  } while ((OlderPotential - OldPotential) > 1e-3);
     1444  *out << Verbose(1) << "done." << endl;
     1445
     1446 
     1447  /// free memory and return with evaluated potential
     1448  for (int i=AtomCount; i--;)
     1449    DistanceList[i]->clear();
     1450  Free((void **)&DistanceList, "molecule::MinimiseConstrainedPotential: **DistanceList");
     1451  Free((void **)&DistanceIterators, "molecule::MinimiseConstrainedPotential: *DistanceIterators");
     1452  return ConstrainedPotential(out, PermutationMap, startstep, endstep, constants, IsAngstroem);
     1453};
     1454
     1455/** Evaluates the (distance-related part) of the constrained potential for the constrained forces.
     1456 * \param *out output stream for debugging
     1457 * \param startstep current MD step giving initial position between which and \a endstep we perform the constrained MD (as further steps are always concatenated)
     1458 * \param endstep step giving final position in constrained MD
     1459 * \param **PermutationMap mapping between the atom label of the initial and the final configuration
     1460 * \param *Force ForceMatrix containing force vectors from the external energy functional minimisation.
     1461 * \todo the constant for the constrained potential distance part is hard-coded independently of the hard-coded value in MinimiseConstrainedPotential()
     1462 */
     1463void molecule::EvaluateConstrainedForces(ofstream *out, int startstep, int endstep, atom **PermutationMap, ForceMatrix *Force)
     1464{
     1465  double constant = 10.;
     1466  atom *Walker = NULL, *Sprinter = NULL;
     1467 
     1468  /// evaluate forces (only the distance to target dependent part) with the final PermutationMap
     1469  *out << Verbose(1) << "Calculating forces and adding onto ForceMatrix ... " << endl;
     1470  Walker = start;
     1471  while (Walker->next != NULL) {
     1472    Walker = Walker->next;
     1473    Sprinter = PermutationMap[Walker->nr];
     1474    // set forces
     1475    for (int i=NDIM;i++;)
     1476      Force->Matrix[0][Walker->nr][5+i] += 2.*constant*sqrt(Trajectories[Walker].R.at(startstep).Distance(&Trajectories[Sprinter].R.at(endstep)));
     1477  } 
     1478  *out << Verbose(1) << "done." << endl;
     1479};
     1480
     1481/** Performs a linear interpolation between two desired atomic configurations with a given number of steps.
     1482 * Note, step number is config::MaxOuterStep
     1483 * \param *out output stream for debugging
     1484 * \param startstep stating initial configuration in molecule::Trajectories
     1485 * \param endstep stating final configuration in molecule::Trajectories
     1486 * \param &config configuration structure
     1487 * \return true - success in writing step files, false - error writing files or only one step in molecule::Trajectories
     1488 */
     1489bool molecule::LinearInterpolationBetweenConfiguration(ofstream *out, int startstep, int endstep, const char *prefix, config &configuration)
     1490{
     1491  molecule *mol = NULL;
     1492  bool status = true;
     1493  int MaxSteps = configuration.MaxOuterStep;
     1494  MoleculeListClass *MoleculePerStep = new MoleculeListClass();
     1495  // Get the Permutation Map by MinimiseConstrainedPotential
     1496  atom **PermutationMap = NULL;
     1497  atom *Walker = NULL, *Sprinter = NULL;
     1498  MinimiseConstrainedPotential(out, PermutationMap, startstep, endstep, configuration.GetIsAngstroem());
     1499
     1500  // check whether we have sufficient space in Trajectories for each atom
     1501  Walker = start;
     1502  while (Walker->next != end) {
     1503    Walker = Walker->next;
     1504    if (Trajectories[Walker].R.size() <= (unsigned int)(MaxSteps)) {
     1505      //cout << "Increasing size for trajectory array of " << keyword << " to " << (MaxSteps+1) << "." << endl;
     1506      Trajectories[Walker].R.resize(MaxSteps+1);
     1507      Trajectories[Walker].U.resize(MaxSteps+1);
     1508      Trajectories[Walker].F.resize(MaxSteps+1);
     1509    }
     1510  }
     1511  // push endstep to last one
     1512  Walker = start;
     1513  while (Walker->next != end) { // remove the endstep (is now the very last one)
     1514    Walker = Walker->next;
     1515    for (int n=NDIM;n--;) {
     1516      Trajectories[Walker].R.at(MaxSteps).x[n] = Trajectories[Walker].R.at(endstep).x[n];
     1517      Trajectories[Walker].U.at(MaxSteps).x[n] = Trajectories[Walker].U.at(endstep).x[n];
     1518      Trajectories[Walker].F.at(MaxSteps).x[n] = Trajectories[Walker].F.at(endstep).x[n];
     1519    }
     1520  }
     1521  endstep = MaxSteps;
     1522 
     1523  // go through all steps and add the molecular configuration to the list and to the Trajectories of \a this molecule
     1524  *out << Verbose(1) << "Filling intermediate " << MaxSteps << " steps with MDSteps of " << MDSteps << "." << endl;
     1525  for (int step = 0; step <= MaxSteps; step++) {
     1526    mol = new molecule(elemente);
     1527    MoleculePerStep->insert(mol);
     1528    Walker = start;
     1529    while (Walker->next != end) {
     1530      Walker = Walker->next;
     1531      // add to molecule list
     1532      Sprinter = mol->AddCopyAtom(Walker);
     1533      for (int n=NDIM;n--;) {
     1534        Sprinter->x.x[n] = Trajectories[Walker].R.at(startstep).x[n] + (Trajectories[PermutationMap[Walker->nr]].R.at(endstep).x[n] - Trajectories[Walker].R.at(startstep).x[n])*((double)step/(double)MaxSteps);
     1535        // add to Trajectories
     1536        //*out << Verbose(3) << step << ">=" << MDSteps-1 << endl;
     1537        if (step < MaxSteps) {
     1538          Trajectories[Walker].R.at(step).x[n] = Trajectories[Walker].R.at(startstep).x[n] + (Trajectories[PermutationMap[Walker->nr]].R.at(endstep).x[n] - Trajectories[Walker].R.at(startstep).x[n])*((double)step/(double)MaxSteps);
     1539          Trajectories[Walker].U.at(step).x[n] = 0.;
     1540          Trajectories[Walker].F.at(step).x[n] = 0.;
     1541        }
     1542      }
     1543    }
     1544  }
     1545  MDSteps = MaxSteps+1;   // otherwise new Trajectories' points aren't stored on save&exit
     1546 
     1547  // store the list to single step files
     1548  int *SortIndex = (int *) Malloc(AtomCount*sizeof(int), "molecule::LinearInterpolationBetweenConfiguration: *SortIndex");
     1549  for (int i=AtomCount; i--; )
     1550    SortIndex[i] = i;
     1551  status = MoleculePerStep->OutputConfigForListOfFragments(out, &configuration, SortIndex);
     1552 
     1553  // free and return
     1554  Free((void **)&PermutationMap, "molecule::MinimiseConstrainedPotential: *PermutationMap");
     1555  delete(MoleculePerStep);
     1556  return status;
     1557};
     1558
    10851559/** Parses nuclear forces from file and performs Verlet integration.
    10861560 * Note that we assume the parsed forces to be in atomic units (hence, if coordinates are in angstroem, we
    10871561 * have to transform them).
    10881562 * This adds a new MD step to the config file.
     1563 * \param *out output stream for debugging
    10891564 * \param *file filename
     1565 * \param config structure with config::Deltat, config::IsAngstroem, config::DoConstrained
    10901566 * \param delta_t time step width in atomic units
    10911567 * \param IsAngstroem whether coordinates are in angstroem (true) or bohrradius (false)
     1568 * \param DoConstrained whether we perform a constrained (>0, target step in molecule::trajectories) or unconstrained (0) molecular dynamics, \sa molecule::MinimiseConstrainedPotential()
    10921569 * \return true - file found and parsed, false - file not found or imparsable
    1093  */
    1094 bool molecule::VerletForceIntegration(char *file, double delta_t, bool IsAngstroem)
    1095 {
    1096   element *runner = elemente->start;
     1570 * \todo This is not yet checked if it is correctly working with DoConstrained set to true.
     1571 */
     1572bool molecule::VerletForceIntegration(ofstream *out, char *file, config &configuration)
     1573{
    10971574  atom *walker = NULL;
    1098   int AtomNo;
    10991575  ifstream input(file);
    11001576  string token;
    11011577  stringstream item;
    1102   double a, IonMass;
     1578  double IonMass, Vector[NDIM], ConstrainedPotentialEnergy, ActualTemp;
    11031579  ForceMatrix Force;
    1104   Vector tmpvector;
    11051580
    11061581  CountElements();  // make sure ElementsInMolecule is up to date
     
    11201595    }
    11211596    // correct Forces
    1122 //    for(int d=0;d<NDIM;d++)
    1123 //      tmpvector.x[d] = 0.;
    1124 //    for(int i=0;i<AtomCount;i++)
    1125 //      for(int d=0;d<NDIM;d++) {
    1126 //        tmpvector.x[d] += Force.Matrix[0][i][d+5];
    1127 //      }
    1128 //    for(int i=0;i<AtomCount;i++)
    1129 //      for(int d=0;d<NDIM;d++) {
    1130 //        Force.Matrix[0][i][d+5] -= tmpvector.x[d]/(double)AtomCount;
    1131 //      }
     1597    for(int d=0;d<NDIM;d++)
     1598      Vector[d] = 0.;
     1599    for(int i=0;i<AtomCount;i++)
     1600      for(int d=0;d<NDIM;d++) {
     1601        Vector[d] += Force.Matrix[0][i][d+5];
     1602      }
     1603    for(int i=0;i<AtomCount;i++)
     1604      for(int d=0;d<NDIM;d++) {
     1605        Force.Matrix[0][i][d+5] -= Vector[d]/(double)AtomCount;
     1606      }
     1607    // solve a constrained potential if we are meant to
     1608    if (configuration.DoConstrainedMD) {
     1609      // calculate forces and potential
     1610      atom **PermutationMap = NULL;
     1611      ConstrainedPotentialEnergy = MinimiseConstrainedPotential(out, PermutationMap,configuration.DoConstrainedMD, 0, configuration.GetIsAngstroem());
     1612      EvaluateConstrainedForces(out, configuration.DoConstrainedMD, 0, PermutationMap, &Force);
     1613      Free((void **)&PermutationMap, "molecule::MinimiseConstrainedPotential: *PermutationMap");
     1614    }
     1615   
    11321616    // and perform Verlet integration for each atom with position, velocity and force vector
    1133     runner = elemente->start;
    1134     while (runner->next != elemente->end) { // go through every element
    1135       runner = runner->next;
    1136       IonMass = runner->mass;
    1137       a = delta_t*0.5/IonMass;        // (F+F_old)/2m = a and thus: v = (F+F_old)/2m * t = (F + F_old) * a
    1138       if (ElementsInMolecule[runner->Z]) { // if this element got atoms
    1139         AtomNo = 0;
     1617    walker = start;
     1618    while (walker->next != end) { // go through every atom of this element
     1619      walker = walker->next;
     1620      //a = configuration.Deltat*0.5/walker->type->mass;        // (F+F_old)/2m = a and thus: v = (F+F_old)/2m * t = (F + F_old) * a
     1621      // check size of vectors
     1622      if (Trajectories[walker].R.size() <= (unsigned int)(MDSteps)) {
     1623        //out << "Increasing size for trajectory array of " << *walker << " to " << (size+10) << "." << endl;
     1624        Trajectories[walker].R.resize(MDSteps+10);
     1625        Trajectories[walker].U.resize(MDSteps+10);
     1626        Trajectories[walker].F.resize(MDSteps+10);
     1627      }
     1628     
     1629      // Update R (and F)
     1630      for (int d=0; d<NDIM; d++) {
     1631        Trajectories[walker].F.at(MDSteps).x[d] = -Force.Matrix[0][walker->nr][d+5]*(configuration.GetIsAngstroem() ? AtomicLengthToAngstroem : 1.);
     1632        Trajectories[walker].R.at(MDSteps).x[d] = Trajectories[walker].R.at(MDSteps-1).x[d];
     1633        Trajectories[walker].R.at(MDSteps).x[d] += configuration.Deltat*(Trajectories[walker].U.at(MDSteps-1).x[d]);     // s(t) = s(0) + v * deltat + 1/2 a * deltat^2
     1634        Trajectories[walker].R.at(MDSteps).x[d] += 0.5*configuration.Deltat*configuration.Deltat*(Trajectories[walker].F.at(MDSteps).x[d]/walker->type->mass);     // F = m * a and s = 0.5 * F/m * t^2 = F * a * t
     1635      }
     1636      // Update U
     1637      for (int d=0; d<NDIM; d++) {
     1638        Trajectories[walker].U.at(MDSteps).x[d] = Trajectories[walker].U.at(MDSteps-1).x[d];
     1639        Trajectories[walker].U.at(MDSteps).x[d] += configuration.Deltat * (Trajectories[walker].F.at(MDSteps).x[d]+Trajectories[walker].F.at(MDSteps-1).x[d]/walker->type->mass); // v = F/m * t
     1640      }
     1641//      out << "Integrated position&velocity of step " << (MDSteps) << ": (";
     1642//      for (int d=0;d<NDIM;d++)
     1643//        out << Trajectories[walker].R.at(MDSteps).x[d] << " ";          // next step
     1644//      out << ")\t(";
     1645//      for (int d=0;d<NDIM;d++)
     1646//        cout << Trajectories[walker].U.at(MDSteps).x[d] << " ";          // next step
     1647//      out << ")" << endl;
     1648            // next atom
     1649    }
     1650  }
     1651  // correct velocities (rather momenta) so that center of mass remains motionless
     1652  for(int d=0;d<NDIM;d++)
     1653    Vector[d] = 0.;
     1654  IonMass = 0.;
     1655  walker = start;
     1656  while (walker->next != end) { // go through every atom
     1657    walker = walker->next;
     1658    IonMass += walker->type->mass;  // sum up total mass
     1659    for(int d=0;d<NDIM;d++) {
     1660      Vector[d] += Trajectories[walker].U.at(MDSteps).x[d]*walker->type->mass;
     1661    }
     1662  }
     1663  // correct velocities (rather momenta) so that center of mass remains motionless
     1664  for(int d=0;d<NDIM;d++)
     1665    Vector[d] /= IonMass;
     1666  ActualTemp = 0.;
     1667  walker = start;
     1668  while (walker->next != end) { // go through every atom of this element
     1669    walker = walker->next;
     1670    for(int d=0;d<NDIM;d++) {
     1671      Trajectories[walker].U.at(MDSteps).x[d] -= Vector[d];
     1672      ActualTemp += 0.5 * walker->type->mass * Trajectories[walker].U.at(MDSteps).x[d] * Trajectories[walker].U.at(MDSteps).x[d];
     1673    }
     1674  }
     1675  Thermostats(configuration, ActualTemp, Berendsen);
     1676  MDSteps++;
     1677
     1678
     1679  // exit
     1680  return true;
     1681};
     1682
     1683/** Implementation of various thermostats.
     1684 * All these thermostats apply an additional force which has the following forms:
     1685 * -# Woodcock
     1686 *  \f$p_i \rightarrow \sqrt{\frac{T_0}{T}} \cdot p_i\f$
     1687 * -# Gaussian
     1688 *  \f$ \frac{ \sum_i \frac{p_i}{m_i} \frac{\partial V}{\partial q_i}} {\sum_i \frac{p^2_i}{m_i}} \cdot p_i\f$
     1689 * -# Langevin
     1690 *  \f$p_{i,n} \rightarrow \sqrt{1-\alpha^2} p_{i,0} + \alpha p_r\f$ 
     1691 * -# Berendsen
     1692 *  \f$p_i \rightarrow \left [ 1+ \frac{\delta t}{\tau_T} \left ( \frac{T_0}{T} \right ) \right ]^{\frac{1}{2}} \cdot p_i\f$
     1693 * -# Nose-Hoover
     1694 *  \f$\zeta p_i \f$ with \f$\frac{\partial \zeta}{\partial t} = \frac{1}{M_s} \left ( \sum^N_{i=1} \frac{p_i^2}{m_i} - g k_B T \right )\f$
     1695 * These Thermostats either simply rescale the velocities, thus this function should be called after ion velocities have been updated, and/or
     1696 * have a constraint force acting additionally on the ions. In the latter case, the ion speeds have to be modified
     1697 * belatedly and the constraint force set.
     1698 * \param *P Problem at hand
     1699 * \param i which of the thermostats to take: 0 - none, 1 - Woodcock, 2 - Gaussian, 3 - Langevin, 4 - Berendsen, 5 - Nose-Hoover
     1700 * \sa InitThermostat()
     1701 */
     1702void molecule::Thermostats(config &configuration, double ActualTemp, int Thermostat)
     1703{
     1704  double ekin = 0.;
     1705  double E = 0., G = 0.;
     1706  double delta_alpha = 0.;
     1707  double ScaleTempFactor;
     1708  double sigma;
     1709  double IonMass;
     1710  int d;
     1711  gsl_rng * r;
     1712  const gsl_rng_type * T;
     1713  double *U = NULL, *F = NULL, FConstraint[NDIM];
     1714  atom *walker = NULL;
     1715 
     1716  // calculate scale configuration
     1717  ScaleTempFactor = configuration.TargetTemp/ActualTemp;
     1718   
     1719  // differentating between the various thermostats
     1720  switch(Thermostat) {
     1721     case None:
     1722      cout << Verbose(2) <<  "Applying no thermostat..." << endl;
     1723      break;
     1724     case Woodcock:
     1725      if ((configuration.ScaleTempStep > 0) && ((MDSteps-1) % configuration.ScaleTempStep == 0)) {
     1726        cout << Verbose(2) <<  "Applying Woodcock thermostat..." << endl;
    11401727        walker = start;
    11411728        while (walker->next != end) { // go through every atom of this element
    11421729          walker = walker->next;
    1143           if (walker->type == runner) { // if this atom fits to element
    1144             // check size of vectors
    1145             if (Trajectories[walker].R.size() <= (unsigned int)(MDSteps)) {
    1146               //cout << "Increasing size for trajectory array of " << *walker << " to " << (size+10) << "." << endl;
    1147               Trajectories[walker].R.resize(MDSteps+10);
    1148               Trajectories[walker].U.resize(MDSteps+10);
    1149               Trajectories[walker].F.resize(MDSteps+10);
     1730          IonMass = walker->type->mass;
     1731          U = Trajectories[walker].U.at(MDSteps).x;
     1732          if (walker->FixedIon == 0) // even FixedIon moves, only not by other's forces
     1733            for (d=0; d<NDIM; d++) {
     1734              U[d] *= sqrt(ScaleTempFactor);
     1735              ekin += 0.5*IonMass * U[d]*U[d];
    11501736            }
    1151             // 1. calculate x(t+\delta t)
    1152             for (int d=0; d<NDIM; d++) {
    1153               Trajectories[walker].F.at(MDSteps).x[d] = -Force.Matrix[0][AtomNo][d+5];
    1154               Trajectories[walker].R.at(MDSteps).x[d] = Trajectories[walker].R.at(MDSteps-1).x[d];
    1155               Trajectories[walker].R.at(MDSteps).x[d] += delta_t*(Trajectories[walker].U.at(MDSteps-1).x[d]);
    1156               Trajectories[walker].R.at(MDSteps).x[d] += 0.5*delta_t*delta_t*(Trajectories[walker].F.at(MDSteps-1).x[d])/IonMass;    // F = m * a and s = 0.5 * F/m * t^2 = F * a * t
     1737        }
     1738      }
     1739      break;
     1740     case Gaussian:
     1741      cout << Verbose(2) <<  "Applying Gaussian thermostat..." << endl;
     1742      walker = start;
     1743      while (walker->next != end) { // go through every atom of this element
     1744        walker = walker->next;
     1745        IonMass = walker->type->mass;
     1746        U = Trajectories[walker].U.at(MDSteps).x;
     1747        F = Trajectories[walker].F.at(MDSteps).x;
     1748        if (walker->FixedIon == 0) // even FixedIon moves, only not by other's forces
     1749          for (d=0; d<NDIM; d++) {
     1750            G += U[d] * F[d];
     1751            E += U[d]*U[d]*IonMass;
     1752          }
     1753      }
     1754      cout << Verbose(1) << "Gaussian Least Constraint constant is " << G/E << "." << endl;
     1755      walker = start;
     1756      while (walker->next != end) { // go through every atom of this element
     1757        walker = walker->next;
     1758        IonMass = walker->type->mass;
     1759        U = Trajectories[walker].U.at(MDSteps).x;
     1760        F = Trajectories[walker].F.at(MDSteps).x;
     1761        if (walker->FixedIon == 0) // even FixedIon moves, only not by other's forces
     1762          for (d=0; d<NDIM; d++) {
     1763            FConstraint[d] = (G/E) * (U[d]*IonMass);
     1764            U[d] += configuration.Deltat/IonMass * (FConstraint[d]);
     1765            ekin += IonMass * U[d]*U[d];
     1766          }
     1767      }
     1768      break;
     1769     case Langevin:
     1770      cout << Verbose(2) <<  "Applying Langevin thermostat..." << endl;
     1771      // init random number generator
     1772      gsl_rng_env_setup();
     1773      T = gsl_rng_default;
     1774      r = gsl_rng_alloc (T);
     1775      // Go through each ion
     1776      walker = start;
     1777      while (walker->next != end) { // go through every atom of this element
     1778        walker = walker->next;
     1779        IonMass = walker->type->mass;
     1780        sigma  = sqrt(configuration.TargetTemp/IonMass); // sigma = (k_b T)/m (Hartree/atomicmass = atomiclength/atomictime)
     1781        U = Trajectories[walker].U.at(MDSteps).x;
     1782        F = Trajectories[walker].F.at(MDSteps).x;
     1783        if (walker->FixedIon == 0) { // even FixedIon moves, only not by other's forces
     1784          // throw a dice to determine whether it gets hit by a heat bath particle
     1785          if (((((rand()/(double)RAND_MAX))*configuration.TempFrequency) < 1.)) { 
     1786            cout << Verbose(3) << "Particle " << *walker << " was hit (sigma " << sigma << "): " << sqrt(U[0]*U[0]+U[1]*U[1]+U[2]*U[2]) << " -> ";
     1787            // pick three random numbers from a Boltzmann distribution around the desired temperature T for each momenta axis
     1788            for (d=0; d<NDIM; d++) {
     1789              U[d] = gsl_ran_gaussian (r, sigma);
    11571790            }
    1158             // 2. Calculate v(t+\delta t)
    1159             for (int d=0; d<NDIM; d++) {
    1160               Trajectories[walker].U.at(MDSteps).x[d] = Trajectories[walker].U.at(MDSteps-1).x[d];
    1161               Trajectories[walker].U.at(MDSteps).x[d] += 0.5*delta_t*(Trajectories[walker].F.at(MDSteps-1).x[d]+Trajectories[walker].F.at(MDSteps).x[d])/IonMass;
    1162             }
    1163 //            cout << "Integrated position&velocity of step " << (MDSteps) << ": (";
    1164 //            for (int d=0;d<NDIM;d++)
    1165 //              cout << Trajectories[walker].R.at(MDSteps).x[d] << " ";          // next step
    1166 //            cout << ")\t(";
    1167 //            for (int d=0;d<NDIM;d++)
    1168 //              cout << Trajectories[walker].U.at(MDSteps).x[d] << " ";          // next step
    1169 //            cout << ")" << endl;
    1170             // next atom
    1171             AtomNo++;
     1791            cout << sqrt(U[0]*U[0]+U[1]*U[1]+U[2]*U[2]) << endl;
     1792          }
     1793          for (d=0; d<NDIM; d++)
     1794            ekin += 0.5*IonMass * U[d]*U[d];
     1795        }
     1796      }
     1797      break;
     1798     case Berendsen:
     1799      cout << Verbose(2) <<  "Applying Berendsen-VanGunsteren thermostat..." << endl;
     1800      walker = start;
     1801      while (walker->next != end) { // go through every atom of this element
     1802        walker = walker->next;
     1803        IonMass = walker->type->mass;
     1804        U = Trajectories[walker].U.at(MDSteps).x;
     1805        F = Trajectories[walker].F.at(MDSteps).x;
     1806        if (walker->FixedIon == 0) { // even FixedIon moves, only not by other's forces
     1807          for (d=0; d<NDIM; d++) {
     1808            U[d] *= sqrt(1+(configuration.Deltat/configuration.TempFrequency)*(ScaleTempFactor-1));
     1809            ekin += 0.5*IonMass * U[d]*U[d];
    11721810          }
    11731811        }
    11741812      }
    1175     }
    1176   }
    1177 //  // correct velocities (rather momenta) so that center of mass remains motionless
    1178 //  tmpvector.zero()
    1179 //  IonMass = 0.;
    1180 //  walker = start;
    1181 //  while (walker->next != end) { // go through every atom
    1182 //    walker = walker->next;
    1183 //    IonMass += walker->type->mass;  // sum up total mass
    1184 //    for(int d=0;d<NDIM;d++) {
    1185 //      tmpvector.x[d] += Trajectories[walker].U.at(MDSteps).x[d]*walker->type->mass;
    1186 //    }
    1187 //  }
    1188 //  walker = start;
    1189 //  while (walker->next != end) { // go through every atom of this element
    1190 //    walker = walker->next;
    1191 //    for(int d=0;d<NDIM;d++) {
    1192 //      Trajectories[walker].U.at(MDSteps).x[d] -= tmpvector.x[d]*walker->type->mass/IonMass;
    1193 //    }
    1194 //  }
    1195   MDSteps++;
    1196 
    1197 
    1198   // exit
    1199   return true;
    1200 };
    1201 
    1202 /** Align all atoms in such a manner that given vector \a *n is along z axis.
     1813      break;
     1814     case NoseHoover:
     1815      cout << Verbose(2) <<  "Applying Nose-Hoover thermostat..." << endl;
     1816      // dynamically evolve alpha (the additional degree of freedom)
     1817      delta_alpha = 0.;
     1818      walker = start;
     1819      while (walker->next != end) { // go through every atom of this element
     1820        walker = walker->next;
     1821        IonMass = walker->type->mass;
     1822        U = Trajectories[walker].U.at(MDSteps).x;
     1823        if (walker->FixedIon == 0) { // even FixedIon moves, only not by other's forces
     1824          for (d=0; d<NDIM; d++) {
     1825            delta_alpha += U[d]*U[d]*IonMass;
     1826          }
     1827        }
     1828      }
     1829      delta_alpha = (delta_alpha - (3.*AtomCount+1.) * configuration.TargetTemp)/(configuration.HooverMass*Units2Electronmass);
     1830      configuration.alpha += delta_alpha*configuration.Deltat;
     1831      cout << Verbose(3) << "alpha = " << delta_alpha << " * " << configuration.Deltat << " = " << configuration.alpha << "." << endl;
     1832      // apply updated alpha as additional force
     1833      walker = start;
     1834      while (walker->next != end) { // go through every atom of this element
     1835        walker = walker->next;
     1836        IonMass = walker->type->mass;
     1837        U = Trajectories[walker].U.at(MDSteps).x;
     1838        if (walker->FixedIon == 0) { // even FixedIon moves, only not by other's forces
     1839          for (d=0; d<NDIM; d++) {
     1840              FConstraint[d] = - configuration.alpha * (U[d] * IonMass);
     1841              U[d] += configuration.Deltat/IonMass * (FConstraint[d]);
     1842              ekin += (0.5*IonMass) * U[d]*U[d];
     1843            }
     1844        }
     1845      }
     1846      break;
     1847  }   
     1848  cout << Verbose(1) << "Kinetic energy is " << ekin << "." << endl;
     1849};
     1850
     1851/** Align all atoms in such a manner that given vector \a *n is along z axis.
    12031852 * \param n[] alignment vector.
    12041853 */
     
    12671916bool molecule::RemoveAtom(atom *pointer)
    12681917{
    1269   if (ElementsInMolecule[pointer->type->Z] != 0)  // this would indicate an error
     1918  if (ElementsInMolecule[pointer->type->Z] != 0)  { // this would indicate an error
    12701919    ElementsInMolecule[pointer->type->Z]--;  // decrease number of atom of this element
    1271   else
     1920    AtomCount--;
     1921  } else
    12721922    cerr << "ERROR: Atom " << pointer->Name << " is of element " << pointer->type->Z << " but the entry in the table of the molecule is 0!" << endl;
    12731923  if (ElementsInMolecule[pointer->type->Z] == 0)  // was last atom of this element?
     
    30933743  while (MolecularWalker->next != NULL) {
    30943744    MolecularWalker = MolecularWalker->next;
     3745    *out << Verbose(0) << "Analysing the cycles of subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
    30953746    LocalBackEdgeStack = new StackClass<bond *> (MolecularWalker->Leaf->BondCount);
    30963747//    // check the list of local atoms for debugging
     
    31083759    delete(LocalBackEdgeStack);
    31093760  }
    3110 
     3761 
    31113762  // ===== 3. if structure still valid, parse key set file and others =====
    31123763  FragmentationToDo = FragmentationToDo && ParseKeySetFile(out, configuration->configpath, ParsedFragmentList);
     
    31143765  // ===== 4. check globally whether there's something to do actually (first adaptivity check)
    31153766  FragmentationToDo = FragmentationToDo && ParseOrderAtSiteFromFile(out, configuration->configpath);
    3116 
    3117   // =================================== Begin of FRAGMENTATION ===============================
    3118   // ===== 6a. assign each keyset to its respective subgraph =====
     3767 
     3768  // =================================== Begin of FRAGMENTATION =============================== 
     3769  // ===== 6a. assign each keyset to its respective subgraph ===== 
    31193770  Subgraphs->next->AssignKeySetsToFragment(out, this, ParsedFragmentList, ListOfLocalAtoms, FragmentList, (FragmentCounter = 0), true);
    31203771
     
    31513802  delete(ParsedFragmentList);
    31523803  delete[](MinimumRingSize);
    3153 
     3804 
    31543805
    31553806  // ==================================== End of FRAGMENTATION ============================================
     
    32443895  atom *Walker = NULL, *OtherAtom = NULL;
    32453896  ReferenceStack->Push(Binder);
    3246 
     3897 
    32473898  do {  // go through all bonds and push local ones
    32483899    Walker = ListOfLocalAtoms[Binder->leftatom->nr];  // get one atom in the reference molecule
     
    37144365};
    37154366
     4367/** Creates \a MoleculeListClass of all unique fragments of the \a molecule containing \a Order atoms or vertices.
     4368 * The picture to have in mind is that of a DFS "snake" of a certain length \a Order, i.e. as in the infamous
     4369 * computer game, that winds through the connected graph representing the molecule. Color (white,
     4370 * lightgray, darkgray, black) indicates whether a vertex has been discovered so far or not. Labels will help in
     4371 * creating only unique fragments and not additional ones with vertices simply in different sequence.
     4372 * The Predecessor is always the one that came before in discovering, needed on backstepping. And
     4373 * finally, the ShortestPath is needed for removing vertices from the snake stack during the back-
     4374 * stepping.
     4375 * \param *out output stream for debugging
     4376 * \param Order number of atoms in each fragment
     4377 * \param *configuration configuration for writing config files for each fragment
     4378 * \return List of all unique fragments with \a Order atoms
     4379 */
     4380/*
     4381MoleculeListClass * molecule::CreateListOfUniqueFragmentsOfOrder(ofstream *out, int Order, config *configuration)
     4382{
     4383  atom **PredecessorList = (atom **) Malloc(sizeof(atom *)*AtomCount, "molecule::CreateListOfUniqueFragmentsOfOrder: **PredecessorList");
     4384  int *ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::CreateListOfUniqueFragmentsOfOrder: *ShortestPathList");
     4385  int *Labels = (int *) Malloc(sizeof(int)*AtomCount, "molecule::CreateListOfUniqueFragmentsOfOrder: *Labels");
     4386  enum Shading *ColorVertexList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::CreateListOfUniqueFragmentsOfOrder: *ColorList");
     4387  enum Shading *ColorEdgeList = (enum Shading *) Malloc(sizeof(enum Shading)*BondCount, "molecule::CreateListOfUniqueFragmentsOfOrder: *ColorBondList");
     4388  StackClass<atom *> *RootStack = new StackClass<atom *>(AtomCount);
     4389  StackClass<atom *> *TouchedStack = new StackClass<atom *>((int)pow(4,Order)+2); // number of atoms reached from one with maximal 4 bonds plus Root itself
     4390  StackClass<atom *> *SnakeStack = new StackClass<atom *>(Order+1); // equal to Order is not possible, as then the StackClass<atom *> cannot discern between full and empty stack!
     4391  MoleculeLeafClass *Leaflet = NULL, *TempLeaf = NULL;
     4392  MoleculeListClass *FragmentList = NULL;
     4393  atom *Walker = NULL, *OtherAtom = NULL, *Root = NULL, *Removal = NULL;
     4394  bond *Binder = NULL;
     4395  int RunningIndex = 0, FragmentCounter = 0;
     4396
     4397  *out << Verbose(1) << "Begin of CreateListOfUniqueFragmentsOfOrder." << endl;
     4398
     4399  // reset parent list
     4400  *out << Verbose(3) << "Resetting labels, parent, predecessor, color and shortest path lists." << endl;
     4401  for (int i=0;i<AtomCount;i++) { // reset all atom labels
     4402    // initialise each vertex as white with no predecessor, empty queue, color lightgray, not labelled, no sons
     4403    Labels[i] = -1;
     4404    SonList[i] = NULL;
     4405    PredecessorList[i] = NULL;
     4406    ColorVertexList[i] = white;
     4407    ShortestPathList[i] = -1;
     4408  }
     4409  for (int i=0;i<BondCount;i++)
     4410    ColorEdgeList[i] = white;
     4411  RootStack->ClearStack();  // clearstack and push first atom if exists
     4412  TouchedStack->ClearStack();
     4413  Walker = start->next;
     4414  while ((Walker != end)
     4415#ifdef ADDHYDROGEN
     4416   && (Walker->type->Z == 1)
     4417        }
     4418      }
     4419      *out << ", SP of " << ShortestPathList[Walker->nr]  << " and its color is " << GetColor(ColorVertexList[Walker->nr]) << "." << endl;
     4420
     4421      // then check the stack for a newly stumbled upon fragment
     4422      if (SnakeStack->ItemCount() == Order) { // is stack full?
     4423        // store the fragment if it is one and get a removal candidate
     4424        Removal = StoreFragmentFromStack(out, Root, Walker, Leaflet, SnakeStack, ShortestPathList, SonList, Labels, &FragmentCounter, configuration);
     4425        // remove the candidate if one was found
     4426        if (Removal != NULL) {
     4427          *out << Verbose(2) << "Removing item " << Removal->Name << " with SP of " << ShortestPathList[Removal->nr] << " from snake stack." << endl;
     4428          SnakeStack->RemoveItem(Removal);
     4429          ColorVertexList[Removal->nr] = lightgray; // return back to not on snake stack but explored marking
     4430          if (Walker == Removal) { // if the current atom is to be removed, we also have to take a step back
     4431            Walker = PredecessorList[Removal->nr];
     4432            *out << Verbose(2) << "Stepping back to " << Walker->Name << "." << endl;
     4433          }
     4434        }
     4435      } else
     4436        Removal = NULL;
     4437
     4438      // finally, look for a white neighbour as the next Walker
     4439      Binder = NULL;
     4440      if ((Removal == NULL) || (Walker != PredecessorList[Removal->nr])) {  // don't look, if a new walker has been set above
     4441        *out << Verbose(2) << "Snake has currently " << SnakeStack->ItemCount() << " item(s)." << endl;
     4442        OtherAtom = NULL; // this is actually not needed, every atom has at least one neighbour
     4443        if (ShortestPathList[Walker->nr] < Order) {
     4444          for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
     4445            Binder = ListOfBondsPerAtom[Walker->nr][i];
     4446            *out << Verbose(2) << "Current bond is " << *Binder << ": ";
     4447            OtherAtom = Binder->GetOtherAtom(Walker);
     4448            if ((Labels[OtherAtom->nr] != -1) && (Labels[OtherAtom->nr] < Labels[Root->nr])) { // we don't step up to labels bigger than us
     4449              *out << "Label " << Labels[OtherAtom->nr] << " is smaller than Root's " << Labels[Root->nr] << "." << endl;
     4450              //ColorVertexList[OtherAtom->nr] = lightgray;    // mark as explored
     4451            } else { // otherwise check its colour and element
     4452              if (
     4453              (OtherAtom->type->Z != 1) &&
     4454#endif
     4455                    (ColorEdgeList[Binder->nr] == white)) {  // skip hydrogen, look for unexplored vertices
     4456                *out << "Moving along " << GetColor(ColorEdgeList[Binder->nr]) << " bond " << Binder << " to " << ((ColorVertexList[OtherAtom->nr] == white) ? "unexplored" : "explored") << " item: " << OtherAtom->Name << "." << endl;
     4457                // i find it currently rather sensible to always set the predecessor in order to find one's way back
     4458                //if (PredecessorList[OtherAtom->nr] == NULL) {
     4459                PredecessorList[OtherAtom->nr] = Walker;
     4460                *out << Verbose(3) << "Setting Predecessor of " << OtherAtom->Name << " to " << PredecessorList[OtherAtom->nr]->Name << "." << endl;
     4461                //} else {
     4462                //  *out << Verbose(3) << "Predecessor of " << OtherAtom->Name << " is " << PredecessorList[OtherAtom->nr]->Name << "." << endl;
     4463                //}
     4464                Walker = OtherAtom;
     4465                break;
     4466              } else {
     4467                if (OtherAtom->type->Z == 1)
     4468                  *out << "Links to a hydrogen atom." << endl;
     4469                else
     4470                  *out << "Bond has not white but " << GetColor(ColorEdgeList[Binder->nr]) << " color." << endl;
     4471              }
     4472            }
     4473          }
     4474        } else {  // means we have stepped beyond the horizon: Return!
     4475          Walker = PredecessorList[Walker->nr];
     4476          OtherAtom = Walker;
     4477          *out << Verbose(3) << "We have gone too far, stepping back to " << Walker->Name << "." << endl;
     4478        }
     4479        if (Walker != OtherAtom) {  // if no white neighbours anymore, color it black
     4480          *out << Verbose(2) << "Coloring " << Walker->Name << " black." << endl;
     4481          ColorVertexList[Walker->nr] = black;
     4482          Walker = PredecessorList[Walker->nr];
     4483        }
     4484      }
     4485    } while ((Walker != Root) || (ColorVertexList[Root->nr] != black));
     4486    *out << Verbose(2) << "Inner Looping is finished." << endl;
     4487
     4488    // if we reset all AtomCount atoms, we have again technically O(N^2) ...
     4489    *out << Verbose(2) << "Resetting lists." << endl;
     4490    Walker = NULL;
     4491    Binder = NULL;
     4492    while (!TouchedStack->IsEmpty()) {
     4493      Walker = TouchedStack->PopLast();
     4494      *out << Verbose(3) << "Re-initialising entries of " << *Walker << "." << endl;
     4495      for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++)
     4496        ColorEdgeList[ListOfBondsPerAtom[Walker->nr][i]->nr] = white;
     4497      PredecessorList[Walker->nr] = NULL;
     4498      ColorVertexList[Walker->nr] = white;
     4499      ShortestPathList[Walker->nr] = -1;
     4500    }
     4501  }
     4502  *out << Verbose(1) << "Outer Looping over all vertices is done." << endl;
     4503
     4504  // copy together
     4505  *out << Verbose(1) << "Copying all fragments into MoleculeList structure." << endl;
     4506  FragmentList = new MoleculeListClass(FragmentCounter, AtomCount);
     4507  RunningIndex = 0;
     4508  while ((Leaflet != NULL) && (RunningIndex < FragmentCounter))  {
     4509    FragmentList->ListOfMolecules[RunningIndex++] = Leaflet->Leaf;
     4510    Leaflet->Leaf = NULL; // prevent molecule from being removed
     4511    TempLeaf = Leaflet;
     4512    Leaflet = Leaflet->previous;
     4513    delete(TempLeaf);
     4514  };
     4515
     4516  // free memory and exit
     4517  Free((void **)&PredecessorList, "molecule::CreateListOfUniqueFragmentsOfOrder: **PredecessorList");
     4518  Free((void **)&ShortestPathList, "molecule::CreateListOfUniqueFragmentsOfOrder: *ShortestPathList");
     4519  Free((void **)&Labels, "molecule::CreateListOfUniqueFragmentsOfOrder: *Labels");
     4520  Free((void **)&ColorVertexList, "molecule::CreateListOfUniqueFragmentsOfOrder: *ColorList");
     4521  delete(RootStack);
     4522  delete(TouchedStack);
     4523  delete(SnakeStack);
     4524
     4525  *out << Verbose(1) << "End of CreateListOfUniqueFragmentsOfOrder." << endl;
     4526  return FragmentList;
     4527};
     4528*/
     4529
    37164530/** Structure containing all values in power set combination generation.
    37174531 */
     
    45455359  if (result) {
    45465360    *out << Verbose(5) << "Calculating Centers of Gravity" << endl;
    4547     DetermineCenter(CenterOfGravity);
    4548     OtherMolecule->DetermineCenter(OtherCenterOfGravity);
     5361    DeterminePeriodicCenter(CenterOfGravity);
     5362    OtherMolecule->DeterminePeriodicCenter(OtherCenterOfGravity);
    45495363    *out << Verbose(5) << "Center of Gravity: ";
    45505364    CenterOfGravity.Output(out);
  • src/molecules.hpp

    r042f82 r36ec71  
    1010
    1111// GSL headers
     12#include <gsl/gsl_eigen.h>
     13#include <gsl/gsl_heapsort.h>
     14#include <gsl/gsl_linalg.h>
     15#include <gsl/gsl_matrix.h>
    1216#include <gsl/gsl_multimin.h>
    1317#include <gsl/gsl_vector.h>
    14 #include <gsl/gsl_matrix.h>
    15 #include <gsl/gsl_eigen.h>
    16 #include <gsl/gsl_heapsort.h>
     18#include <gsl/gsl_randist.h>
    1719
    1820// STL headers
     
    156158};
    157159
    158 ostream & operator << (ostream &ost, atom &a);
     160ostream & operator << (ostream &ost, const atom &a);
    159161
    160162/** Bonds between atoms.
     
    195197};
    196198
    197 ostream & operator << (ostream &ost, bond &b);
     199
     200ostream & operator << (ostream &ost, const bond &b);
    198201
    199202class MoleculeLeafClass;
     203
     204
     205#define MaxThermostats 6      //!< maximum number of thermostat entries in Ions#ThermostatNames and Ions#ThermostatImplemented
     206enum thermostats { None, Woodcock, Gaussian, Langevin, Berendsen, NoseHoover };   //!< Thermostat names for output
     207
    200208
    201209/** The complete molecule.
     
    254262  bool CenterInBox(ofstream *out);
    255263  void CenterEdge(ofstream *out, Vector *max);
    256   void CenterOrigin(ofstream *out, Vector *max);
    257   void CenterGravity(ofstream *out, Vector *max);
     264  void CenterOrigin(ofstream *out);
     265  void CenterPeriodic(ofstream *out);
     266  void CenterAtVector(ofstream *out, Vector *newcenter);
    258267  void Translate(const Vector *x);
    259268  void TranslatePeriodically(const Vector *trans);
     
    261270  void Align(Vector *n);
    262271  void Scale(double **factor);
    263   void DetermineCenter(Vector &center);
     272  void DeterminePeriodicCenter(Vector &center);
    264273  Vector * DetermineCenterOfGravity(ofstream *out);
    265274  Vector * DetermineCenterOfAll(ofstream *out);
    266   void SetNameFromFilename(char *filename);
     275  void SetNameFromFilename(const char *filename);
    267276  void SetBoxDimension(Vector *dim);
    268277  double * ReturnFullMatrixforSymmetric(double *cell_size);
    269278  void ScanForPeriodicCorrection(ofstream *out);
     279  bool VerletForceIntegration(ofstream *out, char *file, config &configuration);
     280  void Thermostats(config &configuration, double ActualTemp, int Thermostat);
    270281  void PrincipalAxisSystem(ofstream *out, bool DoRotate);
    271282  double VolumeOfConvexEnvelope(ofstream *out, bool IsAngstroem);
    272283  Vector* FindEmbeddingHole(ofstream *out, molecule *srcmol);
    273284
    274   bool VerletForceIntegration(char *file, double delta_t, bool IsAngstroem);
    275 
     285
     286  double ConstrainedPotential(ofstream *out, atom **permutation, int start, int end, double *constants, bool IsAngstroem);
     287  double MinimiseConstrainedPotential(ofstream *out, atom **&permutation, int startstep, int endstep, bool IsAngstroem);
     288  void EvaluateConstrainedForces(ofstream *out, int startstep, int endstep, atom **PermutationMap, ForceMatrix *Force);
     289  bool LinearInterpolationBetweenConfiguration(ofstream *out, int startstep, int endstep, const char *prefix, config &configuration);
     290       
    276291  bool CheckBounds(const Vector *x) const;
    277292  void GetAlignvector(struct lsq_params * par) const;
     
    349364  bool AddHydrogenCorrection(ofstream *out, char *path);
    350365  bool StoreForcesFile(ofstream *out, char *path, int *SortIndex);
    351   bool insert(molecule *mol);
     366  void insert(molecule *mol);
    352367  molecule * ReturnIndex(int index);
    353368  bool OutputConfigForListOfFragments(ofstream *out, config *configuration, int *SortIndex);
     
    429444    char *databasepath;
    430445
     446    int DoConstrainedMD;
     447    int MaxOuterStep;
     448    int Thermostat;
     449    int *ThermostatImplemented;
     450    char **ThermostatNames;
     451    double TempFrequency;
     452    double alpha;
     453    double HooverMass;
     454    double TargetTemp;
     455    int ScaleTempStep;
     456   
    431457  private:
    432458    char *mainname;
     
    449475    int Seed;
    450476
    451     int MaxOuterStep;
    452477    int OutVisStep;
    453478    int OutSrcStep;
    454     double TargetTemp;
    455     int ScaleTempStep;
    456479    int MaxPsiStep;
    457480    double EpsWannier;
     
    501524  char *GetDefaultPath() const;
    502525  void SetDefaultPath(const char *path);
     526  void InitThermostats(ifstream *source);
    503527};
    504528
  • src/parser.cpp

    r042f82 r36ec71  
    5656MatrixContainer::MatrixContainer() {
    5757  Indices = NULL;
    58   Header = (char *) Malloc(sizeof(char)*1023, "MatrixContainer::MatrixContainer: *Header");
     58  Header = (char **) Malloc(sizeof(char)*1, "MatrixContainer::MatrixContainer: **Header");
    5959  Matrix = (double ***) Malloc(sizeof(double **)*(1), "MatrixContainer::MatrixContainer: ***Matrix"); // one more each for the total molecule
    6060  RowCounter = (int *) Malloc(sizeof(int)*(1), "MatrixContainer::MatrixContainer: *RowCounter");
     61  ColumnCounter = (int *) Malloc(sizeof(int)*(1), "MatrixContainer::MatrixContainer: *ColumnCounter");
     62  Header[0] = NULL;
    6163  Matrix[0] = NULL;
    6264  RowCounter[0] = -1;
    6365  MatrixCounter = 0;
    64   ColumnCounter = 0;
     66  ColumnCounter[0] = -1;
    6567};
    6668
     
    7072  if (Matrix != NULL) {
    7173    for(int i=MatrixCounter;i--;) {
    72       if (RowCounter != NULL) {
     74      if ((ColumnCounter != NULL) && (RowCounter != NULL)) {
    7375          for(int j=RowCounter[i]+1;j--;)
    7476            Free((void **)&Matrix[i][j], "MatrixContainer::~MatrixContainer: *Matrix[][]");
     
    7678      }
    7779    }
    78     if ((RowCounter != NULL) && (Matrix[MatrixCounter] != NULL))
     80    if ((ColumnCounter != NULL) && (RowCounter != NULL) && (Matrix[MatrixCounter] != NULL))
    7981      for(int j=RowCounter[MatrixCounter]+1;j--;)
    8082        Free((void **)&Matrix[MatrixCounter][j], "MatrixContainer::~MatrixContainer: *Matrix[MatrixCounter][]");
     
    8789      Free((void **)&Indices[i], "MatrixContainer::~MatrixContainer: *Indices[]");
    8890    }
    89   Free((void **)&Indices, "MatrixContainer::~MatrixContainer: **Indices");
    90 
    91   Free((void **)&Header, "MatrixContainer::~MatrixContainer: *Header");
     91  Free((void **)&Indices, "MatrixContainer::~MatrixContainer: **Indices");
     92 
     93  if (Header != NULL)
     94    for(int i=MatrixCounter+1;i--;)
     95      Free((void **)&Header[i], "MatrixContainer::~MatrixContainer: *Header[]");
     96  Free((void **)&Header, "MatrixContainer::~MatrixContainer: **Header");
    9297  Free((void **)&RowCounter, "MatrixContainer::~MatrixContainer: *RowCounter");
    93 };
    94 
     98  Free((void **)&ColumnCounter, "MatrixContainer::~MatrixContainer: *RowCounter");
     99};
     100
     101/** Either copies index matrix from another MatrixContainer or initialises with trivial mapping if NULL.
     102 * This either copies the index matrix or just maps 1 to 1, 2 to 2 and so on for all fragments.
     103 * \param *Matrix pointer to other MatrixContainer
     104 * \return true - copy/initialisation sucessful, false - dimension false for copying
     105 */
     106bool MatrixContainer::InitialiseIndices(class MatrixContainer *Matrix)
     107{
     108  cout << "Initialising indices";
     109  if (Matrix == NULL) {
     110    cout << " with trivial mapping." << endl;
     111    Indices = (int **) Malloc(sizeof(int *)*(MatrixCounter+1), "MatrixContainer::InitialiseIndices: **Indices");
     112    for(int i=MatrixCounter+1;i--;) {
     113      Indices[i] = (int *) Malloc(sizeof(int)*RowCounter[i], "MatrixContainer::InitialiseIndices: *Indices[]");
     114      for(int j=RowCounter[i];j--;)
     115        Indices[i][j] = j;
     116    }
     117  } else {
     118    cout << " from other MatrixContainer." << endl;
     119    if (MatrixCounter != Matrix->MatrixCounter)
     120      return false;
     121    Indices = (int **) Malloc(sizeof(int *)*(MatrixCounter+1), "MatrixContainer::InitialiseIndices: **Indices");
     122    for(int i=MatrixCounter+1;i--;) {
     123      if (RowCounter[i] != Matrix->RowCounter[i])
     124        return false;
     125      Indices[i] = (int *) Malloc(sizeof(int)*Matrix->RowCounter[i], "MatrixContainer::InitialiseIndices: *Indices[]");
     126      for(int j=Matrix->RowCounter[i];j--;) {
     127        Indices[i][j] = Matrix->Indices[i][j];
     128        //cout << Indices[i][j] << "\t";
     129      }
     130      //cout << endl;
     131    }
     132  }
     133  return true;
     134};
    95135
    96136/** Parsing a number of matrices.
     
    121161  }
    122162
    123   // skip some initial lines
     163  // parse header
     164  Header[MatrixNr] = (char *) Malloc(sizeof(char)*1024, "MatrixContainer::ParseMatrix: *Header[]");
    124165  for (int m=skiplines+1;m--;)
    125     input.getline(Header, 1023);
    126 
     166    input.getline(Header[MatrixNr], 1023);
     167 
    127168  // scan header for number of columns
    128   line.str(Header);
     169  line.str(Header[MatrixNr]);
    129170  for(int k=skipcolumns;k--;)
    130     line >> Header;
     171    line >> Header[MatrixNr];
    131172  //cout << line.str() << endl;
    132   ColumnCounter=0;
     173  ColumnCounter[MatrixNr]=0;
    133174  while ( getline(line,token, '\t') ) {
    134175    if (token.length() > 0)
    135       ColumnCounter++;
     176      ColumnCounter[MatrixNr]++;
    136177  }
    137178  //cout << line.str() << endl;
    138   //cout << "ColumnCounter: " << ColumnCounter << "." << endl;
    139   if (ColumnCounter == 0)
    140     cerr << "ColumnCounter: " << ColumnCounter << " from file " << name << ", this is probably an error!" << endl;
    141 
     179  //cout << "ColumnCounter[" << MatrixNr << "]: " << ColumnCounter[MatrixNr] << "." << endl;
     180  if (ColumnCounter[MatrixNr] == 0)
     181    cerr << "ColumnCounter[" << MatrixNr << "]: " << ColumnCounter[MatrixNr] << " from file " << name << ", this is probably an error!" << endl;
     182 
    142183  // scan rest for number of rows/lines
    143184  RowCounter[MatrixNr]=-1;    // counts one line too much
     
    155196
    156197  // allocate matrix if it's not zero dimension in one direction
    157   if ((ColumnCounter > 0) && (RowCounter[MatrixNr] > -1)) {
    158     Matrix[MatrixNr] = (double **) Malloc(sizeof(double *)*(RowCounter[MatrixNr]+1), "MatrixContainer::ParseFragmentMatrix: **Matrix[]");
    159 
     198  if ((ColumnCounter[MatrixNr] > 0) && (RowCounter[MatrixNr] > -1)) {
     199    Matrix[MatrixNr] = (double **) Malloc(sizeof(double *)*(RowCounter[MatrixNr]+1), "MatrixContainer::ParseMatrix: **Matrix[]");
     200 
    160201    // parse in each entry for this matrix
    161202    input.clear();
    162203    input.seekg(ios::beg);
    163204    for (int m=skiplines+1;m--;)
    164       input.getline(Header, 1023);    // skip header
    165     line.str(Header);
     205      input.getline(Header[MatrixNr], 1023);    // skip header
     206    line.str(Header[MatrixNr]);
    166207    for(int k=skipcolumns;k--;)  // skip columns in header too
    167208      line >> filename;
    168     strncpy(Header, line.str().c_str(), 1023);
     209    strncpy(Header[MatrixNr], line.str().c_str(), 1023); 
    169210    for(int j=0;j<RowCounter[MatrixNr];j++) {
    170       Matrix[MatrixNr][j] = (double *) Malloc(sizeof(double)*ColumnCounter, "MatrixContainer::ParseFragmentMatrix: *Matrix[][]");
     211      Matrix[MatrixNr][j] = (double *) Malloc(sizeof(double)*ColumnCounter[MatrixNr], "MatrixContainer::ParseMatrix: *Matrix[][]");
    171212      input.getline(filename, 1023);
    172213      stringstream lines(filename);
     
    174215      for(int k=skipcolumns;k--;)
    175216        lines >> filename;
    176       for(int k=0;(k<ColumnCounter) && (!lines.eof());k++) {
     217      for(int k=0;(k<ColumnCounter[MatrixNr]) && (!lines.eof());k++) {
    177218        lines >> Matrix[MatrixNr][j][k];
    178219        //cout << " " << setprecision(2) << Matrix[MatrixNr][j][k];;
    179220      }
    180221      //cout << endl;
    181       Matrix[MatrixNr][ RowCounter[MatrixNr] ] = (double *) Malloc(sizeof(double)*ColumnCounter, "MatrixContainer::ParseFragmentMatrix: *Matrix[RowCounter[MatrixNr]][]");
    182       for(int j=ColumnCounter;j--;)
     222      Matrix[MatrixNr][ RowCounter[MatrixNr] ] = (double *) Malloc(sizeof(double)*ColumnCounter[MatrixNr], "MatrixContainer::ParseMatrix: *Matrix[RowCounter[MatrixNr]][]");
     223      for(int j=ColumnCounter[MatrixNr];j--;)
    183224        Matrix[MatrixNr][ RowCounter[MatrixNr] ][j] = 0.;
    184225    }
    185226  } else {
    186     cerr << "ERROR: Matrix nr. " << MatrixNr << " has column and row count of (" << ColumnCounter << "," << RowCounter[MatrixNr] << "), could not allocate nor parse!" << endl;
     227    cerr << "ERROR: Matrix nr. " << MatrixNr << " has column and row count of (" << ColumnCounter[MatrixNr] << "," << RowCounter[MatrixNr] << "), could not allocate nor parse!" << endl;
    187228  }
    188229  input.close();
     
    233274
    234275  cout << "Parsing through each fragment and retrieving " << prefix << suffix << "." << endl;
     276  Header = (char **) ReAlloc(Header, sizeof(char *)*(MatrixCounter+1), "MatrixContainer::ParseFragmentMatrix: **Header"); // one more each for the total molecule
    235277  Matrix = (double ***) ReAlloc(Matrix, sizeof(double **)*(MatrixCounter+1), "MatrixContainer::ParseFragmentMatrix: ***Matrix"); // one more each for the total molecule
    236278  RowCounter = (int *) ReAlloc(RowCounter, sizeof(int)*(MatrixCounter+1), "MatrixContainer::ParseFragmentMatrix: *RowCounter");
     279  ColumnCounter = (int *) ReAlloc(ColumnCounter, sizeof(int)*(MatrixCounter+1), "MatrixContainer::ParseFragmentMatrix: *ColumnCounter");
    237280  for(int i=MatrixCounter+1;i--;) {
    238281    Matrix[i] = NULL;
     282    Header[i] = NULL;
    239283    RowCounter[i] = -1;
     284    ColumnCounter[i] = -1;
    240285  }
    241286  for(int i=0; i < MatrixCounter;i++) {
     
    252297
    253298/** Allocates and resets the memory for a number \a MCounter of matrices.
    254  * \param *GivenHeader Header line
     299 * \param **GivenHeader Header line for each matrix
    255300 * \param MCounter number of matrices
    256301 * \param *RCounter number of rows for each matrix
    257  * \param CCounter number of columns for all matrices
    258  * \return Allocation successful
    259  */
    260 bool MatrixContainer::AllocateMatrix(const char *GivenHeader, int MCounter, int *RCounter, int CCounter)
    261 {
    262   Header = (char *) Malloc(sizeof(char)*1024, "MatrixContainer::ParseFragmentMatrix: *EnergyHeader");
    263   strncpy(Header, GivenHeader, 1023);
    264 
     302 * \param *CCounter number of columns for each matrix
     303 * \return Allocation successful
     304 */
     305bool MatrixContainer::AllocateMatrix(char **GivenHeader, int MCounter, int *RCounter, int *CCounter)
     306{
    265307  MatrixCounter = MCounter;
    266   ColumnCounter = CCounter;
    267   Matrix = (double ***) Malloc(sizeof(double **)*(MatrixCounter+1), "MatrixContainer::ParseFragmentMatrix: ***Matrix"); // one more each for the total molecule
    268   RowCounter = (int *) Malloc(sizeof(int)*(MatrixCounter+1), "MatrixContainer::ParseFragmentMatrix: *RowCounter");
     308  Header = (char **) Malloc(sizeof(char *)*(MatrixCounter+1), "MatrixContainer::AllocateMatrix: *Header");
     309  Matrix = (double ***) Malloc(sizeof(double **)*(MatrixCounter+1), "MatrixContainer::AllocateMatrix: ***Matrix"); // one more each for the total molecule
     310  RowCounter = (int *) Malloc(sizeof(int)*(MatrixCounter+1), "MatrixContainer::AllocateMatrix: *RowCounter");
     311  ColumnCounter = (int *) Malloc(sizeof(int)*(MatrixCounter+1), "MatrixContainer::AllocateMatrix: *ColumnCounter");
    269312  for(int i=MatrixCounter+1;i--;) {
     313    Header[i] = (char *) Malloc(sizeof(char)*1024, "MatrixContainer::AllocateMatrix: *Header[i]");
     314    strncpy(Header[i], GivenHeader[i], 1023);
    270315    RowCounter[i] = RCounter[i];
    271     Matrix[i] = (double **) Malloc(sizeof(double *)*(RowCounter[i]+1), "MatrixContainer::ParseFragmentMatrix: **Matrix[]");
     316    ColumnCounter[i] = CCounter[i];
     317    Matrix[i] = (double **) Malloc(sizeof(double *)*(RowCounter[i]+1), "MatrixContainer::AllocateMatrix: **Matrix[]"); 
    272318    for(int j=RowCounter[i]+1;j--;) {
    273       Matrix[i][j] = (double *) Malloc(sizeof(double)*ColumnCounter, "MatrixContainer::ParseFragmentMatrix: *Matrix[][]");
    274       for(int k=ColumnCounter;k--;)
     319      Matrix[i][j] = (double *) Malloc(sizeof(double)*ColumnCounter[i], "MatrixContainer::AllocateMatrix: *Matrix[][]");
     320      for(int k=ColumnCounter[i];k--;)
    275321        Matrix[i][j][k] = 0.;
    276322    }
     
    286332  for(int i=MatrixCounter+1;i--;)
    287333    for(int j=RowCounter[i]+1;j--;)
    288       for(int k=ColumnCounter;k--;)
     334      for(int k=ColumnCounter[i];k--;)
    289335        Matrix[i][j][k] = 0.;
    290336   return true;
     
    299345  for(int i=MatrixCounter+1;i--;)
    300346    for(int j=RowCounter[i]+1;j--;)
    301       for(int k=ColumnCounter;k--;)
     347      for(int k=ColumnCounter[i];k--;)
    302348        if (fabs(Matrix[i][j][k]) > max)
    303349          max = fabs(Matrix[i][j][k]);
     
    315361  for(int i=MatrixCounter+1;i--;)
    316362    for(int j=RowCounter[i]+1;j--;)
    317       for(int k=ColumnCounter;k--;)
     363      for(int k=ColumnCounter[i];k--;)
    318364        if (fabs(Matrix[i][j][k]) < min)
    319365          min = fabs(Matrix[i][j][k]);
     
    331377{
    332378  for(int j=RowCounter[MatrixCounter]+1;j--;)
    333     for(int k=skipcolumns;k<ColumnCounter;k++)
     379    for(int k=skipcolumns;k<ColumnCounter[MatrixCounter];k++)
    334380      Matrix[MatrixCounter][j][k] = value;
    335381   return true;
     
    344390{
    345391  for(int j=RowCounter[MatrixCounter]+1;j--;)
    346     for(int k=skipcolumns;k<ColumnCounter;k++)
     392    for(int k=skipcolumns;k<ColumnCounter[MatrixCounter];k++)
    347393      Matrix[MatrixCounter][j][k] = values[j][k];
    348394   return true;
    349395};
    350396
    351 /** Sums the energy with each factor and put into last element of \a ***Energies.
     397/** Sums the entries with each factor and put into last element of \a ***Matrix.
    352398 * Sums over "E"-terms to create the "F"-terms
    353  * \param Matrix MatrixContainer with matrices (LevelCounter by ColumnCounter) with all the energies.
     399 * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies.
    354400 * \param KeySet KeySetContainer with bond Order and association mapping of each fragment to an order
    355401 * \param Order bond order
     
    384430              }
    385431              if (Order == SubOrder) { // equal order is always copy from Energies
    386                 for(int l=ColumnCounter;l--;) // then adds/subtract each column
     432                for(int l=ColumnCounter[ KeySet.OrderSet[SubOrder][j] ];l--;) // then adds/subtract each column
    387433                  Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][m][l] += MatrixValues.Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l];
    388434              } else {
    389                 for(int l=ColumnCounter;l--;)
     435                for(int l=ColumnCounter[ KeySet.OrderSet[SubOrder][j] ];l--;)
    390436                  Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][m][l] -= Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l];
    391437              }
    392438            }
    393             //if ((ColumnCounter>1) && (RowCounter[0]-1 >= 1))
     439            //if ((ColumnCounter[ KeySet.OrderSet[SubOrder][j] ]>1) && (RowCounter[0]-1 >= 1))
    394440             //cout << "Fragments[ KeySet.OrderSet[" << Order << "][" << CurrentFragment << "]=" << KeySet.OrderSet[Order][CurrentFragment] << " ][" << RowCounter[0]-1 << "][" << 1 << "] = " <<  Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][RowCounter[0]-1][1] << endl;
    395441          }
     
    426472      return false;
    427473    }
    428     output << Header << endl;
     474    output << Header[i] << endl;
    429475    for(int j=0;j<RowCounter[i];j++) {
    430       for(int k=0;k<ColumnCounter;k++)
     476      for(int k=0;k<ColumnCounter[i];k++)
    431477        output << scientific << Matrix[i][j][k] << "\t";
    432478      output << endl;
     
    455501    return false;
    456502  }
    457   output << Header << endl;
     503  output << Header[MatrixCounter] << endl;
    458504  for(int j=0;j<RowCounter[MatrixCounter];j++) {
    459     for(int k=0;k<ColumnCounter;k++)
     505    for(int k=0;k<ColumnCounter[MatrixCounter];k++)
    460506      output << scientific << Matrix[MatrixCounter][j][k] << "\t";
    461507    output << endl;
     
    485531/** Sums the energy with each factor and put into last element of \a EnergyMatrix::Matrix.
    486532 * Sums over the "F"-terms in ANOVA decomposition.
    487  * \param Matrix MatrixContainer with matrices (LevelCounter by ColumnCounter) with all the energies.
     533 * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies.
    488534 * \param CorrectionFragments MatrixContainer with hydrogen saturation correction per fragments
    489535 * \param KeySet KeySetContainer with bond Order and association mapping of each fragment to an order
     
    498544    for(int i=KeySet.FragmentsPerOrder[Order];i--;)
    499545      for(int j=RowCounter[ KeySet.OrderSet[Order][i] ];j--;)
    500         for(int k=ColumnCounter;k--;)
     546        for(int k=ColumnCounter[ KeySet.OrderSet[Order][i] ];k--;)
    501547          Matrix[MatrixCounter][j][k] += sign*Fragments.Matrix[ KeySet.OrderSet[Order][i] ][j][k];
    502548  else
    503549    for(int i=KeySet.FragmentsPerOrder[Order];i--;)
    504550      for(int j=RowCounter[ KeySet.OrderSet[Order][i] ];j--;)
    505         for(int k=ColumnCounter;k--;)
     551        for(int k=ColumnCounter[ KeySet.OrderSet[Order][i] ];k--;)
    506552          Matrix[MatrixCounter][j][k] += sign*(Fragments.Matrix[ KeySet.OrderSet[Order][i] ][j][k] + CorrectionFragments->Matrix[ KeySet.OrderSet[Order][i] ][j][k]);
    507553  return true;
     
    524570    // count maximum of columns
    525571    RowCounter[MatrixCounter] = 0;
    526     for(int j=0; j < MatrixCounter;j++) // (energy matrix might be bigger than number of atoms in terms of rows)
     572    ColumnCounter[MatrixCounter] = 0;
     573    for(int j=0; j < MatrixCounter;j++) { // (energy matrix might be bigger than number of atoms in terms of rows)
    527574      if (RowCounter[j] > RowCounter[MatrixCounter])
    528575        RowCounter[MatrixCounter] = RowCounter[j];
     576      if (ColumnCounter[j] > ColumnCounter[MatrixCounter])  // take maximum of all for last matrix
     577        ColumnCounter[MatrixCounter] = ColumnCounter[j];
     578    }
    529579    // allocate last plus one matrix
    530     cout << "Allocating last plus one matrix with " << (RowCounter[MatrixCounter]+1) << " rows and " << ColumnCounter << " columns." << endl;
     580    cout << "Allocating last plus one matrix with " << (RowCounter[MatrixCounter]+1) << " rows and " << ColumnCounter[MatrixCounter] << " columns." << endl;
    531581    Matrix[MatrixCounter] = (double **) Malloc(sizeof(double *)*(RowCounter[MatrixCounter]+1), "MatrixContainer::ParseFragmentMatrix: **Matrix[]");
    532582    for(int j=0;j<=RowCounter[MatrixCounter];j++)
    533       Matrix[MatrixCounter][j] = (double *) Malloc(sizeof(double)*ColumnCounter, "MatrixContainer::ParseFragmentMatrix: *Matrix[][]");
    534 
     583      Matrix[MatrixCounter][j] = (double *) Malloc(sizeof(double)*ColumnCounter[MatrixCounter], "MatrixContainer::ParseFragmentMatrix: *Matrix[][]");
     584   
    535585    // try independently to parse global energysuffix file if present
    536586    strncpy(filename, name, 1023);
     
    589639
    590640/** Sums the forces and puts into last element of \a ForceMatrix::Matrix.
    591  * \param Matrix MatrixContainer with matrices (LevelCounter by ColumnCounter) with all the energies.
     641 * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies.
    592642 * \param KeySet KeySetContainer with bond Order and association mapping of each fragment to an order
    593643 * \param Order bond order
     
    609659      if (j != -1) {
    610660        //if (j == 0) cout << "Summing onto ion 0, type 0 from fragment " << FragmentNr << ", ion " << l << "." << endl;
    611         for(int k=2;k<ColumnCounter;k++)
     661        for(int k=2;k<ColumnCounter[MatrixCounter];k++)
    612662          Matrix[MatrixCounter][j][k] += sign*Fragments.Matrix[ FragmentNr ][l][k];
    613663      }
     
    656706    input.close();
    657707
     708    ColumnCounter[MatrixCounter] = 0;
     709    for(int j=0; j < MatrixCounter;j++) { // (energy matrix might be bigger than number of atoms in terms of rows)
     710      if (ColumnCounter[j] > ColumnCounter[MatrixCounter])  // take maximum of all for last matrix
     711        ColumnCounter[MatrixCounter] = ColumnCounter[j];
     712    }
     713 
    658714    // allocate last plus one matrix
    659     cout << "Allocating last plus one matrix with " << (RowCounter[MatrixCounter]+1) << " rows and " << ColumnCounter << " columns." << endl;
     715    cout << "Allocating last plus one matrix with " << (RowCounter[MatrixCounter]+1) << " rows and " << ColumnCounter[MatrixCounter] << " columns." << endl;
    660716    Matrix[MatrixCounter] = (double **) Malloc(sizeof(double *)*(RowCounter[MatrixCounter]+1), "MatrixContainer::ParseFragmentMatrix: **Matrix[]");
    661717    for(int j=0;j<=RowCounter[MatrixCounter];j++)
    662       Matrix[MatrixCounter][j] = (double *) Malloc(sizeof(double)*ColumnCounter, "MatrixContainer::ParseFragmentMatrix: *Matrix[][]");
     718      Matrix[MatrixCounter][j] = (double *) Malloc(sizeof(double)*ColumnCounter[MatrixCounter], "MatrixContainer::ParseFragmentMatrix: *Matrix[][]");
     719
     720    // try independently to parse global forcesuffix file if present
     721    strncpy(filename, name, 1023);
     722    strncat(filename, prefix, 1023-strlen(filename));
     723    strncat(filename, suffix.c_str(), 1023-strlen(filename));
     724    ParseMatrix(filename, skiplines, skipcolumns, MatrixCounter);
     725  }
     726 
     727
     728  return status;
     729};
     730
     731// ======================================= CLASS HessianMatrix =============================
     732
     733/** Parsing force Indices of each fragment
     734 * \param *name directory with \a ForcesFile
     735 * \return parsing successful
     736 */
     737bool HessianMatrix::ParseIndices(char *name)
     738{
     739  ifstream input;
     740  char *FragmentNumber = NULL;
     741  char filename[1023];
     742  stringstream line;
     743 
     744  cout << "Parsing hessian indices for " << MatrixCounter << " matrices." << endl;
     745  Indices = (int **) Malloc(sizeof(int *)*(MatrixCounter+1), "HessianMatrix::ParseIndices: **Indices");
     746  line << name << FRAGMENTPREFIX << FORCESFILE;
     747  input.open(line.str().c_str(), ios::in);
     748  //cout << "Opening " << line.str() << " ... "  << input << endl;
     749  if (input == NULL) {
     750    cout << endl << "Unable to open " << line.str() << ", is the directory correct?" << endl;
     751    return false;
     752  }
     753  for (int i=0;(i<MatrixCounter) && (!input.eof());i++) {
     754    // get the number of atoms for this fragment
     755    input.getline(filename, 1023);
     756    line.str(filename);
     757    // parse the values
     758    Indices[i] = (int *) Malloc(sizeof(int)*RowCounter[i], "HessianMatrix::ParseIndices: *Indices[]");
     759    FragmentNumber = FixedDigitNumber(MatrixCounter, i);
     760    //cout << FRAGMENTPREFIX << FragmentNumber << "[" << RowCounter[i] << "]:";
     761    Free((void **)&FragmentNumber, "HessianMatrix::ParseIndices: *FragmentNumber");
     762    for(int j=0;(j<RowCounter[i]) && (!line.eof());j++) {
     763      line >> Indices[i][j];
     764      //cout << " " << Indices[i][j];
     765    }
     766    //cout << endl;
     767  }
     768  Indices[MatrixCounter] = (int *) Malloc(sizeof(int)*RowCounter[MatrixCounter], "HessianMatrix::ParseIndices: *Indices[]");
     769  for(int j=RowCounter[MatrixCounter];j--;) {
     770    Indices[MatrixCounter][j] = j;
     771  }
     772  input.close();
     773  return true;
     774};
     775
     776
     777/** Sums the hessian entries and puts into last element of \a HessianMatrix::Matrix.
     778 * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies.
     779 * \param KeySet KeySetContainer with bond Order and association mapping of each fragment to an order
     780 * \param Order bond order
     781 *  \param sign +1 or -1
     782 * \return true if summing was successful
     783 */
     784bool HessianMatrix::SumSubHessians(class HessianMatrix &Fragments, class KeySetsContainer &KeySet, int Order, double sign)
     785{
     786  int FragmentNr;
     787  // sum forces
     788  for(int i=0;i<KeySet.FragmentsPerOrder[Order];i++) {
     789    FragmentNr = KeySet.OrderSet[Order][i];
     790    for(int l=0;l<RowCounter[ FragmentNr ];l++) {
     791      int j = Indices[ FragmentNr ][l];
     792      if (j > RowCounter[MatrixCounter]) {
     793        cerr << "Current hessian index " << j << " is greater than " << RowCounter[MatrixCounter] << ", where i=" << i << ", Order=" << Order << ", l=" << l << " and FragmentNr=" << FragmentNr << "!" << endl;
     794        return false;
     795      }
     796      if (j != -1) {
     797        for(int m=0;m<ColumnCounter[ FragmentNr ];m++) {
     798          int k = Indices[ FragmentNr ][m];
     799          if (k > ColumnCounter[MatrixCounter]) {
     800            cerr << "Current hessian index " << k << " is greater than " << ColumnCounter[MatrixCounter] << ", where m=" << m << ", j=" << j << ", i=" << i << ", Order=" << Order << ", l=" << l << " and FragmentNr=" << FragmentNr << "!" << endl;
     801            return false;
     802          }
     803          if (k != -1) {
     804            //cout << "Adding " << sign*Fragments.Matrix[ FragmentNr ][l][m] << " from [" << l << "][" << m << "] onto [" << j << "][" << k << "]." << endl;
     805            Matrix[MatrixCounter][j][k] += sign*Fragments.Matrix[ FragmentNr ][l][m];
     806          }
     807        }
     808      }
     809    }
     810  }
     811  return true;
     812};
     813
     814/** Constructor for class HessianMatrix.
     815 */
     816HessianMatrix::HessianMatrix() : MatrixContainer()
     817{
     818   IsSymmetric = true;
     819}
     820
     821/** Sums the hessian entries with each factor and put into last element of \a ***Matrix.
     822 * Sums over "E"-terms to create the "F"-terms
     823 * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies.
     824 * \param KeySet KeySetContainer with bond Order and association mapping of each fragment to an order
     825 * \param Order bond order
     826 * \return true if summing was successful
     827 */
     828bool HessianMatrix::SumSubManyBodyTerms(class MatrixContainer &MatrixValues, class KeySetsContainer &KeySet, int Order)
     829{
     830  // go through each order
     831  for (int CurrentFragment=0;CurrentFragment<KeySet.FragmentsPerOrder[Order];CurrentFragment++) {
     832    //cout << "Current Fragment is " << CurrentFragment << "/" << KeySet.OrderSet[Order][CurrentFragment] << "." << endl;
     833    // then go per order through each suborder and pick together all the terms that contain this fragment
     834    for(int SubOrder=0;SubOrder<=Order;SubOrder++) { // go through all suborders up to the desired order
     835      for (int j=0;j<KeySet.FragmentsPerOrder[SubOrder];j++) { // go through all possible fragments of size suborder
     836        if (KeySet.Contains(KeySet.OrderSet[Order][CurrentFragment], KeySet.OrderSet[SubOrder][j])) {
     837          //cout << "Current other fragment is " << j << "/" << KeySet.OrderSet[SubOrder][j] << "." << endl;
     838          // if the fragment's indices are all in the current fragment
     839          for(int k=0;k<RowCounter[ KeySet.OrderSet[SubOrder][j] ];k++) { // go through all atoms in this fragment
     840            int m = MatrixValues.Indices[ KeySet.OrderSet[SubOrder][j] ][k];
     841            //cout << "Current row index is " << k << "/" << m << "." << endl;
     842            if (m != -1) { // if it's not an added hydrogen
     843              for (int l=0;l<RowCounter[ KeySet.OrderSet[Order][CurrentFragment] ];l++) { // look for the corresponding index in the current fragment
     844                //cout << "Comparing " << m << " with " << MatrixValues.Indices[ KeySet.OrderSet[Order][CurrentFragment] ][l] << "." << endl;
     845                if (m == MatrixValues.Indices[ KeySet.OrderSet[Order][CurrentFragment] ][l]) {
     846                  m = l;
     847                  break; 
     848                }
     849              }
     850              //cout << "Corresponding row index for " << k << " in CurrentFragment is " << m << "." << endl;
     851              if (m > RowCounter[ KeySet.OrderSet[Order][CurrentFragment] ]) {
     852                cerr << "In fragment No. " << KeySet.OrderSet[Order][CurrentFragment]   << " current row index " << m << " is greater than " << RowCounter[ KeySet.OrderSet[Order][CurrentFragment] ] << "!" << endl;
     853                return false;
     854              }
     855             
     856              for(int l=0;l<ColumnCounter[ KeySet.OrderSet[SubOrder][j] ];l++) {
     857                int n = MatrixValues.Indices[ KeySet.OrderSet[SubOrder][j] ][l];
     858                //cout << "Current column index is " << l << "/" << n << "." << endl;
     859                if (n != -1) { // if it's not an added hydrogen
     860                  for (int p=0;p<ColumnCounter[ KeySet.OrderSet[Order][CurrentFragment] ];p++) { // look for the corresponding index in the current fragment
     861                    //cout << "Comparing " << n << " with " << MatrixValues.Indices[ KeySet.OrderSet[Order][CurrentFragment] ][p] << "." << endl;
     862                    if (n == MatrixValues.Indices[ KeySet.OrderSet[Order][CurrentFragment] ][p]) {
     863                      n = p;
     864                      break; 
     865                    }
     866                  }
     867                  //cout << "Corresponding column index for " << l << " in CurrentFragment is " << n << "." << endl;
     868                  if (n > ColumnCounter[ KeySet.OrderSet[Order][CurrentFragment] ]) {
     869                    cerr << "In fragment No. " << KeySet.OrderSet[Order][CurrentFragment]   << " current column index " << n << " is greater than " << ColumnCounter[ KeySet.OrderSet[Order][CurrentFragment] ] << "!" << endl;
     870                    return false;
     871                  }
     872                  if (Order == SubOrder) { // equal order is always copy from Energies
     873                    //cout << "Adding " << MatrixValues.Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l] << " from [" << k << "][" << l << "] onto [" << m << "][" << n << "]." << endl;
     874                    Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][m][n] += MatrixValues.Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l];
     875                  } else {
     876                    //cout << "Subtracting " << Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l] << " from [" << k << "][" << l << "] onto [" << m << "][" << n << "]." << endl;
     877                    Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][m][n] -= Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l];
     878                  }
     879                }
     880              }
     881            }
     882            //if ((ColumnCounter[ KeySet.OrderSet[SubOrder][j] ]>1) && (RowCounter[0]-1 >= 1))
     883             //cout << "Fragments[ KeySet.OrderSet[" << Order << "][" << CurrentFragment << "]=" << KeySet.OrderSet[Order][CurrentFragment] << " ][" << RowCounter[0]-1 << "][" << 1 << "] = " <<  Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][RowCounter[0]-1][1] << endl;
     884          }
     885        } else {
     886          //cout << "Fragment " << KeySet.OrderSet[SubOrder][j] << " is not contained in fragment " << KeySet.OrderSet[Order][CurrentFragment] << "." << endl;
     887        }
     888      }
     889    }
     890   //cout << "Final Fragments[ KeySet.OrderSet[" << Order << "][" << CurrentFragment << "]=" << KeySet.OrderSet[Order][CurrentFragment] << " ][" << KeySet.AtomCounter[0]-1 << "][" << 1 << "] = " <<  Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][KeySet.AtomCounter[0]-1][1] << endl;
     891  }
     892 
     893  return true;
     894};
     895
     896/** Calls MatrixContainer::ParseFragmentMatrix() and additionally allocates last plus one matrix.
     897 * \param *name directory with files
     898 * \param *prefix prefix of each matrix file
     899 * \param *suffix suffix of each matrix file
     900 * \param skiplines number of inital lines to skip
     901 * \param skiplines number of inital columns to skip
     902 * \return parsing successful
     903 */
     904bool HessianMatrix::ParseFragmentMatrix(const char *name, const char *prefix, string suffix, int skiplines, int skipcolumns)
     905{
     906  char filename[1023];
     907  ifstream input;
     908  stringstream file;
     909  int nr;
     910  bool status = MatrixContainer::ParseFragmentMatrix(name, prefix, suffix, skiplines, skipcolumns);
     911
     912  if (status) {
     913    // count number of atoms for last plus one matrix
     914    file << name << FRAGMENTPREFIX << KEYSETFILE;
     915    input.open(file.str().c_str(), ios::in);
     916    if (input == NULL) {
     917      cout << endl << "Unable to open " << file.str() << ", is the directory correct?" << endl;
     918      return false;
     919    }
     920    RowCounter[MatrixCounter] = 0;
     921    ColumnCounter[MatrixCounter] = 0;
     922    while (!input.eof()) {
     923      input.getline(filename, 1023);
     924      stringstream zeile(filename);
     925      while (!zeile.eof()) {
     926        zeile >> nr;
     927        //cout << "Current index: " << nr << "." << endl;
     928        if (nr > RowCounter[MatrixCounter]) {
     929          RowCounter[MatrixCounter] = nr;
     930          ColumnCounter[MatrixCounter] = nr;
     931        }
     932      }
     933    }
     934    RowCounter[MatrixCounter]++;    // nr start at 0, count starts at 1
     935    ColumnCounter[MatrixCounter]++;    // nr start at 0, count starts at 1
     936    input.close();
     937 
     938    // allocate last plus one matrix
     939    cout << "Allocating last plus one matrix with " << (RowCounter[MatrixCounter]+1) << " rows and " << ColumnCounter[MatrixCounter] << " columns." << endl;
     940    Matrix[MatrixCounter] = (double **) Malloc(sizeof(double *)*(RowCounter[MatrixCounter]+1), "MatrixContainer::ParseFragmentMatrix: **Matrix[]");
     941    for(int j=0;j<=RowCounter[MatrixCounter];j++)
     942      Matrix[MatrixCounter][j] = (double *) Malloc(sizeof(double)*ColumnCounter[MatrixCounter], "MatrixContainer::ParseFragmentMatrix: *Matrix[][]");
    663943
    664944    // try independently to parse global forcesuffix file if present
  • src/parser.hpp

    r042f82 r36ec71  
    1919
    2020#define EnergySuffix ".energy.all"
     21#define EnergyFragmentSuffix ".energyfragment.all"
     22#define ForcesSuffix ".forces.all"
     23#define ForceFragmentSuffix ".forcefragment.all"
    2124#define HcorrectionSuffix ".Hcorrection.all"
    22 #define ForcesSuffix ".forces.all"
     25#define HcorrectionFragmentSuffix ".Hcorrectionfragment.all"
     26#define HessianSuffix ".hessian_xx.all"
     27#define HessianFragmentSuffix ".hessianfragment_xx.all"
     28#define OrderSuffix ".Order"
    2329#define ShieldingSuffix ".sigma_all.csv"
    2430#define ShieldingPASSuffix ".sigma_all_PAS.csv"
    2531#define ShieldingFragmentSuffix ".sigma_all_fragment.all"
    2632#define ShieldingPASFragmentSuffix ".sigma_all_PAS_fragment.all"
     33#define ChiSuffix ".chi_all.csv"
     34#define ChiPASSuffix ".chi_all_PAS.csv"
     35#define ChiFragmentSuffix ".chi_all_fragment.all"
     36#define ChiPASFragmentSuffix ".chi_all_PAS_fragment.all"
    2737#define TimeSuffix ".speed"
    28 #define EnergyFragmentSuffix ".energyfragment.all"
    29 #define HcorrectionFragmentSuffix ".Hcorrectionfragment.all"
    30 #define ForceFragmentSuffix ".forcefragment.all"
    31 #define OrderSuffix ".Order"
    3238
    3339// ======================================= FUNCTIONS ==========================================
     
    4349    double ***Matrix;
    4450    int **Indices;
    45     char *Header;
     51    char **Header;
    4652    int MatrixCounter;
    4753    int *RowCounter;
    48     int ColumnCounter;
    49 
     54    int *ColumnCounter;
     55 
    5056  MatrixContainer();
    51   virtual ~MatrixContainer();
    52 
     57  ~MatrixContainer();
     58 
     59  bool InitialiseIndices(class MatrixContainer *Matrix = NULL);
    5360  bool ParseMatrix(const char *name, int skiplines, int skipcolumns, int MatrixNr);
    5461  virtual bool ParseFragmentMatrix(const char *name, const char *prefix, string suffix, int skiplines, int skipcolumns);
    55   bool AllocateMatrix(const char *GivenHeader, int MCounter, int *RCounter, int CCounter);
     62  bool AllocateMatrix(char **GivenHeader, int MCounter, int *RCounter, int *CCounter);
    5663  bool ResetMatrix();
    5764  double FindMinValue();
     
    8491};
    8592
     93// ======================================= CLASS HessianMatrix =============================
     94
     95class HessianMatrix : public MatrixContainer {
     96  public:
     97    HessianMatrix();
     98    //~HessianMatrix();
     99    bool ParseIndices(char *name);
     100    bool SumSubManyBodyTerms(class MatrixContainer &MatrixValues, class KeySetsContainer &KeySet, int Order);
     101    bool SumSubHessians(class HessianMatrix &Fragments, class KeySetsContainer &KeySet, int Order, double sign);
     102    bool ParseFragmentMatrix(const char *name, const char *prefix, string suffix, int skiplines, int skipcolumns);
     103  private:
     104    bool IsSymmetric;
     105};
     106
    86107// ======================================= CLASS KeySetsContainer =============================
    87108
Note: See TracChangeset for help on using the changeset viewer.