Changeset 042f82


Ignore:
Timestamp:
Jul 23, 2009, 2:21:57 PM (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:
36ec71
Parents:
205ccd
Message:

fixed indentation from tabs to two spaces.

Location:
src
Files:
28 edited

Legend:

Unmodified
Added
Removed
  • src/analyzer.cpp

    r205ccd r042f82  
    2323int main(int argc, char **argv)
    2424{
    25         periodentafel *periode = NULL; // and a period table of all elements
    26         EnergyMatrix Energy;
    27         EnergyMatrix Hcorrection;
    28         ForceMatrix Force;
    29         ForceMatrix Shielding;
    30         ForceMatrix ShieldingPAS;
    31         EnergyMatrix Time;
    32         EnergyMatrix EnergyFragments;
    33         EnergyMatrix HcorrectionFragments;
    34         ForceMatrix ForceFragments;
    35         ForceMatrix ShieldingFragments;
    36         ForceMatrix ShieldingPASFragments;
    37         KeySetsContainer KeySet;
    38         ofstream output;
    39         ofstream output2;
    40         ofstream output3;
    41         ofstream output4;
    42         ifstream input;
    43         stringstream filename;
    44         time_t t = time(NULL);
    45         struct tm *ts = localtime(&t);
    46         char *datum = asctime(ts);
    47         stringstream Orderxrange;
    48         stringstream Fragmentxrange;
    49         stringstream yrange;
    50         char *dir = NULL;
    51         bool Hcorrected = true;
    52         int counter;
    53 
    54         cout << "ANOVA Analyzer" << endl;
    55         cout << "==============" << endl;
    56 
    57         // Get the command line options
    58         if (argc < 4) {
    59                 cout << "Usage: " << argv[0] << " <inputdir> <prefix> <outputdir> [elementsdb]" << endl;
    60                 cout << "<inputdir>\ttherein the output of a molecuilder fragmentation is expected, each fragment with a subdir containing an energy.all and a forces.all file." << endl;
    61                 cout << "<prefix>\tprefix of energy and forces file." << endl;
    62                 cout << "<outputdir>\tcreated plotfiles and datafiles are placed into this directory " << endl;
    63                 cout << "[elementsdb]\tpath to elements database, needed for shieldings." << endl;
    64                 return 1;
    65         } else {
    66                 dir = (char *) Malloc(sizeof(char)*(strlen(argv[2])+2), "main: *dir");
    67                 strcpy(dir, "/");
    68                 strcat(dir, argv[2]);
    69         }
    70 
    71         if (argc > 4) {
    72                 cout << "Loading periodentafel." << endl;
    73                 periode = new periodentafel;
    74                 periode->LoadPeriodentafel(argv[4]);
    75         }
    76 
    77         // Test the given directory
    78         if (!TestParams(argc, argv))
    79                 return 1;
    80 
    81         // +++++++++++++++++ PARSING +++++++++++++++++++++++++++++++
    82 
    83         // ------------- Parse through all Fragment subdirs --------
    84         if (!Energy.ParseFragmentMatrix(argv[1], dir, EnergySuffix,0,0)) return 1;
    85         Hcorrected = Hcorrection.ParseFragmentMatrix(argv[1], "", HCORRECTIONSUFFIX,0,0);
    86         if (!Force.ParseFragmentMatrix(argv[1], dir, ForcesSuffix,0,0)) return 1;
    87         if (!Time.ParseFragmentMatrix(argv[1], dir, TimeSuffix, 10,1)) return 1;
    88         if (periode != NULL) { // also look for PAS values
    89                 if (!Shielding.ParseFragmentMatrix(argv[1], dir, ShieldingSuffix, 1, 0)) return 1;
    90                 if (!ShieldingPAS.ParseFragmentMatrix(argv[1], dir, ShieldingPASSuffix, 1, 0)) return 1;
    91         }
    92 
    93         // ---------- Parse the TE Factors into an array -----------------
    94         if (!Energy.ParseIndices()) return 1;
    95         if (Hcorrected) Hcorrection.ParseIndices();
    96 
    97         // ---------- Parse the Force indices into an array ---------------
    98         if (!Force.ParseIndices(argv[1])) return 1;
    99         if (!ForceFragments.AllocateMatrix(Force.Header, Force.MatrixCounter, Force.RowCounter, Force.ColumnCounter)) return 1;
    100         if (!ForceFragments.ParseIndices(argv[1])) return 1;
    101 
    102         // ---------- Parse the shielding indices into an array ---------------
    103         if (periode != NULL) { // also look for PAS values
    104                 if(!Shielding.ParseIndices(argv[1])) return 1;
    105                 if(!ShieldingPAS.ParseIndices(argv[1])) return 1;
    106                 if (!ShieldingFragments.AllocateMatrix(Shielding.Header, Shielding.MatrixCounter, Shielding.RowCounter, Shielding.ColumnCounter)) return 1;
    107                 if (!ShieldingPASFragments.AllocateMatrix(ShieldingPAS.Header, ShieldingPAS.MatrixCounter, ShieldingPAS.RowCounter, ShieldingPAS.ColumnCounter)) return 1;
    108                 if(!ShieldingFragments.ParseIndices(argv[1])) return 1;
    109                 if(!ShieldingPASFragments.ParseIndices(argv[1])) return 1;
    110         }
    111 
    112         // ---------- Parse the KeySets into an array ---------------
    113         if (!KeySet.ParseKeySets(argv[1], Force.RowCounter, Force.MatrixCounter)) return 1;
    114         if (!KeySet.ParseManyBodyTerms()) return 1;
    115 
    116         // ---------- Parse fragment files created by 'joiner' into an array -------------
    117         if (!EnergyFragments.ParseFragmentMatrix(argv[1], dir, EnergyFragmentSuffix,0,0)) return 1;
    118         if (Hcorrected) HcorrectionFragments.ParseFragmentMatrix(argv[1], dir, HcorrectionFragmentSuffix,0,0);
    119         if (!ForceFragments.ParseFragmentMatrix(argv[1], dir, ForceFragmentSuffix,0,0)) return 1;
    120         if (periode != NULL) { // also look for PAS values
    121                 if (!ShieldingFragments.ParseFragmentMatrix(argv[1], dir, ShieldingFragmentSuffix, 1, 0)) return 1;
    122                 if (!ShieldingPASFragments.ParseFragmentMatrix(argv[1], dir, ShieldingPASFragmentSuffix, 1, 0)) return 1;
    123         }
    124 
    125         // +++++++++++++++ TESTING ++++++++++++++++++++++++++++++
    126 
    127         // print energy and forces to file
    128         filename.str("");
    129         filename << argv[3] << "/" << "energy-forces.all";
    130         output.open(filename.str().c_str(), ios::out);
    131         output << endl << "Total Energy" << endl << "==============" << endl << Energy.Header << endl;
    132         for(int j=0;j<Energy.RowCounter[Energy.MatrixCounter];j++) {
    133                 for(int k=0;k<Energy.ColumnCounter;k++)
    134                         output << scientific << Energy.Matrix[ Energy.MatrixCounter ][j][k] << "\t";
    135                 output << endl;
    136         }
    137         output << endl;
    138 
    139         output << endl << "Total Forces" << endl << "===============" << endl << Force.Header << endl;
    140         for(int j=0;j<Force.RowCounter[Force.MatrixCounter];j++) {
    141                 for(int k=0;k<Force.ColumnCounter;k++)
    142                         output << scientific << Force.Matrix[ Force.MatrixCounter ][j][k] << "\t";
    143                 output << endl;
    144         }
    145         output << endl;
    146 
    147         if (periode != NULL) { // also look for PAS values
    148                 output << endl << "Total Shieldings" << endl << "===============" << endl << Shielding.Header << endl;
    149                 for(int j=0;j<Shielding.RowCounter[Shielding.MatrixCounter];j++) {
    150                         for(int k=0;k<Shielding.ColumnCounter;k++)
    151                                 output << scientific << Shielding.Matrix[ Shielding.MatrixCounter ][j][k] << "\t";
    152                         output << endl;
    153                 }
    154                 output << endl;
    155 
    156                 output << endl << "Total Shieldings PAS" << endl << "===============" << endl << ShieldingPAS.Header << endl;
    157                 for(int j=0;j<ShieldingPAS.RowCounter[ShieldingPAS.MatrixCounter];j++) {
    158                         for(int k=0;k<ShieldingPAS.ColumnCounter;k++)
    159                                 output << scientific << ShieldingPAS.Matrix[ ShieldingPAS.MatrixCounter ][j][k] << "\t";
    160                         output << endl;
    161                 }
    162                 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;
    173         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];
    176 
    177         // +++++++++++++++ ANALYZING ++++++++++++++++++++++++++++++
    178 
    179         cout << "Analyzing ..." << endl;
    180 
    181         // ======================================= Creating the data files ==============================================================
    182 
    183         // +++++++++++++++++++++++++++++++++++++++ Plotting Simtime vs Bond Order
    184         // +++++++++++++++++++++++++++++++++++++++ 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();
    215 
    216         // +++++++++++++++++++++++++++++++++++++++ Plotting shieldings
    217 
    218         if (periode != NULL) { // also look for PAS values
    219                 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;
    220                 if (!CreateDataForcesOrderPerAtom(ShieldingPASFragments, KeySet, argv[3], "ShieldingsPAS-Order", "Plot of approximated shieldings versus the Bond Order", datum)) return 1;
    221                 if (!AppendOutputFile(output, argv[3], "ShieldingsPAS-Order.dat" )) return false;
    222                 output << endl << "# Full" << endl;
    223                 for(int j=0;j<ShieldingPAS.RowCounter[ShieldingPAS.MatrixCounter];j++) {
    224                         output << j << "\t";
    225                         for(int k=0;k<ShieldingPAS.ColumnCounter;k++)
    226                                 output << scientific << ShieldingPAS.Matrix[ ShieldingPAS.MatrixCounter ][j][k] << "\t"; //*(((k>1) && (k<6))? 1.e6 : 1.) << "\t";
    227                         output << endl;
    228                 }
    229         }
    230         output.close();
    231 
    232 
    233         // +++++++++++++++++++++++++++++++++++++++ Plotting deviation in energy to full QM
    234         if (!CreateDataDeltaEnergyOrder(Energy, EnergyFragments, KeySet, argv[3], "DeltaEnergies-Order", "Plot of error between approximated and full energies energies versus the Bond Order", datum)) return 1;
    235 
    236         // +++++++++++++++++++++++++++++++++++Plotting Energies vs. Order
    237         if (!CreateDataEnergyOrder(EnergyFragments, KeySet, argv[3], "Energies-Order", "Plot of approximated energies versus the Bond Order", datum)) return 1;
    238 
    239         // +++++++++++++++++++++++++++++++++++++++ Plotting deviation in forces to full QM
    240         if (!CreateDataDeltaForcesOrderPerAtom(Force, ForceFragments, KeySet, argv[3], "DeltaForces-Order", "Plot of error between approximated forces and full forces versus the Bond Order", datum)) return 1;
    241 
    242         // min force
    243         if (!CreateDataDeltaForcesOrder(Force, ForceFragments, KeySet, argv[3], "DeltaMinForces-Order", "Plot of min error between approximated forces and full forces versus the Bond Order", datum, CreateMinimumForce)) return 1;
    244 
    245         // mean force
    246         if (!CreateDataDeltaForcesOrder(Force, ForceFragments, KeySet, argv[3], "DeltaMeanForces-Order", "Plot of mean error between approximated forces and full forces versus the Bond Order", datum, CreateMeanForce)) return 1;
    247 
    248         // max force
    249         if (!CreateDataDeltaForcesOrder(Force, ForceFragments, KeySet, argv[3], "DeltaMaxForces-Order", "Plot of max error between approximated forces and full forces versus the Bond Order", datum, CreateMaximumForce)) return 1;
    250 
    251         // ++++++++++++++++++++++++++++++++++++++Plotting Forces vs. Order
    252         if (!CreateDataForcesOrderPerAtom(ForceFragments, KeySet, argv[3], "Forces-Order", "Plot of approximated forces versus the Bond Order", datum)) return 1;
    253         if (!AppendOutputFile(output, argv[3], "Forces-Order.dat" )) return false;
    254         output << endl << "# Full" << endl;
    255         for(int j=0;j<Force.RowCounter[Force.MatrixCounter];j++) {
    256                 output << j << "\t";
    257                 for(int k=0;k<Force.ColumnCounter;k++)
    258                         output << scientific << Force.Matrix[ Force.MatrixCounter ][j][k] << "\t";
    259                 output << endl;
    260         }
    261         output.close();
    262         // min force
    263         if (!CreateDataForcesOrder(ForceFragments, KeySet, argv[3], "MinForces-Order", "Plot of min approximated forces versus the Bond Order", datum, CreateMinimumForce)) return 1;
    264 
    265         // mean force
    266         if (!CreateDataForcesOrder(ForceFragments, KeySet, argv[3], "MeanForces-Order", "Plot of mean approximated forces versus the Bond Order", datum, CreateMeanForce)) return 1;
    267 
    268         // max force
    269         if (!CreateDataForcesOrder(ForceFragments, KeySet, argv[3], "MaxForces-Order", "Plot of max approximated forces versus the Bond Order", datum, CreateMaximumForce)) return 1;
    270 
    271         // ++++++++++++++++++++++++++++++++++++++Plotting vector sum (should be 0) vs. bond order
    272         if (!CreateDataForcesOrder(ForceFragments, KeySet, argv[3], "VectorSum-Order", "Plot of vector sum of the approximated forces versus the Bond Order", datum, CreateVectorSumForce)) return 1;
    273 
    274         // +++++++++++++++++++++++++++++++Plotting energyfragments vs. order
    275         if (!CreateDataFragment(EnergyFragments, KeySet, argv[3], "Energies-Fragment", "Plot of fragment energy versus the Fragment No", datum, CreateEnergy)) return 1;
    276         if (!CreateDataFragment(EnergyFragments, KeySet, argv[3], "Energies-FragmentOrder", "Plot of fragment energy of each Fragment No vs. Bond Order", datum, CreateEnergy)) return 1;
    277         if (!CreateDataFragmentOrder(EnergyFragments, KeySet, argv[3], "MaxEnergies-FragmentOrder", "Plot of maximum of fragment energy vs. Bond Order", datum, CreateMaxFragmentOrder)) return 1;
    278         if (!CreateDataFragmentOrder(EnergyFragments, KeySet, argv[3], "MinEnergies-FragmentOrder", "Plot of minimum of fragment energy vs. Bond Order", datum, CreateMinFragmentOrder)) return 1;
    279 
    280         // +++++++++++++++++++++++++++++++Ploting min/mean/max forces for each fragment
    281         // min force
    282         if (!CreateDataFragment(ForceFragments, KeySet, argv[3], "MinForces-Fragment", "Plot of min approximated forces versus the Fragment No", datum, CreateMinimumForce)) return 1;
    283 
    284         // mean force
    285         if (!CreateDataFragment(ForceFragments, KeySet, argv[3], "MeanForces-Fragment", "Plot of mean approximated forces versus the Fragment No", datum, CreateMeanForce)) return 1;
    286 
    287         // max force
    288         if (!CreateDataFragment(ForceFragments, KeySet, argv[3], "MaxForces-Fragment", "Plot of max approximated forces versus the Fragment No", datum, CreateMaximumForce)) return 1;
    289 
    290         // +++++++++++++++++++++++++++++++Ploting min/mean/max forces for each fragment per order
    291         // min force
    292         if (!CreateDataFragment(ForceFragments, KeySet, argv[3], "MinForces-FragmentOrder", "Plot of min approximated forces of each Fragment No vs. Bond Order", datum, CreateMinimumForce)) return 1;
    293 
    294         // mean force
    295         if (!CreateDataFragment(ForceFragments, KeySet, argv[3], "MeanForces-FragmentOrder", "Plot of mean approximated forces of each Fragment No vs. Bond Order", datum, CreateMeanForce)) return 1;
    296 
    297         // max force
    298         if (!CreateDataFragment(ForceFragments, KeySet, argv[3], "MaxForces-FragmentOrder", "Plot of max approximated forces of each Fragment No vs. Bond Order", datum, CreateMaximumForce)) return 1;
    299 
    300         // ======================================= Creating the plot files ==============================================================
    301 
    302         Orderxrange << "[1:" << KeySet.Order << "]";
    303         Fragmentxrange << "[0:" << KeySet.FragmentCounter+1 << "]";
    304         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 
    309         // +++++++++++++++++++++++++++++++++++++++ Plotting deviation in energy to full QM
    310         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;
    311 
    312         // +++++++++++++++++++++++++++++++++++Plotting Energies vs. Order
    313         if (!CreatePlotOrder(Energy, KeySet, argv[3], "Energies-Order", 1, "outside", "", "",   1, 1, "bond order k", "approximate energy [Ht]", Orderxrange.str().c_str(), "", "1" , "with linespoints", EnergyPlotLine)) return 1;
    314 
    315         // +++++++++++++++++++++++++++++++++++++++ Plotting deviation in forces to full QM
    316         yrange.str("[1e-8:1e+0]");
    317         // min force
    318         if (!CreatePlotOrder(Force, KeySet, argv[3], "DeltaMinForces-Order", 2, "top right", "y", "",   1, 1, "bond order k", "absolute error in min force [Ht/a.u.]", Orderxrange.str().c_str(), yrange.str().c_str(), "1" , "with linespoints", ForceMagnitudePlotLine)) return 1;
    319 
    320         // mean force
    321         if (!CreatePlotOrder(Force, KeySet, argv[3], "DeltaMeanForces-Order", 2, "top right", "y", "",  1, 1, "bond order k", "absolute error in mean force [Ht/a.u.]", Orderxrange.str().c_str(), yrange.str().c_str(), "1" , "with linespoints", AbsFirstForceValuePlotLine)) return 1;
    322 
    323         // max force
    324         if (!CreatePlotOrder(Force, KeySet, argv[3], "DeltaMaxForces-Order", 2, "top right", "y", "",   1, 1, "bond order k", "absolute error in max force [Ht/a.u.]", Orderxrange.str().c_str(), yrange.str().c_str(), "1" , "with linespoints", ForceMagnitudePlotLine)) return 1;
    325 
    326         // min/mean/max comparison for total force
    327         if(!OpenOutputFile(output, argv[3], "DeltaMinMeanMaxTotalForce-Order.pyx")) return 1;
    328         CreatePlotHeader(output, "DeltaMinMeanMaxTotalForce-Order", 1, "bottom left", "y", NULL,        1, 1, "bond order k", "absolute error in total forces [Ht/a.u.]");
    329         output << "plot " << Orderxrange.str().c_str() << " [1e-8:1e+0] \\" << endl;
    330         output << "'DeltaMinForces-Order.dat' title 'minimum' using 1:(sqrt($" << 8 << "*$" << 8 << "+$" << 8+1 << "*$" << 8+1 << "+$" << 8+2 << "*$" << 8+2 << ")) with linespoints, \\" << endl;
    331         output << "'DeltaMeanForces-Order.dat' title 'mean' using 1:(abs($" << 8 << ")) with linespoints, \\" << endl;
    332         output << "'DeltaMaxForces-Order.dat' title 'maximum' using 1:(sqrt($" << 8 << "*$" << 8 << "+$" << 8+1 << "*$" << 8+1 << "+$" << 8+2 << "*$" << 8+2 << ")) with linespoints" << endl;
    333         output.close();
    334 
    335         // ++++++++++++++++++++++++++++++++++++++Plotting Forces vs. Order
    336         // min force
    337         if (!CreatePlotOrder(Force, KeySet, argv[3], "MinForces-Order", 2, "bottom right", "y", "",     1, 1, "bond order k", "absolute approximated min force [Ht/a.u.]", Orderxrange.str().c_str(), "", "1" , "with linespoints", ForceMagnitudePlotLine)) return 1;
    338 
    339         // mean force
    340         if (!CreatePlotOrder(Force, KeySet, argv[3], "MeanForces-Order", 2, "bottom right", "y", "",    1, 1, "bond order k", "absolute approximated mean force [Ht/a.u.]", Orderxrange.str().c_str(), "", "1" , "with linespoints", AbsFirstForceValuePlotLine)) return 1;
    341 
    342         // max force
    343         if (!CreatePlotOrder(Force, KeySet, argv[3], "MaxForces-Order", 2, "bottom right", "y", "",     1, 1, "bond order k", "absolute approximated max force [Ht/a.u.]", Orderxrange.str().c_str(), "", "1" , "with linespoints", ForceMagnitudePlotLine)) return 1;
    344 
    345         // min/mean/max comparison for total force
    346         if(!OpenOutputFile(output, argv[3],"MinMeanMaxTotalForce-Order.pyx")) return 1;
    347         CreatePlotHeader(output, "MinMeanMaxTotalForce-Order", 1, "bottom left", "y", NULL, 1, 1, "bond order k", "absolute total force [Ht/a.u.]");
    348         output << "plot "<< Orderxrange.str().c_str() << " [1e-8:1e+0] \\" << endl;
    349         output << "'MinForces-Order.dat' title 'minimum' using 1:(sqrt($" << 8 << "*$" << 8 << "+$" << 8+1 << "*$" << 8+1 << "+$" << 8+2 << "*$" << 8+2 << ")) with linespoints, \\" << endl;
    350         output << "'MeanForces-Order.dat' title 'mean' using 1:(abs($" << 8 << ")) with linespoints, \\" << endl;
    351         output << "'MaxForces-Order.dat' title 'maximum' using 1:(sqrt($" << 8 << "*$" << 8 << "+$" << 8+1 << "*$" << 8+1 << "+$" << 8+2 << "*$" << 8+2 << ")) with linespoints" << endl;
    352         output.close();
    353 
    354         // ++++++++++++++++++++++++++++++++++++++Plotting vector sum vs. Order
    355 
    356         if (!CreatePlotOrder(Force, KeySet, argv[3], "VectorSum-Order", 2, "bottom right", "y" ,"", 1, 1, "bond order k", "vector sum of approximated forces [Ht/a.u.]", Orderxrange.str().c_str(), "", "1" , "with linespoints", ForceMagnitudePlotLine)) return 1;
    357 
    358         // +++++++++++++++++++++++++++++++Plotting energyfragments vs. order
    359         yrange.str("");
    360         yrange << "[" << EnergyFragments.FindMinValue() << ":" << EnergyFragments.FindMaxValue() << "]";
    361         if (!CreatePlotOrder(EnergyFragments, KeySet, argv[3], "Energies-Fragment", 5, "below", "y", "", 1, 5, "fragment number", "Energies of each fragment [Ht]", Fragmentxrange.str().c_str(), yrange.str().c_str(), "2" , "with points", AbsEnergyPlotLine)) return 1;
    362         if (!CreatePlotOrder(EnergyFragments, KeySet, argv[3], "Energies-FragmentOrder", 5, "below", "y", "", 1, 1, "bond order", "Energies of each fragment [Ht]", Orderxrange.str().c_str(), yrange.str().c_str(), "1" , "with points", AbsEnergyPlotLine)) return 1;
    363         if (!CreatePlotOrder(EnergyFragments, KeySet, argv[3], "MaxEnergies-FragmentOrder", 5, "below", "y", "", 1, 1, "bond order", "Maximum fragment energy [Ht]", Orderxrange.str().c_str(), yrange.str().c_str(), "1" , "with linespoints", AbsEnergyPlotLine)) return 1;
    364         if (!CreatePlotOrder(EnergyFragments, KeySet, argv[3], "MinEnergies-FragmentOrder", 5, "below", "y", "", 1, 1, "bond order", "Minimum fragment energy [Ht]", Orderxrange.str().c_str(), yrange.str().c_str(), "1" , "with linespoints", AbsEnergyPlotLine)) return 1;
    365 
    366         // +++++++++++++++++++++++++++++++=Ploting min/mean/max forces for each fragment
    367         yrange.str("");
    368         yrange << "[" << ForceFragments.FindMinValue() << ":" << ForceFragments.FindMaxValue()<< "]";
    369         // min
    370         if (!CreatePlotOrder(ForceFragments, KeySet, argv[3], "MinForces-Fragment", 5, "below", "y", "set boxwidth 0.2", 1, 5, "fragment number", "minimum of approximated forces [Ht/a.u.]", Fragmentxrange.str().c_str(), yrange.str().c_str(), "2" , "with boxes fillcolor", BoxesForcePlotLine)) return 1;
    371 
    372         // mean
    373         if (!CreatePlotOrder(ForceFragments, KeySet, argv[3], "MeanForces-Fragment", 5, "below", "y", "set boxwidth 0.2", 1, 5, "fragment number", "mean of approximated forces [Ht/a.u.]", Fragmentxrange.str().c_str(), yrange.str().c_str(), "2" , "with boxes fillcolor", BoxesFirstForceValuePlotLine)) return 1;
    374 
    375         // max
    376         if (!CreatePlotOrder(ForceFragments, KeySet, argv[3], "MaxForces-Fragment", 5, "below", "y", "set boxwidth 0.2", 1, 5, "fragment number", "maximum of approximated forces [Ht/a.u.]", Fragmentxrange.str().c_str(), yrange.str().c_str(), "2" , "with boxes fillcolor", BoxesForcePlotLine)) return 1;
    377 
    378         // +++++++++++++++++++++++++++++++=Ploting min/mean/max forces for each fragment per bond order
    379         // min
    380         if (!CreatePlotOrder(ForceFragments, KeySet, argv[3], "MinForces-FragmentOrder", 5, "below", "y", "set boxwidth 0.2", 1, 1, "bond order", "minimum of approximated forces [Ht/a.u.]", Orderxrange.str().c_str(), yrange.str().c_str(), "1" , "with boxes fillcolor", BoxesForcePlotLine)) return 1;
    381 
    382         // mean
    383         if (!CreatePlotOrder(ForceFragments, KeySet, argv[3], "MeanForces-FragmentOrder", 5, "below", "y", "set boxwidth 0.2", 1, 1, "bond order", "mean of approximated forces [Ht/a.u.]", Orderxrange.str().c_str(), yrange.str().c_str(), "1" , "with boxes fillcolor", BoxesFirstForceValuePlotLine)) return 1;
    384 
    385         // max
    386         if (!CreatePlotOrder(ForceFragments, KeySet, argv[3], "MaxForces-FragmentOrder", 5, "below", "y", "set boxwidth 0.2", 1, 1, "bond order", "maximum of approximated forces [Ht/a.u.]", Orderxrange.str().c_str(), yrange.str().c_str(), "1" , "with boxes fillcolor", BoxesForcePlotLine)) return 1;
    387 
    388         // +++++++++++++++++++++++++++++++=Ploting approximated and true shielding for each atom
    389         if (periode != NULL) { // also look for PAS values
    390                 if(!OpenOutputFile(output, argv[3], "ShieldingsPAS-Order.pyx")) return 1;
    391                 if(!OpenOutputFile(output2, argv[3], "DeltaShieldingsPAS-Order.pyx")) return 1;
    392                 CreatePlotHeader(output, "ShieldingsPAS-Order", 1, "top right", NULL, NULL,     1, 5, "nuclei index", "iso chemical shielding value [ppm]");
    393                 CreatePlotHeader(output2, "DeltaShieldingsPAS-Order", 1, "top right", NULL, NULL,       1, 5, "nuclei index", "iso chemical shielding value [ppm]");
    394                 double step=0.8/KeySet.Order;
    395                 output << "set boxwidth " << step << endl;
    396                 output << "plot [0:" << ShieldingPAS.RowCounter[ShieldingPAS.MatrixCounter]+10 << "]\\" << endl;
    397                 output2 << "plot [0:" << ShieldingPAS.RowCounter[ShieldingPAS.MatrixCounter]+10 << "]\\" << endl;
    398                 for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
    399                         output << "'ShieldingsPAS-Order.dat' index " << BondOrder << " title 'Order " << BondOrder+1 << "' using ($1+" << step*(double)BondOrder << "):7 with boxes, \\" << endl;
    400                         output2 << "'DeltaShieldingsPAS-Order.dat' index " << BondOrder << " title 'Order " << BondOrder+1 << "' using ($1):7 with linespoints";
    401                         if (BondOrder-1 != KeySet.Order)
    402                                 output2 << ", \\" << endl;
    403                 }
    404                 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();
    407         }
    408 
    409         // create Makefile
    410         if(!OpenOutputFile(output, argv[3], "Makefile")) return 1;
    411         output << "PYX = $(shell ls *.pyx)" << endl << endl;
    412         output << "EPS = $(PYX:.pyx=.eps)" << endl << endl;
    413         output << "%.eps: %.pyx" << endl;
    414         output << "\t~/build/pyxplot/pyxplot $<" << endl << endl;
    415         output << "all: $(EPS)" << endl << endl;
    416         output << ".PHONY: clean" << endl;
    417         output << "clean:" << endl;
    418         output << "\trm -rf $(EPS)" << endl;
    419         output.close();
    420 
    421         // ++++++++++++++++ exit ++++++++++++++++++++++++++++++++++
    422         delete(periode);
    423         Free((void **)&dir, "main: *dir");
    424         cout << "done." << endl;
    425         return 0;
     25  periodentafel *periode = NULL; // and a period table of all elements
     26  EnergyMatrix Energy;
     27  EnergyMatrix Hcorrection;
     28  ForceMatrix Force;
     29  ForceMatrix Shielding;
     30  ForceMatrix ShieldingPAS;
     31  EnergyMatrix Time;
     32  EnergyMatrix EnergyFragments;
     33  EnergyMatrix HcorrectionFragments;
     34  ForceMatrix ForceFragments;
     35  ForceMatrix ShieldingFragments;
     36  ForceMatrix ShieldingPASFragments;
     37  KeySetsContainer KeySet;
     38  ofstream output;
     39  ofstream output2;
     40  ofstream output3;
     41  ofstream output4;
     42  ifstream input;
     43  stringstream filename;
     44  time_t t = time(NULL);
     45  struct tm *ts = localtime(&t);
     46  char *datum = asctime(ts);
     47  stringstream Orderxrange;
     48  stringstream Fragmentxrange;
     49  stringstream yrange;
     50  char *dir = NULL;
     51  bool Hcorrected = true;
     52  int counter;
     53
     54  cout << "ANOVA Analyzer" << endl;
     55  cout << "==============" << endl;
     56
     57  // Get the command line options
     58  if (argc < 4) {
     59    cout << "Usage: " << argv[0] << " <inputdir> <prefix> <outputdir> [elementsdb]" << endl;
     60    cout << "<inputdir>\ttherein the output of a molecuilder fragmentation is expected, each fragment with a subdir containing an energy.all and a forces.all file." << endl;
     61    cout << "<prefix>\tprefix of energy and forces file." << endl;
     62    cout << "<outputdir>\tcreated plotfiles and datafiles are placed into this directory " << endl;
     63    cout << "[elementsdb]\tpath to elements database, needed for shieldings." << endl;
     64    return 1;
     65  } else {
     66    dir = (char *) Malloc(sizeof(char)*(strlen(argv[2])+2), "main: *dir");
     67    strcpy(dir, "/");
     68    strcat(dir, argv[2]);
     69  }
     70
     71  if (argc > 4) {
     72    cout << "Loading periodentafel." << endl;
     73    periode = new periodentafel;
     74    periode->LoadPeriodentafel(argv[4]);
     75  }
     76
     77  // Test the given directory
     78  if (!TestParams(argc, argv))
     79    return 1;
     80
     81  // +++++++++++++++++ PARSING +++++++++++++++++++++++++++++++
     82
     83  // ------------- Parse through all Fragment subdirs --------
     84  if (!Energy.ParseFragmentMatrix(argv[1], dir, EnergySuffix,0,0)) return 1;
     85  Hcorrected = Hcorrection.ParseFragmentMatrix(argv[1], "", HCORRECTIONSUFFIX,0,0);
     86  if (!Force.ParseFragmentMatrix(argv[1], dir, ForcesSuffix,0,0)) return 1;
     87  if (!Time.ParseFragmentMatrix(argv[1], dir, TimeSuffix, 10,1)) return 1;
     88  if (periode != NULL) { // also look for PAS values
     89    if (!Shielding.ParseFragmentMatrix(argv[1], dir, ShieldingSuffix, 1, 0)) return 1;
     90    if (!ShieldingPAS.ParseFragmentMatrix(argv[1], dir, ShieldingPASSuffix, 1, 0)) return 1;
     91  }
     92
     93  // ---------- Parse the TE Factors into an array -----------------
     94  if (!Energy.ParseIndices()) return 1;
     95  if (Hcorrected) Hcorrection.ParseIndices();
     96
     97  // ---------- Parse the Force indices into an array ---------------
     98  if (!Force.ParseIndices(argv[1])) return 1;
     99  if (!ForceFragments.AllocateMatrix(Force.Header, Force.MatrixCounter, Force.RowCounter, Force.ColumnCounter)) return 1;
     100  if (!ForceFragments.ParseIndices(argv[1])) return 1;
     101
     102  // ---------- Parse the shielding indices into an array ---------------
     103  if (periode != NULL) { // also look for PAS values
     104    if(!Shielding.ParseIndices(argv[1])) return 1;
     105    if(!ShieldingPAS.ParseIndices(argv[1])) return 1;
     106    if (!ShieldingFragments.AllocateMatrix(Shielding.Header, Shielding.MatrixCounter, Shielding.RowCounter, Shielding.ColumnCounter)) return 1;
     107    if (!ShieldingPASFragments.AllocateMatrix(ShieldingPAS.Header, ShieldingPAS.MatrixCounter, ShieldingPAS.RowCounter, ShieldingPAS.ColumnCounter)) return 1;
     108    if(!ShieldingFragments.ParseIndices(argv[1])) return 1;
     109    if(!ShieldingPASFragments.ParseIndices(argv[1])) return 1;
     110  }
     111
     112  // ---------- Parse the KeySets into an array ---------------
     113  if (!KeySet.ParseKeySets(argv[1], Force.RowCounter, Force.MatrixCounter)) return 1;
     114  if (!KeySet.ParseManyBodyTerms()) return 1;
     115
     116  // ---------- Parse fragment files created by 'joiner' into an array -------------
     117  if (!EnergyFragments.ParseFragmentMatrix(argv[1], dir, EnergyFragmentSuffix,0,0)) return 1;
     118  if (Hcorrected) HcorrectionFragments.ParseFragmentMatrix(argv[1], dir, HcorrectionFragmentSuffix,0,0);
     119  if (!ForceFragments.ParseFragmentMatrix(argv[1], dir, ForceFragmentSuffix,0,0)) return 1;
     120  if (periode != NULL) { // also look for PAS values
     121    if (!ShieldingFragments.ParseFragmentMatrix(argv[1], dir, ShieldingFragmentSuffix, 1, 0)) return 1;
     122    if (!ShieldingPASFragments.ParseFragmentMatrix(argv[1], dir, ShieldingPASFragmentSuffix, 1, 0)) return 1;
     123  }
     124
     125  // +++++++++++++++ TESTING ++++++++++++++++++++++++++++++
     126
     127  // print energy and forces to file
     128  filename.str("");
     129  filename << argv[3] << "/" << "energy-forces.all";
     130  output.open(filename.str().c_str(), ios::out);
     131  output << endl << "Total Energy" << endl << "==============" << endl << Energy.Header << endl;
     132  for(int j=0;j<Energy.RowCounter[Energy.MatrixCounter];j++) {
     133    for(int k=0;k<Energy.ColumnCounter;k++)
     134      output << scientific << Energy.Matrix[ Energy.MatrixCounter ][j][k] << "\t";
     135    output << endl;
     136  }
     137  output << endl;
     138
     139  output << endl << "Total Forces" << endl << "===============" << endl << Force.Header << endl;
     140  for(int j=0;j<Force.RowCounter[Force.MatrixCounter];j++) {
     141    for(int k=0;k<Force.ColumnCounter;k++)
     142      output << scientific << Force.Matrix[ Force.MatrixCounter ][j][k] << "\t";
     143    output << endl;
     144  }
     145  output << endl;
     146
     147  if (periode != NULL) { // also look for PAS values
     148    output << endl << "Total Shieldings" << endl << "===============" << endl << Shielding.Header << endl;
     149    for(int j=0;j<Shielding.RowCounter[Shielding.MatrixCounter];j++) {
     150      for(int k=0;k<Shielding.ColumnCounter;k++)
     151        output << scientific << Shielding.Matrix[ Shielding.MatrixCounter ][j][k] << "\t";
     152      output << endl;
     153    }
     154    output << endl;
     155
     156    output << endl << "Total Shieldings PAS" << endl << "===============" << endl << ShieldingPAS.Header << endl;
     157    for(int j=0;j<ShieldingPAS.RowCounter[ShieldingPAS.MatrixCounter];j++) {
     158      for(int k=0;k<ShieldingPAS.ColumnCounter;k++)
     159        output << scientific << ShieldingPAS.Matrix[ ShieldingPAS.MatrixCounter ][j][k] << "\t";
     160      output << endl;
     161    }
     162    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;
     173  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];
     176
     177  // +++++++++++++++ ANALYZING ++++++++++++++++++++++++++++++
     178
     179  cout << "Analyzing ..." << endl;
     180
     181  // ======================================= Creating the data files ==============================================================
     182
     183  // +++++++++++++++++++++++++++++++++++++++ Plotting Simtime vs Bond Order
     184  // +++++++++++++++++++++++++++++++++++++++ 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();
     215
     216  // +++++++++++++++++++++++++++++++++++++++ Plotting shieldings
     217
     218  if (periode != NULL) { // also look for PAS values
     219    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;
     220    if (!CreateDataForcesOrderPerAtom(ShieldingPASFragments, KeySet, argv[3], "ShieldingsPAS-Order", "Plot of approximated shieldings versus the Bond Order", datum)) return 1;
     221    if (!AppendOutputFile(output, argv[3], "ShieldingsPAS-Order.dat" )) return false;
     222    output << endl << "# Full" << endl;
     223    for(int j=0;j<ShieldingPAS.RowCounter[ShieldingPAS.MatrixCounter];j++) {
     224      output << j << "\t";
     225      for(int k=0;k<ShieldingPAS.ColumnCounter;k++)
     226        output << scientific <<  ShieldingPAS.Matrix[ ShieldingPAS.MatrixCounter ][j][k] << "\t"; //*(((k>1) && (k<6))? 1.e6 : 1.) << "\t";
     227      output << endl;
     228    }
     229  }
     230  output.close();
     231
     232
     233  // +++++++++++++++++++++++++++++++++++++++ Plotting deviation in energy to full QM
     234  if (!CreateDataDeltaEnergyOrder(Energy, EnergyFragments, KeySet, argv[3], "DeltaEnergies-Order", "Plot of error between approximated and full energies energies versus the Bond Order", datum)) return 1;
     235
     236  // +++++++++++++++++++++++++++++++++++Plotting Energies vs. Order
     237  if (!CreateDataEnergyOrder(EnergyFragments, KeySet, argv[3], "Energies-Order", "Plot of approximated energies versus the Bond Order", datum)) return 1;
     238
     239  // +++++++++++++++++++++++++++++++++++++++ Plotting deviation in forces to full QM
     240  if (!CreateDataDeltaForcesOrderPerAtom(Force, ForceFragments, KeySet, argv[3], "DeltaForces-Order", "Plot of error between approximated forces and full forces versus the Bond Order", datum)) return 1;
     241
     242  // min force
     243  if (!CreateDataDeltaForcesOrder(Force, ForceFragments, KeySet, argv[3], "DeltaMinForces-Order", "Plot of min error between approximated forces and full forces versus the Bond Order", datum, CreateMinimumForce)) return 1;
     244
     245  // mean force
     246  if (!CreateDataDeltaForcesOrder(Force, ForceFragments, KeySet, argv[3], "DeltaMeanForces-Order", "Plot of mean error between approximated forces and full forces versus the Bond Order", datum, CreateMeanForce)) return 1;
     247
     248  // max force
     249  if (!CreateDataDeltaForcesOrder(Force, ForceFragments, KeySet, argv[3], "DeltaMaxForces-Order", "Plot of max error between approximated forces and full forces versus the Bond Order", datum, CreateMaximumForce)) return 1;
     250
     251  // ++++++++++++++++++++++++++++++++++++++Plotting Forces vs. Order
     252  if (!CreateDataForcesOrderPerAtom(ForceFragments, KeySet, argv[3], "Forces-Order", "Plot of approximated forces versus the Bond Order", datum)) return 1;
     253  if (!AppendOutputFile(output, argv[3], "Forces-Order.dat" )) return false;
     254  output << endl << "# Full" << endl;
     255  for(int j=0;j<Force.RowCounter[Force.MatrixCounter];j++) {
     256    output << j << "\t";
     257    for(int k=0;k<Force.ColumnCounter;k++)
     258      output << scientific <<  Force.Matrix[ Force.MatrixCounter ][j][k] << "\t";
     259    output << endl;
     260  }
     261  output.close();
     262  // min force
     263  if (!CreateDataForcesOrder(ForceFragments, KeySet, argv[3], "MinForces-Order", "Plot of min approximated forces versus the Bond Order", datum, CreateMinimumForce)) return 1;
     264
     265  // mean force
     266  if (!CreateDataForcesOrder(ForceFragments, KeySet, argv[3], "MeanForces-Order", "Plot of mean approximated forces versus the Bond Order", datum, CreateMeanForce)) return 1;
     267
     268  // max force
     269  if (!CreateDataForcesOrder(ForceFragments, KeySet, argv[3], "MaxForces-Order", "Plot of max approximated forces versus the Bond Order", datum, CreateMaximumForce)) return 1;
     270
     271  // ++++++++++++++++++++++++++++++++++++++Plotting vector sum (should be 0) vs. bond order
     272  if (!CreateDataForcesOrder(ForceFragments, KeySet, argv[3], "VectorSum-Order", "Plot of vector sum of the approximated forces versus the Bond Order", datum, CreateVectorSumForce)) return 1;
     273
     274  // +++++++++++++++++++++++++++++++Plotting energyfragments vs. order
     275  if (!CreateDataFragment(EnergyFragments, KeySet, argv[3], "Energies-Fragment", "Plot of fragment energy versus the Fragment No", datum, CreateEnergy)) return 1;
     276  if (!CreateDataFragment(EnergyFragments, KeySet, argv[3], "Energies-FragmentOrder", "Plot of fragment energy of each Fragment No vs. Bond Order", datum, CreateEnergy)) return 1;
     277  if (!CreateDataFragmentOrder(EnergyFragments, KeySet, argv[3], "MaxEnergies-FragmentOrder", "Plot of maximum of fragment energy vs. Bond Order", datum, CreateMaxFragmentOrder)) return 1;
     278  if (!CreateDataFragmentOrder(EnergyFragments, KeySet, argv[3], "MinEnergies-FragmentOrder", "Plot of minimum of fragment energy vs. Bond Order", datum, CreateMinFragmentOrder)) return 1;
     279
     280  // +++++++++++++++++++++++++++++++Ploting min/mean/max forces for each fragment
     281  // min force
     282  if (!CreateDataFragment(ForceFragments, KeySet, argv[3], "MinForces-Fragment", "Plot of min approximated forces versus the Fragment No", datum, CreateMinimumForce)) return 1;
     283
     284  // mean force
     285  if (!CreateDataFragment(ForceFragments, KeySet, argv[3], "MeanForces-Fragment", "Plot of mean approximated forces versus the Fragment No", datum, CreateMeanForce)) return 1;
     286
     287  // max force
     288  if (!CreateDataFragment(ForceFragments, KeySet, argv[3], "MaxForces-Fragment", "Plot of max approximated forces versus the Fragment No", datum, CreateMaximumForce)) return 1;
     289
     290  // +++++++++++++++++++++++++++++++Ploting min/mean/max forces for each fragment per order
     291  // min force
     292  if (!CreateDataFragment(ForceFragments, KeySet, argv[3], "MinForces-FragmentOrder", "Plot of min approximated forces of each Fragment No vs. Bond Order", datum, CreateMinimumForce)) return 1;
     293
     294  // mean force
     295  if (!CreateDataFragment(ForceFragments, KeySet, argv[3], "MeanForces-FragmentOrder", "Plot of mean approximated forces of each Fragment No vs. Bond Order", datum, CreateMeanForce)) return 1;
     296
     297  // max force
     298  if (!CreateDataFragment(ForceFragments, KeySet, argv[3], "MaxForces-FragmentOrder", "Plot of max approximated forces of each Fragment No vs. Bond Order", datum, CreateMaximumForce)) return 1;
     299
     300  // ======================================= Creating the plot files ==============================================================
     301
     302  Orderxrange << "[1:" << KeySet.Order << "]";
     303  Fragmentxrange << "[0:" << KeySet.FragmentCounter+1 << "]";
     304  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
     309  // +++++++++++++++++++++++++++++++++++++++ Plotting deviation in energy to full QM
     310  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;
     311
     312  // +++++++++++++++++++++++++++++++++++Plotting Energies vs. Order
     313  if (!CreatePlotOrder(Energy, KeySet, argv[3], "Energies-Order", 1, "outside", "", "",  1, 1, "bond order k", "approximate energy [Ht]", Orderxrange.str().c_str(), "", "1" , "with linespoints", EnergyPlotLine)) return 1;
     314
     315  // +++++++++++++++++++++++++++++++++++++++ Plotting deviation in forces to full QM
     316  yrange.str("[1e-8:1e+0]");
     317  // min force
     318  if (!CreatePlotOrder(Force, KeySet, argv[3], "DeltaMinForces-Order", 2, "top right", "y", "",  1, 1, "bond order k", "absolute error in min force [Ht/a.u.]", Orderxrange.str().c_str(), yrange.str().c_str(), "1" , "with linespoints", ForceMagnitudePlotLine)) return 1;
     319
     320  // mean force
     321  if (!CreatePlotOrder(Force, KeySet, argv[3], "DeltaMeanForces-Order", 2, "top right", "y", "",  1, 1, "bond order k", "absolute error in mean force [Ht/a.u.]", Orderxrange.str().c_str(), yrange.str().c_str(), "1" , "with linespoints", AbsFirstForceValuePlotLine)) return 1;
     322
     323  // max force
     324  if (!CreatePlotOrder(Force, KeySet, argv[3], "DeltaMaxForces-Order", 2, "top right", "y", "",  1, 1, "bond order k", "absolute error in max force [Ht/a.u.]", Orderxrange.str().c_str(), yrange.str().c_str(), "1" , "with linespoints", ForceMagnitudePlotLine)) return 1;
     325
     326  // min/mean/max comparison for total force
     327  if(!OpenOutputFile(output, argv[3], "DeltaMinMeanMaxTotalForce-Order.pyx")) return 1;
     328  CreatePlotHeader(output, "DeltaMinMeanMaxTotalForce-Order", 1, "bottom left", "y", NULL,  1, 1, "bond order k", "absolute error in total forces [Ht/a.u.]");
     329  output << "plot " << Orderxrange.str().c_str() << " [1e-8:1e+0] \\" << endl;
     330  output << "'DeltaMinForces-Order.dat' title 'minimum' using 1:(sqrt($" << 8 << "*$" << 8 << "+$" << 8+1 << "*$" << 8+1 << "+$" << 8+2 << "*$" << 8+2 << ")) with linespoints, \\" << endl;
     331  output << "'DeltaMeanForces-Order.dat' title 'mean' using 1:(abs($" << 8 << ")) with linespoints, \\" << endl;
     332  output << "'DeltaMaxForces-Order.dat' title 'maximum' using 1:(sqrt($" << 8 << "*$" << 8 << "+$" << 8+1 << "*$" << 8+1 << "+$" << 8+2 << "*$" << 8+2 << ")) with linespoints" << endl;
     333  output.close();
     334
     335  // ++++++++++++++++++++++++++++++++++++++Plotting Forces vs. Order
     336  // min force
     337  if (!CreatePlotOrder(Force, KeySet, argv[3], "MinForces-Order", 2, "bottom right", "y", "",  1, 1, "bond order k", "absolute approximated min force [Ht/a.u.]", Orderxrange.str().c_str(), "", "1" , "with linespoints", ForceMagnitudePlotLine)) return 1;
     338
     339  // mean force
     340  if (!CreatePlotOrder(Force, KeySet, argv[3], "MeanForces-Order", 2, "bottom right", "y", "",  1, 1, "bond order k", "absolute approximated mean force [Ht/a.u.]", Orderxrange.str().c_str(), "", "1" , "with linespoints", AbsFirstForceValuePlotLine)) return 1;
     341
     342  // max force
     343  if (!CreatePlotOrder(Force, KeySet, argv[3], "MaxForces-Order", 2, "bottom right", "y", "",  1, 1, "bond order k", "absolute approximated max force [Ht/a.u.]", Orderxrange.str().c_str(), "", "1" , "with linespoints", ForceMagnitudePlotLine)) return 1;
     344
     345  // min/mean/max comparison for total force
     346  if(!OpenOutputFile(output, argv[3],"MinMeanMaxTotalForce-Order.pyx")) return 1;
     347  CreatePlotHeader(output, "MinMeanMaxTotalForce-Order", 1, "bottom left", "y", NULL, 1, 1, "bond order k", "absolute total force [Ht/a.u.]");
     348  output << "plot "<< Orderxrange.str().c_str() << " [1e-8:1e+0] \\" << endl;
     349  output << "'MinForces-Order.dat' title 'minimum' using 1:(sqrt($" << 8 << "*$" << 8 << "+$" << 8+1 << "*$" << 8+1 << "+$" << 8+2 << "*$" << 8+2 << ")) with linespoints, \\" << endl;
     350  output << "'MeanForces-Order.dat' title 'mean' using 1:(abs($" << 8 << ")) with linespoints, \\" << endl;
     351  output << "'MaxForces-Order.dat' title 'maximum' using 1:(sqrt($" << 8 << "*$" << 8 << "+$" << 8+1 << "*$" << 8+1 << "+$" << 8+2 << "*$" << 8+2 << ")) with linespoints" << endl;
     352  output.close();
     353
     354  // ++++++++++++++++++++++++++++++++++++++Plotting vector sum vs. Order
     355
     356  if (!CreatePlotOrder(Force, KeySet, argv[3], "VectorSum-Order", 2, "bottom right", "y" ,"", 1, 1, "bond order k", "vector sum of approximated forces [Ht/a.u.]", Orderxrange.str().c_str(), "", "1" , "with linespoints", ForceMagnitudePlotLine)) return 1;
     357
     358  // +++++++++++++++++++++++++++++++Plotting energyfragments vs. order
     359  yrange.str("");
     360  yrange << "[" << EnergyFragments.FindMinValue() << ":" << EnergyFragments.FindMaxValue() << "]";
     361  if (!CreatePlotOrder(EnergyFragments, KeySet, argv[3], "Energies-Fragment", 5, "below", "y", "", 1, 5, "fragment number", "Energies of each fragment [Ht]", Fragmentxrange.str().c_str(), yrange.str().c_str(), "2" , "with points", AbsEnergyPlotLine)) return 1;
     362  if (!CreatePlotOrder(EnergyFragments, KeySet, argv[3], "Energies-FragmentOrder", 5, "below", "y", "", 1, 1, "bond order", "Energies of each fragment [Ht]", Orderxrange.str().c_str(), yrange.str().c_str(), "1" , "with points", AbsEnergyPlotLine)) return 1;
     363  if (!CreatePlotOrder(EnergyFragments, KeySet, argv[3], "MaxEnergies-FragmentOrder", 5, "below", "y", "", 1, 1, "bond order", "Maximum fragment energy [Ht]", Orderxrange.str().c_str(), yrange.str().c_str(), "1" , "with linespoints", AbsEnergyPlotLine)) return 1;
     364  if (!CreatePlotOrder(EnergyFragments, KeySet, argv[3], "MinEnergies-FragmentOrder", 5, "below", "y", "", 1, 1, "bond order", "Minimum fragment energy [Ht]", Orderxrange.str().c_str(), yrange.str().c_str(), "1" , "with linespoints", AbsEnergyPlotLine)) return 1;
     365
     366  // +++++++++++++++++++++++++++++++=Ploting min/mean/max forces for each fragment
     367  yrange.str("");
     368  yrange << "[" << ForceFragments.FindMinValue() << ":" << ForceFragments.FindMaxValue()<< "]";
     369  // min
     370  if (!CreatePlotOrder(ForceFragments, KeySet, argv[3], "MinForces-Fragment", 5, "below", "y", "set boxwidth 0.2", 1, 5, "fragment number", "minimum of approximated forces [Ht/a.u.]", Fragmentxrange.str().c_str(), yrange.str().c_str(), "2" , "with boxes fillcolor", BoxesForcePlotLine)) return 1;
     371
     372  // mean
     373  if (!CreatePlotOrder(ForceFragments, KeySet, argv[3], "MeanForces-Fragment", 5, "below", "y", "set boxwidth 0.2", 1, 5, "fragment number", "mean of approximated forces [Ht/a.u.]", Fragmentxrange.str().c_str(), yrange.str().c_str(), "2" , "with boxes fillcolor", BoxesFirstForceValuePlotLine)) return 1;
     374
     375  // max
     376  if (!CreatePlotOrder(ForceFragments, KeySet, argv[3], "MaxForces-Fragment", 5, "below", "y", "set boxwidth 0.2", 1, 5, "fragment number", "maximum of approximated forces [Ht/a.u.]", Fragmentxrange.str().c_str(), yrange.str().c_str(), "2" , "with boxes fillcolor", BoxesForcePlotLine)) return 1;
     377
     378  // +++++++++++++++++++++++++++++++=Ploting min/mean/max forces for each fragment per bond order
     379  // min
     380  if (!CreatePlotOrder(ForceFragments, KeySet, argv[3], "MinForces-FragmentOrder", 5, "below", "y", "set boxwidth 0.2", 1, 1, "bond order", "minimum of approximated forces [Ht/a.u.]", Orderxrange.str().c_str(), yrange.str().c_str(), "1" , "with boxes fillcolor", BoxesForcePlotLine)) return 1;
     381
     382  // mean
     383  if (!CreatePlotOrder(ForceFragments, KeySet, argv[3], "MeanForces-FragmentOrder", 5, "below", "y", "set boxwidth 0.2", 1, 1, "bond order", "mean of approximated forces [Ht/a.u.]", Orderxrange.str().c_str(), yrange.str().c_str(), "1" , "with boxes fillcolor", BoxesFirstForceValuePlotLine)) return 1;
     384
     385  // max
     386  if (!CreatePlotOrder(ForceFragments, KeySet, argv[3], "MaxForces-FragmentOrder", 5, "below", "y", "set boxwidth 0.2", 1, 1, "bond order", "maximum of approximated forces [Ht/a.u.]", Orderxrange.str().c_str(), yrange.str().c_str(), "1" , "with boxes fillcolor", BoxesForcePlotLine)) return 1;
     387
     388  // +++++++++++++++++++++++++++++++=Ploting approximated and true shielding for each atom
     389  if (periode != NULL) { // also look for PAS values
     390    if(!OpenOutputFile(output, argv[3], "ShieldingsPAS-Order.pyx")) return 1;
     391    if(!OpenOutputFile(output2, argv[3], "DeltaShieldingsPAS-Order.pyx")) return 1;
     392    CreatePlotHeader(output, "ShieldingsPAS-Order", 1, "top right", NULL, NULL,  1, 5, "nuclei index", "iso chemical shielding value [ppm]");
     393    CreatePlotHeader(output2, "DeltaShieldingsPAS-Order", 1, "top right", NULL, NULL,  1, 5, "nuclei index", "iso chemical shielding value [ppm]");
     394    double step=0.8/KeySet.Order;
     395    output << "set boxwidth " << step << endl;
     396    output << "plot [0:" << ShieldingPAS.RowCounter[ShieldingPAS.MatrixCounter]+10 << "]\\" << endl;
     397    output2 << "plot [0:" << ShieldingPAS.RowCounter[ShieldingPAS.MatrixCounter]+10 << "]\\" << endl;
     398    for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
     399      output << "'ShieldingsPAS-Order.dat' index " << BondOrder << " title 'Order " << BondOrder+1 << "' using ($1+" << step*(double)BondOrder << "):7 with boxes, \\" << endl;
     400      output2 << "'DeltaShieldingsPAS-Order.dat' index " << BondOrder << " title 'Order " << BondOrder+1 << "' using ($1):7 with linespoints";
     401      if (BondOrder-1 != KeySet.Order)
     402        output2 << ", \\" << endl;
     403    }
     404    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();
     407  }
     408
     409  // create Makefile
     410  if(!OpenOutputFile(output, argv[3], "Makefile")) return 1;
     411  output << "PYX = $(shell ls *.pyx)" << endl << endl;
     412  output << "EPS = $(PYX:.pyx=.eps)" << endl << endl;
     413  output << "%.eps: %.pyx" << endl;
     414  output << "\t~/build/pyxplot/pyxplot $<" << endl << endl;
     415  output << "all: $(EPS)" << endl << endl;
     416  output << ".PHONY: clean" << endl;
     417  output << "clean:" << endl;
     418  output << "\trm -rf $(EPS)" << endl;
     419  output.close();
     420
     421  // ++++++++++++++++ exit ++++++++++++++++++++++++++++++++++
     422  delete(periode);
     423  Free((void **)&dir, "main: *dir");
     424  cout << "done." << endl;
     425  return 0;
    426426};
    427427
  • src/atom.cpp

    r205ccd r042f82  
    1313atom::atom()
    1414{
    15         Name = NULL;
    16         previous = NULL;
    17         next = NULL;
    18         father = this;  // generally, father is itself
    19         Ancestor = NULL;
    20         type = NULL;
    21         sort = NULL;
    22         FixedIon = 0;
    23         nr = -1;
    24         GraphNr = -1;
    25         ComponentNr = NULL;
    26         IsCyclic = false;
    27         SeparationVertex = false;
    28         LowpointNr = -1;
    29         AdaptiveOrder = 0;
    30         MaxOrder = false;
     15  Name = NULL;
     16  previous = NULL;
     17  next = NULL;
     18  father = this;  // generally, father is itself
     19  Ancestor = NULL;
     20  type = NULL;
     21  sort = NULL;
     22  FixedIon = 0;
     23  nr = -1;
     24  GraphNr = -1;
     25  ComponentNr = NULL;
     26  IsCyclic = false;
     27  SeparationVertex = false;
     28  LowpointNr = -1;
     29  AdaptiveOrder = 0;
     30  MaxOrder = false;
    3131};
    3232
     
    3535atom::~atom()
    3636{
    37         Free((void **)&Name, "atom::~atom: *Name");
    38         Free((void **)&ComponentNr, "atom::~atom: *ComponentNr");
     37  Free((void **)&Name, "atom::~atom: *Name");
     38  Free((void **)&ComponentNr, "atom::~atom: *ComponentNr");
    3939};
    4040
     
    4545atom *atom::GetTrueFather()
    4646{
    47         atom *walker = this;
    48         do {
    49                 if (walker == walker->father) // top most father is the one that points on itself
    50                         break;
    51                 walker = walker->father;
    52         } while (walker != NULL);
    53         return walker;
     47  atom *walker = this;
     48  do {
     49    if (walker == walker->father) // top most father is the one that points on itself
     50      break;
     51    walker = walker->father;
     52  } while (walker != NULL);
     53  return walker;
    5454};
    5555
     
    6262bool atom::Output(int ElementNo, int AtomNo, ofstream *out, const char *comment) const
    6363{
    64         if (out != NULL) {
    65                 *out << "Ion_Type" << ElementNo << "_" << AtomNo << "\t"        << fixed << setprecision(9) << showpoint;
    66                 *out << x.x[0] << "\t" << x.x[1] << "\t" << x.x[2];
    67                 *out << "\t" << FixedIon;
    68                 if (v.Norm() > MYEPSILON)
    69                         *out << "\t" << scientific << setprecision(6) << v.x[0] << "\t" << v.x[1] << "\t" << v.x[2] << "\t";
    70                 if (comment != NULL)
    71                   *out << " # " << comment << endl;
    72                 else
    73                   *out << " # molecule nr " << nr << endl;
    74                 return true;
    75         } else
    76                 return false;
     64  if (out != NULL) {
     65    *out << "Ion_Type" << ElementNo << "_" << AtomNo << "\t"  << fixed << setprecision(9) << showpoint;
     66    *out << x.x[0] << "\t" << x.x[1] << "\t" << x.x[2];
     67    *out << "\t" << FixedIon;
     68    if (v.Norm() > MYEPSILON)
     69      *out << "\t" << scientific << setprecision(6) << v.x[0] << "\t" << v.x[1] << "\t" << v.x[2] << "\t";
     70    if (comment != NULL)
     71      *out << " # " << comment << endl;
     72    else
     73      *out << " # molecule nr " << nr << endl;
     74    return true;
     75  } else
     76    return false;
    7777};
    7878
     
    8282bool atom::OutputXYZLine(ofstream *out) const
    8383{
    84         if (out != NULL) {
    85                 *out << type->symbol << "\t" << x.x[0] << "\t" << x.x[1] << "\t" << x.x[2] << "\t" << endl;
    86                 return true;
    87         } else
    88                 return false;
     84  if (out != NULL) {
     85    *out << type->symbol << "\t" << x.x[0] << "\t" << x.x[1] << "\t" << x.x[2] << "\t" << endl;
     86    return true;
     87  } else
     88    return false;
    8989};
    9090
    9191ostream & operator << (ostream &ost, atom &a)
    9292{
    93         ost << "[" << a.Name << "|" << &a << "]";
    94         return ost;
     93  ost << "[" << a.Name << "|" << &a << "]";
     94  return ost;
    9595};
    9696
     
    101101bool atom::Compare(atom &ptr)
    102102{
    103         if (nr < ptr.nr)
    104                 return true;
    105         else
    106                 return false;
     103  if (nr < ptr.nr)
     104    return true;
     105  else
     106    return false;
    107107};
    108108
    109109bool operator < (atom &a, atom &b)
    110110{
    111         return a.Compare(b);
     111  return a.Compare(b);
    112112};
    113113
  • src/bond.cpp

    r205ccd r042f82  
    1414bond::bond()
    1515{
    16         leftatom = NULL;
    17         rightatom = NULL;
    18         previous = NULL;
    19         next = NULL;
    20         nr = -1;
    21         HydrogenBond = 0;
    22         BondDegree = 0;
    23         Used = white;
    24         Cyclic = false;
    25         Type = Undetermined;
     16  leftatom = NULL;
     17  rightatom = NULL;
     18  previous = NULL;
     19  next = NULL;
     20  nr = -1;
     21  HydrogenBond = 0;
     22  BondDegree = 0;
     23  Used = white;
     24  Cyclic = false;
     25  Type = Undetermined;
    2626};
    2727
     
    3434bond::bond(atom *left, atom *right, int degree=1, int number=0)
    3535{
    36         leftatom = left;
    37         rightatom = right;
    38         previous = NULL;
    39         next = NULL;
    40         HydrogenBond = 0;
    41         if ((left != NULL) && (right != NULL)) {
    42                 if ((left->type != NULL) && (left->type->Z == 1))
    43                         HydrogenBond++;
    44                 if ((right->type != NULL) && (right->type->Z == 1))
    45                         HydrogenBond++;
    46         }
    47         BondDegree = degree;
    48         nr = number;
    49         Used = white;
    50         Cyclic = false;
     36  leftatom = left;
     37  rightatom = right;
     38  previous = NULL;
     39  next = NULL;
     40  HydrogenBond = 0;
     41  if ((left != NULL) && (right != NULL)) {
     42    if ((left->type != NULL) && (left->type->Z == 1))
     43      HydrogenBond++;
     44    if ((right->type != NULL) && (right->type->Z == 1))
     45      HydrogenBond++;
     46  }
     47  BondDegree = degree;
     48  nr = number;
     49  Used = white;
     50  Cyclic = false;
    5151};
    5252bond::bond(atom *left, atom *right)
    5353{
    54         leftatom = left;
    55         rightatom = right;
    56         previous = NULL;
    57         next = NULL;
    58         HydrogenBond = 0;
    59         if ((left != NULL) && (right != NULL)) {
    60                 if ((left->type != NULL) && (left->type->Z == 1))
    61                         HydrogenBond++;
    62                 if ((right->type != NULL) && (right->type->Z == 1))
    63                         HydrogenBond++;
    64         }
    65         BondDegree = 1;
    66         nr = 0;
    67         Used = white;
    68         Cyclic = false;
     54  leftatom = left;
     55  rightatom = right;
     56  previous = NULL;
     57  next = NULL;
     58  HydrogenBond = 0;
     59  if ((left != NULL) && (right != NULL)) {
     60    if ((left->type != NULL) && (left->type->Z == 1))
     61      HydrogenBond++;
     62    if ((right->type != NULL) && (right->type->Z == 1))
     63      HydrogenBond++;
     64  }
     65  BondDegree = 1;
     66  nr = 0;
     67  Used = white;
     68  Cyclic = false;
    6969};
    7070
     
    7373bond::~bond()
    7474{
    75         // remove this node from the list structure
    76         if (previous != NULL) {
    77                 previous->next = next;
    78         }
    79         if (next != NULL) {
    80                 next->previous = previous;
    81         }
     75  // remove this node from the list structure
     76  if (previous != NULL) {
     77    previous->next = next;
     78  }
     79  if (next != NULL) {
     80    next->previous = previous;
     81  }
    8282};
    8383
    8484ostream & operator << (ostream &ost, bond &b)
    8585{
    86         ost << "[" << b.leftatom->Name << " <" << b.BondDegree << "(H" << b.HydrogenBond << ")>" << b.rightatom->Name << "]";
    87         return ost;
     86  ost << "[" << b.leftatom->Name << " <" << b.BondDegree << "(H" << b.HydrogenBond << ")>" << b.rightatom->Name << "]";
     87  return ost;
    8888};
    8989
     
    9494atom * bond::GetOtherAtom(atom *Atom) const
    9595{
    96         if(leftatom == Atom)
    97                 return rightatom;
    98         if(rightatom == Atom)
    99                 return leftatom;
    100         return NULL;
     96  if(leftatom == Atom)
     97    return rightatom;
     98  if(rightatom == Atom)
     99    return leftatom;
     100  return NULL;
    101101};
    102102
     
    107107bond * bond::GetFirstBond()
    108108{
    109         return GetFirst(this);
     109  return GetFirst(this);
    110110};
    111111
     
    116116bond * bond::GetLastBond()
    117117{
    118         return GetLast(this);
     118  return GetLast(this);
    119119};
    120120
     
    124124enum Shading bond::IsUsed()
    125125{
    126         return Used;
     126  return Used;
    127127};
    128128
     
    133133bool bond::Contains(const atom *ptr)
    134134{
    135         return ((leftatom == ptr) || (rightatom == ptr));
     135  return ((leftatom == ptr) || (rightatom == ptr));
    136136};
    137137
     
    142142bool bond::Contains(const int number)
    143143{
    144         return ((leftatom->nr == number) || (rightatom->nr == number));
     144  return ((leftatom->nr == number) || (rightatom->nr == number));
    145145};
    146146
     
    149149 */
    150150bool bond::MarkUsed(enum Shading color) {
    151         if (Used == black) {
    152                 cerr << "ERROR: Bond " << this << " was already marked black!." << endl;
    153                 return false;
    154         } else {
    155                 Used = color;
    156                 return true;
    157         }
     151  if (Used == black) {
     152    cerr << "ERROR: Bond " << this << " was already marked black!." << endl;
     153    return false;
     154  } else {
     155    Used = color;
     156    return true;
     157  }
    158158};
    159159
     
    162162 */
    163163void bond::ResetUsed() {
    164         Used = white;
     164  Used = white;
    165165};
  • src/boundary.cpp

    r205ccd r042f82  
    239239
    240240CandidateForTesselation::CandidateForTesselation(
    241         atom *candidate, BoundaryLineSet* line, Vector OptCandidateCenter, Vector OtherOptCandidateCenter
     241  atom *candidate, BoundaryLineSet* line, Vector OptCandidateCenter, Vector OtherOptCandidateCenter
    242242) {
    243         point = candidate;
    244         BaseLine = line;
    245         OptCenter.CopyVector(&OptCandidateCenter);
    246         OtherOptCenter.CopyVector(&OtherOptCandidateCenter);
     243  point = candidate;
     244  BaseLine = line;
     245  OptCenter.CopyVector(&OptCandidateCenter);
     246  OtherOptCenter.CopyVector(&OtherOptCandidateCenter);
    247247}
    248248
    249249CandidateForTesselation::~CandidateForTesselation() {
    250         point = NULL;
    251         BaseLine = NULL;
     250  point = NULL;
     251  BaseLine = NULL;
    252252}
    253253
     
    19041904  Vector CirclePlaneNormal; // normal vector defining the plane this circle lives in
    19051905  Vector SphereCenter;
    1906   Vector NewSphereCenter;        // center of the sphere defined by the two points of BaseLine and the one of Candidate, first possibility
    1907   Vector OtherNewSphereCenter;  // center of the sphere defined by the two points of BaseLine and the one of Candidate, second possibility
     1906  Vector NewSphereCenter;  // center of the sphere defined by the two points of BaseLine and the one of Candidate, first possibility
     1907  Vector OtherNewSphereCenter;  // center of the sphere defined by the two points of BaseLine and the one of Candidate, second possibility
    19081908  Vector NewNormalVector;   // normal vector of the Candidate's triangle
    19091909  Vector helper, OptCandidateCenter, OtherOptCandidateCenter;
     
    19851985
    19861986                  if ((NewNormalVector.MakeNormalVector(&(BaseLine->endpoints[0]->node->x), &(BaseLine->endpoints[1]->node->x), &(Candidate->x)))
    1987                         && (fabs(NewNormalVector.ScalarProduct(&NewNormalVector)) > HULLEPSILON)
     1987                  && (fabs(NewNormalVector.ScalarProduct(&NewNormalVector)) > HULLEPSILON)
    19881988                  ) {
    19891989                    helper.CopyVector(&NewNormalVector);
     
    20722072  //cout << Verbose(2) << "INFO: Sorting candidate list ..." << endl;
    20732073  if (candidates->size() > 1) {
    2074           candidates->unique();
    2075           candidates->sort(sortCandidates);
     2074    candidates->unique();
     2075    candidates->sort(sortCandidates);
    20762076  }
    20772077
     
    20802080
    20812081struct Intersection {
    2082         Vector x1;
    2083         Vector x2;
    2084         Vector x3;
    2085         Vector x4;
     2082  Vector x1;
     2083  Vector x2;
     2084  Vector x3;
     2085  Vector x4;
    20862086};
    20872087
     
    20932093 */
    20942094double MinIntersectDistance(const gsl_vector * x, void *params) {
    2095         double retval = 0;
    2096         struct Intersection *I = (struct Intersection *)params;
    2097         Vector intersection;
    2098         Vector SideA,SideB,HeightA, HeightB;
    2099         for (int i=0;i<NDIM;i++)
    2100                 intersection.x[i] = gsl_vector_get(x, i);
    2101 
    2102         SideA.CopyVector(&(I->x1));
    2103         SideA.SubtractVector(&I->x2);
    2104         HeightA.CopyVector(&intersection);
    2105         HeightA.SubtractVector(&I->x1);
    2106         HeightA.ProjectOntoPlane(&SideA);
    2107 
    2108         SideB.CopyVector(&I->x3);
    2109         SideB.SubtractVector(&I->x4);
    2110         HeightB.CopyVector(&intersection);
    2111         HeightB.SubtractVector(&I->x3);
    2112         HeightB.ProjectOntoPlane(&SideB);
    2113 
    2114         retval = HeightA.ScalarProduct(&HeightA) + HeightB.ScalarProduct(&HeightB);
    2115         //cout << Verbose(2) << "MinIntersectDistance called, result: " << retval << endl;
    2116 
    2117         return retval;
     2095  double retval = 0;
     2096  struct Intersection *I = (struct Intersection *)params;
     2097  Vector intersection;
     2098  Vector SideA,SideB,HeightA, HeightB;
     2099  for (int i=0;i<NDIM;i++)
     2100    intersection.x[i] = gsl_vector_get(x, i);
     2101
     2102  SideA.CopyVector(&(I->x1));
     2103  SideA.SubtractVector(&I->x2);
     2104  HeightA.CopyVector(&intersection);
     2105  HeightA.SubtractVector(&I->x1);
     2106  HeightA.ProjectOntoPlane(&SideA);
     2107
     2108  SideB.CopyVector(&I->x3);
     2109  SideB.SubtractVector(&I->x4);
     2110  HeightB.CopyVector(&intersection);
     2111  HeightB.SubtractVector(&I->x3);
     2112  HeightB.ProjectOntoPlane(&SideB);
     2113
     2114  retval = HeightA.ScalarProduct(&HeightA) + HeightB.ScalarProduct(&HeightB);
     2115  //cout << Verbose(2) << "MinIntersectDistance called, result: " << retval << endl;
     2116
     2117  return retval;
    21182118};
    21192119
     
    21322132 */
    21332133bool existsIntersection(Vector point1, Vector point2, Vector point3, Vector point4) {
    2134         bool result;
    2135 
    2136         struct Intersection par;
    2137                 par.x1.CopyVector(&point1);
    2138                 par.x2.CopyVector(&point2);
    2139                 par.x3.CopyVector(&point3);
    2140                 par.x4.CopyVector(&point4);
     2134  bool result;
     2135
     2136  struct Intersection par;
     2137    par.x1.CopyVector(&point1);
     2138    par.x2.CopyVector(&point2);
     2139    par.x3.CopyVector(&point3);
     2140    par.x4.CopyVector(&point4);
    21412141
    21422142    const gsl_multimin_fminimizer_type *T = gsl_multimin_fminimizer_nmsimplex;
     
    21792179
    21802180        if (status == GSL_SUCCESS) {
    2181                 cout << Verbose(2) << "converged to minimum" <<  endl;
     2181          cout << Verbose(2) << "converged to minimum" <<  endl;
    21822182        }
    21832183    } while (status == GSL_CONTINUE && iter < 100);
    21842184
    21852185    // check whether intersection is in between or not
    2186         Vector intersection, SideA, SideB, HeightA, HeightB;
    2187         double t1, t2;
    2188         for (int i = 0; i < NDIM; i++) {
    2189                 intersection.x[i] = gsl_vector_get(s->x, i);
    2190         }
    2191 
    2192         SideA.CopyVector(&par.x2);
    2193         SideA.SubtractVector(&par.x1);
    2194         HeightA.CopyVector(&intersection);
    2195         HeightA.SubtractVector(&par.x1);
    2196 
    2197         t1 = HeightA.Projection(&SideA)/SideA.ScalarProduct(&SideA);
    2198 
    2199         SideB.CopyVector(&par.x4);
    2200         SideB.SubtractVector(&par.x3);
    2201         HeightB.CopyVector(&intersection);
    2202         HeightB.SubtractVector(&par.x3);
    2203 
    2204         t2 = HeightB.Projection(&SideB)/SideB.ScalarProduct(&SideB);
    2205 
    2206         cout << Verbose(2) << "Intersection " << intersection << " is at "
    2207                 << t1 << " for (" << point1 << "," << point2 << ") and at "
    2208                 << t2 << " for (" << point3 << "," << point4 << "): ";
    2209 
    2210         if (((t1 >= 0) && (t1 <= 1)) && ((t2 >= 0) && (t2 <= 1))) {
    2211                 cout << "true intersection." << endl;
    2212                 result = true;
    2213         } else {
    2214                 cout << "intersection out of region of interest." << endl;
    2215                 result = false;
    2216         }
    2217 
    2218         // free minimizer stuff
     2186  Vector intersection, SideA, SideB, HeightA, HeightB;
     2187  double t1, t2;
     2188  for (int i = 0; i < NDIM; i++) {
     2189    intersection.x[i] = gsl_vector_get(s->x, i);
     2190  }
     2191
     2192  SideA.CopyVector(&par.x2);
     2193  SideA.SubtractVector(&par.x1);
     2194  HeightA.CopyVector(&intersection);
     2195  HeightA.SubtractVector(&par.x1);
     2196
     2197  t1 = HeightA.Projection(&SideA)/SideA.ScalarProduct(&SideA);
     2198
     2199  SideB.CopyVector(&par.x4);
     2200  SideB.SubtractVector(&par.x3);
     2201  HeightB.CopyVector(&intersection);
     2202  HeightB.SubtractVector(&par.x3);
     2203
     2204  t2 = HeightB.Projection(&SideB)/SideB.ScalarProduct(&SideB);
     2205
     2206  cout << Verbose(2) << "Intersection " << intersection << " is at "
     2207    << t1 << " for (" << point1 << "," << point2 << ") and at "
     2208    << t2 << " for (" << point3 << "," << point4 << "): ";
     2209
     2210  if (((t1 >= 0) && (t1 <= 1)) && ((t2 >= 0) && (t2 <= 1))) {
     2211    cout << "true intersection." << endl;
     2212    result = true;
     2213  } else {
     2214    cout << "intersection out of region of interest." << endl;
     2215    result = false;
     2216  }
     2217
     2218  // free minimizer stuff
    22192219    gsl_vector_free(x);
    22202220    gsl_vector_free(ss);
    22212221    gsl_multimin_fminimizer_free(s);
    22222222
    2223         return result;
     2223  return result;
    22242224}
    22252225
     
    26032603  cout << Verbose(1) << "Third Points are ";
    26042604  for (CandidateList::iterator it = Opt_Candidates->begin(); it != Opt_Candidates->end(); ++it) {
    2605           cout << " " << *(*it)->point;
     2605    cout << " " << *(*it)->point;
    26062606  }
    26072607  cout << endl;
     
    26092609  BoundaryLineSet *BaseRay = &Line;
    26102610  for (CandidateList::iterator it = Opt_Candidates->begin(); it != Opt_Candidates->end(); ++it) {
    2611           cout << Verbose(1) << " Third point candidate is " << *(*it)->point
    2612                 << " with circumsphere's center at " << (*it)->OptCenter << "." << endl;
    2613           cout << Verbose(1) << " Baseline is " << *BaseRay << endl;
    2614 
    2615           // check whether all edges of the new triangle still have space for one more triangle (i.e. TriangleCount <2)
    2616           atom *AtomCandidates[3];
    2617           AtomCandidates[0] = (*it)->point;
    2618           AtomCandidates[1] = BaseRay->endpoints[0]->node;
    2619           AtomCandidates[2] = BaseRay->endpoints[1]->node;
    2620           int existentTrianglesCount = CheckPresenceOfTriangle(out, AtomCandidates);
    2621 
    2622           BTS = NULL;
    2623           // If there is no triangle, add it regularly.
    2624           if (existentTrianglesCount == 0) {
     2611    cout << Verbose(1) << " Third point candidate is " << *(*it)->point
     2612    << " with circumsphere's center at " << (*it)->OptCenter << "." << endl;
     2613    cout << Verbose(1) << " Baseline is " << *BaseRay << endl;
     2614
     2615    // check whether all edges of the new triangle still have space for one more triangle (i.e. TriangleCount <2)
     2616    atom *AtomCandidates[3];
     2617    AtomCandidates[0] = (*it)->point;
     2618    AtomCandidates[1] = BaseRay->endpoints[0]->node;
     2619    AtomCandidates[2] = BaseRay->endpoints[1]->node;
     2620    int existentTrianglesCount = CheckPresenceOfTriangle(out, AtomCandidates);
     2621
     2622    BTS = NULL;
     2623    // If there is no triangle, add it regularly.
     2624    if (existentTrianglesCount == 0) {
    26252625      AddTrianglePoint((*it)->point, 0);
    26262626      AddTrianglePoint(BaseRay->endpoints[0]->node, 1);
     
    26402640        << " for this triangle ... " << endl;
    26412641      //cout << Verbose(1) << "We have "<< TrianglesOnBoundaryCount << " for line " << *BaseRay << "." << endl;
    2642           } else if (existentTrianglesCount == 1) { // If there is a planar region within the structure, we need this triangle a second time.
     2642    } else if (existentTrianglesCount == 1) { // If there is a planar region within the structure, we need this triangle a second time.
    26432643        AddTrianglePoint((*it)->point, 0);
    26442644        AddTrianglePoint(BaseRay->endpoints[0]->node, 1);
     
    26792679    }
    26802680
    2681           if ((result) && (existentTrianglesCount < 2) && (DoSingleStepOutput && (TrianglesOnBoundaryCount % 1 == 0))) { // if we have a new triangle and want to output each new triangle configuration
     2681    if ((result) && (existentTrianglesCount < 2) && (DoSingleStepOutput && (TrianglesOnBoundaryCount % 1 == 0))) { // if we have a new triangle and want to output each new triangle configuration
    26822682      sprintf(NumberName, "-%04d-%s_%s_%s", TriangleFilesWritten, BTS->endpoints[0]->node->Name, BTS->endpoints[1]->node->Name, BTS->endpoints[2]->node->Name);
    26832683      if (DoTecplotOutput) {
     
    27262726      if (DoTecplotOutput || DoRaster3DOutput)
    27272727        TriangleFilesWritten++;
    2728           }
     2728    }
    27292729
    27302730    // set baseline to new ray from ref point (here endpoints[0]->node) to current candidate (here (*it)->point))
    2731           BaseRay = BLS[0];
     2731    BaseRay = BLS[0];
    27322732  }
    27332733
     
    27472747 */
    27482748bool sortCandidates(CandidateForTesselation* candidate1, CandidateForTesselation* candidate2) {
    2749         Vector BaseLineVector, OrthogonalVector, helper;
    2750         if (candidate1->BaseLine != candidate2->BaseLine) {  // sanity check
    2751           cout << Verbose(0) << "ERROR: sortCandidates was called for two different baselines: " << candidate1->BaseLine << " and " << candidate2->BaseLine << "." << endl;
    2752           //return false;
    2753           exit(1);
    2754         }
    2755         // create baseline vector
    2756         BaseLineVector.CopyVector(&(candidate1->BaseLine->endpoints[1]->node->x));
    2757         BaseLineVector.SubtractVector(&(candidate1->BaseLine->endpoints[0]->node->x));
    2758         BaseLineVector.Normalize();
     2749  Vector BaseLineVector, OrthogonalVector, helper;
     2750  if (candidate1->BaseLine != candidate2->BaseLine) {  // sanity check
     2751    cout << Verbose(0) << "ERROR: sortCandidates was called for two different baselines: " << candidate1->BaseLine << " and " << candidate2->BaseLine << "." << endl;
     2752    //return false;
     2753    exit(1);
     2754  }
     2755  // create baseline vector
     2756  BaseLineVector.CopyVector(&(candidate1->BaseLine->endpoints[1]->node->x));
     2757  BaseLineVector.SubtractVector(&(candidate1->BaseLine->endpoints[0]->node->x));
     2758  BaseLineVector.Normalize();
    27592759
    27602760  // create normal in-plane vector to cope with acos() non-uniqueness on [0,2pi] (note that is pointing in the "right" direction already, hence ">0" test!)
    2761         helper.CopyVector(&(candidate1->BaseLine->endpoints[0]->node->x));
    2762         helper.SubtractVector(&(candidate1->point->x));
    2763         OrthogonalVector.CopyVector(&helper);
    2764         helper.VectorProduct(&BaseLineVector);
    2765         OrthogonalVector.SubtractVector(&helper);
    2766         OrthogonalVector.Normalize();
     2761  helper.CopyVector(&(candidate1->BaseLine->endpoints[0]->node->x));
     2762  helper.SubtractVector(&(candidate1->point->x));
     2763  OrthogonalVector.CopyVector(&helper);
     2764  helper.VectorProduct(&BaseLineVector);
     2765  OrthogonalVector.SubtractVector(&helper);
     2766  OrthogonalVector.Normalize();
    27672767
    27682768  // calculate both angles and correct with in-plane vector
    2769         helper.CopyVector(&(candidate1->point->x));
    2770         helper.SubtractVector(&(candidate1->BaseLine->endpoints[0]->node->x));
    2771         double phi = BaseLineVector.Angle(&helper);
     2769  helper.CopyVector(&(candidate1->point->x));
     2770  helper.SubtractVector(&(candidate1->BaseLine->endpoints[0]->node->x));
     2771  double phi = BaseLineVector.Angle(&helper);
    27722772  if (OrthogonalVector.ScalarProduct(&helper) > 0) {
    27732773    phi = 2.*M_PI - phi;
    27742774  }
    27752775  helper.CopyVector(&(candidate2->point->x));
    2776         helper.SubtractVector(&(candidate1->BaseLine->endpoints[0]->node->x));
    2777         double psi = BaseLineVector.Angle(&helper);
     2776  helper.SubtractVector(&(candidate1->BaseLine->endpoints[0]->node->x));
     2777  double psi = BaseLineVector.Angle(&helper);
    27782778  if (OrthogonalVector.ScalarProduct(&helper) > 0) {
    2779                 psi = 2.*M_PI - psi;
    2780         }
    2781 
    2782         cout << Verbose(2) << *candidate1->point << " has angle " << phi << endl;
    2783         cout << Verbose(2) << *candidate2->point << " has angle " << psi << endl;
    2784 
    2785         // return comparison
    2786         return phi < psi;
     2779    psi = 2.*M_PI - psi;
     2780  }
     2781
     2782  cout << Verbose(2) << *candidate1->point << " has angle " << phi << endl;
     2783  cout << Verbose(2) << *candidate2->point << " has angle " << psi << endl;
     2784
     2785  // return comparison
     2786  return phi < psi;
    27872787}
    27882788
  • src/boundary.hpp

    r205ccd r042f82  
    7878class CandidateForTesselation {
    7979  public :
    80         CandidateForTesselation(atom* candidate, BoundaryLineSet* currentBaseLine, Vector OptCandidateCenter, Vector OtherOptCandidateCenter);
    81         ~CandidateForTesselation();
    82         atom *point;
    83         BoundaryLineSet *BaseLine;
    84         Vector OptCenter;
    85         Vector OtherOptCenter;
     80  CandidateForTesselation(atom* candidate, BoundaryLineSet* currentBaseLine, Vector OptCandidateCenter, Vector OtherOptCandidateCenter);
     81  ~CandidateForTesselation();
     82  atom *point;
     83  BoundaryLineSet *BaseLine;
     84  Vector OptCenter;
     85  Vector OtherOptCenter;
    8686};
    8787
  • src/builder.cpp

    r205ccd r042f82  
    1515 * \section about About the Program
    1616 *
    17  *      Molecuilder is a short program, written in C++, that enables the construction of a coordinate set for the
    18  *      atoms making up an molecule by the successive statement of binding angles and distances and referencing to
    19  *      already constructed atoms.
     17 *  Molecuilder is a short program, written in C++, that enables the construction of a coordinate set for the
     18 *  atoms making up an molecule by the successive statement of binding angles and distances and referencing to
     19 *  already constructed atoms.
    2020 *
    21  *      A configuration file may be written that is compatible to the format used by PCP - a parallel Car-Parrinello
    22  *      molecular dynamics implementation.
     21 *  A configuration file may be written that is compatible to the format used by PCP - a parallel Car-Parrinello
     22 *  molecular dynamics implementation.
    2323 *
    2424 * \section install Installation
    2525 *
    26  *      Installation should without problems succeed as follows:
    27  *      -# ./configure (or: mkdir build;mkdir run;cd build; ../configure --bindir=../run)
    28  *      -# make
    29  *      -# make install
     26 *  Installation should without problems succeed as follows:
     27 *  -# ./configure (or: mkdir build;mkdir run;cd build; ../configure --bindir=../run)
     28 *  -# make
     29 *  -# make install
    3030 *
    31  *      Further useful commands are
    32  *      -# make clean uninstall: deletes .o-files and removes executable from the given binary directory\n
    33  *      -# make doxygen-doc: Creates these html pages out of the documented source
     31 *  Further useful commands are
     32 *  -# make clean uninstall: deletes .o-files and removes executable from the given binary directory\n
     33 *  -# make doxygen-doc: Creates these html pages out of the documented source
    3434 *
    3535 * \section run Running
    3636 *
    37  *      The program can be executed by running: ./molecuilder
     37 *  The program can be executed by running: ./molecuilder
    3838 *
    39  *      Note, that it uses a database, called "elements.db", in the executable's directory. If the file is not found,
    40  *      it is created and any given data on elements of the periodic table will be stored therein and re-used on
    41  *      later re-execution.
     39 *  Note, that it uses a database, called "elements.db", in the executable's directory. If the file is not found,
     40 *  it is created and any given data on elements of the periodic table will be stored therein and re-used on
     41 *  later re-execution.
    4242 *
    4343 * \section ref References
    4444 *
    45  *      For the special configuration file format, see the documentation of pcp.
     45 *  For the special configuration file format, see the documentation of pcp.
    4646 *
    4747 */
     
    6363static void AddAtoms(periodentafel *periode, molecule *mol)
    6464{
    65         atom *first, *second, *third, *fourth;
    66         Vector **atoms;
    67         Vector x,y,z,n; // coordinates for absolute point in cell volume
    68         double a,b,c;
    69         char choice;    // menu choice char
    70         bool valid;
    71 
    72         cout << Verbose(0) << "===========ADD ATOM============================" << endl;
    73         cout << Verbose(0) << " a - state absolute coordinates of atom" << endl;
    74         cout << Verbose(0) << " b - state relative coordinates of atom wrt to reference point" << endl;
    75         cout << Verbose(0) << " c - state relative coordinates of atom wrt to already placed atom" << endl;
    76         cout << Verbose(0) << " d - state two atoms, two angles and a distance" << endl;
    77         cout << Verbose(0) << " e - least square distance position to a set of atoms" << endl;
    78         cout << Verbose(0) << "all else - go back" << endl;
    79         cout << Verbose(0) << "===============================================" << endl;
    80         cout << Verbose(0) << "Note: Specifiy angles in degrees not multiples of Pi!" << endl;
    81         cout << Verbose(0) << "INPUT: ";
    82         cin >> choice;
    83 
    84         switch (choice) {
     65  atom *first, *second, *third, *fourth;
     66  Vector **atoms;
     67  Vector x,y,z,n;  // coordinates for absolute point in cell volume
     68  double a,b,c;
     69  char choice;  // menu choice char
     70  bool valid;
     71
     72  cout << Verbose(0) << "===========ADD ATOM============================" << endl;
     73  cout << Verbose(0) << " a - state absolute coordinates of atom" << endl;
     74  cout << Verbose(0) << " b - state relative coordinates of atom wrt to reference point" << endl;
     75  cout << Verbose(0) << " c - state relative coordinates of atom wrt to already placed atom" << endl;
     76  cout << Verbose(0) << " d - state two atoms, two angles and a distance" << endl;
     77  cout << Verbose(0) << " e - least square distance position to a set of atoms" << endl;
     78  cout << Verbose(0) << "all else - go back" << endl;
     79  cout << Verbose(0) << "===============================================" << endl;
     80  cout << Verbose(0) << "Note: Specifiy angles in degrees not multiples of Pi!" << endl;
     81  cout << Verbose(0) << "INPUT: ";
     82  cin >> choice;
     83
     84  switch (choice) {
    8585    default:
    8686      cout << Verbose(0) << "Not a valid choice." << endl;
    8787      break;
    88                         case 'a': // absolute coordinates of atom
     88      case 'a': // absolute coordinates of atom
    8989        cout << Verbose(0) << "Enter absolute coordinates." << endl;
    9090        first = new atom;
    9191        first->x.AskPosition(mol->cell_size, false);
    92         first->type = periode->AskElement();    // give type
    93         mol->AddAtom(first);    // add to molecule
    94                                 break;
    95 
    96                         case 'b': // relative coordinates of atom wrt to reference point
     92        first->type = periode->AskElement();  // give type
     93        mol->AddAtom(first);  // add to molecule
     94        break;
     95
     96      case 'b': // relative coordinates of atom wrt to reference point
    9797        first = new atom;
    9898        valid = true;
     
    106106          cout << Verbose(0) << "\n";
    107107        } while (!(valid = mol->CheckBounds((const Vector *)&first->x)));
    108         first->type = periode->AskElement();    // give type
    109         mol->AddAtom(first);    // add to molecule
    110                                 break;
    111 
    112                         case 'c': // relative coordinates of atom wrt to already placed atom
     108        first->type = periode->AskElement();  // give type
     109        mol->AddAtom(first);  // add to molecule
     110        break;
     111
     112      case 'c': // relative coordinates of atom wrt to already placed atom
    113113        first = new atom;
    114114        valid = true;
     
    122122          }
    123123        } while (!(valid = mol->CheckBounds((const Vector *)&first->x)));
    124         first->type = periode->AskElement();    // give type
    125         mol->AddAtom(first);    // add to molecule
     124        first->type = periode->AskElement();  // give type
     125        mol->AddAtom(first);  // add to molecule
    126126        break;
    127127
     
    224224          cout << Verbose(0) << endl;
    225225        } while (!(valid = mol->CheckBounds((const Vector *)&first->x)));
    226         first->type = periode->AskElement();    // give type
    227         mol->AddAtom(first);    // add to molecule
    228                                 break;
    229 
    230                         case 'e': // least square distance position to a set of atoms
     226        first->type = periode->AskElement();  // give type
     227        mol->AddAtom(first);  // add to molecule
     228        break;
     229
     230      case 'e': // least square distance position to a set of atoms
    231231        first = new atom;
    232232        atoms = new (Vector*[128]);
     
    248248
    249249          first->x.Output((ofstream *)&cout);
    250           first->type = periode->AskElement();  // give type
    251           mol->AddAtom(first);  // add to molecule
     250          first->type = periode->AskElement();  // give type
     251          mol->AddAtom(first);  // add to molecule
    252252        } else {
    253253          delete first;
    254254          cout << Verbose(0) << "Please enter at least two vectors!\n";
    255255        }
    256                                 break;
    257         };
     256        break;
     257  };
    258258};
    259259
     
    263263static void CenterAtoms(molecule *mol)
    264264{
    265         Vector x, y, helper;
    266         char choice;    // menu choice char
    267 
    268         cout << Verbose(0) << "===========CENTER ATOMS=========================" << endl;
    269         cout << Verbose(0) << " a - on origin" << endl;
    270         cout << Verbose(0) << " b - on center of gravity" << endl;
    271         cout << Verbose(0) << " c - within box with additional boundary" << endl;
    272         cout << Verbose(0) << " d - within given simulation box" << endl;
    273         cout << Verbose(0) << "all else - go back" << endl;
    274         cout << Verbose(0) << "===============================================" << endl;
    275         cout << Verbose(0) << "INPUT: ";
    276         cin >> choice;
    277 
    278         switch (choice) {
    279                 default:
    280                         cout << Verbose(0) << "Not a valid choice." << endl;
    281                         break;
    282                 case 'a':
    283                         cout << Verbose(0) << "Centering atoms in config file on origin." << endl;
    284                         mol->CenterOrigin((ofstream *)&cout, &x);
    285                         break;
    286                 case 'b':
    287                         cout << Verbose(0) << "Centering atoms in config file on center of gravity." << endl;
    288                         mol->CenterGravity((ofstream *)&cout, &x);
    289                         break;
    290                 case 'c':
    291                         cout << Verbose(0) << "Centering atoms in config file within given additional boundary." << endl;
    292                         for (int i=0;i<NDIM;i++) {
    293                                 cout << Verbose(0) << "Enter axis " << i << " boundary: ";
    294                                 cin >> y.x[i];
    295                         }
    296                         mol->CenterEdge((ofstream *)&cout, &x); // make every coordinate positive
    297                         mol->Translate(&y); // translate by boundary
    298                         helper.CopyVector(&y);
    299                         helper.Scale(2.);
    300                         helper.AddVector(&x);
    301                         mol->SetBoxDimension(&helper);  // update Box of atoms by boundary
    302                         break;
    303                 case 'd':
    304                         cout << Verbose(1) << "Centering atoms in config file within given simulation box." << endl;
    305                         for (int i=0;i<NDIM;i++) {
    306                                 cout << Verbose(0) << "Enter axis " << i << " boundary: ";
    307                                 cin >> x.x[i];
    308                         }
    309                         // center
    310                         mol->CenterInBox((ofstream *)&cout);
    311                         // update Box of atoms by boundary
    312                         mol->SetBoxDimension(&x);
    313                         break;
    314         }
     265  Vector x, y, helper;
     266  char choice;  // menu choice char
     267
     268  cout << Verbose(0) << "===========CENTER ATOMS=========================" << endl;
     269  cout << Verbose(0) << " a - on origin" << endl;
     270  cout << Verbose(0) << " b - on center of gravity" << endl;
     271  cout << Verbose(0) << " c - within box with additional boundary" << endl;
     272  cout << Verbose(0) << " d - within given simulation box" << endl;
     273  cout << Verbose(0) << "all else - go back" << endl;
     274  cout << Verbose(0) << "===============================================" << endl;
     275  cout << Verbose(0) << "INPUT: ";
     276  cin >> choice;
     277
     278  switch (choice) {
     279    default:
     280      cout << Verbose(0) << "Not a valid choice." << endl;
     281      break;
     282    case 'a':
     283      cout << Verbose(0) << "Centering atoms in config file on origin." << endl;
     284      mol->CenterOrigin((ofstream *)&cout, &x);
     285      break;
     286    case 'b':
     287      cout << Verbose(0) << "Centering atoms in config file on center of gravity." << endl;
     288      mol->CenterGravity((ofstream *)&cout, &x);
     289      break;
     290    case 'c':
     291      cout << Verbose(0) << "Centering atoms in config file within given additional boundary." << endl;
     292      for (int i=0;i<NDIM;i++) {
     293        cout << Verbose(0) << "Enter axis " << i << " boundary: ";
     294        cin >> y.x[i];
     295      }
     296      mol->CenterEdge((ofstream *)&cout, &x);  // make every coordinate positive
     297      mol->Translate(&y); // translate by boundary
     298      helper.CopyVector(&y);
     299      helper.Scale(2.);
     300      helper.AddVector(&x);
     301      mol->SetBoxDimension(&helper);  // update Box of atoms by boundary
     302      break;
     303    case 'd':
     304      cout << Verbose(1) << "Centering atoms in config file within given simulation box." << endl;
     305      for (int i=0;i<NDIM;i++) {
     306        cout << Verbose(0) << "Enter axis " << i << " boundary: ";
     307        cin >> x.x[i];
     308      }
     309      // center
     310      mol->CenterInBox((ofstream *)&cout);
     311      // update Box of atoms by boundary
     312      mol->SetBoxDimension(&x);
     313      break;
     314  }
    315315};
    316316
     
    321321static void AlignAtoms(periodentafel *periode, molecule *mol)
    322322{
    323         atom *first, *second, *third;
    324         Vector x,n;
    325         char choice;    // menu choice char
    326 
    327         cout << Verbose(0) << "===========ALIGN ATOMS=========================" << endl;
    328         cout << Verbose(0) << " a - state three atoms defining align plane" << endl;
    329         cout << Verbose(0) << " b - state alignment vector" << endl;
    330         cout << Verbose(0) << " c - state two atoms in alignment direction" << endl;
    331         cout << Verbose(0) << " d - align automatically by least square fit" << endl;
    332         cout << Verbose(0) << "all else - go back" << endl;
    333         cout << Verbose(0) << "===============================================" << endl;
    334         cout << Verbose(0) << "INPUT: ";
    335         cin >> choice;
    336 
    337         switch (choice) {
    338                 default:
    339                 case 'a': // three atoms defining mirror plane
    340                         first = mol->AskAtom("Enter first atom: ");
    341                         second = mol->AskAtom("Enter second atom: ");
    342                         third = mol->AskAtom("Enter third atom: ");
    343 
    344                         n.MakeNormalVector((const Vector *)&first->x,(const Vector *)&second->x,(const Vector *)&third->x);
    345                         break;
    346                 case 'b': // normal vector of mirror plane
    347                         cout << Verbose(0) << "Enter normal vector of mirror plane." << endl;
    348                         n.AskPosition(mol->cell_size,0);
    349                         n.Normalize();
    350                         break;
    351                 case 'c': // three atoms defining mirror plane
    352                         first = mol->AskAtom("Enter first atom: ");
    353                         second = mol->AskAtom("Enter second atom: ");
    354 
    355                         n.CopyVector((const Vector *)&first->x);
    356                         n.SubtractVector((const Vector *)&second->x);
    357                         n.Normalize();
    358                         break;
    359                 case 'd':
    360                         char shorthand[4];
    361                         Vector a;
    362                         struct lsq_params param;
    363                         do {
    364                                 fprintf(stdout, "Enter the element of atoms to be chosen: ");
    365                                 fscanf(stdin, "%3s", shorthand);
    366                         } while ((param.type = periode->FindElement(shorthand)) == NULL);
    367                         cout << Verbose(0) << "Element is " << param.type->name << endl;
    368                         mol->GetAlignvector(&param);
    369                         for (int i=NDIM;i--;) {
    370                                 x.x[i] = gsl_vector_get(param.x,i);
    371                                 n.x[i] = gsl_vector_get(param.x,i+NDIM);
    372                         }
    373                         gsl_vector_free(param.x);
    374                         cout << Verbose(0) << "Offset vector: ";
    375                         x.Output((ofstream *)&cout);
    376                         cout << Verbose(0) << endl;
    377                         n.Normalize();
    378                         break;
    379         };
    380         cout << Verbose(0) << "Alignment vector: ";
    381         n.Output((ofstream *)&cout);
    382         cout << Verbose(0) << endl;
    383         mol->Align(&n);
     323  atom *first, *second, *third;
     324  Vector x,n;
     325  char choice;  // menu choice char
     326
     327  cout << Verbose(0) << "===========ALIGN ATOMS=========================" << endl;
     328  cout << Verbose(0) << " a - state three atoms defining align plane" << endl;
     329  cout << Verbose(0) << " b - state alignment vector" << endl;
     330  cout << Verbose(0) << " c - state two atoms in alignment direction" << endl;
     331  cout << Verbose(0) << " d - align automatically by least square fit" << endl;
     332  cout << Verbose(0) << "all else - go back" << endl;
     333  cout << Verbose(0) << "===============================================" << endl;
     334  cout << Verbose(0) << "INPUT: ";
     335  cin >> choice;
     336
     337  switch (choice) {
     338    default:
     339    case 'a': // three atoms defining mirror plane
     340      first = mol->AskAtom("Enter first atom: ");
     341      second = mol->AskAtom("Enter second atom: ");
     342      third = mol->AskAtom("Enter third atom: ");
     343
     344      n.MakeNormalVector((const Vector *)&first->x,(const Vector *)&second->x,(const Vector *)&third->x);
     345      break;
     346    case 'b': // normal vector of mirror plane
     347      cout << Verbose(0) << "Enter normal vector of mirror plane." << endl;
     348      n.AskPosition(mol->cell_size,0);
     349      n.Normalize();
     350      break;
     351    case 'c': // three atoms defining mirror plane
     352      first = mol->AskAtom("Enter first atom: ");
     353      second = mol->AskAtom("Enter second atom: ");
     354
     355      n.CopyVector((const Vector *)&first->x);
     356      n.SubtractVector((const Vector *)&second->x);
     357      n.Normalize();
     358      break;
     359    case 'd':
     360      char shorthand[4];
     361      Vector a;
     362      struct lsq_params param;
     363      do {
     364        fprintf(stdout, "Enter the element of atoms to be chosen: ");
     365        fscanf(stdin, "%3s", shorthand);
     366      } while ((param.type = periode->FindElement(shorthand)) == NULL);
     367      cout << Verbose(0) << "Element is " << param.type->name << endl;
     368      mol->GetAlignvector(&param);
     369      for (int i=NDIM;i--;) {
     370        x.x[i] = gsl_vector_get(param.x,i);
     371        n.x[i] = gsl_vector_get(param.x,i+NDIM);
     372      }
     373      gsl_vector_free(param.x);
     374      cout << Verbose(0) << "Offset vector: ";
     375      x.Output((ofstream *)&cout);
     376      cout << Verbose(0) << endl;
     377      n.Normalize();
     378      break;
     379  };
     380  cout << Verbose(0) << "Alignment vector: ";
     381  n.Output((ofstream *)&cout);
     382  cout << Verbose(0) << endl;
     383  mol->Align(&n);
    384384};
    385385
     
    389389static void MirrorAtoms(molecule *mol)
    390390{
    391         atom *first, *second, *third;
    392         Vector n;
    393         char choice;    // menu choice char
    394 
    395         cout << Verbose(0) << "===========MIRROR ATOMS=========================" << endl;
    396         cout << Verbose(0) << " a - state three atoms defining mirror plane" << endl;
    397         cout << Verbose(0) << " b - state normal vector of mirror plane" << endl;
    398         cout << Verbose(0) << " c - state two atoms in normal direction" << endl;
    399         cout << Verbose(0) << "all else - go back" << endl;
    400         cout << Verbose(0) << "===============================================" << endl;
    401         cout << Verbose(0) << "INPUT: ";
    402         cin >> choice;
    403 
    404         switch (choice) {
    405                 default:
    406                 case 'a': // three atoms defining mirror plane
    407                         first = mol->AskAtom("Enter first atom: ");
    408                         second = mol->AskAtom("Enter second atom: ");
    409                         third = mol->AskAtom("Enter third atom: ");
    410 
    411                         n.MakeNormalVector((const Vector *)&first->x,(const Vector *)&second->x,(const Vector *)&third->x);
    412                         break;
    413                 case 'b': // normal vector of mirror plane
    414                         cout << Verbose(0) << "Enter normal vector of mirror plane." << endl;
    415                         n.AskPosition(mol->cell_size,0);
    416                         n.Normalize();
    417                         break;
    418                 case 'c': // three atoms defining mirror plane
    419                         first = mol->AskAtom("Enter first atom: ");
    420                         second = mol->AskAtom("Enter second atom: ");
    421 
    422                         n.CopyVector((const Vector *)&first->x);
    423                         n.SubtractVector((const Vector *)&second->x);
    424                         n.Normalize();
    425                         break;
    426         };
    427         cout << Verbose(0) << "Normal vector: ";
    428         n.Output((ofstream *)&cout);
    429         cout << Verbose(0) << endl;
    430         mol->Mirror((const Vector *)&n);
     391  atom *first, *second, *third;
     392  Vector n;
     393  char choice;  // menu choice char
     394
     395  cout << Verbose(0) << "===========MIRROR ATOMS=========================" << endl;
     396  cout << Verbose(0) << " a - state three atoms defining mirror plane" << endl;
     397  cout << Verbose(0) << " b - state normal vector of mirror plane" << endl;
     398  cout << Verbose(0) << " c - state two atoms in normal direction" << endl;
     399  cout << Verbose(0) << "all else - go back" << endl;
     400  cout << Verbose(0) << "===============================================" << endl;
     401  cout << Verbose(0) << "INPUT: ";
     402  cin >> choice;
     403
     404  switch (choice) {
     405    default:
     406    case 'a': // three atoms defining mirror plane
     407      first = mol->AskAtom("Enter first atom: ");
     408      second = mol->AskAtom("Enter second atom: ");
     409      third = mol->AskAtom("Enter third atom: ");
     410
     411      n.MakeNormalVector((const Vector *)&first->x,(const Vector *)&second->x,(const Vector *)&third->x);
     412      break;
     413    case 'b': // normal vector of mirror plane
     414      cout << Verbose(0) << "Enter normal vector of mirror plane." << endl;
     415      n.AskPosition(mol->cell_size,0);
     416      n.Normalize();
     417      break;
     418    case 'c': // three atoms defining mirror plane
     419      first = mol->AskAtom("Enter first atom: ");
     420      second = mol->AskAtom("Enter second atom: ");
     421
     422      n.CopyVector((const Vector *)&first->x);
     423      n.SubtractVector((const Vector *)&second->x);
     424      n.Normalize();
     425      break;
     426  };
     427  cout << Verbose(0) << "Normal vector: ";
     428  n.Output((ofstream *)&cout);
     429  cout << Verbose(0) << endl;
     430  mol->Mirror((const Vector *)&n);
    431431};
    432432
     
    436436static void RemoveAtoms(molecule *mol)
    437437{
    438         atom *first, *second;
    439         int axis;
    440         double tmp1, tmp2;
    441         char choice;    // menu choice char
    442 
    443         cout << Verbose(0) << "===========REMOVE ATOMS=========================" << endl;
    444         cout << Verbose(0) << " a - state atom for removal by number" << endl;
    445         cout << Verbose(0) << " b - keep only in radius around atom" << endl;
    446         cout << Verbose(0) << " c - remove this with one axis greater value" << endl;
    447         cout << Verbose(0) << "all else - go back" << endl;
    448         cout << Verbose(0) << "===============================================" << endl;
    449         cout << Verbose(0) << "INPUT: ";
    450         cin >> choice;
    451 
    452         switch (choice) {
    453                 default:
    454                 case 'a':
    455                         if (mol->RemoveAtom(mol->AskAtom("Enter number of atom within molecule: ")))
    456                                 cout << Verbose(1) << "Atom removed." << endl;
    457                         else
    458                                 cout << Verbose(1) << "Atom not found." << endl;
    459                         break;
    460                 case 'b':
    461                         second = mol->AskAtom("Enter number of atom as reference point: ");
    462                         cout << Verbose(0) << "Enter radius: ";
    463                         cin >> tmp1;
    464                         first = mol->start;
    465                         while(first->next != mol->end) {
    466                                 first = first->next;
    467                                 if (first->x.DistanceSquared((const Vector *)&second->x) > tmp1*tmp1) // distance to first above radius ...
    468                                         mol->RemoveAtom(first);
    469                         }
    470                         break;
    471                 case 'c':
    472                         cout << Verbose(0) << "Which axis is it: ";
    473                         cin >> axis;
    474                         cout << Verbose(0) << "Left inward boundary: ";
    475                         cin >> tmp1;
    476                         cout << Verbose(0) << "Right inward boundary: ";
    477                         cin >> tmp2;
    478                         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 ...
    482                                         mol->RemoveAtom(first);
    483                         }
    484                         break;
    485         };
    486         //mol->Output((ofstream *)&cout);
    487         choice = 'r';
     438  atom *first, *second;
     439  int axis;
     440  double tmp1, tmp2;
     441  char choice;  // menu choice char
     442
     443  cout << Verbose(0) << "===========REMOVE ATOMS=========================" << endl;
     444  cout << Verbose(0) << " a - state atom for removal by number" << endl;
     445  cout << Verbose(0) << " b - keep only in radius around atom" << endl;
     446  cout << Verbose(0) << " c - remove this with one axis greater value" << endl;
     447  cout << Verbose(0) << "all else - go back" << endl;
     448  cout << Verbose(0) << "===============================================" << endl;
     449  cout << Verbose(0) << "INPUT: ";
     450  cin >> choice;
     451
     452  switch (choice) {
     453    default:
     454    case 'a':
     455      if (mol->RemoveAtom(mol->AskAtom("Enter number of atom within molecule: ")))
     456        cout << Verbose(1) << "Atom removed." << endl;
     457      else
     458        cout << Verbose(1) << "Atom not found." << endl;
     459      break;
     460    case 'b':
     461      second = mol->AskAtom("Enter number of atom as reference point: ");
     462      cout << Verbose(0) << "Enter radius: ";
     463      cin >> tmp1;
     464      first = mol->start;
     465      while(first->next != mol->end) {
     466        first = first->next;
     467        if (first->x.DistanceSquared((const Vector *)&second->x) > tmp1*tmp1) // distance to first above radius ...
     468          mol->RemoveAtom(first);
     469      }
     470      break;
     471    case 'c':
     472      cout << Verbose(0) << "Which axis is it: ";
     473      cin >> axis;
     474      cout << Verbose(0) << "Left inward boundary: ";
     475      cin >> tmp1;
     476      cout << Verbose(0) << "Right inward boundary: ";
     477      cin >> tmp2;
     478      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 ...
     482          mol->RemoveAtom(first);
     483      }
     484      break;
     485  };
     486  //mol->Output((ofstream *)&cout);
     487  choice = 'r';
    488488};
    489489
     
    494494static void MeasureAtoms(periodentafel *periode, molecule *mol, config *configuration)
    495495{
    496         atom *first, *second, *third;
    497         Vector x,y;
    498         double min[256], tmp1, tmp2, tmp3;
    499         int Z;
    500         char choice;    // menu choice char
    501 
    502         cout << Verbose(0) << "===========MEASURE ATOMS=========================" << endl;
    503         cout << Verbose(0) << " a - calculate bond length between one atom and all others" << endl;
    504         cout << Verbose(0) << " b - calculate bond length between two atoms" << endl;
    505         cout << Verbose(0) << " c - calculate bond angle" << endl;
    506         cout << Verbose(0) << " d - calculate principal axis of the system" << endl;
    507         cout << Verbose(0) << " e - calculate volume of the convex envelope" << endl;
    508         cout << Verbose(0) << " f - calculate temperature from current velocity" << endl;
    509         cout << Verbose(0) << " g - output all temperatures per step from velocities" << endl;
    510         cout << Verbose(0) << "all else - go back" << endl;
    511         cout << Verbose(0) << "===============================================" << endl;
    512         cout << Verbose(0) << "INPUT: ";
    513         cin >> choice;
    514 
    515         switch(choice) {
    516                 default:
    517                         cout << Verbose(1) << "Not a valid choice." << endl;
    518                         break;
    519                 case 'a':
    520                         first = mol->AskAtom("Enter first atom: ");
    521                         for (int i=MAX_ELEMENTS;i--;)
    522                                 min[i] = 0.;
    523 
    524                         second = mol->start;
    525                         while ((second->next != mol->end)) {
    526                                 second = second->next; // advance
    527                                 Z = second->type->Z;
    528                                 tmp1 = 0.;
    529                                 if (first != second) {
    530                                         x.CopyVector((const Vector *)&first->x);
    531                                         x.SubtractVector((const Vector *)&second->x);
    532                                         tmp1 = x.Norm();
    533                                 }
    534                                 if ((tmp1 != 0.) && ((min[Z] == 0.) || (tmp1 < min[Z]))) min[Z] = tmp1;
    535                                 //cout << Verbose(0) << "Bond length between Atom " << first->nr << " and " << second->nr << ": " << tmp1 << " a.u." << endl;
    536                         }
    537                         for (int i=MAX_ELEMENTS;i--;)
    538                                 if (min[i] != 0.) cout << Verbose(0) << "Minimum Bond length between " << first->type->name << " Atom " << first->nr << " and next Ion of type " << (periode->FindElement(i))->name << ": " << min[i] << " a.u." << endl;
    539                         break;
    540 
    541                 case 'b':
    542                         first = mol->AskAtom("Enter first atom: ");
    543                         second = mol->AskAtom("Enter second atom: ");
    544                         for (int i=NDIM;i--;)
    545                                 min[i] = 0.;
    546                         x.CopyVector((const Vector *)&first->x);
    547                         x.SubtractVector((const Vector *)&second->x);
    548                         tmp1 = x.Norm();
    549                         cout << Verbose(1) << "Distance vector is ";
    550                         x.Output((ofstream *)&cout);
    551                         cout << "." << endl << "Norm of distance is " << tmp1 << "." << endl;
    552                         break;
    553 
    554                 case 'c':
    555                         cout << Verbose(0) << "Evaluating bond angle between three - first, central, last - atoms." << endl;
    556                         first = mol->AskAtom("Enter first atom: ");
    557                         second = mol->AskAtom("Enter central atom: ");
    558                         third   = mol->AskAtom("Enter last atom: ");
    559                         tmp1 = tmp2 = tmp3 = 0.;
    560                         x.CopyVector((const Vector *)&first->x);
    561                         x.SubtractVector((const Vector *)&second->x);
    562                         y.CopyVector((const Vector *)&third->x);
    563                         y.SubtractVector((const Vector *)&second->x);
    564                         cout << Verbose(0) << "Bond angle between first atom Nr." << first->nr << ", central atom Nr." << second->nr << " and last atom Nr." << third->nr << ": ";
    565                         cout << Verbose(0) << (acos(x.ScalarProduct((const Vector *)&y)/(y.Norm()*x.Norm()))/M_PI*180.) << " degrees" << endl;
    566                         break;
    567                 case 'd':
    568                         cout << Verbose(0) << "Evaluating prinicipal axis." << endl;
    569                         cout << Verbose(0) << "Shall we rotate? [0/1]: ";
    570                         cin >> Z;
    571                         if ((Z >=0) && (Z <=1))
    572                                 mol->PrincipalAxisSystem((ofstream *)&cout, (bool)Z);
    573                         else
    574                                 mol->PrincipalAxisSystem((ofstream *)&cout, false);
    575                         break;
    576                 case 'e':
    577                         cout << Verbose(0) << "Evaluating volume of the convex envelope.";
    578                         VolumeOfConvexEnvelope((ofstream *)&cout, NULL, configuration, NULL, mol);
    579                         break;
    580                 case 'f':
    581                         mol->OutputTemperatureFromTrajectories((ofstream *)&cout, mol->MDSteps-1, mol->MDSteps, (ofstream *)&cout);
    582                         break;
    583                 case 'g':
    584                         {
    585                                 char filename[255];
    586                                 cout << "Please enter filename: " << endl;
    587                                 cin >> filename;
    588                                 cout << Verbose(1) << "Storing temperatures in " << filename << "." << endl;
    589                                 ofstream *output = new ofstream(filename, ios::trunc);
    590                                 if (!mol->OutputTemperatureFromTrajectories((ofstream *)&cout, 0, mol->MDSteps, output))
    591                                         cout << Verbose(2) << "File could not be written." << endl;
    592                                 else
    593                                         cout << Verbose(2) << "File stored." << endl;
    594                                 output->close();
    595                                 delete(output);
    596                         }
    597                         break;
    598         }
     496  atom *first, *second, *third;
     497  Vector x,y;
     498  double min[256], tmp1, tmp2, tmp3;
     499  int Z;
     500  char choice;  // menu choice char
     501
     502  cout << Verbose(0) << "===========MEASURE ATOMS=========================" << endl;
     503  cout << Verbose(0) << " a - calculate bond length between one atom and all others" << endl;
     504  cout << Verbose(0) << " b - calculate bond length between two atoms" << endl;
     505  cout << Verbose(0) << " c - calculate bond angle" << endl;
     506  cout << Verbose(0) << " d - calculate principal axis of the system" << endl;
     507  cout << Verbose(0) << " e - calculate volume of the convex envelope" << endl;
     508  cout << Verbose(0) << " f - calculate temperature from current velocity" << endl;
     509  cout << Verbose(0) << " g - output all temperatures per step from velocities" << endl;
     510  cout << Verbose(0) << "all else - go back" << endl;
     511  cout << Verbose(0) << "===============================================" << endl;
     512  cout << Verbose(0) << "INPUT: ";
     513  cin >> choice;
     514
     515  switch(choice) {
     516    default:
     517      cout << Verbose(1) << "Not a valid choice." << endl;
     518      break;
     519    case 'a':
     520      first = mol->AskAtom("Enter first atom: ");
     521      for (int i=MAX_ELEMENTS;i--;)
     522        min[i] = 0.;
     523
     524      second = mol->start;
     525      while ((second->next != mol->end)) {
     526        second = second->next; // advance
     527        Z = second->type->Z;
     528        tmp1 = 0.;
     529        if (first != second) {
     530          x.CopyVector((const Vector *)&first->x);
     531          x.SubtractVector((const Vector *)&second->x);
     532          tmp1 = x.Norm();
     533        }
     534        if ((tmp1 != 0.) && ((min[Z] == 0.) || (tmp1 < min[Z]))) min[Z] = tmp1;
     535        //cout << Verbose(0) << "Bond length between Atom " << first->nr << " and " << second->nr << ": " << tmp1 << " a.u." << endl;
     536      }
     537      for (int i=MAX_ELEMENTS;i--;)
     538        if (min[i] != 0.) cout << Verbose(0) << "Minimum Bond length between " << first->type->name << " Atom " << first->nr << " and next Ion of type " << (periode->FindElement(i))->name << ": " << min[i] << " a.u." << endl;
     539      break;
     540
     541    case 'b':
     542      first = mol->AskAtom("Enter first atom: ");
     543      second = mol->AskAtom("Enter second atom: ");
     544      for (int i=NDIM;i--;)
     545        min[i] = 0.;
     546      x.CopyVector((const Vector *)&first->x);
     547      x.SubtractVector((const Vector *)&second->x);
     548      tmp1 = x.Norm();
     549      cout << Verbose(1) << "Distance vector is ";
     550      x.Output((ofstream *)&cout);
     551      cout << "." << endl << "Norm of distance is " << tmp1 << "." << endl;
     552      break;
     553
     554    case 'c':
     555      cout << Verbose(0) << "Evaluating bond angle between three - first, central, last - atoms." << endl;
     556      first = mol->AskAtom("Enter first atom: ");
     557      second = mol->AskAtom("Enter central atom: ");
     558      third  = mol->AskAtom("Enter last atom: ");
     559      tmp1 = tmp2 = tmp3 = 0.;
     560      x.CopyVector((const Vector *)&first->x);
     561      x.SubtractVector((const Vector *)&second->x);
     562      y.CopyVector((const Vector *)&third->x);
     563      y.SubtractVector((const Vector *)&second->x);
     564      cout << Verbose(0) << "Bond angle between first atom Nr." << first->nr << ", central atom Nr." << second->nr << " and last atom Nr." << third->nr << ": ";
     565      cout << Verbose(0) << (acos(x.ScalarProduct((const Vector *)&y)/(y.Norm()*x.Norm()))/M_PI*180.) << " degrees" << endl;
     566      break;
     567    case 'd':
     568      cout << Verbose(0) << "Evaluating prinicipal axis." << endl;
     569      cout << Verbose(0) << "Shall we rotate? [0/1]: ";
     570      cin >> Z;
     571      if ((Z >=0) && (Z <=1))
     572        mol->PrincipalAxisSystem((ofstream *)&cout, (bool)Z);
     573      else
     574        mol->PrincipalAxisSystem((ofstream *)&cout, false);
     575      break;
     576    case 'e':
     577      cout << Verbose(0) << "Evaluating volume of the convex envelope.";
     578      VolumeOfConvexEnvelope((ofstream *)&cout, NULL, configuration, NULL, mol);
     579      break;
     580    case 'f':
     581      mol->OutputTemperatureFromTrajectories((ofstream *)&cout, mol->MDSteps-1, mol->MDSteps, (ofstream *)&cout);
     582      break;
     583    case 'g':
     584      {
     585        char filename[255];
     586        cout << "Please enter filename: " << endl;
     587        cin >> filename;
     588        cout << Verbose(1) << "Storing temperatures in " << filename << "." << endl;
     589        ofstream *output = new ofstream(filename, ios::trunc);
     590        if (!mol->OutputTemperatureFromTrajectories((ofstream *)&cout, 0, mol->MDSteps, output))
     591          cout << Verbose(2) << "File could not be written." << endl;
     592        else
     593          cout << Verbose(2) << "File stored." << endl;
     594        output->close();
     595        delete(output);
     596      }
     597      break;
     598  }
    599599};
    600600
     
    605605static void FragmentAtoms(molecule *mol, config *configuration)
    606606{
    607         int Order1;
    608         clock_t start, end;
    609 
    610         cout << Verbose(0) << "Fragmenting molecule with current connection matrix ..." << endl;
    611         cout << Verbose(0) << "What's the desired bond order: ";
    612         cin >> Order1;
    613         if (mol->first->next != mol->last) {    // there are bonds
    614                 start = clock();
    615                 mol->FragmentMolecule((ofstream *)&cout, Order1, configuration);
    616                 end = clock();
    617                 cout << Verbose(0) << "Clocks for this operation: " << (end-start) << ", time: " << ((double)(end-start)/CLOCKS_PER_SEC) << "s." << endl;
    618         } else
    619                 cout << Verbose(0) << "Connection matrix has not yet been generated!" << endl;
     607  int Order1;
     608  clock_t start, end;
     609
     610  cout << Verbose(0) << "Fragmenting molecule with current connection matrix ..." << endl;
     611  cout << Verbose(0) << "What's the desired bond order: ";
     612  cin >> Order1;
     613  if (mol->first->next != mol->last) {  // there are bonds
     614    start = clock();
     615    mol->FragmentMolecule((ofstream *)&cout, Order1, configuration);
     616    end = clock();
     617    cout << Verbose(0) << "Clocks for this operation: " << (end-start) << ", time: " << ((double)(end-start)/CLOCKS_PER_SEC) << "s." << endl;
     618  } else
     619    cout << Verbose(0) << "Connection matrix has not yet been generated!" << endl;
    620620};
    621621
     
    10381038static void testroutine(MoleculeListClass *molecules)
    10391039{
    1040         // the current test routine checks the functionality of the KeySet&Graph concept:
    1041         // We want to have a multiindex (the KeySet) describing a unique subgraph
     1040  // the current test routine checks the functionality of the KeySet&Graph concept:
     1041  // We want to have a multiindex (the KeySet) describing a unique subgraph
    10421042  int i, comp, counter=0;
    10431043
     
    10521052  atom *Walker = mol->start;
    10531053
    1054         // generate some KeySets
    1055         cout << "Generating KeySets." << endl;
    1056         KeySet TestSets[mol->AtomCount+1];
    1057         i=1;
    1058         while (Walker->next != mol->end) {
    1059                 Walker = Walker->next;
    1060                 for (int j=0;j<i;j++) {
    1061                         TestSets[j].insert(Walker->nr);
    1062                 }
    1063                 i++;
    1064         }
    1065         cout << "Testing insertion of already present item in KeySets." << endl;
    1066         KeySetTestPair test;
    1067         test = TestSets[mol->AtomCount-1].insert(Walker->nr);
    1068         if (test.second) {
    1069                 cout << Verbose(1) << "Insertion worked?!" << endl;
    1070         } else {
    1071                 cout << Verbose(1) << "Insertion rejected: Present object is " << (*test.first) << "." << endl;
    1072         }
    1073         TestSets[mol->AtomCount].insert(mol->end->previous->nr);
    1074         TestSets[mol->AtomCount].insert(mol->end->previous->previous->previous->nr);
    1075 
    1076         // constructing Graph structure
    1077         cout << "Generating Subgraph class." << endl;
    1078         Graph Subgraphs;
    1079 
    1080         // insert KeySets into Subgraphs
    1081         cout << "Inserting KeySets into Subgraph class." << endl;
    1082         for (int j=0;j<mol->AtomCount;j++) {
    1083                 Subgraphs.insert(GraphPair (TestSets[j],pair<int, double>(counter++, 1.)));
    1084         }
    1085         cout << "Testing insertion of already present item in Subgraph." << endl;
    1086         GraphTestPair test2;
    1087         test2 = Subgraphs.insert(GraphPair (TestSets[mol->AtomCount],pair<int, double>(counter++, 1.)));
    1088         if (test2.second) {
    1089                 cout << Verbose(1) << "Insertion worked?!" << endl;
    1090         } else {
    1091                 cout << Verbose(1) << "Insertion rejected: Present object is " << (*(test2.first)).second.first << "." << endl;
    1092         }
    1093 
    1094         // show graphs
    1095         cout << "Showing Subgraph's contents, checking that it's sorted." << endl;
    1096         Graph::iterator A = Subgraphs.begin();
    1097         while (A !=     Subgraphs.end()) {
    1098                 cout << (*A).second.first << ": ";
    1099                 KeySet::iterator key = (*A).first.begin();
    1100                 comp = -1;
    1101                 while (key != (*A).first.end()) {
    1102                         if ((*key) > comp)
    1103                                 cout << (*key) << " ";
    1104                         else
    1105                                 cout << (*key) << "! ";
    1106                         comp = (*key);
    1107                         key++;
    1108                 }
    1109                 cout << endl;
    1110                 A++;
    1111         }
    1112         delete(mol);
     1054  // generate some KeySets
     1055  cout << "Generating KeySets." << endl;
     1056  KeySet TestSets[mol->AtomCount+1];
     1057  i=1;
     1058  while (Walker->next != mol->end) {
     1059    Walker = Walker->next;
     1060    for (int j=0;j<i;j++) {
     1061      TestSets[j].insert(Walker->nr);
     1062    }
     1063    i++;
     1064  }
     1065  cout << "Testing insertion of already present item in KeySets." << endl;
     1066  KeySetTestPair test;
     1067  test = TestSets[mol->AtomCount-1].insert(Walker->nr);
     1068  if (test.second) {
     1069    cout << Verbose(1) << "Insertion worked?!" << endl;
     1070  } else {
     1071    cout << Verbose(1) << "Insertion rejected: Present object is " << (*test.first) << "." << endl;
     1072  }
     1073  TestSets[mol->AtomCount].insert(mol->end->previous->nr);
     1074  TestSets[mol->AtomCount].insert(mol->end->previous->previous->previous->nr);
     1075
     1076  // constructing Graph structure
     1077  cout << "Generating Subgraph class." << endl;
     1078  Graph Subgraphs;
     1079
     1080  // insert KeySets into Subgraphs
     1081  cout << "Inserting KeySets into Subgraph class." << endl;
     1082  for (int j=0;j<mol->AtomCount;j++) {
     1083    Subgraphs.insert(GraphPair (TestSets[j],pair<int, double>(counter++, 1.)));
     1084  }
     1085  cout << "Testing insertion of already present item in Subgraph." << endl;
     1086  GraphTestPair test2;
     1087  test2 = Subgraphs.insert(GraphPair (TestSets[mol->AtomCount],pair<int, double>(counter++, 1.)));
     1088  if (test2.second) {
     1089    cout << Verbose(1) << "Insertion worked?!" << endl;
     1090  } else {
     1091    cout << Verbose(1) << "Insertion rejected: Present object is " << (*(test2.first)).second.first << "." << endl;
     1092  }
     1093
     1094  // show graphs
     1095  cout << "Showing Subgraph's contents, checking that it's sorted." << endl;
     1096  Graph::iterator A = Subgraphs.begin();
     1097  while (A !=  Subgraphs.end()) {
     1098    cout << (*A).second.first << ": ";
     1099    KeySet::iterator key = (*A).first.begin();
     1100    comp = -1;
     1101    while (key != (*A).first.end()) {
     1102      if ((*key) > comp)
     1103        cout << (*key) << " ";
     1104      else
     1105        cout << (*key) << "! ";
     1106      comp = (*key);
     1107      key++;
     1108    }
     1109    cout << endl;
     1110    A++;
     1111  }
     1112  delete(mol);
    11131113};
    11141114
     
    11211121static void SaveConfig(char *ConfigFileName, config *configuration, periodentafel *periode, MoleculeListClass *molecules)
    11221122{
    1123         char filename[MAXSTRINGSIZE];
    1124         ofstream output;
    1125         molecule *mol = new molecule(periode);
    1126 
    1127         // merge all molecules in MoleculeListClass into this molecule
    1128         int N = molecules->ListOfMolecules.size();
    1129         int *src = new int(N);
    1130         N=0;
    1131         for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
    1132           src[N++] = (*ListRunner)->IndexNr;
    1133         molecules->SimpleMultiAdd(mol, src, N);
    1134 
    1135         cout << Verbose(0) << "Storing configuration ... " << endl;
    1136         // get correct valence orbitals
    1137         mol->CalculateOrbitals(*configuration);
    1138         configuration->InitMaxMinStopStep = configuration->MaxMinStopStep = configuration->MaxPsiDouble;
    1139         strcpy(filename, ConfigFileName);
    1140         if (ConfigFileName != NULL) { // test the file name
    1141                 output.open(ConfigFileName, ios::trunc);
    1142         } else if (strlen(configuration->configname) != 0) {
    1143                 strcpy(filename, configuration->configname);
    1144                 output.open(configuration->configname, ios::trunc);
    1145                 } else {
    1146                         strcpy(filename, DEFAULTCONFIG);
    1147                         output.open(DEFAULTCONFIG, ios::trunc);
    1148                 }
    1149         output.close();
    1150         output.clear();
    1151         cout << Verbose(0) << "Saving of config file ";
    1152         if (configuration->Save(filename, periode, mol))
    1153                 cout << "successful." << endl;
    1154         else
    1155                 cout << "failed." << endl;
    1156 
    1157         // and save to xyz file
    1158         if (ConfigFileName != NULL) {
    1159                 strcpy(filename, ConfigFileName);
    1160                 strcat(filename, ".xyz");
    1161                 output.open(filename, ios::trunc);
    1162         }
    1163         if (output == NULL) {
    1164                 strcpy(filename,"main_pcp_linux");
    1165                 strcat(filename, ".xyz");
    1166                 output.open(filename, ios::trunc);
    1167         }
    1168         cout << Verbose(0) << "Saving of XYZ file ";
    1169         if (mol->MDSteps <= 1) {
    1170                 if (mol->OutputXYZ(&output))
    1171                         cout << "successful." << endl;
    1172                 else
    1173                         cout << "failed." << endl;
    1174         } else {
    1175                 if (mol->OutputTrajectoriesXYZ(&output))
    1176                         cout << "successful." << endl;
    1177                 else
    1178                         cout << "failed." << endl;
    1179         }
    1180         output.close();
    1181         output.clear();
    1182 
    1183         // and save as MPQC configuration
    1184         if (ConfigFileName != NULL)
    1185                 strcpy(filename, ConfigFileName);
    1186         if (output == NULL)
    1187                 strcpy(filename,"main_pcp_linux");
    1188         cout << Verbose(0) << "Saving as mpqc input ";
    1189         if (configuration->SaveMPQC(filename, mol))
    1190                 cout << "done." << endl;
    1191         else
    1192                 cout << "failed." << endl;
    1193 
    1194         if (!strcmp(configuration->configpath, configuration->GetDefaultPath())) {
    1195                 cerr << "WARNING: config is found under different path then stated in config file::defaultpath!" << endl;
    1196         }
    1197         delete(mol);
     1123  char filename[MAXSTRINGSIZE];
     1124  ofstream output;
     1125  molecule *mol = new molecule(periode);
     1126
     1127  // merge all molecules in MoleculeListClass into this molecule
     1128  int N = molecules->ListOfMolecules.size();
     1129  int *src = new int(N);
     1130  N=0;
     1131  for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++)
     1132    src[N++] = (*ListRunner)->IndexNr;
     1133  molecules->SimpleMultiAdd(mol, src, N);
     1134
     1135  cout << Verbose(0) << "Storing configuration ... " << endl;
     1136  // get correct valence orbitals
     1137  mol->CalculateOrbitals(*configuration);
     1138  configuration->InitMaxMinStopStep = configuration->MaxMinStopStep = configuration->MaxPsiDouble;
     1139  strcpy(filename, ConfigFileName);
     1140  if (ConfigFileName != NULL) { // test the file name
     1141    output.open(ConfigFileName, ios::trunc);
     1142  } else if (strlen(configuration->configname) != 0) {
     1143    strcpy(filename, configuration->configname);
     1144    output.open(configuration->configname, ios::trunc);
     1145    } else {
     1146      strcpy(filename, DEFAULTCONFIG);
     1147      output.open(DEFAULTCONFIG, ios::trunc);
     1148    }
     1149  output.close();
     1150  output.clear();
     1151  cout << Verbose(0) << "Saving of config file ";
     1152  if (configuration->Save(filename, periode, mol))
     1153    cout << "successful." << endl;
     1154  else
     1155    cout << "failed." << endl;
     1156
     1157  // and save to xyz file
     1158  if (ConfigFileName != NULL) {
     1159    strcpy(filename, ConfigFileName);
     1160    strcat(filename, ".xyz");
     1161    output.open(filename, ios::trunc);
     1162  }
     1163  if (output == NULL) {
     1164    strcpy(filename,"main_pcp_linux");
     1165    strcat(filename, ".xyz");
     1166    output.open(filename, ios::trunc);
     1167  }
     1168  cout << Verbose(0) << "Saving of XYZ file ";
     1169  if (mol->MDSteps <= 1) {
     1170    if (mol->OutputXYZ(&output))
     1171      cout << "successful." << endl;
     1172    else
     1173      cout << "failed." << endl;
     1174  } else {
     1175    if (mol->OutputTrajectoriesXYZ(&output))
     1176      cout << "successful." << endl;
     1177    else
     1178      cout << "failed." << endl;
     1179  }
     1180  output.close();
     1181  output.clear();
     1182
     1183  // and save as MPQC configuration
     1184  if (ConfigFileName != NULL)
     1185    strcpy(filename, ConfigFileName);
     1186  if (output == NULL)
     1187    strcpy(filename,"main_pcp_linux");
     1188  cout << Verbose(0) << "Saving as mpqc input ";
     1189  if (configuration->SaveMPQC(filename, mol))
     1190    cout << "done." << endl;
     1191  else
     1192    cout << "failed." << endl;
     1193
     1194  if (!strcmp(configuration->configpath, configuration->GetDefaultPath())) {
     1195    cerr << "WARNING: config is found under different path then stated in config file::defaultpath!" << endl;
     1196  }
     1197  delete(mol);
    11981198};
    11991199
     
    12101210static int ParseCommandLineOptions(int argc, char **argv, MoleculeListClass *&molecules, periodentafel *&periode, config& configuration, char *&ConfigFileName)
    12111211{
    1212         Vector x,y,z,n; // coordinates for absolute point in cell volume
    1213         double *factor; // unit factor if desired
    1214         ifstream test;
    1215         ofstream output;
    1216         string line;
    1217         atom *first;
    1218         bool SaveFlag = false;
    1219         int ExitFlag = 0;
    1220         int j;
    1221         double volume = 0.;
    1222         enum ConfigStatus config_present = absent;
    1223         clock_t start,end;
    1224         int argptr;
     1212  Vector x,y,z,n;  // coordinates for absolute point in cell volume
     1213  double *factor; // unit factor if desired
     1214  ifstream test;
     1215  ofstream output;
     1216  string line;
     1217  atom *first;
     1218  bool SaveFlag = false;
     1219  int ExitFlag = 0;
     1220  int j;
     1221  double volume = 0.;
     1222  enum ConfigStatus config_present = absent;
     1223  clock_t start,end;
     1224  int argptr;
    12251225  strncpy(configuration.databasepath, LocalPath, MAXSTRINGSIZE-1);
    12261226
    1227         // simply create a new molecule, wherein the config file is loaded and the manipulation takes place
    1228         molecule *mol = new molecule(periode);
    1229         molecules->insert(mol);
    1230 
    1231         if (argc > 1) { // config file specified as option
    1232                 // 1. : Parse options that just set variables or print help
    1233                 argptr = 1;
    1234                 do {
    1235                         if (argv[argptr][0] == '-') {
    1236                                 cout << Verbose(0) << "Recognized command line argument: " << argv[argptr][1] << ".\n";
    1237                                 argptr++;
    1238                                 switch(argv[argptr-1][1]) {
    1239                                         case 'h':
    1240                                         case 'H':
    1241                                         case '?':
    1242                                                 cout << "MoleCuilder suite" << endl << "==================" << endl << endl;
    1243                                                 cout << "Usage: " << argv[0] << "[config file] [-{acefpsthH?vfrp}] [further arguments]" << endl;
    1244                                                 cout << "or simply " << argv[0] << " without arguments for interactive session." << endl;
    1245                                                 cout << "\t-a Z x1 x2 x3\tAdd new atom of element Z at coordinates (x1,x2,x3)." << endl;
    1246                                                 cout << "\t-A <source>\tCreate adjacency list from bonds parsed from 'dbond'-style file." <<endl;
    1247                                                 cout << "\t-b xx xy xz yy yz zz\tCenter atoms in domain with given symmetric matrix of (xx,xy,xz,yy,yz,zz)." << endl;
    1248                                                 cout << "\t-B <basis>\tSetting basis to store to MPQC config files." << endl;
    1249                                                 cout << "\t-c x1 x2 x3\tCenter atoms in domain with a minimum distance to boundary of (x1,x2,x3)." << endl;
    1250                                                 cout << "\t-D <bond distance>\tDepth-First-Search Analysis of the molecule, giving cycles and tree/back edges." << endl;
    1251                                                 cout << "\t-O\tCenter atoms in origin." << endl;
    1252                                                 cout << "\t-d x1 x2 x3\tDuplicate cell along each axis by given factor." << endl;
    1253                                                 cout << "\t-e <file>\tSets the databases path to be parsed (default: ./)." << endl;
    1254                                                 cout << "\t-E <id> <Z>\tChange atom <id>'s element to <Z>, <id> begins at 0." << endl;
    1255                                                 cout << "\t-f/F <dist> <order>\tFragments the molecule in BOSSANOVA manner (with/out rings compressed) and stores config files in same dir as config (return code 0 - fragmented, 2 - no fragmentation necessary)." << endl;
    1256                                                 cout << "\t-h/-H/-?\tGive this help screen." << endl;
    1257                                                 cout << "\t-m <0/1>\tCalculate (0)/ Align in(1) PAS with greatest EV along z axis." << endl;
    1258                                                 cout << "\t-n\tFast parsing (i.e. no trajectories are looked for)." << endl;
    1259                                                 cout << "\t-N\tGet non-convex-envelope." << endl;
    1260                                                 cout << "\t-o <out>\tGet volume of the convex envelope (and store to tecplot file)." << endl;
    1261                                                 cout << "\t-p <file>\tParse given xyz file and create raw config file from it." << endl;
    1262                                                 cout << "\t-P <file>\tParse given forces file and append as an MD step to config file via Verlet." << endl;
    1263                                                 cout << "\t-r\t\tConvert file from an old pcp syntax." << endl;
    1264                                                 cout << "\t-t x1 x2 x3\tTranslate all atoms by this vector (x1,x2,x3)." << endl;
     1227  // simply create a new molecule, wherein the config file is loaded and the manipulation takes place
     1228  molecule *mol = new molecule(periode);
     1229  molecules->insert(mol);
     1230
     1231  if (argc > 1) { // config file specified as option
     1232    // 1. : Parse options that just set variables or print help
     1233    argptr = 1;
     1234    do {
     1235      if (argv[argptr][0] == '-') {
     1236        cout << Verbose(0) << "Recognized command line argument: " << argv[argptr][1] << ".\n";
     1237        argptr++;
     1238        switch(argv[argptr-1][1]) {
     1239          case 'h':
     1240          case 'H':
     1241          case '?':
     1242            cout << "MoleCuilder suite" << endl << "==================" << endl << endl;
     1243            cout << "Usage: " << argv[0] << "[config file] [-{acefpsthH?vfrp}] [further arguments]" << endl;
     1244            cout << "or simply " << argv[0] << " without arguments for interactive session." << endl;
     1245            cout << "\t-a Z x1 x2 x3\tAdd new atom of element Z at coordinates (x1,x2,x3)." << endl;
     1246            cout << "\t-A <source>\tCreate adjacency list from bonds parsed from 'dbond'-style file." <<endl;
     1247            cout << "\t-b xx xy xz yy yz zz\tCenter atoms in domain with given symmetric matrix of (xx,xy,xz,yy,yz,zz)." << endl;
     1248            cout << "\t-B <basis>\tSetting basis to store to MPQC config files." << endl;
     1249            cout << "\t-c x1 x2 x3\tCenter atoms in domain with a minimum distance to boundary of (x1,x2,x3)." << endl;
     1250            cout << "\t-D <bond distance>\tDepth-First-Search Analysis of the molecule, giving cycles and tree/back edges." << endl;
     1251            cout << "\t-O\tCenter atoms in origin." << endl;
     1252            cout << "\t-d x1 x2 x3\tDuplicate cell along each axis by given factor." << endl;
     1253            cout << "\t-e <file>\tSets the databases path to be parsed (default: ./)." << endl;
     1254            cout << "\t-E <id> <Z>\tChange atom <id>'s element to <Z>, <id> begins at 0." << endl;
     1255            cout << "\t-f/F <dist> <order>\tFragments the molecule in BOSSANOVA manner (with/out rings compressed) and stores config files in same dir as config (return code 0 - fragmented, 2 - no fragmentation necessary)." << endl;
     1256            cout << "\t-h/-H/-?\tGive this help screen." << endl;
     1257            cout << "\t-m <0/1>\tCalculate (0)/ Align in(1) PAS with greatest EV along z axis." << endl;
     1258            cout << "\t-n\tFast parsing (i.e. no trajectories are looked for)." << endl;
     1259            cout << "\t-N\tGet non-convex-envelope." << endl;
     1260            cout << "\t-o <out>\tGet volume of the convex envelope (and store to tecplot file)." << endl;
     1261            cout << "\t-p <file>\tParse given xyz file and create raw config file from it." << endl;
     1262            cout << "\t-P <file>\tParse given forces file and append as an MD step to config file via Verlet." << endl;
     1263            cout << "\t-r\t\tConvert file from an old pcp syntax." << endl;
     1264            cout << "\t-t x1 x2 x3\tTranslate all atoms by this vector (x1,x2,x3)." << endl;
    12651265            cout << "\t-T x1 x2 x3\tTranslate periodically all atoms by this vector (x1,x2,x3)." << endl;
    1266                                                 cout << "\t-S <file> Store temperatures from the config file in <file>." << endl;
    1267                                                 cout << "\t-s x1 x2 x3\tScale all atom coordinates by this vector (x1,x2,x3)." << endl;
    1268                                                 cout << "\t-u rho\tsuspend in water solution and output necessary cell lengths, average density rho and repetition." << endl;
    1269                                                 cout << "\t-v/-V\t\tGives version information." << endl;
    1270                                                 cout << "Note: config files must not begin with '-' !" << endl;
    1271                                                 delete(mol);
    1272                                                 delete(periode);
    1273                                                 return (1);
    1274                                                 break;
    1275                                         case 'v':
    1276                                         case 'V':
    1277                                                 cout << argv[0] << " " << VERSIONSTRING << endl;
    1278                                                 cout << "Build your own molecule position set." << endl;
    1279                                                 delete(mol);
    1280                                                 delete(periode);
    1281                                                 return (1);
    1282                                                 break;
    1283                                         case 'e':
    1284                                                 if ((argptr >= argc) || (argv[argptr][0] == '-')) {
    1285                                                         cerr << "Not enough or invalid arguments for specifying element db: -e <db file>" << endl;
    1286                                                 } else {
    1287                                                         cout << "Using " << argv[argptr] << " as elements database." << endl;
    1288                                                         strncpy (configuration.databasepath, argv[argptr], MAXSTRINGSIZE-1);
    1289                                                         argptr+=1;
    1290                                                 }
    1291                                                 break;
    1292                                         case 'n':
    1293                                                 cout << "I won't parse trajectories." << endl;
    1294                                                 configuration.FastParsing = true;
    1295                                                 break;
    1296                                         default:        // no match? Step on
    1297                                                 argptr++;
    1298                                                 break;
    1299                                 }
    1300                         } else
    1301                                 argptr++;
    1302                 } while (argptr < argc);
    1303 
    1304                 // 2. Parse the element database
    1305                 if (periode->LoadPeriodentafel(configuration.databasepath)) {
    1306                         cout << Verbose(0) << "Element list loaded successfully." << endl;
    1307                         //periode->Output((ofstream *)&cout);
    1308                 } else {
    1309                         cout << Verbose(0) << "Element list loading failed." << endl;
    1310                         return 1;
    1311                 }
    1312                 // 3. Find config file name and parse if possible
    1313                 if (argv[1][0] != '-') {
    1314                         cout << Verbose(0) << "Config file given." << endl;
    1315                         test.open(argv[1], ios::in);
    1316                         if (test == NULL) {
    1317                                 //return (1);
    1318                                 output.open(argv[1], ios::out);
    1319                                 if (output == NULL) {
    1320                                         cout << Verbose(1) << "Specified config file " << argv[1] << " not found." << endl;
    1321                                         config_present = absent;
    1322                                 } else {
    1323                                         cout << "Empty configuration file." << endl;
    1324                                         ConfigFileName = argv[1];
    1325                                         config_present = empty;
    1326                                         output.close();
    1327                                 }
    1328                         } else {
    1329                                 test.close();
    1330                                 ConfigFileName = argv[1];
    1331                                 cout << Verbose(1) << "Specified config file found, parsing ... ";
    1332                                 switch (configuration.TestSyntax(ConfigFileName, periode, mol)) {
    1333                                         case 1:
    1334                                                 cout << "new syntax." << endl;
    1335                                                 configuration.Load(ConfigFileName, periode, mol);
    1336                                                 config_present = present;
    1337                                                 break;
    1338                                         case 0:
    1339                                                 cout << "old syntax." << endl;
    1340                                                 configuration.LoadOld(ConfigFileName, periode, mol);
    1341                                                 config_present = present;
    1342                                                 break;
    1343                                         default:
    1344                                                 cout << "Unknown syntax or empty, yet present file." << endl;
    1345                                                 config_present = empty;
    1346                         }
    1347                         }
    1348                 } else
    1349                         config_present = absent;
    1350                 // 4. parse again through options, now for those depending on elements db and config presence
    1351                 argptr = 1;
    1352                 do {
    1353                         cout << "Current Command line argument: " << argv[argptr] << "." << endl;
    1354                         if (argv[argptr][0] == '-') {
    1355                                 argptr++;
    1356                                 if ((config_present == present) || (config_present == empty)) {
    1357                                         switch(argv[argptr-1][1]) {
    1358                                                 case 'p':
    1359                                                         ExitFlag = 1;
    1360                                                         if ((argptr >= argc) || (argv[argptr][0] == '-')) {
    1361                                                                 ExitFlag = 255;
    1362                                                                 cerr << "Not enough arguments for parsing: -p <xyz file>" << endl;
    1363                                                         } else {
    1364                                                                 SaveFlag = true;
    1365                                                                 cout << Verbose(1) << "Parsing xyz file for new atoms." << endl;
    1366                                                                 if (!mol->AddXYZFile(argv[argptr]))
    1367                                                                         cout << Verbose(2) << "File not found." << endl;
    1368                                                                 else {
    1369                                                                         cout << Verbose(2) << "File found and parsed." << endl;
    1370                                                                         config_present = present;
    1371                                                                 }
    1372                                                         }
    1373                                                         break;
    1374                                                 case 'a':
    1375                                                         ExitFlag = 1;
    1376                                                         if ((argptr >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr+1]))) {
    1377                                                                 ExitFlag = 255;
    1378                                                                 cerr << "Not enough or invalid arguments for adding atom: -a <element> <x> <y> <z>" << endl;
    1379                                                         } else {
    1380                                                                 SaveFlag = true;
    1381                                                                 cout << Verbose(1) << "Adding new atom with element " << argv[argptr] << " at (" << argv[argptr+1] << "," << argv[argptr+2] << "," << argv[argptr+3] << "), ";
    1382                                                                 first = new atom;
    1383                                                                 first->type = periode->FindElement(atoi(argv[argptr]));
    1384                                                                 if (first->type != NULL)
    1385                                                                         cout << Verbose(2) << "found element " << first->type->name << endl;
    1386                                                                 for (int i=NDIM;i--;)
    1387                                                                         first->x.x[i] = atof(argv[argptr+1+i]);
    1388                                                                 if (first->type != NULL) {
    1389                                                                         mol->AddAtom(first);    // add to molecule
    1390                                                                         if ((config_present == empty) && (mol->AtomCount != 0))
    1391                                                                                 config_present = present;
    1392                                                                 } else
    1393                                                                         cerr << Verbose(1) << "Could not find the specified element." << endl;
    1394                                                                 argptr+=4;
    1395                                                         }
    1396                                                         break;
    1397                                                 default:        // no match? Don't step on (this is done in next switch's default)
    1398                                                         break;
    1399                                         }
    1400                                 }
    1401                                 if (config_present == present) {
    1402                                         switch(argv[argptr-1][1]) {
    1403                                                 case 'B':
    1404                                                         if ((argptr >= argc) || (argv[argptr][0] == '-')) {
    1405                                                                 ExitFlag = 255;
    1406                                                                 cerr << "Not enough or invalid arguments given for setting MPQC basis: -B <basis name>" << endl;
    1407                                                         } else {
    1408                                                                 configuration.basis = argv[argptr];
    1409                                                                 cout << Verbose(1) << "Setting MPQC basis to " << configuration.basis << "." << endl;
    1410                                                                 argptr+=1;
    1411                                                         }
    1412                                                         break;
    1413                                                 case 'D':
    1414                                                         ExitFlag = 1;
    1415                                                         {
    1416                                                                 cout << Verbose(1) << "Depth-First-Search Analysis." << endl;
    1417                                                                 MoleculeLeafClass *Subgraphs = NULL;                    // list of subgraphs from DFS analysis
    1418                                                                 int *MinimumRingSize = new int[mol->AtomCount];
    1419                                                                 atom ***ListOfLocalAtoms = NULL;
    1420                                                                 int FragmentCounter = 0;
    1421                                                                 class StackClass<bond *> *BackEdgeStack = NULL;
    1422                                                                 class StackClass<bond *> *LocalBackEdgeStack = NULL;
    1423                                                                 mol->CreateAdjacencyList((ofstream *)&cout, atof(argv[argptr]), configuration.GetIsAngstroem());
    1424                                                                 mol->CreateListOfBondsPerAtom((ofstream *)&cout);
    1425                                                                 Subgraphs = mol->DepthFirstSearchAnalysis((ofstream *)&cout, BackEdgeStack);
    1426                                                                 if (Subgraphs != NULL) {
    1427                                                                         Subgraphs->next->FillBondStructureFromReference((ofstream *)&cout, mol, (FragmentCounter = 0), ListOfLocalAtoms, false);        // we want to keep the created ListOfLocalAtoms
    1428                                                                         while (Subgraphs->next != NULL) {
    1429                                                                                 Subgraphs = Subgraphs->next;
    1430                                                                                 LocalBackEdgeStack = new StackClass<bond *> (Subgraphs->Leaf->BondCount);
    1431                                                                                 Subgraphs->Leaf->PickLocalBackEdges((ofstream *)&cout, ListOfLocalAtoms[FragmentCounter++], BackEdgeStack, LocalBackEdgeStack);
    1432                                                                                 Subgraphs->Leaf->CyclicStructureAnalysis((ofstream *)&cout, BackEdgeStack, MinimumRingSize);
    1433                                                                                 delete(LocalBackEdgeStack);
    1434                                                                                 delete(Subgraphs->previous);
    1435                                                                         }
    1436                                                                         delete(Subgraphs);
    1437                                                                         for (int i=0;i<FragmentCounter;i++)
    1438                                                                                 Free((void **)&ListOfLocalAtoms[FragmentCounter], "ParseCommandLineOptions: **ListOfLocalAtoms[]");
    1439                                                                         Free((void **)&ListOfLocalAtoms, "ParseCommandLineOptions: ***ListOfLocalAtoms");
    1440                                                                 }
    1441                                                                 delete(BackEdgeStack);
    1442                                                                 delete[](MinimumRingSize);
    1443                                                         }
    1444                                                         //argptr+=1;
    1445                                                         break;
    1446                                                 case 'E':
    1447                                                         ExitFlag = 1;
    1448                                                         if ((argptr+1 >= argc) || (!IsValidNumber(argv[argptr])) || (argv[argptr+1][0] == '-')) {
    1449                                                                 ExitFlag = 255;
    1450                                                                 cerr << "Not enough or invalid arguments given for changing element: -E <atom nr.> <element>" << endl;
    1451                                                         } else {
    1452                                                                 SaveFlag = true;
    1453                                                                 cout << Verbose(1) << "Changing atom " << argv[argptr] << " to element " << argv[argptr+1] << "." << endl;
    1454                                                                 first = mol->FindAtom(atoi(argv[argptr]));
    1455                                                                 first->type = periode->FindElement(atoi(argv[argptr+1]));
    1456                                                                 argptr+=2;
    1457                                                         }
    1458                                                         break;
    1459                                                 case 'A':
    1460                                                         ExitFlag = 1;
    1461                                                         if ((argptr >= argc) || (argv[argptr][0] == '-')) {
    1462                                                                 ExitFlag =255;
    1463                                                                 cerr << "Missing source file for bonds in molecule: -A <bond sourcefile>" << endl;
    1464                                                         } else {
    1465                                                                 cout << "Parsing bonds from " << argv[argptr] << "." << endl;
    1466                                                                 ifstream *input = new ifstream(argv[argptr]);
    1467                                                                 mol->CreateAdjacencyList2((ofstream *)&cout, input);
    1468                                                                 input->close();
    1469                                                                 argptr+=1;
    1470                                                         }
    1471                                                         break;
    1472                                                 case 'N':
    1473                                                         ExitFlag = 1;
    1474                                                         if ((argptr+1 >= argc) || (argv[argptr+1][0] == '-')){
    1475                                                                 ExitFlag = 255;
    1476                                                                 cerr << "Not enough or invalid arguments given for non-convex envelope: -o <radius> <tecplot output file>" << endl;
    1477                                                         } else {
    1478                                                                 class Tesselation T;
    1479                                                                 string filename(argv[argptr+1]);
    1480                                                                 filename.append(".csv");
    1481                                                                 cout << Verbose(0) << "Evaluating non-convex envelope.";
    1482                                                                 cout << Verbose(1) << "Using rolling ball of radius " << atof(argv[argptr]) << " and storing tecplot data in " << argv[argptr+1] << "." << endl;
    1483                                                                 LinkedCell LCList(mol, atof(argv[argptr])*2.);
    1484                                                                 Find_non_convex_border((ofstream *)&cout, mol, &T, &LCList, argv[argptr+1], atof(argv[argptr]));
    1485                                                                 //FindDistributionOfEllipsoids((ofstream *)&cout, &T, &LCList, N, number, filename.c_str());
    1486                                                                 argptr+=2;
    1487                                                         }
    1488                                                         break;
    1489                                                 case 'S':
    1490                                                         ExitFlag = 1;
    1491                                                         if ((argptr >= argc) || (argv[argptr][0] == '-')) {
    1492                                                                 ExitFlag = 255;
    1493                                                                 cerr << "Not enough or invalid arguments given for storing tempature: -S <temperature file>" << endl;
    1494                                                         } else {
    1495                                                                 cout << Verbose(1) << "Storing temperatures in " << argv[argptr] << "." << endl;
    1496                                                                 ofstream *output = new ofstream(argv[argptr], ios::trunc);
    1497                                                                 if (!mol->OutputTemperatureFromTrajectories((ofstream *)&cout, 0, mol->MDSteps, output))
    1498                                                                         cout << Verbose(2) << "File could not be written." << endl;
    1499                                                                 else
    1500                                                                         cout << Verbose(2) << "File stored." << endl;
    1501                                                                 output->close();
    1502                                                                 delete(output);
    1503                                                                 argptr+=1;
    1504                                                         }
    1505                                                         break;
    1506                                                 case 'P':
    1507                                                         ExitFlag = 1;
    1508                                                         if ((argptr >= argc) || (argv[argptr][0] == '-')) {
    1509                                                                 ExitFlag = 255;
    1510                                                                 cerr << "Not enough or invalid arguments given for parsing and integrating forces: -P <forces file>" << endl;
    1511                                                         } else {
    1512                                                                 SaveFlag = true;
    1513                                                                 cout << Verbose(1) << "Parsing forces file and Verlet integrating." << endl;
    1514                                                                 if (!mol->VerletForceIntegration(argv[argptr], configuration.Deltat, configuration.GetIsAngstroem()))
    1515                                                                         cout << Verbose(2) << "File not found." << endl;
    1516                                                                 else
    1517                                                                         cout << Verbose(2) << "File found and parsed." << endl;
    1518                                                                 argptr+=1;
    1519                                                         }
    1520                                                         break;
    1521                                                 case 't':
    1522                                                         ExitFlag = 1;
    1523                                                         if ((argptr+2 >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) {
    1524                                                                 ExitFlag = 255;
    1525                                                                 cerr << "Not enough or invalid arguments given for translation: -t <x> <y> <z>" << endl;
    1526                                                         } else {
    1527                                                                 ExitFlag = 1;
    1528                                                                 SaveFlag = true;
    1529                                                                 cout << Verbose(1) << "Translating all ions to new origin." << endl;
    1530                                                                 for (int i=NDIM;i--;)
    1531                                                                         x.x[i] = atof(argv[argptr+i]);
    1532                                                                 mol->Translate((const Vector *)&x);
    1533                                                                 argptr+=3;
    1534                                                         }
    1535                                                         break;
     1266            cout << "\t-S <file> Store temperatures from the config file in <file>." << endl;
     1267            cout << "\t-s x1 x2 x3\tScale all atom coordinates by this vector (x1,x2,x3)." << endl;
     1268            cout << "\t-u rho\tsuspend in water solution and output necessary cell lengths, average density rho and repetition." << endl;
     1269            cout << "\t-v/-V\t\tGives version information." << endl;
     1270            cout << "Note: config files must not begin with '-' !" << endl;
     1271            delete(mol);
     1272            delete(periode);
     1273            return (1);
     1274            break;
     1275          case 'v':
     1276          case 'V':
     1277            cout << argv[0] << " " << VERSIONSTRING << endl;
     1278            cout << "Build your own molecule position set." << endl;
     1279            delete(mol);
     1280            delete(periode);
     1281            return (1);
     1282            break;
     1283          case 'e':
     1284            if ((argptr >= argc) || (argv[argptr][0] == '-')) {
     1285              cerr << "Not enough or invalid arguments for specifying element db: -e <db file>" << endl;
     1286            } else {
     1287              cout << "Using " << argv[argptr] << " as elements database." << endl;
     1288              strncpy (configuration.databasepath, argv[argptr], MAXSTRINGSIZE-1);
     1289              argptr+=1;
     1290            }
     1291            break;
     1292          case 'n':
     1293            cout << "I won't parse trajectories." << endl;
     1294            configuration.FastParsing = true;
     1295            break;
     1296          default:  // no match? Step on
     1297            argptr++;
     1298            break;
     1299        }
     1300      } else
     1301        argptr++;
     1302    } while (argptr < argc);
     1303
     1304    // 2. Parse the element database
     1305    if (periode->LoadPeriodentafel(configuration.databasepath)) {
     1306      cout << Verbose(0) << "Element list loaded successfully." << endl;
     1307      //periode->Output((ofstream *)&cout);
     1308    } else {
     1309      cout << Verbose(0) << "Element list loading failed." << endl;
     1310      return 1;
     1311    }
     1312    // 3. Find config file name and parse if possible
     1313    if (argv[1][0] != '-') {
     1314      cout << Verbose(0) << "Config file given." << endl;
     1315      test.open(argv[1], ios::in);
     1316      if (test == NULL) {
     1317        //return (1);
     1318        output.open(argv[1], ios::out);
     1319        if (output == NULL) {
     1320          cout << Verbose(1) << "Specified config file " << argv[1] << " not found." << endl;
     1321          config_present = absent;
     1322        } else {
     1323          cout << "Empty configuration file." << endl;
     1324          ConfigFileName = argv[1];
     1325          config_present = empty;
     1326          output.close();
     1327        }
     1328      } else {
     1329        test.close();
     1330        ConfigFileName = argv[1];
     1331        cout << Verbose(1) << "Specified config file found, parsing ... ";
     1332        switch (configuration.TestSyntax(ConfigFileName, periode, mol)) {
     1333          case 1:
     1334            cout << "new syntax." << endl;
     1335            configuration.Load(ConfigFileName, periode, mol);
     1336            config_present = present;
     1337            break;
     1338          case 0:
     1339            cout << "old syntax." << endl;
     1340            configuration.LoadOld(ConfigFileName, periode, mol);
     1341            config_present = present;
     1342            break;
     1343          default:
     1344            cout << "Unknown syntax or empty, yet present file." << endl;
     1345            config_present = empty;
     1346      }
     1347      }
     1348    } else
     1349      config_present = absent;
     1350    // 4. parse again through options, now for those depending on elements db and config presence
     1351    argptr = 1;
     1352    do {
     1353      cout << "Current Command line argument: " << argv[argptr] << "." << endl;
     1354      if (argv[argptr][0] == '-') {
     1355        argptr++;
     1356        if ((config_present == present) || (config_present == empty)) {
     1357          switch(argv[argptr-1][1]) {
     1358            case 'p':
     1359              ExitFlag = 1;
     1360              if ((argptr >= argc) || (argv[argptr][0] == '-')) {
     1361                ExitFlag = 255;
     1362                cerr << "Not enough arguments for parsing: -p <xyz file>" << endl;
     1363              } else {
     1364                SaveFlag = true;
     1365                cout << Verbose(1) << "Parsing xyz file for new atoms." << endl;
     1366                if (!mol->AddXYZFile(argv[argptr]))
     1367                  cout << Verbose(2) << "File not found." << endl;
     1368                else {
     1369                  cout << Verbose(2) << "File found and parsed." << endl;
     1370                  config_present = present;
     1371                }
     1372              }
     1373              break;
     1374            case 'a':
     1375              ExitFlag = 1;
     1376              if ((argptr >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr+1]))) {
     1377                ExitFlag = 255;
     1378                cerr << "Not enough or invalid arguments for adding atom: -a <element> <x> <y> <z>" << endl;
     1379              } else {
     1380                SaveFlag = true;
     1381                cout << Verbose(1) << "Adding new atom with element " << argv[argptr] << " at (" << argv[argptr+1] << "," << argv[argptr+2] << "," << argv[argptr+3] << "), ";
     1382                first = new atom;
     1383                first->type = periode->FindElement(atoi(argv[argptr]));
     1384                if (first->type != NULL)
     1385                  cout << Verbose(2) << "found element " << first->type->name << endl;
     1386                for (int i=NDIM;i--;)
     1387                  first->x.x[i] = atof(argv[argptr+1+i]);
     1388                if (first->type != NULL) {
     1389                  mol->AddAtom(first);  // add to molecule
     1390                  if ((config_present == empty) && (mol->AtomCount != 0))
     1391                    config_present = present;
     1392                } else
     1393                  cerr << Verbose(1) << "Could not find the specified element." << endl;
     1394                argptr+=4;
     1395              }
     1396              break;
     1397            default:  // no match? Don't step on (this is done in next switch's default)
     1398              break;
     1399          }
     1400        }
     1401        if (config_present == present) {
     1402          switch(argv[argptr-1][1]) {
     1403            case 'B':
     1404              if ((argptr >= argc) || (argv[argptr][0] == '-')) {
     1405                ExitFlag = 255;
     1406                cerr << "Not enough or invalid arguments given for setting MPQC basis: -B <basis name>" << endl;
     1407              } else {
     1408                configuration.basis = argv[argptr];
     1409                cout << Verbose(1) << "Setting MPQC basis to " << configuration.basis << "." << endl;
     1410                argptr+=1;
     1411              }
     1412              break;
     1413            case 'D':
     1414              ExitFlag = 1;
     1415              {
     1416                cout << Verbose(1) << "Depth-First-Search Analysis." << endl;
     1417                MoleculeLeafClass *Subgraphs = NULL;      // list of subgraphs from DFS analysis
     1418                int *MinimumRingSize = new int[mol->AtomCount];
     1419                atom ***ListOfLocalAtoms = NULL;
     1420                int FragmentCounter = 0;
     1421                class StackClass<bond *> *BackEdgeStack = NULL;
     1422                class StackClass<bond *> *LocalBackEdgeStack = NULL;
     1423                mol->CreateAdjacencyList((ofstream *)&cout, atof(argv[argptr]), configuration.GetIsAngstroem());
     1424                mol->CreateListOfBondsPerAtom((ofstream *)&cout);
     1425                Subgraphs = mol->DepthFirstSearchAnalysis((ofstream *)&cout, BackEdgeStack);
     1426                if (Subgraphs != NULL) {
     1427                  Subgraphs->next->FillBondStructureFromReference((ofstream *)&cout, mol, (FragmentCounter = 0), ListOfLocalAtoms, false);  // we want to keep the created ListOfLocalAtoms
     1428                  while (Subgraphs->next != NULL) {
     1429                    Subgraphs = Subgraphs->next;
     1430                    LocalBackEdgeStack = new StackClass<bond *> (Subgraphs->Leaf->BondCount);
     1431                    Subgraphs->Leaf->PickLocalBackEdges((ofstream *)&cout, ListOfLocalAtoms[FragmentCounter++], BackEdgeStack, LocalBackEdgeStack);
     1432                    Subgraphs->Leaf->CyclicStructureAnalysis((ofstream *)&cout, BackEdgeStack, MinimumRingSize);
     1433                    delete(LocalBackEdgeStack);
     1434                    delete(Subgraphs->previous);
     1435                  }
     1436                  delete(Subgraphs);
     1437                  for (int i=0;i<FragmentCounter;i++)
     1438                    Free((void **)&ListOfLocalAtoms[FragmentCounter], "ParseCommandLineOptions: **ListOfLocalAtoms[]");
     1439                  Free((void **)&ListOfLocalAtoms, "ParseCommandLineOptions: ***ListOfLocalAtoms");
     1440                }
     1441                delete(BackEdgeStack);
     1442                delete[](MinimumRingSize);
     1443              }
     1444              //argptr+=1;
     1445              break;
     1446            case 'E':
     1447              ExitFlag = 1;
     1448              if ((argptr+1 >= argc) || (!IsValidNumber(argv[argptr])) || (argv[argptr+1][0] == '-')) {
     1449                ExitFlag = 255;
     1450                cerr << "Not enough or invalid arguments given for changing element: -E <atom nr.> <element>" << endl;
     1451              } else {
     1452                SaveFlag = true;
     1453                cout << Verbose(1) << "Changing atom " << argv[argptr] << " to element " << argv[argptr+1] << "." << endl;
     1454                first = mol->FindAtom(atoi(argv[argptr]));
     1455                first->type = periode->FindElement(atoi(argv[argptr+1]));
     1456                argptr+=2;
     1457              }
     1458              break;
     1459            case 'A':
     1460              ExitFlag = 1;
     1461              if ((argptr >= argc) || (argv[argptr][0] == '-')) {
     1462                ExitFlag =255;
     1463                cerr << "Missing source file for bonds in molecule: -A <bond sourcefile>" << endl;
     1464              } else {
     1465                cout << "Parsing bonds from " << argv[argptr] << "." << endl;
     1466                ifstream *input = new ifstream(argv[argptr]);
     1467                mol->CreateAdjacencyList2((ofstream *)&cout, input);
     1468                input->close();
     1469                argptr+=1;
     1470              }
     1471              break;
     1472            case 'N':
     1473              ExitFlag = 1;
     1474              if ((argptr+1 >= argc) || (argv[argptr+1][0] == '-')){
     1475                ExitFlag = 255;
     1476                cerr << "Not enough or invalid arguments given for non-convex envelope: -o <radius> <tecplot output file>" << endl;
     1477              } else {
     1478                class Tesselation T;
     1479                string filename(argv[argptr+1]);
     1480                filename.append(".csv");
     1481                cout << Verbose(0) << "Evaluating non-convex envelope.";
     1482                cout << Verbose(1) << "Using rolling ball of radius " << atof(argv[argptr]) << " and storing tecplot data in " << argv[argptr+1] << "." << endl;
     1483                LinkedCell LCList(mol, atof(argv[argptr])*2.);
     1484                Find_non_convex_border((ofstream *)&cout, mol, &T, &LCList, argv[argptr+1], atof(argv[argptr]));
     1485                //FindDistributionOfEllipsoids((ofstream *)&cout, &T, &LCList, N, number, filename.c_str());
     1486                argptr+=2;
     1487              }
     1488              break;
     1489            case 'S':
     1490              ExitFlag = 1;
     1491              if ((argptr >= argc) || (argv[argptr][0] == '-')) {
     1492                ExitFlag = 255;
     1493                cerr << "Not enough or invalid arguments given for storing tempature: -S <temperature file>" << endl;
     1494              } else {
     1495                cout << Verbose(1) << "Storing temperatures in " << argv[argptr] << "." << endl;
     1496                ofstream *output = new ofstream(argv[argptr], ios::trunc);
     1497                if (!mol->OutputTemperatureFromTrajectories((ofstream *)&cout, 0, mol->MDSteps, output))
     1498                  cout << Verbose(2) << "File could not be written." << endl;
     1499                else
     1500                  cout << Verbose(2) << "File stored." << endl;
     1501                output->close();
     1502                delete(output);
     1503                argptr+=1;
     1504              }
     1505              break;
     1506            case 'P':
     1507              ExitFlag = 1;
     1508              if ((argptr >= argc) || (argv[argptr][0] == '-')) {
     1509                ExitFlag = 255;
     1510                cerr << "Not enough or invalid arguments given for parsing and integrating forces: -P <forces file>" << endl;
     1511              } else {
     1512                SaveFlag = true;
     1513                cout << Verbose(1) << "Parsing forces file and Verlet integrating." << endl;
     1514                if (!mol->VerletForceIntegration(argv[argptr], configuration.Deltat, configuration.GetIsAngstroem()))
     1515                  cout << Verbose(2) << "File not found." << endl;
     1516                else
     1517                  cout << Verbose(2) << "File found and parsed." << endl;
     1518                argptr+=1;
     1519              }
     1520              break;
     1521            case 't':
     1522              ExitFlag = 1;
     1523              if ((argptr+2 >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) {
     1524                ExitFlag = 255;
     1525                cerr << "Not enough or invalid arguments given for translation: -t <x> <y> <z>" << endl;
     1526              } else {
     1527                ExitFlag = 1;
     1528                SaveFlag = true;
     1529                cout << Verbose(1) << "Translating all ions to new origin." << endl;
     1530                for (int i=NDIM;i--;)
     1531                  x.x[i] = atof(argv[argptr+i]);
     1532                mol->Translate((const Vector *)&x);
     1533                argptr+=3;
     1534              }
     1535              break;
    15361536            case 'T':
    15371537              ExitFlag = 1;
     
    15491549              }
    15501550              break;
    1551                                                 case 's':
    1552                                                         ExitFlag = 1;
    1553                                                         if ((argptr >= argc) || (!IsValidNumber(argv[argptr])) ) {
    1554                                                                 ExitFlag = 255;
    1555                                                                 cerr << "Not enough or invalid arguments given for scaling: -s <factor/[factor_x]> [factor_y] [factor_z]" << endl;
    1556                                                         } else {
    1557                                                                 SaveFlag = true;
    1558                                                                 j = -1;
    1559                                                                 cout << Verbose(1) << "Scaling all ion positions by factor." << endl;
    1560                                                                 factor = new double[NDIM];
    1561                                                                 factor[0] = atof(argv[argptr]);
    1562                                                                 if ((argptr < argc) && (IsValidNumber(argv[argptr])))
    1563                                                                         argptr++;
    1564                                                                 factor[1] = atof(argv[argptr]);
    1565                                                                 if ((argptr < argc) && (IsValidNumber(argv[argptr])))
    1566                                                                         argptr++;
    1567                                                                 factor[2] = atof(argv[argptr]);
    1568                                                                 mol->Scale(&factor);
    1569                                                                 for (int i=0;i<NDIM;i++) {
    1570                                                                         j += i+1;
    1571                                                                         x.x[i] = atof(argv[NDIM+i]);
    1572                                                                         mol->cell_size[j]*=factor[i];
    1573                                                                 }
    1574                                                                 delete[](factor);
    1575                                                                 argptr+=1;
    1576                                                         }
    1577                                                         break;
    1578                                                 case 'b':
    1579                                                         ExitFlag = 1;
    1580                                                         if ((argptr+5 >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) || (!IsValidNumber(argv[argptr+3])) || (!IsValidNumber(argv[argptr+4])) || (!IsValidNumber(argv[argptr+5])) ) {
    1581                                                                 ExitFlag = 255;
    1582                                                                 cerr << "Not enough or invalid arguments given for centering in box: -b <xx> <xy> <xz> <yy> <yz> <zz>" << endl;
    1583                                                         } else {
    1584                                                                 SaveFlag = true;
    1585                                                                 cout << Verbose(1) << "Centering atoms in config file within given simulation box." << endl;
    1586                                                                 for (int i=0;i<6;i++) {
    1587                                                                         mol->cell_size[i] = atof(argv[argptr+i]);
    1588                                                                 }
    1589                                                                 // center
    1590                                                                 mol->CenterInBox((ofstream *)&cout);
     1551            case 's':
     1552              ExitFlag = 1;
     1553              if ((argptr >= argc) || (!IsValidNumber(argv[argptr])) ) {
     1554                ExitFlag = 255;
     1555                cerr << "Not enough or invalid arguments given for scaling: -s <factor/[factor_x]> [factor_y] [factor_z]" << endl;
     1556              } else {
     1557                SaveFlag = true;
     1558                j = -1;
     1559                cout << Verbose(1) << "Scaling all ion positions by factor." << endl;
     1560                factor = new double[NDIM];
     1561                factor[0] = atof(argv[argptr]);
     1562                if ((argptr < argc) && (IsValidNumber(argv[argptr])))
     1563                  argptr++;
     1564                factor[1] = atof(argv[argptr]);
     1565                if ((argptr < argc) && (IsValidNumber(argv[argptr])))
     1566                  argptr++;
     1567                factor[2] = atof(argv[argptr]);
     1568                mol->Scale(&factor);
     1569                for (int i=0;i<NDIM;i++) {
     1570                  j += i+1;
     1571                  x.x[i] = atof(argv[NDIM+i]);
     1572                  mol->cell_size[j]*=factor[i];
     1573                }
     1574                delete[](factor);
     1575                argptr+=1;
     1576              }
     1577              break;
     1578            case 'b':
     1579              ExitFlag = 1;
     1580              if ((argptr+5 >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) || (!IsValidNumber(argv[argptr+3])) || (!IsValidNumber(argv[argptr+4])) || (!IsValidNumber(argv[argptr+5])) ) {
     1581                ExitFlag = 255;
     1582                cerr << "Not enough or invalid arguments given for centering in box: -b <xx> <xy> <xz> <yy> <yz> <zz>" << endl;
     1583              } else {
     1584                SaveFlag = true;
     1585                cout << Verbose(1) << "Centering atoms in config file within given simulation box." << endl;
     1586                for (int i=0;i<6;i++) {
     1587                  mol->cell_size[i] = atof(argv[argptr+i]);
     1588                }
     1589                // center
     1590                mol->CenterInBox((ofstream *)&cout);
    15911591                argptr+=6;
    1592                                                         }
    1593                                                         break;
    1594                                                 case 'c':
    1595                                                         ExitFlag = 1;
    1596                                                         if ((argptr+2 >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) {
    1597                                                                 ExitFlag = 255;
    1598                                                                 cerr << "Not enough or invalid arguments given for centering with boundary: -c <boundary_x> <boundary_y> <boundary_z>" << endl;
    1599                                                         } else {
    1600                                                                 SaveFlag = true;
    1601                                                                 j = -1;
    1602                                                                 cout << Verbose(1) << "Centering atoms in config file within given additional boundary." << endl;
    1603                                                                 // make every coordinate positive
    1604                                                                 mol->CenterEdge((ofstream *)&cout, &x);
    1605                                                                 // update Box of atoms by boundary
    1606                                                                 mol->SetBoxDimension(&x);
    1607                                                                 // translate each coordinate by boundary
    1608                                                                 j=-1;
    1609                                                                 for (int i=0;i<NDIM;i++) {
    1610                                                                         j += i+1;
    1611                                                                         x.x[i] = atof(argv[argptr++]);
    1612                                                                         mol->cell_size[j] += x.x[i]*2.;
    1613                                                                 }
    1614                                                                 mol->Translate((const Vector *)&x);
     1592              }
     1593              break;
     1594            case 'c':
     1595              ExitFlag = 1;
     1596              if ((argptr+2 >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) {
     1597                ExitFlag = 255;
     1598                cerr << "Not enough or invalid arguments given for centering with boundary: -c <boundary_x> <boundary_y> <boundary_z>" << endl;
     1599              } else {
     1600                SaveFlag = true;
     1601                j = -1;
     1602                cout << Verbose(1) << "Centering atoms in config file within given additional boundary." << endl;
     1603                // make every coordinate positive
     1604                mol->CenterEdge((ofstream *)&cout, &x);
     1605                // update Box of atoms by boundary
     1606                mol->SetBoxDimension(&x);
     1607                // translate each coordinate by boundary
     1608                j=-1;
     1609                for (int i=0;i<NDIM;i++) {
     1610                  j += i+1;
     1611                  x.x[i] = atof(argv[argptr++]);
     1612                  mol->cell_size[j] += x.x[i]*2.;
     1613                }
     1614                mol->Translate((const Vector *)&x);
    16151615                argptr+=3;
    1616                                                         }
    1617                                                         break;
    1618                                                 case 'O':
    1619                                                         ExitFlag = 1;
    1620                                                         SaveFlag = true;
    1621                                                         cout << Verbose(1) << "Centering atoms in origin." << endl;
    1622                                                         mol->CenterOrigin((ofstream *)&cout, &x);
    1623                                                         mol->SetBoxDimension(&x);
     1616              }
     1617              break;
     1618            case 'O':
     1619              ExitFlag = 1;
     1620              SaveFlag = true;
     1621              cout << Verbose(1) << "Centering atoms in origin." << endl;
     1622              mol->CenterOrigin((ofstream *)&cout, &x);
     1623              mol->SetBoxDimension(&x);
    16241624              argptr+=0;
    1625                                                         break;
    1626                                                 case 'r':
    1627                                                         ExitFlag = 1;
    1628                                                         SaveFlag = true;
    1629                                                         cout << Verbose(1) << "Converting config file from supposed old to new syntax." << endl;
    1630                                                         break;
    1631                                                 case 'F':
    1632                                                 case 'f':
    1633                                                         ExitFlag = 1;
    1634                                                         if ((argptr+1 >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1]))) {
    1635                                                                 ExitFlag = 255;
    1636                                                                 cerr << "Not enough or invalid arguments for fragmentation: -f <max. bond distance> <bond order>" << endl;
    1637                                                         } else {
    1638                                                                 cout << "Fragmenting molecule with bond distance " << argv[argptr] << " angstroem, order of " << argv[argptr+1] << "." << endl;
    1639                                                                 cout << Verbose(0) << "Creating connection matrix..." << endl;
    1640                                                                 start = clock();
    1641                                                                 mol->CreateAdjacencyList((ofstream *)&cout, atof(argv[argptr++]), configuration.GetIsAngstroem());
    1642                                                                 cout << Verbose(0) << "Fragmenting molecule with current connection matrix ..." << endl;
    1643                                                                 if (mol->first->next != mol->last) {
    1644                                                                         ExitFlag = mol->FragmentMolecule((ofstream *)&cout, atoi(argv[argptr]), &configuration);
    1645                                                                 }
    1646                                                                 end = clock();
    1647                                                                 cout << Verbose(0) << "Clocks for this operation: " << (end-start) << ", time: " << ((double)(end-start)/CLOCKS_PER_SEC) << "s." << endl;
    1648                                                                 argptr+=2;
    1649                                                         }
    1650                                                         break;
    1651                                                 case 'm':
    1652                                                         ExitFlag = 1;
    1653                                                         j = atoi(argv[argptr++]);
    1654                                                         if ((j<0) || (j>1)) {
    1655                                                                 cerr << Verbose(1) << "ERROR: Argument of '-m' should be either 0 for no-rotate or 1 for rotate." << endl;
    1656                                                                 j = 0;
    1657                                                         }
    1658                                                         if (j) {
    1659                                                                 SaveFlag = true;
    1660                                                                 cout << Verbose(0) << "Converting to prinicipal axis system." << endl;
    1661                                                         } else
    1662                                                                 cout << Verbose(0) << "Evaluating prinicipal axis." << endl;
    1663                                                         mol->PrincipalAxisSystem((ofstream *)&cout, (bool)j);
    1664                                                         break;
    1665                                                 case 'o':
    1666                                                         ExitFlag = 1;
    1667                                                         if ((argptr >= argc) || (argv[argptr][0] == '-')){
    1668                                                                 ExitFlag = 255;
    1669                                                                 cerr << "Not enough or invalid arguments given for convex envelope: -o <tecplot output file>" << endl;
    1670                                                         } else {
    1671                                                                 cout << Verbose(0) << "Evaluating volume of the convex envelope.";
    1672                                                                 cout << Verbose(1) << "Storing tecplot data in " << argv[argptr] << "." << endl;
    1673                                                                 VolumeOfConvexEnvelope((ofstream *)&cout, argv[argptr], &configuration, NULL, mol);
    1674                                                                 argptr+=1;
    1675                                                         }
    1676                                                         break;
    1677                                                 case 'U':
    1678                                                         ExitFlag = 1;
    1679                                                         if ((argptr+1 >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) ) {
    1680                                                                 ExitFlag = 255;
    1681                                                                 cerr << "Not enough or invalid arguments given for suspension with specified volume: -U <volume> <density>" << endl;
    1682                                                                 volume = -1; // for case 'u': don't print error again
    1683                                                         } else {
    1684                                                                 volume = atof(argv[argptr++]);
    1685                                                                 cout << Verbose(0) << "Using " << volume << " angstrom^3 as the volume instead of convex envelope one's." << endl;
    1686                                                         }
    1687                                                 case 'u':
    1688                                                         ExitFlag = 1;
    1689                                                         if ((argptr >= argc) || (!IsValidNumber(argv[argptr])) ) {
    1690                                                                 if (volume != -1)
    1691                                                                         ExitFlag = 255;
    1692                                                                         cerr << "Not enough arguments given for suspension: -u <density>" << endl;
    1693                                                         } else {
    1694                                                                 double density;
    1695                                                                 SaveFlag = true;
    1696                                                                 cout << Verbose(0) << "Evaluating necessary cell volume for a cluster suspended in water.";
    1697                                                                 density = atof(argv[argptr++]);
    1698                                                                 if (density < 1.0) {
    1699                                                                         cerr << Verbose(0) << "Density must be greater than 1.0g/cm^3 !" << endl;
    1700                                                                         density = 1.3;
    1701                                                                 }
    1702 //                                                              for(int i=0;i<NDIM;i++) {
    1703 //                                                                      repetition[i] = atoi(argv[argptr++]);
    1704 //                                                                      if (repetition[i] < 1)
    1705 //                                                                              cerr << Verbose(0) << "ERROR: repetition value must be greater 1!" << endl;
    1706 //                                                                      repetition[i] = 1;
    1707 //                                                              }
    1708                                                                 PrepareClustersinWater((ofstream *)&cout, &configuration, mol, volume, density);        // if volume == 0, will calculate from ConvexEnvelope
    1709                                                         }
    1710                                                         break;
    1711                                                 case 'd':
    1712                                                         ExitFlag = 1;
    1713                                                         if ((argptr+2 >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) {
    1714                                                                 ExitFlag = 255;
    1715                                                                 cerr << "Not enough or invalid arguments given for repeating cells: -d <repeat_x> <repeat_y> <repeat_z>" << endl;
    1716                                                         } else {
    1717                                                                 SaveFlag = true;
    1718                                                                 for (int axis = 1; axis <= NDIM; axis++) {
    1719                                                                         int faktor = atoi(argv[argptr++]);
    1720                                                                         int count;
    1721                                                                         element ** Elements;
    1722                                                                         Vector ** vectors;
    1723                                                                         if (faktor < 1) {
    1724                                                                                 cerr << Verbose(0) << "ERROR: Repetition faktor mus be greater than 1!" << endl;
    1725                                                                                 faktor = 1;
    1726                                                                         }
    1727                                                                         mol->CountAtoms((ofstream *)&cout);     // recount atoms
    1728                                                                         if (mol->AtomCount != 0) {      // if there is more than none
    1729                                                                                 count = mol->AtomCount; // is changed becausing of adding, thus has to be stored away beforehand
    1730                                                                                 Elements = new element *[count];
    1731                                                                                 vectors = new Vector *[count];
    1732                                                                                 j = 0;
    1733                                                                                 first = mol->start;
    1734                                                                                 while (first->next != mol->end) {       // make a list of all atoms with coordinates and element
    1735                                                                                         first = first->next;
    1736                                                                                         Elements[j] = first->type;
    1737                                                                                         vectors[j] = &first->x;
    1738                                                                                         j++;
    1739                                                                                 }
    1740                                                                                 if (count != j)
    1741                                                                                         cout << Verbose(0) << "ERROR: AtomCount " << count << " is not equal to number of atoms in molecule " << j << "!" << endl;
    1742                                                                                 x.Zero();
    1743                                                                                 y.Zero();
    1744                                                                                 y.x[abs(axis)-1] = mol->cell_size[(abs(axis) == 2) ? 2 : ((abs(axis) == 3) ? 5 : 0)] * abs(axis)/axis; // last term is for sign, first is for magnitude
    1745                                                                                 for (int i=1;i<faktor;i++) {    // then add this list with respective translation factor times
    1746                                                                                         x.AddVector(&y); // per factor one cell width further
    1747                                                                                         for (int k=count;k--;) { // go through every atom of the original cell
    1748                                                                                                 first = new atom(); // create a new body
    1749                                                                                                 first->x.CopyVector(vectors[k]);        // use coordinate of original atom
    1750                                                                                                 first->x.AddVector(&x);                 // translate the coordinates
    1751                                                                                                 first->type = Elements[k];      // insert original element
    1752                                                                                                 mol->AddAtom(first);                            // and add to the molecule (which increments ElementsInMolecule, AtomCount, ...)
    1753                                                                                         }
    1754                                                                                 }
    1755                                                                                 // free memory
    1756                                                                                 delete[](Elements);
    1757                                                                                 delete[](vectors);
    1758                                                                                 // correct cell size
    1759                                                                                 if (axis < 0) { // if sign was negative, we have to translate everything
    1760                                                                                         x.Zero();
    1761                                                                                         x.AddVector(&y);
    1762                                                                                         x.Scale(-(faktor-1));
    1763                                                                                         mol->Translate(&x);
    1764                                                                                 }
    1765                                                                                 mol->cell_size[(abs(axis) == 2) ? 2 : ((abs(axis) == 3) ? 5 : 0)] *= faktor;
    1766                                                                         }
    1767                                                                 }
    1768                                                         }
    1769                                                         break;
    1770                                                 default:        // no match? Step on
    1771                                                         if ((argptr < argc) && (argv[argptr][0] != '-')) // if it started with a '-' we've already made a step!
    1772                                                                 argptr++;
    1773                                                         break;
    1774                                         }
    1775                                 }
    1776                         } else argptr++;
    1777                 } while (argptr < argc);
    1778                 if (SaveFlag)
    1779                         SaveConfig(ConfigFileName, &configuration, periode, molecules);
    1780         } else {        // no arguments, hence scan the elements db
    1781                 if (periode->LoadPeriodentafel(configuration.databasepath))
    1782                         cout << Verbose(0) << "Element list loaded successfully." << endl;
    1783                 else
    1784                         cout << Verbose(0) << "Element list loading failed." << endl;
    1785                 configuration.RetrieveConfigPathAndName("main_pcp_linux");
    1786         }
    1787         return(ExitFlag);
     1625              break;
     1626            case 'r':
     1627              ExitFlag = 1;
     1628              SaveFlag = true;
     1629              cout << Verbose(1) << "Converting config file from supposed old to new syntax." << endl;
     1630              break;
     1631            case 'F':
     1632            case 'f':
     1633              ExitFlag = 1;
     1634              if ((argptr+1 >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1]))) {
     1635                ExitFlag = 255;
     1636                cerr << "Not enough or invalid arguments for fragmentation: -f <max. bond distance> <bond order>" << endl;
     1637              } else {
     1638                cout << "Fragmenting molecule with bond distance " << argv[argptr] << " angstroem, order of " << argv[argptr+1] << "." << endl;
     1639                cout << Verbose(0) << "Creating connection matrix..." << endl;
     1640                start = clock();
     1641                mol->CreateAdjacencyList((ofstream *)&cout, atof(argv[argptr++]), configuration.GetIsAngstroem());
     1642                cout << Verbose(0) << "Fragmenting molecule with current connection matrix ..." << endl;
     1643                if (mol->first->next != mol->last) {
     1644                  ExitFlag = mol->FragmentMolecule((ofstream *)&cout, atoi(argv[argptr]), &configuration);
     1645                }
     1646                end = clock();
     1647                cout << Verbose(0) << "Clocks for this operation: " << (end-start) << ", time: " << ((double)(end-start)/CLOCKS_PER_SEC) << "s." << endl;
     1648                argptr+=2;
     1649              }
     1650              break;
     1651            case 'm':
     1652              ExitFlag = 1;
     1653              j = atoi(argv[argptr++]);
     1654              if ((j<0) || (j>1)) {
     1655                cerr << Verbose(1) << "ERROR: Argument of '-m' should be either 0 for no-rotate or 1 for rotate." << endl;
     1656                j = 0;
     1657              }
     1658              if (j) {
     1659                SaveFlag = true;
     1660                cout << Verbose(0) << "Converting to prinicipal axis system." << endl;
     1661              } else
     1662                cout << Verbose(0) << "Evaluating prinicipal axis." << endl;
     1663              mol->PrincipalAxisSystem((ofstream *)&cout, (bool)j);
     1664              break;
     1665            case 'o':
     1666              ExitFlag = 1;
     1667              if ((argptr >= argc) || (argv[argptr][0] == '-')){
     1668                ExitFlag = 255;
     1669                cerr << "Not enough or invalid arguments given for convex envelope: -o <tecplot output file>" << endl;
     1670              } else {
     1671                cout << Verbose(0) << "Evaluating volume of the convex envelope.";
     1672                cout << Verbose(1) << "Storing tecplot data in " << argv[argptr] << "." << endl;
     1673                VolumeOfConvexEnvelope((ofstream *)&cout, argv[argptr], &configuration, NULL, mol);
     1674                argptr+=1;
     1675              }
     1676              break;
     1677            case 'U':
     1678              ExitFlag = 1;
     1679              if ((argptr+1 >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) ) {
     1680                ExitFlag = 255;
     1681                cerr << "Not enough or invalid arguments given for suspension with specified volume: -U <volume> <density>" << endl;
     1682                volume = -1; // for case 'u': don't print error again
     1683              } else {
     1684                volume = atof(argv[argptr++]);
     1685                cout << Verbose(0) << "Using " << volume << " angstrom^3 as the volume instead of convex envelope one's." << endl;
     1686              }
     1687            case 'u':
     1688              ExitFlag = 1;
     1689              if ((argptr >= argc) || (!IsValidNumber(argv[argptr])) ) {
     1690                if (volume != -1)
     1691                  ExitFlag = 255;
     1692                  cerr << "Not enough arguments given for suspension: -u <density>" << endl;
     1693              } else {
     1694                double density;
     1695                SaveFlag = true;
     1696                cout << Verbose(0) << "Evaluating necessary cell volume for a cluster suspended in water.";
     1697                density = atof(argv[argptr++]);
     1698                if (density < 1.0) {
     1699                  cerr << Verbose(0) << "Density must be greater than 1.0g/cm^3 !" << endl;
     1700                  density = 1.3;
     1701                }
     1702//                for(int i=0;i<NDIM;i++) {
     1703//                  repetition[i] = atoi(argv[argptr++]);
     1704//                  if (repetition[i] < 1)
     1705//                    cerr << Verbose(0) << "ERROR: repetition value must be greater 1!" << endl;
     1706//                  repetition[i] = 1;
     1707//                }
     1708                PrepareClustersinWater((ofstream *)&cout, &configuration, mol, volume, density);  // if volume == 0, will calculate from ConvexEnvelope
     1709              }
     1710              break;
     1711            case 'd':
     1712              ExitFlag = 1;
     1713              if ((argptr+2 >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) {
     1714                ExitFlag = 255;
     1715                cerr << "Not enough or invalid arguments given for repeating cells: -d <repeat_x> <repeat_y> <repeat_z>" << endl;
     1716              } else {
     1717                SaveFlag = true;
     1718                for (int axis = 1; axis <= NDIM; axis++) {
     1719                  int faktor = atoi(argv[argptr++]);
     1720                  int count;
     1721                  element ** Elements;
     1722                  Vector ** vectors;
     1723                  if (faktor < 1) {
     1724                    cerr << Verbose(0) << "ERROR: Repetition faktor mus be greater than 1!" << endl;
     1725                    faktor = 1;
     1726                  }
     1727                  mol->CountAtoms((ofstream *)&cout);  // recount atoms
     1728                  if (mol->AtomCount != 0) {  // if there is more than none
     1729                    count = mol->AtomCount;  // is changed becausing of adding, thus has to be stored away beforehand
     1730                    Elements = new element *[count];
     1731                    vectors = new Vector *[count];
     1732                    j = 0;
     1733                    first = mol->start;
     1734                    while (first->next != mol->end) {  // make a list of all atoms with coordinates and element
     1735                      first = first->next;
     1736                      Elements[j] = first->type;
     1737                      vectors[j] = &first->x;
     1738                      j++;
     1739                    }
     1740                    if (count != j)
     1741                      cout << Verbose(0) << "ERROR: AtomCount " << count << " is not equal to number of atoms in molecule " << j << "!" << endl;
     1742                    x.Zero();
     1743                    y.Zero();
     1744                    y.x[abs(axis)-1] = mol->cell_size[(abs(axis) == 2) ? 2 : ((abs(axis) == 3) ? 5 : 0)] * abs(axis)/axis; // last term is for sign, first is for magnitude
     1745                    for (int i=1;i<faktor;i++) {  // then add this list with respective translation factor times
     1746                      x.AddVector(&y); // per factor one cell width further
     1747                      for (int k=count;k--;) { // go through every atom of the original cell
     1748                        first = new atom(); // create a new body
     1749                        first->x.CopyVector(vectors[k]);  // use coordinate of original atom
     1750                        first->x.AddVector(&x);      // translate the coordinates
     1751                        first->type = Elements[k];  // insert original element
     1752                        mol->AddAtom(first);        // and add to the molecule (which increments ElementsInMolecule, AtomCount, ...)
     1753                      }
     1754                    }
     1755                    // free memory
     1756                    delete[](Elements);
     1757                    delete[](vectors);
     1758                    // correct cell size
     1759                    if (axis < 0) { // if sign was negative, we have to translate everything
     1760                      x.Zero();
     1761                      x.AddVector(&y);
     1762                      x.Scale(-(faktor-1));
     1763                      mol->Translate(&x);
     1764                    }
     1765                    mol->cell_size[(abs(axis) == 2) ? 2 : ((abs(axis) == 3) ? 5 : 0)] *= faktor;
     1766                  }
     1767                }
     1768              }
     1769              break;
     1770            default:  // no match? Step on
     1771              if ((argptr < argc) && (argv[argptr][0] != '-')) // if it started with a '-' we've already made a step!
     1772                argptr++;
     1773              break;
     1774          }
     1775        }
     1776      } else argptr++;
     1777    } while (argptr < argc);
     1778    if (SaveFlag)
     1779      SaveConfig(ConfigFileName, &configuration, periode, molecules);
     1780  } else {  // no arguments, hence scan the elements db
     1781    if (periode->LoadPeriodentafel(configuration.databasepath))
     1782      cout << Verbose(0) << "Element list loaded successfully." << endl;
     1783    else
     1784      cout << Verbose(0) << "Element list loading failed." << endl;
     1785    configuration.RetrieveConfigPathAndName("main_pcp_linux");
     1786  }
     1787  return(ExitFlag);
    17881788};
    17891789
     
    17921792int main(int argc, char **argv)
    17931793{
    1794         periodentafel *periode = new periodentafel; // and a period table of all elements
    1795         MoleculeListClass *molecules = new MoleculeListClass;  // list of all molecules
    1796         molecule *mol = NULL;
    1797         config configuration;
    1798         char choice;    // menu choice char
    1799         Vector x,y,z,n; // coordinates for absolute point in cell volume
    1800         ifstream test;
    1801         ofstream output;
    1802         string line;
    1803         char *ConfigFileName = NULL;
    1804         int j, count;
    1805 
    1806         // =========================== PARSE COMMAND LINE OPTIONS ====================================
    1807         j = ParseCommandLineOptions(argc, argv, molecules, periode, configuration, ConfigFileName);
    1808         switch(j) {
    1809           case 0:  // something went wrong
    1810             delete(molecules); // also free's all molecules contained
    1811             delete(periode);
    1812             return j;
    1813             break;
    1814           case 1:  // just for -v and -h options
    1815             delete(molecules); // also free's all molecules contained
    1816             delete(periode);
    1817             return 0;
    1818             break;
    1819           default:
    1820             break;
    1821         }
    1822 
    1823         // General stuff
    1824         if (molecules->ListOfMolecules.size() == 0) {
     1794  periodentafel *periode = new periodentafel; // and a period table of all elements
     1795  MoleculeListClass *molecules = new MoleculeListClass;  // list of all molecules
     1796  molecule *mol = NULL;
     1797  config configuration;
     1798  char choice;  // menu choice char
     1799  Vector x,y,z,n;  // coordinates for absolute point in cell volume
     1800  ifstream test;
     1801  ofstream output;
     1802  string line;
     1803  char *ConfigFileName = NULL;
     1804  int j, count;
     1805
     1806  // =========================== PARSE COMMAND LINE OPTIONS ====================================
     1807  j = ParseCommandLineOptions(argc, argv, molecules, periode, configuration, ConfigFileName);
     1808  switch(j) {
     1809    case 0:  // something went wrong
     1810      delete(molecules); // also free's all molecules contained
     1811      delete(periode);
     1812      return j;
     1813      break;
     1814    case 1:  // just for -v and -h options
     1815      delete(molecules); // also free's all molecules contained
     1816      delete(periode);
     1817      return 0;
     1818      break;
     1819    default:
     1820      break;
     1821  }
     1822
     1823  // General stuff
     1824  if (molecules->ListOfMolecules.size() == 0) {
    18251825    mol = new molecule(periode);
    18261826    if (mol->cell_size[0] == 0.) {
     
    18321832    }
    18331833    molecules->insert(mol);
    1834         }
    1835 
    1836         // =========================== START INTERACTIVE SESSION ====================================
    1837 
    1838         // now the main construction loop
    1839         cout << Verbose(0) << endl << "Now comes the real construction..." << endl;
    1840         do {
    1841                 cout << Verbose(0) << endl << endl;
    1842                 cout << Verbose(0) << "============Molecule list=======================" << endl;
    1843                 molecules->Enumerate((ofstream *)&cout);
    1844                 cout << Verbose(0) << "============Menu===============================" << endl;
     1834  }
     1835
     1836  // =========================== START INTERACTIVE SESSION ====================================
     1837
     1838  // now the main construction loop
     1839  cout << Verbose(0) << endl << "Now comes the real construction..." << endl;
     1840  do {
     1841    cout << Verbose(0) << endl << endl;
     1842    cout << Verbose(0) << "============Molecule list=======================" << endl;
     1843    molecules->Enumerate((ofstream *)&cout);
     1844    cout << Verbose(0) << "============Menu===============================" << endl;
    18451845    cout << Verbose(0) << "a - set molecule (in)active" << endl;
    18461846    cout << Verbose(0) << "e - edit new molecules" << endl;
     
    18581858    cin >> choice;
    18591859
    1860                 switch (choice) {
    1861                         case 'a':  // (in)activate molecule
     1860    switch (choice) {
     1861      case 'a':  // (in)activate molecule
    18621862        {
    18631863          cout << "Enter index of molecule: ";
     
    18691869            (*ListRunner)->ActiveFlag = !(*ListRunner)->ActiveFlag;
    18701870        }
    1871                           break;
    1872 
    1873                         case 'c': // edit each field of the configuration
    1874                         configuration.Edit();
    1875                         break;
     1871        break;
     1872
     1873      case 'c': // edit each field of the configuration
     1874      configuration.Edit();
     1875      break;
    18761876
    18771877      case 'e': // create molecule
     
    18911891        break;
    18921892
    1893                         case 'q': // quit
    1894                                 break;
    1895 
    1896                         case 's': // save to config file
    1897                                 SaveConfig(ConfigFileName, &configuration, periode, molecules);
    1898                                 break;
    1899 
    1900                         case 'T':
    1901                                 testroutine(molecules);
    1902                                 break;
    1903 
    1904                         default:
    1905                           break;
    1906                 };
    1907         } while (choice != 'q');
    1908 
    1909         // save element data base
    1910         if (periode->StorePeriodentafel(configuration.databasepath)) //ElementsFileName
    1911                 cout << Verbose(0) << "Saving of elements.db successful." << endl;
    1912         else
    1913                 cout << Verbose(0) << "Saving of elements.db failed." << endl;
    1914 
    1915         delete(molecules); // also free's all molecules contained
    1916         delete(periode);
    1917         return (0);
     1893      case 'q': // quit
     1894        break;
     1895
     1896      case 's': // save to config file
     1897        SaveConfig(ConfigFileName, &configuration, periode, molecules);
     1898        break;
     1899
     1900      case 'T':
     1901        testroutine(molecules);
     1902        break;
     1903
     1904      default:
     1905        break;
     1906    };
     1907  } while (choice != 'q');
     1908
     1909  // save element data base
     1910  if (periode->StorePeriodentafel(configuration.databasepath)) //ElementsFileName
     1911    cout << Verbose(0) << "Saving of elements.db successful." << endl;
     1912  else
     1913    cout << Verbose(0) << "Saving of elements.db failed." << endl;
     1914
     1915  delete(molecules); // also free's all molecules contained
     1916  delete(periode);
     1917  return (0);
    19181918}
    19191919
  • src/config.cpp

    r205ccd r042f82  
    163163config::config()
    164164{
    165         mainname = (char *) MallocString(sizeof(char)*MAXSTRINGSIZE,"config constructor: mainname");
    166         defaultpath = (char *) MallocString(sizeof(char)*MAXSTRINGSIZE,"config constructor: defaultpath");
    167         pseudopotpath = (char *) MallocString(sizeof(char)*MAXSTRINGSIZE,"config constructor: pseudopotpath");
     165  mainname = (char *) MallocString(sizeof(char)*MAXSTRINGSIZE,"config constructor: mainname");
     166  defaultpath = (char *) MallocString(sizeof(char)*MAXSTRINGSIZE,"config constructor: defaultpath");
     167  pseudopotpath = (char *) MallocString(sizeof(char)*MAXSTRINGSIZE,"config constructor: pseudopotpath");
    168168  databasepath = (char *) MallocString(sizeof(char)*MAXSTRINGSIZE,"config constructor: databasepath");
    169         configpath = (char *) MallocString(sizeof(char)*MAXSTRINGSIZE,"config constructor: configpath");
    170         configname = (char *) MallocString(sizeof(char)*MAXSTRINGSIZE,"config constructor: configname");
    171         strcpy(mainname,"pcp");
    172         strcpy(defaultpath,"not specified");
    173         strcpy(pseudopotpath,"not specified");
    174         configpath[0]='\0';
    175         configname[0]='\0';
    176         basis = "3-21G";
    177 
    178         FastParsing = false;
    179         ProcPEGamma=8;
    180         ProcPEPsi=1;
    181         DoOutVis=0;
    182         DoOutMes=1;
    183         DoOutNICS=0;
    184         DoOutOrbitals=0;
    185         DoOutCurrent=0;
    186         DoPerturbation=0;
    187         DoFullCurrent=0;
    188         DoWannier=0;
    189         CommonWannier=0;
    190         SawtoothStart=0.01;
    191         VectorPlane=0;
    192         VectorCut=0;
    193         UseAddGramSch=1;
    194         Seed=1;
    195 
    196         MaxOuterStep=0;
    197         Deltat=1;
    198         OutVisStep=10;
    199         OutSrcStep=5;
    200         TargetTemp=0.00095004455;
    201         ScaleTempStep=25;
    202         MaxPsiStep=0;
    203         EpsWannier=1e-7;
    204 
    205         MaxMinStep=100;
    206         RelEpsTotalEnergy=1e-7;
    207         RelEpsKineticEnergy=1e-5;
    208         MaxMinStopStep=1;
    209         MaxMinGapStopStep=0;
    210         MaxInitMinStep=100;
    211         InitRelEpsTotalEnergy=1e-5;
    212         InitRelEpsKineticEnergy=1e-4;
    213         InitMaxMinStopStep=1;
    214         InitMaxMinGapStopStep=0;
    215 
    216         //BoxLength[NDIM*NDIM];
    217 
    218         ECut=128.;
    219         MaxLevel=5;
    220         RiemannTensor=0;
    221         LevRFactor=0;
    222         RiemannLevel=0;
    223         Lev0Factor=2;
    224         RTActualUse=0;
    225         PsiType=0;
    226         MaxPsiDouble=0;
    227         PsiMaxNoUp=0;
    228         PsiMaxNoDown=0;
    229         AddPsis=0;
    230 
    231         RCut=20.;
    232         StructOpt=0;
    233         IsAngstroem=1;
    234         RelativeCoord=0;
    235         MaxTypes=0;
     169  configpath = (char *) MallocString(sizeof(char)*MAXSTRINGSIZE,"config constructor: configpath");
     170  configname = (char *) MallocString(sizeof(char)*MAXSTRINGSIZE,"config constructor: configname");
     171  strcpy(mainname,"pcp");
     172  strcpy(defaultpath,"not specified");
     173  strcpy(pseudopotpath,"not specified");
     174  configpath[0]='\0';
     175  configname[0]='\0';
     176  basis = "3-21G";
     177
     178  FastParsing = false;
     179  ProcPEGamma=8;
     180  ProcPEPsi=1;
     181  DoOutVis=0;
     182  DoOutMes=1;
     183  DoOutNICS=0;
     184  DoOutOrbitals=0;
     185  DoOutCurrent=0;
     186  DoPerturbation=0;
     187  DoFullCurrent=0;
     188  DoWannier=0;
     189  CommonWannier=0;
     190  SawtoothStart=0.01;
     191  VectorPlane=0;
     192  VectorCut=0;
     193  UseAddGramSch=1;
     194  Seed=1;
     195
     196  MaxOuterStep=0;
     197  Deltat=1;
     198  OutVisStep=10;
     199  OutSrcStep=5;
     200  TargetTemp=0.00095004455;
     201  ScaleTempStep=25;
     202  MaxPsiStep=0;
     203  EpsWannier=1e-7;
     204
     205  MaxMinStep=100;
     206  RelEpsTotalEnergy=1e-7;
     207  RelEpsKineticEnergy=1e-5;
     208  MaxMinStopStep=1;
     209  MaxMinGapStopStep=0;
     210  MaxInitMinStep=100;
     211  InitRelEpsTotalEnergy=1e-5;
     212  InitRelEpsKineticEnergy=1e-4;
     213  InitMaxMinStopStep=1;
     214  InitMaxMinGapStopStep=0;
     215
     216  //BoxLength[NDIM*NDIM];
     217
     218  ECut=128.;
     219  MaxLevel=5;
     220  RiemannTensor=0;
     221  LevRFactor=0;
     222  RiemannLevel=0;
     223  Lev0Factor=2;
     224  RTActualUse=0;
     225  PsiType=0;
     226  MaxPsiDouble=0;
     227  PsiMaxNoUp=0;
     228  PsiMaxNoDown=0;
     229  AddPsis=0;
     230
     231  RCut=20.;
     232  StructOpt=0;
     233  IsAngstroem=1;
     234  RelativeCoord=0;
     235  MaxTypes=0;
    236236};
    237237
     
    241241config::~config()
    242242{
    243         Free((void **)&mainname, "config::~config: *mainname");
    244         Free((void **)&defaultpath, "config::~config: *defaultpath");
    245         Free((void **)&pseudopotpath, "config::~config: *pseudopotpath");
     243  Free((void **)&mainname, "config::~config: *mainname");
     244  Free((void **)&defaultpath, "config::~config: *defaultpath");
     245  Free((void **)&pseudopotpath, "config::~config: *pseudopotpath");
    246246  Free((void **)&databasepath, "config::~config: *databasepath");
    247         Free((void **)&configpath, "config::~config: *configpath");
    248         Free((void **)&configname, "config::~config: *configname");
     247  Free((void **)&configpath, "config::~config: *configpath");
     248  Free((void **)&configname, "config::~config: *configname");
    249249};
    250250
     
    255255void config::Edit()
    256256{
    257         char choice;
    258 
    259         do {
    260                 cout << Verbose(0) << "===========EDIT CONFIGURATION============================" << endl;
    261                 cout << Verbose(0) << " A - mainname (prefix for all runtime files)" << endl;
    262                 cout << Verbose(0) << " B - Default path (for runtime files)" << endl;
    263                 cout << Verbose(0) << " C - Path of pseudopotential files" << endl;
    264                 cout << Verbose(0) << " D - Number of coefficient sharing processes" << endl;
    265                 cout << Verbose(0) << " E - Number of wave function sharing processes" << endl;
    266                 cout << Verbose(0) << " F - 0: Don't output density for OpenDX, 1: do" << endl;
    267                 cout << Verbose(0) << " G - 0: Don't output physical data, 1: do" << endl;
    268                 cout << Verbose(0) << " H - 0: Don't output densities of each unperturbed orbital for OpenDX, 1: do" << endl;
    269                 cout << Verbose(0) << " I - 0: Don't output current density for OpenDX, 1: do" << endl;
    270                 cout << Verbose(0) << " J - 0: Don't do the full current calculation, 1: do" << endl;
    271                 cout << Verbose(0) << " K - 0: Don't do perturbation calculation to obtain susceptibility and shielding, 1: do" << endl;
    272                 cout << Verbose(0) << " L - 0: Wannier centres as calculated, 1: common centre for all, 2: unite centres according to spread, 3: cell centre, 4: shifted to nearest grid point" << endl;
    273                 cout << Verbose(0) << " M - Absolute begin of unphysical sawtooth transfer for position operator within cell" << endl;
    274                 cout << Verbose(0) << " N - (0,1,2) x,y,z-plane to do two-dimensional current vector cut" << endl;
    275                 cout << Verbose(0) << " O - Absolute position along vector cut axis for cut plane" << endl;
    276                 cout << Verbose(0) << " P - Additional Gram-Schmidt-Orthonormalization to stabilize numerics" << endl;
    277                 cout << Verbose(0) << " Q - Initial integer value of random number generator" << endl;
    278                 cout << Verbose(0) << " R - for perturbation 0, for structure optimization defines upper limit of iterations" << endl;
    279                 cout << Verbose(0) << " T - Output visual after ...th step" << endl;
    280                 cout << Verbose(0) << " U - Output source densities of wave functions after ...th step" << endl;
    281                 cout << Verbose(0) << " X - minimization iterations per wave function, if unsure leave at default value 0" << endl;
    282                 cout << Verbose(0) << " Y - tolerance value for total spread in iterative Jacobi diagonalization" << endl;
    283                 cout << Verbose(0) << " Z - Maximum number of minimization iterations" << endl;
    284                 cout << Verbose(0) << " a - Relative change in total energy to stop min. iteration" << endl;
    285                 cout << Verbose(0) << " b - Relative change in kinetic energy to stop min. iteration" << endl;
    286                 cout << Verbose(0) << " c - Check stop conditions every ..th step during min. iteration" << endl;
    287                 cout << Verbose(0) << " e - Maximum number of minimization iterations during initial level" << endl;
    288                 cout << Verbose(0) << " f - Relative change in total energy to stop min. iteration during initial level" << endl;
    289                 cout << Verbose(0) << " g - Relative change in kinetic energy to stop min. iteration during initial level" << endl;
    290                 cout << Verbose(0) << " h - Check stop conditions every ..th step during min. iteration during initial level" << endl;
    291 //              cout << Verbose(0) << " j - six lower diagonal entries of matrix, defining the unit cell" << endl;
    292                 cout << Verbose(0) << " k - Energy cutoff of plane wave basis in Hartree" << endl;
    293                 cout << Verbose(0) << " l - Maximum number of levels in multi-level-ansatz" << endl;
    294                 cout << Verbose(0) << " m - Factor by which grid nodes increase between standard and upper level" << endl;
    295                 cout << Verbose(0) << " n - 0: Don't use RiemannTensor, 1: Do" << endl;
    296                 cout << Verbose(0) << " o - Factor by which grid nodes increase between Riemann and standard(?) level" << endl;
    297                 cout << Verbose(0) << " p - Number of Riemann levels" << endl;
    298                 cout << Verbose(0) << " r - 0: Don't Use RiemannTensor, 1: Do" << endl;
    299                 cout << Verbose(0) << " s - 0: Doubly occupied orbitals, 1: Up-/Down-Orbitals" << endl;
    300                 cout << Verbose(0) << " t - Number of orbitals (depends pn SpinType)" << endl;
    301                 cout << Verbose(0) << " u - Number of SpinUp orbitals (depends on SpinType)" << endl;
    302                 cout << Verbose(0) << " v - Number of SpinDown orbitals (depends on SpinType)" << endl;
    303                 cout << Verbose(0) << " w - Number of additional, unoccupied orbitals" << endl;
    304                 cout << Verbose(0) << " x - radial cutoff for ewald summation in Bohrradii" << endl;
    305                 cout << Verbose(0) << " y - 0: Don't do structure optimization beforehand, 1: Do" << endl;
    306                 cout << Verbose(0) << " z - 0: Units are in Bohr radii, 1: units are in Aengstrom" << endl;
    307                 cout << Verbose(0) << " i - 0: Coordinates given in file are absolute, 1: ... are relative to unit cell" << endl;
    308                 cout << Verbose(0) << "=========================================================" << endl;
    309                 cout << Verbose(0) << "INPUT: ";
    310                 cin >> choice;
    311 
    312                 switch (choice) {
    313                                 case 'A': // mainname
    314                                         cout << Verbose(0) << "Old: " << config::mainname << "\t new: ";
    315                                         cin >> config::mainname;
    316                                         break;
    317                                 case 'B': // defaultpath
    318                                         cout << Verbose(0) << "Old: " << config::defaultpath << "\t new: ";
    319                                         cin >> config::defaultpath;
    320                                         break;
    321                                 case 'C': // pseudopotpath
    322                                         cout << Verbose(0) << "Old: " << config::pseudopotpath << "\t new: ";
    323                                         cin >> config::pseudopotpath;
    324                                         break;
    325 
    326                                 case 'D': // ProcPEGamma
    327                                         cout << Verbose(0) << "Old: " << config::ProcPEGamma << "\t new: ";
    328                                         cin >> config::ProcPEGamma;
    329                                         break;
    330                                 case 'E': // ProcPEPsi
    331                                         cout << Verbose(0) << "Old: " << config::ProcPEPsi << "\t new: ";
    332                                         cin >> config::ProcPEPsi;
    333                                         break;
    334                                 case 'F': // DoOutVis
    335                                         cout << Verbose(0) << "Old: " << config::DoOutVis << "\t new: ";
    336                                         cin >> config::DoOutVis;
    337                                         break;
    338                                 case 'G': // DoOutMes
    339                                         cout << Verbose(0) << "Old: " << config::DoOutMes << "\t new: ";
    340                                         cin >> config::DoOutMes;
    341                                         break;
    342                                 case 'H': // DoOutOrbitals
    343                                         cout << Verbose(0) << "Old: " << config::DoOutOrbitals << "\t new: ";
    344                                         cin >> config::DoOutOrbitals;
    345                                         break;
    346                                 case 'I': // DoOutCurrent
    347                                         cout << Verbose(0) << "Old: " << config::DoOutCurrent << "\t new: ";
    348                                         cin >> config::DoOutCurrent;
    349                                         break;
    350                                 case 'J': // DoFullCurrent
    351                                         cout << Verbose(0) << "Old: " << config::DoFullCurrent << "\t new: ";
    352                                         cin >> config::DoFullCurrent;
    353                                         break;
    354                                 case 'K': // DoPerturbation
    355                                         cout << Verbose(0) << "Old: " << config::DoPerturbation << "\t new: ";
    356                                         cin >> config::DoPerturbation;
    357                                         break;
    358                                 case 'L': // CommonWannier
    359                                         cout << Verbose(0) << "Old: " << config::CommonWannier << "\t new: ";
    360                                         cin >> config::CommonWannier;
    361                                         break;
    362                                 case 'M': // SawtoothStart
    363                                         cout << Verbose(0) << "Old: " << config::SawtoothStart << "\t new: ";
    364                                         cin >> config::SawtoothStart;
    365                                         break;
    366                                 case 'N': // VectorPlane
    367                                         cout << Verbose(0) << "Old: " << config::VectorPlane << "\t new: ";
    368                                         cin >> config::VectorPlane;
    369                                         break;
    370                                 case 'O': // VectorCut
    371                                         cout << Verbose(0) << "Old: " << config::VectorCut << "\t new: ";
    372                                         cin >> config::VectorCut;
    373                                         break;
    374                                 case 'P': // UseAddGramSch
    375                                         cout << Verbose(0) << "Old: " << config::UseAddGramSch << "\t new: ";
    376                                         cin >> config::UseAddGramSch;
    377                                         break;
    378                                 case 'Q': // Seed
    379                                         cout << Verbose(0) << "Old: " << config::Seed << "\t new: ";
    380                                         cin >> config::Seed;
    381                                         break;
    382 
    383                                 case 'R': // MaxOuterStep
    384                                         cout << Verbose(0) << "Old: " << config::MaxOuterStep << "\t new: ";
    385                                         cin >> config::MaxOuterStep;
    386                                         break;
    387                                 case 'T': // OutVisStep
    388                                         cout << Verbose(0) << "Old: " << config::OutVisStep << "\t new: ";
    389                                         cin >> config::OutVisStep;
    390                                         break;
    391                                 case 'U': // OutSrcStep
    392                                         cout << Verbose(0) << "Old: " << config::OutSrcStep << "\t new: ";
    393                                         cin >> config::OutSrcStep;
    394                                         break;
    395                                 case 'X': // MaxPsiStep
    396                                         cout << Verbose(0) << "Old: " << config::MaxPsiStep << "\t new: ";
    397                                         cin >> config::MaxPsiStep;
    398                                         break;
    399                                 case 'Y': // EpsWannier
    400                                         cout << Verbose(0) << "Old: " << config::EpsWannier << "\t new: ";
    401                                         cin >> config::EpsWannier;
    402                                         break;
    403 
    404                                 case 'Z': // MaxMinStep
    405                                         cout << Verbose(0) << "Old: " << config::MaxMinStep << "\t new: ";
    406                                         cin >> config::MaxMinStep;
    407                                         break;
    408                                 case 'a': // RelEpsTotalEnergy
    409                                         cout << Verbose(0) << "Old: " << config::RelEpsTotalEnergy << "\t new: ";
    410                                         cin >> config::RelEpsTotalEnergy;
    411                                         break;
    412                                 case 'b': // RelEpsKineticEnergy
    413                                         cout << Verbose(0) << "Old: " << config::RelEpsKineticEnergy << "\t new: ";
    414                                         cin >> config::RelEpsKineticEnergy;
    415                                         break;
    416                                 case 'c': // MaxMinStopStep
    417                                         cout << Verbose(0) << "Old: " << config::MaxMinStopStep << "\t new: ";
    418                                         cin >> config::MaxMinStopStep;
    419                                         break;
    420                                 case 'e': // MaxInitMinStep
    421                                         cout << Verbose(0) << "Old: " << config::MaxInitMinStep << "\t new: ";
    422                                         cin >> config::MaxInitMinStep;
    423                                         break;
    424                                 case 'f': // InitRelEpsTotalEnergy
    425                                         cout << Verbose(0) << "Old: " << config::InitRelEpsTotalEnergy << "\t new: ";
    426                                         cin >> config::InitRelEpsTotalEnergy;
    427                                         break;
    428                                 case 'g': // InitRelEpsKineticEnergy
    429                                         cout << Verbose(0) << "Old: " << config::InitRelEpsKineticEnergy << "\t new: ";
    430                                         cin >> config::InitRelEpsKineticEnergy;
    431                                         break;
    432                                 case 'h': // InitMaxMinStopStep
    433                                         cout << Verbose(0) << "Old: " << config::InitMaxMinStopStep << "\t new: ";
    434                                         cin >> config::InitMaxMinStopStep;
    435                                         break;
    436 
    437 //                              case 'j': // BoxLength
    438 //                                      cout << Verbose(0) << "enter lower triadiagonalo form of basis matrix" << endl << endl;
    439 //                                      for (int i=0;i<6;i++) {
    440 //                                              cout << Verbose(0) << "Cell size" << i << ": ";
    441 //                                              cin >> mol->cell_size[i];
    442 //                                      }
    443 //                                      break;
    444 
    445                                 case 'k': // ECut
    446                                         cout << Verbose(0) << "Old: " << config::ECut << "\t new: ";
    447                                         cin >> config::ECut;
    448                                         break;
    449                                 case 'l': // MaxLevel
    450                                         cout << Verbose(0) << "Old: " << config::MaxLevel << "\t new: ";
    451                                         cin >> config::MaxLevel;
    452                                         break;
    453                                 case 'm': // RiemannTensor
    454                                         cout << Verbose(0) << "Old: " << config::RiemannTensor << "\t new: ";
    455                                         cin >> config::RiemannTensor;
    456                                         break;
    457                                 case 'n': // LevRFactor
    458                                         cout << Verbose(0) << "Old: " << config::LevRFactor << "\t new: ";
    459                                         cin >> config::LevRFactor;
    460                                         break;
    461                                 case 'o': // RiemannLevel
    462                                         cout << Verbose(0) << "Old: " << config::RiemannLevel << "\t new: ";
    463                                         cin >> config::RiemannLevel;
    464                                         break;
    465                                 case 'p': // Lev0Factor
    466                                         cout << Verbose(0) << "Old: " << config::Lev0Factor << "\t new: ";
    467                                         cin >> config::Lev0Factor;
    468                                         break;
    469                                 case 'r': // RTActualUse
    470                                         cout << Verbose(0) << "Old: " << config::RTActualUse << "\t new: ";
    471                                         cin >> config::RTActualUse;
    472                                         break;
    473                                 case 's': // PsiType
    474                                         cout << Verbose(0) << "Old: " << config::PsiType << "\t new: ";
    475                                         cin >> config::PsiType;
    476                                         break;
    477                                 case 't': // MaxPsiDouble
    478                                         cout << Verbose(0) << "Old: " << config::MaxPsiDouble << "\t new: ";
    479                                         cin >> config::MaxPsiDouble;
    480                                         break;
    481                                 case 'u': // PsiMaxNoUp
    482                                         cout << Verbose(0) << "Old: " << config::PsiMaxNoUp << "\t new: ";
    483                                         cin >> config::PsiMaxNoUp;
    484                                         break;
    485                                 case 'v': // PsiMaxNoDown
    486                                         cout << Verbose(0) << "Old: " << config::PsiMaxNoDown << "\t new: ";
    487                                         cin >> config::PsiMaxNoDown;
    488                                         break;
    489                                 case 'w': // AddPsis
    490                                         cout << Verbose(0) << "Old: " << config::AddPsis << "\t new: ";
    491                                         cin >> config::AddPsis;
    492                                         break;
    493 
    494                                 case 'x': // RCut
    495                                         cout << Verbose(0) << "Old: " << config::RCut << "\t new: ";
    496                                         cin >> config::RCut;
    497                                         break;
    498                                 case 'y': // StructOpt
    499                                         cout << Verbose(0) << "Old: " << config::StructOpt << "\t new: ";
    500                                         cin >> config::StructOpt;
    501                                         break;
    502                                 case 'z': // IsAngstroem
    503                                         cout << Verbose(0) << "Old: " << config::IsAngstroem << "\t new: ";
    504                                         cin >> config::IsAngstroem;
    505                                         break;
    506                                 case 'i': // RelativeCoord
    507                                         cout << Verbose(0) << "Old: " << config::RelativeCoord << "\t new: ";
    508                                         cin >> config::RelativeCoord;
    509                                         break;
    510                 };
    511         } while (choice != 'q');
     257  char choice;
     258
     259  do {
     260    cout << Verbose(0) << "===========EDIT CONFIGURATION============================" << endl;
     261    cout << Verbose(0) << " A - mainname (prefix for all runtime files)" << endl;
     262    cout << Verbose(0) << " B - Default path (for runtime files)" << endl;
     263    cout << Verbose(0) << " C - Path of pseudopotential files" << endl;
     264    cout << Verbose(0) << " D - Number of coefficient sharing processes" << endl;
     265    cout << Verbose(0) << " E - Number of wave function sharing processes" << endl;
     266    cout << Verbose(0) << " F - 0: Don't output density for OpenDX, 1: do" << endl;
     267    cout << Verbose(0) << " G - 0: Don't output physical data, 1: do" << endl;
     268    cout << Verbose(0) << " H - 0: Don't output densities of each unperturbed orbital for OpenDX, 1: do" << endl;
     269    cout << Verbose(0) << " I - 0: Don't output current density for OpenDX, 1: do" << endl;
     270    cout << Verbose(0) << " J - 0: Don't do the full current calculation, 1: do" << endl;
     271    cout << Verbose(0) << " K - 0: Don't do perturbation calculation to obtain susceptibility and shielding, 1: do" << endl;
     272    cout << Verbose(0) << " L - 0: Wannier centres as calculated, 1: common centre for all, 2: unite centres according to spread, 3: cell centre, 4: shifted to nearest grid point" << endl;
     273    cout << Verbose(0) << " M - Absolute begin of unphysical sawtooth transfer for position operator within cell" << endl;
     274    cout << Verbose(0) << " N - (0,1,2) x,y,z-plane to do two-dimensional current vector cut" << endl;
     275    cout << Verbose(0) << " O - Absolute position along vector cut axis for cut plane" << endl;
     276    cout << Verbose(0) << " P - Additional Gram-Schmidt-Orthonormalization to stabilize numerics" << endl;
     277    cout << Verbose(0) << " Q - Initial integer value of random number generator" << endl;
     278    cout << Verbose(0) << " R - for perturbation 0, for structure optimization defines upper limit of iterations" << endl;
     279    cout << Verbose(0) << " T - Output visual after ...th step" << endl;
     280    cout << Verbose(0) << " U - Output source densities of wave functions after ...th step" << endl;
     281    cout << Verbose(0) << " X - minimization iterations per wave function, if unsure leave at default value 0" << endl;
     282    cout << Verbose(0) << " Y - tolerance value for total spread in iterative Jacobi diagonalization" << endl;
     283    cout << Verbose(0) << " Z - Maximum number of minimization iterations" << endl;
     284    cout << Verbose(0) << " a - Relative change in total energy to stop min. iteration" << endl;
     285    cout << Verbose(0) << " b - Relative change in kinetic energy to stop min. iteration" << endl;
     286    cout << Verbose(0) << " c - Check stop conditions every ..th step during min. iteration" << endl;
     287    cout << Verbose(0) << " e - Maximum number of minimization iterations during initial level" << endl;
     288    cout << Verbose(0) << " f - Relative change in total energy to stop min. iteration during initial level" << endl;
     289    cout << Verbose(0) << " g - Relative change in kinetic energy to stop min. iteration during initial level" << endl;
     290    cout << Verbose(0) << " h - Check stop conditions every ..th step during min. iteration during initial level" << endl;
     291//    cout << Verbose(0) << " j - six lower diagonal entries of matrix, defining the unit cell" << endl;
     292    cout << Verbose(0) << " k - Energy cutoff of plane wave basis in Hartree" << endl;
     293    cout << Verbose(0) << " l - Maximum number of levels in multi-level-ansatz" << endl;
     294    cout << Verbose(0) << " m - Factor by which grid nodes increase between standard and upper level" << endl;
     295    cout << Verbose(0) << " n - 0: Don't use RiemannTensor, 1: Do" << endl;
     296    cout << Verbose(0) << " o - Factor by which grid nodes increase between Riemann and standard(?) level" << endl;
     297    cout << Verbose(0) << " p - Number of Riemann levels" << endl;
     298    cout << Verbose(0) << " r - 0: Don't Use RiemannTensor, 1: Do" << endl;
     299    cout << Verbose(0) << " s - 0: Doubly occupied orbitals, 1: Up-/Down-Orbitals" << endl;
     300    cout << Verbose(0) << " t - Number of orbitals (depends pn SpinType)" << endl;
     301    cout << Verbose(0) << " u - Number of SpinUp orbitals (depends on SpinType)" << endl;
     302    cout << Verbose(0) << " v - Number of SpinDown orbitals (depends on SpinType)" << endl;
     303    cout << Verbose(0) << " w - Number of additional, unoccupied orbitals" << endl;
     304    cout << Verbose(0) << " x - radial cutoff for ewald summation in Bohrradii" << endl;
     305    cout << Verbose(0) << " y - 0: Don't do structure optimization beforehand, 1: Do" << endl;
     306    cout << Verbose(0) << " z - 0: Units are in Bohr radii, 1: units are in Aengstrom" << endl;
     307    cout << Verbose(0) << " i - 0: Coordinates given in file are absolute, 1: ... are relative to unit cell" << endl;
     308    cout << Verbose(0) << "=========================================================" << endl;
     309    cout << Verbose(0) << "INPUT: ";
     310    cin >> choice;
     311
     312    switch (choice) {
     313        case 'A': // mainname
     314          cout << Verbose(0) << "Old: " << config::mainname << "\t new: ";
     315          cin >> config::mainname;
     316          break;
     317        case 'B': // defaultpath
     318          cout << Verbose(0) << "Old: " << config::defaultpath << "\t new: ";
     319          cin >> config::defaultpath;
     320          break;
     321        case 'C': // pseudopotpath
     322          cout << Verbose(0) << "Old: " << config::pseudopotpath << "\t new: ";
     323          cin >> config::pseudopotpath;
     324          break;
     325
     326        case 'D': // ProcPEGamma
     327          cout << Verbose(0) << "Old: " << config::ProcPEGamma << "\t new: ";
     328          cin >> config::ProcPEGamma;
     329          break;
     330        case 'E': // ProcPEPsi
     331          cout << Verbose(0) << "Old: " << config::ProcPEPsi << "\t new: ";
     332          cin >> config::ProcPEPsi;
     333          break;
     334        case 'F': // DoOutVis
     335          cout << Verbose(0) << "Old: " << config::DoOutVis << "\t new: ";
     336          cin >> config::DoOutVis;
     337          break;
     338        case 'G': // DoOutMes
     339          cout << Verbose(0) << "Old: " << config::DoOutMes << "\t new: ";
     340          cin >> config::DoOutMes;
     341          break;
     342        case 'H': // DoOutOrbitals
     343          cout << Verbose(0) << "Old: " << config::DoOutOrbitals << "\t new: ";
     344          cin >> config::DoOutOrbitals;
     345          break;
     346        case 'I': // DoOutCurrent
     347          cout << Verbose(0) << "Old: " << config::DoOutCurrent << "\t new: ";
     348          cin >> config::DoOutCurrent;
     349          break;
     350        case 'J': // DoFullCurrent
     351          cout << Verbose(0) << "Old: " << config::DoFullCurrent << "\t new: ";
     352          cin >> config::DoFullCurrent;
     353          break;
     354        case 'K': // DoPerturbation
     355          cout << Verbose(0) << "Old: " << config::DoPerturbation << "\t new: ";
     356          cin >> config::DoPerturbation;
     357          break;
     358        case 'L': // CommonWannier
     359          cout << Verbose(0) << "Old: " << config::CommonWannier << "\t new: ";
     360          cin >> config::CommonWannier;
     361          break;
     362        case 'M': // SawtoothStart
     363          cout << Verbose(0) << "Old: " << config::SawtoothStart << "\t new: ";
     364          cin >> config::SawtoothStart;
     365          break;
     366        case 'N': // VectorPlane
     367          cout << Verbose(0) << "Old: " << config::VectorPlane << "\t new: ";
     368          cin >> config::VectorPlane;
     369          break;
     370        case 'O': // VectorCut
     371          cout << Verbose(0) << "Old: " << config::VectorCut << "\t new: ";
     372          cin >> config::VectorCut;
     373          break;
     374        case 'P': // UseAddGramSch
     375          cout << Verbose(0) << "Old: " << config::UseAddGramSch << "\t new: ";
     376          cin >> config::UseAddGramSch;
     377          break;
     378        case 'Q': // Seed
     379          cout << Verbose(0) << "Old: " << config::Seed << "\t new: ";
     380          cin >> config::Seed;
     381          break;
     382
     383        case 'R': // MaxOuterStep
     384          cout << Verbose(0) << "Old: " << config::MaxOuterStep << "\t new: ";
     385          cin >> config::MaxOuterStep;
     386          break;
     387        case 'T': // OutVisStep
     388          cout << Verbose(0) << "Old: " << config::OutVisStep << "\t new: ";
     389          cin >> config::OutVisStep;
     390          break;
     391        case 'U': // OutSrcStep
     392          cout << Verbose(0) << "Old: " << config::OutSrcStep << "\t new: ";
     393          cin >> config::OutSrcStep;
     394          break;
     395        case 'X': // MaxPsiStep
     396          cout << Verbose(0) << "Old: " << config::MaxPsiStep << "\t new: ";
     397          cin >> config::MaxPsiStep;
     398          break;
     399        case 'Y': // EpsWannier
     400          cout << Verbose(0) << "Old: " << config::EpsWannier << "\t new: ";
     401          cin >> config::EpsWannier;
     402          break;
     403
     404        case 'Z': // MaxMinStep
     405          cout << Verbose(0) << "Old: " << config::MaxMinStep << "\t new: ";
     406          cin >> config::MaxMinStep;
     407          break;
     408        case 'a': // RelEpsTotalEnergy
     409          cout << Verbose(0) << "Old: " << config::RelEpsTotalEnergy << "\t new: ";
     410          cin >> config::RelEpsTotalEnergy;
     411          break;
     412        case 'b': // RelEpsKineticEnergy
     413          cout << Verbose(0) << "Old: " << config::RelEpsKineticEnergy << "\t new: ";
     414          cin >> config::RelEpsKineticEnergy;
     415          break;
     416        case 'c': // MaxMinStopStep
     417          cout << Verbose(0) << "Old: " << config::MaxMinStopStep << "\t new: ";
     418          cin >> config::MaxMinStopStep;
     419          break;
     420        case 'e': // MaxInitMinStep
     421          cout << Verbose(0) << "Old: " << config::MaxInitMinStep << "\t new: ";
     422          cin >> config::MaxInitMinStep;
     423          break;
     424        case 'f': // InitRelEpsTotalEnergy
     425          cout << Verbose(0) << "Old: " << config::InitRelEpsTotalEnergy << "\t new: ";
     426          cin >> config::InitRelEpsTotalEnergy;
     427          break;
     428        case 'g': // InitRelEpsKineticEnergy
     429          cout << Verbose(0) << "Old: " << config::InitRelEpsKineticEnergy << "\t new: ";
     430          cin >> config::InitRelEpsKineticEnergy;
     431          break;
     432        case 'h': // InitMaxMinStopStep
     433          cout << Verbose(0) << "Old: " << config::InitMaxMinStopStep << "\t new: ";
     434          cin >> config::InitMaxMinStopStep;
     435          break;
     436
     437//        case 'j': // BoxLength
     438//          cout << Verbose(0) << "enter lower triadiagonalo form of basis matrix" << endl << endl;
     439//          for (int i=0;i<6;i++) {
     440//            cout << Verbose(0) << "Cell size" << i << ": ";
     441//            cin >> mol->cell_size[i];
     442//          }
     443//          break;
     444
     445        case 'k': // ECut
     446          cout << Verbose(0) << "Old: " << config::ECut << "\t new: ";
     447          cin >> config::ECut;
     448          break;
     449        case 'l': // MaxLevel
     450          cout << Verbose(0) << "Old: " << config::MaxLevel << "\t new: ";
     451          cin >> config::MaxLevel;
     452          break;
     453        case 'm': // RiemannTensor
     454          cout << Verbose(0) << "Old: " << config::RiemannTensor << "\t new: ";
     455          cin >> config::RiemannTensor;
     456          break;
     457        case 'n': // LevRFactor
     458          cout << Verbose(0) << "Old: " << config::LevRFactor << "\t new: ";
     459          cin >> config::LevRFactor;
     460          break;
     461        case 'o': // RiemannLevel
     462          cout << Verbose(0) << "Old: " << config::RiemannLevel << "\t new: ";
     463          cin >> config::RiemannLevel;
     464          break;
     465        case 'p': // Lev0Factor
     466          cout << Verbose(0) << "Old: " << config::Lev0Factor << "\t new: ";
     467          cin >> config::Lev0Factor;
     468          break;
     469        case 'r': // RTActualUse
     470          cout << Verbose(0) << "Old: " << config::RTActualUse << "\t new: ";
     471          cin >> config::RTActualUse;
     472          break;
     473        case 's': // PsiType
     474          cout << Verbose(0) << "Old: " << config::PsiType << "\t new: ";
     475          cin >> config::PsiType;
     476          break;
     477        case 't': // MaxPsiDouble
     478          cout << Verbose(0) << "Old: " << config::MaxPsiDouble << "\t new: ";
     479          cin >> config::MaxPsiDouble;
     480          break;
     481        case 'u': // PsiMaxNoUp
     482          cout << Verbose(0) << "Old: " << config::PsiMaxNoUp << "\t new: ";
     483          cin >> config::PsiMaxNoUp;
     484          break;
     485        case 'v': // PsiMaxNoDown
     486          cout << Verbose(0) << "Old: " << config::PsiMaxNoDown << "\t new: ";
     487          cin >> config::PsiMaxNoDown;
     488          break;
     489        case 'w': // AddPsis
     490          cout << Verbose(0) << "Old: " << config::AddPsis << "\t new: ";
     491          cin >> config::AddPsis;
     492          break;
     493
     494        case 'x': // RCut
     495          cout << Verbose(0) << "Old: " << config::RCut << "\t new: ";
     496          cin >> config::RCut;
     497          break;
     498        case 'y': // StructOpt
     499          cout << Verbose(0) << "Old: " << config::StructOpt << "\t new: ";
     500          cin >> config::StructOpt;
     501          break;
     502        case 'z': // IsAngstroem
     503          cout << Verbose(0) << "Old: " << config::IsAngstroem << "\t new: ";
     504          cin >> config::IsAngstroem;
     505          break;
     506        case 'i': // RelativeCoord
     507          cout << Verbose(0) << "Old: " << config::RelativeCoord << "\t new: ";
     508          cin >> config::RelativeCoord;
     509          break;
     510    };
     511  } while (choice != 'q');
    512512};
    513513
     
    520520int config::TestSyntax(char *filename, periodentafel *periode, molecule *mol)
    521521{
    522         int test;
    523         ifstream file(filename);
    524 
    525         // search file for keyword: ProcPEGamma (new syntax)
    526         if (ParseForParameter(1,&file,"ProcPEGamma", 0, 1, 1, int_type, &test, 1, optional)) {
    527                 file.close();
    528                 return 1;
    529         }
    530         // search file for keyword: ProcsGammaPsi (old syntax)
    531         if (ParseForParameter(1,&file,"ProcsGammaPsi", 0, 1, 1, int_type, &test, 1, optional)) {
    532                 file.close();
    533                 return 0;
    534         }
    535         file.close();
    536         return -1;
     522  int test;
     523  ifstream file(filename);
     524
     525  // search file for keyword: ProcPEGamma (new syntax)
     526  if (ParseForParameter(1,&file,"ProcPEGamma", 0, 1, 1, int_type, &test, 1, optional)) {
     527    file.close();
     528    return 1;
     529  }
     530  // search file for keyword: ProcsGammaPsi (old syntax)
     531  if (ParseForParameter(1,&file,"ProcsGammaPsi", 0, 1, 1, int_type, &test, 1, optional)) {
     532    file.close();
     533    return 0;
     534  }
     535  file.close();
     536  return -1;
    537537}
    538538
     
    542542bool config::GetIsAngstroem() const
    543543{
    544         return (IsAngstroem == 1);
     544  return (IsAngstroem == 1);
    545545};
    546546
     
    550550char * config::GetDefaultPath() const
    551551{
    552         return defaultpath;
     552  return defaultpath;
    553553};
    554554
     
    559559void config::SetDefaultPath(const char *path)
    560560{
    561         strcpy(defaultpath, path);
     561  strcpy(defaultpath, path);
    562562};
    563563
     
    567567void config::RetrieveConfigPathAndName(string filename)
    568568{
    569         char *ptr = NULL;
    570         char *buffer = new char[MAXSTRINGSIZE];
    571         strncpy(buffer, filename.c_str(), MAXSTRINGSIZE);
    572         int last = -1;
    573         for(last=MAXSTRINGSIZE;last--;) {
    574                 if (buffer[last] == '/')
    575                         break;
    576         }
    577         if (last == -1) { // no path in front, set to local directory.
    578                 strcpy(configpath, "./");
    579                 ptr = buffer;
    580         } else {
    581                 strncpy(configpath, buffer, last+1);
    582                 ptr = &buffer[last+1];
    583                 if (last < 254)
    584                         configpath[last+1]='\0';
    585         }
    586         strcpy(configname, ptr);
    587         cout << "Found configpath: " << configpath << ", dir slash was found at " << last << ", config name is " << configname << "." << endl;
    588         delete[](buffer);
     569  char *ptr = NULL;
     570  char *buffer = new char[MAXSTRINGSIZE];
     571  strncpy(buffer, filename.c_str(), MAXSTRINGSIZE);
     572  int last = -1;
     573  for(last=MAXSTRINGSIZE;last--;) {
     574    if (buffer[last] == '/')
     575      break;
     576  }
     577  if (last == -1) { // no path in front, set to local directory.
     578    strcpy(configpath, "./");
     579    ptr = buffer;
     580  } else {
     581    strncpy(configpath, buffer, last+1);
     582    ptr = &buffer[last+1];
     583    if (last < 254)
     584      configpath[last+1]='\0';
     585  }
     586  strcpy(configname, ptr);
     587  cout << "Found configpath: " << configpath << ", dir slash was found at " << last << ", config name is " << configname << "." << endl;
     588  delete[](buffer);
    589589};
    590590
     
    597597void config::Load(char *filename, periodentafel *periode, molecule *mol)
    598598{
    599         RetrieveConfigPathAndName(filename);
    600 
    601         // ParseParameterFile
     599  RetrieveConfigPathAndName(filename);
     600
     601  // ParseParameterFile
    602602  struct ConfigFileBuffer *FileBuffer = new ConfigFileBuffer(filename);
    603         FileBuffer->InitMapping();
    604 
    605         /* Oeffne Hauptparameterdatei */
    606         int di;
    607         double BoxLength[9];
    608         string zeile;
    609         string dummy;
    610         element *elementhash[MAX_ELEMENTS];
    611         char name[MAX_ELEMENTS];
    612         char keyword[MAX_ELEMENTS];
    613         int Z, No[MAX_ELEMENTS];
    614         int verbose = 0;
    615         double value[3];
    616 
    617         /* Namen einlesen */
    618 
    619         ParseForParameter(verbose,FileBuffer, "mainname", 0, 1, 1, string_type, (config::mainname), 1, critical);
    620         ParseForParameter(verbose,FileBuffer, "defaultpath", 0, 1, 1, string_type, (config::defaultpath), 1, critical);
    621         ParseForParameter(verbose,FileBuffer, "pseudopotpath", 0, 1, 1, string_type, (config::pseudopotpath), 1, critical);
    622         ParseForParameter(verbose,FileBuffer,"ProcPEGamma", 0, 1, 1, int_type, &(config::ProcPEGamma), 1, critical);
    623         ParseForParameter(verbose,FileBuffer,"ProcPEPsi", 0, 1, 1, int_type, &(config::ProcPEPsi), 1, critical);
    624 
    625         if (!ParseForParameter(verbose,FileBuffer,"Seed", 0, 1, 1, int_type, &(config::Seed), 1, optional))
    626                 config::Seed = 1;
    627 
    628         if(!ParseForParameter(verbose,FileBuffer,"DoOutOrbitals", 0, 1, 1, int_type, &(config::DoOutOrbitals), 1, optional)) {
    629                 config::DoOutOrbitals = 0;
    630         } else {
    631                 if (config::DoOutOrbitals < 0) config::DoOutOrbitals = 0;
    632                 if (config::DoOutOrbitals > 1) config::DoOutOrbitals = 1;
    633         }
    634         ParseForParameter(verbose,FileBuffer,"DoOutVis", 0, 1, 1, int_type, &(config::DoOutVis), 1, critical);
    635         if (config::DoOutVis < 0) config::DoOutVis = 0;
    636         if (config::DoOutVis > 1) config::DoOutVis = 1;
    637         if (!ParseForParameter(verbose,FileBuffer,"VectorPlane", 0, 1, 1, int_type, &(config::VectorPlane), 1, optional))
    638                 config::VectorPlane = -1;
    639         if (!ParseForParameter(verbose,FileBuffer,"VectorCut", 0, 1, 1, double_type, &(config::VectorCut), 1, optional))
    640                 config::VectorCut = 0.;
    641         ParseForParameter(verbose,FileBuffer,"DoOutMes", 0, 1, 1, int_type, &(config::DoOutMes), 1, critical);
    642         if (config::DoOutMes < 0) config::DoOutMes = 0;
    643         if (config::DoOutMes > 1) config::DoOutMes = 1;
    644         if (!ParseForParameter(verbose,FileBuffer,"DoOutCurr", 0, 1, 1, int_type, &(config::DoOutCurrent), 1, optional))
    645                 config::DoOutCurrent = 0;
    646         if (config::DoOutCurrent < 0) config::DoOutCurrent = 0;
    647         if (config::DoOutCurrent > 1) config::DoOutCurrent = 1;
    648         ParseForParameter(verbose,FileBuffer,"AddGramSch", 0, 1, 1, int_type, &(config::UseAddGramSch), 1, critical);
    649         if (config::UseAddGramSch < 0) config::UseAddGramSch = 0;
    650         if (config::UseAddGramSch > 2) config::UseAddGramSch = 2;
    651         if(!ParseForParameter(verbose,FileBuffer,"DoWannier", 0, 1, 1, int_type, &(config::DoWannier), 1, optional)) {
    652                 config::DoWannier = 0;
    653         } else {
    654                 if (config::DoWannier < 0) config::DoWannier = 0;
    655                 if (config::DoWannier > 1) config::DoWannier = 1;
    656         }
    657         if(!ParseForParameter(verbose,FileBuffer,"CommonWannier", 0, 1, 1, int_type, &(config::CommonWannier), 1, optional)) {
    658                 config::CommonWannier = 0;
    659         } else {
    660                 if (config::CommonWannier < 0) config::CommonWannier = 0;
    661                 if (config::CommonWannier > 4) config::CommonWannier = 4;
    662         }
    663         if(!ParseForParameter(verbose,FileBuffer,"SawtoothStart", 0, 1, 1, double_type, &(config::SawtoothStart), 1, optional)) {
    664                 config::SawtoothStart = 0.01;
    665         } else {
    666                 if (config::SawtoothStart < 0.) config::SawtoothStart = 0.;
    667                 if (config::SawtoothStart > 1.) config::SawtoothStart = 1.;
    668         }
    669 
    670         ParseForParameter(verbose,FileBuffer,"MaxOuterStep", 0, 1, 1, int_type, &(config::MaxOuterStep), 1, critical);
    671         if (!ParseForParameter(verbose,FileBuffer,"Deltat", 0, 1, 1, double_type, &(config::Deltat), 1, optional))
    672                 config::Deltat = 1;
    673         ParseForParameter(verbose,FileBuffer,"OutVisStep", 0, 1, 1, int_type, &(config::OutVisStep), 1, optional);
    674         ParseForParameter(verbose,FileBuffer,"OutSrcStep", 0, 1, 1, int_type, &(config::OutSrcStep), 1, optional);
    675         ParseForParameter(verbose,FileBuffer,"TargetTemp", 0, 1, 1, double_type, &(config::TargetTemp), 1, optional);
    676         //ParseForParameter(verbose,FileBuffer,"Thermostat", 0, 1, 1, int_type, &(config::ScaleTempStep), 1, optional);
    677         if (!ParseForParameter(verbose,FileBuffer,"EpsWannier", 0, 1, 1, double_type, &(config::EpsWannier), 1, optional))
    678                 config::EpsWannier = 1e-8;
    679 
    680         // stop conditions
    681         //if (config::MaxOuterStep <= 0) config::MaxOuterStep = 1;
    682         ParseForParameter(verbose,FileBuffer,"MaxPsiStep", 0, 1, 1, int_type, &(config::MaxPsiStep), 1, critical);
    683         if (config::MaxPsiStep <= 0) config::MaxPsiStep = 3;
    684 
    685         ParseForParameter(verbose,FileBuffer,"MaxMinStep", 0, 1, 1, int_type, &(config::MaxMinStep), 1, critical);
    686         ParseForParameter(verbose,FileBuffer,"RelEpsTotalE", 0, 1, 1, double_type, &(config::RelEpsTotalEnergy), 1, critical);
    687         ParseForParameter(verbose,FileBuffer,"RelEpsKineticE", 0, 1, 1, double_type, &(config::RelEpsKineticEnergy), 1, critical);
    688         ParseForParameter(verbose,FileBuffer,"MaxMinStopStep", 0, 1, 1, int_type, &(config::MaxMinStopStep), 1, critical);
    689         ParseForParameter(verbose,FileBuffer,"MaxMinGapStopStep", 0, 1, 1, int_type, &(config::MaxMinGapStopStep), 1, critical);
    690         if (config::MaxMinStep <= 0) config::MaxMinStep = config::MaxPsiStep;
    691         if (config::MaxMinStopStep < 1) config::MaxMinStopStep = 1;
    692         if (config::MaxMinGapStopStep < 1) config::MaxMinGapStopStep = 1;
    693 
    694         ParseForParameter(verbose,FileBuffer,"MaxInitMinStep", 0, 1, 1, int_type, &(config::MaxInitMinStep), 1, critical);
    695         ParseForParameter(verbose,FileBuffer,"InitRelEpsTotalE", 0, 1, 1, double_type, &(config::InitRelEpsTotalEnergy), 1, critical);
    696         ParseForParameter(verbose,FileBuffer,"InitRelEpsKineticE", 0, 1, 1, double_type, &(config::InitRelEpsKineticEnergy), 1, critical);
    697         ParseForParameter(verbose,FileBuffer,"InitMaxMinStopStep", 0, 1, 1, int_type, &(config::InitMaxMinStopStep), 1, critical);
    698         ParseForParameter(verbose,FileBuffer,"InitMaxMinGapStopStep", 0, 1, 1, int_type, &(config::InitMaxMinGapStopStep), 1, critical);
    699         if (config::MaxInitMinStep <= 0) config::MaxInitMinStep = config::MaxPsiStep;
    700         if (config::InitMaxMinStopStep < 1) config::InitMaxMinStopStep = 1;
    701         if (config::InitMaxMinGapStopStep < 1) config::InitMaxMinGapStopStep = 1;
    702 
    703         // Unit cell and magnetic field
    704         ParseForParameter(verbose,FileBuffer, "BoxLength", 0, 3, 3, lower_trigrid, BoxLength, 1, critical); /* Lattice->RealBasis */
    705         mol->cell_size[0] = BoxLength[0];
    706         mol->cell_size[1] = BoxLength[3];
    707         mol->cell_size[2] = BoxLength[4];
    708         mol->cell_size[3] = BoxLength[6];
    709         mol->cell_size[4] = BoxLength[7];
    710         mol->cell_size[5] = BoxLength[8];
    711         //if (1) fprintf(stderr,"\n");
    712 
    713         ParseForParameter(verbose,FileBuffer,"DoPerturbation", 0, 1, 1, int_type, &(config::DoPerturbation), 1, optional);
    714         ParseForParameter(verbose,FileBuffer,"DoOutNICS", 0, 1, 1, int_type, &(config::DoOutNICS), 1, optional);
    715         if (!ParseForParameter(verbose,FileBuffer,"DoFullCurrent", 0, 1, 1, int_type, &(config::DoFullCurrent), 1, optional))
    716                 config::DoFullCurrent = 0;
    717         if (config::DoFullCurrent < 0) config::DoFullCurrent = 0;
    718         if (config::DoFullCurrent > 2) config::DoFullCurrent = 2;
    719         if (config::DoOutNICS < 0) config::DoOutNICS = 0;
    720         if (config::DoOutNICS > 2) config::DoOutNICS = 2;
    721         if (config::DoPerturbation == 0) {
    722                 config::DoFullCurrent = 0;
    723                 config::DoOutNICS = 0;
    724         }
    725 
    726         ParseForParameter(verbose,FileBuffer,"ECut", 0, 1, 1, double_type, &(config::ECut), 1, critical);
    727         ParseForParameter(verbose,FileBuffer,"MaxLevel", 0, 1, 1, int_type, &(config::MaxLevel), 1, critical);
    728         ParseForParameter(verbose,FileBuffer,"Level0Factor", 0, 1, 1, int_type, &(config::Lev0Factor), 1, critical);
    729         if (config::Lev0Factor < 2) {
    730                 config::Lev0Factor = 2;
    731         }
    732         ParseForParameter(verbose,FileBuffer,"RiemannTensor", 0, 1, 1, int_type, &di, 1, critical);
    733         if (di >= 0 && di < 2) {
    734                 config::RiemannTensor = di;
    735         } else {
    736                 fprintf(stderr, "0 <= RiemanTensor < 2: 0 UseNotRT, 1 UseRT");
    737                 exit(1);
    738         }
    739         switch (config::RiemannTensor) {
    740                 case 0: //UseNoRT
    741                         if (config::MaxLevel < 2) {
    742                                 config::MaxLevel = 2;
    743                         }
    744                         config::LevRFactor = 2;
    745                         config::RTActualUse = 0;
    746                         break;
    747                 case 1: // UseRT
    748                         if (config::MaxLevel < 3) {
    749                                 config::MaxLevel = 3;
    750                         }
    751                         ParseForParameter(verbose,FileBuffer,"RiemannLevel", 0, 1, 1, int_type, &(config::RiemannLevel), 1, critical);
    752                         if (config::RiemannLevel < 2) {
    753                                 config::RiemannLevel = 2;
    754                         }
    755                         if (config::RiemannLevel > config::MaxLevel-1) {
    756                                 config::RiemannLevel = config::MaxLevel-1;
    757                         }
    758                         ParseForParameter(verbose,FileBuffer,"LevRFactor", 0, 1, 1, int_type, &(config::LevRFactor), 1, critical);
    759                         if (config::LevRFactor < 2) {
    760                                 config::LevRFactor = 2;
    761                         }
    762                         config::Lev0Factor = 2;
    763                         config::RTActualUse = 2;
    764                         break;
    765         }
    766         ParseForParameter(verbose,FileBuffer,"PsiType", 0, 1, 1, int_type, &di, 1, critical);
    767         if (di >= 0 && di < 2) {
    768                 config::PsiType = di;
    769         } else {
    770                 fprintf(stderr, "0 <= PsiType < 2: 0 UseSpinDouble, 1 UseSpinUpDown");
    771                 exit(1);
    772         }
    773         switch (config::PsiType) {
    774         case 0: // SpinDouble
    775                 ParseForParameter(verbose,FileBuffer,"MaxPsiDouble", 0, 1, 1, int_type, &(config::MaxPsiDouble), 1, critical);
    776                 ParseForParameter(verbose,FileBuffer,"AddPsis", 0, 1, 1, int_type, &(config::AddPsis), 1, optional);
    777                 break;
    778         case 1: // SpinUpDown
    779                 if (config::ProcPEGamma % 2) config::ProcPEGamma*=2;
    780                 ParseForParameter(verbose,FileBuffer,"PsiMaxNoUp", 0, 1, 1, int_type, &(config::PsiMaxNoUp), 1, critical);
    781                 ParseForParameter(verbose,FileBuffer,"PsiMaxNoDown", 0, 1, 1, int_type, &(config::PsiMaxNoDown), 1, critical);
    782                 ParseForParameter(verbose,FileBuffer,"AddPsis", 0, 1, 1, int_type, &(config::AddPsis), 1, optional);
    783                 break;
    784         }
    785 
    786         // IonsInitRead
    787 
    788         ParseForParameter(verbose,FileBuffer,"RCut", 0, 1, 1, double_type, &(config::RCut), 1, critical);
    789         ParseForParameter(verbose,FileBuffer,"IsAngstroem", 0, 1, 1, int_type, &(config::IsAngstroem), 1, critical);
    790         ParseForParameter(verbose,FileBuffer,"MaxTypes", 0, 1, 1, int_type, &(config::MaxTypes), 1, critical);
    791         if (!ParseForParameter(verbose,FileBuffer,"RelativeCoord", 0, 1, 1, int_type, &(config::RelativeCoord) , 1, optional))
    792                 config::RelativeCoord = 0;
    793         if (!ParseForParameter(verbose,FileBuffer,"StructOpt", 0, 1, 1, int_type, &(config::StructOpt), 1, optional))
    794                 config::StructOpt = 0;
    795         if (MaxTypes == 0) {
    796                 cerr << "There are no atoms according to MaxTypes in this config file." << endl;
    797         } else {
    798                 // prescan number of ions per type
    799                 cout << Verbose(0) << "Prescanning ions per type: " << endl;
    800                 int NoAtoms = 0;
    801                 for (int i=0; i < config::MaxTypes; i++) {
    802                         sprintf(name,"Ion_Type%i",i+1);
    803                         ParseForParameter(verbose,FileBuffer, (const char*)name, 0, 1, 1, int_type, &No[i], 1, critical);
    804                         ParseForParameter(verbose,FileBuffer, name, 0, 2, 1, int_type, &Z, 1, critical);
    805                         elementhash[i] = periode->FindElement(Z);
    806                         cout << Verbose(1) << i << ". Z = " << elementhash[i]->Z << " with " << No[i] << " ions." << endl;
    807                         NoAtoms += No[i];
    808                 }
    809                 int repetition = 0; // which repeated keyword shall be read
    810 
    811                 // sort the lines via the LineMapping
     603  FileBuffer->InitMapping();
     604
     605  /* Oeffne Hauptparameterdatei */
     606  int di;
     607  double BoxLength[9];
     608  string zeile;
     609  string dummy;
     610  element *elementhash[MAX_ELEMENTS];
     611  char name[MAX_ELEMENTS];
     612  char keyword[MAX_ELEMENTS];
     613  int Z, No[MAX_ELEMENTS];
     614  int verbose = 0;
     615  double value[3];
     616
     617  /* Namen einlesen */
     618
     619  ParseForParameter(verbose,FileBuffer, "mainname", 0, 1, 1, string_type, (config::mainname), 1, critical);
     620  ParseForParameter(verbose,FileBuffer, "defaultpath", 0, 1, 1, string_type, (config::defaultpath), 1, critical);
     621  ParseForParameter(verbose,FileBuffer, "pseudopotpath", 0, 1, 1, string_type, (config::pseudopotpath), 1, critical);
     622  ParseForParameter(verbose,FileBuffer,"ProcPEGamma", 0, 1, 1, int_type, &(config::ProcPEGamma), 1, critical);
     623  ParseForParameter(verbose,FileBuffer,"ProcPEPsi", 0, 1, 1, int_type, &(config::ProcPEPsi), 1, critical);
     624
     625  if (!ParseForParameter(verbose,FileBuffer,"Seed", 0, 1, 1, int_type, &(config::Seed), 1, optional))
     626    config::Seed = 1;
     627
     628  if(!ParseForParameter(verbose,FileBuffer,"DoOutOrbitals", 0, 1, 1, int_type, &(config::DoOutOrbitals), 1, optional)) {
     629    config::DoOutOrbitals = 0;
     630  } else {
     631    if (config::DoOutOrbitals < 0) config::DoOutOrbitals = 0;
     632    if (config::DoOutOrbitals > 1) config::DoOutOrbitals = 1;
     633  }
     634  ParseForParameter(verbose,FileBuffer,"DoOutVis", 0, 1, 1, int_type, &(config::DoOutVis), 1, critical);
     635  if (config::DoOutVis < 0) config::DoOutVis = 0;
     636  if (config::DoOutVis > 1) config::DoOutVis = 1;
     637  if (!ParseForParameter(verbose,FileBuffer,"VectorPlane", 0, 1, 1, int_type, &(config::VectorPlane), 1, optional))
     638    config::VectorPlane = -1;
     639  if (!ParseForParameter(verbose,FileBuffer,"VectorCut", 0, 1, 1, double_type, &(config::VectorCut), 1, optional))
     640    config::VectorCut = 0.;
     641  ParseForParameter(verbose,FileBuffer,"DoOutMes", 0, 1, 1, int_type, &(config::DoOutMes), 1, critical);
     642  if (config::DoOutMes < 0) config::DoOutMes = 0;
     643  if (config::DoOutMes > 1) config::DoOutMes = 1;
     644  if (!ParseForParameter(verbose,FileBuffer,"DoOutCurr", 0, 1, 1, int_type, &(config::DoOutCurrent), 1, optional))
     645    config::DoOutCurrent = 0;
     646  if (config::DoOutCurrent < 0) config::DoOutCurrent = 0;
     647  if (config::DoOutCurrent > 1) config::DoOutCurrent = 1;
     648  ParseForParameter(verbose,FileBuffer,"AddGramSch", 0, 1, 1, int_type, &(config::UseAddGramSch), 1, critical);
     649  if (config::UseAddGramSch < 0) config::UseAddGramSch = 0;
     650  if (config::UseAddGramSch > 2) config::UseAddGramSch = 2;
     651  if(!ParseForParameter(verbose,FileBuffer,"DoWannier", 0, 1, 1, int_type, &(config::DoWannier), 1, optional)) {
     652    config::DoWannier = 0;
     653  } else {
     654    if (config::DoWannier < 0) config::DoWannier = 0;
     655    if (config::DoWannier > 1) config::DoWannier = 1;
     656  }
     657  if(!ParseForParameter(verbose,FileBuffer,"CommonWannier", 0, 1, 1, int_type, &(config::CommonWannier), 1, optional)) {
     658    config::CommonWannier = 0;
     659  } else {
     660    if (config::CommonWannier < 0) config::CommonWannier = 0;
     661    if (config::CommonWannier > 4) config::CommonWannier = 4;
     662  }
     663  if(!ParseForParameter(verbose,FileBuffer,"SawtoothStart", 0, 1, 1, double_type, &(config::SawtoothStart), 1, optional)) {
     664    config::SawtoothStart = 0.01;
     665  } else {
     666    if (config::SawtoothStart < 0.) config::SawtoothStart = 0.;
     667    if (config::SawtoothStart > 1.) config::SawtoothStart = 1.;
     668  }
     669
     670  ParseForParameter(verbose,FileBuffer,"MaxOuterStep", 0, 1, 1, int_type, &(config::MaxOuterStep), 1, critical);
     671  if (!ParseForParameter(verbose,FileBuffer,"Deltat", 0, 1, 1, double_type, &(config::Deltat), 1, optional))
     672    config::Deltat = 1;
     673  ParseForParameter(verbose,FileBuffer,"OutVisStep", 0, 1, 1, int_type, &(config::OutVisStep), 1, optional);
     674  ParseForParameter(verbose,FileBuffer,"OutSrcStep", 0, 1, 1, int_type, &(config::OutSrcStep), 1, optional);
     675  ParseForParameter(verbose,FileBuffer,"TargetTemp", 0, 1, 1, double_type, &(config::TargetTemp), 1, optional);
     676  //ParseForParameter(verbose,FileBuffer,"Thermostat", 0, 1, 1, int_type, &(config::ScaleTempStep), 1, optional);
     677  if (!ParseForParameter(verbose,FileBuffer,"EpsWannier", 0, 1, 1, double_type, &(config::EpsWannier), 1, optional))
     678    config::EpsWannier = 1e-8;
     679
     680  // stop conditions
     681  //if (config::MaxOuterStep <= 0) config::MaxOuterStep = 1;
     682  ParseForParameter(verbose,FileBuffer,"MaxPsiStep", 0, 1, 1, int_type, &(config::MaxPsiStep), 1, critical);
     683  if (config::MaxPsiStep <= 0) config::MaxPsiStep = 3;
     684
     685  ParseForParameter(verbose,FileBuffer,"MaxMinStep", 0, 1, 1, int_type, &(config::MaxMinStep), 1, critical);
     686  ParseForParameter(verbose,FileBuffer,"RelEpsTotalE", 0, 1, 1, double_type, &(config::RelEpsTotalEnergy), 1, critical);
     687  ParseForParameter(verbose,FileBuffer,"RelEpsKineticE", 0, 1, 1, double_type, &(config::RelEpsKineticEnergy), 1, critical);
     688  ParseForParameter(verbose,FileBuffer,"MaxMinStopStep", 0, 1, 1, int_type, &(config::MaxMinStopStep), 1, critical);
     689  ParseForParameter(verbose,FileBuffer,"MaxMinGapStopStep", 0, 1, 1, int_type, &(config::MaxMinGapStopStep), 1, critical);
     690  if (config::MaxMinStep <= 0) config::MaxMinStep = config::MaxPsiStep;
     691  if (config::MaxMinStopStep < 1) config::MaxMinStopStep = 1;
     692  if (config::MaxMinGapStopStep < 1) config::MaxMinGapStopStep = 1;
     693
     694  ParseForParameter(verbose,FileBuffer,"MaxInitMinStep", 0, 1, 1, int_type, &(config::MaxInitMinStep), 1, critical);
     695  ParseForParameter(verbose,FileBuffer,"InitRelEpsTotalE", 0, 1, 1, double_type, &(config::InitRelEpsTotalEnergy), 1, critical);
     696  ParseForParameter(verbose,FileBuffer,"InitRelEpsKineticE", 0, 1, 1, double_type, &(config::InitRelEpsKineticEnergy), 1, critical);
     697  ParseForParameter(verbose,FileBuffer,"InitMaxMinStopStep", 0, 1, 1, int_type, &(config::InitMaxMinStopStep), 1, critical);
     698  ParseForParameter(verbose,FileBuffer,"InitMaxMinGapStopStep", 0, 1, 1, int_type, &(config::InitMaxMinGapStopStep), 1, critical);
     699  if (config::MaxInitMinStep <= 0) config::MaxInitMinStep = config::MaxPsiStep;
     700  if (config::InitMaxMinStopStep < 1) config::InitMaxMinStopStep = 1;
     701  if (config::InitMaxMinGapStopStep < 1) config::InitMaxMinGapStopStep = 1;
     702
     703  // Unit cell and magnetic field
     704  ParseForParameter(verbose,FileBuffer, "BoxLength", 0, 3, 3, lower_trigrid, BoxLength, 1, critical); /* Lattice->RealBasis */
     705  mol->cell_size[0] = BoxLength[0];
     706  mol->cell_size[1] = BoxLength[3];
     707  mol->cell_size[2] = BoxLength[4];
     708  mol->cell_size[3] = BoxLength[6];
     709  mol->cell_size[4] = BoxLength[7];
     710  mol->cell_size[5] = BoxLength[8];
     711  //if (1) fprintf(stderr,"\n");
     712
     713  ParseForParameter(verbose,FileBuffer,"DoPerturbation", 0, 1, 1, int_type, &(config::DoPerturbation), 1, optional);
     714  ParseForParameter(verbose,FileBuffer,"DoOutNICS", 0, 1, 1, int_type, &(config::DoOutNICS), 1, optional);
     715  if (!ParseForParameter(verbose,FileBuffer,"DoFullCurrent", 0, 1, 1, int_type, &(config::DoFullCurrent), 1, optional))
     716    config::DoFullCurrent = 0;
     717  if (config::DoFullCurrent < 0) config::DoFullCurrent = 0;
     718  if (config::DoFullCurrent > 2) config::DoFullCurrent = 2;
     719  if (config::DoOutNICS < 0) config::DoOutNICS = 0;
     720  if (config::DoOutNICS > 2) config::DoOutNICS = 2;
     721  if (config::DoPerturbation == 0) {
     722    config::DoFullCurrent = 0;
     723    config::DoOutNICS = 0;
     724  }
     725
     726  ParseForParameter(verbose,FileBuffer,"ECut", 0, 1, 1, double_type, &(config::ECut), 1, critical);
     727  ParseForParameter(verbose,FileBuffer,"MaxLevel", 0, 1, 1, int_type, &(config::MaxLevel), 1, critical);
     728  ParseForParameter(verbose,FileBuffer,"Level0Factor", 0, 1, 1, int_type, &(config::Lev0Factor), 1, critical);
     729  if (config::Lev0Factor < 2) {
     730    config::Lev0Factor = 2;
     731  }
     732  ParseForParameter(verbose,FileBuffer,"RiemannTensor", 0, 1, 1, int_type, &di, 1, critical);
     733  if (di >= 0 && di < 2) {
     734    config::RiemannTensor = di;
     735  } else {
     736    fprintf(stderr, "0 <= RiemanTensor < 2: 0 UseNotRT, 1 UseRT");
     737    exit(1);
     738  }
     739  switch (config::RiemannTensor) {
     740    case 0: //UseNoRT
     741      if (config::MaxLevel < 2) {
     742        config::MaxLevel = 2;
     743      }
     744      config::LevRFactor = 2;
     745      config::RTActualUse = 0;
     746      break;
     747    case 1: // UseRT
     748      if (config::MaxLevel < 3) {
     749        config::MaxLevel = 3;
     750      }
     751      ParseForParameter(verbose,FileBuffer,"RiemannLevel", 0, 1, 1, int_type, &(config::RiemannLevel), 1, critical);
     752      if (config::RiemannLevel < 2) {
     753        config::RiemannLevel = 2;
     754      }
     755      if (config::RiemannLevel > config::MaxLevel-1) {
     756        config::RiemannLevel = config::MaxLevel-1;
     757      }
     758      ParseForParameter(verbose,FileBuffer,"LevRFactor", 0, 1, 1, int_type, &(config::LevRFactor), 1, critical);
     759      if (config::LevRFactor < 2) {
     760        config::LevRFactor = 2;
     761      }
     762      config::Lev0Factor = 2;
     763      config::RTActualUse = 2;
     764      break;
     765  }
     766  ParseForParameter(verbose,FileBuffer,"PsiType", 0, 1, 1, int_type, &di, 1, critical);
     767  if (di >= 0 && di < 2) {
     768    config::PsiType = di;
     769  } else {
     770    fprintf(stderr, "0 <= PsiType < 2: 0 UseSpinDouble, 1 UseSpinUpDown");
     771    exit(1);
     772  }
     773  switch (config::PsiType) {
     774  case 0: // SpinDouble
     775    ParseForParameter(verbose,FileBuffer,"MaxPsiDouble", 0, 1, 1, int_type, &(config::MaxPsiDouble), 1, critical);
     776    ParseForParameter(verbose,FileBuffer,"AddPsis", 0, 1, 1, int_type, &(config::AddPsis), 1, optional);
     777    break;
     778  case 1: // SpinUpDown
     779    if (config::ProcPEGamma % 2) config::ProcPEGamma*=2;
     780    ParseForParameter(verbose,FileBuffer,"PsiMaxNoUp", 0, 1, 1, int_type, &(config::PsiMaxNoUp), 1, critical);
     781    ParseForParameter(verbose,FileBuffer,"PsiMaxNoDown", 0, 1, 1, int_type, &(config::PsiMaxNoDown), 1, critical);
     782    ParseForParameter(verbose,FileBuffer,"AddPsis", 0, 1, 1, int_type, &(config::AddPsis), 1, optional);
     783    break;
     784  }
     785
     786  // IonsInitRead
     787
     788  ParseForParameter(verbose,FileBuffer,"RCut", 0, 1, 1, double_type, &(config::RCut), 1, critical);
     789  ParseForParameter(verbose,FileBuffer,"IsAngstroem", 0, 1, 1, int_type, &(config::IsAngstroem), 1, critical);
     790  ParseForParameter(verbose,FileBuffer,"MaxTypes", 0, 1, 1, int_type, &(config::MaxTypes), 1, critical);
     791  if (!ParseForParameter(verbose,FileBuffer,"RelativeCoord", 0, 1, 1, int_type, &(config::RelativeCoord) , 1, optional))
     792    config::RelativeCoord = 0;
     793  if (!ParseForParameter(verbose,FileBuffer,"StructOpt", 0, 1, 1, int_type, &(config::StructOpt), 1, optional))
     794    config::StructOpt = 0;
     795  if (MaxTypes == 0) {
     796    cerr << "There are no atoms according to MaxTypes in this config file." << endl;
     797  } else {
     798    // prescan number of ions per type
     799    cout << Verbose(0) << "Prescanning ions per type: " << endl;
     800    int NoAtoms = 0;
     801    for (int i=0; i < config::MaxTypes; i++) {
     802      sprintf(name,"Ion_Type%i",i+1);
     803      ParseForParameter(verbose,FileBuffer, (const char*)name, 0, 1, 1, int_type, &No[i], 1, critical);
     804      ParseForParameter(verbose,FileBuffer, name, 0, 2, 1, int_type, &Z, 1, critical);
     805      elementhash[i] = periode->FindElement(Z);
     806      cout << Verbose(1) << i << ". Z = " << elementhash[i]->Z << " with " << No[i] << " ions." << endl;
     807      NoAtoms += No[i];
     808    }
     809    int repetition = 0; // which repeated keyword shall be read
     810
     811    // sort the lines via the LineMapping
    812812    sprintf(name,"Ion_Type%i",config::MaxTypes);
    813                 if (!ParseForParameter(verbose,FileBuffer, (const char*)name, 1, 1, 1, int_type, &value[0], 1, critical)) {
    814                   cerr << "There are no atoms in the config file!" << endl;
     813    if (!ParseForParameter(verbose,FileBuffer, (const char*)name, 1, 1, 1, int_type, &value[0], 1, critical)) {
     814      cerr << "There are no atoms in the config file!" << endl;
    815815      return;
    816816    }
    817                 FileBuffer->CurrentLine++;
    818                 //cout << FileBuffer->buffer[ FileBuffer->LineMapping[FileBuffer->CurrentLine]];
    819                 FileBuffer->MapIonTypesInBuffer(NoAtoms);
    820                 //for (int i=0; i<(NoAtoms < 100 ? NoAtoms : 100 < 100 ? NoAtoms : 100);++i) {
    821                 //      cout << FileBuffer->buffer[ FileBuffer->LineMapping[FileBuffer->CurrentLine+i]];
    822                 //}
    823 
    824                 map<int, atom *> AtomList[config::MaxTypes];
    825                 map<int, atom *> LinearList;
    826                 if (!FastParsing) {
    827                         // parse in trajectories
    828                         bool status = true;
    829                         atom *neues = NULL;
    830                         while (status) {
    831                                 cout << "Currently parsing MD step " << repetition << "." << endl;
    832                                 for (int i=0; i < config::MaxTypes; i++) {
    833                                         sprintf(name,"Ion_Type%i",i+1);
    834                                         for(int j=0;j<No[i];j++) {
    835                                                 sprintf(keyword,"%s_%i",name, j+1);
    836                                                 if (repetition == 0) {
    837                                                         neues = new atom();
    838                                                         AtomList[i][j] = neues;
    839                                                         LinearList[FileBuffer->CurrentLine] = neues;
    840                                                         neues->type = elementhash[i]; // find element type
    841                                                 } else
    842                                                         neues = AtomList[i][j];
     817    FileBuffer->CurrentLine++;
     818    //cout << FileBuffer->buffer[ FileBuffer->LineMapping[FileBuffer->CurrentLine]];
     819    FileBuffer->MapIonTypesInBuffer(NoAtoms);
     820    //for (int i=0; i<(NoAtoms < 100 ? NoAtoms : 100 < 100 ? NoAtoms : 100);++i) {
     821    //  cout << FileBuffer->buffer[ FileBuffer->LineMapping[FileBuffer->CurrentLine+i]];
     822    //}
     823
     824    map<int, atom *> AtomList[config::MaxTypes];
     825    map<int, atom *> LinearList;
     826    if (!FastParsing) {
     827      // parse in trajectories
     828      bool status = true;
     829      atom *neues = NULL;
     830      while (status) {
     831        cout << "Currently parsing MD step " << repetition << "." << endl;
     832        for (int i=0; i < config::MaxTypes; i++) {
     833          sprintf(name,"Ion_Type%i",i+1);
     834          for(int j=0;j<No[i];j++) {
     835            sprintf(keyword,"%s_%i",name, j+1);
     836            if (repetition == 0) {
     837              neues = new atom();
     838              AtomList[i][j] = neues;
     839              LinearList[FileBuffer->CurrentLine] = neues;
     840              neues->type = elementhash[i]; // find element type
     841            } else
     842              neues = AtomList[i][j];
    843843            status = (status &&
    844                                                                                 ParseForParameter(verbose,FileBuffer, keyword, 0, 1, 1, double_type, &neues->x.x[0], 1, (repetition == 0) ? critical : optional) &&
    845                                                                                 ParseForParameter(verbose,FileBuffer, keyword, 0, 2, 1, double_type, &neues->x.x[1], 1, (repetition == 0) ? critical : optional) &&
    846                                                                                 ParseForParameter(verbose,FileBuffer, keyword, 0, 3, 1, double_type, &neues->x.x[2], 1, (repetition == 0) ? critical : optional) &&
    847                                                                                 ParseForParameter(verbose,FileBuffer, keyword, 0, 4, 1, int_type, &neues->FixedIon, 1, (repetition == 0) ? critical : optional));
    848                                                 if (!status) break;
    849 
    850                                                 // check size of vectors
    851                                                 if (mol->Trajectories[neues].R.size() <= (unsigned int)(repetition)) {
    852                                                         //cout << "Increasing size for trajectory array of " << keyword << " to " << (repetition+10) << "." << endl;
    853                                                         mol->Trajectories[neues].R.resize(repetition+10);
    854                                                         mol->Trajectories[neues].U.resize(repetition+10);
    855                                                         mol->Trajectories[neues].F.resize(repetition+10);
    856                                                 }
    857 
    858                                                 // put into trajectories list
    859                                                 for (int d=0;d<NDIM;d++)
    860                                                         mol->Trajectories[neues].R.at(repetition).x[d] = neues->x.x[d];
    861 
    862                                                 // parse velocities if present
    863                                                 if(!ParseForParameter(verbose,FileBuffer, keyword, 0, 5, 1, double_type, &neues->v.x[0], 1,optional))
    864                                                         neues->v.x[0] = 0.;
    865                                                 if(!ParseForParameter(verbose,FileBuffer, keyword, 0, 6, 1, double_type, &neues->v.x[1], 1,optional))
    866                                                         neues->v.x[1] = 0.;
    867                                                 if(!ParseForParameter(verbose,FileBuffer, keyword, 0, 7, 1, double_type, &neues->v.x[2], 1,optional))
    868                                                         neues->v.x[2] = 0.;
    869                                                 for (int d=0;d<NDIM;d++)
    870                                                         mol->Trajectories[neues].U.at(repetition).x[d] = neues->v.x[d];
    871 
    872                                                 // parse forces if present
    873                                                 if(!ParseForParameter(verbose,FileBuffer, keyword, 0, 8, 1, double_type, &value[0], 1,optional))
    874                                                         value[0] = 0.;
    875                                                 if(!ParseForParameter(verbose,FileBuffer, keyword, 0, 9, 1, double_type, &value[1], 1,optional))
    876                                                         value[1] = 0.;
    877                                                 if(!ParseForParameter(verbose,FileBuffer, keyword, 1, 10, 1, double_type, &value[2], 1,optional))
    878                                                         value[2] = 0.;
    879                                                 for (int d=0;d<NDIM;d++)
    880                                                         mol->Trajectories[neues].F.at(repetition).x[d] = value[d];
    881 
    882         //                                              cout << "Parsed position of step " << (repetition) << ": (";
    883         //                                              for (int d=0;d<NDIM;d++)
    884         //                                                      cout << mol->Trajectories[neues].R.at(repetition).x[d] << " ";                                  // next step
    885         //                                              cout << ")\t(";
    886         //                                              for (int d=0;d<NDIM;d++)
    887         //                                                      cout << mol->Trajectories[neues].U.at(repetition).x[d] << " ";                                  // next step
    888         //                                              cout << ")\t(";
    889         //                                              for (int d=0;d<NDIM;d++)
    890         //                                                      cout << mol->Trajectories[neues].F.at(repetition).x[d] << " ";                                  // next step
    891         //                                              cout << ")" << endl;
    892                                         }
    893                                 }
    894                                 repetition++;
    895                         }
    896                         // put atoms into the molecule in their original order
    897                         for(map<int, atom*>::iterator runner = LinearList.begin(); runner != LinearList.end(); ++runner) {
    898                                 mol->AddAtom(runner->second);
    899                         }
    900                         repetition--;
    901                         cout << "Found " << repetition << " trajectory steps." << endl;
    902                         mol->MDSteps = repetition;
    903                 } else {
    904                         // find the maximum number of MD steps so that we may parse last one (Ion_Type1_1 must always be present, because is the first atom)
    905                         repetition = 0;
    906                         while ( ParseForParameter(verbose,FileBuffer, "Ion_Type1_1", 0, 1, 1, double_type, &value[0], repetition, (repetition == 0) ? critical : optional) &&
    907                                                         ParseForParameter(verbose,FileBuffer, "Ion_Type1_1", 0, 2, 1, double_type, &value[1], repetition, (repetition == 0) ? critical : optional) &&
    908                                                         ParseForParameter(verbose,FileBuffer, "Ion_Type1_1", 0, 3, 1, double_type, &value[2], repetition, (repetition == 0) ? critical : optional))
    909                                 repetition++;
    910                         cout << "I found " << repetition << " times the keyword Ion_Type1_1." << endl;
    911                         // parse in molecule coordinates
    912                         for (int i=0; i < config::MaxTypes; i++) {
    913                                 sprintf(name,"Ion_Type%i",i+1);
    914                                 for(int j=0;j<No[i];j++) {
    915                                         sprintf(keyword,"%s_%i",name, j+1);
    916                                         atom *neues = new atom();
    917                                         // then parse for each atom the coordinates as often as present
    918                                         ParseForParameter(verbose,FileBuffer, keyword, 0, 1, 1, double_type, &neues->x.x[0], repetition,critical);
    919                                         ParseForParameter(verbose,FileBuffer, keyword, 0, 2, 1, double_type, &neues->x.x[1], repetition,critical);
    920                                         ParseForParameter(verbose,FileBuffer, keyword, 0, 3, 1, double_type, &neues->x.x[2], repetition,critical);
    921                                         ParseForParameter(verbose,FileBuffer, keyword, 0, 4, 1, int_type, &neues->FixedIon, repetition,critical);
    922                                         if(!ParseForParameter(verbose,FileBuffer, keyword, 0, 5, 1, double_type, &neues->v.x[0], repetition,optional))
    923                                                 neues->v.x[0] = 0.;
    924                                         if(!ParseForParameter(verbose,FileBuffer, keyword, 0, 6, 1, double_type, &neues->v.x[1], repetition,optional))
    925                                                 neues->v.x[1] = 0.;
    926                                         if(!ParseForParameter(verbose,FileBuffer, keyword, 0, 7, 1, double_type, &neues->v.x[2], repetition,optional))
    927                                                 neues->v.x[2] = 0.;
    928                                         // here we don't care if forces are present (last in trajectories is always equal to current position)
    929                                         neues->type = elementhash[i]; // find element type
    930                                         mol->AddAtom(neues);
    931                                 }
    932                         }
    933                 }
    934         }
    935         delete(FileBuffer);
     844                    ParseForParameter(verbose,FileBuffer, keyword, 0, 1, 1, double_type, &neues->x.x[0], 1, (repetition == 0) ? critical : optional) &&
     845                    ParseForParameter(verbose,FileBuffer, keyword, 0, 2, 1, double_type, &neues->x.x[1], 1, (repetition == 0) ? critical : optional) &&
     846                    ParseForParameter(verbose,FileBuffer, keyword, 0, 3, 1, double_type, &neues->x.x[2], 1, (repetition == 0) ? critical : optional) &&
     847                    ParseForParameter(verbose,FileBuffer, keyword, 0, 4, 1, int_type, &neues->FixedIon, 1, (repetition == 0) ? critical : optional));
     848            if (!status) break;
     849
     850            // check size of vectors
     851            if (mol->Trajectories[neues].R.size() <= (unsigned int)(repetition)) {
     852              //cout << "Increasing size for trajectory array of " << keyword << " to " << (repetition+10) << "." << endl;
     853              mol->Trajectories[neues].R.resize(repetition+10);
     854              mol->Trajectories[neues].U.resize(repetition+10);
     855              mol->Trajectories[neues].F.resize(repetition+10);
     856            }
     857
     858            // put into trajectories list
     859            for (int d=0;d<NDIM;d++)
     860              mol->Trajectories[neues].R.at(repetition).x[d] = neues->x.x[d];
     861
     862            // parse velocities if present
     863            if(!ParseForParameter(verbose,FileBuffer, keyword, 0, 5, 1, double_type, &neues->v.x[0], 1,optional))
     864              neues->v.x[0] = 0.;
     865            if(!ParseForParameter(verbose,FileBuffer, keyword, 0, 6, 1, double_type, &neues->v.x[1], 1,optional))
     866              neues->v.x[1] = 0.;
     867            if(!ParseForParameter(verbose,FileBuffer, keyword, 0, 7, 1, double_type, &neues->v.x[2], 1,optional))
     868              neues->v.x[2] = 0.;
     869            for (int d=0;d<NDIM;d++)
     870              mol->Trajectories[neues].U.at(repetition).x[d] = neues->v.x[d];
     871
     872            // parse forces if present
     873            if(!ParseForParameter(verbose,FileBuffer, keyword, 0, 8, 1, double_type, &value[0], 1,optional))
     874              value[0] = 0.;
     875            if(!ParseForParameter(verbose,FileBuffer, keyword, 0, 9, 1, double_type, &value[1], 1,optional))
     876              value[1] = 0.;
     877            if(!ParseForParameter(verbose,FileBuffer, keyword, 1, 10, 1, double_type, &value[2], 1,optional))
     878              value[2] = 0.;
     879            for (int d=0;d<NDIM;d++)
     880              mol->Trajectories[neues].F.at(repetition).x[d] = value[d];
     881
     882  //            cout << "Parsed position of step " << (repetition) << ": (";
     883  //            for (int d=0;d<NDIM;d++)
     884  //              cout << mol->Trajectories[neues].R.at(repetition).x[d] << " ";          // next step
     885  //            cout << ")\t(";
     886  //            for (int d=0;d<NDIM;d++)
     887  //              cout << mol->Trajectories[neues].U.at(repetition).x[d] << " ";          // next step
     888  //            cout << ")\t(";
     889  //            for (int d=0;d<NDIM;d++)
     890  //              cout << mol->Trajectories[neues].F.at(repetition).x[d] << " ";          // next step
     891  //            cout << ")" << endl;
     892          }
     893        }
     894        repetition++;
     895      }
     896      // put atoms into the molecule in their original order
     897      for(map<int, atom*>::iterator runner = LinearList.begin(); runner != LinearList.end(); ++runner) {
     898        mol->AddAtom(runner->second);
     899      }
     900      repetition--;
     901      cout << "Found " << repetition << " trajectory steps." << endl;
     902      mol->MDSteps = repetition;
     903    } else {
     904      // find the maximum number of MD steps so that we may parse last one (Ion_Type1_1 must always be present, because is the first atom)
     905      repetition = 0;
     906      while ( ParseForParameter(verbose,FileBuffer, "Ion_Type1_1", 0, 1, 1, double_type, &value[0], repetition, (repetition == 0) ? critical : optional) &&
     907              ParseForParameter(verbose,FileBuffer, "Ion_Type1_1", 0, 2, 1, double_type, &value[1], repetition, (repetition == 0) ? critical : optional) &&
     908              ParseForParameter(verbose,FileBuffer, "Ion_Type1_1", 0, 3, 1, double_type, &value[2], repetition, (repetition == 0) ? critical : optional))
     909        repetition++;
     910      cout << "I found " << repetition << " times the keyword Ion_Type1_1." << endl;
     911      // parse in molecule coordinates
     912      for (int i=0; i < config::MaxTypes; i++) {
     913        sprintf(name,"Ion_Type%i",i+1);
     914        for(int j=0;j<No[i];j++) {
     915          sprintf(keyword,"%s_%i",name, j+1);
     916          atom *neues = new atom();
     917          // then parse for each atom the coordinates as often as present
     918          ParseForParameter(verbose,FileBuffer, keyword, 0, 1, 1, double_type, &neues->x.x[0], repetition,critical);
     919          ParseForParameter(verbose,FileBuffer, keyword, 0, 2, 1, double_type, &neues->x.x[1], repetition,critical);
     920          ParseForParameter(verbose,FileBuffer, keyword, 0, 3, 1, double_type, &neues->x.x[2], repetition,critical);
     921          ParseForParameter(verbose,FileBuffer, keyword, 0, 4, 1, int_type, &neues->FixedIon, repetition,critical);
     922          if(!ParseForParameter(verbose,FileBuffer, keyword, 0, 5, 1, double_type, &neues->v.x[0], repetition,optional))
     923            neues->v.x[0] = 0.;
     924          if(!ParseForParameter(verbose,FileBuffer, keyword, 0, 6, 1, double_type, &neues->v.x[1], repetition,optional))
     925            neues->v.x[1] = 0.;
     926          if(!ParseForParameter(verbose,FileBuffer, keyword, 0, 7, 1, double_type, &neues->v.x[2], repetition,optional))
     927            neues->v.x[2] = 0.;
     928          // here we don't care if forces are present (last in trajectories is always equal to current position)
     929          neues->type = elementhash[i]; // find element type
     930          mol->AddAtom(neues);
     931        }
     932      }
     933    }
     934  }
     935  delete(FileBuffer);
    936936};
    937937
     
    943943void config::LoadOld(char *filename, periodentafel *periode, molecule *mol)
    944944{
    945         ifstream *file = new ifstream(filename);
    946         if (file == NULL) {
    947                 cerr << "ERROR: config file " << filename << " missing!" << endl;
    948                 return;
    949         }
    950         RetrieveConfigPathAndName(filename);
    951         // ParseParameters
    952 
    953         /* Oeffne Hauptparameterdatei */
    954         int l, i, di;
    955         double a,b;
    956         double BoxLength[9];
    957         string zeile;
    958         string dummy;
    959         element *elementhash[128];
    960         int Z, No, AtomNo, found;
    961         int verbose = 0;
    962 
    963         /* Namen einlesen */
    964 
    965         ParseForParameter(verbose,file, "mainname", 0, 1, 1, string_type, (config::mainname), 1, critical);
    966         ParseForParameter(verbose,file, "defaultpath", 0, 1, 1, string_type, (config::defaultpath), 1, critical);
    967         ParseForParameter(verbose,file, "pseudopotpath", 0, 1, 1, string_type, (config::pseudopotpath), 1, critical);
    968         ParseForParameter(verbose,file, "ProcsGammaPsi", 0, 1, 1, int_type, &(config::ProcPEGamma), 1, critical);
    969         ParseForParameter(verbose,file, "ProcsGammaPsi", 0, 2, 1, int_type, &(config::ProcPEPsi), 1, critical);
    970         config::Seed = 1;
    971         config::DoOutOrbitals = 0;
    972         ParseForParameter(verbose,file,"DoOutVis", 0, 1, 1, int_type, &(config::DoOutVis), 1, critical);
    973         if (config::DoOutVis < 0) config::DoOutVis = 0;
    974         if (config::DoOutVis > 1) config::DoOutVis = 1;
    975         config::VectorPlane = -1;
    976         config::VectorCut = 0.;
    977         ParseForParameter(verbose,file,"DoOutMes", 0, 1, 1, int_type, &(config::DoOutMes), 1, critical);
    978         if (config::DoOutMes < 0) config::DoOutMes = 0;
    979         if (config::DoOutMes > 1) config::DoOutMes = 1;
    980         config::DoOutCurrent = 0;
    981         ParseForParameter(verbose,file,"AddGramSch", 0, 1, 1, int_type, &(config::UseAddGramSch), 1, critical);
    982         if (config::UseAddGramSch < 0) config::UseAddGramSch = 0;
    983         if (config::UseAddGramSch > 2) config::UseAddGramSch = 2;
    984         config::CommonWannier = 0;
    985         config::SawtoothStart = 0.01;
    986 
    987         ParseForParameter(verbose,file,"MaxOuterStep", 0, 1, 1, double_type, &(config::MaxOuterStep), 1, critical);
    988         ParseForParameter(verbose,file,"Deltat", 0, 1, 1, double_type, &(config::Deltat), 1, optional);
    989         ParseForParameter(verbose,file,"VisOuterStep", 0, 1, 1, int_type, &(config::OutVisStep), 1, optional);
    990         ParseForParameter(verbose,file,"VisSrcOuterStep", 0, 1, 1, int_type, &(config::OutSrcStep), 1, optional);
    991         ParseForParameter(verbose,file,"TargetTemp", 0, 1, 1, double_type, &(config::TargetTemp), 1, optional);
    992         ParseForParameter(verbose,file,"ScaleTempStep", 0, 1, 1, int_type, &(config::ScaleTempStep), 1, optional);
    993         config::EpsWannier = 1e-8;
    994 
    995         // stop conditions
    996         //if (config::MaxOuterStep <= 0) config::MaxOuterStep = 1;
    997         ParseForParameter(verbose,file,"MaxPsiStep", 0, 1, 1, int_type, &(config::MaxPsiStep), 1, critical);
    998         if (config::MaxPsiStep <= 0) config::MaxPsiStep = 3;
    999 
    1000         ParseForParameter(verbose,file,"MaxMinStep", 0, 1, 1, int_type, &(config::MaxMinStep), 1, critical);
    1001         ParseForParameter(verbose,file,"MaxMinStep", 0, 2, 1, double_type, &(config::RelEpsTotalEnergy), 1, critical);
    1002         ParseForParameter(verbose,file,"MaxMinStep", 0, 3, 1, double_type, &(config::RelEpsKineticEnergy), 1, critical);
    1003         ParseForParameter(verbose,file,"MaxMinStep", 0, 4, 1, int_type, &(config::MaxMinStopStep), 1, critical);
    1004         if (config::MaxMinStep <= 0) config::MaxMinStep = config::MaxPsiStep;
    1005         if (config::MaxMinStopStep < 1) config::MaxMinStopStep = 1;
    1006         config::MaxMinGapStopStep = 1;
    1007 
    1008         ParseForParameter(verbose,file,"MaxInitMinStep", 0, 1, 1, int_type, &(config::MaxInitMinStep), 1, critical);
    1009         ParseForParameter(verbose,file,"MaxInitMinStep", 0, 2, 1, double_type, &(config::InitRelEpsTotalEnergy), 1, critical);
    1010         ParseForParameter(verbose,file,"MaxInitMinStep", 0, 3, 1, double_type, &(config::InitRelEpsKineticEnergy), 1, critical);
    1011         ParseForParameter(verbose,file,"MaxInitMinStep", 0, 4, 1, int_type, &(config::InitMaxMinStopStep), 1, critical);
    1012         if (config::MaxInitMinStep <= 0) config::MaxInitMinStep = config::MaxPsiStep;
    1013         if (config::InitMaxMinStopStep < 1) config::InitMaxMinStopStep = 1;
    1014         config::InitMaxMinGapStopStep = 1;
    1015 
    1016         ParseForParameter(verbose,file, "BoxLength", 0, 3, 3, lower_trigrid, BoxLength, 1, critical); /* Lattice->RealBasis */
    1017         mol->cell_size[0] = BoxLength[0];
    1018         mol->cell_size[1] = BoxLength[3];
    1019         mol->cell_size[2] = BoxLength[4];
    1020         mol->cell_size[3] = BoxLength[6];
    1021         mol->cell_size[4] = BoxLength[7];
    1022         mol->cell_size[5] = BoxLength[8];
    1023         if (1) fprintf(stderr,"\n");
    1024         config::DoPerturbation = 0;
    1025         config::DoFullCurrent = 0;
    1026 
    1027         ParseForParameter(verbose,file,"ECut", 0, 1, 1, double_type, &(config::ECut), 1, critical);
    1028         ParseForParameter(verbose,file,"MaxLevel", 0, 1, 1, int_type, &(config::MaxLevel), 1, critical);
    1029         ParseForParameter(verbose,file,"Level0Factor", 0, 1, 1, int_type, &(config::Lev0Factor), 1, critical);
    1030         if (config::Lev0Factor < 2) {
    1031                 config::Lev0Factor = 2;
    1032         }
    1033         ParseForParameter(verbose,file,"RiemannTensor", 0, 1, 1, int_type, &di, 1, critical);
    1034         if (di >= 0 && di < 2) {
    1035                 config::RiemannTensor = di;
    1036         } else {
    1037                 fprintf(stderr, "0 <= RiemanTensor < 2: 0 UseNotRT, 1 UseRT");
    1038                 exit(1);
    1039         }
    1040         switch (config::RiemannTensor) {
    1041                 case 0: //UseNoRT
    1042                         if (config::MaxLevel < 2) {
    1043                                 config::MaxLevel = 2;
    1044                         }
    1045                         config::LevRFactor = 2;
    1046                         config::RTActualUse = 0;
    1047                         break;
    1048                 case 1: // UseRT
    1049                         if (config::MaxLevel < 3) {
    1050                                 config::MaxLevel = 3;
    1051                         }
    1052                         ParseForParameter(verbose,file,"RiemannLevel", 0, 1, 1, int_type, &(config::RiemannLevel), 1, critical);
    1053                         if (config::RiemannLevel < 2) {
    1054                                 config::RiemannLevel = 2;
    1055                         }
    1056                         if (config::RiemannLevel > config::MaxLevel-1) {
    1057                                 config::RiemannLevel = config::MaxLevel-1;
    1058                         }
    1059                         ParseForParameter(verbose,file,"LevRFactor", 0, 1, 1, int_type, &(config::LevRFactor), 1, critical);
    1060                         if (config::LevRFactor < 2) {
    1061                                 config::LevRFactor = 2;
    1062                         }
    1063                         config::Lev0Factor = 2;
    1064                         config::RTActualUse = 2;
    1065                         break;
    1066         }
    1067         ParseForParameter(verbose,file,"PsiType", 0, 1, 1, int_type, &di, 1, critical);
    1068         if (di >= 0 && di < 2) {
    1069                 config::PsiType = di;
    1070         } else {
    1071                 fprintf(stderr, "0 <= PsiType < 2: 0 UseSpinDouble, 1 UseSpinUpDown");
    1072                 exit(1);
    1073         }
    1074         switch (config::PsiType) {
    1075         case 0: // SpinDouble
    1076                 ParseForParameter(verbose,file,"MaxPsiDouble", 0, 1, 1, int_type, &(config::MaxPsiDouble), 1, critical);
    1077                 config::AddPsis = 0;
    1078                 break;
    1079         case 1: // SpinUpDown
    1080                 if (config::ProcPEGamma % 2) config::ProcPEGamma*=2;
    1081                 ParseForParameter(verbose,file,"MaxPsiUp", 0, 1, 1, int_type, &(config::PsiMaxNoUp), 1, critical);
    1082                 ParseForParameter(verbose,file,"MaxPsiDown", 0, 1, 1, int_type, &(config::PsiMaxNoDown), 1, critical);
    1083                 config::AddPsis = 0;
    1084                 break;
    1085         }
    1086 
    1087         // IonsInitRead
    1088 
    1089         ParseForParameter(verbose,file,"RCut", 0, 1, 1, double_type, &(config::RCut), 1, critical);
    1090         ParseForParameter(verbose,file,"IsAngstroem", 0, 1, 1, int_type, &(config::IsAngstroem), 1, critical);
    1091         config::RelativeCoord = 0;
    1092         config::StructOpt = 0;
    1093 
    1094         // Routine from builder.cpp
    1095 
    1096 
    1097         for (i=MAX_ELEMENTS;i--;)
    1098                 elementhash[i] = NULL;
    1099         cout << Verbose(0) << "Parsing Ions ..." << endl;
    1100         No=0;
    1101         found = 0;
    1102         while (getline(*file,zeile,'\n')) {
    1103                 if (zeile.find("Ions_Data") == 0) {
    1104                         cout << Verbose(1) << "found Ions_Data...begin parsing" << endl;
    1105                         found ++;
    1106                 }
    1107                 if (found > 0) {
    1108                         if (zeile.find("Ions_Data") == 0)
    1109                                 getline(*file,zeile,'\n'); // read next line and parse this one
    1110                         istringstream input(zeile);
    1111                         input >> AtomNo;        // number of atoms
    1112                         input >> Z;                      // atomic number
    1113                         input >> a;
    1114                         input >> l;
    1115                         input >> l;
    1116                         input >> b;              // element mass
    1117                         elementhash[No] = periode->FindElement(Z);
    1118                         cout << Verbose(1) << "AtomNo: " << AtomNo << "\tZ: " << Z << "\ta:" << a << "\tl:"     << l << "\b:" << b << "\tElement:" << elementhash[No] << "\t:" << endl;
    1119                         for(i=0;i<AtomNo;i++) {
    1120                                 if (!getline(*file,zeile,'\n')) {// parse on and on
    1121                                         cout << Verbose(2) << "Error: Too few items in ionic list of element" << elementhash[No] << "." << endl << "Exiting." << endl;
    1122                                         // return 1;
    1123                                 } else {
    1124                                         //cout << Verbose(2) << "Reading line: " << zeile << endl;
    1125                                 }
    1126                                 istringstream input2(zeile);
    1127                                 atom *neues = new atom();
    1128                                 input2 >> neues->x.x[0]; // x
    1129                                 input2 >> neues->x.x[1]; // y
    1130                                 input2 >> neues->x.x[2]; // z
    1131                                 input2 >> l;
    1132                                 neues->type = elementhash[No]; // find element type
    1133                                 mol->AddAtom(neues);
    1134                         }
    1135                         No++;
    1136                 }
    1137         }
    1138         file->close();
    1139         delete(file);
     945  ifstream *file = new ifstream(filename);
     946  if (file == NULL) {
     947    cerr << "ERROR: config file " << filename << " missing!" << endl;
     948    return;
     949  }
     950  RetrieveConfigPathAndName(filename);
     951  // ParseParameters
     952
     953  /* Oeffne Hauptparameterdatei */
     954  int l, i, di;
     955  double a,b;
     956  double BoxLength[9];
     957  string zeile;
     958  string dummy;
     959  element *elementhash[128];
     960  int Z, No, AtomNo, found;
     961  int verbose = 0;
     962
     963  /* Namen einlesen */
     964
     965  ParseForParameter(verbose,file, "mainname", 0, 1, 1, string_type, (config::mainname), 1, critical);
     966  ParseForParameter(verbose,file, "defaultpath", 0, 1, 1, string_type, (config::defaultpath), 1, critical);
     967  ParseForParameter(verbose,file, "pseudopotpath", 0, 1, 1, string_type, (config::pseudopotpath), 1, critical);
     968  ParseForParameter(verbose,file, "ProcsGammaPsi", 0, 1, 1, int_type, &(config::ProcPEGamma), 1, critical);
     969  ParseForParameter(verbose,file, "ProcsGammaPsi", 0, 2, 1, int_type, &(config::ProcPEPsi), 1, critical);
     970  config::Seed = 1;
     971  config::DoOutOrbitals = 0;
     972  ParseForParameter(verbose,file,"DoOutVis", 0, 1, 1, int_type, &(config::DoOutVis), 1, critical);
     973  if (config::DoOutVis < 0) config::DoOutVis = 0;
     974  if (config::DoOutVis > 1) config::DoOutVis = 1;
     975  config::VectorPlane = -1;
     976  config::VectorCut = 0.;
     977  ParseForParameter(verbose,file,"DoOutMes", 0, 1, 1, int_type, &(config::DoOutMes), 1, critical);
     978  if (config::DoOutMes < 0) config::DoOutMes = 0;
     979  if (config::DoOutMes > 1) config::DoOutMes = 1;
     980  config::DoOutCurrent = 0;
     981  ParseForParameter(verbose,file,"AddGramSch", 0, 1, 1, int_type, &(config::UseAddGramSch), 1, critical);
     982  if (config::UseAddGramSch < 0) config::UseAddGramSch = 0;
     983  if (config::UseAddGramSch > 2) config::UseAddGramSch = 2;
     984  config::CommonWannier = 0;
     985  config::SawtoothStart = 0.01;
     986
     987  ParseForParameter(verbose,file,"MaxOuterStep", 0, 1, 1, double_type, &(config::MaxOuterStep), 1, critical);
     988  ParseForParameter(verbose,file,"Deltat", 0, 1, 1, double_type, &(config::Deltat), 1, optional);
     989  ParseForParameter(verbose,file,"VisOuterStep", 0, 1, 1, int_type, &(config::OutVisStep), 1, optional);
     990  ParseForParameter(verbose,file,"VisSrcOuterStep", 0, 1, 1, int_type, &(config::OutSrcStep), 1, optional);
     991  ParseForParameter(verbose,file,"TargetTemp", 0, 1, 1, double_type, &(config::TargetTemp), 1, optional);
     992  ParseForParameter(verbose,file,"ScaleTempStep", 0, 1, 1, int_type, &(config::ScaleTempStep), 1, optional);
     993  config::EpsWannier = 1e-8;
     994
     995  // stop conditions
     996  //if (config::MaxOuterStep <= 0) config::MaxOuterStep = 1;
     997  ParseForParameter(verbose,file,"MaxPsiStep", 0, 1, 1, int_type, &(config::MaxPsiStep), 1, critical);
     998  if (config::MaxPsiStep <= 0) config::MaxPsiStep = 3;
     999
     1000  ParseForParameter(verbose,file,"MaxMinStep", 0, 1, 1, int_type, &(config::MaxMinStep), 1, critical);
     1001  ParseForParameter(verbose,file,"MaxMinStep", 0, 2, 1, double_type, &(config::RelEpsTotalEnergy), 1, critical);
     1002  ParseForParameter(verbose,file,"MaxMinStep", 0, 3, 1, double_type, &(config::RelEpsKineticEnergy), 1, critical);
     1003  ParseForParameter(verbose,file,"MaxMinStep", 0, 4, 1, int_type, &(config::MaxMinStopStep), 1, critical);
     1004  if (config::MaxMinStep <= 0) config::MaxMinStep = config::MaxPsiStep;
     1005  if (config::MaxMinStopStep < 1) config::MaxMinStopStep = 1;
     1006  config::MaxMinGapStopStep = 1;
     1007
     1008  ParseForParameter(verbose,file,"MaxInitMinStep", 0, 1, 1, int_type, &(config::MaxInitMinStep), 1, critical);
     1009  ParseForParameter(verbose,file,"MaxInitMinStep", 0, 2, 1, double_type, &(config::InitRelEpsTotalEnergy), 1, critical);
     1010  ParseForParameter(verbose,file,"MaxInitMinStep", 0, 3, 1, double_type, &(config::InitRelEpsKineticEnergy), 1, critical);
     1011  ParseForParameter(verbose,file,"MaxInitMinStep", 0, 4, 1, int_type, &(config::InitMaxMinStopStep), 1, critical);
     1012  if (config::MaxInitMinStep <= 0) config::MaxInitMinStep = config::MaxPsiStep;
     1013  if (config::InitMaxMinStopStep < 1) config::InitMaxMinStopStep = 1;
     1014  config::InitMaxMinGapStopStep = 1;
     1015
     1016  ParseForParameter(verbose,file, "BoxLength", 0, 3, 3, lower_trigrid, BoxLength, 1, critical); /* Lattice->RealBasis */
     1017  mol->cell_size[0] = BoxLength[0];
     1018  mol->cell_size[1] = BoxLength[3];
     1019  mol->cell_size[2] = BoxLength[4];
     1020  mol->cell_size[3] = BoxLength[6];
     1021  mol->cell_size[4] = BoxLength[7];
     1022  mol->cell_size[5] = BoxLength[8];
     1023  if (1) fprintf(stderr,"\n");
     1024  config::DoPerturbation = 0;
     1025  config::DoFullCurrent = 0;
     1026
     1027  ParseForParameter(verbose,file,"ECut", 0, 1, 1, double_type, &(config::ECut), 1, critical);
     1028  ParseForParameter(verbose,file,"MaxLevel", 0, 1, 1, int_type, &(config::MaxLevel), 1, critical);
     1029  ParseForParameter(verbose,file,"Level0Factor", 0, 1, 1, int_type, &(config::Lev0Factor), 1, critical);
     1030  if (config::Lev0Factor < 2) {
     1031    config::Lev0Factor = 2;
     1032  }
     1033  ParseForParameter(verbose,file,"RiemannTensor", 0, 1, 1, int_type, &di, 1, critical);
     1034  if (di >= 0 && di < 2) {
     1035    config::RiemannTensor = di;
     1036  } else {
     1037    fprintf(stderr, "0 <= RiemanTensor < 2: 0 UseNotRT, 1 UseRT");
     1038    exit(1);
     1039  }
     1040  switch (config::RiemannTensor) {
     1041    case 0: //UseNoRT
     1042      if (config::MaxLevel < 2) {
     1043        config::MaxLevel = 2;
     1044      }
     1045      config::LevRFactor = 2;
     1046      config::RTActualUse = 0;
     1047      break;
     1048    case 1: // UseRT
     1049      if (config::MaxLevel < 3) {
     1050        config::MaxLevel = 3;
     1051      }
     1052      ParseForParameter(verbose,file,"RiemannLevel", 0, 1, 1, int_type, &(config::RiemannLevel), 1, critical);
     1053      if (config::RiemannLevel < 2) {
     1054        config::RiemannLevel = 2;
     1055      }
     1056      if (config::RiemannLevel > config::MaxLevel-1) {
     1057        config::RiemannLevel = config::MaxLevel-1;
     1058      }
     1059      ParseForParameter(verbose,file,"LevRFactor", 0, 1, 1, int_type, &(config::LevRFactor), 1, critical);
     1060      if (config::LevRFactor < 2) {
     1061        config::LevRFactor = 2;
     1062      }
     1063      config::Lev0Factor = 2;
     1064      config::RTActualUse = 2;
     1065      break;
     1066  }
     1067  ParseForParameter(verbose,file,"PsiType", 0, 1, 1, int_type, &di, 1, critical);
     1068  if (di >= 0 && di < 2) {
     1069    config::PsiType = di;
     1070  } else {
     1071    fprintf(stderr, "0 <= PsiType < 2: 0 UseSpinDouble, 1 UseSpinUpDown");
     1072    exit(1);
     1073  }
     1074  switch (config::PsiType) {
     1075  case 0: // SpinDouble
     1076    ParseForParameter(verbose,file,"MaxPsiDouble", 0, 1, 1, int_type, &(config::MaxPsiDouble), 1, critical);
     1077    config::AddPsis = 0;
     1078    break;
     1079  case 1: // SpinUpDown
     1080    if (config::ProcPEGamma % 2) config::ProcPEGamma*=2;
     1081    ParseForParameter(verbose,file,"MaxPsiUp", 0, 1, 1, int_type, &(config::PsiMaxNoUp), 1, critical);
     1082    ParseForParameter(verbose,file,"MaxPsiDown", 0, 1, 1, int_type, &(config::PsiMaxNoDown), 1, critical);
     1083    config::AddPsis = 0;
     1084    break;
     1085  }
     1086
     1087  // IonsInitRead
     1088
     1089  ParseForParameter(verbose,file,"RCut", 0, 1, 1, double_type, &(config::RCut), 1, critical);
     1090  ParseForParameter(verbose,file,"IsAngstroem", 0, 1, 1, int_type, &(config::IsAngstroem), 1, critical);
     1091  config::RelativeCoord = 0;
     1092  config::StructOpt = 0;
     1093
     1094  // Routine from builder.cpp
     1095
     1096
     1097  for (i=MAX_ELEMENTS;i--;)
     1098    elementhash[i] = NULL;
     1099  cout << Verbose(0) << "Parsing Ions ..." << endl;
     1100  No=0;
     1101  found = 0;
     1102  while (getline(*file,zeile,'\n')) {
     1103    if (zeile.find("Ions_Data") == 0) {
     1104      cout << Verbose(1) << "found Ions_Data...begin parsing" << endl;
     1105      found ++;
     1106    }
     1107    if (found > 0) {
     1108      if (zeile.find("Ions_Data") == 0)
     1109        getline(*file,zeile,'\n'); // read next line and parse this one
     1110      istringstream input(zeile);
     1111      input >> AtomNo;  // number of atoms
     1112      input >> Z;      // atomic number
     1113      input >> a;
     1114      input >> l;
     1115      input >> l;
     1116      input >> b;    // element mass
     1117      elementhash[No] = periode->FindElement(Z);
     1118      cout << Verbose(1) << "AtomNo: " << AtomNo << "\tZ: " << Z << "\ta:" << a << "\tl:"  << l << "\b:" << b << "\tElement:" << elementhash[No] << "\t:" << endl;
     1119      for(i=0;i<AtomNo;i++) {
     1120        if (!getline(*file,zeile,'\n')) {// parse on and on
     1121          cout << Verbose(2) << "Error: Too few items in ionic list of element" << elementhash[No] << "." << endl << "Exiting." << endl;
     1122          // return 1;
     1123        } else {
     1124          //cout << Verbose(2) << "Reading line: " << zeile << endl;
     1125        }
     1126        istringstream input2(zeile);
     1127        atom *neues = new atom();
     1128        input2 >> neues->x.x[0]; // x
     1129        input2 >> neues->x.x[1]; // y
     1130        input2 >> neues->x.x[2]; // z
     1131        input2 >> l;
     1132        neues->type = elementhash[No]; // find element type
     1133        mol->AddAtom(neues);
     1134      }
     1135      No++;
     1136    }
     1137  }
     1138  file->close();
     1139  delete(file);
    11401140};
    11411141
     
    11471147bool config::Save(const char *filename, periodentafel *periode, molecule *mol) const
    11481148{
    1149         bool result = true;
    1150         // bring MaxTypes up to date
    1151         mol->CountElements();
    1152         ofstream *output = NULL;
    1153         output = new ofstream(filename, ios::out);
    1154         if (output != NULL) {
    1155                 *output << "# ParallelCarParinello - main configuration file - created with molecuilder" << endl;
    1156                 *output << endl;
    1157                 *output << "mainname\t" << config::mainname << "\t# programm name (for runtime files)" << endl;
    1158                 *output << "defaultpath\t" << config::defaultpath << "\t# where to put files during runtime" << endl;
    1159                 *output << "pseudopotpath\t" << config::pseudopotpath << "\t# where to find pseudopotentials" << endl;
    1160                 *output << endl;
    1161                 *output << "ProcPEGamma\t" << config::ProcPEGamma << "\t# for parallel computing: share constants" << endl;
    1162                 *output << "ProcPEPsi\t" << config::ProcPEPsi << "\t# for parallel computing: share wave functions" << endl;
    1163                 *output << "DoOutVis\t" << config::DoOutVis << "\t# Output data for OpenDX" << endl;
    1164                 *output << "DoOutMes\t" << config::DoOutMes << "\t# Output data for measurements" << endl;
    1165                 *output << "DoOutOrbitals\t" << config::DoOutOrbitals << "\t# Output all Orbitals" << endl;
    1166                 *output << "DoOutCurr\t" << config::DoOutCurrent << "\t# Ouput current density for OpenDx" << endl;
    1167                 *output << "DoOutNICS\t" << config::DoOutNICS << "\t# Output Nucleus independent current shieldings" << endl;
    1168                 *output << "DoPerturbation\t" << config::DoPerturbation << "\t# Do perturbation calculate and determine susceptibility and shielding" << endl;
    1169                 *output << "DoFullCurrent\t" << config::DoFullCurrent << "\t# Do full perturbation" << endl;
    1170                 *output << "CommonWannier\t" << config::CommonWannier << "\t# Put virtual centers at indivual orbits, all common, merged by variance, to grid point, to cell center" << endl;
    1171                 *output << "SawtoothStart\t" << config::SawtoothStart << "\t# Absolute value for smooth transition at cell border " << endl;
    1172                 *output << "VectorPlane\t" << config::VectorPlane << "\t# Cut plane axis (x, y or z: 0,1,2) for two-dim current vector plot" << endl;
    1173                 *output << "VectorCut\t" << config::VectorCut << "\t# Cut plane axis value" << endl;
    1174                 *output << "AddGramSch\t" << config::UseAddGramSch << "\t# Additional GramSchmidtOrtogonalization to be safe" << endl;
    1175                 *output << "Seed\t\t" << config::Seed << "\t# initial value for random seed for Psi coefficients" << endl;
    1176                 *output << endl;
    1177                 *output << "MaxOuterStep\t" << config::MaxOuterStep << "\t# number of MolecularDynamics/Structure optimization steps" << endl;
    1178                 *output << "Deltat\t" << config::Deltat << "\t# time per MD step" << endl;
    1179                 *output << "OutVisStep\t" << config::OutVisStep << "\t# Output visual data every ...th step" << endl;
    1180                 *output << "OutSrcStep\t" << config::OutSrcStep << "\t# Output \"restart\" data every ..th step" << endl;
    1181                 *output << "TargetTemp\t" << config::TargetTemp << "\t# Target temperature" << endl;
    1182                 *output << "MaxPsiStep\t" << config::MaxPsiStep << "\t# number of Minimisation steps per state (0 - default)" << endl;
    1183                 *output << "EpsWannier\t" << config::EpsWannier << "\t# tolerance value for spread minimisation of orbitals" << endl;
    1184                 *output << endl;
    1185                 *output << "# Values specifying when to stop" << endl;
    1186                 *output << "MaxMinStep\t" << config::MaxMinStep << "\t# Maximum number of steps" << endl;
    1187                 *output << "RelEpsTotalE\t" << config::RelEpsTotalEnergy << "\t# relative change in total energy" << endl;
    1188                 *output << "RelEpsKineticE\t" << config::RelEpsKineticEnergy << "\t# relative change in kinetic energy" << endl;
    1189                 *output << "MaxMinStopStep\t" << config::MaxMinStopStep << "\t# check every ..th steps" << endl;
    1190                 *output << "MaxMinGapStopStep\t" << config::MaxMinGapStopStep << "\t# check every ..th steps" << endl;
    1191                 *output << endl;
    1192                 *output << "# Values specifying when to stop for INIT, otherwise same as above" << endl;
    1193                 *output << "MaxInitMinStep\t" << config::MaxInitMinStep << "\t# Maximum number of steps" << endl;
    1194                 *output << "InitRelEpsTotalE\t" << config::InitRelEpsTotalEnergy << "\t# relative change in total energy" << endl;
    1195                 *output << "InitRelEpsKineticE\t" << config::InitRelEpsKineticEnergy << "\t# relative change in kinetic energy" << endl;
    1196                 *output << "InitMaxMinStopStep\t" << config::InitMaxMinStopStep << "\t# check every ..th steps" << endl;
    1197                 *output << "InitMaxMinGapStopStep\t" << config::InitMaxMinGapStopStep << "\t# check every ..th steps" << endl;
    1198                 *output << endl;
    1199                 *output << "BoxLength\t\t\t# (Length of a unit cell)" << endl;
    1200                 *output << mol->cell_size[0] << "\t" << endl;
    1201                 *output << mol->cell_size[1] << "\t" << mol->cell_size[2] << "\t" << endl;
    1202                 *output << mol->cell_size[3] << "\t" << mol->cell_size[4] << "\t" << mol->cell_size[5] << "\t" << endl;
    1203                 // FIXME
    1204                 *output << endl;
    1205                 *output << "ECut\t\t" << config::ECut << "\t# energy cutoff for discretization in Hartrees" << endl;
    1206                 *output << "MaxLevel\t" << config::MaxLevel << "\t# number of different levels in the code, >=2" << endl;
    1207                 *output << "Level0Factor\t" << config::Lev0Factor << "\t# factor by which node number increases from S to 0 level" << endl;
    1208                 *output << "RiemannTensor\t" << config::RiemannTensor << "\t# (Use metric)" << endl;
    1209                 switch (config::RiemannTensor) {
    1210                         case 0: //UseNoRT
    1211                                 break;
    1212                         case 1: // UseRT
    1213                                 *output << "RiemannLevel\t" << config::RiemannLevel << "\t# Number of Riemann Levels" << endl;
    1214                                 *output << "LevRFactor\t" << config::LevRFactor << "\t# factor by which node number increases from 0 to R level from" << endl;
    1215                                 break;
    1216                 }
    1217                 *output << "PsiType\t\t" << config::PsiType << "\t# 0 - doubly occupied, 1 - SpinUp,SpinDown" << endl;
    1218                 // write out both types for easier changing afterwards
    1219         //      switch (PsiType) {
    1220         //              case 0:
    1221                                 *output << "MaxPsiDouble\t" << config::MaxPsiDouble << "\t# here: specifying both maximum number of SpinUp- and -Down-states" << endl;
    1222         //                      break;
    1223         //              case 1:
    1224                                 *output << "PsiMaxNoUp\t" << config::PsiMaxNoUp << "\t# here: specifying maximum number of SpinUp-states" << endl;
    1225                                 *output << "PsiMaxNoDown\t" << config::PsiMaxNoDown << "\t# here: specifying maximum number of SpinDown-states" << endl;
    1226         //                      break;
    1227         //      }
    1228                 *output << "AddPsis\t\t" << config::AddPsis << "\t# Additional unoccupied Psis for bandgap determination" << endl;
    1229                 *output << endl;
    1230                 *output << "RCut\t\t" << config::RCut << "\t# R-cut for the ewald summation" << endl;
    1231                 *output << "StructOpt\t" << config::StructOpt << "\t# Do structure optimization beforehand" << endl;
    1232                 *output << "IsAngstroem\t" << config::IsAngstroem << "\t# 0 - Bohr, 1 - Angstroem" << endl;
    1233                 *output << "RelativeCoord\t" << config::RelativeCoord << "\t# whether ion coordinates are relative (1) or absolute (0)" << endl;
    1234                 *output << "MaxTypes\t" << mol->ElementCount << "\t# maximum number of different ion types" << endl;
    1235                 *output << endl;
    1236                 result = result && mol->Checkout(output);
    1237                 if (mol->MDSteps <=1 )
    1238                         result = result && mol->Output(output);
    1239                 else
    1240                         result = result && mol->OutputTrajectories(output);
    1241                 output->close();
    1242                 output->clear();
    1243                 delete(output);
    1244                 return result;
    1245         } else
    1246                 return false;
     1149  bool result = true;
     1150  // bring MaxTypes up to date
     1151  mol->CountElements();
     1152  ofstream *output = NULL;
     1153  output = new ofstream(filename, ios::out);
     1154  if (output != NULL) {
     1155    *output << "# ParallelCarParinello - main configuration file - created with molecuilder" << endl;
     1156    *output << endl;
     1157    *output << "mainname\t" << config::mainname << "\t# programm name (for runtime files)" << endl;
     1158    *output << "defaultpath\t" << config::defaultpath << "\t# where to put files during runtime" << endl;
     1159    *output << "pseudopotpath\t" << config::pseudopotpath << "\t# where to find pseudopotentials" << endl;
     1160    *output << endl;
     1161    *output << "ProcPEGamma\t" << config::ProcPEGamma << "\t# for parallel computing: share constants" << endl;
     1162    *output << "ProcPEPsi\t" << config::ProcPEPsi << "\t# for parallel computing: share wave functions" << endl;
     1163    *output << "DoOutVis\t" << config::DoOutVis << "\t# Output data for OpenDX" << endl;
     1164    *output << "DoOutMes\t" << config::DoOutMes << "\t# Output data for measurements" << endl;
     1165    *output << "DoOutOrbitals\t" << config::DoOutOrbitals << "\t# Output all Orbitals" << endl;
     1166    *output << "DoOutCurr\t" << config::DoOutCurrent << "\t# Ouput current density for OpenDx" << endl;
     1167    *output << "DoOutNICS\t" << config::DoOutNICS << "\t# Output Nucleus independent current shieldings" << endl;
     1168    *output << "DoPerturbation\t" << config::DoPerturbation << "\t# Do perturbation calculate and determine susceptibility and shielding" << endl;
     1169    *output << "DoFullCurrent\t" << config::DoFullCurrent << "\t# Do full perturbation" << endl;
     1170    *output << "CommonWannier\t" << config::CommonWannier << "\t# Put virtual centers at indivual orbits, all common, merged by variance, to grid point, to cell center" << endl;
     1171    *output << "SawtoothStart\t" << config::SawtoothStart << "\t# Absolute value for smooth transition at cell border " << endl;
     1172    *output << "VectorPlane\t" << config::VectorPlane << "\t# Cut plane axis (x, y or z: 0,1,2) for two-dim current vector plot" << endl;
     1173    *output << "VectorCut\t" << config::VectorCut << "\t# Cut plane axis value" << endl;
     1174    *output << "AddGramSch\t" << config::UseAddGramSch << "\t# Additional GramSchmidtOrtogonalization to be safe" << endl;
     1175    *output << "Seed\t\t" << config::Seed << "\t# initial value for random seed for Psi coefficients" << endl;
     1176    *output << endl;
     1177    *output << "MaxOuterStep\t" << config::MaxOuterStep << "\t# number of MolecularDynamics/Structure optimization steps" << endl;
     1178    *output << "Deltat\t" << config::Deltat << "\t# time per MD step" << endl;
     1179    *output << "OutVisStep\t" << config::OutVisStep << "\t# Output visual data every ...th step" << endl;
     1180    *output << "OutSrcStep\t" << config::OutSrcStep << "\t# Output \"restart\" data every ..th step" << endl;
     1181    *output << "TargetTemp\t" << config::TargetTemp << "\t# Target temperature" << endl;
     1182    *output << "MaxPsiStep\t" << config::MaxPsiStep << "\t# number of Minimisation steps per state (0 - default)" << endl;
     1183    *output << "EpsWannier\t" << config::EpsWannier << "\t# tolerance value for spread minimisation of orbitals" << endl;
     1184    *output << endl;
     1185    *output << "# Values specifying when to stop" << endl;
     1186    *output << "MaxMinStep\t" << config::MaxMinStep << "\t# Maximum number of steps" << endl;
     1187    *output << "RelEpsTotalE\t" << config::RelEpsTotalEnergy << "\t# relative change in total energy" << endl;
     1188    *output << "RelEpsKineticE\t" << config::RelEpsKineticEnergy << "\t# relative change in kinetic energy" << endl;
     1189    *output << "MaxMinStopStep\t" << config::MaxMinStopStep << "\t# check every ..th steps" << endl;
     1190    *output << "MaxMinGapStopStep\t" << config::MaxMinGapStopStep << "\t# check every ..th steps" << endl;
     1191    *output << endl;
     1192    *output << "# Values specifying when to stop for INIT, otherwise same as above" << endl;
     1193    *output << "MaxInitMinStep\t" << config::MaxInitMinStep << "\t# Maximum number of steps" << endl;
     1194    *output << "InitRelEpsTotalE\t" << config::InitRelEpsTotalEnergy << "\t# relative change in total energy" << endl;
     1195    *output << "InitRelEpsKineticE\t" << config::InitRelEpsKineticEnergy << "\t# relative change in kinetic energy" << endl;
     1196    *output << "InitMaxMinStopStep\t" << config::InitMaxMinStopStep << "\t# check every ..th steps" << endl;
     1197    *output << "InitMaxMinGapStopStep\t" << config::InitMaxMinGapStopStep << "\t# check every ..th steps" << endl;
     1198    *output << endl;
     1199    *output << "BoxLength\t\t\t# (Length of a unit cell)" << endl;
     1200    *output << mol->cell_size[0] << "\t" << endl;
     1201    *output << mol->cell_size[1] << "\t" << mol->cell_size[2] << "\t" << endl;
     1202    *output << mol->cell_size[3] << "\t" << mol->cell_size[4] << "\t" << mol->cell_size[5] << "\t" << endl;
     1203    // FIXME
     1204    *output << endl;
     1205    *output << "ECut\t\t" << config::ECut << "\t# energy cutoff for discretization in Hartrees" << endl;
     1206    *output << "MaxLevel\t" << config::MaxLevel << "\t# number of different levels in the code, >=2" << endl;
     1207    *output << "Level0Factor\t" << config::Lev0Factor << "\t# factor by which node number increases from S to 0 level" << endl;
     1208    *output << "RiemannTensor\t" << config::RiemannTensor << "\t# (Use metric)" << endl;
     1209    switch (config::RiemannTensor) {
     1210      case 0: //UseNoRT
     1211        break;
     1212      case 1: // UseRT
     1213        *output << "RiemannLevel\t" << config::RiemannLevel << "\t# Number of Riemann Levels" << endl;
     1214        *output << "LevRFactor\t" << config::LevRFactor << "\t# factor by which node number increases from 0 to R level from" << endl;
     1215        break;
     1216    }
     1217    *output << "PsiType\t\t" << config::PsiType << "\t# 0 - doubly occupied, 1 - SpinUp,SpinDown" << endl;
     1218    // write out both types for easier changing afterwards
     1219  //  switch (PsiType) {
     1220  //    case 0:
     1221        *output << "MaxPsiDouble\t" << config::MaxPsiDouble << "\t# here: specifying both maximum number of SpinUp- and -Down-states" << endl;
     1222  //      break;
     1223  //    case 1:
     1224        *output << "PsiMaxNoUp\t" << config::PsiMaxNoUp << "\t# here: specifying maximum number of SpinUp-states" << endl;
     1225        *output << "PsiMaxNoDown\t" << config::PsiMaxNoDown << "\t# here: specifying maximum number of SpinDown-states" << endl;
     1226  //      break;
     1227  //  }
     1228    *output << "AddPsis\t\t" << config::AddPsis << "\t# Additional unoccupied Psis for bandgap determination" << endl;
     1229    *output << endl;
     1230    *output << "RCut\t\t" << config::RCut << "\t# R-cut for the ewald summation" << endl;
     1231    *output << "StructOpt\t" << config::StructOpt << "\t# Do structure optimization beforehand" << endl;
     1232    *output << "IsAngstroem\t" << config::IsAngstroem << "\t# 0 - Bohr, 1 - Angstroem" << endl;
     1233    *output << "RelativeCoord\t" << config::RelativeCoord << "\t# whether ion coordinates are relative (1) or absolute (0)" << endl;
     1234    *output << "MaxTypes\t" << mol->ElementCount <<  "\t# maximum number of different ion types" << endl;
     1235    *output << endl;
     1236    result = result && mol->Checkout(output);
     1237    if (mol->MDSteps <=1 )
     1238      result = result && mol->Output(output);
     1239    else
     1240      result = result && mol->OutputTrajectories(output);
     1241    output->close();
     1242    output->clear();
     1243    delete(output);
     1244    return result;
     1245  } else
     1246    return false;
    12471247};
    12481248
     
    12541254bool config::SaveMPQC(const char *filename, molecule *mol) const
    12551255{
    1256         int ElementNo = 0;
    1257         int AtomNo;
    1258         atom *Walker = NULL;
    1259         element *runner = NULL;
    1260         Vector *center = NULL;
    1261         ofstream *output = NULL;
    1262         stringstream *fname = NULL;
    1263 
    1264         // first without hessian
    1265         fname = new stringstream;
    1266         *fname << filename << ".in";
    1267         output = new ofstream(fname->str().c_str(), ios::out);
    1268         *output << "% Created by MoleCuilder" << endl;
    1269         *output << "mpqc: (" << endl;
    1270         *output << "\tsavestate = no" << endl;
    1271         *output << "\tdo_gradient = yes" << endl;
    1272         *output << "\tmole<MBPT2>: (" << endl;
    1273         *output << "\t\tmaxiter = 200" << endl;
    1274         *output << "\t\tbasis = $:basis" << endl;
    1275         *output << "\t\tmolecule = $:molecule" << endl;
    1276         *output << "\t\treference<CLHF>: (" << endl;
    1277         *output << "\t\t\tbasis = $:basis" << endl;
    1278         *output << "\t\t\tmolecule = $:molecule" << endl;
    1279         *output << "\t\t)" << endl;
    1280         *output << "\t)" << endl;
    1281         *output << ")" << endl;
    1282         *output << "molecule<Molecule>: (" << endl;
    1283         *output << "\tunit = " << (IsAngstroem ? "angstrom" : "bohr" ) << endl;
    1284         *output << "\t{ atoms geometry } = {" << endl;
    1285         center = mol->DetermineCenterOfAll(output);
    1286         // output of atoms
    1287         runner = mol->elemente->start;
    1288         while (runner->next != mol->elemente->end) { // go through every element
    1289                 runner = runner->next;
    1290                 if (mol->ElementsInMolecule[runner->Z]) { // if this element got atoms
    1291                         ElementNo++;
    1292                         AtomNo = 0;
    1293                         Walker = mol->start;
    1294                         while (Walker->next != mol->end) { // go through every atom of this element
    1295                                 Walker = Walker->next;
    1296                                 if (Walker->type == runner) { // if this atom fits to element
    1297                                         AtomNo++;
    1298                                         *output << "\t\t" << Walker->type->symbol << " [ " << Walker->x.x[0]-center->x[0] << "\t" << Walker->x.x[1]-center->x[1] << "\t" << Walker->x.x[2]-center->x[2] << " ]" << endl;
    1299                                 }
    1300                         }
    1301                 }
    1302         }
    1303         delete(center);
    1304         *output << "\t}" << endl;
    1305         *output << ")" << endl;
    1306         *output << "basis<GaussianBasisSet>: (" << endl;
    1307         *output << "\tname = \""<< basis << "\"" << endl;
    1308         *output << "\tmolecule = $:molecule" << endl;
    1309         *output << ")" << endl;
    1310         output->close();
    1311         delete(output);
    1312         delete(fname);
    1313 
    1314         // second with hessian
    1315         fname = new stringstream;
    1316         *fname << filename << ".hess.in";
    1317         output = new ofstream(fname->str().c_str(), ios::out);
    1318         *output << "% Created by MoleCuilder" << endl;
    1319         *output << "mpqc: (" << endl;
    1320         *output << "\tsavestate = no" << endl;
    1321         *output << "\tdo_gradient = yes" << endl;
    1322         *output << "\tmole<CLHF>: (" << endl;
    1323         *output << "\t\tmaxiter = 200" << endl;
    1324         *output << "\t\tbasis = $:basis" << endl;
    1325         *output << "\t\tmolecule = $:molecule" << endl;
    1326         *output << "\t)" << endl;
    1327         *output << "\tfreq<MolecularFrequencies>: (" << endl;
    1328         *output << "\t\tmolecule=$:molecule" << endl;
    1329         *output << "\t)" << endl;
    1330         *output << ")" << endl;
    1331         *output << "molecule<Molecule>: (" << endl;
    1332         *output << "\tunit = " << (IsAngstroem ? "angstrom" : "bohr" ) << endl;
    1333         *output << "\t{ atoms geometry } = {" << endl;
    1334         center = mol->DetermineCenterOfAll(output);
    1335         // output of atoms
    1336         runner = mol->elemente->start;
    1337         while (runner->next != mol->elemente->end) { // go through every element
    1338                 runner = runner->next;
    1339                 if (mol->ElementsInMolecule[runner->Z]) { // if this element got atoms
    1340                         ElementNo++;
    1341                         AtomNo = 0;
    1342                         Walker = mol->start;
    1343                         while (Walker->next != mol->end) { // go through every atom of this element
    1344                                 Walker = Walker->next;
    1345                                 if (Walker->type == runner) { // if this atom fits to element
    1346                                         AtomNo++;
    1347                                         *output << "\t\t" << Walker->type->symbol << " [ " << Walker->x.x[0]-center->x[0] << "\t" << Walker->x.x[1]-center->x[1] << "\t" << Walker->x.x[2]-center->x[2] << " ]" << endl;
    1348                                 }
    1349                         }
    1350                 }
    1351         }
    1352         delete(center);
    1353         *output << "\t}" << endl;
    1354         *output << ")" << endl;
    1355         *output << "basis<GaussianBasisSet>: (" << endl;
    1356         *output << "\tname = \"3-21G\"" << endl;
    1357         *output << "\tmolecule = $:molecule" << endl;
    1358         *output << ")" << endl;
    1359         output->close();
    1360         delete(output);
    1361         delete(fname);
    1362 
    1363         return true;
     1256  int ElementNo = 0;
     1257  int AtomNo;
     1258  atom *Walker = NULL;
     1259  element *runner = NULL;
     1260  Vector *center = NULL;
     1261  ofstream *output = NULL;
     1262  stringstream *fname = NULL;
     1263
     1264  // first without hessian
     1265  fname = new stringstream;
     1266  *fname << filename << ".in";
     1267  output = new ofstream(fname->str().c_str(), ios::out);
     1268  *output << "% Created by MoleCuilder" << endl;
     1269  *output << "mpqc: (" << endl;
     1270  *output << "\tsavestate = no" << endl;
     1271  *output << "\tdo_gradient = yes" << endl;
     1272  *output << "\tmole<MBPT2>: (" << endl;
     1273  *output << "\t\tmaxiter = 200" << endl;
     1274  *output << "\t\tbasis = $:basis" << endl;
     1275  *output << "\t\tmolecule = $:molecule" << endl;
     1276  *output << "\t\treference<CLHF>: (" << endl;
     1277  *output << "\t\t\tbasis = $:basis" << endl;
     1278  *output << "\t\t\tmolecule = $:molecule" << endl;
     1279  *output << "\t\t)" << endl;
     1280  *output << "\t)" << endl;
     1281  *output << ")" << endl;
     1282  *output << "molecule<Molecule>: (" << endl;
     1283  *output << "\tunit = " << (IsAngstroem ? "angstrom" : "bohr" ) << endl;
     1284  *output << "\t{ atoms geometry } = {" << endl;
     1285  center = mol->DetermineCenterOfAll(output);
     1286  // output of atoms
     1287  runner = mol->elemente->start;
     1288  while (runner->next != mol->elemente->end) { // go through every element
     1289    runner = runner->next;
     1290    if (mol->ElementsInMolecule[runner->Z]) { // if this element got atoms
     1291      ElementNo++;
     1292      AtomNo = 0;
     1293      Walker = mol->start;
     1294      while (Walker->next != mol->end) { // go through every atom of this element
     1295        Walker = Walker->next;
     1296        if (Walker->type == runner) { // if this atom fits to element
     1297          AtomNo++;
     1298          *output << "\t\t" << Walker->type->symbol << " [ " << Walker->x.x[0]-center->x[0] << "\t" << Walker->x.x[1]-center->x[1] << "\t" << Walker->x.x[2]-center->x[2] << " ]" << endl;
     1299        }
     1300      }
     1301    }
     1302  }
     1303  delete(center);
     1304  *output << "\t}" << endl;
     1305  *output << ")" << endl;
     1306  *output << "basis<GaussianBasisSet>: (" << endl;
     1307  *output << "\tname = \""<< basis << "\"" << endl;
     1308  *output << "\tmolecule = $:molecule" << endl;
     1309  *output << ")" << endl;
     1310  output->close();
     1311  delete(output);
     1312  delete(fname);
     1313
     1314  // second with hessian
     1315  fname = new stringstream;
     1316  *fname << filename << ".hess.in";
     1317  output = new ofstream(fname->str().c_str(), ios::out);
     1318  *output << "% Created by MoleCuilder" << endl;
     1319  *output << "mpqc: (" << endl;
     1320  *output << "\tsavestate = no" << endl;
     1321  *output << "\tdo_gradient = yes" << endl;
     1322  *output << "\tmole<CLHF>: (" << endl;
     1323  *output << "\t\tmaxiter = 200" << endl;
     1324  *output << "\t\tbasis = $:basis" << endl;
     1325  *output << "\t\tmolecule = $:molecule" << endl;
     1326  *output << "\t)" << endl;
     1327  *output << "\tfreq<MolecularFrequencies>: (" << endl;
     1328  *output << "\t\tmolecule=$:molecule" << endl;
     1329  *output << "\t)" << endl;
     1330  *output << ")" << endl;
     1331  *output << "molecule<Molecule>: (" << endl;
     1332  *output << "\tunit = " << (IsAngstroem ? "angstrom" : "bohr" ) << endl;
     1333  *output << "\t{ atoms geometry } = {" << endl;
     1334  center = mol->DetermineCenterOfAll(output);
     1335  // output of atoms
     1336  runner = mol->elemente->start;
     1337  while (runner->next != mol->elemente->end) { // go through every element
     1338    runner = runner->next;
     1339    if (mol->ElementsInMolecule[runner->Z]) { // if this element got atoms
     1340      ElementNo++;
     1341      AtomNo = 0;
     1342      Walker = mol->start;
     1343      while (Walker->next != mol->end) { // go through every atom of this element
     1344        Walker = Walker->next;
     1345        if (Walker->type == runner) { // if this atom fits to element
     1346          AtomNo++;
     1347          *output << "\t\t" << Walker->type->symbol << " [ " << Walker->x.x[0]-center->x[0] << "\t" << Walker->x.x[1]-center->x[1] << "\t" << Walker->x.x[2]-center->x[2] << " ]" << endl;
     1348        }
     1349      }
     1350    }
     1351  }
     1352  delete(center);
     1353  *output << "\t}" << endl;
     1354  *output << ")" << endl;
     1355  *output << "basis<GaussianBasisSet>: (" << endl;
     1356  *output << "\tname = \"3-21G\"" << endl;
     1357  *output << "\tmolecule = $:molecule" << endl;
     1358  *output << ")" << endl;
     1359  output->close();
     1360  delete(output);
     1361  delete(fname);
     1362
     1363  return true;
    13641364};
    13651365
     
    13731373 * \param name Name of value in file (at least 3 chars!)
    13741374 * \param sequential 1 - do not reset file pointer to begin of file, 0 - set to beginning
    1375  *                              (if file is sequentially parsed this can be way faster! However, beware of multiple values per line, as whole line is read -
    1376  *                              best approach: 0 0 0 1 (not resetted only on last value of line) - and of yth, which is now
    1377  *                              counted from this unresetted position!)
     1375 *        (if file is sequentially parsed this can be way faster! However, beware of multiple values per line, as whole line is read -
     1376 *        best approach: 0 0 0 1 (not resetted only on last value of line) - and of yth, which is now
     1377 *        counted from this unresetted position!)
    13781378 * \param xth Which among a number of parameters it is (in grid case it's row number as grid is read as a whole!)
    13791379 * \param yth In grid case specifying column number, otherwise the yth \a name matching line
     
    13861386 */
    13871387int config::ParseForParameter(int verbose, ifstream *file, const char *name, int sequential, int const xth, int const yth, int type, void *value, int repetition, int critical) {
    1388         int i,j;        // loop variables
    1389         int length = 0, maxlength = -1;
    1390         long file_position = file->tellg(); // mark current position
    1391         char *dummy1, *dummy, *free_dummy;              // pointers in the line that is read in per step
    1392         dummy1 = free_dummy = (char *) Malloc(256 * sizeof(char), "config::ParseForParameter: *free_dummy");
    1393 
    1394         //fprintf(stderr,"Parsing for %s\n",name);
    1395         if (repetition == 0)
    1396                 //Error(SomeError, "ParseForParameter(): argument repetition must not be 0!");
    1397                 return 0;
    1398 
    1399         int line = 0; // marks line where parameter was found
    1400         int found = (type >= grid) ? 0 : (-yth + 1);    // marks if yth parameter name was found
    1401         while((found != repetition)) {
    1402                 dummy1 = dummy = free_dummy;
    1403                 do {
    1404                         file->getline(dummy1, 256); // Read the whole line
    1405                         if (file->eof()) {
    1406                                 if ((critical) && (found == 0)) {
    1407                                         Free((void **)&free_dummy, "config::ParseForParameter: *free_dummy");
    1408                                         //Error(InitReading, name);
    1409                                         fprintf(stderr,"Error:InitReading, critical %s not found\n", name);
    1410                                         exit(255);
    1411                                 } else {
    1412                                         //if (!sequential)
    1413                                         file->clear();
    1414                                         file->seekg(file_position, ios::beg);   // rewind to start position
    1415                                         Free((void **)&free_dummy, "config::ParseForParameter: *free_dummy");
    1416                                         return 0;
    1417                                 }
    1418                         }
    1419                         line++;
    1420                 } while (dummy != NULL && dummy1 != NULL && ((dummy1[0] == '#') || (dummy1[0] == '\0'))); // skip commentary and empty lines
    1421 
    1422                 // C++ getline removes newline at end, thus re-add
    1423                 if ((dummy1 != NULL) && (strchr(dummy1,'\n') == NULL)) {
    1424                         i = strlen(dummy1);
    1425                         dummy1[i] = '\n';
    1426                         dummy1[i+1] = '\0';
    1427                 }
    1428                 //fprintf(stderr,"line %i ends at %i, newline at %i\n", line, strlen(dummy1), strchr(dummy1,'\n')-free_dummy);
    1429 
    1430                 if (dummy1 == NULL) {
    1431                         if (verbose) fprintf(stderr,"Error reading line %i\n",line);
    1432                 } else {
    1433                         //fprintf(stderr,"Now parsing the line %i: %s\n", line, dummy1);
    1434                 }
    1435                 // Seek for possible end of keyword on line if given ...
    1436                 if (name != NULL) {
    1437                         dummy = strchr(dummy1,'\t');    // set dummy on first tab or space which ever's nearer
    1438                         if (dummy == NULL) {
    1439                                 dummy = strchr(dummy1, ' ');    // if not found seek for space
    1440                                 while ((dummy != NULL) && ((*dummy == '\t') || (*dummy == ' ')))                // skip some more tabs and spaces if necessary
    1441                                         dummy++;
    1442                         }
    1443                         if (dummy == NULL) {
    1444                                 dummy = strchr(dummy1, '\n'); // set on line end then (whole line = keyword)
    1445                                 //fprintf(stderr,"Error: Cannot find tabs or spaces on line %i in search for %s\n", line, name);
    1446                                 //Free((void **)&free_dummy);
    1447                                 //Error(FileOpenParams, NULL);
    1448                         } else {
    1449                                 //fprintf(stderr,"found tab at %i\n",(char *)dummy-(char *)dummy1);
    1450                         }
    1451                 } else dummy = dummy1;
    1452                 // ... and check if it is the keyword!
    1453                 //fprintf(stderr,"name %p, dummy %i/%c, dummy1 %i/%c, strlen(name) %i\n", &name, dummy, *dummy, dummy1, *dummy1, strlen(name));
    1454                 if ((name == NULL) || (((dummy-dummy1 >= 3) && (strncmp(dummy1, name, strlen(name)) == 0)) && ((unsigned int)(dummy-dummy1) == strlen(name)))) {
    1455                         found++; // found the parameter!
    1456                         //fprintf(stderr,"found %s at line %i between %i and %i\n", name, line, dummy1, dummy);
    1457 
    1458                         if (found == repetition) {
    1459                                 for (i=0;i<xth;i++) { // i = rows
    1460                                         if (type >= grid) {
    1461                                                 // grid structure means that grid starts on the next line, not right after keyword
    1462                                                 dummy1 = dummy = free_dummy;
    1463                                                 do {
    1464                                                         file->getline(dummy1, 256); // Read the whole line, skip commentary and empty ones
    1465                                                         if (file->eof()) {
    1466                                                                 if ((critical) && (found == 0)) {
    1467                                                                         Free((void **)&free_dummy, "config::ParseForParameter: *free_dummy");
    1468                                                                         //Error(InitReading, name);
    1469                                                                         fprintf(stderr,"Error:InitReading, critical %s not found\n", name);
    1470                                                                         exit(255);
    1471                                                                 } else {
    1472                                                                         //if (!sequential)
    1473                                                                         file->clear();
    1474                                                                         file->seekg(file_position, ios::beg);   // rewind to start position
    1475                                                                         Free((void **)&free_dummy, "config::ParseForParameter: *free_dummy");
    1476                                                                         return 0;
    1477                                                                 }
    1478                                                         }
    1479                                                         line++;
    1480                                                 } while ((dummy1[0] == '#') || (dummy1[0] == '\n'));
    1481                                                 if (dummy1 == NULL){
    1482                                                         if (verbose) fprintf(stderr,"Error reading line %i\n", line);
    1483                                                 } else {
    1484                                                         //fprintf(stderr,"Reading next line %i: %s\n", line, dummy1);
    1485                                                 }
    1486                                         } else { // simple int, strings or doubles start in the same line
    1487                                                 while ((*dummy == '\t') || (*dummy == ' '))      // skip interjacent tabs and spaces
    1488                                                         dummy++;
    1489                                         }
    1490                                         // C++ getline removes newline at end, thus re-add
    1491                                         if ((dummy1 != NULL) && (strchr(dummy1,'\n') == NULL)) {
    1492                                                 j = strlen(dummy1);
    1493                                                 dummy1[j] = '\n';
    1494                                                 dummy1[j+1] = '\0';
    1495                                         }
    1496 
    1497                                         int start = (type >= grid) ? 0 : yth-1 ;
    1498                                         for (j=start;j<yth;j++) { // j = columns
    1499                                                 // check for lower triangular area and upper triangular area
    1500                                                 if ( ((i > j) && (type == upper_trigrid)) || ((j > i) && (type == lower_trigrid))) {
    1501                                                         *((double *)value) = 0.0;
    1502                                                         fprintf(stderr,"%f\t",*((double *)value));
    1503                                                         value = (void *)((long)value + sizeof(double));
    1504                                                         //value += sizeof(double);
    1505                                                 } else {
    1506                                                         // otherwise we must skip all interjacent tabs and spaces and find next value
    1507                                                         dummy1 = dummy;
    1508                                                         dummy = strchr(dummy1, '\t'); // seek for tab or space
    1509                                                         if (dummy == NULL)
    1510                                                                 dummy = strchr(dummy1, ' ');    // if not found seek for space
    1511                                                         if (dummy == NULL) { // if still zero returned ...
    1512                                                                 dummy = strchr(dummy1, '\n');   // ... at line end then
    1513                                                                 if ((j < yth-1) && (type < 4)) {        // check if xth value or not yet
    1514                                                                         if (critical) {
    1515                                                                                 if (verbose) fprintf(stderr,"Error: EoL at %i and still missing %i value(s) for parameter %s\n", line, yth-j, name);
    1516                                                                                 Free((void **)&free_dummy, "config::ParseForParameter: *free_dummy");
    1517                                                                                 //return 0;
    1518                                                                                 exit(255);
    1519                                                                                 //Error(FileOpenParams, NULL);
    1520                                                                         } else {
    1521                                                                                 //if (!sequential)
    1522                                                                                 file->clear();
    1523                                                                                 file->seekg(file_position, ios::beg);   // rewind to start position
    1524                                                                                 Free((void **)&free_dummy, "config::ParseForParameter: *free_dummy");
    1525                                                                                 return 0;
    1526                                                                         }
    1527                                                                 }
    1528                                                         } else {
    1529                                                                 //fprintf(stderr,"found tab at %i\n",(char *)dummy-(char *)free_dummy);
    1530                                                         }
    1531                                                         if (*dummy1 == '#') {
    1532                                                                 // found comment, skipping rest of line
    1533                                                                 //if (verbose) fprintf(stderr,"Error: '#' at %i and still missing %i value(s) for parameter %s\n", line, yth-j, name);
    1534                                                                 if (!sequential) { // here we need it!
    1535                                                                         file->seekg(file_position, ios::beg);   // rewind to start position
    1536                                                                 }
    1537                                                                 Free((void **)&free_dummy, "config::ParseForParameter: *free_dummy");
    1538                                                                 return 0;
    1539                                                         }
    1540                                                         //fprintf(stderr,"value from %i to %i\n",(char *)dummy1-(char *)free_dummy,(char *)dummy-(char *)free_dummy);
    1541                                                         switch(type) {
    1542                                                                 case (row_int):
    1543                                                                         *((int *)value) = atoi(dummy1);
    1544                                                                         if ((verbose) && (i==0) && (j==0)) fprintf(stderr,"%s = ", name);
    1545                                                                         if (verbose) fprintf(stderr,"%i\t",*((int *)value));
    1546                                                                                 value = (void *)((long)value + sizeof(int));
    1547                                                                                 //value += sizeof(int);
    1548                                                                         break;
    1549                                                                 case(row_double):
    1550                                                                 case(grid):
    1551                                                                 case(lower_trigrid):
    1552                                                                 case(upper_trigrid):
    1553                                                                         *((double *)value) = atof(dummy1);
    1554                                                                         if ((verbose) && (i==0) && (j==0)) fprintf(stderr,"%s = ", name);
    1555                                                                         if (verbose) fprintf(stderr,"%lg\t",*((double *)value));
    1556                                                                         value = (void *)((long)value + sizeof(double));
    1557                                                                         //value += sizeof(double);
    1558                                                                         break;
    1559                                                                 case(double_type):
    1560                                                                         *((double *)value) = atof(dummy1);
    1561                                                                         if ((verbose) && (i == xth-1)) fprintf(stderr,"%s = %lg\n", name, *((double *) value));
    1562                                                                         //value += sizeof(double);
    1563                                                                         break;
    1564                                                                 case(int_type):
    1565                                                                         *((int *)value) = atoi(dummy1);
    1566                                                                         if ((verbose) && (i == xth-1)) fprintf(stderr,"%s = %i\n", name, *((int *) value));
    1567                                                                         //value += sizeof(int);
    1568                                                                         break;
    1569                                                                 default:
    1570                                                                 case(string_type):
    1571                                                                         if (value != NULL) {
    1572                                                                                 //if (maxlength == -1) maxlength = strlen((char *)value); // get maximum size of string array
    1573                                                                                 maxlength = MAXSTRINGSIZE;
    1574                                                                                 length = maxlength > (dummy-dummy1) ? (dummy-dummy1) : maxlength; // cap at maximum
    1575                                                                                 strncpy((char *)value, dummy1, length); // copy as much
    1576                                                                                 ((char *)value)[length] = '\0'; // and set end marker
    1577                                                                                 if ((verbose) && (i == xth-1)) fprintf(stderr,"%s is '%s' (%i chars)\n",name,((char *) value), length);
    1578                                                                                 //value += sizeof(char);
    1579                                                                         } else {
    1580                                                                         }
    1581                                                                 break;
    1582                                                         }
    1583                                                 }
    1584                                                 while (*dummy == '\t')
    1585                                                         dummy++;
    1586                                         }
    1587                                 }
    1588                         }
    1589                 }
    1590         }
    1591         if ((type >= row_int) && (verbose)) fprintf(stderr,"\n");
    1592         Free((void **)&free_dummy, "config::ParseForParameter: *free_dummy");
    1593         if (!sequential) {
    1594                 file->clear();
    1595                 file->seekg(file_position, ios::beg);   // rewind to start position
    1596         }
    1597         //fprintf(stderr, "End of Parsing\n\n");
    1598 
    1599         return (found); // true if found, false if not
     1388  int i,j;  // loop variables
     1389  int length = 0, maxlength = -1;
     1390  long file_position = file->tellg(); // mark current position
     1391  char *dummy1, *dummy, *free_dummy;    // pointers in the line that is read in per step
     1392  dummy1 = free_dummy = (char *) Malloc(256 * sizeof(char), "config::ParseForParameter: *free_dummy");
     1393
     1394  //fprintf(stderr,"Parsing for %s\n",name);
     1395  if (repetition == 0)
     1396    //Error(SomeError, "ParseForParameter(): argument repetition must not be 0!");
     1397    return 0;
     1398
     1399  int line = 0; // marks line where parameter was found
     1400  int found = (type >= grid) ? 0 : (-yth + 1);  // marks if yth parameter name was found
     1401  while((found != repetition)) {
     1402    dummy1 = dummy = free_dummy;
     1403    do {
     1404      file->getline(dummy1, 256); // Read the whole line
     1405      if (file->eof()) {
     1406        if ((critical) && (found == 0)) {
     1407          Free((void **)&free_dummy, "config::ParseForParameter: *free_dummy");
     1408          //Error(InitReading, name);
     1409          fprintf(stderr,"Error:InitReading, critical %s not found\n", name);
     1410          exit(255);
     1411        } else {
     1412          //if (!sequential)
     1413          file->clear();
     1414          file->seekg(file_position, ios::beg);  // rewind to start position
     1415          Free((void **)&free_dummy, "config::ParseForParameter: *free_dummy");
     1416          return 0;
     1417        }
     1418      }
     1419      line++;
     1420    } while (dummy != NULL && dummy1 != NULL && ((dummy1[0] == '#') || (dummy1[0] == '\0'))); // skip commentary and empty lines
     1421
     1422    // C++ getline removes newline at end, thus re-add
     1423    if ((dummy1 != NULL) && (strchr(dummy1,'\n') == NULL)) {
     1424      i = strlen(dummy1);
     1425      dummy1[i] = '\n';
     1426      dummy1[i+1] = '\0';
     1427    }
     1428    //fprintf(stderr,"line %i ends at %i, newline at %i\n", line, strlen(dummy1), strchr(dummy1,'\n')-free_dummy);
     1429
     1430    if (dummy1 == NULL) {
     1431      if (verbose) fprintf(stderr,"Error reading line %i\n",line);
     1432    } else {
     1433      //fprintf(stderr,"Now parsing the line %i: %s\n", line, dummy1);
     1434    }
     1435    // Seek for possible end of keyword on line if given ...
     1436    if (name != NULL) {
     1437      dummy = strchr(dummy1,'\t');  // set dummy on first tab or space which ever's nearer
     1438      if (dummy == NULL) {
     1439        dummy = strchr(dummy1, ' ');  // if not found seek for space
     1440        while ((dummy != NULL) && ((*dummy == '\t') || (*dummy == ' ')))    // skip some more tabs and spaces if necessary
     1441          dummy++;
     1442      }
     1443      if (dummy == NULL) {
     1444        dummy = strchr(dummy1, '\n'); // set on line end then (whole line = keyword)
     1445        //fprintf(stderr,"Error: Cannot find tabs or spaces on line %i in search for %s\n", line, name);
     1446        //Free((void **)&free_dummy);
     1447        //Error(FileOpenParams, NULL);
     1448      } else {
     1449        //fprintf(stderr,"found tab at %i\n",(char *)dummy-(char *)dummy1);
     1450      }
     1451    } else dummy = dummy1;
     1452    // ... and check if it is the keyword!
     1453    //fprintf(stderr,"name %p, dummy %i/%c, dummy1 %i/%c, strlen(name) %i\n", &name, dummy, *dummy, dummy1, *dummy1, strlen(name));
     1454    if ((name == NULL) || (((dummy-dummy1 >= 3) && (strncmp(dummy1, name, strlen(name)) == 0)) && ((unsigned int)(dummy-dummy1) == strlen(name)))) {
     1455      found++; // found the parameter!
     1456      //fprintf(stderr,"found %s at line %i between %i and %i\n", name, line, dummy1, dummy);
     1457
     1458      if (found == repetition) {
     1459        for (i=0;i<xth;i++) { // i = rows
     1460          if (type >= grid) {
     1461            // grid structure means that grid starts on the next line, not right after keyword
     1462            dummy1 = dummy = free_dummy;
     1463            do {
     1464              file->getline(dummy1, 256); // Read the whole line, skip commentary and empty ones
     1465              if (file->eof()) {
     1466                if ((critical) && (found == 0)) {
     1467                  Free((void **)&free_dummy, "config::ParseForParameter: *free_dummy");
     1468                  //Error(InitReading, name);
     1469                  fprintf(stderr,"Error:InitReading, critical %s not found\n", name);
     1470                  exit(255);
     1471                } else {
     1472                  //if (!sequential)
     1473                  file->clear();
     1474                  file->seekg(file_position, ios::beg);  // rewind to start position
     1475                  Free((void **)&free_dummy, "config::ParseForParameter: *free_dummy");
     1476                  return 0;
     1477                }
     1478              }
     1479              line++;
     1480            } while ((dummy1[0] == '#') || (dummy1[0] == '\n'));
     1481            if (dummy1 == NULL){
     1482              if (verbose) fprintf(stderr,"Error reading line %i\n", line);
     1483            } else {
     1484              //fprintf(stderr,"Reading next line %i: %s\n", line, dummy1);
     1485            }
     1486          } else { // simple int, strings or doubles start in the same line
     1487            while ((*dummy == '\t') || (*dummy == ' '))  // skip interjacent tabs and spaces
     1488              dummy++;
     1489          }
     1490          // C++ getline removes newline at end, thus re-add
     1491          if ((dummy1 != NULL) && (strchr(dummy1,'\n') == NULL)) {
     1492            j = strlen(dummy1);
     1493            dummy1[j] = '\n';
     1494            dummy1[j+1] = '\0';
     1495          }
     1496
     1497          int start = (type >= grid) ? 0 : yth-1 ;
     1498          for (j=start;j<yth;j++) { // j = columns
     1499            // check for lower triangular area and upper triangular area
     1500            if ( ((i > j) && (type == upper_trigrid)) || ((j > i) && (type == lower_trigrid))) {
     1501              *((double *)value) = 0.0;
     1502              fprintf(stderr,"%f\t",*((double *)value));
     1503              value = (void *)((long)value + sizeof(double));
     1504              //value += sizeof(double);
     1505            } else {
     1506              // otherwise we must skip all interjacent tabs and spaces and find next value
     1507              dummy1 = dummy;
     1508              dummy = strchr(dummy1, '\t'); // seek for tab or space
     1509              if (dummy == NULL)
     1510                dummy = strchr(dummy1, ' ');  // if not found seek for space
     1511              if (dummy == NULL) { // if still zero returned ...
     1512                dummy = strchr(dummy1, '\n');  // ... at line end then
     1513                if ((j < yth-1) && (type < 4)) {  // check if xth value or not yet
     1514                  if (critical) {
     1515                    if (verbose) fprintf(stderr,"Error: EoL at %i and still missing %i value(s) for parameter %s\n", line, yth-j, name);
     1516                    Free((void **)&free_dummy, "config::ParseForParameter: *free_dummy");
     1517                    //return 0;
     1518                    exit(255);
     1519                    //Error(FileOpenParams, NULL);
     1520                  } else {
     1521                    //if (!sequential)
     1522                    file->clear();
     1523                    file->seekg(file_position, ios::beg);  // rewind to start position
     1524                    Free((void **)&free_dummy, "config::ParseForParameter: *free_dummy");
     1525                    return 0;
     1526                  }
     1527                }
     1528              } else {
     1529                //fprintf(stderr,"found tab at %i\n",(char *)dummy-(char *)free_dummy);
     1530              }
     1531              if (*dummy1 == '#') {
     1532                // found comment, skipping rest of line
     1533                //if (verbose) fprintf(stderr,"Error: '#' at %i and still missing %i value(s) for parameter %s\n", line, yth-j, name);
     1534                if (!sequential) { // here we need it!
     1535                  file->seekg(file_position, ios::beg);  // rewind to start position
     1536                }
     1537                Free((void **)&free_dummy, "config::ParseForParameter: *free_dummy");
     1538                return 0;
     1539              }
     1540              //fprintf(stderr,"value from %i to %i\n",(char *)dummy1-(char *)free_dummy,(char *)dummy-(char *)free_dummy);
     1541              switch(type) {
     1542                case (row_int):
     1543                  *((int *)value) = atoi(dummy1);
     1544                  if ((verbose) && (i==0) && (j==0)) fprintf(stderr,"%s = ", name);
     1545                  if (verbose) fprintf(stderr,"%i\t",*((int *)value));
     1546                    value = (void *)((long)value + sizeof(int));
     1547                    //value += sizeof(int);
     1548                  break;
     1549                case(row_double):
     1550                case(grid):
     1551                case(lower_trigrid):
     1552                case(upper_trigrid):
     1553                  *((double *)value) = atof(dummy1);
     1554                  if ((verbose) && (i==0) && (j==0)) fprintf(stderr,"%s = ", name);
     1555                  if (verbose) fprintf(stderr,"%lg\t",*((double *)value));
     1556                  value = (void *)((long)value + sizeof(double));
     1557                  //value += sizeof(double);
     1558                  break;
     1559                case(double_type):
     1560                  *((double *)value) = atof(dummy1);
     1561                  if ((verbose) && (i == xth-1)) fprintf(stderr,"%s = %lg\n", name, *((double *) value));
     1562                  //value += sizeof(double);
     1563                  break;
     1564                case(int_type):
     1565                  *((int *)value) = atoi(dummy1);
     1566                  if ((verbose) && (i == xth-1)) fprintf(stderr,"%s = %i\n", name, *((int *) value));
     1567                  //value += sizeof(int);
     1568                  break;
     1569                default:
     1570                case(string_type):
     1571                  if (value != NULL) {
     1572                    //if (maxlength == -1) maxlength = strlen((char *)value); // get maximum size of string array
     1573                    maxlength = MAXSTRINGSIZE;
     1574                    length = maxlength > (dummy-dummy1) ? (dummy-dummy1) : maxlength; // cap at maximum
     1575                    strncpy((char *)value, dummy1, length);  // copy as much
     1576                    ((char *)value)[length] = '\0';  // and set end marker
     1577                    if ((verbose) && (i == xth-1)) fprintf(stderr,"%s is '%s' (%i chars)\n",name,((char *) value), length);
     1578                    //value += sizeof(char);
     1579                  } else {
     1580                  }
     1581                break;
     1582              }
     1583            }
     1584            while (*dummy == '\t')
     1585              dummy++;
     1586          }
     1587        }
     1588      }
     1589    }
     1590  }
     1591  if ((type >= row_int) && (verbose)) fprintf(stderr,"\n");
     1592  Free((void **)&free_dummy, "config::ParseForParameter: *free_dummy");
     1593  if (!sequential) {
     1594    file->clear();
     1595    file->seekg(file_position, ios::beg);  // rewind to start position
     1596  }
     1597  //fprintf(stderr, "End of Parsing\n\n");
     1598
     1599  return (found); // true if found, false if not
    16001600}
    16011601
  • src/datacreator.cpp

    r205ccd r042f82  
    1919bool OpenOutputFile(ofstream &output, const char *dir, const char *filename)
    2020{
    21         stringstream name;
    22         name << dir << "/" << filename;
    23         output.open(name.str().c_str(), ios::out);
    24         if (output == NULL) {
    25                 cout << "Unable to open " << name.str() << " for writing, is directory correct?" << endl;
    26                 return false;
    27         }
    28         return true;
     21  stringstream name;
     22  name << dir << "/" << filename;
     23  output.open(name.str().c_str(), ios::out);
     24  if (output == NULL) {
     25    cout << "Unable to open " << name.str() << " for writing, is directory correct?" << endl;
     26    return false;
     27  }
     28  return true;
    2929};
    3030
     
    3737bool AppendOutputFile(ofstream &output, const char *dir, const char *filename)
    3838{
    39         stringstream name;
    40         name << dir << "/" << filename;
    41         output.open(name.str().c_str(), ios::app);
    42         if (output == NULL) {
    43                 cout << "Unable to open " << name.str() << " for writing, is directory correct?" << endl;
    44                 return false;
    45         }
    46         return true;
     39  stringstream name;
     40  name << dir << "/" << filename;
     41  output.open(name.str().c_str(), ios::app);
     42  if (output == NULL) {
     43    cout << "Unable to open " << name.str() << " for writing, is directory correct?" << endl;
     44    return false;
     45  }
     46  return true;
    4747};
    4848
     
    5656bool CreateDataEnergyOrder(class EnergyMatrix &Fragments, class KeySetsContainer &KeySet, const char *dir, const char *prefix, const char *msg, const char *datum)
    5757{
    58         stringstream filename;
    59         ofstream output;
    60 
    61         filename << prefix << ".dat";
    62         if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
    63         cout << msg << endl;
    64         output << "# " << msg << ", created on " << datum;
    65         output << "#Order\tFrag.No.\t" << Fragments.Header << endl;
    66         for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
    67                 for(int i=KeySet.FragmentsPerOrder[BondOrder];i--;) {
    68                         for(int j=Fragments.RowCounter[ KeySet.OrderSet[BondOrder][i] ];j--;)
    69                                 for(int k=Fragments.ColumnCounter;k--;)
    70                                         Fragments.Matrix[Fragments.MatrixCounter][j][k] += Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k];
    71                 }
    72                 output << BondOrder+1 << "\t" << KeySet.FragmentsPerOrder[BondOrder];
    73                 for (int l=0;l<Fragments.ColumnCounter;l++)
    74                         output << scientific << "\t" << Fragments.Matrix[Fragments.MatrixCounter][ Fragments.RowCounter[Fragments.MatrixCounter]-1 ][l];
    75                 output << endl;
    76         }
    77         output.close();
    78         return true;
     58  stringstream filename;
     59  ofstream output;
     60
     61  filename << prefix << ".dat";
     62  if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
     63  cout << msg << endl;
     64  output << "# " << msg << ", created on " << datum;
     65  output << "#Order\tFrag.No.\t" << Fragments.Header << endl;
     66  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
     67    for(int i=KeySet.FragmentsPerOrder[BondOrder];i--;) {
     68      for(int j=Fragments.RowCounter[ KeySet.OrderSet[BondOrder][i] ];j--;)
     69        for(int k=Fragments.ColumnCounter;k--;)
     70          Fragments.Matrix[Fragments.MatrixCounter][j][k] += Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k];
     71    }
     72    output << BondOrder+1 << "\t" << KeySet.FragmentsPerOrder[BondOrder];
     73    for (int l=0;l<Fragments.ColumnCounter;l++)
     74      output << scientific << "\t" << Fragments.Matrix[Fragments.MatrixCounter][ Fragments.RowCounter[Fragments.MatrixCounter]-1 ][l];
     75    output << endl;
     76  }
     77  output.close();
     78  return true;
    7979};
    8080
     
    8989bool CreateDataDeltaEnergyOrder(class EnergyMatrix &Energy, class EnergyMatrix &Fragments, class KeySetsContainer &KeySet, const char *dir, const char *prefix, const char *msg, const char *datum)
    9090{
    91         stringstream filename;
    92         ofstream output;
    93 
    94         filename << prefix << ".dat";
    95         if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
    96         cout << msg << endl;
    97         output << "# " << msg << ", created on " << datum;
    98         output << "#Order\tFrag.No.\t" << Fragments.Header << endl;
    99         Fragments.SetLastMatrix(Energy.Matrix[Energy.MatrixCounter],0);
    100         for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
    101                 for(int i=KeySet.FragmentsPerOrder[BondOrder];i--;) {
    102                         for(int j=Fragments.RowCounter[ KeySet.OrderSet[BondOrder][i] ];j--;)
    103                                 for(int k=Fragments.ColumnCounter;k--;)
    104                                         Fragments.Matrix[Fragments.MatrixCounter][j][k] -= Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k];
    105                 }
    106                 output << BondOrder+1 << "\t" << KeySet.FragmentsPerOrder[BondOrder];
    107                 for (int l=0;l<Fragments.ColumnCounter;l++)
    108                         if (fabs(Energy.Matrix[Energy.MatrixCounter][ Energy.RowCounter[Energy.MatrixCounter]-1 ][l]) < MYEPSILON)
    109                                 output << scientific << "\t" << Fragments.Matrix[Fragments.MatrixCounter][ Fragments.RowCounter[Fragments.MatrixCounter]-1 ][l];
    110                         else
    111                                 output << scientific << "\t" << (Fragments.Matrix[Fragments.MatrixCounter][ Fragments.RowCounter[Fragments.MatrixCounter]-1 ][l] / Energy.Matrix[Energy.MatrixCounter][ Energy.RowCounter[Energy.MatrixCounter]-1 ][l]);
    112                 output << endl;
    113         }
    114         output.close();
    115         return true;
     91  stringstream filename;
     92  ofstream output;
     93
     94  filename << prefix << ".dat";
     95  if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
     96  cout << msg << endl;
     97  output << "# " << msg << ", created on " << datum;
     98  output << "#Order\tFrag.No.\t" << Fragments.Header << endl;
     99  Fragments.SetLastMatrix(Energy.Matrix[Energy.MatrixCounter],0);
     100  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
     101    for(int i=KeySet.FragmentsPerOrder[BondOrder];i--;) {
     102      for(int j=Fragments.RowCounter[ KeySet.OrderSet[BondOrder][i] ];j--;)
     103        for(int k=Fragments.ColumnCounter;k--;)
     104          Fragments.Matrix[Fragments.MatrixCounter][j][k] -= Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k];
     105    }
     106    output << BondOrder+1 << "\t" << KeySet.FragmentsPerOrder[BondOrder];
     107    for (int l=0;l<Fragments.ColumnCounter;l++)
     108      if (fabs(Energy.Matrix[Energy.MatrixCounter][ Energy.RowCounter[Energy.MatrixCounter]-1 ][l]) < MYEPSILON)
     109        output << scientific << "\t" << Fragments.Matrix[Fragments.MatrixCounter][ Fragments.RowCounter[Fragments.MatrixCounter]-1 ][l];
     110      else
     111        output << scientific << "\t" << (Fragments.Matrix[Fragments.MatrixCounter][ Fragments.RowCounter[Fragments.MatrixCounter]-1 ][l] / Energy.Matrix[Energy.MatrixCounter][ Energy.RowCounter[Energy.MatrixCounter]-1 ][l]);
     112    output << endl;
     113  }
     114  output.close();
     115  return true;
    116116};
    117117
     
    126126bool CreateDataForcesOrder(class ForceMatrix &Fragments, class KeySetsContainer &KeySet, const char *dir, const char *prefix,const  char *msg, const char *datum, void (*CreateForce)(class MatrixContainer &, int))
    127127{
    128         stringstream filename;
    129         ofstream output;
    130 
    131         filename << prefix << ".dat";
    132         if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
    133         cout << msg << endl;
    134         output << "# " << msg << ", created on " << datum;
    135         output << "# Order\tFrag.No.\t" << Fragments.Header << endl;
    136         Fragments.SetLastMatrix(0.,0);
    137         for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
    138                 Fragments.SumSubForces(Fragments, KeySet, BondOrder, 1.);
    139                 output << BondOrder+1 << "\t" << KeySet.FragmentsPerOrder[BondOrder];
    140                 CreateForce(Fragments, Fragments.MatrixCounter);
    141                 for (int l=0;l<Fragments.ColumnCounter;l++)
    142                         output << scientific << "\t" << Fragments.Matrix[Fragments.MatrixCounter][ Fragments.RowCounter[Fragments.MatrixCounter] ][l];
    143                 output << endl;
    144         }
    145         output.close();
    146         return true;
     128  stringstream filename;
     129  ofstream output;
     130
     131  filename << prefix << ".dat";
     132  if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
     133  cout << msg << endl;
     134  output << "# " << msg << ", created on " << datum;
     135  output << "# Order\tFrag.No.\t" << Fragments.Header << endl;
     136  Fragments.SetLastMatrix(0.,0);
     137  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
     138    Fragments.SumSubForces(Fragments, KeySet, BondOrder, 1.);
     139    output << BondOrder+1 << "\t" << KeySet.FragmentsPerOrder[BondOrder];
     140    CreateForce(Fragments, Fragments.MatrixCounter);
     141    for (int l=0;l<Fragments.ColumnCounter;l++)
     142      output << scientific << "\t" << Fragments.Matrix[Fragments.MatrixCounter][ Fragments.RowCounter[Fragments.MatrixCounter] ][l];
     143    output << endl;
     144  }
     145  output.close();
     146  return true;
    147147};
    148148
     
    158158bool 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))
    159159{
    160         stringstream filename;
    161         ofstream output;
    162 
    163         filename << prefix << ".dat";
    164         if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
    165         cout << msg << endl;
    166         output << "# " << msg << ", created on " << datum;
    167         output << "# Order\tFrag.No.\t" << Fragments.Header << endl;
    168         Fragments.SetLastMatrix(Force.Matrix[Force.MatrixCounter],0);
    169         for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
    170                 Fragments.SumSubForces(Fragments, KeySet, BondOrder, -1.);
    171                 output << BondOrder+1 << "\t" << KeySet.FragmentsPerOrder[BondOrder];
    172                 CreateForce(Fragments, Fragments.MatrixCounter);
    173                 for (int l=0;l<Fragments.ColumnCounter;l++)
    174                         output << scientific << "\t" << Fragments.Matrix[Fragments.MatrixCounter][ Fragments.RowCounter[Fragments.MatrixCounter] ][l];
    175                 output << endl;
    176         }
    177         output.close();
    178         return true;
     160  stringstream filename;
     161  ofstream output;
     162
     163  filename << prefix << ".dat";
     164  if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
     165  cout << msg << endl;
     166  output << "# " << msg << ", created on " << datum;
     167  output << "# Order\tFrag.No.\t" << Fragments.Header << endl;
     168  Fragments.SetLastMatrix(Force.Matrix[Force.MatrixCounter],0);
     169  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
     170    Fragments.SumSubForces(Fragments, KeySet, BondOrder, -1.);
     171    output << BondOrder+1 << "\t" << KeySet.FragmentsPerOrder[BondOrder];
     172    CreateForce(Fragments, Fragments.MatrixCounter);
     173    for (int l=0;l<Fragments.ColumnCounter;l++)
     174      output << scientific << "\t" << Fragments.Matrix[Fragments.MatrixCounter][ Fragments.RowCounter[Fragments.MatrixCounter] ][l];
     175    output << endl;
     176  }
     177  output.close();
     178  return true;
    179179};
    180180
     
    190190bool CreateDataDeltaForcesOrderPerAtom(class ForceMatrix &Force, class ForceMatrix &Fragments, class KeySetsContainer &KeySet, const char *dir, const char *prefix, const char *msg, const char *datum)
    191191{
    192         stringstream filename;
    193         ofstream output;
    194         double norm = 0.;
    195 
    196         filename << prefix << ".dat";
    197         if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
    198         cout << msg << endl;
    199         output << "# " << msg << ", created on " << datum;
    200         output << "# AtomNo\t" << Fragments.Header << endl;
    201         Fragments.SetLastMatrix(Force.Matrix[Force.MatrixCounter], 0);
    202         for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
    203                 //cout << "Current order is " << BondOrder << "." << endl;
    204                 Fragments.SumSubForces(Fragments, KeySet, BondOrder, -1.);
    205                 // errors per atom
    206                 output << endl << "#Order\t" << BondOrder+1 << endl;
    207                 for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) {
    208                         output << Fragments.Indices[Fragments.MatrixCounter][j] << "\t";
    209                         for (int l=0;l<Fragments.ColumnCounter;l++) {
    210                                 if (((l+1) % 3) == 0) {
    211                                         norm = 0.;
    212                                         for (int m=0;m<NDIM;m++)
    213                                                 norm += Force.Matrix[Force.MatrixCounter][ j ][l+m]*Force.Matrix[Force.MatrixCounter][ j ][l+m];
    214                                         norm = sqrt(norm);
    215                                 }
    216 //                              if (norm < MYEPSILON)
    217                                         output << scientific << Fragments.Matrix[Fragments.MatrixCounter][ j ][l] << "\t";
    218 //                              else
    219 //                                      output << scientific << (Fragments.Matrix[Fragments.MatrixCounter][ j ][l] / norm) << "\t";
    220                         }
    221                         output << endl;
    222                 }
    223                 output << endl;
    224         }
    225         output.close();
    226         return true;
     192  stringstream filename;
     193  ofstream output;
     194  double norm = 0.;
     195
     196  filename << prefix << ".dat";
     197  if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
     198  cout << msg << endl;
     199  output << "# " << msg << ", created on " << datum;
     200  output << "# AtomNo\t" << Fragments.Header << endl;
     201  Fragments.SetLastMatrix(Force.Matrix[Force.MatrixCounter], 0);
     202  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
     203    //cout << "Current order is " << BondOrder << "." << endl;
     204    Fragments.SumSubForces(Fragments, KeySet, BondOrder, -1.);
     205    // errors per atom
     206    output << endl << "#Order\t" << BondOrder+1 << endl;
     207    for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) {
     208      output << Fragments.Indices[Fragments.MatrixCounter][j] << "\t";
     209      for (int l=0;l<Fragments.ColumnCounter;l++) {
     210        if (((l+1) % 3) == 0) {
     211          norm = 0.;
     212          for (int m=0;m<NDIM;m++)
     213            norm += Force.Matrix[Force.MatrixCounter][ j ][l+m]*Force.Matrix[Force.MatrixCounter][ j ][l+m];
     214          norm = sqrt(norm);
     215        }
     216//        if (norm < MYEPSILON)
     217          output << scientific << Fragments.Matrix[Fragments.MatrixCounter][ j ][l] << "\t";
     218//        else
     219//          output << scientific << (Fragments.Matrix[Fragments.MatrixCounter][ j ][l] / norm) << "\t";
     220      }
     221      output << endl;
     222    }
     223    output << endl;
     224  }
     225  output.close();
     226  return true;
    227227};
    228228
     
    237237bool CreateDataForcesOrderPerAtom(class ForceMatrix &Fragments, class KeySetsContainer &KeySet, const char *dir, const char *prefix, const char *msg, const char *datum)
    238238{
    239         stringstream filename;
    240         ofstream output;
    241 
    242         filename << prefix << ".dat";
    243         if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
    244         cout << msg << endl;
    245         output << "# " << msg << ", created on " << datum;
    246         output << "# AtomNo\t" << Fragments.Header << endl;
    247         for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
    248                 //cout << "Current order is " << BondOrder << "." << endl;
    249                 Fragments.SumSubForces(Fragments, KeySet, BondOrder, 1.);
    250                 // errors per atom
    251                 output << endl << "#Order\t" << BondOrder+1 << endl;
    252                 for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) {
    253                         output << Fragments.Indices[Fragments.MatrixCounter][j] << "\t";
    254                         for (int l=0;l<Fragments.ColumnCounter;l++)
    255                                 output << scientific << Fragments.Matrix[Fragments.MatrixCounter][ j ][l] << "\t";
    256                         output << endl;
    257                 }
    258                 output << endl;
    259         }
    260         output.close();
    261         return true;
     239  stringstream filename;
     240  ofstream output;
     241
     242  filename << prefix << ".dat";
     243  if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
     244  cout << msg << endl;
     245  output << "# " << msg << ", created on " << datum;
     246  output << "# AtomNo\t" << Fragments.Header << endl;
     247  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
     248    //cout << "Current order is " << BondOrder << "." << endl;
     249    Fragments.SumSubForces(Fragments, KeySet, BondOrder, 1.);
     250    // errors per atom
     251    output << endl << "#Order\t" << BondOrder+1 << endl;
     252    for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) {
     253      output << Fragments.Indices[Fragments.MatrixCounter][j] << "\t";
     254      for (int l=0;l<Fragments.ColumnCounter;l++)
     255        output << scientific << Fragments.Matrix[Fragments.MatrixCounter][ j ][l] << "\t";
     256      output << endl;
     257    }
     258    output << endl;
     259  }
     260  output.close();
     261  return true;
    262262};
    263263
     
    266266bool CreateDataFragment(class MatrixContainer &Fragment, class KeySetsContainer &KeySet, const char *dir, const char *prefix, const char *msg, const char *datum, void (*CreateFragment)(class MatrixContainer &, int))
    267267{
    268         stringstream filename;
    269         ofstream output;
    270 
    271         filename << prefix << ".dat";
    272         if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
    273         cout << msg << endl;
    274         output << "# " << msg << ", created on " << datum << endl;
    275         output << "#Order\tFrag.No.\t" << Fragment.Header << endl;
    276         for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
    277                 for(int i=0;i<KeySet.FragmentsPerOrder[BondOrder];i++) {
    278                         output << BondOrder+1 << "\t" << KeySet.OrderSet[BondOrder][i]+1;
    279                         CreateFragment(Fragment, KeySet.OrderSet[BondOrder][i]);
    280                         for (int l=0;l<Fragment.ColumnCounter;l++)
    281                                 output << scientific << "\t" << Fragment.Matrix[ KeySet.OrderSet[BondOrder][i] ][ Fragment.RowCounter[ KeySet.OrderSet[BondOrder][i] ] ][l];
    282                         output << endl;
    283                 }
    284         }
    285         output.close();
    286         return true;
     268  stringstream filename;
     269  ofstream output;
     270
     271  filename << prefix << ".dat";
     272  if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
     273  cout << msg << endl;
     274  output << "# " << msg << ", created on " << datum << endl;
     275  output << "#Order\tFrag.No.\t" << Fragment.Header << endl;
     276  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
     277    for(int i=0;i<KeySet.FragmentsPerOrder[BondOrder];i++) {
     278      output << BondOrder+1 << "\t" << KeySet.OrderSet[BondOrder][i]+1;
     279      CreateFragment(Fragment, KeySet.OrderSet[BondOrder][i]);
     280      for (int l=0;l<Fragment.ColumnCounter;l++)
     281        output << scientific << "\t" << Fragment.Matrix[ KeySet.OrderSet[BondOrder][i] ][ Fragment.RowCounter[ KeySet.OrderSet[BondOrder][i] ] ][l];
     282      output << endl;
     283    }
     284  }
     285  output.close();
     286  return true;
    287287};
    288288
     
    294294void CreateMaxFragmentOrder(class MatrixContainer &Fragments, class KeySetsContainer &KeySet, int BondOrder)
    295295{
    296         for(int j=Fragments.RowCounter[ Fragments.MatrixCounter ];j--;) {
    297                 for(int i=KeySet.FragmentsPerOrder[BondOrder];i--;) {
    298                         if (fabs(Fragments.Matrix[ Fragments.MatrixCounter ][j][1]) < fabs(Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][1])) {
    299                                 for (int k=Fragments.ColumnCounter;k--;)
    300                                         Fragments.Matrix[ Fragments.MatrixCounter ][j][k] = Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k];
    301                         }
    302                 }
    303         }
     296  for(int j=Fragments.RowCounter[ Fragments.MatrixCounter ];j--;) {
     297    for(int i=KeySet.FragmentsPerOrder[BondOrder];i--;) {
     298      if (fabs(Fragments.Matrix[ Fragments.MatrixCounter ][j][1]) < fabs(Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][1])) {
     299        for (int k=Fragments.ColumnCounter;k--;)
     300          Fragments.Matrix[ Fragments.MatrixCounter ][j][k] = Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k];
     301      }
     302    }
     303  }
    304304};
    305305
     
    311311void CreateMinFragmentOrder(class MatrixContainer &Fragments, class KeySetsContainer &KeySet, int BondOrder)
    312312{
    313         for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) {
    314                 int i=0;
    315                 do {    // first get a minimum value unequal to 0
    316                         for (int k=Fragments.ColumnCounter;k--;)
    317                                 Fragments.Matrix[ Fragments.MatrixCounter ][j][k] = Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k];
    318                         i++;
    319                 } while ((fabs(Fragments.Matrix[ Fragments.MatrixCounter ][j][1]) < MYEPSILON) && (i<KeySet.FragmentsPerOrder[BondOrder]));
    320                 for(;i<KeySet.FragmentsPerOrder[BondOrder];i++) { // then find lowest
    321                         if (fabs(Fragments.Matrix[ Fragments.MatrixCounter ][j][1]) > fabs(Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][1])) {
    322                                 for (int k=Fragments.ColumnCounter;k--;)
    323                                         Fragments.Matrix[ Fragments.MatrixCounter ][j][k] = Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k];
    324                         }
    325                 }
    326         }
     313  for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) {
     314    int i=0;
     315    do {  // first get a minimum value unequal to 0
     316      for (int k=Fragments.ColumnCounter;k--;)
     317        Fragments.Matrix[ Fragments.MatrixCounter ][j][k] = Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k];
     318      i++;
     319    } while ((fabs(Fragments.Matrix[ Fragments.MatrixCounter ][j][1]) < MYEPSILON) && (i<KeySet.FragmentsPerOrder[BondOrder]));
     320    for(;i<KeySet.FragmentsPerOrder[BondOrder];i++) { // then find lowest
     321      if (fabs(Fragments.Matrix[ Fragments.MatrixCounter ][j][1]) > fabs(Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][1])) {
     322        for (int k=Fragments.ColumnCounter;k--;)
     323          Fragments.Matrix[ Fragments.MatrixCounter ][j][k] = Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k];
     324      }
     325    }
     326  }
    327327};
    328328
     
    331331bool 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))
    332332{
    333         stringstream filename;
    334         ofstream output;
    335 
    336         filename << prefix << ".dat";
    337         if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
    338         cout << msg << endl;
    339         output << "# " << msg << ", created on " << datum;
    340         output << "#Order\tFrag.No.\t" << Fragment.Header << endl;
    341         // max
    342         for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
    343                 Fragment.SetLastMatrix(0.,0);
    344                 CreateFragmentOrder(Fragment, KeySet, BondOrder);
    345                 output << BondOrder+1 << "\t" << KeySet.FragmentsPerOrder[BondOrder];
    346                 for (int l=0;l<Fragment.ColumnCounter;l++)
    347                         output << scientific << "\t" << Fragment.Matrix[ Fragment.MatrixCounter ][ Fragment.RowCounter[ Fragment.MatrixCounter ]-1 ][l];
    348                 output << endl;
    349         }
    350         output.close();
    351         return true;
     333  stringstream filename;
     334  ofstream output;
     335
     336  filename << prefix << ".dat";
     337  if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
     338  cout << msg << endl;
     339  output << "# " << msg << ", created on " << datum;
     340  output << "#Order\tFrag.No.\t" << Fragment.Header << endl;
     341  // max
     342  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
     343    Fragment.SetLastMatrix(0.,0);
     344    CreateFragmentOrder(Fragment, KeySet, BondOrder);
     345    output << BondOrder+1 << "\t" << KeySet.FragmentsPerOrder[BondOrder];
     346    for (int l=0;l<Fragment.ColumnCounter;l++)
     347      output << scientific << "\t" << Fragment.Matrix[ Fragment.MatrixCounter ][ Fragment.RowCounter[ Fragment.MatrixCounter ]-1 ][l];
     348    output << endl;
     349  }
     350  output.close();
     351  return true;
    352352};
    353353
     
    358358void CreateEnergy(class MatrixContainer &Energy, int MatrixNumber)
    359359{
    360         for(int k=0;k<Energy.ColumnCounter;k++)
    361                 Energy.Matrix[MatrixNumber][ Energy.RowCounter[MatrixNumber] ] [k] =    Energy.Matrix[MatrixNumber][ Energy.RowCounter[MatrixNumber]-1 ] [k];
     360  for(int k=0;k<Energy.ColumnCounter;k++)
     361    Energy.Matrix[MatrixNumber][ Energy.RowCounter[MatrixNumber] ] [k] =  Energy.Matrix[MatrixNumber][ Energy.RowCounter[MatrixNumber]-1 ] [k];
    362362};
    363363
     
    369369void CreateMinimumForce(class MatrixContainer &Force, int MatrixNumber)
    370370{
    371         for (int l=Force.ColumnCounter;l--;)
    372                 Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l] = 0.;
    373         for (int l=5;l<Force.ColumnCounter;l+=3) {
    374                 double stored = 0;
    375                 int k=0;
    376                 do {
    377                         for (int m=NDIM;m--;) {
    378                                 stored += Force.Matrix[MatrixNumber][ k ][l+m]
    379                                                         * Force.Matrix[MatrixNumber][ k ][l+m];
    380                                 Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l+m]       = Force.Matrix[MatrixNumber][ k ][l+m];
    381                         }
    382                         k++;
    383                 } while ((fabs(stored) < MYEPSILON) && (k<Force.RowCounter[MatrixNumber]));
    384                 for (;k<Force.RowCounter[MatrixNumber];k++) {
    385                         double tmp = 0;
    386                         for (int m=NDIM;m--;)
    387                                 tmp += Force.Matrix[MatrixNumber][ k ][l+m]
    388                                                         * Force.Matrix[MatrixNumber][ k ][l+m];
    389                         if ((fabs(tmp) > MYEPSILON) && (tmp < stored)) {        // current force is greater than stored
    390                                 for (int m=NDIM;m--;)
    391                                         Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l+m]       = Force.Matrix[MatrixNumber][ k ][l+m];
    392                                 stored = tmp;
    393                         }
    394                 }
    395         }
     371  for (int l=Force.ColumnCounter;l--;)
     372    Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l] = 0.;
     373  for (int l=5;l<Force.ColumnCounter;l+=3) {
     374    double stored = 0;
     375    int k=0;
     376    do {
     377      for (int m=NDIM;m--;) {
     378        stored += Force.Matrix[MatrixNumber][ k ][l+m]
     379              * Force.Matrix[MatrixNumber][ k ][l+m];
     380        Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l+m]  = Force.Matrix[MatrixNumber][ k ][l+m];
     381      }
     382      k++;
     383    } while ((fabs(stored) < MYEPSILON) && (k<Force.RowCounter[MatrixNumber]));
     384    for (;k<Force.RowCounter[MatrixNumber];k++) {
     385      double tmp = 0;
     386      for (int m=NDIM;m--;)
     387        tmp += Force.Matrix[MatrixNumber][ k ][l+m]
     388              * Force.Matrix[MatrixNumber][ k ][l+m];
     389      if ((fabs(tmp) > MYEPSILON) && (tmp < stored)) {  // current force is greater than stored
     390        for (int m=NDIM;m--;)
     391          Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l+m]  = Force.Matrix[MatrixNumber][ k ][l+m];
     392        stored = tmp;
     393      }
     394    }
     395  }
    396396};
    397397
     
    399399 * Results are stored in the matrix ForceMatrix::MatrixCounter of \a Force.
    400400 * \param Force ForceMatrix class containing matrix values
    401         * \param MatrixNumber the index for the ForceMatrix::matrix array
     401  * \param MatrixNumber the index for the ForceMatrix::matrix array
    402402 */
    403403void CreateMeanForce(class MatrixContainer &Force, int MatrixNumber)
    404404{
    405         int divisor = 0;
    406         for (int l=Force.ColumnCounter;l--;)
    407                 Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l] = 0.;
    408         for (int l=5;l<Force.ColumnCounter;l+=3) {
    409                 double tmp = 0;
    410                 for (int k=Force.RowCounter[MatrixNumber];k--;) {
    411                         double norm = 0.;
    412                         for (int m=NDIM;m--;)
    413                                 norm += Force.Matrix[MatrixNumber][ k ][l+m]
    414                                                         * Force.Matrix[MatrixNumber][ k ][l+m];
    415                         tmp += sqrt(norm);
    416                         if (fabs(norm) > MYEPSILON) divisor++;
    417                 }
    418                 tmp /= (double)divisor;
    419                 Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l] = tmp;
    420         }
     405  int divisor = 0;
     406  for (int l=Force.ColumnCounter;l--;)
     407    Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l] = 0.;
     408  for (int l=5;l<Force.ColumnCounter;l+=3) {
     409    double tmp = 0;
     410    for (int k=Force.RowCounter[MatrixNumber];k--;) {
     411      double norm = 0.;
     412      for (int m=NDIM;m--;)
     413        norm += Force.Matrix[MatrixNumber][ k ][l+m]
     414              * Force.Matrix[MatrixNumber][ k ][l+m];
     415      tmp += sqrt(norm);
     416      if (fabs(norm) > MYEPSILON) divisor++;
     417    }
     418    tmp /= (double)divisor;
     419    Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l] = tmp;
     420  }
    421421};
    422422
     
    428428void CreateMaximumForce(class MatrixContainer &Force, int MatrixNumber)
    429429{
    430         for (int l=5;l<Force.ColumnCounter;l+=3) {
    431                 double stored = 0;
    432                 for (int k=Force.RowCounter[MatrixNumber];k--;) {
    433                         double tmp = 0;
    434                         for (int m=NDIM;m--;)
    435                                 tmp += Force.Matrix[MatrixNumber][ k ][l+m]
    436                                                         * Force.Matrix[MatrixNumber][ k ][l+m];
    437                         if (tmp > stored) {     // current force is greater than stored
    438                                 for (int m=NDIM;m--;)
    439                                         Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l+m]       = Force.Matrix[MatrixNumber][ k ][l+m];
    440                                 stored = tmp;
    441                         }
    442                 }
    443         }
     430  for (int l=5;l<Force.ColumnCounter;l+=3) {
     431    double stored = 0;
     432    for (int k=Force.RowCounter[MatrixNumber];k--;) {
     433      double tmp = 0;
     434      for (int m=NDIM;m--;)
     435        tmp += Force.Matrix[MatrixNumber][ k ][l+m]
     436              * Force.Matrix[MatrixNumber][ k ][l+m];
     437      if (tmp > stored) {  // current force is greater than stored
     438        for (int m=NDIM;m--;)
     439          Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l+m]  = Force.Matrix[MatrixNumber][ k ][l+m];
     440        stored = tmp;
     441      }
     442    }
     443  }
    444444};
    445445
     
    450450void CreateSameForce(class MatrixContainer &Force, int MatrixNumber)
    451451{
    452         // does nothing
     452  // does nothing
    453453};
    454454
     
    460460void CreateVectorSumForce(class MatrixContainer &Force, int MatrixNumber)
    461461{
    462         for (int l=Force.ColumnCounter;l--;)
    463                 Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l] = 0.;
    464         for (int l=0;l<Force.ColumnCounter;l++) {
    465                 for (int k=Force.RowCounter[MatrixNumber];k--;)
    466                         Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l] += Force.Matrix[MatrixNumber][k][l];
    467         }
     462  for (int l=Force.ColumnCounter;l--;)
     463    Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l] = 0.;
     464  for (int l=0;l<Force.ColumnCounter;l++) {
     465    for (int k=Force.RowCounter[MatrixNumber];k--;)
     466      Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l] += Force.Matrix[MatrixNumber][k][l];
     467  }
    468468};
    469469
     
    480480void CreatePlotHeader(ofstream &output, const char *prefix, const int keycolumns, const char *key, const char *logscale, const char *extraline, const int mxtics, const int xtics, const char *xlabel, const char *ylabel)
    481481{
    482         //output << "#!/home/heber/build/pyxplot/pyxplot" << endl << endl;
    483         output << "reset" << endl;
    484         output << "set keycolumns "<< keycolumns << endl;
    485         output << "set key " << key << endl;
    486         output << "set mxtics "<< mxtics << endl;
    487         output << "set xtics "<< xtics << endl;
    488         if (logscale != NULL)
    489                 output << "set logscale " << logscale << endl;
    490         if (extraline != NULL)
    491                 output << extraline << endl;
    492         output << "set xlabel '" << xlabel << "'" << endl;
    493         output << "set ylabel '" << ylabel << "'" << endl;
    494         output << "set terminal eps color" << endl;
    495         output << "set output '"<< prefix << ".eps'" << endl;
     482  //output << "#!/home/heber/build/pyxplot/pyxplot" << endl << endl;
     483  output << "reset" << endl;
     484  output << "set keycolumns "<< keycolumns << endl;
     485  output << "set key " << key << endl;
     486  output << "set mxtics "<< mxtics << endl;
     487  output << "set xtics "<< xtics << endl;
     488  if (logscale != NULL)
     489    output << "set logscale " << logscale << endl;
     490  if (extraline != NULL)
     491    output << extraline << endl;
     492  output << "set xlabel '" << xlabel << "'" << endl;
     493  output << "set ylabel '" << ylabel << "'" << endl;
     494  output << "set terminal eps color" << endl;
     495  output << "set output '"<< prefix << ".eps'" << endl;
    496496};
    497497
     
    517517bool CreatePlotOrder(class MatrixContainer &Matrix, const class KeySetsContainer &KeySet, const char *dir, const char *prefix, const int keycolumns, const char *key, const char *logscale, const char *extraline, const int mxtics, const int xtics, const char *xlabel, const char *ylabel, const char *xrange, const char *yrange, const char *xargument, const char *uses, void (*CreatePlotLines)(ofstream &, class MatrixContainer &, const char *, const char *, const char *))
    518518{
    519         stringstream filename;
    520         ofstream output;
    521 
    522         filename << prefix << ".pyx";
    523         if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
    524         CreatePlotHeader(output, prefix, keycolumns, key, logscale, extraline, mxtics, xtics, xlabel, ylabel);
    525         output << "plot " << xrange << " " << yrange << " \\" << endl;
    526         CreatePlotLines(output, Matrix, prefix, xargument, uses);
    527         output.close();
    528         return true;
     519  stringstream filename;
     520  ofstream output;
     521
     522  filename << prefix << ".pyx";
     523  if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
     524  CreatePlotHeader(output, prefix, keycolumns, key, logscale, extraline, mxtics, xtics, xlabel, ylabel);
     525  output << "plot " << xrange << " " << yrange << " \\" << endl;
     526  CreatePlotLines(output, Matrix, prefix, xargument, uses);
     527  output.close();
     528  return true;
    529529};
    530530
     
    538538void AbsEnergyPlotLine(ofstream &output, class MatrixContainer &Energy, const char *prefix, const char *xargument, const char *uses)
    539539{
    540         stringstream line(Energy.Header);
    541         string token;
    542 
    543         getline(line, token, '\t');
    544         for (int i=2; i<= Energy.ColumnCounter;i++) {
    545                 getline(line, token, '\t');
    546                 while (token[0] == ' ') // remove leading white spaces
    547                         token.erase(0,1);
    548                 output << "'" << prefix << ".dat' title '" << token << "' using " << xargument << ":(abs($" << i+2 << ")) " << uses;
    549                 if (i != (Energy.ColumnCounter))
    550                         output << ", \\";
    551                 output << endl;
    552         }
     540  stringstream line(Energy.Header);
     541  string token;
     542
     543  getline(line, token, '\t');
     544  for (int i=2; i<= Energy.ColumnCounter;i++) {
     545    getline(line, token, '\t');
     546    while (token[0] == ' ') // remove leading white spaces
     547      token.erase(0,1);
     548    output << "'" << prefix << ".dat' title '" << token << "' using " << xargument << ":(abs($" << i+2 << ")) " << uses;
     549    if (i != (Energy.ColumnCounter))
     550      output << ", \\";
     551    output << endl;
     552  }
    553553};
    554554
     
    562562void EnergyPlotLine(ofstream &output, class MatrixContainer &Energy, const char *prefix, const char *xargument, const char *uses)
    563563{
    564         stringstream line(Energy.Header);
    565         string token;
    566 
    567         getline(line, token, '\t');
    568         for (int i=1; i<= Energy.ColumnCounter;i++) {
    569                 getline(line, token, '\t');
    570                 while (token[0] == ' ') // remove leading white spaces
    571                         token.erase(0,1);
    572                 output << "'" << prefix << ".dat' title '" << token << "' using " << xargument << ":" << i+2 << " " << uses;
    573                 if (i != (Energy.ColumnCounter))
    574                         output << ", \\";
    575                 output << endl;
    576         }
     564  stringstream line(Energy.Header);
     565  string token;
     566
     567  getline(line, token, '\t');
     568  for (int i=1; i<= Energy.ColumnCounter;i++) {
     569    getline(line, token, '\t');
     570    while (token[0] == ' ') // remove leading white spaces
     571      token.erase(0,1);
     572    output << "'" << prefix << ".dat' title '" << token << "' using " << xargument << ":" << i+2 << " " << uses;
     573    if (i != (Energy.ColumnCounter))
     574      output << ", \\";
     575    output << endl;
     576  }
    577577};
    578578
     
    586586void ForceMagnitudePlotLine(ofstream &output, class MatrixContainer &Force, const char *prefix, const char *xargument, const char *uses)
    587587{
    588         stringstream line(Force.Header);
    589         string token;
    590 
    591         getline(line, token, '\t');
    592         getline(line, token, '\t');
    593         getline(line, token, '\t');
    594         getline(line, token, '\t');
    595         getline(line, token, '\t');
    596         for (int i=7; i< Force.ColumnCounter;i+=NDIM) {
    597                 getline(line, token, '\t');
    598                 while (token[0] == ' ') // remove leading white spaces
    599                         token.erase(0,1);
    600                 token.erase(token.length(), 1); // kill residual index char (the '0')
    601                 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))
    603                         output << ", \\";
    604                 output << endl;
    605                 getline(line, token, '\t');
    606                 getline(line, token, '\t');
    607         }
     588  stringstream line(Force.Header);
     589  string token;
     590
     591  getline(line, token, '\t');
     592  getline(line, token, '\t');
     593  getline(line, token, '\t');
     594  getline(line, token, '\t');
     595  getline(line, token, '\t');
     596  for (int i=7; i< Force.ColumnCounter;i+=NDIM) {
     597    getline(line, token, '\t');
     598    while (token[0] == ' ') // remove leading white spaces
     599      token.erase(0,1);
     600    token.erase(token.length(), 1);  // kill residual index char (the '0')
     601    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))
     603      output << ", \\";
     604    output << endl;
     605    getline(line, token, '\t');
     606    getline(line, token, '\t');
     607  }
    608608};
    609609
     
    617617void AbsFirstForceValuePlotLine(ofstream &output, class MatrixContainer &Force, const char *prefix, const char *xargument, const char *uses)
    618618{
    619         stringstream line(Force.Header);
    620         string token;
    621 
    622         getline(line, token, '\t');
    623         getline(line, token, '\t');
    624         getline(line, token, '\t');
    625         getline(line, token, '\t');
    626         getline(line, token, '\t');
    627         for (int i=7; i< Force.ColumnCounter;i+=NDIM) {
    628                 getline(line, token, '\t');
    629                 while (token[0] == ' ') // remove leading white spaces
    630                         token.erase(0,1);
    631                 token.erase(token.length(), 1); // kill residual index char (the '0')
    632                 output << "'" << prefix << ".dat' title '" << token << "' using " << xargument << ":(abs($" << i+1 << ")) " << uses;
    633                 if (i != (Force.ColumnCounter-1))
    634                         output << ", \\";
    635                 output << endl;
    636                 getline(line, token, '\t');
    637                 getline(line, token, '\t');
    638         }
     619  stringstream line(Force.Header);
     620  string token;
     621
     622  getline(line, token, '\t');
     623  getline(line, token, '\t');
     624  getline(line, token, '\t');
     625  getline(line, token, '\t');
     626  getline(line, token, '\t');
     627  for (int i=7; i< Force.ColumnCounter;i+=NDIM) {
     628    getline(line, token, '\t');
     629    while (token[0] == ' ') // remove leading white spaces
     630      token.erase(0,1);
     631    token.erase(token.length(), 1);  // kill residual index char (the '0')
     632    output << "'" << prefix << ".dat' title '" << token << "' using " << xargument << ":(abs($" << i+1 << ")) " << uses;
     633    if (i != (Force.ColumnCounter-1))
     634      output << ", \\";
     635    output << endl;
     636    getline(line, token, '\t');
     637    getline(line, token, '\t');
     638  }
    639639};
    640640
     
    648648void BoxesForcePlotLine(ofstream &output, class MatrixContainer &Force, const char *prefix, const char *xargument, const char *uses)
    649649{
    650         stringstream line(Force.Header);
    651         const char *fillcolor[5] = {"black", "red", "blue", "green", "cyan"};
    652         string token;
    653 
    654         getline(line, token, '\t');
    655         getline(line, token, '\t');
    656         getline(line, token, '\t');
    657         getline(line, token, '\t');
    658         getline(line, token, '\t');
    659         for (int i=7; i< Force.ColumnCounter;i+=NDIM) {
    660                 getline(line, token, '\t');
    661                 while (token[0] == ' ') // remove leading white spaces
    662                         token.erase(0,1);
    663                 token.erase(token.length(), 1); // kill residual index char (the '0')
    664                 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))
    666                         output << ", \\";
    667                 output << endl;
    668                 getline(line, token, '\t');
    669                 getline(line, token, '\t');
    670         }
     650  stringstream line(Force.Header);
     651  const char *fillcolor[5] = {"black", "red", "blue", "green", "cyan"};
     652  string token;
     653
     654  getline(line, token, '\t');
     655  getline(line, token, '\t');
     656  getline(line, token, '\t');
     657  getline(line, token, '\t');
     658  getline(line, token, '\t');
     659  for (int i=7; i< Force.ColumnCounter;i+=NDIM) {
     660    getline(line, token, '\t');
     661    while (token[0] == ' ') // remove leading white spaces
     662      token.erase(0,1);
     663    token.erase(token.length(), 1);  // kill residual index char (the '0')
     664    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))
     666      output << ", \\";
     667    output << endl;
     668    getline(line, token, '\t');
     669    getline(line, token, '\t');
     670  }
    671671};
    672672
     
    680680void BoxesFirstForceValuePlotLine(ofstream &output, class MatrixContainer &Force, const char *prefix, const char *xargument, const char *uses)
    681681{
    682         stringstream line(Force.Header);
    683         const char *fillcolor[5] = {"black", "red", "blue", "green", "cyan"};
    684         string token;
    685 
    686         getline(line, token, '\t');
    687         getline(line, token, '\t');
    688         getline(line, token, '\t');
    689         getline(line, token, '\t');
    690         getline(line, token, '\t');
    691         for (int i=7; i< Force.ColumnCounter;i+=NDIM) {
    692                 getline(line, token, '\t');
    693                 while (token[0] == ' ') // remove leading white spaces
    694                         token.erase(0,1);
    695                 token.erase(token.length(), 1); // kill residual index char (the '0')
    696                 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))
    698                         output << ", \\";
    699                 output << endl;
    700                 getline(line, token, '\t');
    701                 getline(line, token, '\t');
    702         }
    703 };
     682  stringstream line(Force.Header);
     683  const char *fillcolor[5] = {"black", "red", "blue", "green", "cyan"};
     684  string token;
     685
     686  getline(line, token, '\t');
     687  getline(line, token, '\t');
     688  getline(line, token, '\t');
     689  getline(line, token, '\t');
     690  getline(line, token, '\t');
     691  for (int i=7; i< Force.ColumnCounter;i+=NDIM) {
     692    getline(line, token, '\t');
     693    while (token[0] == ' ') // remove leading white spaces
     694      token.erase(0,1);
     695    token.erase(token.length(), 1);  // kill residual index char (the '0')
     696    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))
     698      output << ", \\";
     699    output << endl;
     700    getline(line, token, '\t');
     701    getline(line, token, '\t');
     702  }
     703};
  • src/defs.hpp

    r205ccd r042f82  
    1010using namespace std;
    1111
    12 #define MYEPSILON 1e-13  //!< machine epsilon precision
    13 #define NDIM    3        //!< number of spatial dimensions
    14 #define MAX_ELEMENTS 128        //!< maximum number of elements for certain lookup tables
    15 #define AtomicLengthToAngstroem 0.52917721 //!< conversion factor from atomic length/bohrradius to angstroem
    16 #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
    17 #define AtomicEnergyToKelvin 315774.67  //!< conversion factor from atomic energy to kelvin via boltzmann factor
     12#define MYEPSILON 1e-13  //!< machine epsilon precision
     13#define NDIM  3  //!< number of spatial dimensions
     14#define MAX_ELEMENTS 128  //!< maximum number of elements for certain lookup tables
     15#define AtomicLengthToAngstroem  0.52917721 //!< conversion factor from atomic length/bohrradius to angstroem
     16#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
     17#define AtomicEnergyToKelvin 315774.67  //!< conversion factor from atomic energy to kelvin via boltzmann factor
    1818#define VERSIONSTRING "v1.0"
    1919
     
    2424enum EdgeType { Undetermined, TreeEdge, BackEdge }; //!< edge type in a graph after Depth-First-Search analysis.
    2525
    26 enum Shading { white, lightgray, darkgray, black };     //!< color in Breadth-First-Search analysis
     26enum Shading { white, lightgray, darkgray, black };  //!< color in Breadth-First-Search analysis
    2727
    28 //enum CutCyclicBond { KeepBond,        SaturateBond }; //!< Saturation scheme either atom- or bondwise
     28//enum CutCyclicBond { KeepBond,  SaturateBond }; //!< Saturation scheme either atom- or bondwise
    2929
    3030// Specifting whether a value in the parameter file must be specified or is optional
    31 enum necessity { optional,              //!< parameter is optional, if not given sensible value is chosen
    32                                                                  critical                //!< parameter must be given or programme won't initiate
    33                                                         };
     31enum necessity { optional,    //!< parameter is optional, if not given sensible value is chosen
     32                 critical    //!< parameter must be given or programme won't initiate
     33              };
    3434
    3535// Specifying the status of the on command line given config file
     
    4343
    4444// various standard filenames
    45 #define DEFAULTCONFIG "main_pcp_linux"          //!< default filename of config file
    46 #define CONVEXENVELOPE "ConvexEnvelope.dat"             //!< default filename of convex envelope tecplot data file
    47 #define KEYSETFILE "KeySets.dat"                //!< default filename of BOSSANOVA key sets file
    48 #define ADJACENCYFILE "Adjacency.dat"           //!< default filename of BOSSANOVA adjacancy file
    49 #define TEFACTORSFILE "TE-Factors.dat"          //!< default filename of BOSSANOVA total energy factors file
    50 #define FORCESFILE "Forces-Factors.dat"         //!< default filename of BOSSANOVA force factors file
    51 #define HCORRECTIONSUFFIX "Hcorrection.dat"             //!< default filename of BOSSANOVA H correction file (unwanted saturation interaction)
    52 #define FITCONSTANTSUFFIX "FitConstant.dat"      //!< suffix of default filename of BOSSANOVA fit constants file (unwanted saturation interaction)
    53 #define SHIELDINGSUFFIX "sigma_all.csv"                                                         //!< default filename of BOSSANOVA shieldings file
    54 #define SHIELDINGPASSUFFIX "sigma_all_PAS.csv"                                                          //!< default filename of BOSSANOVA shieldings PAS file
    55 #define ORDERATSITEFILE "OrderAtSite.dat"               //!< default filename of BOSSANOVA Bond Order at each atom file
    56 #define ENERGYPERFRAGMENT "EnergyPerFragment"           //!< default filename of BOSSANOVA Energy contribution Per Fragment file
    57 #define FRAGMENTPREFIX "BondFragment"           //!< default filename prefix of BOSSANOVA fragment config and directories
    58 #define STANDARDCONFIG "unknown.conf"           //!< default filename of standard config file
    59 #define STANDARDELEMENTSDB "elements.db"                //!< default filename of elements data base with masses, Z, VanDerWaals radii, ...
    60 #define STANDARDVALENCEDB "valence.db"          //!< default filename of valence number per element database
    61 #define STANDARDORBITALDB "orbitals.db"         //!< default filename of orbitals per element database
    62 #define STANDARDHBONDDISTANCEDB "Hbonddistance.db"              //!< default filename of typial bond distance to hydrogen database
    63 #define STANDARDHBONDANGLEDB "Hbondangle.db"            //!< default filename of typial bond angle to hydrogen database
     45#define DEFAULTCONFIG "main_pcp_linux"    //!< default filename of config file
     46#define CONVEXENVELOPE "ConvexEnvelope.dat"    //!< default filename of convex envelope tecplot data file
     47#define KEYSETFILE "KeySets.dat"    //!< default filename of BOSSANOVA key sets file
     48#define ADJACENCYFILE "Adjacency.dat"    //!< default filename of BOSSANOVA adjacancy file
     49#define TEFACTORSFILE "TE-Factors.dat"    //!< default filename of BOSSANOVA total energy factors file
     50#define FORCESFILE "Forces-Factors.dat"    //!< default filename of BOSSANOVA force factors file
     51#define HCORRECTIONSUFFIX "Hcorrection.dat"    //!< default filename of BOSSANOVA H correction file (unwanted saturation interaction)
     52#define FITCONSTANTSUFFIX "FitConstant.dat"  //!< suffix of default filename of BOSSANOVA fit constants file (unwanted saturation interaction)
     53#define SHIELDINGSUFFIX "sigma_all.csv"                //!< default filename of BOSSANOVA shieldings file
     54#define SHIELDINGPASSUFFIX "sigma_all_PAS.csv"                //!< default filename of BOSSANOVA shieldings PAS file
     55#define ORDERATSITEFILE "OrderAtSite.dat"    //!< default filename of BOSSANOVA Bond Order at each atom file
     56#define ENERGYPERFRAGMENT "EnergyPerFragment"    //!< default filename of BOSSANOVA Energy contribution Per Fragment file
     57#define FRAGMENTPREFIX "BondFragment"    //!< default filename prefix of BOSSANOVA fragment config and directories
     58#define STANDARDCONFIG "unknown.conf"    //!< default filename of standard config file
     59#define STANDARDELEMENTSDB "elements.db"    //!< default filename of elements data base with masses, Z, VanDerWaals radii, ...
     60#define STANDARDVALENCEDB "valence.db"    //!< default filename of valence number per element database
     61#define STANDARDORBITALDB "orbitals.db"    //!< default filename of orbitals per element database
     62#define STANDARDHBONDDISTANCEDB "Hbonddistance.db"    //!< default filename of typial bond distance to hydrogen database
     63#define STANDARDHBONDANGLEDB "Hbondangle.db"    //!< default filename of typial bond angle to hydrogen database
    6464
    6565// some values
     
    6868
    6969
    70 #define UPDATECOUNT 10  //!< update ten sites per BOSSANOVA interval
     70#define UPDATECOUNT 10  //!< update ten sites per BOSSANOVA interval
    7171
    7272#endif /*DEFS_HPP_*/
  • src/element.cpp

    r205ccd r042f82  
    1212 */
    1313element::element() {
    14         Z = -1;
    15         No = -1;
    16         previous = NULL;
    17         next = NULL;
    18         sort = NULL;
     14  Z = -1;
     15  No = -1;
     16  previous = NULL;
     17  next = NULL;
     18  sort = NULL;
    1919};
    2020
     
    2828bool element::Output(ofstream *out) const
    2929{
    30         if (out != NULL) {
    31                 *out << name << "\t" << symbol << "\t" << period << "\t" << group << "\t" << block << "\t" << Z << "\t" << mass << "\t" << CovalentRadius << "\t" << VanDerWaalsRadius << endl;
    32                 //*out << Z << "\t"     << fixed << setprecision(11) << showpoint << mass << "g/mol\t" << name << "\t" << symbol << "\t" << endl;
    33                 return true;
    34         } else
    35                 return false;
     30  if (out != NULL) {
     31    *out << name << "\t" << symbol << "\t" << period << "\t" << group << "\t" << block << "\t" << Z << "\t" << mass << "\t" << CovalentRadius << "\t" << VanDerWaalsRadius << endl;
     32    //*out << Z << "\t"  << fixed << setprecision(11) << showpoint << mass << "g/mol\t" << name << "\t" << symbol << "\t" << endl;
     33    return true;
     34  } else
     35    return false;
    3636};
    3737
    3838/** Prints element data to \a *out.
    3939 * \param *out outstream
    40  * \param No    cardinal number of element
     40 * \param No  cardinal number of element
    4141 * \param NoOfAtoms total number of atom of this element type
    4242 */
    4343bool element::Checkout(ofstream *out, const int Number, const int NoOfAtoms) const
    4444{
    45         if (out != NULL) {
    46                 *out << "Ion_Type" << Number << "\t" << NoOfAtoms << "\t" << Z << "\t1.0\t3\t3\t" << fixed << setprecision(11) << showpoint << mass << "\t" << name << "\t" << symbol <<endl;
    47                 return true;
    48         } else
    49                 return false;
     45  if (out != NULL) {
     46    *out << "Ion_Type" << Number << "\t" << NoOfAtoms << "\t" << Z << "\t1.0\t3\t3\t" << fixed << setprecision(11) << showpoint << mass << "\t" << name << "\t" << symbol <<endl;
     47    return true;
     48  } else
     49    return false;
    5050};
  • src/ellipsoid.cpp

    r205ccd r042f82  
    22 * ellipsoid.cpp
    33 *
    4  *      Created on: Jan 20, 2009
    5  *                      Author: heber
     4 *  Created on: Jan 20, 2009
     5 *      Author: heber
    66 */
    77
     
    1717double SquaredDistanceToEllipsoid(Vector &x, Vector &EllipsoidCenter, double *EllipsoidLength, double *EllipsoidAngle)
    1818{
    19         Vector helper, RefPoint;
    20         double distance = -1.;
    21         double Matrix[NDIM*NDIM];
    22         double InverseLength[3];
    23         double psi,theta,phi; // euler angles in ZX'Z'' convention
    24 
    25         //cout << Verbose(3) << "Begin of SquaredDistanceToEllipsoid" << endl;
    26 
    27         for(int i=0;i<3;i++)
    28                 InverseLength[i] = 1./EllipsoidLength[i];
    29 
    30         // 1. translate coordinate system so that ellipsoid center is in origin
    31         helper.CopyVector(&x);
    32         helper.SubtractVector(&EllipsoidCenter);
    33         RefPoint.CopyVector(&helper);
    34         //cout << Verbose(4) << "Translated given point is at " << RefPoint << "." << endl;
    35 
    36         // 2. transform coordinate system by inverse of rotation matrix and of diagonal matrix
    37         psi = EllipsoidAngle[0];
    38         theta = EllipsoidAngle[1];
    39         phi = EllipsoidAngle[2];
    40         Matrix[0] = cos(psi)*cos(phi) - sin(psi)*cos(theta)*sin(phi);
    41         Matrix[1] = -cos(psi)*sin(phi) - sin(psi)*cos(theta)*cos(phi);
    42         Matrix[2] = sin(psi)*sin(theta);
    43         Matrix[3] = sin(psi)*cos(phi) + cos(psi)*cos(theta)*sin(phi);
    44         Matrix[4] = cos(psi)*cos(theta)*cos(phi) - sin(psi)*sin(phi);
    45         Matrix[5] = -cos(psi)*sin(theta);
    46         Matrix[6] = sin(theta)*sin(phi);
    47         Matrix[7] = sin(theta)*cos(phi);
    48         Matrix[8] = cos(theta);
    49         helper.MatrixMultiplication(Matrix);
    50         helper.Scale(InverseLength);
    51         //cout << Verbose(4) << "Transformed RefPoint is at " << helper << "." << endl;
    52 
    53         // 3. construct intersection point with unit sphere and ray between origin and x
    54         helper.Normalize(); // is simply normalizes vector in distance direction
    55         //cout << Verbose(4) << "Transformed intersection is at " << helper << "." << endl;
    56 
    57         // 4. transform back the constructed intersection point
    58         psi = -EllipsoidAngle[0];
    59         theta = -EllipsoidAngle[1];
    60         phi = -EllipsoidAngle[2];
    61         helper.Scale(EllipsoidLength);
    62         Matrix[0] = cos(psi)*cos(phi) - sin(psi)*cos(theta)*sin(phi);
    63         Matrix[1] = -cos(psi)*sin(phi) - sin(psi)*cos(theta)*cos(phi);
    64         Matrix[2] = sin(psi)*sin(theta);
    65         Matrix[3] = sin(psi)*cos(phi) + cos(psi)*cos(theta)*sin(phi);
    66         Matrix[4] = cos(psi)*cos(theta)*cos(phi) - sin(psi)*sin(phi);
    67         Matrix[5] = -cos(psi)*sin(theta);
    68         Matrix[6] = sin(theta)*sin(phi);
    69         Matrix[7] = sin(theta)*cos(phi);
    70         Matrix[8] = cos(theta);
    71         helper.MatrixMultiplication(Matrix);
    72         //cout << Verbose(4) << "Intersection is at " << helper << "." << endl;
    73 
    74         // 5. determine distance between backtransformed point and x
    75         distance = RefPoint.DistanceSquared(&helper);
    76         //cout << Verbose(4) << "Squared distance between intersection and RefPoint is " << distance << "." << endl;
    77 
    78         return distance;
    79         //cout << Verbose(3) << "End of SquaredDistanceToEllipsoid" << endl;
     19  Vector helper, RefPoint;
     20  double distance = -1.;
     21  double Matrix[NDIM*NDIM];
     22  double InverseLength[3];
     23  double psi,theta,phi; // euler angles in ZX'Z'' convention
     24
     25  //cout << Verbose(3) << "Begin of SquaredDistanceToEllipsoid" << endl;
     26
     27  for(int i=0;i<3;i++)
     28    InverseLength[i] = 1./EllipsoidLength[i];
     29
     30  // 1. translate coordinate system so that ellipsoid center is in origin
     31  helper.CopyVector(&x);
     32  helper.SubtractVector(&EllipsoidCenter);
     33  RefPoint.CopyVector(&helper);
     34  //cout << Verbose(4) << "Translated given point is at " << RefPoint << "." << endl;
     35
     36  // 2. transform coordinate system by inverse of rotation matrix and of diagonal matrix
     37  psi = EllipsoidAngle[0];
     38  theta = EllipsoidAngle[1];
     39  phi = EllipsoidAngle[2];
     40  Matrix[0] = cos(psi)*cos(phi) - sin(psi)*cos(theta)*sin(phi);
     41  Matrix[1] = -cos(psi)*sin(phi) - sin(psi)*cos(theta)*cos(phi);
     42  Matrix[2] = sin(psi)*sin(theta);
     43  Matrix[3] = sin(psi)*cos(phi) + cos(psi)*cos(theta)*sin(phi);
     44  Matrix[4] = cos(psi)*cos(theta)*cos(phi) - sin(psi)*sin(phi);
     45  Matrix[5] = -cos(psi)*sin(theta);
     46  Matrix[6] = sin(theta)*sin(phi);
     47  Matrix[7] = sin(theta)*cos(phi);
     48  Matrix[8] = cos(theta);
     49  helper.MatrixMultiplication(Matrix);
     50  helper.Scale(InverseLength);
     51  //cout << Verbose(4) << "Transformed RefPoint is at " << helper << "." << endl;
     52
     53  // 3. construct intersection point with unit sphere and ray between origin and x
     54  helper.Normalize(); // is simply normalizes vector in distance direction
     55  //cout << Verbose(4) << "Transformed intersection is at " << helper << "." << endl;
     56
     57  // 4. transform back the constructed intersection point
     58  psi = -EllipsoidAngle[0];
     59  theta = -EllipsoidAngle[1];
     60  phi = -EllipsoidAngle[2];
     61  helper.Scale(EllipsoidLength);
     62  Matrix[0] = cos(psi)*cos(phi) - sin(psi)*cos(theta)*sin(phi);
     63  Matrix[1] = -cos(psi)*sin(phi) - sin(psi)*cos(theta)*cos(phi);
     64  Matrix[2] = sin(psi)*sin(theta);
     65  Matrix[3] = sin(psi)*cos(phi) + cos(psi)*cos(theta)*sin(phi);
     66  Matrix[4] = cos(psi)*cos(theta)*cos(phi) - sin(psi)*sin(phi);
     67  Matrix[5] = -cos(psi)*sin(theta);
     68  Matrix[6] = sin(theta)*sin(phi);
     69  Matrix[7] = sin(theta)*cos(phi);
     70  Matrix[8] = cos(theta);
     71  helper.MatrixMultiplication(Matrix);
     72  //cout << Verbose(4) << "Intersection is at " << helper << "." << endl;
     73
     74  // 5. determine distance between backtransformed point and x
     75  distance = RefPoint.DistanceSquared(&helper);
     76  //cout << Verbose(4) << "Squared distance between intersection and RefPoint is " << distance << "." << endl;
     77
     78  return distance;
     79  //cout << Verbose(3) << "End of SquaredDistanceToEllipsoid" << endl;
    8080};
    8181
     
    8383 */
    8484struct EllipsoidMinimisation {
    85         int N;                  //!< dimension of vector set
    86         Vector *x;      //!< array of vectors
     85  int N;      //!< dimension of vector set
     86  Vector *x;  //!< array of vectors
    8787};
    8888
     
    9494double SumSquaredDistance (const gsl_vector * x, void * params)
    9595{
    96         Vector *set= ((struct EllipsoidMinimisation *)params)->x;
    97         int N = ((struct EllipsoidMinimisation *)params)->N;
    98         double SumDistance = 0.;
    99         double distance;
    100         Vector Center;
    101         double EllipsoidLength[3], EllipsoidAngle[3];
    102 
    103         // put parameters into suitable ellipsoid form
    104         for (int i=0;i<3;i++) {
    105                 Center.x[i] = gsl_vector_get(x, i+0);
    106                 EllipsoidLength[i] = gsl_vector_get(x, i+3);
    107                 EllipsoidAngle[i] = gsl_vector_get(x, i+6);
    108         }
    109 
    110         // go through all points and sum distance
    111         for (int i=0;i<N;i++) {
    112                 distance = SquaredDistanceToEllipsoid(set[i], Center, EllipsoidLength, EllipsoidAngle);
    113                 if (!isnan(distance)) {
    114                         SumDistance += distance;
    115                 } else {
    116                         SumDistance = GSL_NAN;
    117                         break;
    118                 }
    119         }
    120 
    121         //cout << "Current summed distance is " << SumDistance << "." << endl;
    122         return SumDistance;
     96  Vector *set= ((struct EllipsoidMinimisation *)params)->x;
     97  int N = ((struct EllipsoidMinimisation *)params)->N;
     98  double SumDistance = 0.;
     99  double distance;
     100  Vector Center;
     101  double EllipsoidLength[3], EllipsoidAngle[3];
     102
     103  // put parameters into suitable ellipsoid form
     104  for (int i=0;i<3;i++) {
     105    Center.x[i] = gsl_vector_get(x, i+0);
     106    EllipsoidLength[i] = gsl_vector_get(x, i+3);
     107    EllipsoidAngle[i] = gsl_vector_get(x, i+6);
     108  }
     109
     110  // go through all points and sum distance
     111  for (int i=0;i<N;i++) {
     112    distance = SquaredDistanceToEllipsoid(set[i], Center, EllipsoidLength, EllipsoidAngle);
     113    if (!isnan(distance)) {
     114      SumDistance += distance;
     115    } else {
     116      SumDistance = GSL_NAN;
     117      break;
     118    }
     119  }
     120
     121  //cout << "Current summed distance is " << SumDistance << "." << endl;
     122  return SumDistance;
    123123};
    124124
     
    132132bool FitPointSetToEllipsoid(ofstream *out, Vector *set, int N, Vector *EllipsoidCenter, double *EllipsoidLength, double *EllipsoidAngle)
    133133{
    134         int status = GSL_SUCCESS;
    135         *out << Verbose(2) << "Begin of FitPointSetToEllipsoid " << endl;
    136         if (N >= 3) { // check that enough points are given (9 d.o.f.)
    137                 struct EllipsoidMinimisation par;
    138                 const gsl_multimin_fminimizer_type *T = gsl_multimin_fminimizer_nmsimplex;
    139                 gsl_multimin_fminimizer *s = NULL;
    140                 gsl_vector *ss, *x;
    141                 gsl_multimin_function minex_func;
    142 
    143                 size_t iter = 0;
    144                 double size;
    145 
    146                 /* Starting point */
    147                 x = gsl_vector_alloc (9);
    148                 for (int i=0;i<3;i++) {
    149                         gsl_vector_set (x, i+0, EllipsoidCenter->x[i]);
    150                         gsl_vector_set (x, i+3, EllipsoidLength[i]);
    151                         gsl_vector_set (x, i+6, EllipsoidAngle[i]);
    152                 }
    153                 par.x = set;
    154                 par.N = N;
    155 
    156                 /* Set initial step sizes */
    157                 ss = gsl_vector_alloc (9);
    158                 for (int i=0;i<3;i++) {
    159                         gsl_vector_set (ss, i+0, 0.1);
    160                         gsl_vector_set (ss, i+3, 1.0);
    161                         gsl_vector_set (ss, i+6, M_PI/20.);
    162                 }
    163 
    164                 /* Initialize method and iterate */
    165                 minex_func.n = 9;
    166                 minex_func.f = &SumSquaredDistance;
    167                 minex_func.params = (void *)&par;
    168 
    169                 s = gsl_multimin_fminimizer_alloc (T, 9);
    170                 gsl_multimin_fminimizer_set (s, &minex_func, x, ss);
    171 
    172                 do {
    173                         iter++;
    174                         status = gsl_multimin_fminimizer_iterate(s);
    175 
    176                         if (status)
    177                                 break;
    178 
    179                         size = gsl_multimin_fminimizer_size (s);
    180                         status = gsl_multimin_test_size (size, 1e-2);
    181 
    182                         if (status == GSL_SUCCESS) {
    183                                 for (int i=0;i<3;i++) {
    184                                         EllipsoidCenter->x[i] = gsl_vector_get (s->x,i+0);
    185                                         EllipsoidLength[i] = gsl_vector_get (s->x, i+3);
    186                                         EllipsoidAngle[i] = gsl_vector_get (s->x, i+6);
    187                                 }
    188                                 *out << setprecision(3) << Verbose(4) << "Converged fit at: " << *EllipsoidCenter << ", lengths " << EllipsoidLength[0] << ", " << EllipsoidLength[1] << ", " << EllipsoidLength[2] << ", angles " << EllipsoidAngle[0] << ", " << EllipsoidAngle[1] << ", " << EllipsoidAngle[2] << " with summed distance " << s->fval << "." << endl;
    189                         }
    190 
    191                 } while (status == GSL_CONTINUE && iter < 1000);
    192 
    193                 gsl_vector_free(x);
    194                 gsl_vector_free(ss);
    195                 gsl_multimin_fminimizer_free (s);
    196 
    197         } else {
    198                 *out << Verbose(3) << "Not enough points provided for fit to ellipsoid." << endl;
    199                 return false;
    200         }
    201         *out << Verbose(2) << "End of FitPointSetToEllipsoid" << endl;
    202         if (status == GSL_SUCCESS)
    203                 return true;
    204         else
    205                 return false;
     134  int status = GSL_SUCCESS;
     135  *out << Verbose(2) << "Begin of FitPointSetToEllipsoid " << endl;
     136  if (N >= 3) { // check that enough points are given (9 d.o.f.)
     137    struct EllipsoidMinimisation par;
     138    const gsl_multimin_fminimizer_type *T = gsl_multimin_fminimizer_nmsimplex;
     139    gsl_multimin_fminimizer *s = NULL;
     140    gsl_vector *ss, *x;
     141    gsl_multimin_function minex_func;
     142
     143    size_t iter = 0;
     144    double size;
     145
     146    /* Starting point */
     147    x = gsl_vector_alloc (9);
     148    for (int i=0;i<3;i++) {
     149      gsl_vector_set (x, i+0, EllipsoidCenter->x[i]);
     150      gsl_vector_set (x, i+3, EllipsoidLength[i]);
     151      gsl_vector_set (x, i+6, EllipsoidAngle[i]);
     152    }
     153    par.x = set;
     154    par.N = N;
     155
     156    /* Set initial step sizes */
     157    ss = gsl_vector_alloc (9);
     158    for (int i=0;i<3;i++) {
     159      gsl_vector_set (ss, i+0, 0.1);
     160      gsl_vector_set (ss, i+3, 1.0);
     161      gsl_vector_set (ss, i+6, M_PI/20.);
     162    }
     163
     164    /* Initialize method and iterate */
     165    minex_func.n = 9;
     166    minex_func.f = &SumSquaredDistance;
     167    minex_func.params = (void *)&par;
     168
     169    s = gsl_multimin_fminimizer_alloc (T, 9);
     170    gsl_multimin_fminimizer_set (s, &minex_func, x, ss);
     171
     172    do {
     173      iter++;
     174      status = gsl_multimin_fminimizer_iterate(s);
     175
     176      if (status)
     177        break;
     178
     179      size = gsl_multimin_fminimizer_size (s);
     180      status = gsl_multimin_test_size (size, 1e-2);
     181
     182      if (status == GSL_SUCCESS) {
     183        for (int i=0;i<3;i++) {
     184          EllipsoidCenter->x[i] = gsl_vector_get (s->x,i+0);
     185          EllipsoidLength[i] = gsl_vector_get (s->x, i+3);
     186          EllipsoidAngle[i] = gsl_vector_get (s->x, i+6);
     187        }
     188        *out << setprecision(3) << Verbose(4) << "Converged fit at: " << *EllipsoidCenter << ", lengths " << EllipsoidLength[0] << ", " << EllipsoidLength[1] << ", " << EllipsoidLength[2] << ", angles " << EllipsoidAngle[0] << ", " << EllipsoidAngle[1] << ", " << EllipsoidAngle[2] << " with summed distance " << s->fval << "." << endl;
     189      }
     190
     191    } while (status == GSL_CONTINUE && iter < 1000);
     192
     193    gsl_vector_free(x);
     194    gsl_vector_free(ss);
     195    gsl_multimin_fminimizer_free (s);
     196
     197  } else {
     198    *out << Verbose(3) << "Not enough points provided for fit to ellipsoid." << endl;
     199    return false;
     200  }
     201  *out << Verbose(2) << "End of FitPointSetToEllipsoid" << endl;
     202  if (status == GSL_SUCCESS)
     203    return true;
     204  else
     205    return false;
    206206};
    207207
     
    217217  size_t PointsLeft = 0;
    218218  size_t PointsPicked = 0;
    219         int Nlower[NDIM], Nupper[NDIM];
    220         set<int> PickedAtomNrs; // ordered list of picked atoms
    221         set<int>::iterator current;
    222         int index;
    223         atom *Candidate = NULL;
    224         LinkedAtoms *List = NULL;
    225         *out << Verbose(2) << "Begin of PickRandomPointSet" << endl;
    226 
    227         // allocate array
    228         if (x == NULL) {
    229                 x = new Vector[PointsToPick];
    230         } else {
    231                 *out << "WARNING: Given pointer to vector array seems already allocated." << endl;
    232         }
    233 
    234         do {
    235                 for(int i=0;i<NDIM;i++) // pick three random indices
    236                         LC->n[i] = (rand() % LC->N[i]);
    237                 *out << Verbose(2) << "INFO: Center cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " ... ";
    238                 // get random cell
    239                 List = LC->GetCurrentCell();
    240                 if (List == NULL) {     // set index to it
    241                         continue;
    242                 }
    243                 *out << "with No. " << LC->index << "." << endl;
    244 
    245                 *out << Verbose(2) << "LC Intervals:";
    246                 for (int i=0;i<NDIM;i++) {
    247                         Nlower[i] = ((LC->n[i]-1) >= 0) ? LC->n[i]-1 : 0;
    248                         Nupper[i] = ((LC->n[i]+1) < LC->N[i]) ? LC->n[i]+1 : LC->N[i]-1;
    249                         *out << " [" << Nlower[i] << "," << Nupper[i] << "] ";
    250                 }
    251                 *out << endl;
    252 
    253                 // count whether there are sufficient atoms in this cell+neighbors
    254                 PointsLeft=0;
    255                 for (LC->n[0] = Nlower[0]; LC->n[0] <= Nupper[0]; LC->n[0]++)
    256                         for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++)
    257                                 for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) {
    258                                         List = LC->GetCurrentCell();
    259                                         PointsLeft += List->size();
    260                                 }
    261                 *out << Verbose(2) << "There are " << PointsLeft << " atoms in this neighbourhood." << endl;
    262                 if (PointsLeft < PointsToPick) {        // ensure that we can pick enough points in its neighbourhood at all.
    263                         continue;
    264                 }
    265 
    266                 // pre-pick a fixed number of atoms
    267                 PickedAtomNrs.clear();
    268                 do {
    269                         index = (rand() % PointsLeft);
    270                         current = PickedAtomNrs.find(index);    // not present?
    271                         if (current == PickedAtomNrs.end()) {
    272                                 //*out << Verbose(2) << "Picking atom nr. " << index << "." << endl;
    273                                 PickedAtomNrs.insert(index);
    274                         }
    275                 } while (PickedAtomNrs.size() < PointsToPick);
    276 
    277                 index = 0; // now go through all and pick those whose from PickedAtomsNr
    278                 PointsPicked=0;
    279                 current = PickedAtomNrs.begin();
    280                 for (LC->n[0] = Nlower[0]; LC->n[0] <= Nupper[0]; LC->n[0]++)
    281                         for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++)
    282                                 for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) {
    283                                         List = LC->GetCurrentCell();
    284 //                                      *out << Verbose(2) << "Current cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << " containing " << List->size() << " points." << endl;
    285                                         if (List != NULL) {
    286 //                                              if (List->begin() != List->end())
    287 //                                                      *out << Verbose(2) << "Going through candidates ... " << endl;
    288 //                                              else
    289 //                                                      *out << Verbose(2) << "Cell is empty ... " << endl;
    290                                                 for (LinkedAtoms::iterator Runner = List->begin(); Runner != List->end(); Runner++) {
    291                                                         if ((current != PickedAtomNrs.end()) && (*current == index)) {
    292                                                                 Candidate = (*Runner);
    293                                                                 *out << Verbose(2) << "Current picked node is " << **Runner << " with index " << index << "." << endl;
    294                                                                 x[PointsPicked++].CopyVector(&(Candidate->x));          // we have one more atom picked
    295                                                                 current++;              // next pre-picked atom
    296                                                         }
    297                                                         index++;        // next atom nr.
    298                                                 }
    299 //                                      } else {
    300 //                                              *out << Verbose(2) << "List for this index not allocated!" << endl;
    301                                         }
    302                                 }
    303                 *out << Verbose(2) << "The following points were picked: " << endl;
    304                 for (size_t i=0;i<PointsPicked;i++)
    305                         *out << Verbose(2) << x[i] << endl;
    306                 if (PointsPicked == PointsToPick)       // break out of loop if we have all
    307                         break;
    308         } while(1);
    309 
    310         *out << Verbose(2) << "End of PickRandomPointSet" << endl;
     219  int Nlower[NDIM], Nupper[NDIM];
     220  set<int> PickedAtomNrs;  // ordered list of picked atoms
     221  set<int>::iterator current;
     222  int index;
     223  atom *Candidate = NULL;
     224  LinkedAtoms *List = NULL;
     225  *out << Verbose(2) << "Begin of PickRandomPointSet" << endl;
     226
     227  // allocate array
     228  if (x == NULL) {
     229    x = new Vector[PointsToPick];
     230  } else {
     231    *out << "WARNING: Given pointer to vector array seems already allocated." << endl;
     232  }
     233
     234  do {
     235    for(int i=0;i<NDIM;i++) // pick three random indices
     236      LC->n[i] = (rand() % LC->N[i]);
     237    *out << Verbose(2) << "INFO: Center cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " ... ";
     238    // get random cell
     239    List = LC->GetCurrentCell();
     240    if (List == NULL) {  // set index to it
     241      continue;
     242    }
     243    *out << "with No. " << LC->index << "." << endl;
     244
     245    *out << Verbose(2) << "LC Intervals:";
     246    for (int i=0;i<NDIM;i++) {
     247      Nlower[i] = ((LC->n[i]-1) >= 0) ? LC->n[i]-1 : 0;
     248      Nupper[i] = ((LC->n[i]+1) < LC->N[i]) ? LC->n[i]+1 : LC->N[i]-1;
     249      *out << " [" << Nlower[i] << "," << Nupper[i] << "] ";
     250    }
     251    *out << endl;
     252
     253    // count whether there are sufficient atoms in this cell+neighbors
     254    PointsLeft=0;
     255    for (LC->n[0] = Nlower[0]; LC->n[0] <= Nupper[0]; LC->n[0]++)
     256      for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++)
     257        for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) {
     258          List = LC->GetCurrentCell();
     259          PointsLeft += List->size();
     260        }
     261    *out << Verbose(2) << "There are " << PointsLeft << " atoms in this neighbourhood." << endl;
     262    if (PointsLeft < PointsToPick) {  // ensure that we can pick enough points in its neighbourhood at all.
     263      continue;
     264    }
     265
     266    // pre-pick a fixed number of atoms
     267    PickedAtomNrs.clear();
     268    do {
     269      index = (rand() % PointsLeft);
     270      current = PickedAtomNrs.find(index);  // not present?
     271      if (current == PickedAtomNrs.end()) {
     272        //*out << Verbose(2) << "Picking atom nr. " << index << "." << endl;
     273        PickedAtomNrs.insert(index);
     274      }
     275    } while (PickedAtomNrs.size() < PointsToPick);
     276
     277    index = 0; // now go through all and pick those whose from PickedAtomsNr
     278    PointsPicked=0;
     279    current = PickedAtomNrs.begin();
     280    for (LC->n[0] = Nlower[0]; LC->n[0] <= Nupper[0]; LC->n[0]++)
     281      for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++)
     282        for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) {
     283          List = LC->GetCurrentCell();
     284//          *out << Verbose(2) << "Current cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << " containing " << List->size() << " points." << endl;
     285          if (List != NULL) {
     286//            if (List->begin() != List->end())
     287//              *out << Verbose(2) << "Going through candidates ... " << endl;
     288//            else
     289//              *out << Verbose(2) << "Cell is empty ... " << endl;
     290            for (LinkedAtoms::iterator Runner = List->begin(); Runner != List->end(); Runner++) {
     291              if ((current != PickedAtomNrs.end()) && (*current == index)) {
     292                Candidate = (*Runner);
     293                *out << Verbose(2) << "Current picked node is " << **Runner << " with index " << index << "." << endl;
     294                x[PointsPicked++].CopyVector(&(Candidate->x));    // we have one more atom picked
     295                current++;    // next pre-picked atom
     296              }
     297              index++;  // next atom nr.
     298            }
     299//          } else {
     300//            *out << Verbose(2) << "List for this index not allocated!" << endl;
     301          }
     302        }
     303    *out << Verbose(2) << "The following points were picked: " << endl;
     304    for (size_t i=0;i<PointsPicked;i++)
     305      *out << Verbose(2) << x[i] << endl;
     306    if (PointsPicked == PointsToPick)  // break out of loop if we have all
     307      break;
     308  } while(1);
     309
     310  *out << Verbose(2) << "End of PickRandomPointSet" << endl;
    311311};
    312312
     
    321321  size_t PointsLeft = (size_t) T->PointsOnBoundaryCount;
    322322  size_t PointsPicked = 0;
    323         double value, threshold;
    324         PointMap *List = &T->PointsOnBoundary;
    325         *out << Verbose(2) << "Begin of PickRandomPointSet" << endl;
    326 
    327         // allocate array
    328         if (x == NULL) {
    329                 x = new Vector[PointsToPick];
    330         } else {
    331                 *out << "WARNING: Given pointer to vector array seems already allocated." << endl;
    332         }
    333 
    334         if (List != NULL)
    335                 for (PointMap::iterator Runner = List->begin(); Runner != List->end(); Runner++) {
    336                         threshold = 1. - (double)(PointsToPick - PointsPicked)/(double)PointsLeft;
    337                         value = (double)rand()/(double)RAND_MAX;
    338                         //*out << Verbose(3) << "Current node is " << *Runner->second->node << " with " << value << " ... " << threshold << ": ";
    339                         if (value > threshold) {
    340                                 x[PointsPicked].CopyVector(&(Runner->second->node->x));
    341                                 PointsPicked++;
    342                                 //*out << "IN." << endl;
    343                         } else {
    344                                 //*out << "OUT." << endl;
    345                         }
    346                         PointsLeft--;
    347                 }
    348         *out << Verbose(2) << "The following points were picked: " << endl;
    349         for (size_t i=0;i<PointsPicked;i++)
    350                 *out << Verbose(3) << x[i] << endl;
    351 
    352         *out << Verbose(2) << "End of PickRandomPointSet" << endl;
     323  double value, threshold;
     324  PointMap *List = &T->PointsOnBoundary;
     325  *out << Verbose(2) << "Begin of PickRandomPointSet" << endl;
     326
     327  // allocate array
     328  if (x == NULL) {
     329    x = new Vector[PointsToPick];
     330  } else {
     331    *out << "WARNING: Given pointer to vector array seems already allocated." << endl;
     332  }
     333
     334  if (List != NULL)
     335    for (PointMap::iterator Runner = List->begin(); Runner != List->end(); Runner++) {
     336      threshold = 1. - (double)(PointsToPick - PointsPicked)/(double)PointsLeft;
     337      value = (double)rand()/(double)RAND_MAX;
     338      //*out << Verbose(3) << "Current node is " << *Runner->second->node << " with " << value << " ... " << threshold << ": ";
     339      if (value > threshold) {
     340        x[PointsPicked].CopyVector(&(Runner->second->node->x));
     341        PointsPicked++;
     342        //*out << "IN." << endl;
     343      } else {
     344        //*out << "OUT." << endl;
     345      }
     346      PointsLeft--;
     347    }
     348  *out << Verbose(2) << "The following points were picked: " << endl;
     349  for (size_t i=0;i<PointsPicked;i++)
     350    *out << Verbose(3) << x[i] << endl;
     351
     352  *out << Verbose(2) << "End of PickRandomPointSet" << endl;
    353353};
    354354
     
    363363void FindDistributionOfEllipsoids(ofstream *out, class Tesselation *T, class LinkedCell *LCList, int N, int number, const char *filename)
    364364{
    365         ofstream output;
    366         Vector *x = NULL;
    367         Vector Center;
    368         Vector EllipsoidCenter;
    369         double EllipsoidLength[3];
    370         double EllipsoidAngle[3];
    371         double distance, MaxDistance, MinDistance;
    372         *out << Verbose(0) << "Begin of FindDistributionOfEllipsoids" << endl;
    373 
    374         // construct center of gravity of boundary point set for initial ellipsoid center
    375         Center.Zero();
    376         for (PointMap::iterator Runner = T->PointsOnBoundary.begin(); Runner != T->PointsOnBoundary.end(); Runner++)
    377                 Center.AddVector(&Runner->second->node->x);
    378         Center.Scale(1./T->PointsOnBoundaryCount);
    379         *out << Verbose(1) << "Center is at " << Center << "." << endl;
    380 
    381         // Output header
    382         output.open(filename, ios::trunc);
    383         output << "# Nr.\tCenterX\tCenterY\tCenterZ\ta\tb\tc\tpsi\ttheta\tphi" << endl;
    384 
    385         // loop over desired number of parameter sets
    386         for (;number >0;number--) {
    387                 *out << Verbose(1) << "Determining data set " << number << " ... " << endl;
    388                 // pick the point set
    389                 x = NULL;
    390                 //PickRandomPointSet(out, T, LCList, x, N);
    391                 PickRandomNeighbouredPointSet(out, T, LCList, x, N);
    392 
    393                 // calculate some sensible starting values for parameter fit
    394                 MaxDistance = 0.;
    395                 MinDistance = x[0].ScalarProduct(&x[0]);
    396                 for (int i=0;i<N;i++) {
    397                         distance = x[i].ScalarProduct(&x[i]);
    398                         if (distance > MaxDistance)
    399                                 MaxDistance = distance;
    400                         if (distance < MinDistance)
    401                                 MinDistance = distance;
    402                 }
    403                 //*out << Verbose(2) << "MinDistance " << MinDistance << ", MaxDistance " << MaxDistance << "." << endl;
    404                 EllipsoidCenter.CopyVector(&Center);    // use Center of Gravity as initial center of ellipsoid
    405                 for (int i=0;i<3;i++)
    406                         EllipsoidAngle[i] = 0.;
    407                 EllipsoidLength[0] = sqrt(MaxDistance);
    408                 EllipsoidLength[1] = sqrt((MaxDistance+MinDistance)/2.);
    409                 EllipsoidLength[2] = sqrt(MinDistance);
    410 
    411                 // fit the parameters
    412                 if (FitPointSetToEllipsoid(out, x, N, &EllipsoidCenter, &EllipsoidLength[0], &EllipsoidAngle[0])) {
    413                         *out << Verbose(1) << "Picking succeeded!" << endl;
    414                         // output obtained parameter set
    415                         output << number << "\t";
    416                         for (int i=0;i<3;i++)
    417                                 output << setprecision(9) << EllipsoidCenter.x[i] << "\t";
    418                         for (int i=0;i<3;i++)
    419                                 output << setprecision(9) << EllipsoidLength[i] << "\t";
    420                         for (int i=0;i<3;i++)
    421                                 output << setprecision(9) << EllipsoidAngle[i] << "\t";
    422                         output << endl;
    423                 } else { // increase N to pick one more
    424                         *out << Verbose(1) << "Picking failed!" << endl;
    425                         number++;
    426                 }
    427                 delete[](x);    // free allocated memory for point set
    428         }
    429         // close output and finish
    430         output.close();
    431 
    432         *out << Verbose(0) << "End of FindDistributionOfEllipsoids" << endl;
    433 };
     365  ofstream output;
     366  Vector *x = NULL;
     367  Vector Center;
     368  Vector EllipsoidCenter;
     369  double EllipsoidLength[3];
     370  double EllipsoidAngle[3];
     371  double distance, MaxDistance, MinDistance;
     372  *out << Verbose(0) << "Begin of FindDistributionOfEllipsoids" << endl;
     373
     374  // construct center of gravity of boundary point set for initial ellipsoid center
     375  Center.Zero();
     376  for (PointMap::iterator Runner = T->PointsOnBoundary.begin(); Runner != T->PointsOnBoundary.end(); Runner++)
     377    Center.AddVector(&Runner->second->node->x);
     378  Center.Scale(1./T->PointsOnBoundaryCount);
     379  *out << Verbose(1) << "Center is at " << Center << "." << endl;
     380
     381  // Output header
     382  output.open(filename, ios::trunc);
     383  output << "# Nr.\tCenterX\tCenterY\tCenterZ\ta\tb\tc\tpsi\ttheta\tphi" << endl;
     384
     385  // loop over desired number of parameter sets
     386  for (;number >0;number--) {
     387    *out << Verbose(1) << "Determining data set " << number << " ... " << endl;
     388    // pick the point set
     389    x = NULL;
     390    //PickRandomPointSet(out, T, LCList, x, N);
     391    PickRandomNeighbouredPointSet(out, T, LCList, x, N);
     392
     393    // calculate some sensible starting values for parameter fit
     394    MaxDistance = 0.;
     395    MinDistance = x[0].ScalarProduct(&x[0]);
     396    for (int i=0;i<N;i++) {
     397      distance = x[i].ScalarProduct(&x[i]);
     398      if (distance > MaxDistance)
     399        MaxDistance = distance;
     400      if (distance < MinDistance)
     401        MinDistance = distance;
     402    }
     403    //*out << Verbose(2) << "MinDistance " << MinDistance << ", MaxDistance " << MaxDistance << "." << endl;
     404    EllipsoidCenter.CopyVector(&Center);  // use Center of Gravity as initial center of ellipsoid
     405    for (int i=0;i<3;i++)
     406      EllipsoidAngle[i] = 0.;
     407    EllipsoidLength[0] = sqrt(MaxDistance);
     408    EllipsoidLength[1] = sqrt((MaxDistance+MinDistance)/2.);
     409    EllipsoidLength[2] = sqrt(MinDistance);
     410
     411    // fit the parameters
     412    if (FitPointSetToEllipsoid(out, x, N, &EllipsoidCenter, &EllipsoidLength[0], &EllipsoidAngle[0])) {
     413      *out << Verbose(1) << "Picking succeeded!" << endl;
     414      // output obtained parameter set
     415      output << number << "\t";
     416      for (int i=0;i<3;i++)
     417        output << setprecision(9) << EllipsoidCenter.x[i] << "\t";
     418      for (int i=0;i<3;i++)
     419        output << setprecision(9) << EllipsoidLength[i] << "\t";
     420      for (int i=0;i<3;i++)
     421        output << setprecision(9) << EllipsoidAngle[i] << "\t";
     422      output << endl;
     423    } else { // increase N to pick one more
     424      *out << Verbose(1) << "Picking failed!" << endl;
     425      number++;
     426    }
     427    delete[](x);  // free allocated memory for point set
     428  }
     429  // close output and finish
     430  output.close();
     431
     432  *out << Verbose(0) << "End of FindDistributionOfEllipsoids" << endl;
     433};
  • src/ellipsoid.hpp

    r205ccd r042f82  
    22 * ellipsoid.hpp
    33 *
    4  *      Created on: Jan 20, 2009
    5  *                      Author: heber
     4 *  Created on: Jan 20, 2009
     5 *      Author: heber
    66 */
    77
  • src/helpers.cpp

    r205ccd r042f82  
    1515double ask_value(const char *text)
    1616{
    17         double test = 0.1439851348959832147598734598273456723948652983045928346598365;
    18         do {
    19                 cout << Verbose(0) << text;
    20                 cin >> test;
    21         } while (test == 0.1439851348959832147598734598273456723948652983045928346598365);
    22         return test;
     17  double test = 0.1439851348959832147598734598273456723948652983045928346598365;
     18  do {
     19    cout << Verbose(0) << text;
     20    cin >> test;
     21  } while (test == 0.1439851348959832147598734598273456723948652983045928346598365);
     22  return test;
    2323};
    2424
     
    2929#ifdef HAVE_DEBUG
    3030void debug_in(const char *output, const char *file, const int line) {
    31         if (output) fprintf(stderr,"DEBUG: in %s at line %i: %s\n", file, line, output);
     31  if (output) fprintf(stderr,"DEBUG: in %s at line %i: %s\n", file, line, output);
    3232}
    3333#else
    34 void debug_in(const char *output, const char *file, const int line) {}  // print nothing
     34void debug_in(const char *output, const char *file, const int line) {}  // print nothing
    3535#endif
    3636
     
    4242void * Malloc(size_t size, const char* output)
    4343{
    44         void *buffer = NULL;
    45         buffer = (void *)malloc(size); // alloc
    46         if (buffer == NULL)
    47                 cout << Verbose(0) << "Malloc failed - pointer is NULL: " << output << endl;
    48         return(buffer);
     44  void *buffer = NULL;
     45  buffer = (void *)malloc(size); // alloc
     46  if (buffer == NULL)
     47    cout << Verbose(0) << "Malloc failed - pointer is NULL: " << output << endl;
     48  return(buffer);
    4949};
    5050
     
    5656void * Calloc(size_t size, const char* output)
    5757{
    58         void *buffer = NULL;
    59         buffer = (void *)calloc(size, (size_t)0); // alloc
    60         if (buffer == NULL)
    61                 cout << Verbose(0) << "Calloc failed - pointer is NULL: " << output << endl;
    62         return(buffer);
     58  void *buffer = NULL;
     59  buffer = (void *)calloc(size, (size_t)0); // alloc
     60  if (buffer == NULL)
     61    cout << Verbose(0) << "Calloc failed - pointer is NULL: " << output << endl;
     62  return(buffer);
    6363};
    6464
     
    7171void * ReAlloc(void * OldPointer, size_t size, const char* output)
    7272{
    73         void *buffer = NULL;
    74         if (OldPointer == NULL)
    75                 //cout << Verbose(0) << "ReAlloc impossible - old is NULL: " << output << endl;
    76                 buffer = (void *)malloc(size); // malloc
    77         else
    78                 buffer = (void *)realloc(OldPointer, size); // realloc
    79         if (buffer == NULL)
    80                 cout << Verbose(0) << "ReAlloc failed - new is NULL: " << output << endl;
    81         return(buffer);
     73  void *buffer = NULL;
     74  if (OldPointer == NULL)
     75    //cout << Verbose(0) << "ReAlloc impossible - old is NULL: " << output << endl;
     76    buffer = (void *)malloc(size); // malloc
     77  else
     78    buffer = (void *)realloc(OldPointer, size); // realloc
     79  if (buffer == NULL)
     80    cout << Verbose(0) << "ReAlloc failed - new is NULL: " << output << endl;
     81  return(buffer);
    8282};
    8383
     
    8888void Free(void ** buffer, const char* output)
    8989{
    90         if (*buffer == NULL) {
    91                 //cout << Verbose(5) << "Free not necesary: " << output << endl;
    92         } else {
    93                 free(*buffer);
    94                 *buffer = NULL;
    95         }
     90  if (*buffer == NULL) {
     91    //cout << Verbose(5) << "Free not necesary: " << output << endl;
     92  } else {
     93    free(*buffer);
     94    *buffer = NULL;
     95  }
    9696};
    9797
     
    103103char* MallocString(size_t size, const char* output)
    104104{
    105         size_t i;
    106         char *buffer;
    107         buffer = (char *)malloc(sizeof(char) * (size+1)); // alloc
    108         if (buffer == NULL)
    109                 cout << Verbose(0) << output << endl;
    110         for (i=size;i--;)       // reset
    111                 buffer[i] = i % 2 == 0 ? 'p': 'c';
    112         buffer[size] = '\0'; // and set length marker on its end
    113         return(buffer);
     105  size_t i;
     106  char *buffer;
     107  buffer = (char *)malloc(sizeof(char) * (size+1)); // alloc
     108  if (buffer == NULL)
     109    cout << Verbose(0) << output << endl;
     110  for (i=size;i--;)  // reset
     111    buffer[i] = i % 2 == 0 ? 'p': 'c';
     112  buffer[size] = '\0'; // and set length marker on its end
     113  return(buffer);
    114114}
    115115
     
    121121void bound(double *b, double lower_bound, double upper_bound)
    122122{
    123         double step = (upper_bound - lower_bound);
    124         while (*b >= upper_bound)
    125                 *b -= step;
    126         while (*b < lower_bound)
    127                 *b += step;
     123  double step = (upper_bound - lower_bound);
     124  while (*b >= upper_bound)
     125    *b -= step;
     126  while (*b < lower_bound)
     127    *b += step;
    128128};
    129129
     
    134134void flip(double *x, double *y)
    135135{
    136         double tmp;
    137         tmp = *x;
    138         *x = *y;
    139         *y = tmp;
     136  double tmp;
     137  tmp = *x;
     138  *x = *y;
     139  *y = tmp;
    140140};
    141141
     
    147147int pot(int base, int n)
    148148{
    149         int res = 1;
    150         int j;
    151         for (j=n;j--;)
    152                 res *= base;
    153         return res;
     149  int res = 1;
     150  int j;
     151  for (j=n;j--;)
     152    res *= base;
     153  return res;
    154154};
    155155
     
    161161char *FixedDigitNumber(const int FragmentNumber, const int digits)
    162162{
    163         char *returnstring;
    164         int number = FragmentNumber;
    165         int order = 0;
    166         while (number != 0) { // determine number of digits needed
    167                 number = (int)floor(((double)number / 10.));
    168                 order++;
    169                 //cout << "Number is " << number << ", order is " << order << "." << endl;
    170         }
    171         // allocate string
    172         returnstring = (char *) Malloc(sizeof(char)*(order+2), "FixedDigitNumber: *returnstring");
    173         // terminate    and fill string array from end backward
    174         returnstring[order] = '\0';
    175         number = digits;
    176         for (int i=order;i--;) {
    177                 returnstring[i] = '0' + (char)(number % 10);
    178                 number = (int)floor(((double)number / 10.));
    179         }
    180         //cout << returnstring << endl;
    181         return returnstring;
     163  char *returnstring;
     164  int number = FragmentNumber;
     165  int order = 0;
     166  while (number != 0) { // determine number of digits needed
     167    number = (int)floor(((double)number / 10.));
     168    order++;
     169    //cout << "Number is " << number << ", order is " << order << "." << endl;
     170  }
     171  // allocate string
     172  returnstring = (char *) Malloc(sizeof(char)*(order+2), "FixedDigitNumber: *returnstring");
     173  // terminate  and fill string array from end backward
     174  returnstring[order] = '\0';
     175  number = digits;
     176  for (int i=order;i--;) {
     177    returnstring[i] = '0' + (char)(number % 10);
     178    number = (int)floor(((double)number / 10.));
     179  }
     180  //cout << returnstring << endl;
     181  return returnstring;
    182182};
    183183
     
    188188bool IsValidNumber( const char *string)
    189189{
    190         int ptr = 0;
    191         if ((string[ptr] == '.') || (string[ptr] == '-')) // number may be negative or start with dot
    192                 ptr++;
    193         if ((string[ptr] >= '0') && (string[ptr] <= '9'))
    194                 return true;
    195         return false;
     190  int ptr = 0;
     191  if ((string[ptr] == '.') || (string[ptr] == '-')) // number may be negative or start with dot
     192    ptr++;
     193  if ((string[ptr] >= '0') && (string[ptr] <= '9'))
     194    return true;
     195  return false;
    196196};
    197197
  • src/helpers.hpp

    r205ccd r042f82  
    3838
    3939/* Behandelt aufgetretene Fehler. error ist der Fehlertyp(enum Errors)
    40         void *SpecialData ist ein untypisierter Zeiger auf Spezielle Daten zur Fehlerbehandlung.
    41         Man koennte auch noch einen Zeiger auf eine Funktion uebergeben */
     40  void *SpecialData ist ein untypisierter Zeiger auf Spezielle Daten zur Fehlerbehandlung.
     41  Man koennte auch noch einen Zeiger auf eine Funktion uebergeben */
    4242extern void /*@exits@*/ debug(const char *output);
    43         //__attribute__ ((__return__));
     43  //__attribute__ ((__return__));
    4444#define debug(data) debug_in((data), __FILE__, __LINE__)
    4545
    4646extern void /*@exits@*/ debug_in(const char *output,
    47                 const char *file, const int line);
    48         //__attribute__ ((__return__));
     47    const char *file, const int line);
     48  //__attribute__ ((__return__));
    4949
    5050double ask_value(const char *text);
     
    7373template <typename T> bool CreateFatherLookupTable(ofstream *out, T *start, T *end, T **&LookupTable, int count = 0)
    7474{
    75         bool status = true;
    76         T *Walker = NULL;
    77         int AtomNo;
    78 
    79         if (LookupTable != NULL) {
    80                 *out << "Pointer for Lookup table is not NULL! Aborting ..." <<endl;
    81                 return false;
    82         }
    83 
    84         // count them
    85         if (count == 0) {
    86                 Walker = start;
    87                 while (Walker->next != end) { // create a lookup table (Atom::nr -> atom) used as a marker table lateron
    88                         Walker = Walker->next;
    89                         count = (count < Walker->GetTrueFather()->nr) ? Walker->GetTrueFather()->nr : count;
    90                 }
    91         }
    92         if (count <= 0) {
    93                 *out << "Count of lookup list is 0 or less." << endl;
    94                 return false;
    95         }
    96 
    97         // allocat and fill
    98         LookupTable = (T **) Malloc(sizeof(T *)*count, "CreateFatherLookupTable - **LookupTable");
    99         if (LookupTable == NULL) {
    100                 cerr << "LookupTable memory allocation failed!" << endl;
    101                 status = false;
    102         } else {
    103                 for (int i=0;i<count;i++)
    104                         LookupTable[i] = NULL;
    105                 Walker = start;
    106                 while (Walker->next != end) { // create a lookup table (Atom::nr -> atom) used as a marker table lateron
    107                         Walker = Walker->next;
    108                         AtomNo = Walker->GetTrueFather()->nr;
    109                         if ((AtomNo >= 0) && (AtomNo < count)) {
    110                                 //*out << "Setting LookupTable[" << AtomNo << "] to " << *Walker << endl;
    111                                 LookupTable[AtomNo] = Walker;
    112                         } else {
    113                                 *out << "Walker " << *Walker << " exceeded range of nuclear ids [0, " << count << ")." << endl;
    114                                 status = false;
    115                                 break;
    116                         }
    117                 }
    118         }
    119 
    120         return status;
     75  bool status = true;
     76  T *Walker = NULL;
     77  int AtomNo;
     78
     79  if (LookupTable != NULL) {
     80    *out << "Pointer for Lookup table is not NULL! Aborting ..." <<endl;
     81    return false;
     82  }
     83
     84  // count them
     85  if (count == 0) {
     86    Walker = start;
     87    while (Walker->next != end) { // create a lookup table (Atom::nr -> atom) used as a marker table lateron
     88      Walker = Walker->next;
     89      count = (count < Walker->GetTrueFather()->nr) ? Walker->GetTrueFather()->nr : count;
     90    }
     91  }
     92  if (count <= 0) {
     93    *out << "Count of lookup list is 0 or less." << endl;
     94    return false;
     95  }
     96
     97  // allocat and fill
     98  LookupTable = (T **) Malloc(sizeof(T *)*count, "CreateFatherLookupTable - **LookupTable");
     99  if (LookupTable == NULL) {
     100    cerr << "LookupTable memory allocation failed!" << endl;
     101    status = false;
     102  } else {
     103    for (int i=0;i<count;i++)
     104      LookupTable[i] = NULL;
     105    Walker = start;
     106    while (Walker->next != end) { // create a lookup table (Atom::nr -> atom) used as a marker table lateron
     107      Walker = Walker->next;
     108      AtomNo = Walker->GetTrueFather()->nr;
     109      if ((AtomNo >= 0) && (AtomNo < count)) {
     110        //*out << "Setting LookupTable[" << AtomNo << "] to " << *Walker << endl;
     111        LookupTable[AtomNo] = Walker;
     112      } else {
     113        *out << "Walker " << *Walker << " exceeded range of nuclear ids [0, " << count << ")." << endl;
     114        status = false;
     115        break;
     116      }
     117    }
     118  }
     119
     120  return status;
    121121};
    122122
     
    129129template <typename X> void link(X *walker, X *end)
    130130{
    131         X *vorher = end->previous;
    132         if (vorher != NULL)
    133                 vorher->next = walker;
    134         end->previous = walker;
    135         walker->previous = vorher;
    136         walker->next = end;
     131  X *vorher = end->previous;
     132  if (vorher != NULL)
     133    vorher->next = walker;
     134  end->previous = walker;
     135  walker->previous = vorher;
     136  walker->next = end;
    137137};
    138138
     
    143143template <typename X> void unlink(X *walker)
    144144{
    145         if (walker->next != NULL)
    146                 walker->next->previous = walker->previous;
    147         if (walker->previous != NULL)
    148                 walker->previous->next = walker->next;
     145  if (walker->next != NULL)
     146    walker->next->previous = walker->previous;
     147  if (walker->previous != NULL)
     148    walker->previous->next = walker->next;
    149149};
    150150
    151151/** Adds new item before an item \a *end in a list.
    152  * \param *pointer      item to be added
    153  * \param *end  end of list
     152 * \param *pointer  item to be added
     153 * \param *end  end of list
    154154 * \return true - addition succeeded, false - unable to add item to list
    155155 */
    156 template <typename X>   bool add(X *pointer, X *end)
    157 {
    158         if (end != NULL) {
    159                 link(pointer, end);
    160         } else {
    161                 pointer->previous = NULL;
    162                 pointer->next = NULL;
    163         }
    164         return true;
     156template <typename X>  bool add(X *pointer, X *end)
     157{
     158  if (end != NULL) {
     159    link(pointer, end);
     160  } else {
     161    pointer->previous = NULL;
     162    pointer->next = NULL;
     163  }
     164  return true;
    165165};
    166166
    167167/** Finds item in list
    168  * \param *suche        search criteria
    169  * \param *start        begin of list
    170  * \param *end  end of list
     168 * \param *suche  search criteria
     169 * \param *start  begin of list
     170 * \param *end  end of list
    171171 * \return X - if found, NULL - if not found
    172172 */
    173173template <typename X, typename Y> X * find(Y *suche, X *start, X *end)
    174174{
    175         X *walker = start;
    176         while (walker->next != end) { // go through list
    177                 walker = walker->next; // step onward beforehand
    178                 if (*walker->sort == *suche) return (walker);
    179         }
    180         return NULL;
     175  X *walker = start;
     176  while (walker->next != end) { // go through list
     177    walker = walker->next; // step onward beforehand
     178    if (*walker->sort == *suche) return (walker);
     179  }
     180  return NULL;
    181181};
    182182
     
    187187template <typename X> void removewithoutcheck(X *walker)
    188188{
    189         if (walker != NULL) {
    190                 unlink(walker);
    191                 delete(walker);
    192                 walker = NULL;
    193         }
     189  if (walker != NULL) {
     190    unlink(walker);
     191    delete(walker);
     192    walker = NULL;
     193  }
    194194};
    195195
    196196/** Removes an item from the list, checks if exists.
    197197 * Checks beforehand if atom is really within molecule list.
    198  * \param *pointer      item to be removed
    199  * \param *start        begin of list
    200  * \param *end  end of list
     198 * \param *pointer  item to be removed
     199 * \param *start  begin of list
     200 * \param *end  end of list
    201201 * \return true - removing succeeded, false - given item not found in list
    202202 */
    203203template <typename X> bool remove(X *pointer, X *start, X *end)
    204204{
    205         X *walker = find (pointer->sort, start, end);
    206 /*      while (walker->next != pointer) { // search through list
    207                 walker = walker->next;
    208                 if (walker == end) return false;        // item not found in list
    209         }*/
    210         // atom found, now unlink
    211         if (walker != NULL)
    212                 removewithoutcheck(walker);
    213         else
    214                 return false;
    215         return true;
     205  X *walker = find (pointer->sort, start, end);
     206/*  while (walker->next != pointer) { // search through list
     207    walker = walker->next;
     208    if (walker == end) return false;  // item not found in list
     209  }*/
     210  // atom found, now unlink
     211  if (walker != NULL)
     212    removewithoutcheck(walker);
     213  else
     214    return false;
     215  return true;
    216216};
    217217
     
    223223template <typename X> bool cleanup(X *start, X *end)
    224224{
    225         X *pointer = start->next;
    226         X *walker;
    227         while (pointer != end) { // go through list
    228                 walker = pointer; // mark current
    229                 pointer = pointer->next; // step onward beforehand
    230                 // remove walker
    231                 unlink(walker);
    232                 delete(walker);
    233                 walker = NULL;
    234         }
    235         return true;
     225  X *pointer = start->next;
     226  X *walker;
     227  while (pointer != end) { // go through list
     228    walker = pointer; // mark current
     229    pointer = pointer->next; // step onward beforehand
     230    // remove walker
     231    unlink(walker);
     232    delete(walker);
     233    walker = NULL;
     234  }
     235  return true;
    236236};
    237237
     
    242242template <typename X> X *GetFirst(X *me)
    243243{
    244         X *Binder = me;
    245         while(Binder->previous != NULL)
    246                 Binder = Binder->previous;
    247         return Binder;
     244  X *Binder = me;
     245  while(Binder->previous != NULL)
     246    Binder = Binder->previous;
     247  return Binder;
    248248};
    249249
     
    254254template <typename X> X *GetLast(X *me)
    255255{
    256         X *Binder = me;
    257         while(Binder->next != NULL)
    258                 Binder = Binder->next;
    259         return Binder;
     256  X *Binder = me;
     257  while(Binder->next != NULL)
     258    Binder = Binder->next;
     259  return Binder;
    260260};
    261261
     
    266266template <typename X> void Free2DArray(X **ptr, int dim)
    267267{
    268         int i;
    269         if (ptr != NULL) {
    270                 for(i=dim;i--;)
    271                         if (ptr[i] != NULL)
    272                                 free(ptr[i]);
    273                 free(ptr);
    274         }
     268  int i;
     269  if (ptr != NULL) {
     270    for(i=dim;i--;)
     271      if (ptr[i] != NULL)
     272        free(ptr[i]);
     273    free(ptr);
     274  }
    275275};
    276276
     
    281281class Verbose
    282282{
    283         public:
    284                 Verbose(int value) : Verbosity(value) { }
    285 
    286                 ostream& print (ostream &ost) const;
    287         private:
    288                 int Verbosity;
     283  public:
     284    Verbose(int value) : Verbosity(value) { }
     285
     286    ostream& print (ostream &ost) const;
     287  private:
     288    int Verbosity;
    289289};
    290290
     
    295295class Binary
    296296{
    297         public:
    298                 Binary(int value) : BinaryNumber(value) { }
    299 
    300                 ostream& print (ostream &ost) const;
    301         private:
    302                 int BinaryNumber;
     297  public:
     298    Binary(int value) : BinaryNumber(value) { }
     299
     300    ostream& print (ostream &ost) const;
     301  private:
     302    int BinaryNumber;
    303303};
    304304
  • src/joiner.cpp

    r205ccd r042f82  
    1717int main(int argc, char **argv)
    1818{
    19         periodentafel *periode = NULL; // and a period table of all elements
    20         EnergyMatrix Energy;
    21         EnergyMatrix Hcorrection;
    22         ForceMatrix Force;
    23         EnergyMatrix EnergyFragments;
    24         EnergyMatrix HcorrectionFragments;
    25         ForceMatrix ForceFragments;
    26         ForceMatrix Shielding;
    27         ForceMatrix ShieldingPAS;
    28         ForceMatrix ShieldingFragments;
    29         ForceMatrix ShieldingPASFragments;
    30         KeySetsContainer KeySet;
    31         stringstream prefix;
    32         char *dir = NULL;
    33         bool Hcorrected = true;
     19  periodentafel *periode = NULL; // and a period table of all elements
     20  EnergyMatrix Energy;
     21  EnergyMatrix Hcorrection;
     22  ForceMatrix Force;
     23  EnergyMatrix EnergyFragments;
     24  EnergyMatrix HcorrectionFragments;
     25  ForceMatrix ForceFragments;
     26  ForceMatrix Shielding;
     27  ForceMatrix ShieldingPAS;
     28  ForceMatrix ShieldingFragments;
     29  ForceMatrix ShieldingPASFragments;
     30  KeySetsContainer KeySet;
     31  stringstream prefix;
     32  char *dir = NULL;
     33  bool Hcorrected = true;
    3434
    35         cout << "Joiner" << endl;
    36         cout << "======" << endl;
     35  cout << "Joiner" << endl;
     36  cout << "======" << endl;
    3737
    38         // Get the command line options
    39         if (argc < 3) {
    40                 cout << "Usage: " << argv[0] << " <inputdir> <prefix> [elementsdb]" << endl;
    41                 cout << "<inputdir>\ttherein the output of a molecuilder fragmentation is expected, each fragment with a subdir containing an energy.all and a forces.all file." << endl;
    42                 cout << "<prefix>\tprefix of energy and forces file." << endl;
    43                 cout << "[elementsdb]\tpath to elements database, needed for shieldings." << endl;
    44                 return 1;
    45         } else {
    46                 dir = (char *) Malloc(sizeof(char)*(strlen(argv[2])+2), "main: *dir");
    47                 strcpy(dir, "/");
    48                 strcat(dir, argv[2]);
    49         }
    50         if (argc > 3) {
    51                 periode = new periodentafel;
    52                 periode->LoadPeriodentafel(argv[3]);
    53         }
     38  // Get the command line options
     39  if (argc < 3) {
     40    cout << "Usage: " << argv[0] << " <inputdir> <prefix> [elementsdb]" << endl;
     41    cout << "<inputdir>\ttherein the output of a molecuilder fragmentation is expected, each fragment with a subdir containing an energy.all and a forces.all file." << endl;
     42    cout << "<prefix>\tprefix of energy and forces file." << endl;
     43    cout << "[elementsdb]\tpath to elements database, needed for shieldings." << endl;
     44    return 1;
     45  } else {
     46    dir = (char *) Malloc(sizeof(char)*(strlen(argv[2])+2), "main: *dir");
     47    strcpy(dir, "/");
     48    strcat(dir, argv[2]);
     49  }
     50  if (argc > 3) {
     51    periode = new periodentafel;
     52    periode->LoadPeriodentafel(argv[3]);
     53  }
    5454
    55         // Test the given directory
    56         if (!TestParams(argc, argv))
    57                 return 1;
     55  // Test the given directory
     56  if (!TestParams(argc, argv))
     57    return 1;
    5858
    59         // +++++++++++++++++ PARSING +++++++++++++++++++++++++++++++
     59  // +++++++++++++++++ PARSING +++++++++++++++++++++++++++++++
    6060
    61         // ------------- Parse through all Fragment subdirs --------
    62         if (!Energy.ParseFragmentMatrix(argv[1], dir, EnergySuffix, 0,0)) return 1;
    63         Hcorrected = Hcorrection.ParseFragmentMatrix(argv[1], "", HCORRECTIONSUFFIX, 0,0);
    64         if (!Force.ParseFragmentMatrix(argv[1], dir, ForcesSuffix, 0,0)) return 1;
    65         if (periode != NULL) { // also look for PAS values
    66                 if (!Shielding.ParseFragmentMatrix(argv[1], dir, ShieldingSuffix, 1, 0)) return 1;
    67                 if (!ShieldingPAS.ParseFragmentMatrix(argv[1], dir, ShieldingPASSuffix, 1, 0)) return 1;
    68         }
     61  // ------------- Parse through all Fragment subdirs --------
     62  if (!Energy.ParseFragmentMatrix(argv[1], dir, EnergySuffix, 0,0)) return 1;
     63  Hcorrected = Hcorrection.ParseFragmentMatrix(argv[1], "", HCORRECTIONSUFFIX, 0,0);
     64  if (!Force.ParseFragmentMatrix(argv[1], dir, ForcesSuffix, 0,0)) return 1;
     65  if (periode != NULL) { // also look for PAS values
     66    if (!Shielding.ParseFragmentMatrix(argv[1], dir, ShieldingSuffix, 1, 0)) return 1;
     67    if (!ShieldingPAS.ParseFragmentMatrix(argv[1], dir, ShieldingPASSuffix, 1, 0)) return 1;
     68  }
    6969
    70         // ---------- Parse the TE Factors into an array -----------------
    71         if (!Energy.ParseIndices()) return 1;
    72         if (Hcorrected) Hcorrection.ParseIndices();
     70  // ---------- Parse the TE Factors into an array -----------------
     71  if (!Energy.ParseIndices()) return 1;
     72  if (Hcorrected) Hcorrection.ParseIndices();
    7373
    74         // ---------- Parse the Force indices into an array ---------------
    75         if (!Force.ParseIndices(argv[1])) return 1;
     74  // ---------- Parse the Force indices into an array ---------------
     75  if (!Force.ParseIndices(argv[1])) return 1;
    7676
    77         // ---------- Parse the shielding indices into an array ---------------
    78         if (periode != NULL) { // also look for PAS values
    79                 if(!Shielding.ParseIndices(argv[1])) return 1;
    80                 if(!ShieldingPAS.ParseIndices(argv[1])) return 1;
    81         }
     77  // ---------- Parse the shielding indices into an array ---------------
     78  if (periode != NULL) { // also look for PAS values
     79    if(!Shielding.ParseIndices(argv[1])) return 1;
     80    if(!ShieldingPAS.ParseIndices(argv[1])) return 1;
     81  }
    8282
    83         // ---------- Parse the KeySets into an array ---------------
    84         if (!KeySet.ParseKeySets(argv[1], Force.RowCounter, Force.MatrixCounter)) return 1;
     83  // ---------- Parse the KeySets into an array ---------------
     84  if (!KeySet.ParseKeySets(argv[1], Force.RowCounter, Force.MatrixCounter)) return 1;
    8585
    86         if (!KeySet.ParseManyBodyTerms()) return 1;
    87         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);
    89         if (!ForceFragments.AllocateMatrix(Force.Header, Force.MatrixCounter, Force.RowCounter, Force.ColumnCounter)) return 1;
    90         if (periode != NULL) { // also look for PAS values
    91                 if (!ShieldingFragments.AllocateMatrix(Shielding.Header, Shielding.MatrixCounter, Shielding.RowCounter, Shielding.ColumnCounter)) return 1;
    92                 if (!ShieldingPASFragments.AllocateMatrix(ShieldingPAS.Header, ShieldingPAS.MatrixCounter, ShieldingPAS.RowCounter, ShieldingPAS.ColumnCounter)) return 1;
    93         }
     86  if (!KeySet.ParseManyBodyTerms()) return 1;
     87  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);
     89  if (!ForceFragments.AllocateMatrix(Force.Header, Force.MatrixCounter, Force.RowCounter, Force.ColumnCounter)) return 1;
     90  if (periode != NULL) { // also look for PAS values
     91    if (!ShieldingFragments.AllocateMatrix(Shielding.Header, Shielding.MatrixCounter, Shielding.RowCounter, Shielding.ColumnCounter)) return 1;
     92    if (!ShieldingPASFragments.AllocateMatrix(ShieldingPAS.Header, ShieldingPAS.MatrixCounter, ShieldingPAS.RowCounter, ShieldingPAS.ColumnCounter)) return 1;
     93  }
    9494
    95         // ----------- Resetting last matrices (where full QM values are stored right now)
    96         if(!Energy.SetLastMatrix(0., 0)) return 1;
    97         if(!Force.SetLastMatrix(0., 2)) return 1;
    98         if (periode != NULL) { // also look for PAS values
    99                 if(!Shielding.SetLastMatrix(0., 2)) return 1;
    100                 if(!ShieldingPAS.SetLastMatrix(0., 2)) return 1;
    101         }
     95  // ----------- Resetting last matrices (where full QM values are stored right now)
     96  if(!Energy.SetLastMatrix(0., 0)) return 1;
     97  if(!Force.SetLastMatrix(0., 2)) return 1;
     98  if (periode != NULL) { // also look for PAS values
     99    if(!Shielding.SetLastMatrix(0., 2)) return 1;
     100    if(!ShieldingPAS.SetLastMatrix(0., 2)) return 1;
     101  }
    102102
    103         // +++++++++++++++++ SUMMING +++++++++++++++++++++++++++++++
     103  // +++++++++++++++++ SUMMING +++++++++++++++++++++++++++++++
    104104
    105         // --------- sum up and write for each order----------------
    106         for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
    107                 // --------- sum up energy --------------------
    108                 cout << "Summing energy of order " << BondOrder+1 << " ..." << endl;
    109                 if (!EnergyFragments.SumSubManyBodyTerms(Energy, KeySet, BondOrder)) return 1;
    110                 if (Hcorrected) {
    111                         HcorrectionFragments.SumSubManyBodyTerms(Hcorrection, KeySet, BondOrder);
    112                         if (!Energy.SumSubEnergy(EnergyFragments, &HcorrectionFragments, KeySet, BondOrder, 1.)) return 1;
    113                         if (Hcorrected) Hcorrection.SumSubEnergy(HcorrectionFragments, NULL, KeySet, BondOrder, 1.);
    114                 } else
    115                         if (!Energy.SumSubEnergy(EnergyFragments, NULL, KeySet, BondOrder, 1.)) return 1;
    116                 // --------- sum up Forces --------------------
    117                 cout << "Summing forces of order " << BondOrder+1 << " ..." << endl;
    118                 if (!ForceFragments.SumSubManyBodyTerms(Force, KeySet, BondOrder)) return 1;
    119                 if (!Force.SumSubForces(ForceFragments, KeySet, BondOrder, 1.)) return 1;
    120                 if (periode != NULL) { // also look for PAS values
    121                         cout << "Summing shieldings of order " << BondOrder+1 << " ..." << endl;
    122                         if (!ShieldingFragments.SumSubManyBodyTerms(Shielding, KeySet, BondOrder)) return 1;
    123                         if (!Shielding.SumSubForces(ShieldingFragments, KeySet, BondOrder, 1.)) return 1;
    124                         if (!ShieldingPASFragments.SumSubManyBodyTerms(ShieldingPAS, KeySet, BondOrder)) return 1;
    125                         if (!ShieldingPAS.SumSubForces(ShieldingPASFragments, KeySet, BondOrder, 1.)) return 1;
    126                 }
     105  // --------- sum up and write for each order----------------
     106  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
     107    // --------- sum up energy --------------------
     108    cout << "Summing energy of order " << BondOrder+1 << " ..." << endl;
     109    if (!EnergyFragments.SumSubManyBodyTerms(Energy, KeySet, BondOrder)) return 1;
     110    if (Hcorrected) {
     111      HcorrectionFragments.SumSubManyBodyTerms(Hcorrection, KeySet, BondOrder);
     112      if (!Energy.SumSubEnergy(EnergyFragments, &HcorrectionFragments, KeySet, BondOrder, 1.)) return 1;
     113      if (Hcorrected) Hcorrection.SumSubEnergy(HcorrectionFragments, NULL, KeySet, BondOrder, 1.);
     114    } else
     115      if (!Energy.SumSubEnergy(EnergyFragments, NULL, KeySet, BondOrder, 1.)) return 1;
     116    // --------- sum up Forces --------------------
     117    cout << "Summing forces of order " << BondOrder+1 << " ..." << endl;
     118    if (!ForceFragments.SumSubManyBodyTerms(Force, KeySet, BondOrder)) return 1;
     119    if (!Force.SumSubForces(ForceFragments, KeySet, BondOrder, 1.)) return 1;
     120    if (periode != NULL) { // also look for PAS values
     121      cout << "Summing shieldings of order " << BondOrder+1 << " ..." << endl;
     122      if (!ShieldingFragments.SumSubManyBodyTerms(Shielding, KeySet, BondOrder)) return 1;
     123      if (!Shielding.SumSubForces(ShieldingFragments, KeySet, BondOrder, 1.)) return 1;
     124      if (!ShieldingPASFragments.SumSubManyBodyTerms(ShieldingPAS, KeySet, BondOrder)) return 1;
     125      if (!ShieldingPAS.SumSubForces(ShieldingPASFragments, KeySet, BondOrder, 1.)) return 1;
     126    }
    127127
    128                 // --------- write the energy and forces file --------------------
    129                 prefix.str(" ");
    130                 prefix << dir << OrderSuffix << (BondOrder+1);
    131                 cout << "Writing files " << argv[1] << prefix.str() << ". ..." << endl;
    132                 // energy
    133                 if (!Energy.WriteLastMatrix(argv[1], (prefix.str()).c_str(), EnergySuffix)) return 1;
    134                 // forces
    135                 if (!Force.WriteLastMatrix(argv[1], (prefix.str()).c_str(), ForcesSuffix)) return 1;
    136                 // shieldings
    137                 if (periode != NULL) { // also look for PAS values
    138                         if (!Shielding.WriteLastMatrix(argv[1], (prefix.str()).c_str(), ShieldingSuffix)) return 1;
    139                         if (!ShieldingPAS.WriteLastMatrix(argv[1], (prefix.str()).c_str(), ShieldingPASSuffix)) return 1;
    140                 }
    141         }
    142         // fragments
    143         prefix.str(" ");
    144         prefix << dir << EnergyFragmentSuffix;
    145         if (!EnergyFragments.WriteTotalFragments(argv[1], (prefix.str()).c_str())) return 1;
    146         if (Hcorrected) {
    147                 prefix.str(" ");
    148                 prefix << dir << HcorrectionFragmentSuffix;
    149                 if (!HcorrectionFragments.WriteTotalFragments(argv[1], (prefix.str()).c_str())) return 1;
    150         }
    151         prefix.str(" ");
    152         prefix << dir << ForceFragmentSuffix;
    153         if (!ForceFragments.WriteTotalFragments(argv[1], (prefix.str()).c_str())) return 1;
    154         if (!CreateDataFragment(EnergyFragments, KeySet, argv[1], FRAGMENTPREFIX ENERGYPERFRAGMENT, "fragment energy versus the Fragment No", "today", CreateEnergy)) return 1;
    155         if (periode != NULL) { // also look for PAS values
    156                 prefix.str(" ");
    157                 prefix << dir << ShieldingFragmentSuffix;
    158                 if (!ShieldingFragments.WriteTotalFragments(argv[1], (prefix.str()).c_str())) return 1;
    159                 prefix.str(" ");
    160                 prefix << dir << ShieldingPASFragmentSuffix;
    161                 if (!ShieldingPASFragments.WriteTotalFragments(argv[1], (prefix.str()).c_str())) return 1;
    162         }
     128    // --------- write the energy and forces file --------------------
     129    prefix.str(" ");
     130    prefix << dir << OrderSuffix << (BondOrder+1);
     131    cout << "Writing files " << argv[1] << prefix.str() << ". ..." << endl;
     132    // energy
     133    if (!Energy.WriteLastMatrix(argv[1], (prefix.str()).c_str(), EnergySuffix)) return 1;
     134    // forces
     135    if (!Force.WriteLastMatrix(argv[1], (prefix.str()).c_str(), ForcesSuffix)) return 1;
     136    // shieldings
     137    if (periode != NULL) { // also look for PAS values
     138      if (!Shielding.WriteLastMatrix(argv[1], (prefix.str()).c_str(), ShieldingSuffix)) return 1;
     139      if (!ShieldingPAS.WriteLastMatrix(argv[1], (prefix.str()).c_str(), ShieldingPASSuffix)) return 1;
     140    }
     141  }
     142  // fragments
     143  prefix.str(" ");
     144  prefix << dir << EnergyFragmentSuffix;
     145  if (!EnergyFragments.WriteTotalFragments(argv[1], (prefix.str()).c_str())) return 1;
     146  if (Hcorrected) {
     147    prefix.str(" ");
     148    prefix << dir << HcorrectionFragmentSuffix;
     149    if (!HcorrectionFragments.WriteTotalFragments(argv[1], (prefix.str()).c_str())) return 1;
     150  }
     151  prefix.str(" ");
     152  prefix << dir << ForceFragmentSuffix;
     153  if (!ForceFragments.WriteTotalFragments(argv[1], (prefix.str()).c_str())) return 1;
     154  if (!CreateDataFragment(EnergyFragments, KeySet, argv[1], FRAGMENTPREFIX ENERGYPERFRAGMENT, "fragment energy versus the Fragment No", "today", CreateEnergy)) return 1;
     155  if (periode != NULL) { // also look for PAS values
     156    prefix.str(" ");
     157    prefix << dir << ShieldingFragmentSuffix;
     158    if (!ShieldingFragments.WriteTotalFragments(argv[1], (prefix.str()).c_str())) return 1;
     159    prefix.str(" ");
     160    prefix << dir << ShieldingPASFragmentSuffix;
     161    if (!ShieldingPASFragments.WriteTotalFragments(argv[1], (prefix.str()).c_str())) return 1;
     162  }
    163163
    164         // write last matrices as fragments into central dir (not subdir as above), for analyzer to know index bounds
    165         if (!Energy.WriteLastMatrix(argv[1], dir, EnergyFragmentSuffix)) return 1;
    166         if (Hcorrected) Hcorrection.WriteLastMatrix(argv[1], dir, HcorrectionFragmentSuffix);
    167         if (!Force.WriteLastMatrix(argv[1], dir, ForceFragmentSuffix)) return 1;
    168         if (periode != NULL) { // also look for PAS values
    169                 if (!Shielding.WriteLastMatrix(argv[1], dir, ShieldingFragmentSuffix)) return 1;
    170                 if (!ShieldingPAS.WriteLastMatrix(argv[1], dir, ShieldingPASFragmentSuffix)) return 1;
    171         }
     164  // write last matrices as fragments into central dir (not subdir as above), for analyzer to know index bounds
     165  if (!Energy.WriteLastMatrix(argv[1], dir, EnergyFragmentSuffix)) return 1;
     166  if (Hcorrected) Hcorrection.WriteLastMatrix(argv[1], dir, HcorrectionFragmentSuffix);
     167  if (!Force.WriteLastMatrix(argv[1], dir, ForceFragmentSuffix)) return 1;
     168  if (periode != NULL) { // also look for PAS values
     169    if (!Shielding.WriteLastMatrix(argv[1], dir, ShieldingFragmentSuffix)) return 1;
     170    if (!ShieldingPAS.WriteLastMatrix(argv[1], dir, ShieldingPASFragmentSuffix)) return 1;
     171  }
    172172
    173         // exit
    174         delete(periode);
    175         Free((void **)&dir, "main: *dir");
    176         cout << "done." << endl;
    177         return 0;
     173  // exit
     174  delete(periode);
     175  Free((void **)&dir, "main: *dir");
     176  cout << "done." << endl;
     177  return 0;
    178178};
    179179
  • src/linkedcell.cpp

    r205ccd r042f82  
    66LinkedCell::LinkedCell()
    77{
    8         LC = NULL;
    9         for(int i=0;i<NDIM;i++)
    10                 N[i] = 0;
    11         index = -1;
    12         RADIUS = 0.;
    13         max.Zero();
    14         min.Zero();
     8  LC = NULL;
     9  for(int i=0;i<NDIM;i++)
     10    N[i] = 0;
     11  index = -1;
     12  RADIUS = 0.;
     13  max.Zero();
     14  min.Zero();
    1515};
    1616
     
    2121LinkedCell::LinkedCell(molecule *mol, double radius)
    2222{
    23         atom *Walker = NULL;
     23  atom *Walker = NULL;
    2424
    25         RADIUS = radius;
    26         LC = NULL;
    27         for(int i=0;i<NDIM;i++)
    28                 N[i] = 0;
    29         index = -1;
    30         max.Zero();
    31         min.Zero();
    32         cout << Verbose(1) << "Begin of LinkedCell" << endl;
    33         if (mol->start->next == mol->end) {
    34                 cerr << "ERROR: molecule contains no atoms!" << endl;
    35                 return;
    36         }
    37         // 1. find max and min per axis of atoms
    38         Walker = mol->start->next;
    39         for (int i=0;i<NDIM;i++) {
    40                 max.x[i] = Walker->x.x[i];
    41                 min.x[i] = Walker->x.x[i];
    42         }
    43         while (Walker != mol->end) {
    44                 for (int i=0;i<NDIM;i++) {
    45                         if (max.x[i] < Walker->x.x[i])
    46                                 max.x[i] = Walker->x.x[i];
    47                         if (min.x[i] > Walker->x.x[i])
    48                                 min.x[i] = Walker->x.x[i];
    49                 }
    50                 Walker = Walker->next;
    51         }
    52         cout << Verbose(2) << "Bounding box is " << min << " and " << max << "." << endl;
     25  RADIUS = radius;
     26  LC = NULL;
     27  for(int i=0;i<NDIM;i++)
     28    N[i] = 0;
     29  index = -1;
     30  max.Zero();
     31  min.Zero();
     32  cout << Verbose(1) << "Begin of LinkedCell" << endl;
     33  if (mol->start->next == mol->end) {
     34    cerr << "ERROR: molecule contains no atoms!" << endl;
     35    return;
     36  }
     37  // 1. find max and min per axis of atoms
     38  Walker = mol->start->next;
     39  for (int i=0;i<NDIM;i++) {
     40    max.x[i] = Walker->x.x[i];
     41    min.x[i] = Walker->x.x[i];
     42  }
     43  while (Walker != mol->end) {
     44    for (int i=0;i<NDIM;i++) {
     45      if (max.x[i] < Walker->x.x[i])
     46        max.x[i] = Walker->x.x[i];
     47      if (min.x[i] > Walker->x.x[i])
     48        min.x[i] = Walker->x.x[i];
     49    }
     50    Walker = Walker->next;
     51  }
     52  cout << Verbose(2) << "Bounding box is " << min << " and " << max << "." << endl;
    5353
    54         // 2. find then umber of cells per axis
    55         for (int i=0;i<NDIM;i++) {
    56                 N[i] = (int)floor((max.x[i] - min.x[i])/RADIUS)+1;
    57         }
    58         cout << Verbose(2) << "Number of cells per axis are " << N[0] << ", " << N[1] << " and " << N[2] << "." << endl;
     54  // 2. find then umber of cells per axis
     55  for (int i=0;i<NDIM;i++) {
     56    N[i] = (int)floor((max.x[i] - min.x[i])/RADIUS)+1;
     57  }
     58  cout << Verbose(2) << "Number of cells per axis are " << N[0] << ", " << N[1] << " and " << N[2] << "." << endl;
    5959
    60         // 3. allocate the lists
    61         cout << Verbose(2) << "Allocating cells ... ";
    62         if (LC != NULL) {
    63                 cout << Verbose(1) << "ERROR: Linked Cell list is already allocated, I do nothing." << endl;
    64                 return;
    65         }
    66         LC = new LinkedAtoms[N[0]*N[1]*N[2]];
    67         for (index=0;index<N[0]*N[1]*N[2];index++) {
    68                 LC [index].clear();
    69         }
    70         cout << "done."  << endl;
     60  // 3. allocate the lists
     61  cout << Verbose(2) << "Allocating cells ... ";
     62  if (LC != NULL) {
     63    cout << Verbose(1) << "ERROR: Linked Cell list is already allocated, I do nothing." << endl;
     64    return;
     65  }
     66  LC = new LinkedAtoms[N[0]*N[1]*N[2]];
     67  for (index=0;index<N[0]*N[1]*N[2];index++) {
     68    LC [index].clear();
     69  }
     70  cout << "done."  << endl;
    7171
    72         // 4. put each atom into its respective cell
     72  // 4. put each atom into its respective cell
    7373  cout << Verbose(2) << "Filling cells ... ";
    74         Walker = mol->start;
    75         while (Walker->next != mol->end) {
    76                 Walker = Walker->next;
    77                 for (int i=0;i<NDIM;i++) {
    78                         n[i] = (int)floor((Walker->x.x[i] - min.x[i])/RADIUS);
    79                 }
    80                 index = n[0] * N[1] * N[2] + n[1] * N[2] + n[2];
    81                 LC[index].push_back(Walker);
    82                 //cout << Verbose(2) << *Walker << " goes into cell " << n[0] << ", " << n[1] << ", " << n[2] << " with No. " << index << "." << endl;
    83         }
     74  Walker = mol->start;
     75  while (Walker->next != mol->end) {
     76    Walker = Walker->next;
     77    for (int i=0;i<NDIM;i++) {
     78      n[i] = (int)floor((Walker->x.x[i] - min.x[i])/RADIUS);
     79    }
     80    index = n[0] * N[1] * N[2] + n[1] * N[2] + n[2];
     81    LC[index].push_back(Walker);
     82    //cout << Verbose(2) << *Walker << " goes into cell " << n[0] << ", " << n[1] << ", " << n[2] << " with No. " << index << "." << endl;
     83  }
    8484  cout << "done."  << endl;
    85         cout << Verbose(1) << "End of LinkedCell" << endl;
     85  cout << Verbose(1) << "End of LinkedCell" << endl;
    8686};
    8787
     
    9090LinkedCell::~LinkedCell()
    9191{
    92         if (LC != NULL)
    93         for (index=0;index<N[0]*N[1]*N[2];index++)
    94                 LC[index].clear();
    95         delete[](LC);
    96         for(int i=0;i<NDIM;i++)
    97                 N[i] = 0;
    98         index = -1;
    99         max.Zero();
    100         min.Zero();
     92  if (LC != NULL)
     93  for (index=0;index<N[0]*N[1]*N[2];index++)
     94    LC[index].clear();
     95  delete[](LC);
     96  for(int i=0;i<NDIM;i++)
     97    N[i] = 0;
     98  index = -1;
     99  max.Zero();
     100  min.Zero();
    101101};
    102102
     
    106106bool LinkedCell::CheckBounds()
    107107{
    108         bool status = true;
    109         for(int i=0;i<NDIM;i++)
    110                 status = status && ((n[i] >=0) && (n[i] < N[i]));
    111         if (!status)
    112         cerr << "ERROR: indices are out of bounds!" << endl;
    113         return status;
     108  bool status = true;
     109  for(int i=0;i<NDIM;i++)
     110    status = status && ((n[i] >=0) && (n[i] < N[i]));
     111  if (!status)
     112  cerr << "ERROR: indices are out of bounds!" << endl;
     113  return status;
    114114};
    115115
     
    120120LinkedAtoms* LinkedCell::GetCurrentCell()
    121121{
    122         if (CheckBounds()) {
    123                 index = n[0] * N[1] * N[2] + n[1] * N[2] + n[2];
    124                 return (&(LC[index]));
    125         } else {
    126                 return NULL;
    127         }
     122  if (CheckBounds()) {
     123    index = n[0] * N[1] * N[2] + n[1] * N[2] + n[2];
     124    return (&(LC[index]));
     125  } else {
     126    return NULL;
     127  }
    128128};
    129129
     
    134134bool LinkedCell::SetIndexToAtom(atom *Walker)
    135135{
    136         bool status = false;
    137         for (int i=0;i<NDIM;i++) {
    138                 n[i] = (int)floor((Walker->x.x[i] - min.x[i])/RADIUS);
    139         }
    140         index = n[0] * N[1] * N[2] + n[1] * N[2] + n[2];
    141         if (CheckBounds()) {
    142                 for (LinkedAtoms::iterator Runner = LC[index].begin(); Runner != LC[index].end(); Runner++)
    143                         status = status || ((*Runner) == Walker);
    144                 return status;
    145         } else {
    146                 cerr << Verbose(1) << "ERROR: Atom "<< *Walker << " at " << Walker->x << " is out of bounds." << endl;
    147                 return false;
    148         }
     136  bool status = false;
     137  for (int i=0;i<NDIM;i++) {
     138    n[i] = (int)floor((Walker->x.x[i] - min.x[i])/RADIUS);
     139  }
     140  index = n[0] * N[1] * N[2] + n[1] * N[2] + n[2];
     141  if (CheckBounds()) {
     142    for (LinkedAtoms::iterator Runner = LC[index].begin(); Runner != LC[index].end(); Runner++)
     143      status = status || ((*Runner) == Walker);
     144    return status;
     145  } else {
     146    cerr << Verbose(1) << "ERROR: Atom "<< *Walker << " at " << Walker->x << " is out of bounds." << endl;
     147    return false;
     148  }
    149149};
    150150
     
    155155bool LinkedCell::SetIndexToVector(Vector *x)
    156156{
    157         bool status = true;
    158         for (int i=0;i<NDIM;i++) {
    159                 n[i] = (int)floor((x->x[i] - min.x[i])/RADIUS);
    160                 if (max.x[i] < x->x[i])
    161                         status = false;
    162                 if (min.x[i] > x->x[i])
    163                         status = false;
    164         }
    165         return status;
     157  bool status = true;
     158  for (int i=0;i<NDIM;i++) {
     159    n[i] = (int)floor((x->x[i] - min.x[i])/RADIUS);
     160    if (max.x[i] < x->x[i])
     161      status = false;
     162    if (min.x[i] > x->x[i])
     163      status = false;
     164  }
     165  return status;
    166166};
    167167
  • src/linkedcell.hpp

    r205ccd r042f82  
    1212
    1313class LinkedCell{
    14         public:
    15                 Vector max;                      // upper boundary
    16                 Vector min;                      // lower boundary
    17                 LinkedAtoms *LC;        // linked cell list
    18                 double RADIUS;          // cell edge length
    19                 int N[NDIM];                    // number of cells per axis
    20                 int n[NDIM];                    // temporary variable for current cell per axis
    21                 int index;                              // temporary index variable , access by index = n[0] * N[1] * N[2] + n[1] * N[2] + n[2];
     14  public:
     15    Vector max;      // upper boundary
     16    Vector min;      // lower boundary
     17    LinkedAtoms *LC;  // linked cell list
     18    double RADIUS;    // cell edge length
     19    int N[NDIM];      // number of cells per axis
     20    int n[NDIM];      // temporary variable for current cell per axis
     21    int index;        // temporary index variable , access by index = n[0] * N[1] * N[2] + n[1] * N[2] + n[2];
    2222
    23                 LinkedCell();
    24                 LinkedCell(molecule *mol, double RADIUS);
    25                 ~LinkedCell();
    26                 LinkedAtoms* GetCurrentCell();
    27                 bool SetIndexToAtom(atom *Walker);
    28                 bool SetIndexToVector(Vector *x);
    29                 bool CheckBounds();
     23    LinkedCell();
     24    LinkedCell(molecule *mol, double RADIUS);
     25    ~LinkedCell();
     26    LinkedAtoms* GetCurrentCell();
     27    bool SetIndexToAtom(atom *Walker);
     28    bool SetIndexToVector(Vector *x);
     29    bool CheckBounds();
    3030
    31                 // not implemented yet
    32                 bool AddAtom(atom *Walker);
    33                 bool DeleteAtom(atom *Walker);
    34                 bool MoveAtom(atom *Walker);
     31    // not implemented yet
     32    bool AddAtom(atom *Walker);
     33    bool DeleteAtom(atom *Walker);
     34    bool MoveAtom(atom *Walker);
    3535};
    3636
  • src/moleculelist.cpp

    r205ccd r042f82  
    523523
    524524  // open file for the force factors
    525   *out << Verbose(1) << "Saving force factors ... ";
     525  *out << Verbose(1) << "Saving  force factors ... ";
    526526  line << path << "/" << FRAGMENTPREFIX << FORCESFILE;
    527527  ForcesFile.open(line.str().c_str(), ios::out);
     
    691691MoleculeLeafClass::MoleculeLeafClass(MoleculeLeafClass *PreviousLeaf = NULL)
    692692{
    693   //    if (Up != NULL)
    694   //            if (Up->DownLeaf == NULL) // are we the first down leaf for the upper leaf?
    695   //                    Up->DownLeaf = this;
    696   //    UpLeaf = Up;
    697   //    DownLeaf = NULL;
     693  //  if (Up != NULL)
     694  //    if (Up->DownLeaf == NULL) // are we the first down leaf for the upper leaf?
     695  //      Up->DownLeaf = this;
     696  //  UpLeaf = Up;
     697  //  DownLeaf = NULL;
    698698  Leaf = NULL;
    699699  previous = PreviousLeaf;
     
    711711MoleculeLeafClass::~MoleculeLeafClass()
    712712{
    713   //    if (DownLeaf != NULL) {// drop leaves further down
    714   //            MoleculeLeafClass *Walker = DownLeaf;
    715   //            MoleculeLeafClass *Next;
    716   //            do {
    717   //                    Next = Walker->NextLeaf;
    718   //                    delete(Walker);
    719   //                    Walker = Next;
    720   //            } while (Walker != NULL);
    721   //            // Last Walker sets DownLeaf automatically to NULL
    722   //    }
     713  //  if (DownLeaf != NULL) {// drop leaves further down
     714  //    MoleculeLeafClass *Walker = DownLeaf;
     715  //    MoleculeLeafClass *Next;
     716  //    do {
     717  //      Next = Walker->NextLeaf;
     718  //      delete(Walker);
     719  //      Walker = Next;
     720  //    } while (Walker != NULL);
     721  //    // Last Walker sets DownLeaf automatically to NULL
     722  //  }
    723723  // remove the leaf itself
    724724  if (Leaf != NULL) {
     
    729729  if (previous != NULL)
    730730    previous->next = next;
    731   //    } else { // we are first in list (connects to UpLeaf->DownLeaf)
    732   //            if ((NextLeaf != NULL) && (NextLeaf->UpLeaf == NULL))
    733   //                    NextLeaf->UpLeaf = UpLeaf;      // either null as we are top level or the upleaf of the first node
    734   //            if (UpLeaf != NULL)
    735   //                    UpLeaf->DownLeaf = NextLeaf;    // either null as we are only leaf or NextLeaf if we are just the first
    736   //    }
    737   //    UpLeaf = NULL;
     731  //  } else { // we are first in list (connects to UpLeaf->DownLeaf)
     732  //    if ((NextLeaf != NULL) && (NextLeaf->UpLeaf == NULL))
     733  //      NextLeaf->UpLeaf = UpLeaf;  // either null as we are top level or the upleaf of the first node
     734  //    if (UpLeaf != NULL)
     735  //      UpLeaf->DownLeaf = NextLeaf;  // either null as we are only leaf or NextLeaf if we are just the first
     736  //  }
     737  //  UpLeaf = NULL;
    738738  if (next != NULL) // are we last in list
    739739    next->previous = previous;
  • src/molecules.cpp

    r205ccd r042f82  
    1616double LSQ (const gsl_vector * x, void * params)
    1717{
    18         double sum = 0.;
    19         struct LSQ_params *par = (struct LSQ_params *)params;
    20         Vector **vectors = par->vectors;
    21         int num = par->num;
    22 
    23         for (int i=num;i--;) {
    24                 for(int j=NDIM;j--;)
    25                         sum += (gsl_vector_get(x,j) - (vectors[i])->x[j])*(gsl_vector_get(x,j) - (vectors[i])->x[j]);
    26         }
    27 
    28         return sum;
     18  double sum = 0.;
     19  struct LSQ_params *par = (struct LSQ_params *)params;
     20  Vector **vectors = par->vectors;
     21  int num = par->num;
     22
     23  for (int i=num;i--;) {
     24    for(int j=NDIM;j--;)
     25      sum += (gsl_vector_get(x,j) - (vectors[i])->x[j])*(gsl_vector_get(x,j) - (vectors[i])->x[j]);
     26  }
     27
     28  return sum;
    2929};
    3030
     
    3636molecule::molecule(periodentafel *teil)
    3737{
    38         // init atom chain list
    39         start = new atom;
    40         end = new atom;
    41         start->father = NULL;
    42         end->father = NULL;
    43         link(start,end);
    44         // init bond chain list
    45         first = new bond(start, end, 1, -1);
    46         last = new bond(start, end, 1, -1);
    47         link(first,last);
    48         // other stuff
    49         MDSteps = 0;
    50         last_atom = 0;
    51         elemente = teil;
    52         AtomCount = 0;
    53         BondCount = 0;
    54         NoNonBonds = 0;
    55         NoNonHydrogen = 0;
    56         NoCyclicBonds = 0;
    57         ListOfBondsPerAtom = NULL;
    58         NumberOfBondsPerAtom = NULL;
    59         ElementCount = 0;
    60         for(int i=MAX_ELEMENTS;i--;)
    61                 ElementsInMolecule[i] = 0;
    62         cell_size[0] = cell_size[2] = cell_size[5]= 20.;
    63         cell_size[1] = cell_size[3] = cell_size[4]= 0.;
    64         strcpy(name,"none");
     38  // init atom chain list
     39  start = new atom;
     40  end = new atom;
     41  start->father = NULL;
     42  end->father = NULL;
     43  link(start,end);
     44  // init bond chain list
     45  first = new bond(start, end, 1, -1);
     46  last = new bond(start, end, 1, -1);
     47  link(first,last);
     48  // other stuff
     49  MDSteps = 0;
     50  last_atom = 0;
     51  elemente = teil;
     52  AtomCount = 0;
     53  BondCount = 0;
     54  NoNonBonds = 0;
     55  NoNonHydrogen = 0;
     56  NoCyclicBonds = 0;
     57  ListOfBondsPerAtom = NULL;
     58  NumberOfBondsPerAtom = NULL;
     59  ElementCount = 0;
     60  for(int i=MAX_ELEMENTS;i--;)
     61    ElementsInMolecule[i] = 0;
     62  cell_size[0] = cell_size[2] = cell_size[5]= 20.;
     63  cell_size[1] = cell_size[3] = cell_size[4]= 0.;
     64  strcpy(name,"none");
    6565};
    6666
     
    7070molecule::~molecule()
    7171{
    72         if (ListOfBondsPerAtom != NULL)
    73                 for(int i=AtomCount;i--;)
    74                         Free((void **)&ListOfBondsPerAtom[i], "molecule::~molecule: ListOfBondsPerAtom[i]");
    75         Free((void **)&ListOfBondsPerAtom, "molecule::~molecule: ListOfBondsPerAtom");
    76         Free((void **)&NumberOfBondsPerAtom, "molecule::~molecule: NumberOfBondsPerAtom");
    77         CleanupMolecule();
    78         delete(first);
    79         delete(last);
    80         delete(end);
    81         delete(start);
     72  if (ListOfBondsPerAtom != NULL)
     73    for(int i=AtomCount;i--;)
     74      Free((void **)&ListOfBondsPerAtom[i], "molecule::~molecule: ListOfBondsPerAtom[i]");
     75  Free((void **)&ListOfBondsPerAtom, "molecule::~molecule: ListOfBondsPerAtom");
     76  Free((void **)&NumberOfBondsPerAtom, "molecule::~molecule: NumberOfBondsPerAtom");
     77  CleanupMolecule();
     78  delete(first);
     79  delete(last);
     80  delete(end);
     81  delete(start);
    8282};
    8383
     
    8989bool molecule::AddAtom(atom *pointer)
    9090{
    91         if (pointer != NULL) {
    92                 pointer->sort = &pointer->nr;
    93                 pointer->nr = last_atom++;      // increase number within molecule
    94                 AtomCount++;
    95                 if (pointer->type != NULL) {
    96                         if (ElementsInMolecule[pointer->type->Z] == 0)
    97                                 ElementCount++;
    98                         ElementsInMolecule[pointer->type->Z]++; // increase number of elements
    99                         if (pointer->type->Z != 1)
    100                                 NoNonHydrogen++;
    101                         if (pointer->Name == NULL) {
    102                                 Free((void **)&pointer->Name, "molecule::AddAtom: *pointer->Name");
    103                                 pointer->Name = (char *) Malloc(sizeof(char)*6, "molecule::AddAtom: *pointer->Name");
    104                                 sprintf(pointer->Name, "%2s%02d", pointer->type->symbol, pointer->nr+1);
    105                         }
    106                 }
    107                 return add(pointer, end);
    108         } else
    109                 return false;
     91  if (pointer != NULL) {
     92    pointer->sort = &pointer->nr;
     93    pointer->nr = last_atom++;  // increase number within molecule
     94    AtomCount++;
     95    if (pointer->type != NULL) {
     96      if (ElementsInMolecule[pointer->type->Z] == 0)
     97        ElementCount++;
     98      ElementsInMolecule[pointer->type->Z]++; // increase number of elements
     99      if (pointer->type->Z != 1)
     100        NoNonHydrogen++;
     101      if (pointer->Name == NULL) {
     102        Free((void **)&pointer->Name, "molecule::AddAtom: *pointer->Name");
     103        pointer->Name = (char *) Malloc(sizeof(char)*6, "molecule::AddAtom: *pointer->Name");
     104        sprintf(pointer->Name, "%2s%02d", pointer->type->symbol, pointer->nr+1);
     105      }
     106    }
     107    return add(pointer, end);
     108  } else
     109    return false;
    110110};
    111111
     
    117117atom * molecule::AddCopyAtom(atom *pointer)
    118118{
    119         if (pointer != NULL) {
    120                 atom *walker = new atom();
    121                 walker->type = pointer->type;   // copy element of atom
    122                 walker->x.CopyVector(&pointer->x); // copy coordination
    123                 walker->v.CopyVector(&pointer->v); // copy velocity
    124                 walker->FixedIon = pointer->FixedIon;
    125                 walker->sort = &walker->nr;
    126                 walker->nr = last_atom++;       // increase number within molecule
    127                 walker->father = pointer; //->GetTrueFather();
    128                 walker->Name = (char *) Malloc(sizeof(char)*strlen(pointer->Name)+1, "molecule::AddCopyAtom: *Name");
    129                 strcpy (walker->Name, pointer->Name);
    130                 add(walker, end);
    131                 if ((pointer->type != NULL) && (pointer->type->Z != 1))
    132                         NoNonHydrogen++;
    133                 AtomCount++;
    134                 return walker;
    135         } else
    136                 return NULL;
     119  if (pointer != NULL) {
     120    atom *walker = new atom();
     121    walker->type = pointer->type;  // copy element of atom
     122    walker->x.CopyVector(&pointer->x); // copy coordination
     123    walker->v.CopyVector(&pointer->v); // copy velocity
     124    walker->FixedIon = pointer->FixedIon;
     125    walker->sort = &walker->nr;
     126    walker->nr = last_atom++;  // increase number within molecule
     127    walker->father = pointer; //->GetTrueFather();
     128    walker->Name = (char *) Malloc(sizeof(char)*strlen(pointer->Name)+1, "molecule::AddCopyAtom: *Name");
     129    strcpy (walker->Name, pointer->Name);
     130    add(walker, end);
     131    if ((pointer->type != NULL) && (pointer->type->Z != 1))
     132      NoNonHydrogen++;
     133    AtomCount++;
     134    return walker;
     135  } else
     136    return NULL;
    137137};
    138138
     
    142142 * -# Single Bond: Simply add new atom with bond distance rescaled to typical hydrogen one
    143143 * -# Double Bond: Here, we need the **BondList of the \a *origin atom, by scanning for the other bonds instead of
    144  *              *Bond, we use the through these connected atoms to determine the plane they lie in, vector::MakeNormalvector().
    145  *              The orthonormal vector to this plane along with the vector in *Bond direction determines the plane the two
    146  *              replacing hydrogens shall lie in. Now, all remains to do is take the usual hydrogen double bond angle for the
    147  *              element of *origin and form the sin/cos admixture of both plane vectors for the new coordinates of the two
    148  *              hydrogens forming this angle with *origin.
     144 *    *Bond, we use the through these connected atoms to determine the plane they lie in, vector::MakeNormalvector().
     145 *    The orthonormal vector to this plane along with the vector in *Bond direction determines the plane the two
     146 *    replacing hydrogens shall lie in. Now, all remains to do is take the usual hydrogen double bond angle for the
     147 *    element of *origin and form the sin/cos admixture of both plane vectors for the new coordinates of the two
     148 *    hydrogens forming this angle with *origin.
    149149 * -# Triple Bond: The idea is to set up a tetraoid (C1-H1-H2-H3) (however the lengths \f$b\f$ of the sides of the base
    150  *              triangle formed by the to be added hydrogens are not equal to the typical bond distance \f$l\f$ but have to be
    151  *              determined from the typical angle \f$\alpha\f$ for a hydrogen triple connected to the element of *origin):
    152  *              We have the height \f$d\f$ as the vector in *Bond direction (from triangle C1-H1-H2).
    153  *              \f[ h = l \cdot \cos{\left (\frac{\alpha}{2} \right )} \qquad b = 2l \cdot \sin{\left (\frac{\alpha}{2} \right)} \quad \rightarrow \quad d = l \cdot \sqrt{\cos^2{\left (\frac{\alpha}{2} \right)}-\frac{1}{3}\cdot\sin^2{\left (\frac{\alpha}{2}\right )}}
    154  *              \f]
    155  *              vector::GetNormalvector() creates one orthonormal vector from this *Bond vector and vector::MakeNormalvector creates
    156  *              the third one from the former two vectors. The latter ones form the plane of the base triangle mentioned above.
    157  *              The lengths for these are \f$f\f$ and \f$g\f$ (from triangle H1-H2-(center of H1-H2-H3)) with knowledge that
    158  *              the median lines in an isosceles triangle meet in the center point with a ratio 2:1.
    159  *              \f[ f = \frac{b}{\sqrt{3}} \qquad g = \frac{b}{2}
    160  *              \f]
    161  *              as the coordination of all three atoms in the coordinate system of these three vectors:
    162  *              \f$\pmatrix{d & f & 0}\f$, \f$\pmatrix{d & -0.5 \cdot f & g}\f$ and \f$\pmatrix{d & -0.5 \cdot f & -g}\f$.
     150 *    triangle formed by the to be added hydrogens are not equal to the typical bond distance \f$l\f$ but have to be
     151 *    determined from the typical angle \f$\alpha\f$ for a hydrogen triple connected to the element of *origin):
     152 *    We have the height \f$d\f$ as the vector in *Bond direction (from triangle C1-H1-H2).
     153 *    \f[ h = l \cdot \cos{\left (\frac{\alpha}{2} \right )} \qquad b = 2l \cdot \sin{\left (\frac{\alpha}{2} \right)} \quad \rightarrow \quad d = l \cdot \sqrt{\cos^2{\left (\frac{\alpha}{2} \right)}-\frac{1}{3}\cdot\sin^2{\left (\frac{\alpha}{2}\right )}}
     154 *    \f]
     155 *    vector::GetNormalvector() creates one orthonormal vector from this *Bond vector and vector::MakeNormalvector creates
     156 *    the third one from the former two vectors. The latter ones form the plane of the base triangle mentioned above.
     157 *    The lengths for these are \f$f\f$ and \f$g\f$ (from triangle H1-H2-(center of H1-H2-H3)) with knowledge that
     158 *    the median lines in an isosceles triangle meet in the center point with a ratio 2:1.
     159 *    \f[ f = \frac{b}{\sqrt{3}} \qquad g = \frac{b}{2}
     160 *    \f]
     161 *    as the coordination of all three atoms in the coordinate system of these three vectors:
     162 *    \f$\pmatrix{d & f & 0}\f$, \f$\pmatrix{d & -0.5 \cdot f & g}\f$ and \f$\pmatrix{d & -0.5 \cdot f & -g}\f$.
    163163 *
    164164 * \param *out output stream for debugging
     
    168168 * \param *replacement pointer to the atom which shall be copied as a hydrogen atom in this molecule
    169169 * \param **BondList list of bonds \a *replacement has (necessary to determine plane for double and triple bonds)
    170  * \param NumBond       number of bonds in \a **BondList
     170 * \param NumBond  number of bonds in \a **BondList
    171171 * \param isAngstroem whether the coordination of the given atoms is in AtomicLength (false) or Angstrom(true)
    172172 * \return number of atoms added, if < bond::BondDegree then something went wrong
     
    175175bool molecule::AddHydrogenReplacementAtom(ofstream *out, bond *TopBond, atom *BottomOrigin, atom *TopOrigin, atom *TopReplacement, bond **BondList, int NumBond, bool IsAngstroem)
    176176{
    177         double bondlength;      // bond length of the bond to be replaced/cut
    178         double bondangle;       // bond angle of the bond to be replaced/cut
    179         double BondRescale;      // rescale value for the hydrogen bond length
    180         bool AllWentWell = true;                // flag gathering the boolean return value of molecule::AddAtom and other functions, as return value on exit
    181         bond *FirstBond = NULL, *SecondBond = NULL; // Other bonds in double bond case to determine "other" plane
    182         atom *FirstOtherAtom = NULL, *SecondOtherAtom = NULL, *ThirdOtherAtom = NULL; // pointer to hydrogen atoms to be added
    183         double b,l,d,f,g, alpha, factors[NDIM];         // hold temporary values in triple bond case for coordination determination
    184         Vector Orthovector1, Orthovector2;      // temporary vectors in coordination construction
    185         Vector InBondvector;            // vector in direction of *Bond
    186         bond *Binder = NULL;
    187         double *matrix;
    188 
    189 //      *out << Verbose(3) << "Begin of AddHydrogenReplacementAtom." << endl;
    190         // create vector in direction of bond
    191         InBondvector.CopyVector(&TopReplacement->x);
    192         InBondvector.SubtractVector(&TopOrigin->x);
    193         bondlength = InBondvector.Norm();
    194 
    195         // is greater than typical bond distance? Then we have to correct periodically
    196         // the problem is not the H being out of the box, but InBondvector have the wrong direction
    197         // due to TopReplacement or Origin being on the wrong side!
    198         if (bondlength > BondDistance) {
    199 //              *out << Verbose(4) << "InBondvector is: ";
    200 //              InBondvector.Output(out);
    201 //              *out << endl;
    202                 Orthovector1.Zero();
    203                 for (int i=NDIM;i--;) {
    204                         l = TopReplacement->x.x[i] - TopOrigin->x.x[i];
    205                         if (fabs(l) > BondDistance) { // is component greater than bond distance
    206                                 Orthovector1.x[i] = (l < 0) ? -1. : +1.;
    207                         } // (signs are correct, was tested!)
    208                 }
    209                 matrix = ReturnFullMatrixforSymmetric(cell_size);
    210                 Orthovector1.MatrixMultiplication(matrix);
    211                 InBondvector.SubtractVector(&Orthovector1); // subtract just the additional translation
    212                 Free((void **)&matrix, "molecule::AddHydrogenReplacementAtom: *matrix");
    213                 bondlength = InBondvector.Norm();
    214 //              *out << Verbose(4) << "Corrected InBondvector is now: ";
    215 //              InBondvector.Output(out);
    216 //              *out << endl;
    217         } // periodic correction finished
    218 
    219         InBondvector.Normalize();
    220         // get typical bond length and store as scale factor for later
    221         BondRescale = TopOrigin->type->HBondDistance[TopBond->BondDegree-1];
    222         if (BondRescale == -1) {
    223                 cerr << Verbose(3) << "ERROR: There is no typical hydrogen bond distance in replacing bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") of degree " << TopBond->BondDegree << "!" << endl;
    224                 return false;
    225                 BondRescale = bondlength;
    226         } else {
    227                 if (!IsAngstroem)
    228                         BondRescale /= (1.*AtomicLengthToAngstroem);
    229         }
    230 
    231         // discern single, double and triple bonds
    232         switch(TopBond->BondDegree) {
    233                 case 1:
    234                         FirstOtherAtom = new atom();            // new atom
    235                         FirstOtherAtom->type = elemente->FindElement(1);        // element is Hydrogen
    236                         FirstOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
    237                         FirstOtherAtom->FixedIon = TopReplacement->FixedIon;
    238                         if (TopReplacement->type->Z == 1) { // neither rescale nor replace if it's already hydrogen
    239                                 FirstOtherAtom->father = TopReplacement;
    240                                 BondRescale = bondlength;
    241                         } else {
    242                                 FirstOtherAtom->father = NULL;  // if we replace hydrogen, we mark it as our father, otherwise we are just an added hydrogen with no father
    243                         }
    244                         InBondvector.Scale(&BondRescale);        // rescale the distance vector to Hydrogen bond length
    245                         FirstOtherAtom->x.CopyVector(&TopOrigin->x); // set coordination to origin ...
    246                         FirstOtherAtom->x.AddVector(&InBondvector);     // ... and add distance vector to replacement atom
    247                         AllWentWell = AllWentWell && AddAtom(FirstOtherAtom);
    248 //                      *out << Verbose(4) << "Added " << *FirstOtherAtom << " at: ";
    249 //                      FirstOtherAtom->x.Output(out);
    250 //                      *out << endl;
    251                         Binder = AddBond(BottomOrigin, FirstOtherAtom, 1);
    252                         Binder->Cyclic = false;
    253                         Binder->Type = TreeEdge;
    254                         break;
    255                 case 2:
    256                         // determine two other bonds (warning if there are more than two other) plus valence sanity check
    257                         for (int i=0;i<NumBond;i++) {
    258                                 if (BondList[i] != TopBond) {
    259                                         if (FirstBond == NULL) {
    260                                                 FirstBond = BondList[i];
    261                                                 FirstOtherAtom = BondList[i]->GetOtherAtom(TopOrigin);
    262                                         } else if (SecondBond == NULL) {
    263                                                 SecondBond = BondList[i];
    264                                                 SecondOtherAtom = BondList[i]->GetOtherAtom(TopOrigin);
    265                                         } else {
    266                                                 *out << Verbose(3) << "WARNING: Detected more than four bonds for atom " << TopOrigin->Name;
    267                                         }
    268                                 }
    269                         }
    270                         if (SecondOtherAtom == NULL) {  // then we have an atom with valence four, but only 3 bonds: one to replace and one which is TopBond (third is FirstBond)
    271                                 SecondBond = TopBond;
    272                                 SecondOtherAtom = TopReplacement;
    273                         }
    274                         if (FirstOtherAtom != NULL) { // then we just have this double bond and the plane does not matter at all
    275 //                              *out << Verbose(3) << "Regarding the double bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") to be constructed: Taking " << FirstOtherAtom->Name << " and " << SecondOtherAtom->Name << " along with " << TopOrigin->Name << " to determine orthogonal plane." << endl;
    276 
    277                                 // determine the plane of these two with the *origin
    278                                 AllWentWell = AllWentWell && Orthovector1.MakeNormalVector(&TopOrigin->x, &FirstOtherAtom->x, &SecondOtherAtom->x);
    279                         } else {
    280                                 Orthovector1.GetOneNormalVector(&InBondvector);
    281                         }
    282                         //*out << Verbose(3)<< "Orthovector1: ";
    283                         //Orthovector1.Output(out);
    284                         //*out << endl;
    285                         // orthogonal vector and bond vector between origin and replacement form the new plane
    286                         Orthovector1.MakeNormalVector(&InBondvector);
    287                         Orthovector1.Normalize();
    288                         //*out << Verbose(3) << "ReScaleCheck: " << Orthovector1.Norm() << " and " << InBondvector.Norm() << "." << endl;
    289 
    290                         // create the two Hydrogens ...
    291                         FirstOtherAtom = new atom();
    292                         SecondOtherAtom = new atom();
    293                         FirstOtherAtom->type = elemente->FindElement(1);
    294                         SecondOtherAtom->type = elemente->FindElement(1);
    295                         FirstOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
    296                         FirstOtherAtom->FixedIon = TopReplacement->FixedIon;
    297                         SecondOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
    298                         SecondOtherAtom->FixedIon = TopReplacement->FixedIon;
    299                         FirstOtherAtom->father = NULL;  // we are just an added hydrogen with no father
    300                         SecondOtherAtom->father = NULL; //      we are just an added hydrogen with no father
    301                         bondangle = TopOrigin->type->HBondAngle[1];
    302                         if (bondangle == -1) {
    303                                 *out << Verbose(3) << "ERROR: There is no typical hydrogen bond angle in replacing bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") of degree " << TopBond->BondDegree << "!" << endl;
    304                                 return false;
    305                                 bondangle = 0;
    306                         }
    307                         bondangle *= M_PI/180./2.;
    308 //                      *out << Verbose(3) << "ReScaleCheck: InBondvector ";
    309 //                      InBondvector.Output(out);
    310 //                      *out << endl;
    311 //                      *out << Verbose(3) << "ReScaleCheck: Orthovector ";
    312 //                      Orthovector1.Output(out);
    313 //                      *out << endl;
    314 //                      *out << Verbose(3) << "Half the bond angle is " << bondangle << ", sin and cos of it: " << sin(bondangle) << ", " << cos(bondangle) << endl;
    315                         FirstOtherAtom->x.Zero();
    316                         SecondOtherAtom->x.Zero();
    317                         for(int i=NDIM;i--;) { // rotate by half the bond angle in both directions (InBondvector is bondangle = 0 direction)
    318                                 FirstOtherAtom->x.x[i] = InBondvector.x[i] * cos(bondangle) + Orthovector1.x[i] * (sin(bondangle));
    319                                 SecondOtherAtom->x.x[i] = InBondvector.x[i] * cos(bondangle) + Orthovector1.x[i] * (-sin(bondangle));
    320                         }
    321                         FirstOtherAtom->x.Scale(&BondRescale);  // rescale by correct BondDistance
    322                         SecondOtherAtom->x.Scale(&BondRescale);
    323                         //*out << Verbose(3) << "ReScaleCheck: " << FirstOtherAtom->x.Norm() << " and " << SecondOtherAtom->x.Norm() << "." << endl;
    324                         for(int i=NDIM;i--;) { // and make relative to origin atom
    325                                 FirstOtherAtom->x.x[i] += TopOrigin->x.x[i];
    326                                 SecondOtherAtom->x.x[i] += TopOrigin->x.x[i];
    327                         }
    328                         // ... and add to molecule
    329                         AllWentWell = AllWentWell && AddAtom(FirstOtherAtom);
    330                         AllWentWell = AllWentWell && AddAtom(SecondOtherAtom);
    331 //                      *out << Verbose(4) << "Added " << *FirstOtherAtom << " at: ";
    332 //                      FirstOtherAtom->x.Output(out);
    333 //                      *out << endl;
    334 //                      *out << Verbose(4) << "Added " << *SecondOtherAtom << " at: ";
    335 //                      SecondOtherAtom->x.Output(out);
    336 //                      *out << endl;
    337                         Binder = AddBond(BottomOrigin, FirstOtherAtom, 1);
    338                         Binder->Cyclic = false;
    339                         Binder->Type = TreeEdge;
    340                         Binder = AddBond(BottomOrigin, SecondOtherAtom, 1);
    341                         Binder->Cyclic = false;
    342                         Binder->Type = TreeEdge;
    343                         break;
    344                 case 3:
    345                         // take the "usual" tetraoidal angle and add the three Hydrogen in direction of the bond (height of the tetraoid)
    346                         FirstOtherAtom = new atom();
    347                         SecondOtherAtom = new atom();
    348                         ThirdOtherAtom = new atom();
    349                         FirstOtherAtom->type = elemente->FindElement(1);
    350                         SecondOtherAtom->type = elemente->FindElement(1);
    351                         ThirdOtherAtom->type = elemente->FindElement(1);
    352                         FirstOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
    353                         FirstOtherAtom->FixedIon = TopReplacement->FixedIon;
    354                         SecondOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
    355                         SecondOtherAtom->FixedIon = TopReplacement->FixedIon;
    356                         ThirdOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
    357                         ThirdOtherAtom->FixedIon = TopReplacement->FixedIon;
    358                         FirstOtherAtom->father = NULL;  //      we are just an added hydrogen with no father
    359                         SecondOtherAtom->father = NULL; //      we are just an added hydrogen with no father
    360                         ThirdOtherAtom->father = NULL;  //      we are just an added hydrogen with no father
    361 
    362                         // we need to vectors orthonormal the InBondvector
    363                         AllWentWell = AllWentWell && Orthovector1.GetOneNormalVector(&InBondvector);
    364 //                      *out << Verbose(3) << "Orthovector1: ";
    365 //                      Orthovector1.Output(out);
    366 //                      *out << endl;
    367                         AllWentWell = AllWentWell && Orthovector2.MakeNormalVector(&InBondvector, &Orthovector1);
    368 //                      *out << Verbose(3) << "Orthovector2: ";
    369 //                      Orthovector2.Output(out);
    370 //                      *out << endl;
    371 
    372                         // create correct coordination for the three atoms
    373                         alpha = (TopOrigin->type->HBondAngle[2])/180.*M_PI/2.;  // retrieve triple bond angle from database
    374                         l = BondRescale;                                // desired bond length
    375                         b = 2.*l*sin(alpha);            // base length of isosceles triangle
    376                         d = l*sqrt(cos(alpha)*cos(alpha) - sin(alpha)*sin(alpha)/3.);    // length for InBondvector
    377                         f = b/sqrt(3.); // length for Orthvector1
    378                         g = b/2.;                                // length for Orthvector2
    379 //                      *out << Verbose(3) << "Bond length and half-angle: " << l << ", " << alpha << "\t (b,d,f,g) = " << b << ", " << d << ", " << f << ", " << g << ", " << endl;
    380 //                      *out << Verbose(3) << "The three Bond lengths: " << sqrt(d*d+f*f) << ", " << sqrt(d*d+(-0.5*f)*(-0.5*f)+g*g) << ", "    << sqrt(d*d+(-0.5*f)*(-0.5*f)+g*g) << endl;
    381                         factors[0] = d;
    382                         factors[1] = f;
    383                         factors[2] = 0.;
    384                         FirstOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
    385                         factors[1] = -0.5*f;
    386                         factors[2] = g;
    387                         SecondOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
    388                         factors[2] = -g;
    389                         ThirdOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
    390 
    391                         // rescale each to correct BondDistance
    392 //                      FirstOtherAtom->x.Scale(&BondRescale);
    393 //                      SecondOtherAtom->x.Scale(&BondRescale);
    394 //                      ThirdOtherAtom->x.Scale(&BondRescale);
    395 
    396                         // and relative to *origin atom
    397                         FirstOtherAtom->x.AddVector(&TopOrigin->x);
    398                         SecondOtherAtom->x.AddVector(&TopOrigin->x);
    399                         ThirdOtherAtom->x.AddVector(&TopOrigin->x);
    400 
    401                         // ... and add to molecule
    402                         AllWentWell = AllWentWell && AddAtom(FirstOtherAtom);
    403                         AllWentWell = AllWentWell && AddAtom(SecondOtherAtom);
    404                         AllWentWell = AllWentWell && AddAtom(ThirdOtherAtom);
    405 //                      *out << Verbose(4) << "Added " << *FirstOtherAtom << " at: ";
    406 //                      FirstOtherAtom->x.Output(out);
    407 //                      *out << endl;
    408 //                      *out << Verbose(4) << "Added " << *SecondOtherAtom << " at: ";
    409 //                      SecondOtherAtom->x.Output(out);
    410 //                      *out << endl;
    411 //                      *out << Verbose(4) << "Added " << *ThirdOtherAtom << " at: ";
    412 //                      ThirdOtherAtom->x.Output(out);
    413 //                      *out << endl;
    414                         Binder = AddBond(BottomOrigin, FirstOtherAtom, 1);
    415                         Binder->Cyclic = false;
    416                         Binder->Type = TreeEdge;
    417                         Binder = AddBond(BottomOrigin, SecondOtherAtom, 1);
    418                         Binder->Cyclic = false;
    419                         Binder->Type = TreeEdge;
    420                         Binder = AddBond(BottomOrigin, ThirdOtherAtom, 1);
    421                         Binder->Cyclic = false;
    422                         Binder->Type = TreeEdge;
    423                         break;
    424                 default:
    425                         cerr << "ERROR: BondDegree does not state single, double or triple bond!" << endl;
    426                         AllWentWell = false;
    427                         break;
    428         }
    429 
    430 //      *out << Verbose(3) << "End of AddHydrogenReplacementAtom." << endl;
    431         return AllWentWell;
     177  double bondlength;  // bond length of the bond to be replaced/cut
     178  double bondangle;  // bond angle of the bond to be replaced/cut
     179  double BondRescale;  // rescale value for the hydrogen bond length
     180  bool AllWentWell = true;    // flag gathering the boolean return value of molecule::AddAtom and other functions, as return value on exit
     181  bond *FirstBond = NULL, *SecondBond = NULL; // Other bonds in double bond case to determine "other" plane
     182  atom *FirstOtherAtom = NULL, *SecondOtherAtom = NULL, *ThirdOtherAtom = NULL; // pointer to hydrogen atoms to be added
     183  double b,l,d,f,g, alpha, factors[NDIM];    // hold temporary values in triple bond case for coordination determination
     184  Vector Orthovector1, Orthovector2;  // temporary vectors in coordination construction
     185  Vector InBondvector;    // vector in direction of *Bond
     186  bond *Binder = NULL;
     187  double *matrix;
     188
     189//  *out << Verbose(3) << "Begin of AddHydrogenReplacementAtom." << endl;
     190  // create vector in direction of bond
     191  InBondvector.CopyVector(&TopReplacement->x);
     192  InBondvector.SubtractVector(&TopOrigin->x);
     193  bondlength = InBondvector.Norm();
     194
     195  // is greater than typical bond distance? Then we have to correct periodically
     196  // the problem is not the H being out of the box, but InBondvector have the wrong direction
     197  // due to TopReplacement or Origin being on the wrong side!
     198  if (bondlength > BondDistance) {
     199//    *out << Verbose(4) << "InBondvector is: ";
     200//    InBondvector.Output(out);
     201//    *out << endl;
     202    Orthovector1.Zero();
     203    for (int i=NDIM;i--;) {
     204      l = TopReplacement->x.x[i] - TopOrigin->x.x[i];
     205      if (fabs(l) > BondDistance) { // is component greater than bond distance
     206        Orthovector1.x[i] = (l < 0) ? -1. : +1.;
     207      } // (signs are correct, was tested!)
     208    }
     209    matrix = ReturnFullMatrixforSymmetric(cell_size);
     210    Orthovector1.MatrixMultiplication(matrix);
     211    InBondvector.SubtractVector(&Orthovector1); // subtract just the additional translation
     212    Free((void **)&matrix, "molecule::AddHydrogenReplacementAtom: *matrix");
     213    bondlength = InBondvector.Norm();
     214//    *out << Verbose(4) << "Corrected InBondvector is now: ";
     215//    InBondvector.Output(out);
     216//    *out << endl;
     217  } // periodic correction finished
     218
     219  InBondvector.Normalize();
     220  // get typical bond length and store as scale factor for later
     221  BondRescale = TopOrigin->type->HBondDistance[TopBond->BondDegree-1];
     222  if (BondRescale == -1) {
     223    cerr << Verbose(3) << "ERROR: There is no typical hydrogen bond distance in replacing bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") of degree " << TopBond->BondDegree << "!" << endl;
     224    return false;
     225    BondRescale = bondlength;
     226  } else {
     227    if (!IsAngstroem)
     228      BondRescale /= (1.*AtomicLengthToAngstroem);
     229  }
     230
     231  // discern single, double and triple bonds
     232  switch(TopBond->BondDegree) {
     233    case 1:
     234      FirstOtherAtom = new atom();    // new atom
     235      FirstOtherAtom->type = elemente->FindElement(1);  // element is Hydrogen
     236      FirstOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
     237      FirstOtherAtom->FixedIon = TopReplacement->FixedIon;
     238      if (TopReplacement->type->Z == 1) { // neither rescale nor replace if it's already hydrogen
     239        FirstOtherAtom->father = TopReplacement;
     240        BondRescale = bondlength;
     241      } else {
     242        FirstOtherAtom->father = NULL;  // if we replace hydrogen, we mark it as our father, otherwise we are just an added hydrogen with no father
     243      }
     244      InBondvector.Scale(&BondRescale);  // rescale the distance vector to Hydrogen bond length
     245      FirstOtherAtom->x.CopyVector(&TopOrigin->x); // set coordination to origin ...
     246      FirstOtherAtom->x.AddVector(&InBondvector);  // ... and add distance vector to replacement atom
     247      AllWentWell = AllWentWell && AddAtom(FirstOtherAtom);
     248//      *out << Verbose(4) << "Added " << *FirstOtherAtom << " at: ";
     249//      FirstOtherAtom->x.Output(out);
     250//      *out << endl;
     251      Binder = AddBond(BottomOrigin, FirstOtherAtom, 1);
     252      Binder->Cyclic = false;
     253      Binder->Type = TreeEdge;
     254      break;
     255    case 2:
     256      // determine two other bonds (warning if there are more than two other) plus valence sanity check
     257      for (int i=0;i<NumBond;i++) {
     258        if (BondList[i] != TopBond) {
     259          if (FirstBond == NULL) {
     260            FirstBond = BondList[i];
     261            FirstOtherAtom = BondList[i]->GetOtherAtom(TopOrigin);
     262          } else if (SecondBond == NULL) {
     263            SecondBond = BondList[i];
     264            SecondOtherAtom = BondList[i]->GetOtherAtom(TopOrigin);
     265          } else {
     266            *out << Verbose(3) << "WARNING: Detected more than four bonds for atom " << TopOrigin->Name;
     267          }
     268        }
     269      }
     270      if (SecondOtherAtom == NULL) {  // then we have an atom with valence four, but only 3 bonds: one to replace and one which is TopBond (third is FirstBond)
     271        SecondBond = TopBond;
     272        SecondOtherAtom = TopReplacement;
     273      }
     274      if (FirstOtherAtom != NULL) { // then we just have this double bond and the plane does not matter at all
     275//        *out << Verbose(3) << "Regarding the double bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") to be constructed: Taking " << FirstOtherAtom->Name << " and " << SecondOtherAtom->Name << " along with " << TopOrigin->Name << " to determine orthogonal plane." << endl;
     276
     277        // determine the plane of these two with the *origin
     278        AllWentWell = AllWentWell && Orthovector1.MakeNormalVector(&TopOrigin->x, &FirstOtherAtom->x, &SecondOtherAtom->x);
     279      } else {
     280        Orthovector1.GetOneNormalVector(&InBondvector);
     281      }
     282      //*out << Verbose(3)<< "Orthovector1: ";
     283      //Orthovector1.Output(out);
     284      //*out << endl;
     285      // orthogonal vector and bond vector between origin and replacement form the new plane
     286      Orthovector1.MakeNormalVector(&InBondvector);
     287      Orthovector1.Normalize();
     288      //*out << Verbose(3) << "ReScaleCheck: " << Orthovector1.Norm() << " and " << InBondvector.Norm() << "." << endl;
     289
     290      // create the two Hydrogens ...
     291      FirstOtherAtom = new atom();
     292      SecondOtherAtom = new atom();
     293      FirstOtherAtom->type = elemente->FindElement(1);
     294      SecondOtherAtom->type = elemente->FindElement(1);
     295      FirstOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
     296      FirstOtherAtom->FixedIon = TopReplacement->FixedIon;
     297      SecondOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
     298      SecondOtherAtom->FixedIon = TopReplacement->FixedIon;
     299      FirstOtherAtom->father = NULL;  // we are just an added hydrogen with no father
     300      SecondOtherAtom->father = NULL;  //  we are just an added hydrogen with no father
     301      bondangle = TopOrigin->type->HBondAngle[1];
     302      if (bondangle == -1) {
     303        *out << Verbose(3) << "ERROR: There is no typical hydrogen bond angle in replacing bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") of degree " << TopBond->BondDegree << "!" << endl;
     304        return false;
     305        bondangle = 0;
     306      }
     307      bondangle *= M_PI/180./2.;
     308//      *out << Verbose(3) << "ReScaleCheck: InBondvector ";
     309//      InBondvector.Output(out);
     310//      *out << endl;
     311//      *out << Verbose(3) << "ReScaleCheck: Orthovector ";
     312//      Orthovector1.Output(out);
     313//      *out << endl;
     314//      *out << Verbose(3) << "Half the bond angle is " << bondangle << ", sin and cos of it: " << sin(bondangle) << ", " << cos(bondangle) << endl;
     315      FirstOtherAtom->x.Zero();
     316      SecondOtherAtom->x.Zero();
     317      for(int i=NDIM;i--;) { // rotate by half the bond angle in both directions (InBondvector is bondangle = 0 direction)
     318        FirstOtherAtom->x.x[i] = InBondvector.x[i] * cos(bondangle) + Orthovector1.x[i] * (sin(bondangle));
     319        SecondOtherAtom->x.x[i] = InBondvector.x[i] * cos(bondangle) + Orthovector1.x[i] * (-sin(bondangle));
     320      }
     321      FirstOtherAtom->x.Scale(&BondRescale);  // rescale by correct BondDistance
     322      SecondOtherAtom->x.Scale(&BondRescale);
     323      //*out << Verbose(3) << "ReScaleCheck: " << FirstOtherAtom->x.Norm() << " and " << SecondOtherAtom->x.Norm() << "." << endl;
     324      for(int i=NDIM;i--;) { // and make relative to origin atom
     325        FirstOtherAtom->x.x[i] += TopOrigin->x.x[i];
     326        SecondOtherAtom->x.x[i] += TopOrigin->x.x[i];
     327      }
     328      // ... and add to molecule
     329      AllWentWell = AllWentWell && AddAtom(FirstOtherAtom);
     330      AllWentWell = AllWentWell && AddAtom(SecondOtherAtom);
     331//      *out << Verbose(4) << "Added " << *FirstOtherAtom << " at: ";
     332//      FirstOtherAtom->x.Output(out);
     333//      *out << endl;
     334//      *out << Verbose(4) << "Added " << *SecondOtherAtom << " at: ";
     335//      SecondOtherAtom->x.Output(out);
     336//      *out << endl;
     337      Binder = AddBond(BottomOrigin, FirstOtherAtom, 1);
     338      Binder->Cyclic = false;
     339      Binder->Type = TreeEdge;
     340      Binder = AddBond(BottomOrigin, SecondOtherAtom, 1);
     341      Binder->Cyclic = false;
     342      Binder->Type = TreeEdge;
     343      break;
     344    case 3:
     345      // take the "usual" tetraoidal angle and add the three Hydrogen in direction of the bond (height of the tetraoid)
     346      FirstOtherAtom = new atom();
     347      SecondOtherAtom = new atom();
     348      ThirdOtherAtom = new atom();
     349      FirstOtherAtom->type = elemente->FindElement(1);
     350      SecondOtherAtom->type = elemente->FindElement(1);
     351      ThirdOtherAtom->type = elemente->FindElement(1);
     352      FirstOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
     353      FirstOtherAtom->FixedIon = TopReplacement->FixedIon;
     354      SecondOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
     355      SecondOtherAtom->FixedIon = TopReplacement->FixedIon;
     356      ThirdOtherAtom->v.CopyVector(&TopReplacement->v); // copy velocity
     357      ThirdOtherAtom->FixedIon = TopReplacement->FixedIon;
     358      FirstOtherAtom->father = NULL;  //  we are just an added hydrogen with no father
     359      SecondOtherAtom->father = NULL;  //  we are just an added hydrogen with no father
     360      ThirdOtherAtom->father = NULL;  //  we are just an added hydrogen with no father
     361
     362      // we need to vectors orthonormal the InBondvector
     363      AllWentWell = AllWentWell && Orthovector1.GetOneNormalVector(&InBondvector);
     364//      *out << Verbose(3) << "Orthovector1: ";
     365//      Orthovector1.Output(out);
     366//      *out << endl;
     367      AllWentWell = AllWentWell && Orthovector2.MakeNormalVector(&InBondvector, &Orthovector1);
     368//      *out << Verbose(3) << "Orthovector2: ";
     369//      Orthovector2.Output(out);
     370//      *out << endl;
     371
     372      // create correct coordination for the three atoms
     373      alpha = (TopOrigin->type->HBondAngle[2])/180.*M_PI/2.;  // retrieve triple bond angle from database
     374      l = BondRescale;        // desired bond length
     375      b = 2.*l*sin(alpha);    // base length of isosceles triangle
     376      d = l*sqrt(cos(alpha)*cos(alpha) - sin(alpha)*sin(alpha)/3.);  // length for InBondvector
     377      f = b/sqrt(3.);  // length for Orthvector1
     378      g = b/2.;        // length for Orthvector2
     379//      *out << Verbose(3) << "Bond length and half-angle: " << l << ", " << alpha << "\t (b,d,f,g) = " << b << ", " << d << ", " << f << ", " << g << ", " << endl;
     380//      *out << Verbose(3) << "The three Bond lengths: " << sqrt(d*d+f*f) << ", " << sqrt(d*d+(-0.5*f)*(-0.5*f)+g*g) << ", "  << sqrt(d*d+(-0.5*f)*(-0.5*f)+g*g) << endl;
     381      factors[0] = d;
     382      factors[1] = f;
     383      factors[2] = 0.;
     384      FirstOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
     385      factors[1] = -0.5*f;
     386      factors[2] = g;
     387      SecondOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
     388      factors[2] = -g;
     389      ThirdOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
     390
     391      // rescale each to correct BondDistance
     392//      FirstOtherAtom->x.Scale(&BondRescale);
     393//      SecondOtherAtom->x.Scale(&BondRescale);
     394//      ThirdOtherAtom->x.Scale(&BondRescale);
     395
     396      // and relative to *origin atom
     397      FirstOtherAtom->x.AddVector(&TopOrigin->x);
     398      SecondOtherAtom->x.AddVector(&TopOrigin->x);
     399      ThirdOtherAtom->x.AddVector(&TopOrigin->x);
     400
     401      // ... and add to molecule
     402      AllWentWell = AllWentWell && AddAtom(FirstOtherAtom);
     403      AllWentWell = AllWentWell && AddAtom(SecondOtherAtom);
     404      AllWentWell = AllWentWell && AddAtom(ThirdOtherAtom);
     405//      *out << Verbose(4) << "Added " << *FirstOtherAtom << " at: ";
     406//      FirstOtherAtom->x.Output(out);
     407//      *out << endl;
     408//      *out << Verbose(4) << "Added " << *SecondOtherAtom << " at: ";
     409//      SecondOtherAtom->x.Output(out);
     410//      *out << endl;
     411//      *out << Verbose(4) << "Added " << *ThirdOtherAtom << " at: ";
     412//      ThirdOtherAtom->x.Output(out);
     413//      *out << endl;
     414      Binder = AddBond(BottomOrigin, FirstOtherAtom, 1);
     415      Binder->Cyclic = false;
     416      Binder->Type = TreeEdge;
     417      Binder = AddBond(BottomOrigin, SecondOtherAtom, 1);
     418      Binder->Cyclic = false;
     419      Binder->Type = TreeEdge;
     420      Binder = AddBond(BottomOrigin, ThirdOtherAtom, 1);
     421      Binder->Cyclic = false;
     422      Binder->Type = TreeEdge;
     423      break;
     424    default:
     425      cerr << "ERROR: BondDegree does not state single, double or triple bond!" << endl;
     426      AllWentWell = false;
     427      break;
     428  }
     429
     430//  *out << Verbose(3) << "End of AddHydrogenReplacementAtom." << endl;
     431  return AllWentWell;
    432432};
    433433
     
    439439bool molecule::AddXYZFile(string filename)
    440440{
    441         istringstream *input = NULL;
    442         int NumberOfAtoms = 0; // atom number in xyz read
    443         int i, j; // loop variables
    444         atom *Walker = NULL;    // pointer to added atom
    445         char shorthand[3];      // shorthand for atom name
    446         ifstream xyzfile;        // xyz file
    447         string line;            // currently parsed line
    448         double x[3];            // atom coordinates
    449 
    450         xyzfile.open(filename.c_str());
    451         if (!xyzfile)
    452                 return false;
    453 
    454         getline(xyzfile,line,'\n'); // Read numer of atoms in file
    455         input = new istringstream(line);
    456         *input >> NumberOfAtoms;
    457         cout << Verbose(0) << "Parsing " << NumberOfAtoms << " atoms in file." << endl;
    458         getline(xyzfile,line,'\n'); // Read comment
    459         cout << Verbose(1) << "Comment: " << line << endl;
    460 
    461         if (MDSteps == 0) // no atoms yet present
    462                 MDSteps++;
    463         for(i=0;i<NumberOfAtoms;i++){
    464                 Walker = new atom;
    465                 getline(xyzfile,line,'\n');
    466                 istringstream *item = new istringstream(line);
    467                 //istringstream input(line);
    468                 //cout << Verbose(1) << "Reading: " << line << endl;
    469                 *item >> shorthand;
    470                 *item >> x[0];
    471                 *item >> x[1];
    472                 *item >> x[2];
    473                 Walker->type = elemente->FindElement(shorthand);
    474                 if (Walker->type == NULL) {
    475                         cerr << "Could not parse the element at line: '" << line << "', setting to H.";
    476                         Walker->type = elemente->FindElement(1);
    477                 }
    478                 if (Trajectories[Walker].R.size() <= (unsigned int)MDSteps) {
    479                         Trajectories[Walker].R.resize(MDSteps+10);
    480                         Trajectories[Walker].U.resize(MDSteps+10);
    481                         Trajectories[Walker].F.resize(MDSteps+10);
    482                 }
    483                 for(j=NDIM;j--;) {
    484                         Walker->x.x[j] = x[j];
    485                         Trajectories[Walker].R.at(MDSteps-1).x[j] = x[j];
    486                         Trajectories[Walker].U.at(MDSteps-1).x[j] = 0;
    487                         Trajectories[Walker].F.at(MDSteps-1).x[j] = 0;
    488                 }
    489                 AddAtom(Walker);        // add to molecule
    490                 delete(item);
    491         }
    492         xyzfile.close();
    493         delete(input);
    494         return true;
     441  istringstream *input = NULL;
     442  int NumberOfAtoms = 0; // atom number in xyz read
     443  int i, j; // loop variables
     444  atom *Walker = NULL;  // pointer to added atom
     445  char shorthand[3];  // shorthand for atom name
     446  ifstream xyzfile;  // xyz file
     447  string line;    // currently parsed line
     448  double x[3];    // atom coordinates
     449
     450  xyzfile.open(filename.c_str());
     451  if (!xyzfile)
     452    return false;
     453
     454  getline(xyzfile,line,'\n'); // Read numer of atoms in file
     455  input = new istringstream(line);
     456  *input >> NumberOfAtoms;
     457  cout << Verbose(0) << "Parsing " << NumberOfAtoms << " atoms in file." << endl;
     458  getline(xyzfile,line,'\n'); // Read comment
     459  cout << Verbose(1) << "Comment: " << line << endl;
     460
     461  if (MDSteps == 0) // no atoms yet present
     462    MDSteps++;
     463  for(i=0;i<NumberOfAtoms;i++){
     464    Walker = new atom;
     465    getline(xyzfile,line,'\n');
     466    istringstream *item = new istringstream(line);
     467    //istringstream input(line);
     468    //cout << Verbose(1) << "Reading: " << line << endl;
     469    *item >> shorthand;
     470    *item >> x[0];
     471    *item >> x[1];
     472    *item >> x[2];
     473    Walker->type = elemente->FindElement(shorthand);
     474    if (Walker->type == NULL) {
     475      cerr << "Could not parse the element at line: '" << line << "', setting to H.";
     476      Walker->type = elemente->FindElement(1);
     477    }
     478    if (Trajectories[Walker].R.size() <= (unsigned int)MDSteps) {
     479      Trajectories[Walker].R.resize(MDSteps+10);
     480      Trajectories[Walker].U.resize(MDSteps+10);
     481      Trajectories[Walker].F.resize(MDSteps+10);
     482    }
     483    for(j=NDIM;j--;) {
     484      Walker->x.x[j] = x[j];
     485      Trajectories[Walker].R.at(MDSteps-1).x[j] = x[j];
     486      Trajectories[Walker].U.at(MDSteps-1).x[j] = 0;
     487      Trajectories[Walker].F.at(MDSteps-1).x[j] = 0;
     488    }
     489    AddAtom(Walker);  // add to molecule
     490    delete(item);
     491  }
     492  xyzfile.close();
     493  delete(input);
     494  return true;
    495495};
    496496
     
    500500molecule *molecule::CopyMolecule()
    501501{
    502         molecule *copy = new molecule(elemente);
    503         atom *CurrentAtom = NULL;
    504         atom *LeftAtom = NULL, *RightAtom = NULL;
    505         atom *Walker = NULL;
    506 
    507         // copy all atoms
    508         Walker = start;
    509         while(Walker->next != end) {
    510                 Walker = Walker->next;
    511                 CurrentAtom = copy->AddCopyAtom(Walker);
    512         }
    513 
    514         // copy all bonds
    515         bond *Binder = first;
    516         bond *NewBond = NULL;
    517         while(Binder->next != last) {
    518                 Binder = Binder->next;
    519                 // get the pendant atoms of current bond in the copy molecule
    520                 LeftAtom = copy->start;
    521                 while (LeftAtom->next != copy->end) {
    522                         LeftAtom = LeftAtom->next;
    523                         if (LeftAtom->father == Binder->leftatom)
    524                                 break;
    525                 }
    526                 RightAtom = copy->start;
    527                 while (RightAtom->next != copy->end) {
    528                         RightAtom = RightAtom->next;
    529                         if (RightAtom->father == Binder->rightatom)
    530                                 break;
    531                 }
    532                 NewBond = copy->AddBond(LeftAtom, RightAtom, Binder->BondDegree);
    533                 NewBond->Cyclic = Binder->Cyclic;
    534                 if (Binder->Cyclic)
    535                         copy->NoCyclicBonds++;
    536                 NewBond->Type = Binder->Type;
    537         }
    538         // correct fathers
    539         Walker = copy->start;
    540         while(Walker->next != copy->end) {
    541                 Walker = Walker->next;
    542                 if (Walker->father->father == Walker->father)    // same atom in copy's father points to itself
    543                         Walker->father = Walker;        // set father to itself (copy of a whole molecule)
    544                 else
    545                  Walker->father = Walker->father->father;       // set father to original's father
    546         }
    547         // copy values
    548         copy->CountAtoms((ofstream *)&cout);
    549         copy->CountElements();
    550         if (first->next != last) {      // if adjaceny list is present
    551                 copy->BondDistance = BondDistance;
    552                 copy->CreateListOfBondsPerAtom((ofstream *)&cout);
    553         }
    554 
    555         return copy;
     502  molecule *copy = new molecule(elemente);
     503  atom *CurrentAtom = NULL;
     504  atom *LeftAtom = NULL, *RightAtom = NULL;
     505  atom *Walker = NULL;
     506
     507  // copy all atoms
     508  Walker = start;
     509  while(Walker->next != end) {
     510    Walker = Walker->next;
     511    CurrentAtom = copy->AddCopyAtom(Walker);
     512  }
     513
     514  // copy all bonds
     515  bond *Binder = first;
     516  bond *NewBond = NULL;
     517  while(Binder->next != last) {
     518    Binder = Binder->next;
     519    // get the pendant atoms of current bond in the copy molecule
     520    LeftAtom = copy->start;
     521    while (LeftAtom->next != copy->end) {
     522      LeftAtom = LeftAtom->next;
     523      if (LeftAtom->father == Binder->leftatom)
     524        break;
     525    }
     526    RightAtom = copy->start;
     527    while (RightAtom->next != copy->end) {
     528      RightAtom = RightAtom->next;
     529      if (RightAtom->father == Binder->rightatom)
     530        break;
     531    }
     532    NewBond = copy->AddBond(LeftAtom, RightAtom, Binder->BondDegree);
     533    NewBond->Cyclic = Binder->Cyclic;
     534    if (Binder->Cyclic)
     535      copy->NoCyclicBonds++;
     536    NewBond->Type = Binder->Type;
     537  }
     538  // correct fathers
     539  Walker = copy->start;
     540  while(Walker->next != copy->end) {
     541    Walker = Walker->next;
     542    if (Walker->father->father == Walker->father)  // same atom in copy's father points to itself
     543      Walker->father = Walker;  // set father to itself (copy of a whole molecule)
     544    else
     545     Walker->father = Walker->father->father;  // set father to original's father
     546  }
     547  // copy values
     548  copy->CountAtoms((ofstream *)&cout);
     549  copy->CountElements();
     550  if (first->next != last) {  // if adjaceny list is present
     551    copy->BondDistance = BondDistance;
     552    copy->CreateListOfBondsPerAtom((ofstream *)&cout);
     553  }
     554
     555  return copy;
    556556};
    557557
     
    564564bond * molecule::AddBond(atom *atom1, atom *atom2, int degree=1)
    565565{
    566         bond *Binder = NULL;
    567         if ((atom1 != NULL) && (FindAtom(atom1->nr) != NULL) && (atom2 != NULL) && (FindAtom(atom2->nr) != NULL)) {
    568                 Binder = new bond(atom1, atom2, degree, BondCount++);
    569                 if ((atom1->type != NULL) && (atom1->type->Z != 1) && (atom2->type != NULL) && (atom2->type->Z != 1))
    570                         NoNonBonds++;
    571                 add(Binder, last);
    572         } else {
    573                 cerr << Verbose(1) << "ERROR: Could not add bond between " << atom1->Name << " and " << atom2->Name << " as one or both are not present in the molecule." << endl;
    574         }
    575         return Binder;
     566  bond *Binder = NULL;
     567  if ((atom1 != NULL) && (FindAtom(atom1->nr) != NULL) && (atom2 != NULL) && (FindAtom(atom2->nr) != NULL)) {
     568    Binder = new bond(atom1, atom2, degree, BondCount++);
     569    if ((atom1->type != NULL) && (atom1->type->Z != 1) && (atom2->type != NULL) && (atom2->type->Z != 1))
     570      NoNonBonds++;
     571    add(Binder, last);
     572  } else {
     573    cerr << Verbose(1) << "ERROR: Could not add bond between " << atom1->Name << " and " << atom2->Name << " as one or both are not present in the molecule." << endl;
     574  }
     575  return Binder;
    576576};
    577577
     
    583583bool molecule::RemoveBond(bond *pointer)
    584584{
    585         //cerr << Verbose(1) << "molecule::RemoveBond: Function not implemented yet." << endl;
    586         removewithoutcheck(pointer);
    587         return true;
     585  //cerr << Verbose(1) << "molecule::RemoveBond: Function not implemented yet." << endl;
     586  removewithoutcheck(pointer);
     587  return true;
    588588};
    589589
     
    595595bool molecule::RemoveBonds(atom *BondPartner)
    596596{
    597         cerr << Verbose(1) << "molecule::RemoveBond: Function not implemented yet." << endl;
    598         return false;
     597  cerr << Verbose(1) << "molecule::RemoveBond: Function not implemented yet." << endl;
     598  return false;
    599599};
    600600
     
    619619void molecule::SetBoxDimension(Vector *dim)
    620620{
    621         cell_size[0] = dim->x[0];
    622         cell_size[1] = 0.;
    623         cell_size[2] = dim->x[1];
    624         cell_size[3] = 0.;
    625         cell_size[4] = 0.;
    626         cell_size[5] = dim->x[2];
     621  cell_size[0] = dim->x[0];
     622  cell_size[1] = 0.;
     623  cell_size[2] = dim->x[1];
     624  cell_size[3] = 0.;
     625  cell_size[4] = 0.;
     626  cell_size[5] = dim->x[2];
    627627};
    628628
     
    632632bool molecule::CenterInBox(ofstream *out)
    633633{
    634         bool status = true;
    635         atom *ptr = NULL;
    636         Vector x;
    637         double *M = ReturnFullMatrixforSymmetric(cell_size);
     634  bool status = true;
     635  atom *ptr = NULL;
     636  Vector x;
     637  double *M = ReturnFullMatrixforSymmetric(cell_size);
    638638  double *Minv = x.InverseMatrix(M);
    639         double value;
    640 
    641 //      cout << "The box matrix is :" << endl;
     639  double value;
     640
     641//  cout << "The box matrix is :" << endl;
    642642//  for (int i=0;i<NDIM;++i) {
    643643//    for (int j=0;j<NDIM;++j)
     
    651651//    cout << endl;
    652652//  }
    653         // go through all atoms
     653  // go through all atoms
    654654  ptr = start->next;  // start at first in list
    655655  if (ptr != end) {  //list not empty?
     
    676676  delete(M);
    677677  delete(Minv);
    678         return status;
     678  return status;
    679679};
    680680
     
    685685void molecule::CenterEdge(ofstream *out, Vector *max)
    686686{
    687         Vector *min = new Vector;
    688 
    689 //      *out << Verbose(3) << "Begin of CenterEdge." << endl;
    690         atom *ptr = start->next;        // start at first in list
    691         if (ptr != end) {        //list not empty?
    692                 for (int i=NDIM;i--;) {
    693                         max->x[i] = ptr->x.x[i];
    694                         min->x[i] = ptr->x.x[i];
    695                 }
    696                 while (ptr->next != end) {      // continue with second if present
    697                         ptr = ptr->next;
    698                         //ptr->Output(1,1,out);
    699                         for (int i=NDIM;i--;) {
    700                                 max->x[i] = (max->x[i] < ptr->x.x[i]) ? ptr->x.x[i] : max->x[i];
    701                                 min->x[i] = (min->x[i] > ptr->x.x[i]) ? ptr->x.x[i] : min->x[i];
    702                         }
    703                 }
    704 //              *out << Verbose(4) << "Maximum is ";
    705 //              max->Output(out);
    706 //              *out << ", Minimum is ";
    707 //              min->Output(out);
    708 //              *out << endl;
    709                 min->Scale(-1.);
    710                 max->AddVector(min);
    711                 Translate(min);
    712         }
    713         delete(min);
    714 //      *out << Verbose(3) << "End of CenterEdge." << endl;
     687  Vector *min = new Vector;
     688
     689//  *out << Verbose(3) << "Begin of CenterEdge." << endl;
     690  atom *ptr = start->next;  // start at first in list
     691  if (ptr != end) {  //list not empty?
     692    for (int i=NDIM;i--;) {
     693      max->x[i] = ptr->x.x[i];
     694      min->x[i] = ptr->x.x[i];
     695    }
     696    while (ptr->next != end) {  // continue with second if present
     697      ptr = ptr->next;
     698      //ptr->Output(1,1,out);
     699      for (int i=NDIM;i--;) {
     700        max->x[i] = (max->x[i] < ptr->x.x[i]) ? ptr->x.x[i] : max->x[i];
     701        min->x[i] = (min->x[i] > ptr->x.x[i]) ? ptr->x.x[i] : min->x[i];
     702      }
     703    }
     704//    *out << Verbose(4) << "Maximum is ";
     705//    max->Output(out);
     706//    *out << ", Minimum is ";
     707//    min->Output(out);
     708//    *out << endl;
     709    min->Scale(-1.);
     710    max->AddVector(min);
     711    Translate(min);
     712  }
     713  delete(min);
     714//  *out << Verbose(3) << "End of CenterEdge." << endl;
    715715};
    716716
     
    721721void molecule::CenterOrigin(ofstream *out, Vector *center)
    722722{
    723         int Num = 0;
    724         atom *ptr = start->next;        // start at first in list
    725 
    726         for(int i=NDIM;i--;) // zero center vector
    727                 center->x[i] = 0.;
    728 
    729         if (ptr != end) {        //list not empty?
    730                 while (ptr->next != end) {      // continue with second if present
    731                         ptr = ptr->next;
    732                         Num++;
    733                         center->AddVector(&ptr->x);
    734                 }
    735                 center->Scale(-1./Num); // divide through total number (and sign for direction)
    736                 Translate(center);
    737         }
     723  int Num = 0;
     724  atom *ptr = start->next;  // start at first in list
     725
     726  for(int i=NDIM;i--;) // zero center vector
     727    center->x[i] = 0.;
     728
     729  if (ptr != end) {  //list not empty?
     730    while (ptr->next != end) {  // continue with second if present
     731      ptr = ptr->next;
     732      Num++;
     733      center->AddVector(&ptr->x);
     734    }
     735    center->Scale(-1./Num); // divide through total number (and sign for direction)
     736    Translate(center);
     737  }
    738738};
    739739
     
    744744Vector * molecule::DetermineCenterOfAll(ofstream *out)
    745745{
    746         atom *ptr = start->next;        // start at first in list
    747         Vector *a = new Vector();
    748         Vector tmp;
    749         double Num = 0;
    750 
    751         a->Zero();
    752 
    753         if (ptr != end) {        //list not empty?
    754                 while (ptr->next != end) {      // continue with second if present
    755                         ptr = ptr->next;
    756                         Num += 1.;
    757                         tmp.CopyVector(&ptr->x);
    758                         a->AddVector(&tmp);
    759                 }
    760                 a->Scale(-1./Num); // divide through total mass (and sign for direction)
    761         }
    762         //cout << Verbose(1) << "Resulting center of gravity: ";
    763         //a->Output(out);
    764         //cout << endl;
    765         return a;
     746  atom *ptr = start->next;  // start at first in list
     747  Vector *a = new Vector();
     748  Vector tmp;
     749  double Num = 0;
     750
     751  a->Zero();
     752
     753  if (ptr != end) {  //list not empty?
     754    while (ptr->next != end) {  // continue with second if present
     755      ptr = ptr->next;
     756      Num += 1.;
     757      tmp.CopyVector(&ptr->x);
     758      a->AddVector(&tmp);
     759    }
     760    a->Scale(-1./Num); // divide through total mass (and sign for direction)
     761  }
     762  //cout << Verbose(1) << "Resulting center of gravity: ";
     763  //a->Output(out);
     764  //cout << endl;
     765  return a;
    766766};
    767767
     
    772772Vector * molecule::DetermineCenterOfGravity(ofstream *out)
    773773{
    774         atom *ptr = start->next;        // start at first in list
    775         Vector *a = new Vector();
    776         Vector tmp;
    777         double Num = 0;
    778 
    779         a->Zero();
    780 
    781         if (ptr != end) {        //list not empty?
    782                 while (ptr->next != end) {      // continue with second if present
    783                         ptr = ptr->next;
    784                         Num += ptr->type->mass;
    785                         tmp.CopyVector(&ptr->x);
    786                         tmp.Scale(ptr->type->mass);     // scale by mass
    787                         a->AddVector(&tmp);
    788                 }
    789                 a->Scale(-1./Num); // divide through total mass (and sign for direction)
    790         }
    791 //      *out << Verbose(1) << "Resulting center of gravity: ";
    792 //      a->Output(out);
    793 //      *out << endl;
    794         return a;
     774  atom *ptr = start->next;  // start at first in list
     775  Vector *a = new Vector();
     776  Vector tmp;
     777  double Num = 0;
     778
     779  a->Zero();
     780
     781  if (ptr != end) {  //list not empty?
     782    while (ptr->next != end) {  // continue with second if present
     783      ptr = ptr->next;
     784      Num += ptr->type->mass;
     785      tmp.CopyVector(&ptr->x);
     786      tmp.Scale(ptr->type->mass);  // scale by mass
     787      a->AddVector(&tmp);
     788    }
     789    a->Scale(-1./Num); // divide through total mass (and sign for direction)
     790  }
     791//  *out << Verbose(1) << "Resulting center of gravity: ";
     792//  a->Output(out);
     793//  *out << endl;
     794  return a;
    795795};
    796796
     
    801801void molecule::CenterGravity(ofstream *out, Vector *center)
    802802{
    803         if (center == NULL) {
    804                 DetermineCenter(*center);
    805                 Translate(center);
    806                 delete(center);
    807         } else {
    808                 Translate(center);
    809         }
     803  if (center == NULL) {
     804    DetermineCenter(*center);
     805    Translate(center);
     806    delete(center);
     807  } else {
     808    Translate(center);
     809  }
    810810};
    811811
     
    815815void molecule::Scale(double **factor)
    816816{
    817         atom *ptr = start;
    818 
    819         while (ptr->next != end) {
    820                 ptr = ptr->next;
    821                 for (int j=0;j<MDSteps;j++)
    822                         Trajectories[ptr].R.at(j).Scale(factor);
    823                 ptr->x.Scale(factor);
    824         }
     817  atom *ptr = start;
     818
     819  while (ptr->next != end) {
     820    ptr = ptr->next;
     821    for (int j=0;j<MDSteps;j++)
     822      Trajectories[ptr].R.at(j).Scale(factor);
     823    ptr->x.Scale(factor);
     824  }
    825825};
    826826
     
    830830void molecule::Translate(const Vector *trans)
    831831{
    832         atom *ptr = start;
    833 
    834         while (ptr->next != end) {
    835                 ptr = ptr->next;
    836                 for (int j=0;j<MDSteps;j++)
    837                         Trajectories[ptr].R.at(j).Translate(trans);
    838                 ptr->x.Translate(trans);
    839         }
     832  atom *ptr = start;
     833
     834  while (ptr->next != end) {
     835    ptr = ptr->next;
     836    for (int j=0;j<MDSteps;j++)
     837      Trajectories[ptr].R.at(j).Translate(trans);
     838    ptr->x.Translate(trans);
     839  }
    840840};
    841841
     
    900900void molecule::Mirror(const Vector *n)
    901901{
    902         atom *ptr = start;
    903 
    904         while (ptr->next != end) {
    905                 ptr = ptr->next;
    906                 for (int j=0;j<MDSteps;j++)
    907                         Trajectories[ptr].R.at(j).Mirror(n);
    908                 ptr->x.Mirror(n);
    909         }
     902  atom *ptr = start;
     903
     904  while (ptr->next != end) {
     905    ptr = ptr->next;
     906    for (int j=0;j<MDSteps;j++)
     907      Trajectories[ptr].R.at(j).Mirror(n);
     908    ptr->x.Mirror(n);
     909  }
    910910};
    911911
     
    915915void molecule::DetermineCenter(Vector &Center)
    916916{
    917         atom *Walker = start;
    918         bond *Binder = NULL;
    919         double *matrix = ReturnFullMatrixforSymmetric(cell_size);
    920         double tmp;
    921         bool flag;
    922         Vector Testvector, Translationvector;
    923 
    924         do {
    925                 Center.Zero();
    926                 flag = true;
    927                 while (Walker->next != end) {
    928                         Walker = Walker->next;
     917  atom *Walker = start;
     918  bond *Binder = NULL;
     919  double *matrix = ReturnFullMatrixforSymmetric(cell_size);
     920  double tmp;
     921  bool flag;
     922  Vector Testvector, Translationvector;
     923
     924  do {
     925    Center.Zero();
     926    flag = true;
     927    while (Walker->next != end) {
     928      Walker = Walker->next;
    929929#ifdef ADDHYDROGEN
    930                         if (Walker->type->Z != 1) {
     930      if (Walker->type->Z != 1) {
    931931#endif
    932                                 Testvector.CopyVector(&Walker->x);
    933                                 Testvector.InverseMatrixMultiplication(matrix);
    934                                 Translationvector.Zero();
    935                                 for (int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) {
    936                                         Binder = ListOfBondsPerAtom[Walker->nr][i];
    937                                         if (Walker->nr < Binder->GetOtherAtom(Walker)->nr) // otherwise we shift one to, the other fro and gain nothing
    938                                                 for (int j=0;j<NDIM;j++) {
    939                                                         tmp = Walker->x.x[j] - Binder->GetOtherAtom(Walker)->x.x[j];
    940                                                         if ((fabs(tmp)) > BondDistance) {
    941                                                                 flag = false;
    942                                                                 cout << Verbose(0) << "Hit: atom " << Walker->Name << " in bond " << *Binder << " has to be shifted due to " << tmp << "." << endl;
    943                                                                 if (tmp > 0)
    944                                                                         Translationvector.x[j] -= 1.;
    945                                                                 else
    946                                                                         Translationvector.x[j] += 1.;
    947                                                         }
    948                                                 }
    949                                 }
    950                                 Testvector.AddVector(&Translationvector);
    951                                 Testvector.MatrixMultiplication(matrix);
    952                                 Center.AddVector(&Testvector);
    953                                 cout << Verbose(1) << "vector is: ";
    954                                 Testvector.Output((ofstream *)&cout);
    955                                 cout << endl;
     932        Testvector.CopyVector(&Walker->x);
     933        Testvector.InverseMatrixMultiplication(matrix);
     934        Translationvector.Zero();
     935        for (int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) {
     936          Binder = ListOfBondsPerAtom[Walker->nr][i];
     937          if (Walker->nr < Binder->GetOtherAtom(Walker)->nr) // otherwise we shift one to, the other fro and gain nothing
     938            for (int j=0;j<NDIM;j++) {
     939              tmp = Walker->x.x[j] - Binder->GetOtherAtom(Walker)->x.x[j];
     940              if ((fabs(tmp)) > BondDistance) {
     941                flag = false;
     942                cout << Verbose(0) << "Hit: atom " << Walker->Name << " in bond " << *Binder << " has to be shifted due to " << tmp << "." << endl;
     943                if (tmp > 0)
     944                  Translationvector.x[j] -= 1.;
     945                else
     946                  Translationvector.x[j] += 1.;
     947              }
     948            }
     949        }
     950        Testvector.AddVector(&Translationvector);
     951        Testvector.MatrixMultiplication(matrix);
     952        Center.AddVector(&Testvector);
     953        cout << Verbose(1) << "vector is: ";
     954        Testvector.Output((ofstream *)&cout);
     955        cout << endl;
    956956#ifdef ADDHYDROGEN
    957                                 // now also change all hydrogens
    958                                 for (int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) {
    959                                         Binder = ListOfBondsPerAtom[Walker->nr][i];
    960                                         if (Binder->GetOtherAtom(Walker)->type->Z == 1) {
    961                                                 Testvector.CopyVector(&Binder->GetOtherAtom(Walker)->x);
    962                                                 Testvector.InverseMatrixMultiplication(matrix);
    963                                                 Testvector.AddVector(&Translationvector);
    964                                                 Testvector.MatrixMultiplication(matrix);
    965                                                 Center.AddVector(&Testvector);
    966                                                 cout << Verbose(1) << "Hydrogen vector is: ";
    967                                                 Testvector.Output((ofstream *)&cout);
    968                                                 cout << endl;
    969                                         }
    970                                 }
    971                         }
     957        // now also change all hydrogens
     958        for (int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) {
     959          Binder = ListOfBondsPerAtom[Walker->nr][i];
     960          if (Binder->GetOtherAtom(Walker)->type->Z == 1) {
     961            Testvector.CopyVector(&Binder->GetOtherAtom(Walker)->x);
     962            Testvector.InverseMatrixMultiplication(matrix);
     963            Testvector.AddVector(&Translationvector);
     964            Testvector.MatrixMultiplication(matrix);
     965            Center.AddVector(&Testvector);
     966            cout << Verbose(1) << "Hydrogen vector is: ";
     967            Testvector.Output((ofstream *)&cout);
     968            cout << endl;
     969          }
     970        }
     971      }
    972972#endif
    973                 }
    974         } while (!flag);
    975         Free((void **)&matrix, "molecule::DetermineCenter: *matrix");
    976         Center.Scale(1./(double)AtomCount);
     973    }
     974  } while (!flag);
     975  Free((void **)&matrix, "molecule::DetermineCenter: *matrix");
     976  Center.Scale(1./(double)AtomCount);
    977977};
    978978
     
    983983void molecule::PrincipalAxisSystem(ofstream *out, bool DoRotate)
    984984{
    985         atom *ptr = start;      // start at first in list
    986         double InertiaTensor[NDIM*NDIM];
    987         Vector *CenterOfGravity = DetermineCenterOfGravity(out);
    988 
    989         CenterGravity(out, CenterOfGravity);
    990 
    991         // reset inertia tensor
    992         for(int i=0;i<NDIM*NDIM;i++)
    993                 InertiaTensor[i] = 0.;
    994 
    995         // sum up inertia tensor
    996         while (ptr->next != end) {
    997                 ptr = ptr->next;
    998                 Vector x;
    999                 x.CopyVector(&ptr->x);
    1000                 //x.SubtractVector(CenterOfGravity);
    1001                 InertiaTensor[0] += ptr->type->mass*(x.x[1]*x.x[1] + x.x[2]*x.x[2]);
    1002                 InertiaTensor[1] += ptr->type->mass*(-x.x[0]*x.x[1]);
    1003                 InertiaTensor[2] += ptr->type->mass*(-x.x[0]*x.x[2]);
    1004                 InertiaTensor[3] += ptr->type->mass*(-x.x[1]*x.x[0]);
    1005                 InertiaTensor[4] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[2]*x.x[2]);
    1006                 InertiaTensor[5] += ptr->type->mass*(-x.x[1]*x.x[2]);
    1007                 InertiaTensor[6] += ptr->type->mass*(-x.x[2]*x.x[0]);
    1008                 InertiaTensor[7] += ptr->type->mass*(-x.x[2]*x.x[1]);
    1009                 InertiaTensor[8] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[1]*x.x[1]);
    1010         }
    1011         // print InertiaTensor for debugging
    1012         *out << "The inertia tensor is:" << endl;
    1013         for(int i=0;i<NDIM;i++) {
    1014                 for(int j=0;j<NDIM;j++)
    1015                         *out << InertiaTensor[i*NDIM+j] << " ";
    1016                 *out << endl;
    1017         }
    1018         *out << endl;
    1019 
    1020         // diagonalize to determine principal axis system
    1021         gsl_eigen_symmv_workspace *T = gsl_eigen_symmv_alloc(NDIM);
    1022         gsl_matrix_view m = gsl_matrix_view_array(InertiaTensor, NDIM, NDIM);
    1023         gsl_vector *eval = gsl_vector_alloc(NDIM);
    1024         gsl_matrix *evec = gsl_matrix_alloc(NDIM, NDIM);
    1025         gsl_eigen_symmv(&m.matrix, eval, evec, T);
    1026         gsl_eigen_symmv_free(T);
    1027         gsl_eigen_symmv_sort(eval, evec, GSL_EIGEN_SORT_ABS_DESC);
    1028 
    1029         for(int i=0;i<NDIM;i++) {
    1030                 *out << Verbose(1) << "eigenvalue = " << gsl_vector_get(eval, i);
    1031                 *out << ", eigenvector = (" << evec->data[i * evec->tda + 0] << "," << evec->data[i * evec->tda + 1] << "," << evec->data[i * evec->tda + 2] << ")" << endl;
    1032         }
    1033 
    1034         // check whether we rotate or not
    1035         if (DoRotate) {
    1036                 *out << Verbose(1) << "Transforming molecule into PAS ... ";
    1037                 // the eigenvectors specify the transformation matrix
    1038                 ptr = start;
    1039                 while (ptr->next != end) {
    1040                         ptr = ptr->next;
    1041                         for (int j=0;j<MDSteps;j++)
    1042                                 Trajectories[ptr].R.at(j).MatrixMultiplication(evec->data);
    1043                         ptr->x.MatrixMultiplication(evec->data);
    1044                 }
    1045                 *out << "done." << endl;
    1046 
    1047                 // summing anew for debugging (resulting matrix has to be diagonal!)
    1048                 // reset inertia tensor
    1049                 for(int i=0;i<NDIM*NDIM;i++)
    1050                         InertiaTensor[i] = 0.;
    1051 
    1052                 // sum up inertia tensor
    1053                 ptr = start;
    1054                 while (ptr->next != end) {
    1055                         ptr = ptr->next;
    1056                         Vector x;
    1057                         x.CopyVector(&ptr->x);
    1058                         //x.SubtractVector(CenterOfGravity);
    1059                         InertiaTensor[0] += ptr->type->mass*(x.x[1]*x.x[1] + x.x[2]*x.x[2]);
    1060                         InertiaTensor[1] += ptr->type->mass*(-x.x[0]*x.x[1]);
    1061                         InertiaTensor[2] += ptr->type->mass*(-x.x[0]*x.x[2]);
    1062                         InertiaTensor[3] += ptr->type->mass*(-x.x[1]*x.x[0]);
    1063                         InertiaTensor[4] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[2]*x.x[2]);
    1064                         InertiaTensor[5] += ptr->type->mass*(-x.x[1]*x.x[2]);
    1065                         InertiaTensor[6] += ptr->type->mass*(-x.x[2]*x.x[0]);
    1066                         InertiaTensor[7] += ptr->type->mass*(-x.x[2]*x.x[1]);
    1067                         InertiaTensor[8] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[1]*x.x[1]);
    1068                 }
    1069                 // print InertiaTensor for debugging
    1070                 *out << "The inertia tensor is:" << endl;
    1071                 for(int i=0;i<NDIM;i++) {
    1072                         for(int j=0;j<NDIM;j++)
    1073                                 *out << InertiaTensor[i*NDIM+j] << " ";
    1074                         *out << endl;
    1075                 }
    1076                 *out << endl;
    1077         }
    1078 
    1079         // free everything
    1080         delete(CenterOfGravity);
    1081         gsl_vector_free(eval);
    1082         gsl_matrix_free(evec);
     985  atom *ptr = start;  // start at first in list
     986  double InertiaTensor[NDIM*NDIM];
     987  Vector *CenterOfGravity = DetermineCenterOfGravity(out);
     988
     989  CenterGravity(out, CenterOfGravity);
     990
     991  // reset inertia tensor
     992  for(int i=0;i<NDIM*NDIM;i++)
     993    InertiaTensor[i] = 0.;
     994
     995  // sum up inertia tensor
     996  while (ptr->next != end) {
     997    ptr = ptr->next;
     998    Vector x;
     999    x.CopyVector(&ptr->x);
     1000    //x.SubtractVector(CenterOfGravity);
     1001    InertiaTensor[0] += ptr->type->mass*(x.x[1]*x.x[1] + x.x[2]*x.x[2]);
     1002    InertiaTensor[1] += ptr->type->mass*(-x.x[0]*x.x[1]);
     1003    InertiaTensor[2] += ptr->type->mass*(-x.x[0]*x.x[2]);
     1004    InertiaTensor[3] += ptr->type->mass*(-x.x[1]*x.x[0]);
     1005    InertiaTensor[4] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[2]*x.x[2]);
     1006    InertiaTensor[5] += ptr->type->mass*(-x.x[1]*x.x[2]);
     1007    InertiaTensor[6] += ptr->type->mass*(-x.x[2]*x.x[0]);
     1008    InertiaTensor[7] += ptr->type->mass*(-x.x[2]*x.x[1]);
     1009    InertiaTensor[8] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[1]*x.x[1]);
     1010  }
     1011  // print InertiaTensor for debugging
     1012  *out << "The inertia tensor is:" << endl;
     1013  for(int i=0;i<NDIM;i++) {
     1014    for(int j=0;j<NDIM;j++)
     1015      *out << InertiaTensor[i*NDIM+j] << " ";
     1016    *out << endl;
     1017  }
     1018  *out << endl;
     1019
     1020  // diagonalize to determine principal axis system
     1021  gsl_eigen_symmv_workspace *T = gsl_eigen_symmv_alloc(NDIM);
     1022  gsl_matrix_view m = gsl_matrix_view_array(InertiaTensor, NDIM, NDIM);
     1023  gsl_vector *eval = gsl_vector_alloc(NDIM);
     1024  gsl_matrix *evec = gsl_matrix_alloc(NDIM, NDIM);
     1025  gsl_eigen_symmv(&m.matrix, eval, evec, T);
     1026  gsl_eigen_symmv_free(T);
     1027  gsl_eigen_symmv_sort(eval, evec, GSL_EIGEN_SORT_ABS_DESC);
     1028
     1029  for(int i=0;i<NDIM;i++) {
     1030    *out << Verbose(1) << "eigenvalue = " << gsl_vector_get(eval, i);
     1031    *out << ", eigenvector = (" << evec->data[i * evec->tda + 0] << "," << evec->data[i * evec->tda + 1] << "," << evec->data[i * evec->tda + 2] << ")" << endl;
     1032  }
     1033
     1034  // check whether we rotate or not
     1035  if (DoRotate) {
     1036    *out << Verbose(1) << "Transforming molecule into PAS ... ";
     1037    // the eigenvectors specify the transformation matrix
     1038    ptr = start;
     1039    while (ptr->next != end) {
     1040      ptr = ptr->next;
     1041      for (int j=0;j<MDSteps;j++)
     1042        Trajectories[ptr].R.at(j).MatrixMultiplication(evec->data);
     1043      ptr->x.MatrixMultiplication(evec->data);
     1044    }
     1045    *out << "done." << endl;
     1046
     1047    // summing anew for debugging (resulting matrix has to be diagonal!)
     1048    // reset inertia tensor
     1049    for(int i=0;i<NDIM*NDIM;i++)
     1050      InertiaTensor[i] = 0.;
     1051
     1052    // sum up inertia tensor
     1053    ptr = start;
     1054    while (ptr->next != end) {
     1055      ptr = ptr->next;
     1056      Vector x;
     1057      x.CopyVector(&ptr->x);
     1058      //x.SubtractVector(CenterOfGravity);
     1059      InertiaTensor[0] += ptr->type->mass*(x.x[1]*x.x[1] + x.x[2]*x.x[2]);
     1060      InertiaTensor[1] += ptr->type->mass*(-x.x[0]*x.x[1]);
     1061      InertiaTensor[2] += ptr->type->mass*(-x.x[0]*x.x[2]);
     1062      InertiaTensor[3] += ptr->type->mass*(-x.x[1]*x.x[0]);
     1063      InertiaTensor[4] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[2]*x.x[2]);
     1064      InertiaTensor[5] += ptr->type->mass*(-x.x[1]*x.x[2]);
     1065      InertiaTensor[6] += ptr->type->mass*(-x.x[2]*x.x[0]);
     1066      InertiaTensor[7] += ptr->type->mass*(-x.x[2]*x.x[1]);
     1067      InertiaTensor[8] += ptr->type->mass*(x.x[0]*x.x[0] + x.x[1]*x.x[1]);
     1068    }
     1069    // print InertiaTensor for debugging
     1070    *out << "The inertia tensor is:" << endl;
     1071    for(int i=0;i<NDIM;i++) {
     1072      for(int j=0;j<NDIM;j++)
     1073        *out << InertiaTensor[i*NDIM+j] << " ";
     1074      *out << endl;
     1075    }
     1076    *out << endl;
     1077  }
     1078
     1079  // free everything
     1080  delete(CenterOfGravity);
     1081  gsl_vector_free(eval);
     1082  gsl_matrix_free(evec);
    10831083};
    10841084
     
    10941094bool molecule::VerletForceIntegration(char *file, double delta_t, bool IsAngstroem)
    10951095{
    1096         element *runner = elemente->start;
    1097         atom *walker = NULL;
    1098         int AtomNo;
    1099         ifstream input(file);
    1100         string token;
    1101         stringstream item;
    1102         double a, IonMass;
    1103         ForceMatrix Force;
    1104         Vector tmpvector;
    1105 
    1106         CountElements();        // make sure ElementsInMolecule is up to date
    1107 
    1108         // check file
    1109         if (input == NULL) {
    1110                 return false;
    1111         } else {
    1112                 // parse file into ForceMatrix
    1113                 if (!Force.ParseMatrix(file, 0,0,0)) {
    1114                         cerr << "Could not parse Force Matrix file " << file << "." << endl;
    1115                         return false;
    1116                 }
    1117                 if (Force.RowCounter[0] != AtomCount) {
    1118                         cerr << "Mismatch between number of atoms in file " << Force.RowCounter[0] << " and in molecule " << AtomCount << "." << endl;
    1119                         return false;
    1120                 }
    1121                 // 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 //                      }
    1132                 // 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;
    1140                                 walker = start;
    1141                                 while (walker->next != end) { // go through every atom of this element
    1142                                         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);
    1150                                                 }
    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
    1157                                                 }
    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++;
    1172                                         }
    1173                                 }
    1174                         }
    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;
     1096  element *runner = elemente->start;
     1097  atom *walker = NULL;
     1098  int AtomNo;
     1099  ifstream input(file);
     1100  string token;
     1101  stringstream item;
     1102  double a, IonMass;
     1103  ForceMatrix Force;
     1104  Vector tmpvector;
     1105
     1106  CountElements();  // make sure ElementsInMolecule is up to date
     1107
     1108  // check file
     1109  if (input == NULL) {
     1110    return false;
     1111  } else {
     1112    // parse file into ForceMatrix
     1113    if (!Force.ParseMatrix(file, 0,0,0)) {
     1114      cerr << "Could not parse Force Matrix file " << file << "." << endl;
     1115      return false;
     1116    }
     1117    if (Force.RowCounter[0] != AtomCount) {
     1118      cerr << "Mismatch between number of atoms in file " << Force.RowCounter[0] << " and in molecule " << AtomCount << "." << endl;
     1119      return false;
     1120    }
     1121    // 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//      }
     1132    // 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;
     1140        walker = start;
     1141        while (walker->next != end) { // go through every atom of this element
     1142          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);
     1150            }
     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
     1157            }
     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++;
     1172          }
     1173        }
     1174      }
     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;
    12001200};
    12011201
     
    12051205void molecule::Align(Vector *n)
    12061206{
    1207         atom *ptr = start;
    1208         double alpha, tmp;
    1209         Vector z_axis;
    1210         z_axis.x[0] = 0.;
    1211         z_axis.x[1] = 0.;
    1212         z_axis.x[2] = 1.;
    1213 
    1214         // rotate on z-x plane
    1215         cout << Verbose(0) << "Begin of Aligning all atoms." << endl;
    1216         alpha = atan(-n->x[0]/n->x[2]);
    1217         cout << Verbose(1) << "Z-X-angle: " << alpha << " ... ";
    1218         while (ptr->next != end) {
    1219                 ptr = ptr->next;
    1220                 tmp = ptr->x.x[0];
    1221                 ptr->x.x[0] =   cos(alpha) * tmp + sin(alpha) * ptr->x.x[2];
    1222                 ptr->x.x[2] = -sin(alpha) * tmp + cos(alpha) * ptr->x.x[2];
    1223                 for (int j=0;j<MDSteps;j++) {
    1224                         tmp = Trajectories[ptr].R.at(j).x[0];
    1225                         Trajectories[ptr].R.at(j).x[0] =        cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2];
    1226                         Trajectories[ptr].R.at(j).x[2] = -sin(alpha) * tmp + cos(alpha) * Trajectories[ptr].R.at(j).x[2];
    1227                 }
    1228         }
    1229         // rotate n vector
    1230         tmp = n->x[0];
    1231         n->x[0] =       cos(alpha) * tmp +      sin(alpha) * n->x[2];
    1232         n->x[2] = -sin(alpha) * tmp +   cos(alpha) * n->x[2];
    1233         cout << Verbose(1) << "alignment vector after first rotation: ";
    1234         n->Output((ofstream *)&cout);
    1235         cout << endl;
    1236 
    1237         // rotate on z-y plane
    1238         ptr = start;
    1239         alpha = atan(-n->x[1]/n->x[2]);
    1240         cout << Verbose(1) << "Z-Y-angle: " << alpha << " ... ";
    1241         while (ptr->next != end) {
    1242                 ptr = ptr->next;
    1243                 tmp = ptr->x.x[1];
    1244                 ptr->x.x[1] =   cos(alpha) * tmp + sin(alpha) * ptr->x.x[2];
    1245                 ptr->x.x[2] = -sin(alpha) * tmp + cos(alpha) * ptr->x.x[2];
    1246                 for (int j=0;j<MDSteps;j++) {
    1247                         tmp = Trajectories[ptr].R.at(j).x[1];
    1248                         Trajectories[ptr].R.at(j).x[1] =        cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2];
    1249                         Trajectories[ptr].R.at(j).x[2] = -sin(alpha) * tmp + cos(alpha) * Trajectories[ptr].R.at(j).x[2];
    1250                 }
    1251         }
    1252         // rotate n vector (for consistency check)
    1253         tmp = n->x[1];
    1254         n->x[1] =       cos(alpha) * tmp +      sin(alpha) * n->x[2];
    1255         n->x[2] = -sin(alpha) * tmp +   cos(alpha) * n->x[2];
    1256 
    1257         cout << Verbose(1) << "alignment vector after second rotation: ";
    1258         n->Output((ofstream *)&cout);
    1259         cout << Verbose(1) << endl;
    1260         cout << Verbose(0) << "End of Aligning all atoms." << endl;
     1207  atom *ptr = start;
     1208  double alpha, tmp;
     1209  Vector z_axis;
     1210  z_axis.x[0] = 0.;
     1211  z_axis.x[1] = 0.;
     1212  z_axis.x[2] = 1.;
     1213
     1214  // rotate on z-x plane
     1215  cout << Verbose(0) << "Begin of Aligning all atoms." << endl;
     1216  alpha = atan(-n->x[0]/n->x[2]);
     1217  cout << Verbose(1) << "Z-X-angle: " << alpha << " ... ";
     1218  while (ptr->next != end) {
     1219    ptr = ptr->next;
     1220    tmp = ptr->x.x[0];
     1221    ptr->x.x[0] =  cos(alpha) * tmp + sin(alpha) * ptr->x.x[2];
     1222    ptr->x.x[2] = -sin(alpha) * tmp + cos(alpha) * ptr->x.x[2];
     1223    for (int j=0;j<MDSteps;j++) {
     1224      tmp = Trajectories[ptr].R.at(j).x[0];
     1225      Trajectories[ptr].R.at(j).x[0] =  cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2];
     1226      Trajectories[ptr].R.at(j).x[2] = -sin(alpha) * tmp + cos(alpha) * Trajectories[ptr].R.at(j).x[2];
     1227    }
     1228  }
     1229  // rotate n vector
     1230  tmp = n->x[0];
     1231  n->x[0] =  cos(alpha) * tmp +  sin(alpha) * n->x[2];
     1232  n->x[2] = -sin(alpha) * tmp +  cos(alpha) * n->x[2];
     1233  cout << Verbose(1) << "alignment vector after first rotation: ";
     1234  n->Output((ofstream *)&cout);
     1235  cout << endl;
     1236
     1237  // rotate on z-y plane
     1238  ptr = start;
     1239  alpha = atan(-n->x[1]/n->x[2]);
     1240  cout << Verbose(1) << "Z-Y-angle: " << alpha << " ... ";
     1241  while (ptr->next != end) {
     1242    ptr = ptr->next;
     1243    tmp = ptr->x.x[1];
     1244    ptr->x.x[1] =  cos(alpha) * tmp + sin(alpha) * ptr->x.x[2];
     1245    ptr->x.x[2] = -sin(alpha) * tmp + cos(alpha) * ptr->x.x[2];
     1246    for (int j=0;j<MDSteps;j++) {
     1247      tmp = Trajectories[ptr].R.at(j).x[1];
     1248      Trajectories[ptr].R.at(j).x[1] =  cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2];
     1249      Trajectories[ptr].R.at(j).x[2] = -sin(alpha) * tmp + cos(alpha) * Trajectories[ptr].R.at(j).x[2];
     1250    }
     1251  }
     1252  // rotate n vector (for consistency check)
     1253  tmp = n->x[1];
     1254  n->x[1] =  cos(alpha) * tmp +  sin(alpha) * n->x[2];
     1255  n->x[2] = -sin(alpha) * tmp +  cos(alpha) * n->x[2];
     1256
     1257  cout << Verbose(1) << "alignment vector after second rotation: ";
     1258  n->Output((ofstream *)&cout);
     1259  cout << Verbose(1) << endl;
     1260  cout << Verbose(0) << "End of Aligning all atoms." << endl;
    12611261};
    12621262
     
    12671267bool molecule::RemoveAtom(atom *pointer)
    12681268{
    1269         if (ElementsInMolecule[pointer->type->Z] != 0)  // this would indicate an error
    1270                 ElementsInMolecule[pointer->type->Z]--; // decrease number of atom of this element
    1271         else
    1272                 cerr << "ERROR: Atom " << pointer->Name << " is of element " << pointer->type->Z << " but the entry in the table of the molecule is 0!" << endl;
    1273         if (ElementsInMolecule[pointer->type->Z] == 0)  // was last atom of this element?
    1274                 ElementCount--;
    1275         Trajectories.erase(pointer);
    1276         return remove(pointer, start, end);
     1269  if (ElementsInMolecule[pointer->type->Z] != 0)  // this would indicate an error
     1270    ElementsInMolecule[pointer->type->Z]--;  // decrease number of atom of this element
     1271  else
     1272    cerr << "ERROR: Atom " << pointer->Name << " is of element " << pointer->type->Z << " but the entry in the table of the molecule is 0!" << endl;
     1273  if (ElementsInMolecule[pointer->type->Z] == 0)  // was last atom of this element?
     1274    ElementCount--;
     1275  Trajectories.erase(pointer);
     1276  return remove(pointer, start, end);
    12771277};
    12781278
     
    13011301bool molecule::CleanupMolecule()
    13021302{
    1303         return (cleanup(start,end) && cleanup(first,last));
     1303  return (cleanup(start,end) && cleanup(first,last));
    13041304};
    13051305
     
    13081308 * \return pointer to atom or NULL
    13091309 */
    1310 atom * molecule::FindAtom(int Nr)       const{
    1311         atom * walker = find(&Nr, start,end);
    1312         if (walker != NULL) {
    1313                 //cout << Verbose(0) << "Found Atom Nr. " << walker->nr << endl;
    1314                 return walker;
    1315         } else {
    1316                 cout << Verbose(0) << "Atom not found in list." << endl;
    1317                 return NULL;
    1318         }
     1310atom * molecule::FindAtom(int Nr)  const{
     1311  atom * walker = find(&Nr, start,end);
     1312  if (walker != NULL) {
     1313    //cout << Verbose(0) << "Found Atom Nr. " << walker->nr << endl;
     1314    return walker;
     1315  } else {
     1316    cout << Verbose(0) << "Atom not found in list." << endl;
     1317    return NULL;
     1318  }
    13191319};
    13201320
     
    13241324atom * molecule::AskAtom(string text)
    13251325{
    1326         int No;
    1327         atom *ion = NULL;
    1328         do {
    1329                 //cout << Verbose(0) << "============Atom list==========================" << endl;
    1330                 //mol->Output((ofstream *)&cout);
    1331                 //cout << Verbose(0) << "===============================================" << endl;
    1332                 cout << Verbose(0) << text;
    1333                 cin >> No;
    1334                 ion = this->FindAtom(No);
    1335         } while (ion == NULL);
    1336         return ion;
     1326  int No;
     1327  atom *ion = NULL;
     1328  do {
     1329    //cout << Verbose(0) << "============Atom list==========================" << endl;
     1330    //mol->Output((ofstream *)&cout);
     1331    //cout << Verbose(0) << "===============================================" << endl;
     1332    cout << Verbose(0) << text;
     1333    cin >> No;
     1334    ion = this->FindAtom(No);
     1335  } while (ion == NULL);
     1336  return ion;
    13371337};
    13381338
     
    13431343bool molecule::CheckBounds(const Vector *x) const
    13441344{
    1345         bool result = true;
    1346         int j =-1;
    1347         for (int i=0;i<NDIM;i++) {
    1348                 j += i+1;
    1349                 result = result && ((x->x[i] >= 0) && (x->x[i] < cell_size[j]));
    1350         }
    1351         //return result;
    1352         return true; /// probably not gonna use the check no more
     1345  bool result = true;
     1346  int j =-1;
     1347  for (int i=0;i<NDIM;i++) {
     1348    j += i+1;
     1349    result = result && ((x->x[i] >= 0) && (x->x[i] < cell_size[j]));
     1350  }
     1351  //return result;
     1352  return true; /// probably not gonna use the check no more
    13531353};
    13541354
     
    13601360double LeastSquareDistance (const gsl_vector * x, void * params)
    13611361{
    1362         double res = 0, t;
    1363         Vector a,b,c,d;
    1364         struct lsq_params *par = (struct lsq_params *)params;
    1365         atom *ptr = par->mol->start;
    1366 
    1367         // initialize vectors
    1368         a.x[0] = gsl_vector_get(x,0);
    1369         a.x[1] = gsl_vector_get(x,1);
    1370         a.x[2] = gsl_vector_get(x,2);
    1371         b.x[0] = gsl_vector_get(x,3);
    1372         b.x[1] = gsl_vector_get(x,4);
    1373         b.x[2] = gsl_vector_get(x,5);
    1374         // go through all atoms
    1375         while (ptr != par->mol->end) {
    1376                 ptr = ptr->next;
    1377                 if (ptr->type == ((struct lsq_params *)params)->type) { // for specific type
    1378                         c.CopyVector(&ptr->x);  // copy vector to temporary one
    1379                         c.SubtractVector(&a);    // subtract offset vector
    1380                         t = c.ScalarProduct(&b);                                        // get direction parameter
    1381                         d.CopyVector(&b);                        // and create vector
    1382                         d.Scale(&t);
    1383                         c.SubtractVector(&d);    // ... yielding distance vector
    1384                         res += d.ScalarProduct((const Vector *)&d);                             // add squared distance
    1385                 }
    1386         }
    1387         return res;
     1362  double res = 0, t;
     1363  Vector a,b,c,d;
     1364  struct lsq_params *par = (struct lsq_params *)params;
     1365  atom *ptr = par->mol->start;
     1366
     1367  // initialize vectors
     1368  a.x[0] = gsl_vector_get(x,0);
     1369  a.x[1] = gsl_vector_get(x,1);
     1370  a.x[2] = gsl_vector_get(x,2);
     1371  b.x[0] = gsl_vector_get(x,3);
     1372  b.x[1] = gsl_vector_get(x,4);
     1373  b.x[2] = gsl_vector_get(x,5);
     1374  // go through all atoms
     1375  while (ptr != par->mol->end) {
     1376    ptr = ptr->next;
     1377    if (ptr->type == ((struct lsq_params *)params)->type) { // for specific type
     1378      c.CopyVector(&ptr->x);  // copy vector to temporary one
     1379      c.SubtractVector(&a);  // subtract offset vector
     1380      t = c.ScalarProduct(&b);          // get direction parameter
     1381      d.CopyVector(&b);      // and create vector
     1382      d.Scale(&t);
     1383      c.SubtractVector(&d);  // ... yielding distance vector
     1384      res += d.ScalarProduct((const Vector *)&d);        // add squared distance
     1385    }
     1386  }
     1387  return res;
    13881388};
    13891389
     
    13931393void molecule::GetAlignvector(struct lsq_params * par) const
    13941394{
    1395                 int np = 6;
    1396 
    1397         const gsl_multimin_fminimizer_type *T =
    1398                 gsl_multimin_fminimizer_nmsimplex;
    1399         gsl_multimin_fminimizer *s = NULL;
    1400         gsl_vector *ss;
    1401         gsl_multimin_function minex_func;
    1402 
    1403         size_t iter = 0, i;
    1404         int status;
    1405         double size;
    1406 
    1407         /* Initial vertex size vector */
    1408         ss = gsl_vector_alloc (np);
    1409 
    1410         /* Set all step sizes to 1 */
    1411         gsl_vector_set_all (ss, 1.0);
    1412 
    1413         /* Starting point */
    1414         par->x = gsl_vector_alloc (np);
    1415         par->mol = this;
    1416 
    1417          gsl_vector_set (par->x, 0, 0.0);       // offset
    1418         gsl_vector_set (par->x, 1, 0.0);
    1419         gsl_vector_set (par->x, 2, 0.0);
    1420          gsl_vector_set (par->x, 3, 0.0);       // direction
    1421         gsl_vector_set (par->x, 4, 0.0);
    1422         gsl_vector_set (par->x, 5, 1.0);
    1423 
    1424         /* Initialize method and iterate */
    1425         minex_func.f = &LeastSquareDistance;
    1426         minex_func.n = np;
    1427         minex_func.params = (void *)par;
    1428 
    1429         s = gsl_multimin_fminimizer_alloc (T, np);
    1430         gsl_multimin_fminimizer_set (s, &minex_func, par->x, ss);
    1431 
    1432         do
    1433                 {
    1434                         iter++;
    1435                         status = gsl_multimin_fminimizer_iterate(s);
    1436 
    1437                         if (status)
    1438                                 break;
    1439 
    1440                         size = gsl_multimin_fminimizer_size (s);
    1441                         status = gsl_multimin_test_size (size, 1e-2);
    1442 
    1443                         if (status == GSL_SUCCESS)
    1444                                 {
    1445                                         printf ("converged to minimum at\n");
    1446                                 }
    1447 
    1448                         printf ("%5d ", (int)iter);
    1449                         for (i = 0; i < (size_t)np; i++)
    1450                                 {
    1451                                         printf ("%10.3e ", gsl_vector_get (s->x, i));
    1452                                 }
    1453                         printf ("f() = %7.3f size = %.3f\n", s->fval, size);
    1454                 }
    1455         while (status == GSL_CONTINUE && iter < 100);
    1456 
    1457         for (i=0;i<(size_t)np;i++)
    1458                 gsl_vector_set(par->x, i, gsl_vector_get(s->x, i));
    1459         //gsl_vector_free(par->x);
    1460         gsl_vector_free(ss);
    1461         gsl_multimin_fminimizer_free (s);
     1395    int np = 6;
     1396
     1397  const gsl_multimin_fminimizer_type *T =
     1398    gsl_multimin_fminimizer_nmsimplex;
     1399  gsl_multimin_fminimizer *s = NULL;
     1400  gsl_vector *ss;
     1401  gsl_multimin_function minex_func;
     1402
     1403  size_t iter = 0, i;
     1404  int status;
     1405  double size;
     1406
     1407  /* Initial vertex size vector */
     1408  ss = gsl_vector_alloc (np);
     1409
     1410  /* Set all step sizes to 1 */
     1411  gsl_vector_set_all (ss, 1.0);
     1412
     1413  /* Starting point */
     1414  par->x = gsl_vector_alloc (np);
     1415  par->mol = this;
     1416
     1417   gsl_vector_set (par->x, 0, 0.0);  // offset
     1418  gsl_vector_set (par->x, 1, 0.0);
     1419  gsl_vector_set (par->x, 2, 0.0);
     1420   gsl_vector_set (par->x, 3, 0.0);  // direction
     1421  gsl_vector_set (par->x, 4, 0.0);
     1422  gsl_vector_set (par->x, 5, 1.0);
     1423
     1424  /* Initialize method and iterate */
     1425  minex_func.f = &LeastSquareDistance;
     1426  minex_func.n = np;
     1427  minex_func.params = (void *)par;
     1428
     1429  s = gsl_multimin_fminimizer_alloc (T, np);
     1430  gsl_multimin_fminimizer_set (s, &minex_func, par->x, ss);
     1431
     1432  do
     1433    {
     1434      iter++;
     1435      status = gsl_multimin_fminimizer_iterate(s);
     1436
     1437      if (status)
     1438        break;
     1439
     1440      size = gsl_multimin_fminimizer_size (s);
     1441      status = gsl_multimin_test_size (size, 1e-2);
     1442
     1443      if (status == GSL_SUCCESS)
     1444        {
     1445          printf ("converged to minimum at\n");
     1446        }
     1447
     1448      printf ("%5d ", (int)iter);
     1449      for (i = 0; i < (size_t)np; i++)
     1450        {
     1451          printf ("%10.3e ", gsl_vector_get (s->x, i));
     1452        }
     1453      printf ("f() = %7.3f size = %.3f\n", s->fval, size);
     1454    }
     1455  while (status == GSL_CONTINUE && iter < 100);
     1456
     1457  for (i=0;i<(size_t)np;i++)
     1458    gsl_vector_set(par->x, i, gsl_vector_get(s->x, i));
     1459  //gsl_vector_free(par->x);
     1460  gsl_vector_free(ss);
     1461  gsl_multimin_fminimizer_free (s);
    14621462};
    14631463
     
    14671467bool molecule::Output(ofstream *out)
    14681468{
    1469         atom *walker = NULL;
    1470         int ElementNo[MAX_ELEMENTS], AtomNo[MAX_ELEMENTS];
    1471         CountElements();
    1472 
    1473         for (int i=0;i<MAX_ELEMENTS;++i) {
    1474           AtomNo[i] = 0;
    1475           ElementNo[i] = 0;
    1476         }
    1477         if (out == NULL) {
    1478                 return false;
    1479         } else {
    1480                 *out << "#Ion_TypeNr._Nr.R[0]           R[1]            R[2]            MoveType (0 MoveIon, 1 FixedIon)" << endl;
     1469  atom *walker = NULL;
     1470  int ElementNo[MAX_ELEMENTS], AtomNo[MAX_ELEMENTS];
     1471  CountElements();
     1472
     1473  for (int i=0;i<MAX_ELEMENTS;++i) {
     1474    AtomNo[i] = 0;
     1475    ElementNo[i] = 0;
     1476  }
     1477  if (out == NULL) {
     1478    return false;
     1479  } else {
     1480    *out << "#Ion_TypeNr._Nr.R[0]    R[1]    R[2]    MoveType (0 MoveIon, 1 FixedIon)" << endl;
    14811481    walker = start;
    14821482    while (walker->next != end) { // go through every atom of this element
     
    14951495      walker->Output(ElementNo[walker->type->Z], AtomNo[walker->type->Z], out); // removed due to trajectories
    14961496    }
    1497                 return true;
    1498         }
     1497    return true;
     1498  }
    14991499};
    15001500
     
    15041504bool molecule::OutputTrajectories(ofstream *out)
    15051505{
    1506         atom *walker = NULL;
     1506  atom *walker = NULL;
    15071507  int ElementNo[MAX_ELEMENTS], AtomNo[MAX_ELEMENTS];
    1508         CountElements();
    1509 
    1510         if (out == NULL) {
    1511                 return false;
    1512         } else {
    1513                 for (int step = 0; step < MDSteps; step++) {
    1514                         if (step == 0) {
    1515                                 *out << "#Ion_TypeNr._Nr.R[0]           R[1]            R[2]            MoveType (0 MoveIon, 1 FixedIon)" << endl;
    1516                         } else {
    1517                                 *out << "# ====== MD step " << step << " =========" << endl;
    1518                         }
    1519                   for (int i=0;i<MAX_ELEMENTS;++i) {
    1520                     AtomNo[i] = 0;
    1521                     ElementNo[i] = 0;
    1522                   }
     1508  CountElements();
     1509
     1510  if (out == NULL) {
     1511    return false;
     1512  } else {
     1513    for (int step = 0; step < MDSteps; step++) {
     1514      if (step == 0) {
     1515        *out << "#Ion_TypeNr._Nr.R[0]    R[1]    R[2]    MoveType (0 MoveIon, 1 FixedIon)" << endl;
     1516      } else {
     1517        *out << "# ====== MD step " << step << " =========" << endl;
     1518      }
     1519      for (int i=0;i<MAX_ELEMENTS;++i) {
     1520        AtomNo[i] = 0;
     1521        ElementNo[i] = 0;
     1522      }
    15231523    walker = start;
    15241524    while (walker->next != end) { // go through every atom of this element
     
    15351535        walker = walker->next;
    15361536        AtomNo[walker->type->Z]++;
    1537         *out << "Ion_Type" << ElementNo[walker->type->Z] << "_" << AtomNo[walker->type->Z] << "\t"      << fixed << setprecision(9) << showpoint;
     1537        *out << "Ion_Type" << ElementNo[walker->type->Z] << "_" << AtomNo[walker->type->Z] << "\t"  << fixed << setprecision(9) << showpoint;
    15381538        *out << Trajectories[walker].R.at(step).x[0] << "\t" << Trajectories[walker].R.at(step).x[1] << "\t" << Trajectories[walker].R.at(step).x[2];
    15391539        *out << "\t" << walker->FixedIon;
     
    15441544        *out << "\t# Number in molecule " << walker->nr << endl;
    15451545      }
    1546                 }
    1547                 return true;
    1548         }
     1546    }
     1547    return true;
     1548  }
    15491549};
    15501550
     
    15541554void molecule::OutputListOfBonds(ofstream *out) const
    15551555{
    1556         *out << Verbose(2) << endl << "From Contents of ListOfBondsPerAtom, all non-hydrogen atoms:" << endl;
    1557         atom *Walker = start;
    1558         while (Walker->next != end) {
    1559                 Walker = Walker->next;
     1556  *out << Verbose(2) << endl << "From Contents of ListOfBondsPerAtom, all non-hydrogen atoms:" << endl;
     1557  atom *Walker = start;
     1558  while (Walker->next != end) {
     1559    Walker = Walker->next;
    15601560#ifdef ADDHYDROGEN
    1561                 if (Walker->type->Z != 1) {      // regard only non-hydrogen
     1561    if (Walker->type->Z != 1) {  // regard only non-hydrogen
    15621562#endif
    1563                         *out << Verbose(2) << "Atom " << Walker->Name << " has Bonds: "<<endl;
    1564                         for(int j=0;j<NumberOfBondsPerAtom[Walker->nr];j++) {
    1565                                 *out << Verbose(3) << *(ListOfBondsPerAtom)[Walker->nr][j] << endl;
    1566                         }
     1563      *out << Verbose(2) << "Atom " << Walker->Name << " has Bonds: "<<endl;
     1564      for(int j=0;j<NumberOfBondsPerAtom[Walker->nr];j++) {
     1565        *out << Verbose(3) << *(ListOfBondsPerAtom)[Walker->nr][j] << endl;
     1566      }
    15671567#ifdef ADDHYDROGEN
    1568                 }
     1568    }
    15691569#endif
    1570         }
    1571         *out << endl;
     1570  }
     1571  *out << endl;
    15721572};
    15731573
     
    15751575 * \param *out stream pointer
    15761576 */
    1577 bool molecule::Checkout(ofstream *out)  const
    1578 {
    1579         return elemente->Checkout(out, ElementsInMolecule);
     1577bool molecule::Checkout(ofstream *out)  const
     1578{
     1579  return elemente->Checkout(out, ElementsInMolecule);
    15801580};
    15811581
     
    15851585bool molecule::OutputTrajectoriesXYZ(ofstream *out)
    15861586{
    1587         atom *walker = NULL;
    1588         int No = 0;
    1589         time_t now;
    1590 
    1591         now = time((time_t *)NULL);      // Get the system time and put it into 'now' as 'calender time'
    1592         walker = start;
    1593         while (walker->next != end) { // go through every atom and count
    1594                 walker = walker->next;
    1595                 No++;
    1596         }
    1597         if (out != NULL) {
    1598                 for (int step=0;step<MDSteps;step++) {
    1599                         *out << No << "\n\tCreated by molecuilder, step " << step << ", on " << ctime(&now);
    1600                         walker = start;
    1601                         while (walker->next != end) { // go through every atom of this element
    1602                                 walker = walker->next;
    1603                                 *out << walker->type->symbol << "\t" << Trajectories[walker].R.at(step).x[0] << "\t" << Trajectories[walker].R.at(step).x[1] << "\t" << Trajectories[walker].R.at(step).x[2] << endl;
    1604                         }
    1605                 }
    1606                 return true;
    1607         } else
    1608                 return false;
     1587  atom *walker = NULL;
     1588  int No = 0;
     1589  time_t now;
     1590
     1591  now = time((time_t *)NULL);  // Get the system time and put it into 'now' as 'calender time'
     1592  walker = start;
     1593  while (walker->next != end) { // go through every atom and count
     1594    walker = walker->next;
     1595    No++;
     1596  }
     1597  if (out != NULL) {
     1598    for (int step=0;step<MDSteps;step++) {
     1599      *out << No << "\n\tCreated by molecuilder, step " << step << ", on " << ctime(&now);
     1600      walker = start;
     1601      while (walker->next != end) { // go through every atom of this element
     1602        walker = walker->next;
     1603        *out << walker->type->symbol << "\t" << Trajectories[walker].R.at(step).x[0] << "\t" << Trajectories[walker].R.at(step).x[1] << "\t" << Trajectories[walker].R.at(step).x[2] << endl;
     1604      }
     1605    }
     1606    return true;
     1607  } else
     1608    return false;
    16091609};
    16101610
     
    16141614bool molecule::OutputXYZ(ofstream *out) const
    16151615{
    1616         atom *walker = NULL;
    1617         int AtomNo = 0;
    1618         time_t now;
    1619 
    1620         now = time((time_t *)NULL);      // Get the system time and put it into 'now' as 'calender time'
    1621         walker = start;
    1622         while (walker->next != end) { // go through every atom and count
    1623                 walker = walker->next;
    1624                 AtomNo++;
    1625         }
    1626         if (out != NULL) {
    1627                 *out << AtomNo << "\n\tCreated by molecuilder on " << ctime(&now);
     1616  atom *walker = NULL;
     1617  int AtomNo = 0;
     1618  time_t now;
     1619
     1620  now = time((time_t *)NULL);  // Get the system time and put it into 'now' as 'calender time'
     1621  walker = start;
     1622  while (walker->next != end) { // go through every atom and count
     1623    walker = walker->next;
     1624    AtomNo++;
     1625  }
     1626  if (out != NULL) {
     1627    *out << AtomNo << "\n\tCreated by molecuilder on " << ctime(&now);
    16281628    walker = start;
    16291629    while (walker->next != end) { // go through every atom of this element
     
    16311631      walker->OutputXYZLine(out);
    16321632    }
    1633                 return true;
    1634         } else
    1635                 return false;
     1633    return true;
     1634  } else
     1635    return false;
    16361636};
    16371637
     
    16411641void molecule::CountAtoms(ofstream *out)
    16421642{
    1643         int i = 0;
    1644         atom *Walker = start;
    1645         while (Walker->next != end) {
    1646                 Walker = Walker->next;
    1647                 i++;
    1648         }
    1649         if ((AtomCount == 0) || (i != AtomCount)) {
    1650                 *out << Verbose(3) << "Mismatch in AtomCount " << AtomCount << " and recounted number " << i << ", renaming all." << endl;
    1651                 AtomCount = i;
    1652 
    1653                 // count NonHydrogen atoms and give each atom a unique name
    1654                 if (AtomCount != 0) {
    1655                         i=0;
    1656                         NoNonHydrogen = 0;
    1657                         Walker = start;
    1658                         while (Walker->next != end) {
    1659                                 Walker = Walker->next;
    1660                                 Walker->nr = i; // update number in molecule (for easier referencing in FragmentMolecule lateron)
    1661                                 if (Walker->type->Z != 1) // count non-hydrogen atoms whilst at it
    1662                                         NoNonHydrogen++;
    1663                                 Free((void **)&Walker->Name, "molecule::CountAtoms: *walker->Name");
    1664                                 Walker->Name = (char *) Malloc(sizeof(char)*6, "molecule::CountAtoms: *walker->Name");
    1665                                 sprintf(Walker->Name, "%2s%02d", Walker->type->symbol, Walker->nr+1);
    1666                                 *out << "Naming atom nr. " << Walker->nr << " " << Walker->Name << "." << endl;
    1667                                 i++;
    1668                         }
    1669                 } else
    1670                         *out << Verbose(3) << "AtomCount is still " << AtomCount << ", thus counting nothing." << endl;
    1671         }
     1643  int i = 0;
     1644  atom *Walker = start;
     1645  while (Walker->next != end) {
     1646    Walker = Walker->next;
     1647    i++;
     1648  }
     1649  if ((AtomCount == 0) || (i != AtomCount)) {
     1650    *out << Verbose(3) << "Mismatch in AtomCount " << AtomCount << " and recounted number " << i << ", renaming all." << endl;
     1651    AtomCount = i;
     1652
     1653    // count NonHydrogen atoms and give each atom a unique name
     1654    if (AtomCount != 0) {
     1655      i=0;
     1656      NoNonHydrogen = 0;
     1657      Walker = start;
     1658      while (Walker->next != end) {
     1659        Walker = Walker->next;
     1660        Walker->nr = i;  // update number in molecule (for easier referencing in FragmentMolecule lateron)
     1661        if (Walker->type->Z != 1) // count non-hydrogen atoms whilst at it
     1662          NoNonHydrogen++;
     1663        Free((void **)&Walker->Name, "molecule::CountAtoms: *walker->Name");
     1664        Walker->Name = (char *) Malloc(sizeof(char)*6, "molecule::CountAtoms: *walker->Name");
     1665        sprintf(Walker->Name, "%2s%02d", Walker->type->symbol, Walker->nr+1);
     1666        *out << "Naming atom nr. " << Walker->nr << " " << Walker->Name << "." << endl;
     1667        i++;
     1668      }
     1669    } else
     1670      *out << Verbose(3) << "AtomCount is still " << AtomCount << ", thus counting nothing." << endl;
     1671  }
    16721672};
    16731673
     
    16761676void molecule::CountElements()
    16771677{
    1678         int i = 0;
    1679         for(i=MAX_ELEMENTS;i--;)
    1680                 ElementsInMolecule[i] = 0;
    1681         ElementCount = 0;
    1682 
    1683         atom *walker = start;
    1684         while (walker->next != end) {
    1685                 walker = walker->next;
    1686                 ElementsInMolecule[walker->type->Z]++;
    1687                 i++;
    1688         }
    1689         for(i=MAX_ELEMENTS;i--;)
    1690                 ElementCount += (ElementsInMolecule[i] != 0 ? 1 : 0);
     1678  int i = 0;
     1679  for(i=MAX_ELEMENTS;i--;)
     1680    ElementsInMolecule[i] = 0;
     1681  ElementCount = 0;
     1682
     1683  atom *walker = start;
     1684  while (walker->next != end) {
     1685    walker = walker->next;
     1686    ElementsInMolecule[walker->type->Z]++;
     1687    i++;
     1688  }
     1689  for(i=MAX_ELEMENTS;i--;)
     1690    ElementCount += (ElementsInMolecule[i] != 0 ? 1 : 0);
    16911691};
    16921692
     
    16981698int molecule::CountCyclicBonds(ofstream *out)
    16991699{
    1700         int No = 0;
    1701         int *MinimumRingSize = NULL;
    1702         MoleculeLeafClass *Subgraphs = NULL;
    1703         class StackClass<bond *> *BackEdgeStack = NULL;
    1704         bond *Binder = first;
    1705         if ((Binder->next != last) && (Binder->next->Type == Undetermined)) {
    1706                 *out << Verbose(0) << "No Depth-First-Search analysis performed so far, calling ..." << endl;
    1707                 Subgraphs = DepthFirstSearchAnalysis(out, BackEdgeStack);
    1708                 while (Subgraphs->next != NULL) {
    1709                         Subgraphs = Subgraphs->next;
    1710                         delete(Subgraphs->previous);
    1711                 }
    1712                 delete(Subgraphs);
    1713                 delete[](MinimumRingSize);
    1714         }
    1715         while(Binder->next != last) {
    1716                 Binder = Binder->next;
    1717                 if (Binder->Cyclic)
    1718                         No++;
    1719         }
    1720         delete(BackEdgeStack);
    1721         return No;
     1700  int No = 0;
     1701  int *MinimumRingSize = NULL;
     1702  MoleculeLeafClass *Subgraphs = NULL;
     1703  class StackClass<bond *> *BackEdgeStack = NULL;
     1704  bond *Binder = first;
     1705  if ((Binder->next != last) && (Binder->next->Type == Undetermined)) {
     1706    *out << Verbose(0) << "No Depth-First-Search analysis performed so far, calling ..." << endl;
     1707    Subgraphs = DepthFirstSearchAnalysis(out, BackEdgeStack);
     1708    while (Subgraphs->next != NULL) {
     1709      Subgraphs = Subgraphs->next;
     1710      delete(Subgraphs->previous);
     1711    }
     1712    delete(Subgraphs);
     1713    delete[](MinimumRingSize);
     1714  }
     1715  while(Binder->next != last) {
     1716    Binder = Binder->next;
     1717    if (Binder->Cyclic)
     1718      No++;
     1719  }
     1720  delete(BackEdgeStack);
     1721  return No;
    17221722};
    17231723/** Returns Shading as a char string.
     
    17271727string molecule::GetColor(enum Shading color)
    17281728{
    1729         switch(color) {
    1730                 case white:
    1731                         return "white";
    1732                         break;
    1733                 case lightgray:
    1734                         return "lightgray";
    1735                         break;
    1736                 case darkgray:
    1737                         return "darkgray";
    1738                         break;
    1739                 case black:
    1740                         return "black";
    1741                         break;
    1742                 default:
    1743                         return "uncolored";
    1744                         break;
    1745         };
     1729  switch(color) {
     1730    case white:
     1731      return "white";
     1732      break;
     1733    case lightgray:
     1734      return "lightgray";
     1735      break;
     1736    case darkgray:
     1737      return "darkgray";
     1738      break;
     1739    case black:
     1740      return "black";
     1741      break;
     1742    default:
     1743      return "uncolored";
     1744      break;
     1745  };
    17461746};
    17471747
     
    17521752void molecule::CalculateOrbitals(class config &configuration)
    17531753{
    1754         configuration.MaxPsiDouble = configuration.PsiMaxNoDown = configuration.PsiMaxNoUp = configuration.PsiType = 0;
    1755         for(int i=MAX_ELEMENTS;i--;) {
    1756                 if (ElementsInMolecule[i] != 0) {
    1757                         //cout << "CalculateOrbitals: " << elemente->FindElement(i)->name << " has a valence of " << (int)elemente->FindElement(i)->Valence << " and there are " << ElementsInMolecule[i] << " of it." << endl;
    1758                         configuration.MaxPsiDouble += ElementsInMolecule[i]*((int)elemente->FindElement(i)->Valence);
    1759                 }
    1760         }
    1761         configuration.PsiMaxNoDown = configuration.MaxPsiDouble/2 + (configuration.MaxPsiDouble % 2);
    1762         configuration.PsiMaxNoUp = configuration.MaxPsiDouble/2;
    1763         configuration.MaxPsiDouble /= 2;
    1764         configuration.PsiType = (configuration.PsiMaxNoDown == configuration.PsiMaxNoUp) ? 0 : 1;
    1765         if ((configuration.PsiType == 1) && (configuration.ProcPEPsi < 2)) {
    1766                 configuration.ProcPEGamma /= 2;
    1767                 configuration.ProcPEPsi *= 2;
    1768         } else {
    1769                 configuration.ProcPEGamma *= configuration.ProcPEPsi;
    1770                 configuration.ProcPEPsi = 1;
    1771         }
    1772         configuration.InitMaxMinStopStep = configuration.MaxMinStopStep = configuration.MaxPsiDouble;
     1754  configuration.MaxPsiDouble = configuration.PsiMaxNoDown = configuration.PsiMaxNoUp = configuration.PsiType = 0;
     1755  for(int i=MAX_ELEMENTS;i--;) {
     1756    if (ElementsInMolecule[i] != 0) {
     1757      //cout << "CalculateOrbitals: " << elemente->FindElement(i)->name << " has a valence of " << (int)elemente->FindElement(i)->Valence << " and there are " << ElementsInMolecule[i] << " of it." << endl;
     1758      configuration.MaxPsiDouble += ElementsInMolecule[i]*((int)elemente->FindElement(i)->Valence);
     1759    }
     1760  }
     1761  configuration.PsiMaxNoDown = configuration.MaxPsiDouble/2 + (configuration.MaxPsiDouble % 2);
     1762  configuration.PsiMaxNoUp = configuration.MaxPsiDouble/2;
     1763  configuration.MaxPsiDouble /= 2;
     1764  configuration.PsiType = (configuration.PsiMaxNoDown == configuration.PsiMaxNoUp) ? 0 : 1;
     1765  if ((configuration.PsiType == 1) && (configuration.ProcPEPsi < 2)) {
     1766    configuration.ProcPEGamma /= 2;
     1767    configuration.ProcPEPsi *= 2;
     1768  } else {
     1769    configuration.ProcPEGamma *= configuration.ProcPEPsi;
     1770    configuration.ProcPEPsi = 1;
     1771  }
     1772  configuration.InitMaxMinStopStep = configuration.MaxMinStopStep = configuration.MaxPsiDouble;
    17731773};
    17741774
     
    17791779{
    17801780
    1781         // 1 We will parse bonds out of the dbond file created by tremolo.
    1782                         int atom1, atom2, temp;
    1783                         atom *Walker, *OtherWalker;
    1784 
    1785                                         if (!input)
    1786                                         {
    1787                                                 cout << Verbose(1) << "Opening silica failed \n";
    1788                                         };
    1789 
    1790                         *input >> ws >> atom1;
    1791                         *input >> ws >> atom2;
    1792                                         cout << Verbose(1) << "Scanning file\n";
    1793                                         while (!input->eof()) // Check whether we read everything already
    1794                                         {
    1795                                 *input >> ws >> atom1;
    1796                                 *input >> ws >> atom2;
    1797                                                 if(atom2<atom1) //Sort indices of atoms in order
    1798                                                 {
    1799                                                         temp=atom1;
    1800                                                         atom1=atom2;
    1801                                                         atom2=temp;
    1802                                                 };
    1803 
    1804                                                 Walker=start;
    1805                                                 while(Walker-> nr != atom1) // Find atom corresponding to first index
    1806                                                 {
    1807                                                         Walker = Walker->next;
    1808                                                 };
    1809                                                 OtherWalker = Walker->next;
    1810                                                 while(OtherWalker->nr != atom2) // Find atom corresponding to second index
    1811                                                 {
    1812                                                         OtherWalker= OtherWalker->next;
    1813                                                 };
    1814                                                 AddBond(Walker, OtherWalker); //Add the bond between the two atoms with respective indices.
    1815 
    1816                                         }
    1817 
    1818                                         CreateListOfBondsPerAtom(out);
     1781  // 1 We will parse bonds out of the dbond file created by tremolo.
     1782      int atom1, atom2, temp;
     1783      atom *Walker, *OtherWalker;
     1784
     1785          if (!input)
     1786          {
     1787            cout << Verbose(1) << "Opening silica failed \n";
     1788          };
     1789
     1790      *input >> ws >> atom1;
     1791      *input >> ws >> atom2;
     1792          cout << Verbose(1) << "Scanning file\n";
     1793          while (!input->eof()) // Check whether we read everything already
     1794          {
     1795        *input >> ws >> atom1;
     1796        *input >> ws >> atom2;
     1797            if(atom2<atom1) //Sort indices of atoms in order
     1798            {
     1799              temp=atom1;
     1800              atom1=atom2;
     1801              atom2=temp;
     1802            };
     1803
     1804            Walker=start;
     1805            while(Walker-> nr != atom1) // Find atom corresponding to first index
     1806            {
     1807              Walker = Walker->next;
     1808            };
     1809            OtherWalker = Walker->next;
     1810            while(OtherWalker->nr != atom2) // Find atom corresponding to second index
     1811            {
     1812              OtherWalker= OtherWalker->next;
     1813            };
     1814            AddBond(Walker, OtherWalker); //Add the bond between the two atoms with respective indices.
     1815
     1816          }
     1817
     1818          CreateListOfBondsPerAtom(out);
    18191819
    18201820};
     
    18271827 * To make it O(N log N) the function uses the linked-cell technique as follows:
    18281828 * The procedure is step-wise:
    1829  *      -# Remove every bond in list
    1830  *      -# Count the atoms in the molecule with CountAtoms()
    1831  *      -# partition cell into smaller linked cells of size \a bonddistance
    1832  *      -# put each atom into its corresponding cell
    1833  *      -# go through every cell, check the atoms therein against all possible bond partners in the 27 adjacent cells, add bond if true
    1834  *      -# create the list of bonds via CreateListOfBondsPerAtom()
    1835  *      -# correct the bond degree iteratively (single->double->triple bond)
    1836  *      -# finally print the bond list to \a *out if desired
     1829 *  -# Remove every bond in list
     1830 *  -# Count the atoms in the molecule with CountAtoms()
     1831 *  -# partition cell into smaller linked cells of size \a bonddistance
     1832 *  -# put each atom into its corresponding cell
     1833 *  -# go through every cell, check the atoms therein against all possible bond partners in the 27 adjacent cells, add bond if true
     1834 *  -# create the list of bonds via CreateListOfBondsPerAtom()
     1835 *  -# correct the bond degree iteratively (single->double->triple bond)
     1836 *  -# finally print the bond list to \a *out if desired
    18371837 * \param *out out stream for printing the matrix, NULL if no output
    18381838 * \param bonddistance length of linked cells (i.e. maximum minimal length checked)
     
    18421842{
    18431843
    1844         atom *Walker = NULL, *OtherWalker = NULL, *Candidate = NULL;
    1845         int No, NoBonds, CandidateBondNo;
    1846         int NumberCells, divisor[NDIM], n[NDIM], N[NDIM], index, Index, j;
    1847         molecule **CellList;
    1848         double distance, MinDistance, MaxDistance;
    1849         double *matrix = ReturnFullMatrixforSymmetric(cell_size);
    1850         Vector x;
    1851         int FalseBondDegree = 0;
    1852 
    1853         BondDistance = bonddistance; // * ((IsAngstroem) ? 1. : 1./AtomicLengthToAngstroem);
    1854         *out << Verbose(0) << "Begin of CreateAdjacencyList." << endl;
    1855         // remove every bond from the list
    1856         if ((first->next != last) && (last->previous != first)) {       // there are bonds present
    1857                 cleanup(first,last);
    1858         }
    1859 
    1860         // count atoms in molecule = dimension of matrix (also give each unique name and continuous numbering)
    1861         CountAtoms(out);
    1862         *out << Verbose(1) << "AtomCount " << AtomCount << "." << endl;
    1863 
    1864         if (AtomCount != 0) {
    1865                 // 1. find divisor for each axis, such that a sphere with radius of at least bonddistance can be placed into each cell
    1866                 j=-1;
    1867                 for (int i=0;i<NDIM;i++) {
    1868                         j += i+1;
    1869                         divisor[i] = (int)floor(cell_size[j]/bonddistance); // take smaller value such that size of linked cell is at least bonddistance
    1870                         //*out << Verbose(1) << "divisor[" << i << "]   = " << divisor[i] << "." << endl;
    1871                 }
    1872                 // 2a. allocate memory for the cell list
    1873                 NumberCells = divisor[0]*divisor[1]*divisor[2];
    1874                 *out << Verbose(1) << "Allocating " << NumberCells << " cells." << endl;
    1875                 CellList = (molecule **) Malloc(sizeof(molecule *)*NumberCells, "molecule::CreateAdjacencyList - ** CellList");
    1876                 for (int i=NumberCells;i--;)
    1877                         CellList[i] = NULL;
    1878 
    1879                 // 2b. put all atoms into its corresponding list
    1880                 Walker = start;
    1881                 while(Walker->next != end) {
    1882                         Walker = Walker->next;
    1883                         //*out << Verbose(1) << "Current atom is " << *Walker << " with coordinates ";
    1884                         //Walker->x.Output(out);
    1885                         //*out << "." << endl;
    1886                         // compute the cell by the atom's coordinates
    1887                         j=-1;
    1888                         for (int i=0;i<NDIM;i++) {
    1889                                 j += i+1;
    1890                                 x.CopyVector(&(Walker->x));
    1891                                 x.KeepPeriodic(out, matrix);
    1892                                 n[i] = (int)floor(x.x[i]/cell_size[j]*(double)divisor[i]);
    1893                         }
    1894                         index = n[2] + (n[1] + n[0] * divisor[1]) * divisor[2];
    1895                         //*out << Verbose(1) << "Atom " << *Walker << " goes into cell number [" << n[0] << "," << n[1] << "," << n[2] << "] = " << index << "." << endl;
    1896                         // add copy atom to this cell
    1897                         if (CellList[index] == NULL)    // allocate molecule if not done
    1898                                 CellList[index] = new molecule(elemente);
    1899                         OtherWalker = CellList[index]->AddCopyAtom(Walker); // add a copy of walker to this atom, father will be walker for later reference
    1900                         //*out << Verbose(1) << "Copy Atom is " << *OtherWalker << "." << endl;
    1901                 }
    1902                 //for (int i=0;i<NumberCells;i++)
    1903                         //*out << Verbose(1) << "Cell number " << i << ": " << CellList[i] << "." << endl;
    1904 
    1905 
    1906                 // 3a. go through every cell
    1907                 for (N[0]=divisor[0];N[0]--;)
    1908                         for (N[1]=divisor[1];N[1]--;)
    1909                                 for (N[2]=divisor[2];N[2]--;) {
    1910                                         Index = N[2] + (N[1] + N[0] * divisor[1]) * divisor[2];
    1911                                         if (CellList[Index] != NULL) { // if there atoms in this cell
    1912                                                 //*out << Verbose(1) << "Current cell is " << Index << "." << endl;
    1913                                                 // 3b. for every atom therein
    1914                                                 Walker = CellList[Index]->start;
    1915                                                 while (Walker->next != CellList[Index]->end) {  // go through every atom
    1916                                                         Walker = Walker->next;
    1917                                                         //*out << Verbose(0) << "Current Atom is " << *Walker << "." << endl;
    1918                                                         // 3c. check for possible bond between each atom in this and every one in the 27 cells
    1919                                                         for (n[0]=-1;n[0]<=1;n[0]++)
    1920                                                                 for (n[1]=-1;n[1]<=1;n[1]++)
    1921                                                                         for (n[2]=-1;n[2]<=1;n[2]++) {
    1922                                                                                 // compute the index of this comparison cell and make it periodic
    1923                                                                                 index = ((N[2]+n[2]+divisor[2])%divisor[2]) + (((N[1]+n[1]+divisor[1])%divisor[1]) + ((N[0]+n[0]+divisor[0])%divisor[0]) * divisor[1]) * divisor[2];
    1924                                                                                 //*out << Verbose(1) << "Number of comparison cell is " << index << "." << endl;
    1925                                                                                 if (CellList[index] != NULL) {  // if there are any atoms in this cell
    1926                                                                                         OtherWalker = CellList[index]->start;
    1927                                                                                         while(OtherWalker->next != CellList[index]->end) {      // go through every atom in this cell
    1928                                                                                                 OtherWalker = OtherWalker->next;
    1929                                                                                                 //*out << Verbose(0) << "Current comparison atom is " << *OtherWalker << "." << endl;
    1930                                                                                                 /// \todo periodic check is missing here!
    1931                                                                                                 //*out << Verbose(1) << "Checking distance " << OtherWalker->x.PeriodicDistanceSquared(&(Walker->x), cell_size) << " against typical bond length of " << bonddistance*bonddistance << "." << endl;
    1932                                                                                                 MinDistance = OtherWalker->type->CovalentRadius + Walker->type->CovalentRadius;
    1933                                                                                                 MinDistance *= (IsAngstroem) ? 1. : 1./AtomicLengthToAngstroem;
    1934                                                                                                 MaxDistance = MinDistance + BONDTHRESHOLD;
    1935                                                                                                 MinDistance -= BONDTHRESHOLD;
    1936                                                                                                 distance = OtherWalker->x.PeriodicDistanceSquared(&(Walker->x), cell_size);
    1937                                                                                                 if ((OtherWalker->father->nr > Walker->father->nr) && (distance <= MaxDistance*MaxDistance) && (distance >= MinDistance*MinDistance)) { // create bond if distance is smaller
    1938                                                                                                         //*out << Verbose(1) << "Adding Bond between " << *Walker << " and " << *OtherWalker << " in distance " << sqrt(distance) << "." << endl;
    1939                                                                                                         AddBond(Walker->father, OtherWalker->father, 1);        // also increases molecule::BondCount
    1940                                                                                                 } else {
    1941                                                                                                         //*out << Verbose(1) << "Not Adding: Wrong label order or distance too great." << endl;
    1942                                                                                                 }
    1943                                                                                         }
    1944                                                                                 }
    1945                                                                         }
    1946                                                 }
    1947                                         }
    1948                                 }
    1949 
    1950 
    1951 
    1952                 // 4. free the cell again
    1953                 for (int i=NumberCells;i--;)
    1954                         if (CellList[i] != NULL) {
    1955                                 delete(CellList[i]);
    1956                         }
    1957                 Free((void **)&CellList, "molecule::CreateAdjacencyList - ** CellList");
    1958 
    1959                 // create the adjacency list per atom
    1960                 CreateListOfBondsPerAtom(out);
    1961 
    1962                 // correct Bond degree of each bond by checking both bond partners for a mismatch between valence and current sum of bond degrees,
    1963                 // iteratively increase the one first where the other bond partner has the fewest number of bonds (i.e. in general bonds oxygene
    1964                 // preferred over carbon bonds). Beforehand, we had picked the first mismatching partner, which lead to oxygenes with single instead of
    1965                 // double bonds as was expected.
    1966                 if (BondCount != 0) {
    1967                         NoCyclicBonds = 0;
    1968                         *out << Verbose(1) << "Correcting Bond degree of each bond ... ";
    1969                         do {
    1970                                 No = 0; // No acts as breakup flag (if 1 we still continue)
    1971                                 Walker = start;
    1972                                 while (Walker->next != end) { // go through every atom
    1973                                         Walker = Walker->next;
    1974                                         // count valence of first partner
    1975                                         NoBonds = 0;
    1976                                         for(j=0;j<NumberOfBondsPerAtom[Walker->nr];j++)
    1977                                                 NoBonds += ListOfBondsPerAtom[Walker->nr][j]->BondDegree;
    1978                                         *out << Verbose(3) << "Walker " << *Walker << ": " << (int)Walker->type->NoValenceOrbitals << " > " << NoBonds << "?" << endl;
    1979                                         if ((int)(Walker->type->NoValenceOrbitals) > NoBonds) { // we have a mismatch, check all bonding partners for mismatch
    1980                                                 Candidate = NULL;
    1981                                                 CandidateBondNo = -1;
    1982                                                 for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) { // go through each of its bond partners
    1983                                                         OtherWalker = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
    1984                                                         // count valence of second partner
    1985                                                         NoBonds = 0;
    1986                                                         for(j=0;j<NumberOfBondsPerAtom[OtherWalker->nr];j++)
    1987                                                                 NoBonds += ListOfBondsPerAtom[OtherWalker->nr][j]->BondDegree;
    1988                                                         *out << Verbose(3) << "OtherWalker " << *OtherWalker << ": " << (int)OtherWalker->type->NoValenceOrbitals << " > " << NoBonds << "?" << endl;
    1989                                                         if ((int)(OtherWalker->type->NoValenceOrbitals) > NoBonds) { // check if possible candidate
    1990                                                                 if ((Candidate == NULL) || (NumberOfBondsPerAtom[Candidate->nr] > NumberOfBondsPerAtom[OtherWalker->nr])) { // pick the one with fewer number of bonds first
    1991                                                                         Candidate = OtherWalker;
    1992                                                                         CandidateBondNo = i;
    1993                                                                         *out << Verbose(3) << "New candidate is " << *Candidate << "." << endl;
    1994                                                                 }
    1995                                                         }
    1996                                                 }
    1997                                                 if ((Candidate != NULL) && (CandidateBondNo != -1)) {
    1998                                                         ListOfBondsPerAtom[Walker->nr][CandidateBondNo]->BondDegree++;
    1999                                                         *out << Verbose(2) << "Increased bond degree for bond " << *ListOfBondsPerAtom[Walker->nr][CandidateBondNo] << "." << endl;
    2000                                                 } else
    2001                                                         *out << Verbose(2) << "Could not find correct degree for atom " << *Walker << "." << endl;
    2002                                                         FalseBondDegree++;
    2003                                         }
    2004                                 }
    2005                         } while (No);
    2006                 *out << " done." << endl;
    2007                 } else
    2008                         *out << Verbose(1) << "BondCount is " << BondCount << ", no bonds between any of the " << AtomCount << " atoms." << endl;
    2009                 *out << Verbose(1) << "I detected " << BondCount << " bonds in the molecule with distance " << bonddistance << ", " << FalseBondDegree << " bonds could not be corrected." << endl;
    2010 
    2011                 // output bonds for debugging (if bond chain list was correctly installed)
    2012                 *out << Verbose(1) << endl << "From contents of bond chain list:";
    2013                 bond *Binder = first;
    2014                 while(Binder->next != last) {
    2015                         Binder = Binder->next;
    2016                         *out << *Binder << "\t" << endl;
    2017                 }
    2018                 *out << endl;
    2019         } else
    2020                 *out << Verbose(1) << "AtomCount is " << AtomCount << ", thus no bonds, no connections!." << endl;
    2021         *out << Verbose(0) << "End of CreateAdjacencyList." << endl;
    2022         Free((void **)&matrix, "molecule::CreateAdjacencyList: *matrix");
     1844  atom *Walker = NULL, *OtherWalker = NULL, *Candidate = NULL;
     1845  int No, NoBonds, CandidateBondNo;
     1846  int NumberCells, divisor[NDIM], n[NDIM], N[NDIM], index, Index, j;
     1847  molecule **CellList;
     1848  double distance, MinDistance, MaxDistance;
     1849  double *matrix = ReturnFullMatrixforSymmetric(cell_size);
     1850  Vector x;
     1851  int FalseBondDegree = 0;
     1852
     1853  BondDistance = bonddistance; // * ((IsAngstroem) ? 1. : 1./AtomicLengthToAngstroem);
     1854  *out << Verbose(0) << "Begin of CreateAdjacencyList." << endl;
     1855  // remove every bond from the list
     1856  if ((first->next != last) && (last->previous != first)) {  // there are bonds present
     1857    cleanup(first,last);
     1858  }
     1859
     1860  // count atoms in molecule = dimension of matrix (also give each unique name and continuous numbering)
     1861  CountAtoms(out);
     1862  *out << Verbose(1) << "AtomCount " << AtomCount << "." << endl;
     1863
     1864  if (AtomCount != 0) {
     1865    // 1. find divisor for each axis, such that a sphere with radius of at least bonddistance can be placed into each cell
     1866    j=-1;
     1867    for (int i=0;i<NDIM;i++) {
     1868      j += i+1;
     1869      divisor[i] = (int)floor(cell_size[j]/bonddistance); // take smaller value such that size of linked cell is at least bonddistance
     1870      //*out << Verbose(1) << "divisor[" << i << "]  = " << divisor[i] << "." << endl;
     1871    }
     1872    // 2a. allocate memory for the cell list
     1873    NumberCells = divisor[0]*divisor[1]*divisor[2];
     1874    *out << Verbose(1) << "Allocating " << NumberCells << " cells." << endl;
     1875    CellList = (molecule **) Malloc(sizeof(molecule *)*NumberCells, "molecule::CreateAdjacencyList - ** CellList");
     1876    for (int i=NumberCells;i--;)
     1877      CellList[i] = NULL;
     1878
     1879    // 2b. put all atoms into its corresponding list
     1880    Walker = start;
     1881    while(Walker->next != end) {
     1882      Walker = Walker->next;
     1883      //*out << Verbose(1) << "Current atom is " << *Walker << " with coordinates ";
     1884      //Walker->x.Output(out);
     1885      //*out << "." << endl;
     1886      // compute the cell by the atom's coordinates
     1887      j=-1;
     1888      for (int i=0;i<NDIM;i++) {
     1889        j += i+1;
     1890        x.CopyVector(&(Walker->x));
     1891        x.KeepPeriodic(out, matrix);
     1892        n[i] = (int)floor(x.x[i]/cell_size[j]*(double)divisor[i]);
     1893      }
     1894      index = n[2] + (n[1] + n[0] * divisor[1]) * divisor[2];
     1895      //*out << Verbose(1) << "Atom " << *Walker << " goes into cell number [" << n[0] << "," << n[1] << "," << n[2] << "] = " << index << "." << endl;
     1896      // add copy atom to this cell
     1897      if (CellList[index] == NULL)  // allocate molecule if not done
     1898        CellList[index] = new molecule(elemente);
     1899      OtherWalker = CellList[index]->AddCopyAtom(Walker); // add a copy of walker to this atom, father will be walker for later reference
     1900      //*out << Verbose(1) << "Copy Atom is " << *OtherWalker << "." << endl;
     1901    }
     1902    //for (int i=0;i<NumberCells;i++)
     1903      //*out << Verbose(1) << "Cell number " << i << ": " << CellList[i] << "." << endl;
     1904
     1905
     1906    // 3a. go through every cell
     1907    for (N[0]=divisor[0];N[0]--;)
     1908      for (N[1]=divisor[1];N[1]--;)
     1909        for (N[2]=divisor[2];N[2]--;) {
     1910          Index = N[2] + (N[1] + N[0] * divisor[1]) * divisor[2];
     1911          if (CellList[Index] != NULL) { // if there atoms in this cell
     1912            //*out << Verbose(1) << "Current cell is " << Index << "." << endl;
     1913            // 3b. for every atom therein
     1914            Walker = CellList[Index]->start;
     1915            while (Walker->next != CellList[Index]->end) {  // go through every atom
     1916              Walker = Walker->next;
     1917              //*out << Verbose(0) << "Current Atom is " << *Walker << "." << endl;
     1918              // 3c. check for possible bond between each atom in this and every one in the 27 cells
     1919              for (n[0]=-1;n[0]<=1;n[0]++)
     1920                for (n[1]=-1;n[1]<=1;n[1]++)
     1921                  for (n[2]=-1;n[2]<=1;n[2]++) {
     1922                    // compute the index of this comparison cell and make it periodic
     1923                    index = ((N[2]+n[2]+divisor[2])%divisor[2]) + (((N[1]+n[1]+divisor[1])%divisor[1]) + ((N[0]+n[0]+divisor[0])%divisor[0]) * divisor[1]) * divisor[2];
     1924                    //*out << Verbose(1) << "Number of comparison cell is " << index << "." << endl;
     1925                    if (CellList[index] != NULL) {  // if there are any atoms in this cell
     1926                      OtherWalker = CellList[index]->start;
     1927                      while(OtherWalker->next != CellList[index]->end) {  // go through every atom in this cell
     1928                        OtherWalker = OtherWalker->next;
     1929                        //*out << Verbose(0) << "Current comparison atom is " << *OtherWalker << "." << endl;
     1930                        /// \todo periodic check is missing here!
     1931                        //*out << Verbose(1) << "Checking distance " << OtherWalker->x.PeriodicDistanceSquared(&(Walker->x), cell_size) << " against typical bond length of " << bonddistance*bonddistance << "." << endl;
     1932                        MinDistance = OtherWalker->type->CovalentRadius + Walker->type->CovalentRadius;
     1933                        MinDistance *= (IsAngstroem) ? 1. : 1./AtomicLengthToAngstroem;
     1934                        MaxDistance = MinDistance + BONDTHRESHOLD;
     1935                        MinDistance -= BONDTHRESHOLD;
     1936                        distance = OtherWalker->x.PeriodicDistanceSquared(&(Walker->x), cell_size);
     1937                        if ((OtherWalker->father->nr > Walker->father->nr) && (distance <= MaxDistance*MaxDistance) && (distance >= MinDistance*MinDistance)) { // create bond if distance is smaller
     1938                          //*out << Verbose(1) << "Adding Bond between " << *Walker << " and " << *OtherWalker << " in distance " << sqrt(distance) << "." << endl;
     1939                          AddBond(Walker->father, OtherWalker->father, 1);  // also increases molecule::BondCount
     1940                        } else {
     1941                          //*out << Verbose(1) << "Not Adding: Wrong label order or distance too great." << endl;
     1942                        }
     1943                      }
     1944                    }
     1945                  }
     1946            }
     1947          }
     1948        }
     1949
     1950
     1951
     1952    // 4. free the cell again
     1953    for (int i=NumberCells;i--;)
     1954      if (CellList[i] != NULL) {
     1955        delete(CellList[i]);
     1956      }
     1957    Free((void **)&CellList, "molecule::CreateAdjacencyList - ** CellList");
     1958
     1959    // create the adjacency list per atom
     1960    CreateListOfBondsPerAtom(out);
     1961
     1962    // correct Bond degree of each bond by checking both bond partners for a mismatch between valence and current sum of bond degrees,
     1963    // iteratively increase the one first where the other bond partner has the fewest number of bonds (i.e. in general bonds oxygene
     1964    // preferred over carbon bonds). Beforehand, we had picked the first mismatching partner, which lead to oxygenes with single instead of
     1965    // double bonds as was expected.
     1966    if (BondCount != 0) {
     1967      NoCyclicBonds = 0;
     1968      *out << Verbose(1) << "Correcting Bond degree of each bond ... ";
     1969      do {
     1970        No = 0; // No acts as breakup flag (if 1 we still continue)
     1971        Walker = start;
     1972        while (Walker->next != end) { // go through every atom
     1973          Walker = Walker->next;
     1974          // count valence of first partner
     1975          NoBonds = 0;
     1976          for(j=0;j<NumberOfBondsPerAtom[Walker->nr];j++)
     1977            NoBonds += ListOfBondsPerAtom[Walker->nr][j]->BondDegree;
     1978          *out << Verbose(3) << "Walker " << *Walker << ": " << (int)Walker->type->NoValenceOrbitals << " > " << NoBonds << "?" << endl;
     1979          if ((int)(Walker->type->NoValenceOrbitals) > NoBonds) { // we have a mismatch, check all bonding partners for mismatch
     1980            Candidate = NULL;
     1981            CandidateBondNo = -1;
     1982            for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) { // go through each of its bond partners
     1983              OtherWalker = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
     1984              // count valence of second partner
     1985              NoBonds = 0;
     1986              for(j=0;j<NumberOfBondsPerAtom[OtherWalker->nr];j++)
     1987                NoBonds += ListOfBondsPerAtom[OtherWalker->nr][j]->BondDegree;
     1988              *out << Verbose(3) << "OtherWalker " << *OtherWalker << ": " << (int)OtherWalker->type->NoValenceOrbitals << " > " << NoBonds << "?" << endl;
     1989              if ((int)(OtherWalker->type->NoValenceOrbitals) > NoBonds) { // check if possible candidate
     1990                if ((Candidate == NULL) || (NumberOfBondsPerAtom[Candidate->nr] > NumberOfBondsPerAtom[OtherWalker->nr])) { // pick the one with fewer number of bonds first
     1991                  Candidate = OtherWalker;
     1992                  CandidateBondNo = i;
     1993                  *out << Verbose(3) << "New candidate is " << *Candidate << "." << endl;
     1994                }
     1995              }
     1996            }
     1997            if ((Candidate != NULL) && (CandidateBondNo != -1)) {
     1998              ListOfBondsPerAtom[Walker->nr][CandidateBondNo]->BondDegree++;
     1999              *out << Verbose(2) << "Increased bond degree for bond " << *ListOfBondsPerAtom[Walker->nr][CandidateBondNo] << "." << endl;
     2000            } else
     2001              *out << Verbose(2) << "Could not find correct degree for atom " << *Walker << "." << endl;
     2002              FalseBondDegree++;
     2003          }
     2004        }
     2005      } while (No);
     2006    *out << " done." << endl;
     2007    } else
     2008      *out << Verbose(1) << "BondCount is " << BondCount << ", no bonds between any of the " << AtomCount << " atoms." << endl;
     2009    *out << Verbose(1) << "I detected " << BondCount << " bonds in the molecule with distance " << bonddistance << ", " << FalseBondDegree << " bonds could not be corrected." << endl;
     2010
     2011    // output bonds for debugging (if bond chain list was correctly installed)
     2012    *out << Verbose(1) << endl << "From contents of bond chain list:";
     2013    bond *Binder = first;
     2014    while(Binder->next != last) {
     2015      Binder = Binder->next;
     2016      *out << *Binder << "\t" << endl;
     2017    }
     2018    *out << endl;
     2019  } else
     2020    *out << Verbose(1) << "AtomCount is " << AtomCount << ", thus no bonds, no connections!." << endl;
     2021  *out << Verbose(0) << "End of CreateAdjacencyList." << endl;
     2022  Free((void **)&matrix, "molecule::CreateAdjacencyList: *matrix");
    20232023
    20242024};
     
    20362036MoleculeLeafClass * molecule::DepthFirstSearchAnalysis(ofstream *out, class StackClass<bond *> *&BackEdgeStack)
    20372037{
    2038         class StackClass<atom *> *AtomStack = new StackClass<atom *>(AtomCount);
    2039         BackEdgeStack = new StackClass<bond *> (BondCount);
    2040         MoleculeLeafClass *SubGraphs = new MoleculeLeafClass(NULL);
    2041         MoleculeLeafClass *LeafWalker = SubGraphs;
    2042         int CurrentGraphNr = 0, OldGraphNr;
    2043         int ComponentNumber = 0;
    2044         atom *Walker = NULL, *OtherAtom = NULL, *Root = start->next;
    2045         bond *Binder = NULL;
    2046         bool BackStepping = false;
    2047 
    2048         *out << Verbose(0) << "Begin of DepthFirstSearchAnalysis" << endl;
    2049 
    2050         ResetAllBondsToUnused();
    2051         ResetAllAtomNumbers();
    2052         InitComponentNumbers();
    2053         BackEdgeStack->ClearStack();
    2054         while (Root != end) { // if there any atoms at all
    2055                 // (1) mark all edges unused, empty stack, set atom->GraphNr = 0 for all
    2056                 AtomStack->ClearStack();
    2057 
    2058                 // put into new subgraph molecule and add this to list of subgraphs
    2059                 LeafWalker = new MoleculeLeafClass(LeafWalker);
    2060                 LeafWalker->Leaf = new molecule(elemente);
    2061                 LeafWalker->Leaf->AddCopyAtom(Root);
    2062 
    2063                 OldGraphNr = CurrentGraphNr;
    2064                 Walker = Root;
    2065                 do { // (10)
    2066                         do { // (2) set number and Lowpoint of Atom to i, increase i, push current atom
    2067                                 if (!BackStepping) { // if we don't just return from (8)
    2068                                         Walker->GraphNr = CurrentGraphNr;
    2069                                         Walker->LowpointNr = CurrentGraphNr;
    2070                                         *out << Verbose(1) << "Setting Walker[" << Walker->Name << "]'s number to " << Walker->GraphNr << " with Lowpoint " << Walker->LowpointNr << "." << endl;
    2071                                         AtomStack->Push(Walker);
    2072                                         CurrentGraphNr++;
    2073                                 }
    2074                                 do { // (3) if Walker has no unused egdes, go to (5)
    2075                                         BackStepping = false; // reset backstepping flag for (8)
    2076                                         if (Binder == NULL) // if we don't just return from (11), Binder is already set to next unused
    2077                                                 Binder = FindNextUnused(Walker);
    2078                                         if (Binder == NULL)
    2079                                                 break;
    2080                                         *out << Verbose(2) << "Current Unused Bond is " << *Binder << "." << endl;
    2081                                         // (4) Mark Binder used, ...
    2082                                         Binder->MarkUsed(black);
    2083                                         OtherAtom = Binder->GetOtherAtom(Walker);
    2084                                         *out << Verbose(2) << "(4) OtherAtom is " << OtherAtom->Name << "." << endl;
    2085                                         if (OtherAtom->GraphNr != -1) {
    2086                                                 // (4a) ... if "other" atom has been visited (GraphNr != 0), set lowpoint to minimum of both, go to (3)
    2087                                                 Binder->Type = BackEdge;
    2088                                                 BackEdgeStack->Push(Binder);
    2089                                                 Walker->LowpointNr = ( Walker->LowpointNr < OtherAtom->GraphNr ) ? Walker->LowpointNr : OtherAtom->GraphNr;
    2090                                                 *out << Verbose(3) << "(4a) Visited: Setting Lowpoint of Walker[" << Walker->Name << "] to " << Walker->LowpointNr << "." << endl;
    2091                                         } else {
    2092                                                 // (4b) ... otherwise set OtherAtom as Ancestor of Walker and Walker as OtherAtom, go to (2)
    2093                                                 Binder->Type = TreeEdge;
    2094                                                 OtherAtom->Ancestor = Walker;
    2095                                                 Walker = OtherAtom;
    2096                                                 *out << Verbose(3) << "(4b) Not Visited: OtherAtom[" << OtherAtom->Name << "]'s Ancestor is now " << OtherAtom->Ancestor->Name << ", Walker is OtherAtom " << OtherAtom->Name << "." << endl;
    2097                                                 break;
    2098                                         }
    2099                                         Binder = NULL;
    2100                                 } while (1);    // (3)
    2101                                 if (Binder == NULL) {
    2102                                         *out << Verbose(2) << "No more Unused Bonds." << endl;
    2103                                         break;
    2104                                 } else
    2105                                         Binder = NULL;
    2106                         } while (1);    // (2)
    2107 
    2108                         // if we came from backstepping, yet there were no more unused bonds, we end up here with no Ancestor, because Walker is Root! Then we are finished!
    2109                         if ((Walker == Root) && (Binder == NULL))
    2110                                 break;
    2111 
    2112                         // (5) if Ancestor of Walker is ...
    2113                         *out << Verbose(1) << "(5) Number of Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "] is " << Walker->Ancestor->GraphNr << "." << endl;
    2114                         if (Walker->Ancestor->GraphNr != Root->GraphNr) {
    2115                                 // (6)  (Ancestor of Walker is not Root)
    2116                                 if (Walker->LowpointNr < Walker->Ancestor->GraphNr) {
    2117                                         // (6a) set Ancestor's Lowpoint number to minimum of of its Ancestor and itself, go to Step(8)
    2118                                         Walker->Ancestor->LowpointNr = (Walker->Ancestor->LowpointNr < Walker->LowpointNr) ? Walker->Ancestor->LowpointNr : Walker->LowpointNr;
    2119                                         *out << Verbose(2) << "(6) Setting Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "]'s Lowpoint to " << Walker->Ancestor->LowpointNr << "." << endl;
    2120                                 } else {
    2121                                         // (7) (Ancestor of Walker is a separating vertex, remove all from stack till Walker (including), these and Ancestor form a component
    2122                                         Walker->Ancestor->SeparationVertex = true;
    2123                                         *out << Verbose(2) << "(7) Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "]'s is a separating vertex, creating component." << endl;
    2124                                         SetNextComponentNumber(Walker->Ancestor, ComponentNumber);
    2125                                         *out << Verbose(3) << "(7) Walker[" << Walker->Name << "]'s Ancestor's Compont is " << ComponentNumber << "." << endl;
    2126                                         SetNextComponentNumber(Walker, ComponentNumber);
    2127                                         *out << Verbose(3) << "(7) Walker[" << Walker->Name << "]'s Compont is " << ComponentNumber << "." << endl;
    2128                                         do {
    2129                                                 OtherAtom = AtomStack->PopLast();
    2130                                                 LeafWalker->Leaf->AddCopyAtom(OtherAtom);
    2131                                                 SetNextComponentNumber(OtherAtom, ComponentNumber);
    2132                                                 *out << Verbose(3) << "(7) Other[" << OtherAtom->Name << "]'s Compont is " << ComponentNumber << "." << endl;
    2133                                         } while (OtherAtom != Walker);
    2134                                         ComponentNumber++;
    2135                                 }
    2136                                 // (8) Walker becomes its Ancestor, go to (3)
    2137                                 *out << Verbose(2) << "(8) Walker[" << Walker->Name << "] is now its Ancestor " << Walker->Ancestor->Name << ", backstepping. " << endl;
    2138                                 Walker = Walker->Ancestor;
    2139                                 BackStepping = true;
    2140                         }
    2141                         if (!BackStepping) {    // coming from (8) want to go to (3)
    2142                                 // (9) remove all from stack till Walker (including), these and Root form a component
    2143                                 AtomStack->Output(out);
    2144                                 SetNextComponentNumber(Root, ComponentNumber);
    2145                                 *out << Verbose(3) << "(9) Root[" << Root->Name << "]'s Component is " << ComponentNumber << "." << endl;
    2146                                 SetNextComponentNumber(Walker, ComponentNumber);
    2147                                 *out << Verbose(3) << "(9) Walker[" << Walker->Name << "]'s Component is " << ComponentNumber << "." << endl;
    2148                                 do {
    2149                                         OtherAtom = AtomStack->PopLast();
    2150                                         LeafWalker->Leaf->AddCopyAtom(OtherAtom);
    2151                                         SetNextComponentNumber(OtherAtom, ComponentNumber);
    2152                                         *out << Verbose(3) << "(7) Other[" << OtherAtom->Name << "]'s Compont is " << ComponentNumber << "." << endl;
    2153                                 } while (OtherAtom != Walker);
    2154                                 ComponentNumber++;
    2155 
    2156                                 // (11) Root is separation vertex,      set Walker to Root and go to (4)
    2157                                 Walker = Root;
    2158                                 Binder = FindNextUnused(Walker);
    2159                                 *out << Verbose(1) << "(10) Walker is Root[" << Root->Name << "], next Unused Bond is " << Binder << "." << endl;
    2160                                 if (Binder != NULL) { // Root is separation vertex
    2161                                         *out << Verbose(1) << "(11) Root is a separation vertex." << endl;
    2162                                         Walker->SeparationVertex = true;
    2163                                 }
    2164                         }
    2165                 } while ((BackStepping) || (Binder != NULL)); // (10) halt only if Root has no unused edges
    2166 
    2167                 // From OldGraphNr to CurrentGraphNr ranges an disconnected subgraph
    2168                 *out << Verbose(0) << "Disconnected subgraph ranges from " << OldGraphNr << " to " << CurrentGraphNr << "." << endl;
    2169                 LeafWalker->Leaf->Output(out);
    2170                 *out << endl;
    2171 
    2172                 // step on to next root
    2173                 while ((Root != end) && (Root->GraphNr != -1)) {
    2174                         //*out << Verbose(1) << "Current next subgraph root candidate is " << Root->Name << "." << endl;
    2175                         if (Root->GraphNr != -1) // if already discovered, step on
    2176                                 Root = Root->next;
    2177                 }
    2178         }
    2179         // set cyclic bond criterium on "same LP" basis
    2180         Binder = first;
    2181         while(Binder->next != last) {
    2182                 Binder = Binder->next;
    2183                 if (Binder->rightatom->LowpointNr == Binder->leftatom->LowpointNr) { // cyclic ??
    2184                         Binder->Cyclic = true;
    2185                         NoCyclicBonds++;
    2186                 }
    2187         }
    2188 
    2189 
    2190         *out << Verbose(1) << "Final graph info for each atom is:" << endl;
    2191         Walker = start;
    2192         while (Walker->next != end) {
    2193                 Walker = Walker->next;
    2194                 *out << Verbose(2) << "Atom " << Walker->Name << " is " << ((Walker->SeparationVertex) ? "a" : "not a") << " separation vertex, components are ";
    2195                 OutputComponentNumber(out, Walker);
    2196                 *out << " with Lowpoint " << Walker->LowpointNr << " and Graph Nr. " << Walker->GraphNr << "." << endl;
    2197         }
    2198 
    2199         *out << Verbose(1) << "Final graph info for each bond is:" << endl;
    2200         Binder = first;
    2201         while(Binder->next != last) {
    2202                 Binder = Binder->next;
    2203                 *out << Verbose(2) << ((Binder->Type == TreeEdge) ? "TreeEdge " : "BackEdge ") << *Binder << ": <";
    2204                 *out << ((Binder->leftatom->SeparationVertex) ? "SP," : "") << "L" << Binder->leftatom->LowpointNr << " G" << Binder->leftatom->GraphNr << " Comp.";
    2205                 OutputComponentNumber(out, Binder->leftatom);
    2206                 *out << " ===   ";
    2207                 *out << ((Binder->rightatom->SeparationVertex) ? "SP," : "") << "L" << Binder->rightatom->LowpointNr << " G" << Binder->rightatom->GraphNr << " Comp.";
    2208                 OutputComponentNumber(out, Binder->rightatom);
    2209                 *out << ">." << endl;
    2210                 if (Binder->Cyclic) // cyclic ??
    2211                         *out << Verbose(3) << "Lowpoint at each side are equal: CYCLIC!" << endl;
    2212         }
    2213 
    2214         // free all and exit
    2215         delete(AtomStack);
    2216         *out << Verbose(0) << "End of DepthFirstSearchAnalysis" << endl;
    2217         return SubGraphs;
     2038  class StackClass<atom *> *AtomStack = new StackClass<atom *>(AtomCount);
     2039  BackEdgeStack = new StackClass<bond *> (BondCount);
     2040  MoleculeLeafClass *SubGraphs = new MoleculeLeafClass(NULL);
     2041  MoleculeLeafClass *LeafWalker = SubGraphs;
     2042  int CurrentGraphNr = 0, OldGraphNr;
     2043  int ComponentNumber = 0;
     2044  atom *Walker = NULL, *OtherAtom = NULL, *Root = start->next;
     2045  bond *Binder = NULL;
     2046  bool BackStepping = false;
     2047
     2048  *out << Verbose(0) << "Begin of DepthFirstSearchAnalysis" << endl;
     2049
     2050  ResetAllBondsToUnused();
     2051  ResetAllAtomNumbers();
     2052  InitComponentNumbers();
     2053  BackEdgeStack->ClearStack();
     2054  while (Root != end) { // if there any atoms at all
     2055    // (1) mark all edges unused, empty stack, set atom->GraphNr = 0 for all
     2056    AtomStack->ClearStack();
     2057
     2058    // put into new subgraph molecule and add this to list of subgraphs
     2059    LeafWalker = new MoleculeLeafClass(LeafWalker);
     2060    LeafWalker->Leaf = new molecule(elemente);
     2061    LeafWalker->Leaf->AddCopyAtom(Root);
     2062
     2063    OldGraphNr = CurrentGraphNr;
     2064    Walker = Root;
     2065    do { // (10)
     2066      do { // (2) set number and Lowpoint of Atom to i, increase i, push current atom
     2067        if (!BackStepping) { // if we don't just return from (8)
     2068          Walker->GraphNr = CurrentGraphNr;
     2069          Walker->LowpointNr = CurrentGraphNr;
     2070          *out << Verbose(1) << "Setting Walker[" << Walker->Name << "]'s number to " << Walker->GraphNr << " with Lowpoint " << Walker->LowpointNr << "." << endl;
     2071          AtomStack->Push(Walker);
     2072          CurrentGraphNr++;
     2073        }
     2074        do { // (3) if Walker has no unused egdes, go to (5)
     2075          BackStepping = false; // reset backstepping flag for (8)
     2076          if (Binder == NULL) // if we don't just return from (11), Binder is already set to next unused
     2077            Binder = FindNextUnused(Walker);
     2078          if (Binder == NULL)
     2079            break;
     2080          *out << Verbose(2) << "Current Unused Bond is " << *Binder << "." << endl;
     2081          // (4) Mark Binder used, ...
     2082          Binder->MarkUsed(black);
     2083          OtherAtom = Binder->GetOtherAtom(Walker);
     2084          *out << Verbose(2) << "(4) OtherAtom is " << OtherAtom->Name << "." << endl;
     2085          if (OtherAtom->GraphNr != -1) {
     2086            // (4a) ... if "other" atom has been visited (GraphNr != 0), set lowpoint to minimum of both, go to (3)
     2087            Binder->Type = BackEdge;
     2088            BackEdgeStack->Push(Binder);
     2089            Walker->LowpointNr = ( Walker->LowpointNr < OtherAtom->GraphNr ) ? Walker->LowpointNr : OtherAtom->GraphNr;
     2090            *out << Verbose(3) << "(4a) Visited: Setting Lowpoint of Walker[" << Walker->Name << "] to " << Walker->LowpointNr << "." << endl;
     2091          } else {
     2092            // (4b) ... otherwise set OtherAtom as Ancestor of Walker and Walker as OtherAtom, go to (2)
     2093            Binder->Type = TreeEdge;
     2094            OtherAtom->Ancestor = Walker;
     2095            Walker = OtherAtom;
     2096            *out << Verbose(3) << "(4b) Not Visited: OtherAtom[" << OtherAtom->Name << "]'s Ancestor is now " << OtherAtom->Ancestor->Name << ", Walker is OtherAtom " << OtherAtom->Name << "." << endl;
     2097            break;
     2098          }
     2099          Binder = NULL;
     2100        } while (1);  // (3)
     2101        if (Binder == NULL) {
     2102          *out << Verbose(2) << "No more Unused Bonds." << endl;
     2103          break;
     2104        } else
     2105          Binder = NULL;
     2106      } while (1);  // (2)
     2107
     2108      // if we came from backstepping, yet there were no more unused bonds, we end up here with no Ancestor, because Walker is Root! Then we are finished!
     2109      if ((Walker == Root) && (Binder == NULL))
     2110        break;
     2111
     2112      // (5) if Ancestor of Walker is ...
     2113      *out << Verbose(1) << "(5) Number of Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "] is " << Walker->Ancestor->GraphNr << "." << endl;
     2114      if (Walker->Ancestor->GraphNr != Root->GraphNr) {
     2115        // (6)  (Ancestor of Walker is not Root)
     2116        if (Walker->LowpointNr < Walker->Ancestor->GraphNr) {
     2117          // (6a) set Ancestor's Lowpoint number to minimum of of its Ancestor and itself, go to Step(8)
     2118          Walker->Ancestor->LowpointNr = (Walker->Ancestor->LowpointNr < Walker->LowpointNr) ? Walker->Ancestor->LowpointNr : Walker->LowpointNr;
     2119          *out << Verbose(2) << "(6) Setting Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "]'s Lowpoint to " << Walker->Ancestor->LowpointNr << "." << endl;
     2120        } else {
     2121          // (7) (Ancestor of Walker is a separating vertex, remove all from stack till Walker (including), these and Ancestor form a component
     2122          Walker->Ancestor->SeparationVertex = true;
     2123          *out << Verbose(2) << "(7) Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "]'s is a separating vertex, creating component." << endl;
     2124          SetNextComponentNumber(Walker->Ancestor, ComponentNumber);
     2125          *out << Verbose(3) << "(7) Walker[" << Walker->Name << "]'s Ancestor's Compont is " << ComponentNumber << "." << endl;
     2126          SetNextComponentNumber(Walker, ComponentNumber);
     2127          *out << Verbose(3) << "(7) Walker[" << Walker->Name << "]'s Compont is " << ComponentNumber << "." << endl;
     2128          do {
     2129            OtherAtom = AtomStack->PopLast();
     2130            LeafWalker->Leaf->AddCopyAtom(OtherAtom);
     2131            SetNextComponentNumber(OtherAtom, ComponentNumber);
     2132            *out << Verbose(3) << "(7) Other[" << OtherAtom->Name << "]'s Compont is " << ComponentNumber << "." << endl;
     2133          } while (OtherAtom != Walker);
     2134          ComponentNumber++;
     2135        }
     2136        // (8) Walker becomes its Ancestor, go to (3)
     2137        *out << Verbose(2) << "(8) Walker[" << Walker->Name << "] is now its Ancestor " << Walker->Ancestor->Name << ", backstepping. " << endl;
     2138        Walker = Walker->Ancestor;
     2139        BackStepping = true;
     2140      }
     2141      if (!BackStepping) {  // coming from (8) want to go to (3)
     2142        // (9) remove all from stack till Walker (including), these and Root form a component
     2143        AtomStack->Output(out);
     2144        SetNextComponentNumber(Root, ComponentNumber);
     2145        *out << Verbose(3) << "(9) Root[" << Root->Name << "]'s Component is " << ComponentNumber << "." << endl;
     2146        SetNextComponentNumber(Walker, ComponentNumber);
     2147        *out << Verbose(3) << "(9) Walker[" << Walker->Name << "]'s Component is " << ComponentNumber << "." << endl;
     2148        do {
     2149          OtherAtom = AtomStack->PopLast();
     2150          LeafWalker->Leaf->AddCopyAtom(OtherAtom);
     2151          SetNextComponentNumber(OtherAtom, ComponentNumber);
     2152          *out << Verbose(3) << "(7) Other[" << OtherAtom->Name << "]'s Compont is " << ComponentNumber << "." << endl;
     2153        } while (OtherAtom != Walker);
     2154        ComponentNumber++;
     2155
     2156        // (11) Root is separation vertex,  set Walker to Root and go to (4)
     2157        Walker = Root;
     2158        Binder = FindNextUnused(Walker);
     2159        *out << Verbose(1) << "(10) Walker is Root[" << Root->Name << "], next Unused Bond is " << Binder << "." << endl;
     2160        if (Binder != NULL) { // Root is separation vertex
     2161          *out << Verbose(1) << "(11) Root is a separation vertex." << endl;
     2162          Walker->SeparationVertex = true;
     2163        }
     2164      }
     2165    } while ((BackStepping) || (Binder != NULL)); // (10) halt only if Root has no unused edges
     2166
     2167    // From OldGraphNr to CurrentGraphNr ranges an disconnected subgraph
     2168    *out << Verbose(0) << "Disconnected subgraph ranges from " << OldGraphNr << " to " << CurrentGraphNr << "." << endl;
     2169    LeafWalker->Leaf->Output(out);
     2170    *out << endl;
     2171
     2172    // step on to next root
     2173    while ((Root != end) && (Root->GraphNr != -1)) {
     2174      //*out << Verbose(1) << "Current next subgraph root candidate is " << Root->Name << "." << endl;
     2175      if (Root->GraphNr != -1) // if already discovered, step on
     2176        Root = Root->next;
     2177    }
     2178  }
     2179  // set cyclic bond criterium on "same LP" basis
     2180  Binder = first;
     2181  while(Binder->next != last) {
     2182    Binder = Binder->next;
     2183    if (Binder->rightatom->LowpointNr == Binder->leftatom->LowpointNr) { // cyclic ??
     2184      Binder->Cyclic = true;
     2185      NoCyclicBonds++;
     2186    }
     2187  }
     2188
     2189
     2190  *out << Verbose(1) << "Final graph info for each atom is:" << endl;
     2191  Walker = start;
     2192  while (Walker->next != end) {
     2193    Walker = Walker->next;
     2194    *out << Verbose(2) << "Atom " << Walker->Name << " is " << ((Walker->SeparationVertex) ? "a" : "not a") << " separation vertex, components are ";
     2195    OutputComponentNumber(out, Walker);
     2196    *out << " with Lowpoint " << Walker->LowpointNr << " and Graph Nr. " << Walker->GraphNr << "." << endl;
     2197  }
     2198
     2199  *out << Verbose(1) << "Final graph info for each bond is:" << endl;
     2200  Binder = first;
     2201  while(Binder->next != last) {
     2202    Binder = Binder->next;
     2203    *out << Verbose(2) << ((Binder->Type == TreeEdge) ? "TreeEdge " : "BackEdge ") << *Binder << ": <";
     2204    *out << ((Binder->leftatom->SeparationVertex) ? "SP," : "") << "L" << Binder->leftatom->LowpointNr << " G" << Binder->leftatom->GraphNr << " Comp.";
     2205    OutputComponentNumber(out, Binder->leftatom);
     2206    *out << " ===  ";
     2207    *out << ((Binder->rightatom->SeparationVertex) ? "SP," : "") << "L" << Binder->rightatom->LowpointNr << " G" << Binder->rightatom->GraphNr << " Comp.";
     2208    OutputComponentNumber(out, Binder->rightatom);
     2209    *out << ">." << endl;
     2210    if (Binder->Cyclic) // cyclic ??
     2211      *out << Verbose(3) << "Lowpoint at each side are equal: CYCLIC!" << endl;
     2212  }
     2213
     2214  // free all and exit
     2215  delete(AtomStack);
     2216  *out << Verbose(0) << "End of DepthFirstSearchAnalysis" << endl;
     2217  return SubGraphs;
    22182218};
    22192219
     
    22282228 * \todo BFS from the not-same-LP to find back to starting point of tributary cycle over more than one bond
    22292229 */
    2230 void molecule::CyclicStructureAnalysis(ofstream *out, class StackClass<bond *> *        BackEdgeStack, int *&MinimumRingSize)
    2231 {
    2232         atom **PredecessorList = (atom **) Malloc(sizeof(atom *)*AtomCount, "molecule::CyclicStructureAnalysis: **PredecessorList");
    2233         int *ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::CyclicStructureAnalysis: *ShortestPathList");
    2234         enum Shading *ColorList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::CyclicStructureAnalysis: *ColorList");
    2235         class StackClass<atom *> *BFSStack = new StackClass<atom *> (AtomCount);        // will hold the current ring
    2236         class StackClass<atom *> *TouchedStack = new StackClass<atom *> (AtomCount);    // contains all "touched" atoms (that need to be reset after BFS loop)
    2237         atom *Walker = NULL, *OtherAtom = NULL, *Root = NULL;
    2238         bond *Binder = NULL, *BackEdge = NULL;
    2239         int RingSize, NumCycles, MinRingSize = -1;
    2240 
    2241         // initialise each vertex as white with no predecessor, empty queue, color Root lightgray
    2242         for (int i=AtomCount;i--;) {
    2243                 PredecessorList[i] = NULL;
    2244                 ShortestPathList[i] = -1;
    2245                 ColorList[i] = white;
    2246         }
    2247 
    2248         *out << Verbose(1) << "Back edge list - ";
    2249         BackEdgeStack->Output(out);
    2250 
    2251         *out << Verbose(1) << "Analysing cycles ... " << endl;
    2252         NumCycles = 0;
    2253         while (!BackEdgeStack->IsEmpty()) {
    2254                 BackEdge = BackEdgeStack->PopFirst();
    2255                 // this is the target
    2256                 Root = BackEdge->leftatom;
    2257                 // this is the source point
    2258                 Walker = BackEdge->rightatom;
    2259                 ShortestPathList[Walker->nr] = 0;
    2260                 BFSStack->ClearStack(); // start with empty BFS stack
    2261                 BFSStack->Push(Walker);
    2262                 TouchedStack->Push(Walker);
    2263                 *out << Verbose(1) << "---------------------------------------------------------------------------------------------------------" << endl;
    2264                 OtherAtom = NULL;
    2265                 do {    // look for Root
    2266                         Walker = BFSStack->PopFirst();
    2267                         *out << Verbose(2) << "Current Walker is " << *Walker << ", we look for SP to Root " << *Root << "." << endl;
    2268                         for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
    2269                                 Binder = ListOfBondsPerAtom[Walker->nr][i];
    2270                                 if (Binder != BackEdge) { // only walk along DFS spanning tree (otherwise we always find SP of one being backedge Binder)
    2271                                         OtherAtom = Binder->GetOtherAtom(Walker);
     2230void molecule::CyclicStructureAnalysis(ofstream *out, class StackClass<bond *> *  BackEdgeStack, int *&MinimumRingSize)
     2231{
     2232  atom **PredecessorList = (atom **) Malloc(sizeof(atom *)*AtomCount, "molecule::CyclicStructureAnalysis: **PredecessorList");
     2233  int *ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::CyclicStructureAnalysis: *ShortestPathList");
     2234  enum Shading *ColorList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::CyclicStructureAnalysis: *ColorList");
     2235  class StackClass<atom *> *BFSStack = new StackClass<atom *> (AtomCount);  // will hold the current ring
     2236  class StackClass<atom *> *TouchedStack = new StackClass<atom *> (AtomCount);  // contains all "touched" atoms (that need to be reset after BFS loop)
     2237  atom *Walker = NULL, *OtherAtom = NULL, *Root = NULL;
     2238  bond *Binder = NULL, *BackEdge = NULL;
     2239  int RingSize, NumCycles, MinRingSize = -1;
     2240
     2241  // initialise each vertex as white with no predecessor, empty queue, color Root lightgray
     2242  for (int i=AtomCount;i--;) {
     2243    PredecessorList[i] = NULL;
     2244    ShortestPathList[i] = -1;
     2245    ColorList[i] = white;
     2246  }
     2247
     2248  *out << Verbose(1) << "Back edge list - ";
     2249  BackEdgeStack->Output(out);
     2250
     2251  *out << Verbose(1) << "Analysing cycles ... " << endl;
     2252  NumCycles = 0;
     2253  while (!BackEdgeStack->IsEmpty()) {
     2254    BackEdge = BackEdgeStack->PopFirst();
     2255    // this is the target
     2256    Root = BackEdge->leftatom;
     2257    // this is the source point
     2258    Walker = BackEdge->rightatom;
     2259    ShortestPathList[Walker->nr] = 0;
     2260    BFSStack->ClearStack();  // start with empty BFS stack
     2261    BFSStack->Push(Walker);
     2262    TouchedStack->Push(Walker);
     2263    *out << Verbose(1) << "---------------------------------------------------------------------------------------------------------" << endl;
     2264    OtherAtom = NULL;
     2265    do {  // look for Root
     2266      Walker = BFSStack->PopFirst();
     2267      *out << Verbose(2) << "Current Walker is " << *Walker << ", we look for SP to Root " << *Root << "." << endl;
     2268      for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
     2269        Binder = ListOfBondsPerAtom[Walker->nr][i];
     2270        if (Binder != BackEdge) { // only walk along DFS spanning tree (otherwise we always find SP of one being backedge Binder)
     2271          OtherAtom = Binder->GetOtherAtom(Walker);
    22722272#ifdef ADDHYDROGEN
    2273                                         if (OtherAtom->type->Z != 1) {
     2273          if (OtherAtom->type->Z != 1) {
    22742274#endif
    2275                                                 *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
    2276                                                 if (ColorList[OtherAtom->nr] == white) {
    2277                                                         TouchedStack->Push(OtherAtom);
    2278                                                         ColorList[OtherAtom->nr] = lightgray;
    2279                                                         PredecessorList[OtherAtom->nr] = Walker;        // Walker is the predecessor
    2280                                                         ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
    2281                                                         *out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " lightgray, its predecessor is " << Walker->Name << " and its Shortest Path is " << ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl;
    2282                                                         //if (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr]) { // Check for maximum distance
    2283                                                                 *out << Verbose(3) << "Putting OtherAtom into queue." << endl;
    2284                                                                 BFSStack->Push(OtherAtom);
    2285                                                         //}
    2286                                                 } else {
    2287                                                         *out << Verbose(3) << "Not Adding, has already been visited." << endl;
    2288                                                 }
    2289                                                 if (OtherAtom == Root)
    2290                                                         break;
     2275            *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
     2276            if (ColorList[OtherAtom->nr] == white) {
     2277              TouchedStack->Push(OtherAtom);
     2278              ColorList[OtherAtom->nr] = lightgray;
     2279              PredecessorList[OtherAtom->nr] = Walker;  // Walker is the predecessor
     2280              ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
     2281              *out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " lightgray, its predecessor is " << Walker->Name << " and its Shortest Path is " << ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl;
     2282              //if (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr]) { // Check for maximum distance
     2283                *out << Verbose(3) << "Putting OtherAtom into queue." << endl;
     2284                BFSStack->Push(OtherAtom);
     2285              //}
     2286            } else {
     2287              *out << Verbose(3) << "Not Adding, has already been visited." << endl;
     2288            }
     2289            if (OtherAtom == Root)
     2290              break;
    22912291#ifdef ADDHYDROGEN
    2292                                         } else {
    2293                                                 *out << Verbose(2) << "Skipping hydrogen atom " << *OtherAtom << "." << endl;
    2294                                                 ColorList[OtherAtom->nr] = black;
    2295                                         }
     2292          } else {
     2293            *out << Verbose(2) << "Skipping hydrogen atom " << *OtherAtom << "." << endl;
     2294            ColorList[OtherAtom->nr] = black;
     2295          }
    22962296#endif
    2297                                 } else {
    2298                                         *out << Verbose(2) << "Bond " << *Binder << " not Visiting, is the back edge." << endl;
    2299                                 }
    2300                         }
    2301                         ColorList[Walker->nr] = black;
    2302                         *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
    2303                         if (OtherAtom == Root) { // if we have found the root, check whether this cycle wasn't already found beforehand
    2304                                 // step through predecessor list
    2305                                 while (OtherAtom != BackEdge->rightatom) {
    2306                                         if (!OtherAtom->GetTrueFather()->IsCyclic)      // if one bond in the loop is not marked as cyclic, we haven't found this cycle yet
    2307                                                 break;
    2308                                         else
    2309                                                 OtherAtom = PredecessorList[OtherAtom->nr];
    2310                                 }
    2311                                 if (OtherAtom == BackEdge->rightatom) { // if each atom in found cycle is cyclic, loop's been found before already
    2312                                         *out << Verbose(3) << "This cycle was already found before, skipping and removing seeker from search." << endl;\
    2313                                         do {
    2314                                                 OtherAtom = TouchedStack->PopLast();
    2315                                                 if (PredecessorList[OtherAtom->nr] == Walker) {
    2316                                                         *out << Verbose(4) << "Removing " << *OtherAtom << " from lists and stacks." << endl;
    2317                                                         PredecessorList[OtherAtom->nr] = NULL;
    2318                                                         ShortestPathList[OtherAtom->nr] = -1;
    2319                                                         ColorList[OtherAtom->nr] = white;
    2320                                                         BFSStack->RemoveItem(OtherAtom);
    2321                                                 }
    2322                                         } while ((!TouchedStack->IsEmpty()) && (PredecessorList[OtherAtom->nr] == NULL));
    2323                                         TouchedStack->Push(OtherAtom);  // last was wrongly popped
    2324                                         OtherAtom = BackEdge->rightatom; // set to not Root
    2325                                 } else
    2326                                         OtherAtom = Root;
    2327                         }
    2328                 } while ((!BFSStack->IsEmpty()) && (OtherAtom != Root) && (OtherAtom != NULL)); // || (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr])));
    2329 
    2330                 if (OtherAtom == Root) {
    2331                         // now climb back the predecessor list and thus find the cycle members
    2332                         NumCycles++;
    2333                         RingSize = 1;
    2334                         Root->GetTrueFather()->IsCyclic = true;
    2335                         *out << Verbose(1) << "Found ring contains: ";
    2336                         Walker = Root;
    2337                         while (Walker != BackEdge->rightatom) {
    2338                                 *out << Walker->Name << " <-> ";
    2339                                 Walker = PredecessorList[Walker->nr];
    2340                                 Walker->GetTrueFather()->IsCyclic = true;
    2341                                 RingSize++;
    2342                         }
    2343                         *out << Walker->Name << "       with a length of " << RingSize << "." << endl << endl;
    2344                         // walk through all and set MinimumRingSize
    2345                         Walker = Root;
    2346                         MinimumRingSize[Walker->GetTrueFather()->nr] = RingSize;
    2347                         while (Walker != BackEdge->rightatom) {
    2348                                 Walker = PredecessorList[Walker->nr];
    2349                                 if (RingSize < MinimumRingSize[Walker->GetTrueFather()->nr])
    2350                                         MinimumRingSize[Walker->GetTrueFather()->nr] = RingSize;
    2351                         }
    2352                         if ((RingSize < MinRingSize) || (MinRingSize == -1))
    2353                                 MinRingSize = RingSize;
    2354                 } else {
    2355                         *out << Verbose(1) << "No ring containing " << *Root << " with length equal to or smaller than " << MinimumRingSize[Walker->GetTrueFather()->nr] << " found." << endl;
    2356                 }
    2357 
    2358                 // now clean the lists
    2359                 while (!TouchedStack->IsEmpty()){
    2360                         Walker = TouchedStack->PopFirst();
    2361                         PredecessorList[Walker->nr] = NULL;
    2362                         ShortestPathList[Walker->nr] = -1;
    2363                         ColorList[Walker->nr] = white;
    2364                 }
    2365         }
    2366         if (MinRingSize != -1) {
    2367                 // go over all atoms
    2368                 Root = start;
    2369                 while(Root->next != end) {
    2370                         Root = Root->next;
    2371 
    2372                         if (MinimumRingSize[Root->GetTrueFather()->nr] == AtomCount) { // check whether MinimumRingSize is set, if not BFS to next where it is
    2373                                 Walker = Root;
    2374                                 ShortestPathList[Walker->nr] = 0;
    2375                                 BFSStack->ClearStack(); // start with empty BFS stack
    2376                                 BFSStack->Push(Walker);
    2377                                 TouchedStack->Push(Walker);
    2378                                 //*out << Verbose(1) << "---------------------------------------------------------------------------------------------------------" << endl;
    2379                                 OtherAtom = Walker;
    2380                                 while (OtherAtom != NULL) {     // look for Root
    2381                                         Walker = BFSStack->PopFirst();
    2382                                         //*out << Verbose(2) << "Current Walker is " << *Walker << ", we look for SP to Root " << *Root << "." << endl;
    2383                                         for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
    2384                                                 Binder = ListOfBondsPerAtom[Walker->nr][i];
    2385                                                 if ((Binder != BackEdge) || (NumberOfBondsPerAtom[Walker->nr] == 1)) { // only walk along DFS spanning tree (otherwise we always find SP of 1 being backedge Binder), but terminal hydrogens may be connected via backedge, hence extra check
    2386                                                         OtherAtom = Binder->GetOtherAtom(Walker);
    2387                                                         //*out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
    2388                                                         if (ColorList[OtherAtom->nr] == white) {
    2389                                                                 TouchedStack->Push(OtherAtom);
    2390                                                                 ColorList[OtherAtom->nr] = lightgray;
    2391                                                                 PredecessorList[OtherAtom->nr] = Walker;        // Walker is the predecessor
    2392                                                                 ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
    2393                                                                 //*out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " lightgray, its predecessor is " << Walker->Name << " and its Shortest Path is " << ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl;
    2394                                                                 if (OtherAtom->GetTrueFather()->IsCyclic) { // if the other atom is connected to a ring
    2395                                                                         MinimumRingSize[Root->GetTrueFather()->nr] = ShortestPathList[OtherAtom->nr]+MinimumRingSize[OtherAtom->GetTrueFather()->nr];
    2396                                                                         OtherAtom = NULL; //break;
    2397                                                                         break;
    2398                                                                 } else
    2399                                                                         BFSStack->Push(OtherAtom);
    2400                                                         } else {
    2401                                                                 //*out << Verbose(3) << "Not Adding, has already been visited." << endl;
    2402                                                         }
    2403                                                 } else {
    2404                                                         //*out << Verbose(3) << "Not Visiting, is a back edge." << endl;
    2405                                                 }
    2406                                         }
    2407                                         ColorList[Walker->nr] = black;
    2408                                         //*out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
    2409                                 }
    2410 
    2411                                 // now clean the lists
    2412                                 while (!TouchedStack->IsEmpty()){
    2413                                         Walker = TouchedStack->PopFirst();
    2414                                         PredecessorList[Walker->nr] = NULL;
    2415                                         ShortestPathList[Walker->nr] = -1;
    2416                                         ColorList[Walker->nr] = white;
    2417                                 }
    2418                         }
    2419                         *out << Verbose(1) << "Minimum ring size of " << *Root << " is " << MinimumRingSize[Root->GetTrueFather()->nr] << "." << endl;
    2420                 }
    2421                 *out << Verbose(1) << "Minimum ring size is " << MinRingSize << ", over " << NumCycles << " cycles total." << endl;
    2422         } else
    2423                 *out << Verbose(1) << "No rings were detected in the molecular structure." << endl;
    2424 
    2425         Free((void **)&PredecessorList, "molecule::CyclicStructureAnalysis: **PredecessorList");
    2426         Free((void **)&ShortestPathList, "molecule::CyclicStructureAnalysis: **ShortestPathList");
    2427         Free((void **)&ColorList, "molecule::CyclicStructureAnalysis: **ColorList");
    2428         delete(BFSStack);
     2297        } else {
     2298          *out << Verbose(2) << "Bond " << *Binder << " not Visiting, is the back edge." << endl;
     2299        }
     2300      }
     2301      ColorList[Walker->nr] = black;
     2302      *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
     2303      if (OtherAtom == Root) { // if we have found the root, check whether this cycle wasn't already found beforehand
     2304        // step through predecessor list
     2305        while (OtherAtom != BackEdge->rightatom) {
     2306          if (!OtherAtom->GetTrueFather()->IsCyclic)  // if one bond in the loop is not marked as cyclic, we haven't found this cycle yet
     2307            break;
     2308          else
     2309            OtherAtom = PredecessorList[OtherAtom->nr];
     2310        }
     2311        if (OtherAtom == BackEdge->rightatom) { // if each atom in found cycle is cyclic, loop's been found before already
     2312          *out << Verbose(3) << "This cycle was already found before, skipping and removing seeker from search." << endl;\
     2313          do {
     2314            OtherAtom = TouchedStack->PopLast();
     2315            if (PredecessorList[OtherAtom->nr] == Walker) {
     2316              *out << Verbose(4) << "Removing " << *OtherAtom << " from lists and stacks." << endl;
     2317              PredecessorList[OtherAtom->nr] = NULL;
     2318              ShortestPathList[OtherAtom->nr] = -1;
     2319              ColorList[OtherAtom->nr] = white;
     2320              BFSStack->RemoveItem(OtherAtom);
     2321            }
     2322          } while ((!TouchedStack->IsEmpty()) && (PredecessorList[OtherAtom->nr] == NULL));
     2323          TouchedStack->Push(OtherAtom);  // last was wrongly popped
     2324          OtherAtom = BackEdge->rightatom; // set to not Root
     2325        } else
     2326          OtherAtom = Root;
     2327      }
     2328    } while ((!BFSStack->IsEmpty()) && (OtherAtom != Root) && (OtherAtom != NULL)); // || (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr])));
     2329
     2330    if (OtherAtom == Root) {
     2331      // now climb back the predecessor list and thus find the cycle members
     2332      NumCycles++;
     2333      RingSize = 1;
     2334      Root->GetTrueFather()->IsCyclic = true;
     2335      *out << Verbose(1) << "Found ring contains: ";
     2336      Walker = Root;
     2337      while (Walker != BackEdge->rightatom) {
     2338        *out << Walker->Name << " <-> ";
     2339        Walker = PredecessorList[Walker->nr];
     2340        Walker->GetTrueFather()->IsCyclic = true;
     2341        RingSize++;
     2342      }
     2343      *out << Walker->Name << "  with a length of " << RingSize << "." << endl << endl;
     2344      // walk through all and set MinimumRingSize
     2345      Walker = Root;
     2346      MinimumRingSize[Walker->GetTrueFather()->nr] = RingSize;
     2347      while (Walker != BackEdge->rightatom) {
     2348        Walker = PredecessorList[Walker->nr];
     2349        if (RingSize < MinimumRingSize[Walker->GetTrueFather()->nr])
     2350          MinimumRingSize[Walker->GetTrueFather()->nr] = RingSize;
     2351      }
     2352      if ((RingSize < MinRingSize) || (MinRingSize == -1))
     2353        MinRingSize = RingSize;
     2354    } else {
     2355      *out << Verbose(1) << "No ring containing " << *Root << " with length equal to or smaller than " << MinimumRingSize[Walker->GetTrueFather()->nr] << " found." << endl;
     2356    }
     2357
     2358    // now clean the lists
     2359    while (!TouchedStack->IsEmpty()){
     2360      Walker = TouchedStack->PopFirst();
     2361      PredecessorList[Walker->nr] = NULL;
     2362      ShortestPathList[Walker->nr] = -1;
     2363      ColorList[Walker->nr] = white;
     2364    }
     2365  }
     2366  if (MinRingSize != -1) {
     2367    // go over all atoms
     2368    Root = start;
     2369    while(Root->next != end) {
     2370      Root = Root->next;
     2371
     2372      if (MinimumRingSize[Root->GetTrueFather()->nr] == AtomCount) { // check whether MinimumRingSize is set, if not BFS to next where it is
     2373        Walker = Root;
     2374        ShortestPathList[Walker->nr] = 0;
     2375        BFSStack->ClearStack();  // start with empty BFS stack
     2376        BFSStack->Push(Walker);
     2377        TouchedStack->Push(Walker);
     2378        //*out << Verbose(1) << "---------------------------------------------------------------------------------------------------------" << endl;
     2379        OtherAtom = Walker;
     2380        while (OtherAtom != NULL) {  // look for Root
     2381          Walker = BFSStack->PopFirst();
     2382          //*out << Verbose(2) << "Current Walker is " << *Walker << ", we look for SP to Root " << *Root << "." << endl;
     2383          for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
     2384            Binder = ListOfBondsPerAtom[Walker->nr][i];
     2385            if ((Binder != BackEdge) || (NumberOfBondsPerAtom[Walker->nr] == 1)) { // only walk along DFS spanning tree (otherwise we always find SP of 1 being backedge Binder), but terminal hydrogens may be connected via backedge, hence extra check
     2386              OtherAtom = Binder->GetOtherAtom(Walker);
     2387              //*out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
     2388              if (ColorList[OtherAtom->nr] == white) {
     2389                TouchedStack->Push(OtherAtom);
     2390                ColorList[OtherAtom->nr] = lightgray;
     2391                PredecessorList[OtherAtom->nr] = Walker;  // Walker is the predecessor
     2392                ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
     2393                //*out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " lightgray, its predecessor is " << Walker->Name << " and its Shortest Path is " << ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl;
     2394                if (OtherAtom->GetTrueFather()->IsCyclic) { // if the other atom is connected to a ring
     2395                  MinimumRingSize[Root->GetTrueFather()->nr] = ShortestPathList[OtherAtom->nr]+MinimumRingSize[OtherAtom->GetTrueFather()->nr];
     2396                  OtherAtom = NULL; //break;
     2397                  break;
     2398                } else
     2399                  BFSStack->Push(OtherAtom);
     2400              } else {
     2401                //*out << Verbose(3) << "Not Adding, has already been visited." << endl;
     2402              }
     2403            } else {
     2404              //*out << Verbose(3) << "Not Visiting, is a back edge." << endl;
     2405            }
     2406          }
     2407          ColorList[Walker->nr] = black;
     2408          //*out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
     2409        }
     2410
     2411        // now clean the lists
     2412        while (!TouchedStack->IsEmpty()){
     2413          Walker = TouchedStack->PopFirst();
     2414          PredecessorList[Walker->nr] = NULL;
     2415          ShortestPathList[Walker->nr] = -1;
     2416          ColorList[Walker->nr] = white;
     2417        }
     2418      }
     2419      *out << Verbose(1) << "Minimum ring size of " << *Root << " is " << MinimumRingSize[Root->GetTrueFather()->nr] << "." << endl;
     2420    }
     2421    *out << Verbose(1) << "Minimum ring size is " << MinRingSize << ", over " << NumCycles << " cycles total." << endl;
     2422  } else
     2423    *out << Verbose(1) << "No rings were detected in the molecular structure." << endl;
     2424
     2425  Free((void **)&PredecessorList, "molecule::CyclicStructureAnalysis: **PredecessorList");
     2426  Free((void **)&ShortestPathList, "molecule::CyclicStructureAnalysis: **ShortestPathList");
     2427  Free((void **)&ColorList, "molecule::CyclicStructureAnalysis: **ColorList");
     2428  delete(BFSStack);
    24292429};
    24302430
     
    24362436void molecule::SetNextComponentNumber(atom *vertex, int nr)
    24372437{
    2438         int i=0;
    2439         if (vertex != NULL) {
    2440                 for(;i<NumberOfBondsPerAtom[vertex->nr];i++) {
    2441                         if (vertex->ComponentNr[i] == -1) {      // check if not yet used
    2442                                 vertex->ComponentNr[i] = nr;
    2443                                 break;
    2444                         }
    2445                         else if (vertex->ComponentNr[i] == nr) // if number is already present, don't add another time
    2446                                 break;  // breaking here will not cause error!
    2447                 }
    2448                 if (i == NumberOfBondsPerAtom[vertex->nr])
    2449                         cerr << "Error: All Component entries are already occupied!" << endl;
    2450         } else
    2451                         cerr << "Error: Given vertex is NULL!" << endl;
     2438  int i=0;
     2439  if (vertex != NULL) {
     2440    for(;i<NumberOfBondsPerAtom[vertex->nr];i++) {
     2441      if (vertex->ComponentNr[i] == -1) {  // check if not yet used
     2442        vertex->ComponentNr[i] = nr;
     2443        break;
     2444      }
     2445      else if (vertex->ComponentNr[i] == nr) // if number is already present, don't add another time
     2446        break;  // breaking here will not cause error!
     2447    }
     2448    if (i == NumberOfBondsPerAtom[vertex->nr])
     2449      cerr << "Error: All Component entries are already occupied!" << endl;
     2450  } else
     2451      cerr << "Error: Given vertex is NULL!" << endl;
    24522452};
    24532453
     
    24572457void molecule::OutputComponentNumber(ofstream *out, atom *vertex)
    24582458{
    2459         for(int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++)
    2460                 *out << vertex->ComponentNr[i] << "     ";
     2459  for(int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++)
     2460    *out << vertex->ComponentNr[i] << "  ";
    24612461};
    24622462
     
    24652465void molecule::InitComponentNumbers()
    24662466{
    2467         atom *Walker = start;
    2468         while(Walker->next != end) {
    2469                 Walker = Walker->next;
    2470                 if (Walker->ComponentNr != NULL)
    2471                         Free((void **)&Walker->ComponentNr, "molecule::InitComponentNumbers: **Walker->ComponentNr");
    2472                 Walker->ComponentNr = (int *) Malloc(sizeof(int)*NumberOfBondsPerAtom[Walker->nr], "molecule::InitComponentNumbers: *Walker->ComponentNr");
    2473                 for (int i=NumberOfBondsPerAtom[Walker->nr];i--;)
    2474                         Walker->ComponentNr[i] = -1;
    2475         }
     2467  atom *Walker = start;
     2468  while(Walker->next != end) {
     2469    Walker = Walker->next;
     2470    if (Walker->ComponentNr != NULL)
     2471      Free((void **)&Walker->ComponentNr, "molecule::InitComponentNumbers: **Walker->ComponentNr");
     2472    Walker->ComponentNr = (int *) Malloc(sizeof(int)*NumberOfBondsPerAtom[Walker->nr], "molecule::InitComponentNumbers: *Walker->ComponentNr");
     2473    for (int i=NumberOfBondsPerAtom[Walker->nr];i--;)
     2474      Walker->ComponentNr[i] = -1;
     2475  }
    24762476};
    24772477
     
    24822482bond * molecule::FindNextUnused(atom *vertex)
    24832483{
    2484         for(int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++)
    2485                 if (ListOfBondsPerAtom[vertex->nr][i]->IsUsed() == white)
    2486                         return(ListOfBondsPerAtom[vertex->nr][i]);
    2487         return NULL;
     2484  for(int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++)
     2485    if (ListOfBondsPerAtom[vertex->nr][i]->IsUsed() == white)
     2486      return(ListOfBondsPerAtom[vertex->nr][i]);
     2487  return NULL;
    24882488};
    24892489
     
    24932493void molecule::ResetAllBondsToUnused()
    24942494{
    2495         bond *Binder = first;
    2496         while (Binder->next != last) {
    2497                 Binder = Binder->next;
    2498                 Binder->ResetUsed();
    2499         }
     2495  bond *Binder = first;
     2496  while (Binder->next != last) {
     2497    Binder = Binder->next;
     2498    Binder->ResetUsed();
     2499  }
    25002500};
    25012501
     
    25042504void molecule::ResetAllAtomNumbers()
    25052505{
    2506         atom *Walker = start;
    2507         while (Walker->next != end) {
    2508                 Walker = Walker->next;
    2509                 Walker->GraphNr = -1;
    2510         }
     2506  atom *Walker = start;
     2507  while (Walker->next != end) {
     2508    Walker = Walker->next;
     2509    Walker->GraphNr  = -1;
     2510  }
    25112511};
    25122512
     
    25172517void OutputAlreadyVisited(ofstream *out, int *list)
    25182518{
    2519         *out << Verbose(4) << "Already Visited Bonds:\t";
    2520         for(int i=1;i<=list[0];i++) *out << Verbose(0) << list[i] << "  ";
    2521         *out << endl;
     2519  *out << Verbose(4) << "Already Visited Bonds:\t";
     2520  for(int i=1;i<=list[0];i++) *out << Verbose(0) << list[i] << "  ";
     2521  *out << endl;
    25222522};
    25232523
     
    25252525 * The upper limit is
    25262526 * \f[
    2527  *      n = N \cdot C^k
     2527 *  n = N \cdot C^k
    25282528 * \f]
    25292529 * where \f$C=2^c\f$ and c is the maximum bond degree over N number of atoms.
     
    25342534int molecule::GuesstimateFragmentCount(ofstream *out, int order)
    25352535{
    2536         int c = 0;
    2537         int FragmentCount;
    2538         // get maximum bond degree
    2539         atom *Walker = start;
    2540         while (Walker->next != end) {
    2541                 Walker = Walker->next;
    2542                 c = (NumberOfBondsPerAtom[Walker->nr] > c) ? NumberOfBondsPerAtom[Walker->nr] : c;
    2543         }
    2544         FragmentCount = NoNonHydrogen*(1 << (c*order));
    2545         *out << Verbose(1) << "Upper limit for this subgraph is " << FragmentCount << " for " << NoNonHydrogen << " non-H atoms with maximum bond degree of " << c << "." << endl;
    2546         return FragmentCount;
     2536  int c = 0;
     2537  int FragmentCount;
     2538  // get maximum bond degree
     2539  atom *Walker = start;
     2540  while (Walker->next != end) {
     2541    Walker = Walker->next;
     2542    c = (NumberOfBondsPerAtom[Walker->nr] > c) ? NumberOfBondsPerAtom[Walker->nr] : c;
     2543  }
     2544  FragmentCount = NoNonHydrogen*(1 << (c*order));
     2545  *out << Verbose(1) << "Upper limit for this subgraph is " << FragmentCount << " for " << NoNonHydrogen << " non-H atoms with maximum bond degree of " << c << "." << endl;
     2546  return FragmentCount;
    25472547};
    25482548
     
    25552555bool molecule::ScanBufferIntoKeySet(ofstream *out, char *buffer, KeySet &CurrentSet)
    25562556{
    2557         stringstream line;
    2558         int AtomNr;
    2559         int status = 0;
    2560 
    2561         line.str(buffer);
    2562         while (!line.eof()) {
    2563                 line >> AtomNr;
    2564                 if ((AtomNr >= 0) && (AtomNr < AtomCount)) {
    2565                         CurrentSet.insert(AtomNr);      // insert at end, hence in same order as in file!
    2566                         status++;
    2567                 } // else it's "-1" or else and thus must not be added
    2568         }
    2569         *out << Verbose(1) << "The scanned KeySet is ";
    2570         for(KeySet::iterator runner = CurrentSet.begin(); runner != CurrentSet.end(); runner++) {
    2571                 *out << (*runner) << "\t";
    2572         }
    2573         *out << endl;
    2574         return (status != 0);
     2557  stringstream line;
     2558  int AtomNr;
     2559  int status = 0;
     2560
     2561  line.str(buffer);
     2562  while (!line.eof()) {
     2563    line >> AtomNr;
     2564    if ((AtomNr >= 0) && (AtomNr < AtomCount)) {
     2565      CurrentSet.insert(AtomNr);  // insert at end, hence in same order as in file!
     2566      status++;
     2567    } // else it's "-1" or else and thus must not be added
     2568  }
     2569  *out << Verbose(1) << "The scanned KeySet is ";
     2570  for(KeySet::iterator runner = CurrentSet.begin(); runner != CurrentSet.end(); runner++) {
     2571    *out << (*runner) << "\t";
     2572  }
     2573  *out << endl;
     2574  return (status != 0);
    25752575};
    25762576
     
    25872587bool molecule::ParseKeySetFile(ofstream *out, char *path, Graph *&FragmentList)
    25882588{
    2589         bool status = true;
    2590         ifstream InputFile;
    2591         stringstream line;
    2592         GraphTestPair testGraphInsert;
    2593         int NumberOfFragments = 0;
    2594         double TEFactor;
    2595         char *filename = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::ParseKeySetFile - filename");
    2596 
    2597         if (FragmentList == NULL) { // check list pointer
    2598                 FragmentList = new Graph;
    2599         }
    2600 
    2601         // 1st pass: open file and read
    2602         *out << Verbose(1) << "Parsing the KeySet file ... " << endl;
    2603         sprintf(filename, "%s/%s%s", path, FRAGMENTPREFIX, KEYSETFILE);
    2604         InputFile.open(filename);
    2605         if (InputFile != NULL) {
    2606                 // each line represents a new fragment
    2607                 char *buffer = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::ParseKeySetFile - *buffer");
    2608                 // 1. parse keysets and insert into temp. graph
    2609                 while (!InputFile.eof()) {
    2610                         InputFile.getline(buffer, MAXSTRINGSIZE);
    2611                         KeySet CurrentSet;
    2612                         if ((strlen(buffer) > 0) && (ScanBufferIntoKeySet(out, buffer, CurrentSet))) {  // if at least one valid atom was added, write config
    2613                                 testGraphInsert = FragmentList->insert(GraphPair (CurrentSet,pair<int,double>(NumberOfFragments++,1))); // store fragment number and current factor
    2614                                 if (!testGraphInsert.second) {
    2615                                         cerr << "KeySet file must be corrupt as there are two equal key sets therein!" << endl;
    2616                                 }
    2617                         }
    2618                 }
    2619                 // 2. Free and done
    2620                 InputFile.close();
    2621                 InputFile.clear();
    2622                 Free((void **)&buffer, "molecule::ParseKeySetFile - *buffer");
    2623                 *out << Verbose(1) << "done." << endl;
    2624         } else {
    2625                 *out << Verbose(1) << "File " << filename << " not found." << endl;
    2626                 status = false;
    2627         }
    2628 
    2629         // 2nd pass: open TEFactors file and read
    2630         *out << Verbose(1) << "Parsing the TEFactors file ... " << endl;
    2631         sprintf(filename, "%s/%s%s", path, FRAGMENTPREFIX, TEFACTORSFILE);
    2632         InputFile.open(filename);
    2633         if (InputFile != NULL) {
    2634                 // 3. add found TEFactors to each keyset
    2635                 NumberOfFragments = 0;
    2636                 for(Graph::iterator runner = FragmentList->begin();runner != FragmentList->end(); runner++) {
    2637                         if (!InputFile.eof()) {
    2638                                 InputFile >> TEFactor;
    2639                                 (*runner).second.second = TEFactor;
    2640                                 *out << Verbose(2) << "Setting " << ++NumberOfFragments << " fragment's TEFactor to " << (*runner).second.second << "." << endl;
    2641                         } else {
    2642                                 status = false;
    2643                                 break;
    2644                         }
    2645                 }
    2646                 // 4. Free and done
    2647                 InputFile.close();
    2648                 *out << Verbose(1) << "done." << endl;
    2649         } else {
    2650                 *out << Verbose(1) << "File " << filename << " not found." << endl;
    2651                 status = false;
    2652         }
    2653 
    2654         // free memory
    2655         Free((void **)&filename, "molecule::ParseKeySetFile - filename");
    2656 
    2657         return status;
     2589  bool status = true;
     2590  ifstream InputFile;
     2591  stringstream line;
     2592  GraphTestPair testGraphInsert;
     2593  int NumberOfFragments = 0;
     2594  double TEFactor;
     2595  char *filename = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::ParseKeySetFile - filename");
     2596
     2597  if (FragmentList == NULL) { // check list pointer
     2598    FragmentList = new Graph;
     2599  }
     2600
     2601  // 1st pass: open file and read
     2602  *out << Verbose(1) << "Parsing the KeySet file ... " << endl;
     2603  sprintf(filename, "%s/%s%s", path, FRAGMENTPREFIX, KEYSETFILE);
     2604  InputFile.open(filename);
     2605  if (InputFile != NULL) {
     2606    // each line represents a new fragment
     2607    char *buffer = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::ParseKeySetFile - *buffer");
     2608    // 1. parse keysets and insert into temp. graph
     2609    while (!InputFile.eof()) {
     2610      InputFile.getline(buffer, MAXSTRINGSIZE);
     2611      KeySet CurrentSet;
     2612      if ((strlen(buffer) > 0) && (ScanBufferIntoKeySet(out, buffer, CurrentSet))) {  // if at least one valid atom was added, write config
     2613        testGraphInsert = FragmentList->insert(GraphPair (CurrentSet,pair<int,double>(NumberOfFragments++,1)));  // store fragment number and current factor
     2614        if (!testGraphInsert.second) {
     2615          cerr << "KeySet file must be corrupt as there are two equal key sets therein!" << endl;
     2616        }
     2617      }
     2618    }
     2619    // 2. Free and done
     2620    InputFile.close();
     2621    InputFile.clear();
     2622    Free((void **)&buffer, "molecule::ParseKeySetFile - *buffer");
     2623    *out << Verbose(1) << "done." << endl;
     2624  } else {
     2625    *out << Verbose(1) << "File " << filename << " not found." << endl;
     2626    status = false;
     2627  }
     2628
     2629  // 2nd pass: open TEFactors file and read
     2630  *out << Verbose(1) << "Parsing the TEFactors file ... " << endl;
     2631  sprintf(filename, "%s/%s%s", path, FRAGMENTPREFIX, TEFACTORSFILE);
     2632  InputFile.open(filename);
     2633  if (InputFile != NULL) {
     2634    // 3. add found TEFactors to each keyset
     2635    NumberOfFragments = 0;
     2636    for(Graph::iterator runner = FragmentList->begin();runner != FragmentList->end(); runner++) {
     2637      if (!InputFile.eof()) {
     2638        InputFile >> TEFactor;
     2639        (*runner).second.second = TEFactor;
     2640        *out << Verbose(2) << "Setting " << ++NumberOfFragments << " fragment's TEFactor to " << (*runner).second.second << "." << endl;
     2641      } else {
     2642        status = false;
     2643        break;
     2644      }
     2645    }
     2646    // 4. Free and done
     2647    InputFile.close();
     2648    *out << Verbose(1) << "done." << endl;
     2649  } else {
     2650    *out << Verbose(1) << "File " << filename << " not found." << endl;
     2651    status = false;
     2652  }
     2653
     2654  // free memory
     2655  Free((void **)&filename, "molecule::ParseKeySetFile - filename");
     2656
     2657  return status;
    26582658};
    26592659
     
    26662666bool molecule::StoreKeySetFile(ofstream *out, Graph &KeySetList, char *path)
    26672667{
    2668         ofstream output;
    2669         bool status =   true;
    2670         string line;
    2671 
    2672         // open KeySet file
    2673         line = path;
    2674         line.append("/");
    2675         line += FRAGMENTPREFIX;
    2676         line += KEYSETFILE;
    2677         output.open(line.c_str(), ios::out);
    2678         *out << Verbose(1) << "Saving key sets of the total graph ... ";
    2679         if(output != NULL) {
    2680                 for(Graph::iterator runner = KeySetList.begin(); runner != KeySetList.end(); runner++) {
    2681                         for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) {
    2682                                 if (sprinter != (*runner).first.begin())
    2683                                         output << "\t";
    2684                                 output << *sprinter;
    2685                         }
    2686                         output << endl;
    2687                 }
    2688                 *out << "done." << endl;
    2689         } else {
    2690                 cerr << "Unable to open " << line << " for writing keysets!" << endl;
    2691                 status = false;
    2692         }
    2693         output.close();
    2694         output.clear();
    2695 
    2696         // open TEFactors file
    2697         line = path;
    2698         line.append("/");
    2699         line += FRAGMENTPREFIX;
    2700         line += TEFACTORSFILE;
    2701         output.open(line.c_str(), ios::out);
    2702         *out << Verbose(1) << "Saving TEFactors of the total graph ... ";
    2703         if(output != NULL) {
    2704                 for(Graph::iterator runner = KeySetList.begin(); runner != KeySetList.end(); runner++)
    2705                         output << (*runner).second.second << endl;
    2706                 *out << Verbose(1) << "done." << endl;
    2707         } else {
    2708                 *out << Verbose(1) << "failed to open " << line << "." << endl;
    2709                 status = false;
    2710         }
    2711         output.close();
    2712 
    2713         return status;
     2668  ofstream output;
     2669  bool status =  true;
     2670  string line;
     2671
     2672  // open KeySet file
     2673  line = path;
     2674  line.append("/");
     2675  line += FRAGMENTPREFIX;
     2676  line += KEYSETFILE;
     2677  output.open(line.c_str(), ios::out);
     2678  *out << Verbose(1) << "Saving key sets of the total graph ... ";
     2679  if(output != NULL) {
     2680    for(Graph::iterator runner = KeySetList.begin(); runner != KeySetList.end(); runner++) {
     2681      for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) {
     2682        if (sprinter != (*runner).first.begin())
     2683          output << "\t";
     2684        output << *sprinter;
     2685      }
     2686      output << endl;
     2687    }
     2688    *out << "done." << endl;
     2689  } else {
     2690    cerr << "Unable to open " << line << " for writing keysets!" << endl;
     2691    status = false;
     2692  }
     2693  output.close();
     2694  output.clear();
     2695
     2696  // open TEFactors file
     2697  line = path;
     2698  line.append("/");
     2699  line += FRAGMENTPREFIX;
     2700  line += TEFACTORSFILE;
     2701  output.open(line.c_str(), ios::out);
     2702  *out << Verbose(1) << "Saving TEFactors of the total graph ... ";
     2703  if(output != NULL) {
     2704    for(Graph::iterator runner = KeySetList.begin(); runner != KeySetList.end(); runner++)
     2705      output << (*runner).second.second << endl;
     2706    *out << Verbose(1) << "done." << endl;
     2707  } else {
     2708    *out << Verbose(1) << "failed to open " << line << "." << endl;
     2709    status = false;
     2710  }
     2711  output.close();
     2712
     2713  return status;
    27142714};
    27152715
     
    27222722bool molecule::StoreAdjacencyToFile(ofstream *out, char *path)
    27232723{
    2724         ofstream AdjacencyFile;
    2725         atom *Walker = NULL;
    2726         stringstream line;
    2727         bool status = true;
    2728 
    2729         line << path << "/" << FRAGMENTPREFIX << ADJACENCYFILE;
    2730         AdjacencyFile.open(line.str().c_str(), ios::out);
    2731         *out << Verbose(1) << "Saving adjacency list ... ";
    2732         if (AdjacencyFile != NULL) {
    2733                 Walker = start;
    2734                 while(Walker->next != end) {
    2735                         Walker = Walker->next;
    2736                         AdjacencyFile << Walker->nr << "\t";
    2737                         for (int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++)
    2738                                 AdjacencyFile << ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker)->nr << "\t";
    2739                         AdjacencyFile << endl;
    2740                 }
    2741                 AdjacencyFile.close();
    2742                 *out << Verbose(1) << "done." << endl;
    2743         } else {
    2744                 *out << Verbose(1) << "failed to open file " << line.str() << "." << endl;
    2745                 status = false;
    2746         }
    2747 
    2748         return status;
     2724  ofstream AdjacencyFile;
     2725  atom *Walker = NULL;
     2726  stringstream line;
     2727  bool status = true;
     2728
     2729  line << path << "/" << FRAGMENTPREFIX << ADJACENCYFILE;
     2730  AdjacencyFile.open(line.str().c_str(), ios::out);
     2731  *out << Verbose(1) << "Saving adjacency list ... ";
     2732  if (AdjacencyFile != NULL) {
     2733    Walker = start;
     2734    while(Walker->next != end) {
     2735      Walker = Walker->next;
     2736      AdjacencyFile << Walker->nr << "\t";
     2737      for (int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++)
     2738        AdjacencyFile << ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker)->nr << "\t";
     2739      AdjacencyFile << endl;
     2740    }
     2741    AdjacencyFile.close();
     2742    *out << Verbose(1) << "done." << endl;
     2743  } else {
     2744    *out << Verbose(1) << "failed to open file " << line.str() << "." << endl;
     2745    status = false;
     2746  }
     2747
     2748  return status;
    27492749};
    27502750
     
    27572757bool molecule::CheckAdjacencyFileAgainstMolecule(ofstream *out, char *path, atom **ListOfAtoms)
    27582758{
    2759         ifstream File;
    2760         stringstream filename;
    2761         bool status = true;
    2762         char *buffer = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer");
    2763 
    2764         filename << path << "/" << FRAGMENTPREFIX << ADJACENCYFILE;
    2765         File.open(filename.str().c_str(), ios::out);
    2766         *out << Verbose(1) << "Looking at bond structure stored in adjacency file and comparing to present one ... ";
    2767         if (File != NULL) {
    2768                 // allocate storage structure
    2769                 int NonMatchNumber = 0; // will number of atoms with differing bond structure
    2770                 int *CurrentBonds = (int *) Malloc(sizeof(int)*8, "molecule::CheckAdjacencyFileAgainstMolecule - CurrentBonds"); // contains parsed bonds of current atom
    2771                 int CurrentBondsOfAtom;
    2772 
    2773                 // Parse the file line by line and count the bonds
    2774                 while (!File.eof()) {
    2775                         File.getline(buffer, MAXSTRINGSIZE);
    2776                         stringstream line;
    2777                         line.str(buffer);
    2778                         int AtomNr = -1;
    2779                         line >> AtomNr;
    2780                         CurrentBondsOfAtom = -1; // we count one too far due to line end
    2781                         // parse into structure
    2782                         if ((AtomNr >= 0) && (AtomNr < AtomCount)) {
    2783                                 while (!line.eof())
    2784                                         line >> CurrentBonds[ ++CurrentBondsOfAtom ];
    2785                                 // compare against present bonds
    2786                                 //cout << Verbose(2) << "Walker is " << *Walker << ", bond partners: ";
    2787                                 if (CurrentBondsOfAtom == NumberOfBondsPerAtom[AtomNr]) {
    2788                                         for(int i=0;i<NumberOfBondsPerAtom[AtomNr];i++) {
    2789                                                 int id = ListOfBondsPerAtom[AtomNr][i]->GetOtherAtom(ListOfAtoms[AtomNr])->nr;
    2790                                                 int j = 0;
    2791                                                 for (;(j<CurrentBondsOfAtom) && (CurrentBonds[j++] != id);); // check against all parsed bonds
    2792                                                 if (CurrentBonds[j-1] != id) { // no match ? Then mark in ListOfAtoms
    2793                                                         ListOfAtoms[AtomNr] = NULL;
    2794                                                         NonMatchNumber++;
    2795                                                         status = false;
    2796                                                         //out << "[" << id << "]\t";
    2797                                                 } else {
    2798                                                         //out << id << "\t";
    2799                                                 }
    2800                                         }
    2801                                         //out << endl;
    2802                                 } else {
    2803                                         *out << "Number of bonds for Atom " << *ListOfAtoms[AtomNr] << " does not match, parsed " << CurrentBondsOfAtom << " against " << NumberOfBondsPerAtom[AtomNr] << "." << endl;
    2804                                         status = false;
    2805                                 }
    2806                         }
    2807                 }
    2808                 File.close();
    2809                 File.clear();
    2810                 if (status) { // if equal we parse the KeySetFile
    2811                         *out << Verbose(1) << "done: Equal." << endl;
    2812                         status = true;
    2813                 } else
    2814                         *out << Verbose(1) << "done: Not equal by " << NonMatchNumber << " atoms." << endl;
    2815                 Free((void **)&CurrentBonds, "molecule::CheckAdjacencyFileAgainstMolecule - **CurrentBonds");
    2816         } else {
    2817                 *out << Verbose(1) << "Adjacency file not found." << endl;
    2818                 status = false;
    2819         }
    2820         *out << endl;
    2821         Free((void **)&buffer, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer");
    2822 
    2823         return status;
     2759  ifstream File;
     2760  stringstream filename;
     2761  bool status = true;
     2762  char *buffer = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer");
     2763
     2764  filename << path << "/" << FRAGMENTPREFIX << ADJACENCYFILE;
     2765  File.open(filename.str().c_str(), ios::out);
     2766  *out << Verbose(1) << "Looking at bond structure stored in adjacency file and comparing to present one ... ";
     2767  if (File != NULL) {
     2768    // allocate storage structure
     2769    int NonMatchNumber = 0;  // will number of atoms with differing bond structure
     2770    int *CurrentBonds = (int *) Malloc(sizeof(int)*8, "molecule::CheckAdjacencyFileAgainstMolecule - CurrentBonds"); // contains parsed bonds of current atom
     2771    int CurrentBondsOfAtom;
     2772
     2773    // Parse the file line by line and count the bonds
     2774    while (!File.eof()) {
     2775      File.getline(buffer, MAXSTRINGSIZE);
     2776      stringstream line;
     2777      line.str(buffer);
     2778      int AtomNr = -1;
     2779      line >> AtomNr;
     2780      CurrentBondsOfAtom = -1; // we count one too far due to line end
     2781      // parse into structure
     2782      if ((AtomNr >= 0) && (AtomNr < AtomCount)) {
     2783        while (!line.eof())
     2784          line >> CurrentBonds[ ++CurrentBondsOfAtom ];
     2785        // compare against present bonds
     2786        //cout << Verbose(2) << "Walker is " << *Walker << ", bond partners: ";
     2787        if (CurrentBondsOfAtom == NumberOfBondsPerAtom[AtomNr]) {
     2788          for(int i=0;i<NumberOfBondsPerAtom[AtomNr];i++) {
     2789            int id = ListOfBondsPerAtom[AtomNr][i]->GetOtherAtom(ListOfAtoms[AtomNr])->nr;
     2790            int j = 0;
     2791            for (;(j<CurrentBondsOfAtom) && (CurrentBonds[j++] != id);); // check against all parsed bonds
     2792            if (CurrentBonds[j-1] != id) { // no match ? Then mark in ListOfAtoms
     2793              ListOfAtoms[AtomNr] = NULL;
     2794              NonMatchNumber++;
     2795              status = false;
     2796              //out << "[" << id << "]\t";
     2797            } else {
     2798              //out << id << "\t";
     2799            }
     2800          }
     2801          //out << endl;
     2802        } else {
     2803          *out << "Number of bonds for Atom " << *ListOfAtoms[AtomNr] << " does not match, parsed " << CurrentBondsOfAtom << " against " << NumberOfBondsPerAtom[AtomNr] << "." << endl;
     2804          status = false;
     2805        }
     2806      }
     2807    }
     2808    File.close();
     2809    File.clear();
     2810    if (status) { // if equal we parse the KeySetFile
     2811      *out << Verbose(1) << "done: Equal." << endl;
     2812      status = true;
     2813    } else
     2814      *out << Verbose(1) << "done: Not equal by " << NonMatchNumber << " atoms." << endl;
     2815    Free((void **)&CurrentBonds, "molecule::CheckAdjacencyFileAgainstMolecule - **CurrentBonds");
     2816  } else {
     2817    *out << Verbose(1) << "Adjacency file not found." << endl;
     2818    status = false;
     2819  }
     2820  *out << endl;
     2821  Free((void **)&buffer, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer");
     2822
     2823  return status;
    28242824};
    28252825
     
    28352835bool molecule::CheckOrderAtSite(ofstream *out, bool *AtomMask, Graph *GlobalKeySetList, int Order, int *MinimumRingSize, char *path)
    28362836{
    2837         atom *Walker = start;
    2838         bool status = false;
    2839         ifstream InputFile;
    2840 
    2841         // initialize mask list
    2842         for(int i=AtomCount;i--;)
    2843                 AtomMask[i] = false;
    2844 
    2845         if (Order < 0) { // adaptive increase of BondOrder per site
    2846                 if (AtomMask[AtomCount] == true)        // break after one step
    2847                         return false;
    2848                 // parse the EnergyPerFragment file
    2849                 char *buffer = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::CheckOrderAtSite: *buffer");
    2850                 sprintf(buffer, "%s/%s%s.dat", path, FRAGMENTPREFIX, ENERGYPERFRAGMENT);
    2851                 InputFile.open(buffer, ios::in);
    2852                 if ((InputFile != NULL) && (GlobalKeySetList != NULL)) {
    2853                         // transmorph graph keyset list into indexed KeySetList
    2854                         map<int,KeySet> IndexKeySetList;
    2855                         for(Graph::iterator runner = GlobalKeySetList->begin(); runner != GlobalKeySetList->end(); runner++) {
    2856                                 IndexKeySetList.insert( pair<int,KeySet>(runner->second.first,runner->first) );
    2857                         }
    2858                         int lines = 0;
    2859                         // count the number of lines, i.e. the number of fragments
    2860                         InputFile.getline(buffer, MAXSTRINGSIZE); // skip comment lines
    2861                         InputFile.getline(buffer, MAXSTRINGSIZE);
    2862                         while(!InputFile.eof()) {
    2863                                 InputFile.getline(buffer, MAXSTRINGSIZE);
    2864                                 lines++;
    2865                         }
    2866                         //*out << Verbose(2) << "Scanned " << lines-1 << " lines." << endl;      // one endline too much
    2867                         InputFile.clear();
    2868                         InputFile.seekg(ios::beg);
    2869                         map<int, pair<double,int> > AdaptiveCriteriaList;       // (Root No., (Value, Order)) !
    2870                         int No, FragOrder;
    2871                         double Value;
    2872                         // each line represents a fragment root (Atom::nr) id and its energy contribution
    2873                         InputFile.getline(buffer, MAXSTRINGSIZE); // skip comment lines
    2874                         InputFile.getline(buffer, MAXSTRINGSIZE);
    2875                         while(!InputFile.eof()) {
    2876                                 InputFile.getline(buffer, MAXSTRINGSIZE);
    2877                                 if (strlen(buffer) > 2) {
    2878                                         //*out << Verbose(2) << "Scanning: " << buffer << endl;
    2879                                         stringstream line(buffer);
    2880                                         line >> FragOrder;
    2881                                         line >> ws >> No;
    2882                                         line >> ws >> Value; // skip time entry
    2883                                         line >> ws >> Value;
    2884                                         No -= 1;        // indices start at 1 in file, not 0
    2885                                         //*out << Verbose(2) << " - yields (" << No << "," << Value << ", " << FragOrder << ")" << endl;
    2886 
    2887                                         // clean the list of those entries that have been superceded by higher order terms already
    2888                                         map<int,KeySet>::iterator marker = IndexKeySetList.find(No);            // find keyset to Frag No.
    2889                                         if (marker != IndexKeySetList.end()) {  // if found
    2890                                                 Value *= 1 + MYEPSILON*(*((*marker).second.begin()));            // in case of equal energies this makes em not equal without changing anything actually
    2891                                                 // as the smallest number in each set has always been the root (we use global id to keep the doubles away), seek smallest and insert into AtomMask
    2892                                                 pair <map<int, pair<double,int> >::iterator, bool> InsertedElement = AdaptiveCriteriaList.insert( make_pair(*((*marker).second.begin()), pair<double,int>( fabs(Value), FragOrder) ));
    2893                                                 map<int, pair<double,int> >::iterator PresentItem = InsertedElement.first;
    2894                                                 if (!InsertedElement.second) { // this root is already present
    2895                                                         if ((*PresentItem).second.second < FragOrder)   // if order there is lower, update entry with higher-order term
    2896                                                                 //if ((*PresentItem).second.first < (*runner).first)            // as higher-order terms are not always better, we skip this part (which would always include this site into adaptive increase)
    2897                                                                 {       // if value is smaller, update value and order
    2898                                                                 (*PresentItem).second.first = fabs(Value);
    2899                                                                 (*PresentItem).second.second = FragOrder;
    2900                                                                 *out << Verbose(2) << "Updated element (" <<    (*PresentItem).first << ",[" << (*PresentItem).second.first << "," << (*PresentItem).second.second << "])." << endl;
    2901                                                         } else {
    2902                                                                 *out << Verbose(2) << "Did not update element " <<      (*PresentItem).first << " as " << FragOrder << " is less than or equal to " << (*PresentItem).second.second << "." << endl;
    2903                                                         }
    2904                                                 } else {
    2905                                                         *out << Verbose(2) << "Inserted element (" <<   (*PresentItem).first << ",[" << (*PresentItem).second.first << "," << (*PresentItem).second.second << "])." << endl;
    2906                                                 }
    2907                                         } else {
    2908                                                 *out << Verbose(1) << "No Fragment under No. " << No << "found." << endl;
    2909                                         }
    2910                                 }
    2911                         }
    2912                         // then map back onto (Value, (Root Nr., Order)) (i.e. sorted by value to pick the highest ones)
    2913                         map<double, pair<int,int> > FinalRootCandidates;
    2914                         *out << Verbose(1) << "Root candidate list is: " << endl;
    2915                         for(map<int, pair<double,int> >::iterator runner = AdaptiveCriteriaList.begin(); runner != AdaptiveCriteriaList.end(); runner++) {
    2916                                 Walker = FindAtom((*runner).first);
    2917                                 if (Walker != NULL) {
    2918                                         //if ((*runner).second.second >= Walker->AdaptiveOrder) { // only insert if this is an "active" root site for the current order
    2919                                         if (!Walker->MaxOrder) {
    2920                                                 *out << Verbose(2) << "(" << (*runner).first << ",[" << (*runner).second.first << "," << (*runner).second.second << "])" << endl;
    2921                                                 FinalRootCandidates.insert( make_pair( (*runner).second.first, pair<int,int>((*runner).first, (*runner).second.second) ) );
    2922                                         } else {
    2923                                                 *out << Verbose(2) << "Excluding (" << *Walker << ", " << (*runner).first << ",[" << (*runner).second.first << "," << (*runner).second.second << "]), as it has reached its maximum order." << endl;
    2924                                         }
    2925                                 } else {
    2926                                         cerr << "Atom No. " << (*runner).second.first << " was not found in this molecule." << endl;
    2927                                 }
    2928                         }
    2929                         // pick the ones still below threshold and mark as to be adaptively updated
    2930                         for(map<double, pair<int,int> >::iterator runner = FinalRootCandidates.upper_bound(pow(10.,Order)); runner != FinalRootCandidates.end(); runner++) {
    2931                                 No = (*runner).second.first;
    2932                                 Walker = FindAtom(No);
    2933                                 //if (Walker->AdaptiveOrder < MinimumRingSize[Walker->nr]) {
    2934                                         *out << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", setting entry " << No << " of Atom mask to true." << endl;
    2935                                         AtomMask[No] = true;
    2936                                         status = true;
    2937                                 //} else
    2938                                         //*out << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", however MinimumRingSize of " << MinimumRingSize[Walker->nr] << " does not allow further adaptive increase." << endl;
    2939                         }
    2940                         // close and done
    2941                         InputFile.close();
    2942                         InputFile.clear();
    2943                 } else {
    2944                         cerr << "Unable to parse " << buffer << " file, incrementing all." << endl;
    2945                         while (Walker->next != end) {
    2946                                 Walker = Walker->next;
    2947                 #ifdef ADDHYDROGEN
    2948                                 if (Walker->type->Z != 1) // skip hydrogen
    2949                 #endif
    2950                                 {
    2951                                         AtomMask[Walker->nr] = true;    // include all (non-hydrogen) atoms
    2952                                         status = true;
    2953                                 }
    2954                         }
    2955                 }
    2956                 Free((void **)&buffer, "molecule::CheckOrderAtSite: *buffer");
    2957                 // pick a given number of highest values and set AtomMask
    2958         } else { // global increase of Bond Order
    2959                 while (Walker->next != end) {
    2960                         Walker = Walker->next;
    2961         #ifdef ADDHYDROGEN
    2962                         if (Walker->type->Z != 1) // skip hydrogen
    2963         #endif
    2964                         {
    2965                                 AtomMask[Walker->nr] = true;    // include all (non-hydrogen) atoms
    2966                                 if ((Order != 0) && (Walker->AdaptiveOrder < Order)) // && (Walker->AdaptiveOrder < MinimumRingSize[Walker->nr]))
    2967                                         status = true;
    2968                         }
    2969                 }
    2970                 if ((Order == 0) && (AtomMask[AtomCount] == false))     // single stepping, just check
    2971                         status = true;
    2972 
    2973                 if (!status) {
    2974                         if (Order == 0)
    2975                                 *out << Verbose(1) << "Single stepping done." << endl;
    2976                         else
    2977                                 *out << Verbose(1) << "Order at every site is already equal or above desired order " << Order << "." << endl;
    2978                 }
    2979         }
    2980 
    2981         // print atom mask for debugging
    2982         *out << "                                                       ";
    2983         for(int i=0;i<AtomCount;i++)
    2984                 *out << (i % 10);
    2985         *out << endl << "Atom mask is: ";
    2986         for(int i=0;i<AtomCount;i++)
    2987                 *out << (AtomMask[i] ? "t" : "f");
    2988         *out << endl;
    2989 
    2990         return status;
     2837  atom *Walker = start;
     2838  bool status = false;
     2839  ifstream InputFile;
     2840
     2841  // initialize mask list
     2842  for(int i=AtomCount;i--;)
     2843    AtomMask[i] = false;
     2844
     2845  if (Order < 0) { // adaptive increase of BondOrder per site
     2846    if (AtomMask[AtomCount] == true)  // break after one step
     2847      return false;
     2848    // parse the EnergyPerFragment file
     2849    char *buffer = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::CheckOrderAtSite: *buffer");
     2850    sprintf(buffer, "%s/%s%s.dat", path, FRAGMENTPREFIX, ENERGYPERFRAGMENT);
     2851    InputFile.open(buffer, ios::in);
     2852    if ((InputFile != NULL) && (GlobalKeySetList != NULL)) {
     2853      // transmorph graph keyset list into indexed KeySetList
     2854      map<int,KeySet> IndexKeySetList;
     2855      for(Graph::iterator runner = GlobalKeySetList->begin(); runner != GlobalKeySetList->end(); runner++) {
     2856        IndexKeySetList.insert( pair<int,KeySet>(runner->second.first,runner->first) );
     2857      }
     2858      int lines = 0;
     2859      // count the number of lines, i.e. the number of fragments
     2860      InputFile.getline(buffer, MAXSTRINGSIZE); // skip comment lines
     2861      InputFile.getline(buffer, MAXSTRINGSIZE);
     2862      while(!InputFile.eof()) {
     2863        InputFile.getline(buffer, MAXSTRINGSIZE);
     2864        lines++;
     2865      }
     2866      //*out << Verbose(2) << "Scanned " << lines-1 << " lines." << endl;  // one endline too much
     2867      InputFile.clear();
     2868      InputFile.seekg(ios::beg);
     2869      map<int, pair<double,int> > AdaptiveCriteriaList;  // (Root No., (Value, Order)) !
     2870      int No, FragOrder;
     2871      double Value;
     2872      // each line represents a fragment root (Atom::nr) id and its energy contribution
     2873      InputFile.getline(buffer, MAXSTRINGSIZE); // skip comment lines
     2874      InputFile.getline(buffer, MAXSTRINGSIZE);
     2875      while(!InputFile.eof()) {
     2876        InputFile.getline(buffer, MAXSTRINGSIZE);
     2877        if (strlen(buffer) > 2) {
     2878          //*out << Verbose(2) << "Scanning: " << buffer << endl;
     2879          stringstream line(buffer);
     2880          line >> FragOrder;
     2881          line >> ws >> No;
     2882          line >> ws >> Value; // skip time entry
     2883          line >> ws >> Value;
     2884          No -= 1;  // indices start at 1 in file, not 0
     2885          //*out << Verbose(2) << " - yields (" << No << "," << Value << ", " << FragOrder << ")" << endl;
     2886
     2887          // clean the list of those entries that have been superceded by higher order terms already
     2888          map<int,KeySet>::iterator marker = IndexKeySetList.find(No);    // find keyset to Frag No.
     2889          if (marker != IndexKeySetList.end()) {  // if found
     2890            Value *= 1 + MYEPSILON*(*((*marker).second.begin()));    // in case of equal energies this makes em not equal without changing anything actually
     2891            // as the smallest number in each set has always been the root (we use global id to keep the doubles away), seek smallest and insert into AtomMask
     2892            pair <map<int, pair<double,int> >::iterator, bool> InsertedElement = AdaptiveCriteriaList.insert( make_pair(*((*marker).second.begin()), pair<double,int>( fabs(Value), FragOrder) ));
     2893            map<int, pair<double,int> >::iterator PresentItem = InsertedElement.first;
     2894            if (!InsertedElement.second) { // this root is already present
     2895              if ((*PresentItem).second.second < FragOrder)  // if order there is lower, update entry with higher-order term
     2896                //if ((*PresentItem).second.first < (*runner).first)    // as higher-order terms are not always better, we skip this part (which would always include this site into adaptive increase)
     2897                {  // if value is smaller, update value and order
     2898                (*PresentItem).second.first = fabs(Value);
     2899                (*PresentItem).second.second = FragOrder;
     2900                *out << Verbose(2) << "Updated element (" <<  (*PresentItem).first << ",[" << (*PresentItem).second.first << "," << (*PresentItem).second.second << "])." << endl;
     2901              } else {
     2902                *out << Verbose(2) << "Did not update element " <<  (*PresentItem).first << " as " << FragOrder << " is less than or equal to " << (*PresentItem).second.second << "." << endl;
     2903              }
     2904            } else {
     2905              *out << Verbose(2) << "Inserted element (" <<  (*PresentItem).first << ",[" << (*PresentItem).second.first << "," << (*PresentItem).second.second << "])." << endl;
     2906            }
     2907          } else {
     2908            *out << Verbose(1) << "No Fragment under No. " << No << "found." << endl;
     2909          }
     2910        }
     2911      }
     2912      // then map back onto (Value, (Root Nr., Order)) (i.e. sorted by value to pick the highest ones)
     2913      map<double, pair<int,int> > FinalRootCandidates;
     2914      *out << Verbose(1) << "Root candidate list is: " << endl;
     2915      for(map<int, pair<double,int> >::iterator runner = AdaptiveCriteriaList.begin(); runner != AdaptiveCriteriaList.end(); runner++) {
     2916        Walker = FindAtom((*runner).first);
     2917        if (Walker != NULL) {
     2918          //if ((*runner).second.second >= Walker->AdaptiveOrder) { // only insert if this is an "active" root site for the current order
     2919          if (!Walker->MaxOrder) {
     2920            *out << Verbose(2) << "(" << (*runner).first << ",[" << (*runner).second.first << "," << (*runner).second.second << "])" << endl;
     2921            FinalRootCandidates.insert( make_pair( (*runner).second.first, pair<int,int>((*runner).first, (*runner).second.second) ) );
     2922          } else {
     2923            *out << Verbose(2) << "Excluding (" << *Walker << ", " << (*runner).first << ",[" << (*runner).second.first << "," << (*runner).second.second << "]), as it has reached its maximum order." << endl;
     2924          }
     2925        } else {
     2926          cerr << "Atom No. " << (*runner).second.first << " was not found in this molecule." << endl;
     2927        }
     2928      }
     2929      // pick the ones still below threshold and mark as to be adaptively updated
     2930      for(map<double, pair<int,int> >::iterator runner = FinalRootCandidates.upper_bound(pow(10.,Order)); runner != FinalRootCandidates.end(); runner++) {
     2931        No = (*runner).second.first;
     2932        Walker = FindAtom(No);
     2933        //if (Walker->AdaptiveOrder < MinimumRingSize[Walker->nr]) {
     2934          *out << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", setting entry " << No << " of Atom mask to true." << endl;
     2935          AtomMask[No] = true;
     2936          status = true;
     2937        //} else
     2938          //*out << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", however MinimumRingSize of " << MinimumRingSize[Walker->nr] << " does not allow further adaptive increase." << endl;
     2939      }
     2940      // close and done
     2941      InputFile.close();
     2942      InputFile.clear();
     2943    } else {
     2944      cerr << "Unable to parse " << buffer << " file, incrementing all." << endl;
     2945      while (Walker->next != end) {
     2946        Walker = Walker->next;
     2947    #ifdef ADDHYDROGEN
     2948        if (Walker->type->Z != 1) // skip hydrogen
     2949    #endif
     2950        {
     2951          AtomMask[Walker->nr] = true;  // include all (non-hydrogen) atoms
     2952          status = true;
     2953        }
     2954      }
     2955    }
     2956    Free((void **)&buffer, "molecule::CheckOrderAtSite: *buffer");
     2957    // pick a given number of highest values and set AtomMask
     2958  } else { // global increase of Bond Order
     2959    while (Walker->next != end) {
     2960      Walker = Walker->next;
     2961  #ifdef ADDHYDROGEN
     2962      if (Walker->type->Z != 1) // skip hydrogen
     2963  #endif
     2964      {
     2965        AtomMask[Walker->nr] = true;  // include all (non-hydrogen) atoms
     2966        if ((Order != 0) && (Walker->AdaptiveOrder < Order)) // && (Walker->AdaptiveOrder < MinimumRingSize[Walker->nr]))
     2967          status = true;
     2968      }
     2969    }
     2970    if ((Order == 0) && (AtomMask[AtomCount] == false))  // single stepping, just check
     2971      status = true;
     2972
     2973    if (!status) {
     2974      if (Order == 0)
     2975        *out << Verbose(1) << "Single stepping done." << endl;
     2976      else
     2977        *out << Verbose(1) << "Order at every site is already equal or above desired order " << Order << "." << endl;
     2978    }
     2979  }
     2980
     2981  // print atom mask for debugging
     2982  *out << "              ";
     2983  for(int i=0;i<AtomCount;i++)
     2984    *out << (i % 10);
     2985  *out << endl << "Atom mask is: ";
     2986  for(int i=0;i<AtomCount;i++)
     2987    *out << (AtomMask[i] ? "t" : "f");
     2988  *out << endl;
     2989
     2990  return status;
    29912991};
    29922992
     
    29982998bool molecule::CreateMappingLabelsToConfigSequence(ofstream *out, int *&SortIndex)
    29992999{
    3000         element *runner = elemente->start;
    3001         int AtomNo = 0;
    3002         atom *Walker = NULL;
    3003 
    3004         if (SortIndex != NULL) {
    3005                 *out << Verbose(1) << "SortIndex is " << SortIndex << " and not NULL as expected." << endl;
    3006                 return false;
    3007         }
    3008         SortIndex = (int *) Malloc(sizeof(int)*AtomCount, "molecule::FragmentMolecule: *SortIndex");
    3009         for(int i=AtomCount;i--;)
    3010                 SortIndex[i] = -1;
    3011         while (runner->next != elemente->end) { // go through every element
    3012                 runner = runner->next;
    3013                 if (ElementsInMolecule[runner->Z]) { // if this element got atoms
    3014                         Walker = start;
    3015                         while (Walker->next != end) { // go through every atom of this element
    3016                                 Walker = Walker->next;
    3017                                 if (Walker->type->Z == runner->Z) // if this atom fits to element
    3018                                         SortIndex[Walker->nr] = AtomNo++;
    3019                         }
    3020                 }
    3021         }
    3022         return true;
     3000  element *runner = elemente->start;
     3001  int AtomNo = 0;
     3002  atom *Walker = NULL;
     3003
     3004  if (SortIndex != NULL) {
     3005    *out << Verbose(1) << "SortIndex is " << SortIndex << " and not NULL as expected." << endl;
     3006    return false;
     3007  }
     3008  SortIndex = (int *) Malloc(sizeof(int)*AtomCount, "molecule::FragmentMolecule: *SortIndex");
     3009  for(int i=AtomCount;i--;)
     3010    SortIndex[i] = -1;
     3011  while (runner->next != elemente->end) { // go through every element
     3012    runner = runner->next;
     3013    if (ElementsInMolecule[runner->Z]) { // if this element got atoms
     3014      Walker = start;
     3015      while (Walker->next != end) { // go through every atom of this element
     3016        Walker = Walker->next;
     3017        if (Walker->type->Z == runner->Z) // if this atom fits to element
     3018          SortIndex[Walker->nr] = AtomNo++;
     3019      }
     3020    }
     3021  }
     3022  return true;
    30233023};
    30243024
     
    30293029y contribution", and that's why this consciously not done in the following loop)
    30303030 * -# in a loop over all subgraphs
    3031  *      -# calls FragmentBOSSANOVA with this RootStack and within the subgraph molecule structure
    3032  *      -# creates molecule (fragment)s from the returned keysets (StoreFragmentFromKeySet)
     3031 *  -# calls FragmentBOSSANOVA with this RootStack and within the subgraph molecule structure
     3032 *  -# creates molecule (fragment)s from the returned keysets (StoreFragmentFromKeySet)
    30333033 * -# combines the generated molecule lists from all subgraphs
    30343034 * -# saves to disk: fragment configs, adjacency, orderatsite, keyset files
     
    30433043int molecule::FragmentMolecule(ofstream *out, int Order, config *configuration)
    30443044{
    3045         MoleculeListClass *BondFragments = NULL;
    3046         int *SortIndex = NULL;
    3047         int *MinimumRingSize = new int[AtomCount];
    3048         int FragmentCounter;
    3049         MoleculeLeafClass *MolecularWalker = NULL;
    3050         MoleculeLeafClass *Subgraphs = NULL;                    // list of subgraphs from DFS analysis
    3051         fstream File;
    3052         bool FragmentationToDo = true;
    3053         class StackClass<bond *> *BackEdgeStack = NULL, *LocalBackEdgeStack = NULL;
    3054         bool CheckOrder = false;
    3055         Graph **FragmentList = NULL;
    3056         Graph *ParsedFragmentList = NULL;
    3057         Graph TotalGraph;                // graph with all keysets however local numbers
    3058         int TotalNumberOfKeySets = 0;
    3059         atom **ListOfAtoms = NULL;
    3060         atom ***ListOfLocalAtoms = NULL;
    3061         bool *AtomMask = NULL;
    3062 
    3063         *out << endl;
     3045  MoleculeListClass *BondFragments = NULL;
     3046  int *SortIndex = NULL;
     3047  int *MinimumRingSize = new int[AtomCount];
     3048  int FragmentCounter;
     3049  MoleculeLeafClass *MolecularWalker = NULL;
     3050  MoleculeLeafClass *Subgraphs = NULL;      // list of subgraphs from DFS analysis
     3051  fstream File;
     3052  bool FragmentationToDo = true;
     3053  class StackClass<bond *> *BackEdgeStack = NULL, *LocalBackEdgeStack = NULL;
     3054  bool CheckOrder = false;
     3055  Graph **FragmentList = NULL;
     3056  Graph *ParsedFragmentList = NULL;
     3057  Graph TotalGraph;    // graph with all keysets however local numbers
     3058  int TotalNumberOfKeySets = 0;
     3059  atom **ListOfAtoms = NULL;
     3060  atom ***ListOfLocalAtoms = NULL;
     3061  bool *AtomMask = NULL;
     3062
     3063  *out << endl;
    30643064#ifdef ADDHYDROGEN
    3065         *out << Verbose(0) << "I will treat hydrogen special and saturate dangling bonds with it." << endl;
     3065  *out << Verbose(0) << "I will treat hydrogen special and saturate dangling bonds with it." << endl;
    30663066#else
    3067         *out << Verbose(0) << "Hydrogen is treated just like the rest of the lot." << endl;
     3067  *out << Verbose(0) << "Hydrogen is treated just like the rest of the lot." << endl;
    30683068#endif
    30693069
    3070         // ++++++++++++++++++++++++++++ INITIAL STUFF: Bond structure analysis, file parsing, ... ++++++++++++++++++++++++++++++++++++++++++
    3071 
    3072         // ===== 1. Check whether bond structure is same as stored in files ====
    3073 
    3074         // fill the adjacency list
    3075         CreateListOfBondsPerAtom(out);
    3076 
    3077         // create lookup table for Atom::nr
    3078         FragmentationToDo = FragmentationToDo && CreateFatherLookupTable(out, start, end, ListOfAtoms, AtomCount);
    3079 
    3080         // === compare it with adjacency file ===
    3081         FragmentationToDo = FragmentationToDo && CheckAdjacencyFileAgainstMolecule(out, configuration->configpath, ListOfAtoms);
    3082         Free((void **)&ListOfAtoms, "molecule::FragmentMolecule - **ListOfAtoms");
    3083 
    3084         // ===== 2. perform a DFS analysis to gather info on cyclic structure and a list of disconnected subgraphs =====
    3085         Subgraphs = DepthFirstSearchAnalysis(out, BackEdgeStack);
    3086         // fill the bond structure of the individually stored subgraphs
    3087         Subgraphs->next->FillBondStructureFromReference(out, this, (FragmentCounter = 0), ListOfLocalAtoms, false);     // we want to keep the created ListOfLocalAtoms
    3088         // analysis of the cycles (print rings, get minimum cycle length) for each subgraph
    3089         for(int i=AtomCount;i--;)
    3090                 MinimumRingSize[i] = AtomCount;
    3091         MolecularWalker = Subgraphs;
    3092         FragmentCounter = 0;
    3093         while (MolecularWalker->next != NULL) {
    3094                 MolecularWalker = MolecularWalker->next;
    3095                 LocalBackEdgeStack = new StackClass<bond *> (MolecularWalker->Leaf->BondCount);
    3096 //              // check the list of local atoms for debugging
    3097 //              *out << Verbose(0) << "ListOfLocalAtoms for this subgraph is:" << endl;
    3098 //              for (int i=0;i<AtomCount;i++)
    3099 //                      if (ListOfLocalAtoms[FragmentCounter][i] == NULL)
    3100 //                              *out << "\tNULL";
    3101 //                      else
    3102 //                              *out << "\t" << ListOfLocalAtoms[FragmentCounter][i]->Name;
    3103                 *out << Verbose(0) << "Gathering local back edges for subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
    3104                 MolecularWalker->Leaf->PickLocalBackEdges(out, ListOfLocalAtoms[FragmentCounter++], BackEdgeStack, LocalBackEdgeStack);
    3105                 *out << Verbose(0) << "Analysing the cycles of subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
    3106                 MolecularWalker->Leaf->CyclicStructureAnalysis(out, LocalBackEdgeStack, MinimumRingSize);
    3107                 *out << Verbose(0) << "Done with Analysing the cycles of subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
    3108                 delete(LocalBackEdgeStack);
    3109         }
    3110 
    3111         // ===== 3. if structure still valid, parse key set file and others =====
    3112         FragmentationToDo = FragmentationToDo && ParseKeySetFile(out, configuration->configpath, ParsedFragmentList);
    3113 
    3114         // ===== 4. check globally whether there's something to do actually (first adaptivity check)
    3115         FragmentationToDo = FragmentationToDo && ParseOrderAtSiteFromFile(out, configuration->configpath);
    3116 
    3117         // =================================== Begin of FRAGMENTATION ===============================
    3118         // ===== 6a. assign each keyset to its respective subgraph =====
    3119         Subgraphs->next->AssignKeySetsToFragment(out, this, ParsedFragmentList, ListOfLocalAtoms, FragmentList, (FragmentCounter = 0), true);
    3120 
    3121         // ===== 6b. prepare and go into the adaptive (Order<0), single-step (Order==0) or incremental (Order>0) cycle
    3122         KeyStack *RootStack = new KeyStack[Subgraphs->next->Count()];
    3123         AtomMask = new bool[AtomCount+1];
    3124         AtomMask[AtomCount] = false;
    3125         FragmentationToDo = false;      // if CheckOrderAtSite just ones recommends fragmentation, we will save fragments afterwards
    3126         while ((CheckOrder = CheckOrderAtSite(out, AtomMask, ParsedFragmentList, Order, MinimumRingSize, configuration->configpath))) {
    3127                 FragmentationToDo = FragmentationToDo || CheckOrder;
    3128                 AtomMask[AtomCount] = true;      // last plus one entry is used as marker that we have been through this loop once already in CheckOrderAtSite()
    3129                 // ===== 6b. fill RootStack for each subgraph (second adaptivity check) =====
    3130                 Subgraphs->next->FillRootStackForSubgraphs(out, RootStack, AtomMask, (FragmentCounter = 0));
    3131 
    3132                 // ===== 7. fill the bond fragment list =====
    3133                 FragmentCounter = 0;
    3134                 MolecularWalker = Subgraphs;
    3135                 while (MolecularWalker->next != NULL) {
    3136                         MolecularWalker = MolecularWalker->next;
    3137                         *out << Verbose(1) << "Fragmenting subgraph " << MolecularWalker << "." << endl;
    3138                         //MolecularWalker->Leaf->OutputListOfBonds(out);        // output ListOfBondsPerAtom for debugging
    3139                         if (MolecularWalker->Leaf->first->next != MolecularWalker->Leaf->last) {
    3140                                 // call BOSSANOVA method
    3141                                 *out << Verbose(0) << endl << " ========== BOND ENERGY of subgraph " << FragmentCounter << " ========================= " << endl;
    3142                                 MolecularWalker->Leaf->FragmentBOSSANOVA(out, FragmentList[FragmentCounter], RootStack[FragmentCounter], MinimumRingSize);
    3143                         } else {
    3144                                 cerr << "Subgraph " << MolecularWalker << " has no atoms!" << endl;
    3145                         }
    3146                         FragmentCounter++;      // next fragment list
    3147                 }
    3148         }
    3149         delete[](RootStack);
    3150         delete[](AtomMask);
    3151         delete(ParsedFragmentList);
    3152         delete[](MinimumRingSize);
    3153 
    3154 
    3155         // ==================================== End of FRAGMENTATION ============================================
    3156 
    3157         // ===== 8a. translate list into global numbers (i.e. ones that are valid in "this" molecule, not in MolecularWalker->Leaf)
    3158         Subgraphs->next->TranslateIndicesToGlobalIDs(out, FragmentList, (FragmentCounter = 0), TotalNumberOfKeySets, TotalGraph);
    3159 
    3160         // free subgraph memory again
    3161         FragmentCounter = 0;
    3162         if (Subgraphs != NULL) {
    3163                 while (Subgraphs->next != NULL) {
    3164                         Subgraphs = Subgraphs->next;
    3165                         delete(FragmentList[FragmentCounter++]);
    3166                         delete(Subgraphs->previous);
    3167                 }
    3168                 delete(Subgraphs);
    3169         }
    3170         Free((void **)&FragmentList, "molecule::FragmentMolecule - **FragmentList");
    3171 
    3172         // ===== 8b. gather keyset lists (graphs) from all subgraphs and transform into MoleculeListClass =====
    3173         //if (FragmentationToDo) {              // we should always store the fragments again as coordination might have changed slightly without changing bond structure
    3174                 // allocate memory for the pointer array and transmorph graphs into full molecular fragments
    3175                 BondFragments = new MoleculeListClass();
    3176                 int k=0;
    3177                 for(Graph::iterator runner = TotalGraph.begin(); runner != TotalGraph.end(); runner++) {
    3178                         KeySet test = (*runner).first;
    3179                         *out << "Fragment No." << (*runner).second.first << " with TEFactor " << (*runner).second.second << "." << endl;
    3180                         BondFragments->insert(StoreFragmentFromKeySet(out, test, configuration));
    3181                         k++;
    3182                 }
    3183                 *out << k << "/" << BondFragments->ListOfMolecules.size() << " fragments generated from the keysets." << endl;
    3184 
    3185                 // ===== 9. Save fragments' configuration and keyset files et al to disk ===
    3186                 if (BondFragments->ListOfMolecules.size() != 0) {
    3187                         // create the SortIndex from BFS labels to order in the config file
    3188                         CreateMappingLabelsToConfigSequence(out, SortIndex);
    3189 
    3190                         *out << Verbose(1) << "Writing " << BondFragments->ListOfMolecules.size() << " possible bond fragmentation configs" << endl;
    3191                         if (BondFragments->OutputConfigForListOfFragments(out, configuration, SortIndex))
    3192                                 *out << Verbose(1) << "All configs written." << endl;
    3193                         else
    3194                                 *out << Verbose(1) << "Some config writing failed." << endl;
    3195 
    3196                         // store force index reference file
    3197                         BondFragments->StoreForcesFile(out, configuration->configpath, SortIndex);
    3198 
    3199                         // store keysets file
    3200                         StoreKeySetFile(out, TotalGraph, configuration->configpath);
    3201 
    3202                         // store Adjacency file
    3203                         StoreAdjacencyToFile(out, configuration->configpath);
    3204 
    3205                         // store Hydrogen saturation correction file
    3206                         BondFragments->AddHydrogenCorrection(out, configuration->configpath);
    3207 
    3208                         // store adaptive orders into file
    3209                         StoreOrderAtSiteFile(out, configuration->configpath);
    3210 
    3211                         // restore orbital and Stop values
    3212                         CalculateOrbitals(*configuration);
    3213 
    3214                         // free memory for bond part
    3215                         *out << Verbose(1) << "Freeing bond memory" << endl;
    3216                         delete(FragmentList); // remove bond molecule from memory
    3217                         Free((void **)&SortIndex, "molecule::FragmentMolecule: *SortIndex");
    3218                 } else
    3219                         *out << Verbose(1) << "FragmentList is zero on return, splitting failed." << endl;
    3220         //} else
    3221         //      *out << Verbose(1) << "No fragments to store." << endl;
    3222         *out << Verbose(0) << "End of bond fragmentation." << endl;
    3223 
    3224         return ((int)(!FragmentationToDo)+1);           // 1 - continue, 2 - stop (no fragmentation occured)
     3070  // ++++++++++++++++++++++++++++ INITIAL STUFF: Bond structure analysis, file parsing, ... ++++++++++++++++++++++++++++++++++++++++++
     3071
     3072  // ===== 1. Check whether bond structure is same as stored in files ====
     3073
     3074  // fill the adjacency list
     3075  CreateListOfBondsPerAtom(out);
     3076
     3077  // create lookup table for Atom::nr
     3078  FragmentationToDo = FragmentationToDo && CreateFatherLookupTable(out, start, end, ListOfAtoms, AtomCount);
     3079
     3080  // === compare it with adjacency file ===
     3081  FragmentationToDo = FragmentationToDo && CheckAdjacencyFileAgainstMolecule(out, configuration->configpath, ListOfAtoms);
     3082  Free((void **)&ListOfAtoms, "molecule::FragmentMolecule - **ListOfAtoms");
     3083
     3084  // ===== 2. perform a DFS analysis to gather info on cyclic structure and a list of disconnected subgraphs =====
     3085  Subgraphs = DepthFirstSearchAnalysis(out, BackEdgeStack);
     3086  // fill the bond structure of the individually stored subgraphs
     3087  Subgraphs->next->FillBondStructureFromReference(out, this, (FragmentCounter = 0), ListOfLocalAtoms, false);  // we want to keep the created ListOfLocalAtoms
     3088  // analysis of the cycles (print rings, get minimum cycle length) for each subgraph
     3089  for(int i=AtomCount;i--;)
     3090    MinimumRingSize[i] = AtomCount;
     3091  MolecularWalker = Subgraphs;
     3092  FragmentCounter = 0;
     3093  while (MolecularWalker->next != NULL) {
     3094    MolecularWalker = MolecularWalker->next;
     3095    LocalBackEdgeStack = new StackClass<bond *> (MolecularWalker->Leaf->BondCount);
     3096//    // check the list of local atoms for debugging
     3097//    *out << Verbose(0) << "ListOfLocalAtoms for this subgraph is:" << endl;
     3098//    for (int i=0;i<AtomCount;i++)
     3099//      if (ListOfLocalAtoms[FragmentCounter][i] == NULL)
     3100//        *out << "\tNULL";
     3101//      else
     3102//        *out << "\t" << ListOfLocalAtoms[FragmentCounter][i]->Name;
     3103    *out << Verbose(0) << "Gathering local back edges for subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
     3104    MolecularWalker->Leaf->PickLocalBackEdges(out, ListOfLocalAtoms[FragmentCounter++], BackEdgeStack, LocalBackEdgeStack);
     3105    *out << Verbose(0) << "Analysing the cycles of subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
     3106    MolecularWalker->Leaf->CyclicStructureAnalysis(out, LocalBackEdgeStack, MinimumRingSize);
     3107    *out << Verbose(0) << "Done with Analysing the cycles of subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
     3108    delete(LocalBackEdgeStack);
     3109  }
     3110
     3111  // ===== 3. if structure still valid, parse key set file and others =====
     3112  FragmentationToDo = FragmentationToDo && ParseKeySetFile(out, configuration->configpath, ParsedFragmentList);
     3113
     3114  // ===== 4. check globally whether there's something to do actually (first adaptivity check)
     3115  FragmentationToDo = FragmentationToDo && ParseOrderAtSiteFromFile(out, configuration->configpath);
     3116
     3117  // =================================== Begin of FRAGMENTATION ===============================
     3118  // ===== 6a. assign each keyset to its respective subgraph =====
     3119  Subgraphs->next->AssignKeySetsToFragment(out, this, ParsedFragmentList, ListOfLocalAtoms, FragmentList, (FragmentCounter = 0), true);
     3120
     3121  // ===== 6b. prepare and go into the adaptive (Order<0), single-step (Order==0) or incremental (Order>0) cycle
     3122  KeyStack *RootStack = new KeyStack[Subgraphs->next->Count()];
     3123  AtomMask = new bool[AtomCount+1];
     3124  AtomMask[AtomCount] = false;
     3125  FragmentationToDo = false;  // if CheckOrderAtSite just ones recommends fragmentation, we will save fragments afterwards
     3126  while ((CheckOrder = CheckOrderAtSite(out, AtomMask, ParsedFragmentList, Order, MinimumRingSize, configuration->configpath))) {
     3127    FragmentationToDo = FragmentationToDo || CheckOrder;
     3128    AtomMask[AtomCount] = true;  // last plus one entry is used as marker that we have been through this loop once already in CheckOrderAtSite()
     3129    // ===== 6b. fill RootStack for each subgraph (second adaptivity check) =====
     3130    Subgraphs->next->FillRootStackForSubgraphs(out, RootStack, AtomMask, (FragmentCounter = 0));
     3131
     3132    // ===== 7. fill the bond fragment list =====
     3133    FragmentCounter = 0;
     3134    MolecularWalker = Subgraphs;
     3135    while (MolecularWalker->next != NULL) {
     3136      MolecularWalker = MolecularWalker->next;
     3137      *out << Verbose(1) << "Fragmenting subgraph " << MolecularWalker << "." << endl;
     3138      //MolecularWalker->Leaf->OutputListOfBonds(out);  // output ListOfBondsPerAtom for debugging
     3139      if (MolecularWalker->Leaf->first->next != MolecularWalker->Leaf->last) {
     3140        // call BOSSANOVA method
     3141        *out << Verbose(0) << endl << " ========== BOND ENERGY of subgraph " << FragmentCounter << " ========================= " << endl;
     3142        MolecularWalker->Leaf->FragmentBOSSANOVA(out, FragmentList[FragmentCounter], RootStack[FragmentCounter], MinimumRingSize);
     3143      } else {
     3144        cerr << "Subgraph " << MolecularWalker << " has no atoms!" << endl;
     3145      }
     3146      FragmentCounter++;  // next fragment list
     3147    }
     3148  }
     3149  delete[](RootStack);
     3150  delete[](AtomMask);
     3151  delete(ParsedFragmentList);
     3152  delete[](MinimumRingSize);
     3153
     3154
     3155  // ==================================== End of FRAGMENTATION ============================================
     3156
     3157  // ===== 8a. translate list into global numbers (i.e. ones that are valid in "this" molecule, not in MolecularWalker->Leaf)
     3158  Subgraphs->next->TranslateIndicesToGlobalIDs(out, FragmentList, (FragmentCounter = 0), TotalNumberOfKeySets, TotalGraph);
     3159
     3160  // free subgraph memory again
     3161  FragmentCounter = 0;
     3162  if (Subgraphs != NULL) {
     3163    while (Subgraphs->next != NULL) {
     3164      Subgraphs = Subgraphs->next;
     3165      delete(FragmentList[FragmentCounter++]);
     3166      delete(Subgraphs->previous);
     3167    }
     3168    delete(Subgraphs);
     3169  }
     3170  Free((void **)&FragmentList, "molecule::FragmentMolecule - **FragmentList");
     3171
     3172  // ===== 8b. gather keyset lists (graphs) from all subgraphs and transform into MoleculeListClass =====
     3173  //if (FragmentationToDo) {    // we should always store the fragments again as coordination might have changed slightly without changing bond structure
     3174    // allocate memory for the pointer array and transmorph graphs into full molecular fragments
     3175    BondFragments = new MoleculeListClass();
     3176    int k=0;
     3177    for(Graph::iterator runner = TotalGraph.begin(); runner != TotalGraph.end(); runner++) {
     3178      KeySet test = (*runner).first;
     3179      *out << "Fragment No." << (*runner).second.first << " with TEFactor " << (*runner).second.second << "." << endl;
     3180      BondFragments->insert(StoreFragmentFromKeySet(out, test, configuration));
     3181      k++;
     3182    }
     3183    *out << k << "/" << BondFragments->ListOfMolecules.size() << " fragments generated from the keysets." << endl;
     3184
     3185    // ===== 9. Save fragments' configuration and keyset files et al to disk ===
     3186    if (BondFragments->ListOfMolecules.size() != 0) {
     3187      // create the SortIndex from BFS labels to order in the config file
     3188      CreateMappingLabelsToConfigSequence(out, SortIndex);
     3189
     3190      *out << Verbose(1) << "Writing " << BondFragments->ListOfMolecules.size() << " possible bond fragmentation configs" << endl;
     3191      if (BondFragments->OutputConfigForListOfFragments(out, configuration, SortIndex))
     3192        *out << Verbose(1) << "All configs written." << endl;
     3193      else
     3194        *out << Verbose(1) << "Some config writing failed." << endl;
     3195
     3196      // store force index reference file
     3197      BondFragments->StoreForcesFile(out, configuration->configpath, SortIndex);
     3198
     3199      // store keysets file
     3200      StoreKeySetFile(out, TotalGraph, configuration->configpath);
     3201
     3202      // store Adjacency file
     3203      StoreAdjacencyToFile(out, configuration->configpath);
     3204
     3205      // store Hydrogen saturation correction file
     3206      BondFragments->AddHydrogenCorrection(out, configuration->configpath);
     3207
     3208      // store adaptive orders into file
     3209      StoreOrderAtSiteFile(out, configuration->configpath);
     3210
     3211      // restore orbital and Stop values
     3212      CalculateOrbitals(*configuration);
     3213
     3214      // free memory for bond part
     3215      *out << Verbose(1) << "Freeing bond memory" << endl;
     3216      delete(FragmentList); // remove bond molecule from memory
     3217      Free((void **)&SortIndex, "molecule::FragmentMolecule: *SortIndex");
     3218    } else
     3219      *out << Verbose(1) << "FragmentList is zero on return, splitting failed." << endl;
     3220  //} else
     3221  //  *out << Verbose(1) << "No fragments to store." << endl;
     3222  *out << Verbose(0) << "End of bond fragmentation." << endl;
     3223
     3224  return ((int)(!FragmentationToDo)+1);    // 1 - continue, 2 - stop (no fragmentation occured)
    32253225};
    32263226
     
    32353235bool molecule::PickLocalBackEdges(ofstream *out, atom **ListOfLocalAtoms, class StackClass<bond *> *&ReferenceStack, class StackClass<bond *> *&LocalStack)
    32363236{
    3237         bool status = true;
    3238         if (ReferenceStack->IsEmpty()) {
    3239                 cerr << "ReferenceStack is empty!" << endl;
    3240                 return false;
    3241         }
    3242         bond *Binder = ReferenceStack->PopFirst();
    3243         bond *FirstBond = Binder;        // mark the first bond, so that we don't loop through the stack indefinitely
    3244         atom *Walker = NULL, *OtherAtom = NULL;
    3245         ReferenceStack->Push(Binder);
    3246 
    3247         do {    // go through all bonds and push local ones
    3248                 Walker = ListOfLocalAtoms[Binder->leftatom->nr];        // get one atom in the reference molecule
    3249                 if (Walker != NULL) // if this Walker exists in the subgraph ...
    3250                         for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {           // go through the local list of bonds
    3251                                 OtherAtom = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
    3252                                 if (OtherAtom == ListOfLocalAtoms[Binder->rightatom->nr]) { // found the bond
    3253                                         LocalStack->Push(ListOfBondsPerAtom[Walker->nr][i]);
    3254                                         *out << Verbose(3) << "Found local edge " << *(ListOfBondsPerAtom[Walker->nr][i]) << "." << endl;
    3255                                         break;
    3256                                 }
    3257                         }
    3258                 Binder = ReferenceStack->PopFirst();    // loop the stack for next item
    3259                 *out << Verbose(3) << "Current candidate edge " << Binder << "." << endl;
    3260                 ReferenceStack->Push(Binder);
    3261         } while (FirstBond != Binder);
    3262 
    3263         return status;
     3237  bool status = true;
     3238  if (ReferenceStack->IsEmpty()) {
     3239    cerr << "ReferenceStack is empty!" << endl;
     3240    return false;
     3241  }
     3242  bond *Binder = ReferenceStack->PopFirst();
     3243  bond *FirstBond = Binder;  // mark the first bond, so that we don't loop through the stack indefinitely
     3244  atom *Walker = NULL, *OtherAtom = NULL;
     3245  ReferenceStack->Push(Binder);
     3246
     3247  do {  // go through all bonds and push local ones
     3248    Walker = ListOfLocalAtoms[Binder->leftatom->nr];  // get one atom in the reference molecule
     3249    if (Walker != NULL) // if this Walker exists in the subgraph ...
     3250      for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {    // go through the local list of bonds
     3251        OtherAtom = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
     3252        if (OtherAtom == ListOfLocalAtoms[Binder->rightatom->nr]) { // found the bond
     3253          LocalStack->Push(ListOfBondsPerAtom[Walker->nr][i]);
     3254          *out << Verbose(3) << "Found local edge " << *(ListOfBondsPerAtom[Walker->nr][i]) << "." << endl;
     3255          break;
     3256        }
     3257      }
     3258    Binder = ReferenceStack->PopFirst();  // loop the stack for next item
     3259    *out << Verbose(3) << "Current candidate edge " << Binder << "." << endl;
     3260    ReferenceStack->Push(Binder);
     3261  } while (FirstBond != Binder);
     3262
     3263  return status;
    32643264};
    32653265
     
    32723272bool molecule::StoreOrderAtSiteFile(ofstream *out, char *path)
    32733273{
    3274         stringstream line;
    3275         ofstream file;
    3276 
    3277         line << path << "/" << FRAGMENTPREFIX << ORDERATSITEFILE;
    3278         file.open(line.str().c_str());
    3279         *out << Verbose(1) << "Writing OrderAtSite " << ORDERATSITEFILE << " ... " << endl;
    3280         if (file != NULL) {
    3281                 atom *Walker = start;
    3282                 while (Walker->next != end) {
    3283                         Walker = Walker->next;
    3284                         file << Walker->nr << "\t" << (int)Walker->AdaptiveOrder << "\t" << (int)Walker->MaxOrder << endl;
    3285                         *out << Verbose(2) << "Storing: " << Walker->nr << "\t" << (int)Walker->AdaptiveOrder << "\t" << (int)Walker->MaxOrder << "." << endl;
    3286                 }
    3287                 file.close();
    3288                 *out << Verbose(1) << "done." << endl;
    3289                 return true;
    3290         } else {
    3291                 *out << Verbose(1) << "failed to open file " << line.str() << "." << endl;
    3292                 return false;
    3293         }
     3274  stringstream line;
     3275  ofstream file;
     3276
     3277  line << path << "/" << FRAGMENTPREFIX << ORDERATSITEFILE;
     3278  file.open(line.str().c_str());
     3279  *out << Verbose(1) << "Writing OrderAtSite " << ORDERATSITEFILE << " ... " << endl;
     3280  if (file != NULL) {
     3281    atom *Walker = start;
     3282    while (Walker->next != end) {
     3283      Walker = Walker->next;
     3284      file << Walker->nr << "\t" << (int)Walker->AdaptiveOrder << "\t" << (int)Walker->MaxOrder << endl;
     3285      *out << Verbose(2) << "Storing: " << Walker->nr << "\t" << (int)Walker->AdaptiveOrder << "\t" << (int)Walker->MaxOrder << "." << endl;
     3286    }
     3287    file.close();
     3288    *out << Verbose(1) << "done." << endl;
     3289    return true;
     3290  } else {
     3291    *out << Verbose(1) << "failed to open file " << line.str() << "." << endl;
     3292    return false;
     3293  }
    32943294};
    32953295
     
    33033303bool molecule::ParseOrderAtSiteFromFile(ofstream *out, char *path)
    33043304{
    3305         unsigned char *OrderArray = (unsigned char *) Malloc(sizeof(unsigned char)*AtomCount, "molecule::ParseOrderAtSiteFromFile - *OrderArray");
    3306         bool *MaxArray = (bool *) Malloc(sizeof(bool)*AtomCount, "molecule::ParseOrderAtSiteFromFile - *MaxArray");
    3307         bool status;
    3308         int AtomNr, value;
    3309         stringstream line;
    3310         ifstream file;
    3311 
    3312         *out << Verbose(1) << "Begin of ParseOrderAtSiteFromFile" << endl;
    3313         for(int i=AtomCount;i--;)
    3314                 OrderArray[i] = 0;
    3315         line << path << "/" << FRAGMENTPREFIX << ORDERATSITEFILE;
    3316         file.open(line.str().c_str());
    3317         if (file != NULL) {
    3318                 for (int i=AtomCount;i--;) { // initialise with 0
    3319                         OrderArray[i] = 0;
    3320                         MaxArray[i] = 0;
    3321                 }
    3322                 while (!file.eof()) { // parse from file
    3323                         AtomNr = -1;
    3324                         file >> AtomNr;
    3325                         if (AtomNr != -1) {      // test whether we really parsed something (this is necessary, otherwise last atom is set twice and to 0 on second time)
    3326                                 file >> value;
    3327                                 OrderArray[AtomNr] = value;
    3328                                 file >> value;
    3329                                 MaxArray[AtomNr] = value;
    3330                                 //*out << Verbose(2) << "AtomNr " << AtomNr << " with order " << (int)OrderArray[AtomNr] << " and max order set to " << (int)MaxArray[AtomNr] << "." << endl;
    3331                         }
    3332                 }
    3333                 atom *Walker = start;
    3334                 while (Walker->next != end) { // fill into atom classes
    3335                         Walker = Walker->next;
    3336                         Walker->AdaptiveOrder = OrderArray[Walker->nr];
    3337                         Walker->MaxOrder = MaxArray[Walker->nr];
    3338                         *out << Verbose(2) << *Walker << " gets order " << (int)Walker->AdaptiveOrder << " and is " << (!Walker->MaxOrder ? "not " : " ") << "maxed." << endl;
    3339                 }
    3340                 file.close();
    3341                 *out << Verbose(1) << "done." << endl;
    3342                 status = true;
    3343         } else {
    3344                 *out << Verbose(1) << "failed to open file " << line.str() << "." << endl;
    3345                 status = false;
    3346         }
    3347         Free((void **)&OrderArray, "molecule::ParseOrderAtSiteFromFile - *OrderArray");
    3348         Free((void **)&MaxArray, "molecule::ParseOrderAtSiteFromFile - *MaxArray");
    3349 
    3350         *out << Verbose(1) << "End of ParseOrderAtSiteFromFile" << endl;
    3351         return status;
     3305  unsigned char *OrderArray = (unsigned char *) Malloc(sizeof(unsigned char)*AtomCount, "molecule::ParseOrderAtSiteFromFile - *OrderArray");
     3306  bool *MaxArray = (bool *) Malloc(sizeof(bool)*AtomCount, "molecule::ParseOrderAtSiteFromFile - *MaxArray");
     3307  bool status;
     3308  int AtomNr, value;
     3309  stringstream line;
     3310  ifstream file;
     3311
     3312  *out << Verbose(1) << "Begin of ParseOrderAtSiteFromFile" << endl;
     3313  for(int i=AtomCount;i--;)
     3314    OrderArray[i] = 0;
     3315  line << path << "/" << FRAGMENTPREFIX << ORDERATSITEFILE;
     3316  file.open(line.str().c_str());
     3317  if (file != NULL) {
     3318    for (int i=AtomCount;i--;) { // initialise with 0
     3319      OrderArray[i] = 0;
     3320      MaxArray[i] = 0;
     3321    }
     3322    while (!file.eof()) { // parse from file
     3323      AtomNr = -1;
     3324      file >> AtomNr;
     3325      if (AtomNr != -1) {  // test whether we really parsed something (this is necessary, otherwise last atom is set twice and to 0 on second time)
     3326        file >> value;
     3327        OrderArray[AtomNr] = value;
     3328        file >> value;
     3329        MaxArray[AtomNr] = value;
     3330        //*out << Verbose(2) << "AtomNr " << AtomNr << " with order " << (int)OrderArray[AtomNr] << " and max order set to " << (int)MaxArray[AtomNr] << "." << endl;
     3331      }
     3332    }
     3333    atom *Walker = start;
     3334    while (Walker->next != end) { // fill into atom classes
     3335      Walker = Walker->next;
     3336      Walker->AdaptiveOrder = OrderArray[Walker->nr];
     3337      Walker->MaxOrder = MaxArray[Walker->nr];
     3338      *out << Verbose(2) << *Walker << " gets order " << (int)Walker->AdaptiveOrder << " and is " << (!Walker->MaxOrder ? "not " : " ") << "maxed." << endl;
     3339    }
     3340    file.close();
     3341    *out << Verbose(1) << "done." << endl;
     3342    status = true;
     3343  } else {
     3344    *out << Verbose(1) << "failed to open file " << line.str() << "." << endl;
     3345    status = false;
     3346  }
     3347  Free((void **)&OrderArray, "molecule::ParseOrderAtSiteFromFile - *OrderArray");
     3348  Free((void **)&MaxArray, "molecule::ParseOrderAtSiteFromFile - *MaxArray");
     3349
     3350  *out << Verbose(1) << "End of ParseOrderAtSiteFromFile" << endl;
     3351  return status;
    33523352};
    33533353
     
    33603360void molecule::CreateListOfBondsPerAtom(ofstream *out)
    33613361{
    3362         bond *Binder = NULL;
    3363         atom *Walker = NULL;
    3364         int TotalDegree;
    3365         *out << Verbose(1) << "Begin of Creating ListOfBondsPerAtom: AtomCount = " << AtomCount << "\tBondCount = " << BondCount << "\tNoNonBonds = " << NoNonBonds << "." << endl;
    3366 
    3367         // re-allocate memory
    3368         *out << Verbose(2) << "(Re-)Allocating memory." << endl;
    3369         if (ListOfBondsPerAtom != NULL) {
    3370                 for(int i=AtomCount;i--;)
    3371                         Free((void **)&ListOfBondsPerAtom[i], "molecule::CreateListOfBondsPerAtom: ListOfBondsPerAtom[i]");
    3372                 Free((void **)&ListOfBondsPerAtom, "molecule::CreateListOfBondsPerAtom: ListOfBondsPerAtom");
    3373         }
    3374         if (NumberOfBondsPerAtom != NULL)
    3375                 Free((void **)&NumberOfBondsPerAtom, "molecule::CreateListOfBondsPerAtom: NumberOfBondsPerAtom");
    3376         ListOfBondsPerAtom = (bond ***) Malloc(sizeof(bond **)*AtomCount, "molecule::CreateListOfBondsPerAtom: ***ListOfBondsPerAtom");
    3377         NumberOfBondsPerAtom = (int *) Malloc(sizeof(int)*AtomCount, "molecule::CreateListOfBondsPerAtom: *NumberOfBondsPerAtom");
    3378 
    3379         // reset bond counts per atom
    3380         for(int i=AtomCount;i--;)
    3381                 NumberOfBondsPerAtom[i] = 0;
    3382         // count bonds per atom
    3383         Binder = first;
    3384         while (Binder->next != last) {
    3385                 Binder = Binder->next;
    3386                 NumberOfBondsPerAtom[Binder->leftatom->nr]++;
    3387                 NumberOfBondsPerAtom[Binder->rightatom->nr]++;
    3388         }
    3389         for(int i=AtomCount;i--;) {
    3390                 // allocate list of bonds per atom
    3391                 ListOfBondsPerAtom[i] = (bond **) Malloc(sizeof(bond *)*NumberOfBondsPerAtom[i], "molecule::CreateListOfBondsPerAtom: **ListOfBondsPerAtom[]");
    3392                 // clear the list again, now each NumberOfBondsPerAtom marks current free field
    3393                 NumberOfBondsPerAtom[i] = 0;
    3394         }
    3395         // fill the list
    3396         Binder = first;
    3397         while (Binder->next != last) {
    3398                 Binder = Binder->next;
    3399                 ListOfBondsPerAtom[Binder->leftatom->nr][NumberOfBondsPerAtom[Binder->leftatom->nr]++] = Binder;
    3400                 ListOfBondsPerAtom[Binder->rightatom->nr][NumberOfBondsPerAtom[Binder->rightatom->nr]++] = Binder;
    3401         }
    3402 
    3403         // output list for debugging
    3404         *out << Verbose(3) << "ListOfBondsPerAtom for each atom:" << endl;
    3405         Walker = start;
    3406         while (Walker->next != end) {
    3407                 Walker = Walker->next;
    3408                 *out << Verbose(4) << "Atom " << Walker->Name << "/" << Walker->nr << " with " << NumberOfBondsPerAtom[Walker->nr] << " bonds: ";
    3409                 TotalDegree = 0;
    3410                 for (int j=0;j<NumberOfBondsPerAtom[Walker->nr];j++) {
    3411                         *out << *ListOfBondsPerAtom[Walker->nr][j] << "\t";
    3412                         TotalDegree += ListOfBondsPerAtom[Walker->nr][j]->BondDegree;
    3413                 }
    3414                 *out << " -- TotalDegree: " << TotalDegree << endl;
    3415         }
    3416         *out << Verbose(1) << "End of Creating ListOfBondsPerAtom." << endl << endl;
     3362  bond *Binder = NULL;
     3363  atom *Walker = NULL;
     3364  int TotalDegree;
     3365  *out << Verbose(1) << "Begin of Creating ListOfBondsPerAtom: AtomCount = " << AtomCount << "\tBondCount = " << BondCount << "\tNoNonBonds = " << NoNonBonds << "." << endl;
     3366
     3367  // re-allocate memory
     3368  *out << Verbose(2) << "(Re-)Allocating memory." << endl;
     3369  if (ListOfBondsPerAtom != NULL) {
     3370    for(int i=AtomCount;i--;)
     3371      Free((void **)&ListOfBondsPerAtom[i], "molecule::CreateListOfBondsPerAtom: ListOfBondsPerAtom[i]");
     3372    Free((void **)&ListOfBondsPerAtom, "molecule::CreateListOfBondsPerAtom: ListOfBondsPerAtom");
     3373  }
     3374  if (NumberOfBondsPerAtom != NULL)
     3375    Free((void **)&NumberOfBondsPerAtom, "molecule::CreateListOfBondsPerAtom: NumberOfBondsPerAtom");
     3376  ListOfBondsPerAtom = (bond ***) Malloc(sizeof(bond **)*AtomCount, "molecule::CreateListOfBondsPerAtom: ***ListOfBondsPerAtom");
     3377  NumberOfBondsPerAtom = (int *) Malloc(sizeof(int)*AtomCount, "molecule::CreateListOfBondsPerAtom: *NumberOfBondsPerAtom");
     3378
     3379  // reset bond counts per atom
     3380  for(int i=AtomCount;i--;)
     3381    NumberOfBondsPerAtom[i] = 0;
     3382  // count bonds per atom
     3383  Binder = first;
     3384  while (Binder->next != last) {
     3385    Binder = Binder->next;
     3386    NumberOfBondsPerAtom[Binder->leftatom->nr]++;
     3387    NumberOfBondsPerAtom[Binder->rightatom->nr]++;
     3388  }
     3389  for(int i=AtomCount;i--;) {
     3390    // allocate list of bonds per atom
     3391    ListOfBondsPerAtom[i] = (bond **) Malloc(sizeof(bond *)*NumberOfBondsPerAtom[i], "molecule::CreateListOfBondsPerAtom: **ListOfBondsPerAtom[]");
     3392    // clear the list again, now each NumberOfBondsPerAtom marks current free field
     3393    NumberOfBondsPerAtom[i] = 0;
     3394  }
     3395  // fill the list
     3396  Binder = first;
     3397  while (Binder->next != last) {
     3398    Binder = Binder->next;
     3399    ListOfBondsPerAtom[Binder->leftatom->nr][NumberOfBondsPerAtom[Binder->leftatom->nr]++] = Binder;
     3400    ListOfBondsPerAtom[Binder->rightatom->nr][NumberOfBondsPerAtom[Binder->rightatom->nr]++] = Binder;
     3401  }
     3402
     3403  // output list for debugging
     3404  *out << Verbose(3) << "ListOfBondsPerAtom for each atom:" << endl;
     3405  Walker = start;
     3406  while (Walker->next != end) {
     3407    Walker = Walker->next;
     3408    *out << Verbose(4) << "Atom " << Walker->Name << "/" << Walker->nr << " with " << NumberOfBondsPerAtom[Walker->nr] << " bonds: ";
     3409    TotalDegree = 0;
     3410    for (int j=0;j<NumberOfBondsPerAtom[Walker->nr];j++) {
     3411      *out << *ListOfBondsPerAtom[Walker->nr][j] << "\t";
     3412      TotalDegree += ListOfBondsPerAtom[Walker->nr][j]->BondDegree;
     3413    }
     3414    *out << " -- TotalDegree: " << TotalDegree << endl;
     3415  }
     3416  *out << Verbose(1) << "End of Creating ListOfBondsPerAtom." << endl << endl;
    34173417};
    34183418
     
    34313431void molecule::BreadthFirstSearchAdd(ofstream *out, molecule *Mol, atom **&AddedAtomList, bond **&AddedBondList, atom *Root, bond *Bond, int BondOrder, bool IsAngstroem)
    34323432{
    3433         atom **PredecessorList = (atom **) Malloc(sizeof(atom *)*AtomCount, "molecule::BreadthFirstSearchAdd: **PredecessorList");
    3434         int *ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::BreadthFirstSearchAdd: *ShortestPathList");
    3435         enum Shading *ColorList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::BreadthFirstSearchAdd: *ColorList");
    3436         class StackClass<atom *> *AtomStack = new StackClass<atom *>(AtomCount);
    3437         atom *Walker = NULL, *OtherAtom = NULL;
    3438         bond *Binder = NULL;
    3439 
    3440         // add Root if not done yet
    3441         AtomStack->ClearStack();
    3442         if (AddedAtomList[Root->nr] == NULL)    // add Root if not yet present
    3443                 AddedAtomList[Root->nr] = Mol->AddCopyAtom(Root);
    3444         AtomStack->Push(Root);
    3445 
    3446         // initialise each vertex as white with no predecessor, empty queue, color Root lightgray
    3447         for (int i=AtomCount;i--;) {
    3448                 PredecessorList[i] = NULL;
    3449                 ShortestPathList[i] = -1;
    3450                 if (AddedAtomList[i] != NULL) // mark already present atoms (i.e. Root and maybe others) as visited
    3451                         ColorList[i] = lightgray;
    3452                 else
    3453                         ColorList[i] = white;
    3454         }
    3455         ShortestPathList[Root->nr] = 0;
    3456 
    3457         // and go on ... Queue always contains all lightgray vertices
    3458         while (!AtomStack->IsEmpty()) {
    3459                 // we have to pop the oldest atom from stack. This keeps the atoms on the stack always of the same ShortestPath distance.
    3460                 // e.g. if current atom is 2, push to end of stack are of length 3, but first all of length 2 would be popped. They again
    3461                 // append length of 3 (their neighbours). Thus on stack we have always atoms of a certain length n at bottom of stack and
    3462                 // followed by n+1 till top of stack.
    3463                 Walker = AtomStack->PopFirst(); // pop oldest added
    3464                 *out << Verbose(1) << "Current Walker is: " << Walker->Name << ", and has " << NumberOfBondsPerAtom[Walker->nr] << " bonds." << endl;
    3465                 for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
    3466                         Binder = ListOfBondsPerAtom[Walker->nr][i];
    3467                         if (Binder != NULL) { // don't look at bond equal NULL
    3468                                 OtherAtom = Binder->GetOtherAtom(Walker);
    3469                                 *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
    3470                                 if (ColorList[OtherAtom->nr] == white) {
    3471                                         if (Binder != Bond) // let other atom white if it's via Root bond. In case it's cyclic it has to be reached again (yet Root is from OtherAtom already black, thus no problem)
    3472                                                 ColorList[OtherAtom->nr] = lightgray;
    3473                                         PredecessorList[OtherAtom->nr] = Walker;        // Walker is the predecessor
    3474                                         ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
    3475                                         *out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " " << ((ColorList[OtherAtom->nr] == white) ? "white" : "lightgray") << ", its predecessor is " << Walker->Name << " and its Shortest Path is " << ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl;
    3476                                         if ((((ShortestPathList[OtherAtom->nr] < BondOrder) && (Binder != Bond))) ) { // Check for maximum distance
    3477                                                 *out << Verbose(3);
    3478                                                 if (AddedAtomList[OtherAtom->nr] == NULL) { // add if it's not been so far
    3479                                                         AddedAtomList[OtherAtom->nr] = Mol->AddCopyAtom(OtherAtom);
    3480                                                         *out << "Added OtherAtom " << OtherAtom->Name;
    3481                                                         AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
    3482                                                         AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
    3483                                                         AddedBondList[Binder->nr]->Type = Binder->Type;
    3484                                                         *out << " and bond " << *(AddedBondList[Binder->nr]) << ", ";
    3485                                                 } else {        // this code should actually never come into play (all white atoms are not yet present in BondMolecule, that's why they are white in the first place)
    3486                                                         *out << "Not adding OtherAtom " << OtherAtom->Name;
    3487                                                         if (AddedBondList[Binder->nr] == NULL) {
    3488                                                                 AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
    3489                                                                 AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
    3490                                                                 AddedBondList[Binder->nr]->Type = Binder->Type;
    3491                                                                 *out << ", added Bond " << *(AddedBondList[Binder->nr]);
    3492                                                         } else
    3493                                                                 *out << ", not added Bond ";
    3494                                                 }
    3495                                                 *out << ", putting OtherAtom into queue." << endl;
    3496                                                 AtomStack->Push(OtherAtom);
    3497                                         } else { // out of bond order, then replace
    3498                                                 if ((AddedAtomList[OtherAtom->nr] == NULL) && (Binder->Cyclic))
    3499                                                         ColorList[OtherAtom->nr] = white; // unmark if it has not been queued/added, to make it available via its other bonds (cyclic)
    3500                                                 if (Binder == Bond)
    3501                                                         *out << Verbose(3) << "Not Queueing, is the Root bond";
    3502                                                 else if (ShortestPathList[OtherAtom->nr] >= BondOrder)
    3503                                                         *out << Verbose(3) << "Not Queueing, is out of Bond Count of " << BondOrder;
    3504                                                 if (!Binder->Cyclic)
    3505                                                         *out << ", is not part of a cyclic bond, saturating bond with Hydrogen." << endl;
    3506                                                 if (AddedBondList[Binder->nr] == NULL) {
    3507                                                         if ((AddedAtomList[OtherAtom->nr] != NULL)) { // .. whether we add or saturate
    3508                                                                 AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
    3509                                                                 AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
    3510                                                                 AddedBondList[Binder->nr]->Type = Binder->Type;
    3511                                                         } else {
     3433  atom **PredecessorList = (atom **) Malloc(sizeof(atom *)*AtomCount, "molecule::BreadthFirstSearchAdd: **PredecessorList");
     3434  int *ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::BreadthFirstSearchAdd: *ShortestPathList");
     3435  enum Shading *ColorList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::BreadthFirstSearchAdd: *ColorList");
     3436  class StackClass<atom *> *AtomStack = new StackClass<atom *>(AtomCount);
     3437  atom *Walker = NULL, *OtherAtom = NULL;
     3438  bond *Binder = NULL;
     3439
     3440  // add Root if not done yet
     3441  AtomStack->ClearStack();
     3442  if (AddedAtomList[Root->nr] == NULL)  // add Root if not yet present
     3443    AddedAtomList[Root->nr] = Mol->AddCopyAtom(Root);
     3444  AtomStack->Push(Root);
     3445
     3446  // initialise each vertex as white with no predecessor, empty queue, color Root lightgray
     3447  for (int i=AtomCount;i--;) {
     3448    PredecessorList[i] = NULL;
     3449    ShortestPathList[i] = -1;
     3450    if (AddedAtomList[i] != NULL) // mark already present atoms (i.e. Root and maybe others) as visited
     3451      ColorList[i] = lightgray;
     3452    else
     3453      ColorList[i] = white;
     3454  }
     3455  ShortestPathList[Root->nr] = 0;
     3456
     3457  // and go on ... Queue always contains all lightgray vertices
     3458  while (!AtomStack->IsEmpty()) {
     3459    // we have to pop the oldest atom from stack. This keeps the atoms on the stack always of the same ShortestPath distance.
     3460    // e.g. if current atom is 2, push to end of stack are of length 3, but first all of length 2 would be popped. They again
     3461    // append length of 3 (their neighbours). Thus on stack we have always atoms of a certain length n at bottom of stack and
     3462    // followed by n+1 till top of stack.
     3463    Walker = AtomStack->PopFirst(); // pop oldest added
     3464    *out << Verbose(1) << "Current Walker is: " << Walker->Name << ", and has " << NumberOfBondsPerAtom[Walker->nr] << " bonds." << endl;
     3465    for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
     3466      Binder = ListOfBondsPerAtom[Walker->nr][i];
     3467      if (Binder != NULL) { // don't look at bond equal NULL
     3468        OtherAtom = Binder->GetOtherAtom(Walker);
     3469        *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
     3470        if (ColorList[OtherAtom->nr] == white) {
     3471          if (Binder != Bond) // let other atom white if it's via Root bond. In case it's cyclic it has to be reached again (yet Root is from OtherAtom already black, thus no problem)
     3472            ColorList[OtherAtom->nr] = lightgray;
     3473          PredecessorList[OtherAtom->nr] = Walker;  // Walker is the predecessor
     3474          ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
     3475          *out << Verbose(2) << "Coloring OtherAtom " << OtherAtom->Name << " " << ((ColorList[OtherAtom->nr] == white) ? "white" : "lightgray") << ", its predecessor is " << Walker->Name << " and its Shortest Path is " << ShortestPathList[OtherAtom->nr] << " egde(s) long." << endl;
     3476          if ((((ShortestPathList[OtherAtom->nr] < BondOrder) && (Binder != Bond))) ) { // Check for maximum distance
     3477            *out << Verbose(3);
     3478            if (AddedAtomList[OtherAtom->nr] == NULL) { // add if it's not been so far
     3479              AddedAtomList[OtherAtom->nr] = Mol->AddCopyAtom(OtherAtom);
     3480              *out << "Added OtherAtom " << OtherAtom->Name;
     3481              AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
     3482              AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
     3483              AddedBondList[Binder->nr]->Type = Binder->Type;
     3484              *out << " and bond " << *(AddedBondList[Binder->nr]) << ", ";
     3485            } else {  // this code should actually never come into play (all white atoms are not yet present in BondMolecule, that's why they are white in the first place)
     3486              *out << "Not adding OtherAtom " << OtherAtom->Name;
     3487              if (AddedBondList[Binder->nr] == NULL) {
     3488                AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
     3489                AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
     3490                AddedBondList[Binder->nr]->Type = Binder->Type;
     3491                *out << ", added Bond " << *(AddedBondList[Binder->nr]);
     3492              } else
     3493                *out << ", not added Bond ";
     3494            }
     3495            *out << ", putting OtherAtom into queue." << endl;
     3496            AtomStack->Push(OtherAtom);
     3497          } else { // out of bond order, then replace
     3498            if ((AddedAtomList[OtherAtom->nr] == NULL) && (Binder->Cyclic))
     3499              ColorList[OtherAtom->nr] = white; // unmark if it has not been queued/added, to make it available via its other bonds (cyclic)
     3500            if (Binder == Bond)
     3501              *out << Verbose(3) << "Not Queueing, is the Root bond";
     3502            else if (ShortestPathList[OtherAtom->nr] >= BondOrder)
     3503              *out << Verbose(3) << "Not Queueing, is out of Bond Count of " << BondOrder;
     3504            if (!Binder->Cyclic)
     3505              *out << ", is not part of a cyclic bond, saturating bond with Hydrogen." << endl;
     3506            if (AddedBondList[Binder->nr] == NULL) {
     3507              if ((AddedAtomList[OtherAtom->nr] != NULL)) { // .. whether we add or saturate
     3508                AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
     3509                AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
     3510                AddedBondList[Binder->nr]->Type = Binder->Type;
     3511              } else {
    35123512#ifdef ADDHYDROGEN
    3513                                                                 if (!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem))
    3514                                                                         exit(1);
     3513                if (!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem))
     3514                  exit(1);
    35153515#endif
    3516                                                         }
    3517                                                 }
    3518                                         }
    3519                                 } else {
    3520                                         *out << Verbose(3) << "Not Adding, has already been visited." << endl;
    3521                                         // This has to be a cyclic bond, check whether it's present ...
    3522                                         if (AddedBondList[Binder->nr] == NULL) {
    3523                                                 if ((Binder != Bond) && (Binder->Cyclic) && (((ShortestPathList[Walker->nr]+1) < BondOrder))) {
    3524                                                         AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
    3525                                                         AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
    3526                                                         AddedBondList[Binder->nr]->Type = Binder->Type;
    3527                                                 } else { // if it's root bond it has to broken (otherwise we would not create the fragments)
     3516              }
     3517            }
     3518          }
     3519        } else {
     3520          *out << Verbose(3) << "Not Adding, has already been visited." << endl;
     3521          // This has to be a cyclic bond, check whether it's present ...
     3522          if (AddedBondList[Binder->nr] == NULL) {
     3523            if ((Binder != Bond) && (Binder->Cyclic) && (((ShortestPathList[Walker->nr]+1) < BondOrder))) {
     3524              AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
     3525              AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
     3526              AddedBondList[Binder->nr]->Type = Binder->Type;
     3527            } else { // if it's root bond it has to broken (otherwise we would not create the fragments)
    35283528#ifdef ADDHYDROGEN
    3529                                                         if(!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem))
    3530                                                                 exit(1);
     3529              if(!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem))
     3530                exit(1);
    35313531#endif
    3532                                                 }
    3533                                         }
    3534                                 }
    3535                         }
    3536                 }
    3537                 ColorList[Walker->nr] = black;
    3538                 *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
    3539         }
    3540         Free((void **)&PredecessorList, "molecule::BreadthFirstSearchAdd: **PredecessorList");
    3541         Free((void **)&ShortestPathList, "molecule::BreadthFirstSearchAdd: **ShortestPathList");
    3542         Free((void **)&ColorList, "molecule::BreadthFirstSearchAdd: **ColorList");
    3543         delete(AtomStack);
     3532            }
     3533          }
     3534        }
     3535      }
     3536    }
     3537    ColorList[Walker->nr] = black;
     3538    *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
     3539  }
     3540  Free((void **)&PredecessorList, "molecule::BreadthFirstSearchAdd: **PredecessorList");
     3541  Free((void **)&ShortestPathList, "molecule::BreadthFirstSearchAdd: **ShortestPathList");
     3542  Free((void **)&ColorList, "molecule::BreadthFirstSearchAdd: **ColorList");
     3543  delete(AtomStack);
    35443544};
    35453545
     
    35553555bool molecule::BuildInducedSubgraph(ofstream *out, const molecule *Father)
    35563556{
    3557         atom *Walker = NULL, *OtherAtom = NULL;
    3558         bool status = true;
    3559         atom **ParentList = (atom **) Malloc(sizeof(atom *)*Father->AtomCount, "molecule::BuildInducedSubgraph: **ParentList");
    3560 
    3561         *out << Verbose(2) << "Begin of BuildInducedSubgraph." << endl;
    3562 
    3563         // reset parent list
    3564         *out << Verbose(3) << "Resetting ParentList." << endl;
    3565         for (int i=Father->AtomCount;i--;)
    3566                 ParentList[i] = NULL;
    3567 
    3568         // fill parent list with sons
    3569         *out << Verbose(3) << "Filling Parent List." << endl;
    3570         Walker = start;
    3571         while (Walker->next != end) {
    3572                 Walker = Walker->next;
    3573                 ParentList[Walker->father->nr] = Walker;
    3574                 // Outputting List for debugging
    3575                 *out << Verbose(4) << "Son["<< Walker->father->nr <<"] of " << Walker->father <<        " is " << ParentList[Walker->father->nr] << "." << endl;
    3576         }
    3577 
    3578         // check each entry of parent list and if ok (one-to-and-onto matching) create bonds
    3579         *out << Verbose(3) << "Creating bonds." << endl;
    3580         Walker = Father->start;
    3581         while (Walker->next != Father->end) {
    3582                 Walker = Walker->next;
    3583                 if (ParentList[Walker->nr] != NULL) {
    3584                         if (ParentList[Walker->nr]->father != Walker) {
    3585                                 status = false;
    3586                         } else {
    3587                                 for (int i=0;i<Father->NumberOfBondsPerAtom[Walker->nr];i++) {
    3588                                         OtherAtom = Father->ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
    3589                                         if (ParentList[OtherAtom->nr] != NULL) { // if otheratom is also a father of an atom on this molecule, create the bond
    3590                                                 *out << Verbose(4) << "Endpoints of Bond " << Father->ListOfBondsPerAtom[Walker->nr][i] << " are both present: " << ParentList[Walker->nr]->Name << " and " << ParentList[OtherAtom->nr]->Name << "." << endl;
    3591                                                 AddBond(ParentList[Walker->nr], ParentList[OtherAtom->nr], Father->ListOfBondsPerAtom[Walker->nr][i]->BondDegree);
    3592                                         }
    3593                                 }
    3594                         }
    3595                 }
    3596         }
    3597 
    3598         Free((void **)&ParentList, "molecule::BuildInducedSubgraph: **ParentList");
    3599         *out << Verbose(2) << "End of BuildInducedSubgraph." << endl;
    3600         return status;
     3557  atom *Walker = NULL, *OtherAtom = NULL;
     3558  bool status = true;
     3559  atom **ParentList = (atom **) Malloc(sizeof(atom *)*Father->AtomCount, "molecule::BuildInducedSubgraph: **ParentList");
     3560
     3561  *out << Verbose(2) << "Begin of BuildInducedSubgraph." << endl;
     3562
     3563  // reset parent list
     3564  *out << Verbose(3) << "Resetting ParentList." << endl;
     3565  for (int i=Father->AtomCount;i--;)
     3566    ParentList[i] = NULL;
     3567
     3568  // fill parent list with sons
     3569  *out << Verbose(3) << "Filling Parent List." << endl;
     3570  Walker = start;
     3571  while (Walker->next != end) {
     3572    Walker = Walker->next;
     3573    ParentList[Walker->father->nr] = Walker;
     3574    // Outputting List for debugging
     3575    *out << Verbose(4) << "Son["<< Walker->father->nr <<"] of " << Walker->father <<  " is " << ParentList[Walker->father->nr] << "." << endl;
     3576  }
     3577
     3578  // check each entry of parent list and if ok (one-to-and-onto matching) create bonds
     3579  *out << Verbose(3) << "Creating bonds." << endl;
     3580  Walker = Father->start;
     3581  while (Walker->next != Father->end) {
     3582    Walker = Walker->next;
     3583    if (ParentList[Walker->nr] != NULL) {
     3584      if (ParentList[Walker->nr]->father != Walker) {
     3585        status = false;
     3586      } else {
     3587        for (int i=0;i<Father->NumberOfBondsPerAtom[Walker->nr];i++) {
     3588          OtherAtom = Father->ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
     3589          if (ParentList[OtherAtom->nr] != NULL) { // if otheratom is also a father of an atom on this molecule, create the bond
     3590            *out << Verbose(4) << "Endpoints of Bond " << Father->ListOfBondsPerAtom[Walker->nr][i] << " are both present: " << ParentList[Walker->nr]->Name << " and " << ParentList[OtherAtom->nr]->Name << "." << endl;
     3591            AddBond(ParentList[Walker->nr], ParentList[OtherAtom->nr], Father->ListOfBondsPerAtom[Walker->nr][i]->BondDegree);
     3592          }
     3593        }
     3594      }
     3595    }
     3596  }
     3597
     3598  Free((void **)&ParentList, "molecule::BuildInducedSubgraph: **ParentList");
     3599  *out << Verbose(2) << "End of BuildInducedSubgraph." << endl;
     3600  return status;
    36013601};
    36023602
     
    36103610int molecule::LookForRemovalCandidate(ofstream *&out, KeySet *&Leaf, int *&ShortestPathList)
    36113611{
    3612         atom *Runner = NULL;
    3613         int SP, Removal;
    3614 
    3615         *out << Verbose(2) << "Looking for removal candidate." << endl;
    3616         SP = -1; //0;   // not -1, so that Root is never removed
    3617         Removal = -1;
    3618         for (KeySet::iterator runner = Leaf->begin(); runner != Leaf->end(); runner++) {
    3619                 Runner = FindAtom((*runner));
    3620                 if (Runner->type->Z != 1) { // skip all those added hydrogens when re-filling snake stack
    3621                         if (ShortestPathList[(*runner)] > SP) { // remove the oldest one with longest shortest path
    3622                                 SP = ShortestPathList[(*runner)];
    3623                                 Removal = (*runner);
    3624                         }
    3625                 }
    3626         }
    3627         return Removal;
     3612  atom *Runner = NULL;
     3613  int SP, Removal;
     3614
     3615  *out << Verbose(2) << "Looking for removal candidate." << endl;
     3616  SP = -1; //0;  // not -1, so that Root is never removed
     3617  Removal = -1;
     3618  for (KeySet::iterator runner = Leaf->begin(); runner != Leaf->end(); runner++) {
     3619    Runner = FindAtom((*runner));
     3620    if (Runner->type->Z != 1) { // skip all those added hydrogens when re-filling snake stack
     3621      if (ShortestPathList[(*runner)] > SP) {  // remove the oldest one with longest shortest path
     3622        SP = ShortestPathList[(*runner)];
     3623        Removal = (*runner);
     3624      }
     3625    }
     3626  }
     3627  return Removal;
    36283628};
    36293629
     
    36383638molecule * molecule::StoreFragmentFromKeySet(ofstream *out, KeySet &Leaflet, bool IsAngstroem)
    36393639{
    3640         atom *Runner = NULL, *FatherOfRunner = NULL, *OtherFather = NULL;
    3641         atom **SonList = (atom **) Malloc(sizeof(atom *)*AtomCount, "molecule::StoreFragmentFromStack: **SonList");
    3642         molecule *Leaf = new molecule(elemente);
    3643         bool LonelyFlag = false;
    3644         int size;
    3645 
    3646 //      *out << Verbose(1) << "Begin of StoreFragmentFromKeyset." << endl;
    3647 
    3648         Leaf->BondDistance = BondDistance;
    3649         for(int i=NDIM*2;i--;)
    3650                 Leaf->cell_size[i] = cell_size[i];
    3651 
    3652         // initialise SonList (indicates when we need to replace a bond with hydrogen instead)
    3653         for(int i=AtomCount;i--;)
    3654                 SonList[i] = NULL;
    3655 
    3656         // first create the minimal set of atoms from the KeySet
    3657         size = 0;
    3658         for(KeySet::iterator runner = Leaflet.begin(); runner != Leaflet.end(); runner++) {
    3659                 FatherOfRunner = FindAtom((*runner));   // find the id
    3660                 SonList[FatherOfRunner->nr] = Leaf->AddCopyAtom(FatherOfRunner);
    3661                 size++;
    3662         }
    3663 
    3664         // create the bonds between all: Make it an induced subgraph and add hydrogen
    3665 //      *out << Verbose(2) << "Creating bonds from father graph (i.e. induced subgraph creation)." << endl;
    3666         Runner = Leaf->start;
    3667         while (Runner->next != Leaf->end) {
    3668                 Runner = Runner->next;
    3669                 LonelyFlag = true;
    3670                 FatherOfRunner = Runner->father;
    3671                 if (SonList[FatherOfRunner->nr] != NULL)        {       // check if this, our father, is present in list
    3672                         // create all bonds
    3673                         for (int i=0;i<NumberOfBondsPerAtom[FatherOfRunner->nr];i++) { // go through every bond of father
    3674                                 OtherFather = ListOfBondsPerAtom[FatherOfRunner->nr][i]->GetOtherAtom(FatherOfRunner);
    3675 //                              *out << Verbose(2) << "Father " << *FatherOfRunner << " of son " << *SonList[FatherOfRunner->nr] << " is bound to " << *OtherFather;
    3676                                 if (SonList[OtherFather->nr] != NULL) {
    3677 //                                      *out << ", whose son is " << *SonList[OtherFather->nr] << "." << endl;
    3678                                         if (OtherFather->nr > FatherOfRunner->nr) { // add bond (nr check is for adding only one of both variants: ab, ba)
    3679 //                                              *out << Verbose(3) << "Adding Bond: ";
    3680 //                                              *out <<
    3681                                                 Leaf->AddBond(Runner, SonList[OtherFather->nr], ListOfBondsPerAtom[FatherOfRunner->nr][i]->BondDegree);
    3682 //                                              *out << "." << endl;
    3683                                                 //NumBonds[Runner->nr]++;
    3684                                         } else {
    3685 //                                              *out << Verbose(3) << "Not adding bond, labels in wrong order." << endl;
    3686                                         }
    3687                                         LonelyFlag = false;
    3688                                 } else {
    3689 //                                      *out << ", who has no son in this fragment molecule." << endl;
     3640  atom *Runner = NULL, *FatherOfRunner = NULL, *OtherFather = NULL;
     3641  atom **SonList = (atom **) Malloc(sizeof(atom *)*AtomCount, "molecule::StoreFragmentFromStack: **SonList");
     3642  molecule *Leaf = new molecule(elemente);
     3643  bool LonelyFlag = false;
     3644  int size;
     3645
     3646//  *out << Verbose(1) << "Begin of StoreFragmentFromKeyset." << endl;
     3647
     3648  Leaf->BondDistance = BondDistance;
     3649  for(int i=NDIM*2;i--;)
     3650    Leaf->cell_size[i] = cell_size[i];
     3651
     3652  // initialise SonList (indicates when we need to replace a bond with hydrogen instead)
     3653  for(int i=AtomCount;i--;)
     3654    SonList[i] = NULL;
     3655
     3656  // first create the minimal set of atoms from the KeySet
     3657  size = 0;
     3658  for(KeySet::iterator runner = Leaflet.begin(); runner != Leaflet.end(); runner++) {
     3659    FatherOfRunner = FindAtom((*runner));  // find the id
     3660    SonList[FatherOfRunner->nr] = Leaf->AddCopyAtom(FatherOfRunner);
     3661    size++;
     3662  }
     3663
     3664  // create the bonds between all: Make it an induced subgraph and add hydrogen
     3665//  *out << Verbose(2) << "Creating bonds from father graph (i.e. induced subgraph creation)." << endl;
     3666  Runner = Leaf->start;
     3667  while (Runner->next != Leaf->end) {
     3668    Runner = Runner->next;
     3669    LonelyFlag = true;
     3670    FatherOfRunner = Runner->father;
     3671    if (SonList[FatherOfRunner->nr] != NULL)  {  // check if this, our father, is present in list
     3672      // create all bonds
     3673      for (int i=0;i<NumberOfBondsPerAtom[FatherOfRunner->nr];i++) { // go through every bond of father
     3674        OtherFather = ListOfBondsPerAtom[FatherOfRunner->nr][i]->GetOtherAtom(FatherOfRunner);
     3675//        *out << Verbose(2) << "Father " << *FatherOfRunner << " of son " << *SonList[FatherOfRunner->nr] << " is bound to " << *OtherFather;
     3676        if (SonList[OtherFather->nr] != NULL) {
     3677//          *out << ", whose son is " << *SonList[OtherFather->nr] << "." << endl;
     3678          if (OtherFather->nr > FatherOfRunner->nr) { // add bond (nr check is for adding only one of both variants: ab, ba)
     3679//            *out << Verbose(3) << "Adding Bond: ";
     3680//            *out <<
     3681            Leaf->AddBond(Runner, SonList[OtherFather->nr], ListOfBondsPerAtom[FatherOfRunner->nr][i]->BondDegree);
     3682//            *out << "." << endl;
     3683            //NumBonds[Runner->nr]++;
     3684          } else {
     3685//            *out << Verbose(3) << "Not adding bond, labels in wrong order." << endl;
     3686          }
     3687          LonelyFlag = false;
     3688        } else {
     3689//          *out << ", who has no son in this fragment molecule." << endl;
    36903690#ifdef ADDHYDROGEN
    3691                                         //*out << Verbose(3) << "Adding Hydrogen to " << Runner->Name << " and a bond in between." << endl;
    3692                                         if(!Leaf->AddHydrogenReplacementAtom(out, ListOfBondsPerAtom[FatherOfRunner->nr][i], Runner, FatherOfRunner, OtherFather, ListOfBondsPerAtom[FatherOfRunner->nr],NumberOfBondsPerAtom[FatherOfRunner->nr], IsAngstroem))
    3693                                                 exit(1);
     3691          //*out << Verbose(3) << "Adding Hydrogen to " << Runner->Name << " and a bond in between." << endl;
     3692          if(!Leaf->AddHydrogenReplacementAtom(out, ListOfBondsPerAtom[FatherOfRunner->nr][i], Runner, FatherOfRunner, OtherFather, ListOfBondsPerAtom[FatherOfRunner->nr],NumberOfBondsPerAtom[FatherOfRunner->nr], IsAngstroem))
     3693            exit(1);
    36943694#endif
    3695                                         //NumBonds[Runner->nr] += ListOfBondsPerAtom[FatherOfRunner->nr][i]->BondDegree;
    3696                                 }
    3697                         }
    3698                 } else {
    3699                         *out << Verbose(0) << "ERROR: Son " << Runner->Name << " has father " << FatherOfRunner->Name << " but its entry in SonList is " << SonList[FatherOfRunner->nr] << "!" << endl;
    3700                 }
    3701                 if ((LonelyFlag) && (size > 1)) {
    3702                         *out << Verbose(0) << *Runner << "has got bonds only to hydrogens!" << endl;
    3703                 }
     3695          //NumBonds[Runner->nr] += ListOfBondsPerAtom[FatherOfRunner->nr][i]->BondDegree;
     3696        }
     3697      }
     3698    } else {
     3699      *out << Verbose(0) << "ERROR: Son " << Runner->Name << " has father " << FatherOfRunner->Name << " but its entry in SonList is " << SonList[FatherOfRunner->nr] << "!" << endl;
     3700    }
     3701    if ((LonelyFlag) && (size > 1)) {
     3702      *out << Verbose(0) << *Runner << "has got bonds only to hydrogens!" << endl;
     3703    }
    37043704#ifdef ADDHYDROGEN
    3705                 while ((Runner->next != Leaf->end) && (Runner->next->type->Z == 1)) // skip added hydrogen
    3706                         Runner = Runner->next;
     3705    while ((Runner->next != Leaf->end) && (Runner->next->type->Z == 1)) // skip added hydrogen
     3706      Runner = Runner->next;
    37073707#endif
    3708         }
    3709         Leaf->CreateListOfBondsPerAtom(out);
    3710         //Leaflet->Leaf->ScanForPeriodicCorrection(out);
    3711         Free((void **)&SonList, "molecule::StoreFragmentFromStack: **SonList");
    3712 //      *out << Verbose(1) << "End of StoreFragmentFromKeyset." << endl;
    3713         return Leaf;
     3708  }
     3709  Leaf->CreateListOfBondsPerAtom(out);
     3710  //Leaflet->Leaf->ScanForPeriodicCorrection(out);
     3711  Free((void **)&SonList, "molecule::StoreFragmentFromStack: **SonList");
     3712//  *out << Verbose(1) << "End of StoreFragmentFromKeyset." << endl;
     3713  return Leaf;
    37143714};
    37153715
     
    37173717 */
    37183718struct UniqueFragments {
    3719         config *configuration;
    3720         atom *Root;
    3721         Graph *Leaflet;
    3722         KeySet *FragmentSet;
    3723         int ANOVAOrder;
    3724         int FragmentCounter;
    3725         int CurrentIndex;
    3726         double TEFactor;
    3727         int *ShortestPathList;
    3728         bool **UsedList;
    3729         bond **BondsPerSPList;
    3730         int *BondsPerSPCount;
     3719  config *configuration;
     3720  atom *Root;
     3721  Graph *Leaflet;
     3722  KeySet *FragmentSet;
     3723  int ANOVAOrder;
     3724  int FragmentCounter;
     3725  int CurrentIndex;
     3726  double TEFactor;
     3727  int *ShortestPathList;
     3728  bool **UsedList;
     3729  bond **BondsPerSPList;
     3730  int *BondsPerSPCount;
    37313731};
    37323732
    37333733/** From a given set of Bond sorted by Shortest Path distance, create all possible fragments of size \a SetDimension.
    37343734 * -# loops over every possible combination (2^dimension of edge set)
    3735  *      -# inserts current set, if there's still space left
    3736  *              -# yes: calls SPFragmentGenerator with structure, created new edge list and size respective to root dist
     3735 *  -# inserts current set, if there's still space left
     3736 *    -# yes: calls SPFragmentGenerator with structure, created new edge list and size respective to root dist
    37373737ance+1
    3738  *              -# no: stores fragment into keyset list by calling InsertFragmentIntoGraph
    3739  *      -# removes all items added into the snake stack (in UniqueFragments structure) added during level (root
     3738 *    -# no: stores fragment into keyset list by calling InsertFragmentIntoGraph
     3739 *  -# removes all items added into the snake stack (in UniqueFragments structure) added during level (root
    37403740distance) and current set
    37413741 * \param *out output stream for debugging
     
    37473747void molecule::SPFragmentGenerator(ofstream *out, struct UniqueFragments *FragmentSearch, int RootDistance, bond **BondsSet, int SetDimension, int SubOrder)
    37483748{
    3749         atom *OtherWalker = NULL;
    3750         int verbosity = 0; //FragmentSearch->ANOVAOrder-SubOrder;
    3751         int NumCombinations;
    3752         bool bit;
    3753         int bits, TouchedIndex, SubSetDimension, SP, Added;
    3754         int Removal;
    3755         int SpaceLeft;
    3756         int *TouchedList = (int *) Malloc(sizeof(int)*(SubOrder+1), "molecule::SPFragmentGenerator: *TouchedList");
    3757         bond *Binder = NULL;
    3758         bond **BondsList = NULL;
    3759         KeySetTestPair TestKeySetInsert;
    3760 
    3761         NumCombinations = 1 << SetDimension;
    3762 
    3763         // Hier muessen von 1 bis NumberOfBondsPerAtom[Walker->nr] alle Kombinationen
    3764         // von Endstuecken (aus den Bonds) hinzugefᅵᅵgt werden und fᅵᅵr verbleibende ANOVAOrder
    3765         // rekursiv GraphCrawler in der nᅵᅵchsten Ebene aufgerufen werden
    3766 
    3767         *out << Verbose(1+verbosity) << "Begin of SPFragmentGenerator." << endl;
    3768         *out << Verbose(1+verbosity) << "We are " << RootDistance << " away from Root, which is " << *FragmentSearch->Root << ", SubOrder is " << SubOrder << ", SetDimension is " << SetDimension << " and this means " <<     NumCombinations-1 << " combination(s)." << endl;
    3769 
    3770         // initialised touched list (stores added atoms on this level)
    3771         *out << Verbose(1+verbosity) << "Clearing touched list." << endl;
    3772         for (TouchedIndex=SubOrder+1;TouchedIndex--;)   // empty touched list
    3773                 TouchedList[TouchedIndex] = -1;
    3774         TouchedIndex = 0;
    3775 
    3776         // create every possible combination of the endpieces
    3777         *out << Verbose(1+verbosity) << "Going through all combinations of the power set." << endl;
    3778         for (int i=1;i<NumCombinations;i++) {   // sweep through all power set combinations (skip empty set!)
    3779                 // count the set bit of i
    3780                 bits = 0;
    3781                 for (int j=SetDimension;j--;)
    3782                         bits += (i & (1 << j)) >> j;
    3783 
    3784                 *out << Verbose(1+verbosity) << "Current set is " << Binary(i | (1 << SetDimension)) << ", number of bits is " << bits << "." << endl;
    3785                 if (bits <= SubOrder) { // if not greater than additional atoms allowed on stack, continue
    3786                         // --1-- add this set of the power set of bond partners to the snake stack
    3787                         Added = 0;
    3788                         for (int j=0;j<SetDimension;j++) {      // pull out every bit by shifting
    3789                                 bit = ((i & (1 << j)) != 0);    // mask the bit for the j-th bond
    3790                                 if (bit) {      // if bit is set, we add this bond partner
    3791                                         OtherWalker = BondsSet[j]->rightatom;   // rightatom is always the one more distant, i.e. the one to add
    3792                                         //*out << Verbose(1+verbosity) << "Current Bond is " << ListOfBondsPerAtom[Walker->nr][i] << ", checking on " << *OtherWalker << "." << endl;
    3793                                         *out << Verbose(2+verbosity) << "Adding " << *OtherWalker << " with nr " << OtherWalker->nr << "." << endl;
    3794                                         TestKeySetInsert = FragmentSearch->FragmentSet->insert(OtherWalker->nr);
    3795                                         if (TestKeySetInsert.second) {
    3796                                                 TouchedList[TouchedIndex++] = OtherWalker->nr;  // note as added
    3797                                                 Added++;
    3798                                         } else {
    3799                                                 *out << Verbose(2+verbosity) << "This was item was already present in the keyset." << endl;
    3800                                         }
    3801                                                 //FragmentSearch->UsedList[OtherWalker->nr][i] = true;
    3802                                         //}
    3803                                 } else {
    3804                                         *out << Verbose(2+verbosity) << "Not adding." << endl;
    3805                                 }
    3806                         }
    3807 
    3808                         SpaceLeft = SubOrder - Added ;// SubOrder - bits; // due to item's maybe being already present, this does not work anymore
    3809                         if (SpaceLeft > 0) {
    3810                                 *out << Verbose(1+verbosity) << "There's still some space left on stack: " << SpaceLeft << "." << endl;
    3811                                 if (SubOrder > 1) {             // Due to Added above we have to check extra whether we're not already reaching beyond the desired Order
    3812                                         // --2-- look at all added end pieces of this combination, construct bond subsets and sweep through a power set of these by recursion
    3813                                         SP = RootDistance+1;    // this is the next level
    3814                                         // first count the members in the subset
    3815                                         SubSetDimension = 0;
    3816                                         Binder = FragmentSearch->BondsPerSPList[2*SP];          // start node for this level
    3817                                         while (Binder->next != FragmentSearch->BondsPerSPList[2*SP+1]) {                // compare to end node of this level
    3818                                                 Binder = Binder->next;
    3819                                                 for (int k=TouchedIndex;k--;) {
    3820                                                         if (Binder->Contains(TouchedList[k]))    // if we added this very endpiece
    3821                                                                 SubSetDimension++;
    3822                                                 }
    3823                                         }
    3824                                         // then allocate and fill the list
    3825                                         BondsList = (bond **) Malloc(sizeof(bond *)*SubSetDimension, "molecule::SPFragmentGenerator: **BondsList");
    3826                                         SubSetDimension = 0;
    3827                                         Binder = FragmentSearch->BondsPerSPList[2*SP];
    3828                                         while (Binder->next != FragmentSearch->BondsPerSPList[2*SP+1]) {
    3829                                                 Binder = Binder->next;
    3830                                                 for (int k=0;k<TouchedIndex;k++) {
    3831                                                         if (Binder->leftatom->nr == TouchedList[k])      // leftatom is always the close one
    3832                                                                 BondsList[SubSetDimension++] = Binder;
    3833                                                 }
    3834                                         }
    3835                                         *out << Verbose(2+verbosity) << "Calling subset generator " << SP << " away from root " << *FragmentSearch->Root << " with sub set dimension " << SubSetDimension << "." << endl;
    3836                                         SPFragmentGenerator(out, FragmentSearch, SP, BondsList, SubSetDimension, SubOrder-bits);
    3837                                         Free((void **)&BondsList, "molecule::SPFragmentGenerator: **BondsList");
    3838                                 }
    3839                         } else {
    3840                                 // --2-- otherwise store the complete fragment
    3841                                 *out << Verbose(1+verbosity) << "Enough items on stack for a fragment!" << endl;
    3842                                 // store fragment as a KeySet
    3843                                 *out << Verbose(2) << "Found a new fragment[" << FragmentSearch->FragmentCounter << "], local nr.s are: ";
    3844                                 for(KeySet::iterator runner = FragmentSearch->FragmentSet->begin(); runner != FragmentSearch->FragmentSet->end(); runner++)
    3845                                         *out << (*runner) << " ";
    3846                                 *out << endl;
    3847                                 //if (!CheckForConnectedSubgraph(out, FragmentSearch->FragmentSet))
    3848                                         //*out << Verbose(0) << "ERROR: The found fragment is not a connected subgraph!" << endl;
    3849                                 InsertFragmentIntoGraph(out, FragmentSearch);
    3850                                 //Removal = LookForRemovalCandidate(out, FragmentSearch->FragmentSet, FragmentSearch->ShortestPathList);
    3851                                 //Removal = StoreFragmentFromStack(out, FragmentSearch->Root, FragmentSearch->Leaflet, FragmentSearch->FragmentStack, FragmentSearch->ShortestPathList, &FragmentSearch->FragmentCounter, FragmentSearch->configuration);
    3852                         }
    3853 
    3854                         // --3-- remove all added items in this level from snake stack
    3855                         *out << Verbose(1+verbosity) << "Removing all items that were added on this SP level " << RootDistance << "." << endl;
    3856                         for(int j=0;j<TouchedIndex;j++) {
    3857                                 Removal = TouchedList[j];
    3858                                 *out << Verbose(2+verbosity) << "Removing item nr. " << Removal << " from snake stack." << endl;
    3859                                 FragmentSearch->FragmentSet->erase(Removal);
    3860                                 TouchedList[j] = -1;
    3861                         }
    3862                         *out << Verbose(2) << "Remaining local nr.s on snake stack are: ";
    3863                         for(KeySet::iterator runner = FragmentSearch->FragmentSet->begin(); runner != FragmentSearch->FragmentSet->end(); runner++)
    3864                                 *out << (*runner) << " ";
    3865                         *out << endl;
    3866                         TouchedIndex = 0; // set Index to 0 for list of atoms added on this level
    3867                 } else {
    3868                         *out << Verbose(2+verbosity) << "More atoms to add for this set (" << bits << ") than space left on stack " << SubOrder << ", skipping this set." << endl;
    3869                 }
    3870         }
    3871         Free((void **)&TouchedList, "molecule::SPFragmentGenerator: *TouchedList");
    3872         *out << Verbose(1+verbosity) << "End of SPFragmentGenerator, " << RootDistance << " away from Root " << *FragmentSearch->Root << " and SubOrder is " << SubOrder << "." << endl;
     3749  atom *OtherWalker = NULL;
     3750  int verbosity = 0; //FragmentSearch->ANOVAOrder-SubOrder;
     3751  int NumCombinations;
     3752  bool bit;
     3753  int bits, TouchedIndex, SubSetDimension, SP, Added;
     3754  int Removal;
     3755  int SpaceLeft;
     3756  int *TouchedList = (int *) Malloc(sizeof(int)*(SubOrder+1), "molecule::SPFragmentGenerator: *TouchedList");
     3757  bond *Binder = NULL;
     3758  bond **BondsList = NULL;
     3759  KeySetTestPair TestKeySetInsert;
     3760
     3761  NumCombinations = 1 << SetDimension;
     3762
     3763  // Hier muessen von 1 bis NumberOfBondsPerAtom[Walker->nr] alle Kombinationen
     3764  // von Endstuecken (aus den Bonds) hinzugefᅵᅵgt werden und fᅵᅵr verbleibende ANOVAOrder
     3765  // rekursiv GraphCrawler in der nᅵᅵchsten Ebene aufgerufen werden
     3766
     3767  *out << Verbose(1+verbosity) << "Begin of SPFragmentGenerator." << endl;
     3768  *out << Verbose(1+verbosity) << "We are " << RootDistance << " away from Root, which is " << *FragmentSearch->Root << ", SubOrder is " << SubOrder << ", SetDimension is " << SetDimension << " and this means " <<  NumCombinations-1 << " combination(s)." << endl;
     3769
     3770  // initialised touched list (stores added atoms on this level)
     3771  *out << Verbose(1+verbosity) << "Clearing touched list." << endl;
     3772  for (TouchedIndex=SubOrder+1;TouchedIndex--;)  // empty touched list
     3773    TouchedList[TouchedIndex] = -1;
     3774  TouchedIndex = 0;
     3775
     3776  // create every possible combination of the endpieces
     3777  *out << Verbose(1+verbosity) << "Going through all combinations of the power set." << endl;
     3778  for (int i=1;i<NumCombinations;i++) {  // sweep through all power set combinations (skip empty set!)
     3779    // count the set bit of i
     3780    bits = 0;
     3781    for (int j=SetDimension;j--;)
     3782      bits += (i & (1 << j)) >> j;
     3783
     3784    *out << Verbose(1+verbosity) << "Current set is " << Binary(i | (1 << SetDimension)) << ", number of bits is " << bits << "." << endl;
     3785    if (bits <= SubOrder) { // if not greater than additional atoms allowed on stack, continue
     3786      // --1-- add this set of the power set of bond partners to the snake stack
     3787      Added = 0;
     3788      for (int j=0;j<SetDimension;j++) {  // pull out every bit by shifting
     3789        bit = ((i & (1 << j)) != 0);  // mask the bit for the j-th bond
     3790        if (bit) {  // if bit is set, we add this bond partner
     3791          OtherWalker = BondsSet[j]->rightatom;  // rightatom is always the one more distant, i.e. the one to add
     3792          //*out << Verbose(1+verbosity) << "Current Bond is " << ListOfBondsPerAtom[Walker->nr][i] << ", checking on " << *OtherWalker << "." << endl;
     3793          *out << Verbose(2+verbosity) << "Adding " << *OtherWalker << " with nr " << OtherWalker->nr << "." << endl;
     3794          TestKeySetInsert = FragmentSearch->FragmentSet->insert(OtherWalker->nr);
     3795          if (TestKeySetInsert.second) {
     3796            TouchedList[TouchedIndex++] = OtherWalker->nr;  // note as added
     3797            Added++;
     3798          } else {
     3799            *out << Verbose(2+verbosity) << "This was item was already present in the keyset." << endl;
     3800          }
     3801            //FragmentSearch->UsedList[OtherWalker->nr][i] = true;
     3802          //}
     3803        } else {
     3804          *out << Verbose(2+verbosity) << "Not adding." << endl;
     3805        }
     3806      }
     3807
     3808      SpaceLeft = SubOrder - Added ;// SubOrder - bits; // due to item's maybe being already present, this does not work anymore
     3809      if (SpaceLeft > 0) {
     3810        *out << Verbose(1+verbosity) << "There's still some space left on stack: " << SpaceLeft << "." << endl;
     3811        if (SubOrder > 1) {    // Due to Added above we have to check extra whether we're not already reaching beyond the desired Order
     3812          // --2-- look at all added end pieces of this combination, construct bond subsets and sweep through a power set of these by recursion
     3813          SP = RootDistance+1;  // this is the next level
     3814          // first count the members in the subset
     3815          SubSetDimension = 0;
     3816          Binder = FragmentSearch->BondsPerSPList[2*SP];    // start node for this level
     3817          while (Binder->next != FragmentSearch->BondsPerSPList[2*SP+1]) {    // compare to end node of this level
     3818            Binder = Binder->next;
     3819            for (int k=TouchedIndex;k--;) {
     3820              if (Binder->Contains(TouchedList[k]))  // if we added this very endpiece
     3821                SubSetDimension++;
     3822            }
     3823          }
     3824          // then allocate and fill the list
     3825          BondsList = (bond **) Malloc(sizeof(bond *)*SubSetDimension, "molecule::SPFragmentGenerator: **BondsList");
     3826          SubSetDimension = 0;
     3827          Binder = FragmentSearch->BondsPerSPList[2*SP];
     3828          while (Binder->next != FragmentSearch->BondsPerSPList[2*SP+1]) {
     3829            Binder = Binder->next;
     3830            for (int k=0;k<TouchedIndex;k++) {
     3831              if (Binder->leftatom->nr == TouchedList[k])  // leftatom is always the close one
     3832                BondsList[SubSetDimension++] = Binder;
     3833            }
     3834          }
     3835          *out << Verbose(2+verbosity) << "Calling subset generator " << SP << " away from root " << *FragmentSearch->Root << " with sub set dimension " << SubSetDimension << "." << endl;
     3836          SPFragmentGenerator(out, FragmentSearch, SP, BondsList, SubSetDimension, SubOrder-bits);
     3837          Free((void **)&BondsList, "molecule::SPFragmentGenerator: **BondsList");
     3838        }
     3839      } else {
     3840        // --2-- otherwise store the complete fragment
     3841        *out << Verbose(1+verbosity) << "Enough items on stack for a fragment!" << endl;
     3842        // store fragment as a KeySet
     3843        *out << Verbose(2) << "Found a new fragment[" << FragmentSearch->FragmentCounter << "], local nr.s are: ";
     3844        for(KeySet::iterator runner = FragmentSearch->FragmentSet->begin(); runner != FragmentSearch->FragmentSet->end(); runner++)
     3845          *out << (*runner) << " ";
     3846        *out << endl;
     3847        //if (!CheckForConnectedSubgraph(out, FragmentSearch->FragmentSet))
     3848          //*out << Verbose(0) << "ERROR: The found fragment is not a connected subgraph!" << endl;
     3849        InsertFragmentIntoGraph(out, FragmentSearch);
     3850        //Removal = LookForRemovalCandidate(out, FragmentSearch->FragmentSet, FragmentSearch->ShortestPathList);
     3851        //Removal = StoreFragmentFromStack(out, FragmentSearch->Root, FragmentSearch->Leaflet, FragmentSearch->FragmentStack, FragmentSearch->ShortestPathList, &FragmentSearch->FragmentCounter, FragmentSearch->configuration);
     3852      }
     3853
     3854      // --3-- remove all added items in this level from snake stack
     3855      *out << Verbose(1+verbosity) << "Removing all items that were added on this SP level " << RootDistance << "." << endl;
     3856      for(int j=0;j<TouchedIndex;j++) {
     3857        Removal = TouchedList[j];
     3858        *out << Verbose(2+verbosity) << "Removing item nr. " << Removal << " from snake stack." << endl;
     3859        FragmentSearch->FragmentSet->erase(Removal);
     3860        TouchedList[j] = -1;
     3861      }
     3862      *out << Verbose(2) << "Remaining local nr.s on snake stack are: ";
     3863      for(KeySet::iterator runner = FragmentSearch->FragmentSet->begin(); runner != FragmentSearch->FragmentSet->end(); runner++)
     3864        *out << (*runner) << " ";
     3865      *out << endl;
     3866      TouchedIndex = 0; // set Index to 0 for list of atoms added on this level
     3867    } else {
     3868      *out << Verbose(2+verbosity) << "More atoms to add for this set (" << bits << ") than space left on stack " << SubOrder << ", skipping this set." << endl;
     3869    }
     3870  }
     3871  Free((void **)&TouchedList, "molecule::SPFragmentGenerator: *TouchedList");
     3872  *out << Verbose(1+verbosity) << "End of SPFragmentGenerator, " << RootDistance << " away from Root " << *FragmentSearch->Root << " and SubOrder is " << SubOrder << "." << endl;
    38733873};
    38743874
     
    38813881bool molecule::CheckForConnectedSubgraph(ofstream *out, KeySet *Fragment)
    38823882{
    3883         atom *Walker = NULL, *Walker2 = NULL;
    3884         bool BondStatus = false;
    3885         int size;
    3886 
    3887         *out << Verbose(1) << "Begin of CheckForConnectedSubgraph" << endl;
    3888         *out << Verbose(2) << "Disconnected atom: ";
    3889 
    3890         // count number of atoms in graph
    3891         size = 0;
    3892         for(KeySet::iterator runner = Fragment->begin(); runner != Fragment->end(); runner++)
    3893                 size++;
    3894         if (size > 1)
    3895                 for(KeySet::iterator runner = Fragment->begin(); runner != Fragment->end(); runner++) {
    3896                         Walker = FindAtom(*runner);
    3897                         BondStatus = false;
    3898                         for(KeySet::iterator runners = Fragment->begin(); runners != Fragment->end(); runners++) {
    3899                                 Walker2 = FindAtom(*runners);
    3900                                 for (int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) {
    3901                                         if (ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker) == Walker2) {
    3902                                                 BondStatus = true;
    3903                                                 break;
    3904                                         }
    3905                                         if (BondStatus)
    3906                                                 break;
    3907                                 }
    3908                         }
    3909                         if (!BondStatus) {
    3910                                 *out << (*Walker) << endl;
    3911                                 return false;
    3912                         }
    3913                 }
    3914         else {
    3915                 *out << "none." << endl;
    3916                 return true;
    3917         }
    3918         *out << "none." << endl;
    3919 
    3920         *out << Verbose(1) << "End of CheckForConnectedSubgraph" << endl;
    3921 
    3922         return true;
     3883  atom *Walker = NULL, *Walker2 = NULL;
     3884  bool BondStatus = false;
     3885  int size;
     3886
     3887  *out << Verbose(1) << "Begin of CheckForConnectedSubgraph" << endl;
     3888  *out << Verbose(2) << "Disconnected atom: ";
     3889
     3890  // count number of atoms in graph
     3891  size = 0;
     3892  for(KeySet::iterator runner = Fragment->begin(); runner != Fragment->end(); runner++)
     3893    size++;
     3894  if (size > 1)
     3895    for(KeySet::iterator runner = Fragment->begin(); runner != Fragment->end(); runner++) {
     3896      Walker = FindAtom(*runner);
     3897      BondStatus = false;
     3898      for(KeySet::iterator runners = Fragment->begin(); runners != Fragment->end(); runners++) {
     3899        Walker2 = FindAtom(*runners);
     3900        for (int i=0;i<NumberOfBondsPerAtom[Walker->nr]; i++) {
     3901          if (ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker) == Walker2) {
     3902            BondStatus = true;
     3903            break;
     3904          }
     3905          if (BondStatus)
     3906            break;
     3907        }
     3908      }
     3909      if (!BondStatus) {
     3910        *out << (*Walker) << endl;
     3911        return false;
     3912      }
     3913    }
     3914  else {
     3915    *out << "none." << endl;
     3916    return true;
     3917  }
     3918  *out << "none." << endl;
     3919
     3920  *out << Verbose(1) << "End of CheckForConnectedSubgraph" << endl;
     3921
     3922  return true;
    39233923}
    39243924
     
    39403940int molecule::PowerSetGenerator(ofstream *out, int Order, struct UniqueFragments &FragmentSearch, KeySet RestrictedKeySet)
    39413941{
    3942         int SP, AtomKeyNr;
    3943         atom *Walker = NULL, *OtherWalker = NULL, *Predecessor = NULL;
    3944         bond *Binder = NULL;
    3945         bond *CurrentEdge = NULL;
    3946         bond **BondsList = NULL;
    3947         int RootKeyNr = FragmentSearch.Root->GetTrueFather()->nr;
    3948         int Counter = FragmentSearch.FragmentCounter;
    3949         int RemainingWalkers;
    3950 
    3951         *out << endl;
    3952         *out << Verbose(0) << "Begin of PowerSetGenerator with order " << Order << " at Root " << *FragmentSearch.Root << "." << endl;
    3953 
    3954         // prepare Label and SP arrays of the BFS search
    3955         FragmentSearch.ShortestPathList[FragmentSearch.Root->nr] = 0;
    3956 
    3957         // prepare root level (SP = 0) and a loop bond denoting Root
    3958         for (int i=1;i<Order;i++)
    3959                 FragmentSearch.BondsPerSPCount[i] = 0;
    3960         FragmentSearch.BondsPerSPCount[0] = 1;
    3961         Binder = new bond(FragmentSearch.Root, FragmentSearch.Root);
    3962         add(Binder, FragmentSearch.BondsPerSPList[1]);
    3963 
    3964         // do a BFS search to fill the SP lists and label the found vertices
    3965         // Actually, we should construct a spanning tree vom the root atom and select all edges therefrom and put them into
    3966         // according shortest path lists. However, we don't. Rather we fill these lists right away, as they do form a spanning
    3967         // tree already sorted into various SP levels. That's why we just do loops over the depth (CurrentSP) and breadth
    3968         // (EdgeinSPLevel) of this tree ...
    3969         // In another picture, the bonds always contain a direction by rightatom being the one more distant from root and hence
    3970         // naturally leftatom forming its predecessor, preventing the BFS"seeker" from continuing in the wrong direction.
    3971         *out << endl;
    3972         *out << Verbose(0) << "Starting BFS analysis ..." << endl;
    3973         for (SP = 0; SP < (Order-1); SP++) {
    3974                 *out << Verbose(1) << "New SP level reached: " << SP << ", creating new SP list with " << FragmentSearch.BondsPerSPCount[SP] << " item(s)";
    3975                 if (SP > 0) {
    3976                         *out << ", old level closed with " << FragmentSearch.BondsPerSPCount[SP-1] << " item(s)." << endl;
    3977                         FragmentSearch.BondsPerSPCount[SP] = 0;
    3978                 } else
    3979                         *out << "." << endl;
    3980 
    3981                 RemainingWalkers = FragmentSearch.BondsPerSPCount[SP];
    3982                 CurrentEdge = FragmentSearch.BondsPerSPList[2*SP];              /// start of this SP level's list
    3983                 while (CurrentEdge->next != FragmentSearch.BondsPerSPList[2*SP+1]) {            /// end of this SP level's list
    3984                         CurrentEdge = CurrentEdge->next;
    3985                         RemainingWalkers--;
    3986                         Walker = CurrentEdge->rightatom;                // rightatom is always the one more distant
    3987                         Predecessor = CurrentEdge->leftatom;            // ... and leftatom is predecessor
    3988                         AtomKeyNr = Walker->nr;
    3989                         *out << Verbose(0) << "Current Walker is: " << *Walker << " with nr " << Walker->nr << " and SP of " << SP << ", with " << RemainingWalkers << " remaining walkers on this level." << endl;
    3990                         // check for new sp level
    3991                         // go through all its bonds
    3992                         *out << Verbose(1) << "Going through all bonds of Walker." << endl;
    3993                         for (int i=0;i<NumberOfBondsPerAtom[AtomKeyNr];i++) {
    3994                                 Binder = ListOfBondsPerAtom[AtomKeyNr][i];
    3995                                 OtherWalker = Binder->GetOtherAtom(Walker);
    3996                                 if ((RestrictedKeySet.find(OtherWalker->nr) != RestrictedKeySet.end())
    3997         #ifdef ADDHYDROGEN
    3998                                 && (OtherWalker->type->Z != 1)
    3999         #endif
    4000                                                                                                                                                                                                                                                         ) {     // skip hydrogens and restrict to fragment
    4001                                         *out << Verbose(2) << "Current partner is " << *OtherWalker << " with nr " << OtherWalker->nr << " in bond " << *Binder << "." << endl;
    4002                                         // set the label if not set (and push on root stack as well)
    4003                                         if ((OtherWalker != Predecessor) && (OtherWalker->GetTrueFather()->nr > RootKeyNr)) { // only pass through those with label bigger than Root's
    4004                                                 FragmentSearch.ShortestPathList[OtherWalker->nr] = SP+1;
    4005                                                 *out << Verbose(3) << "Set Shortest Path to " << FragmentSearch.ShortestPathList[OtherWalker->nr] << "." << endl;
    4006                                                 // add the bond in between to the SP list
    4007                                                 Binder = new bond(Walker, OtherWalker); // create a new bond in such a manner, that bond::rightatom is always the one more distant
    4008                                                 add(Binder, FragmentSearch.BondsPerSPList[2*(SP+1)+1]);
    4009                                                 FragmentSearch.BondsPerSPCount[SP+1]++;
    4010                                                 *out << Verbose(3) << "Added its bond to SP list, having now " << FragmentSearch.BondsPerSPCount[SP+1] << " item(s)." << endl;
    4011                                         } else {
    4012                                                 if (OtherWalker != Predecessor)
    4013                                                         *out << Verbose(3) << "Not passing on, as index of " << *OtherWalker << " " << OtherWalker->GetTrueFather()->nr << " is smaller than that of Root " << RootKeyNr << "." << endl;
    4014                                                 else
    4015                                                         *out << Verbose(3) << "This is my predecessor " << *Predecessor << "." << endl;
    4016                                         }
    4017                                 } else *out << Verbose(2) << "Is not in the restricted keyset or skipping hydrogen " << *OtherWalker << "." << endl;
    4018                         }
    4019                 }
    4020         }
    4021 
    4022         // outputting all list for debugging
    4023         *out << Verbose(0) << "Printing all found lists." << endl;
    4024         for(int i=1;i<Order;i++) {              // skip the root edge in the printing
    4025                 Binder = FragmentSearch.BondsPerSPList[2*i];
    4026                 *out << Verbose(1) << "Current SP level is " << i << "." << endl;
    4027                 while (Binder->next != FragmentSearch.BondsPerSPList[2*i+1]) {
    4028                         Binder = Binder->next;
    4029                         *out << Verbose(2) << *Binder << endl;
    4030                 }
    4031         }
    4032 
    4033         // creating fragments with the found edge sets  (may be done in reverse order, faster)
    4034         SP = -1;        // the Root <-> Root edge must be subtracted!
    4035         for(int i=Order;i--;) { // sum up all found edges
    4036                 Binder = FragmentSearch.BondsPerSPList[2*i];
    4037                 while (Binder->next != FragmentSearch.BondsPerSPList[2*i+1]) {
    4038                         Binder = Binder->next;
    4039                         SP ++;
    4040                 }
    4041         }
    4042         *out << Verbose(0) << "Total number of edges is " << SP << "." << endl;
    4043         if (SP >= (Order-1)) {
    4044                 // start with root (push on fragment stack)
    4045                 *out << Verbose(0) << "Starting fragment generation with " << *FragmentSearch.Root << ", local nr is " << FragmentSearch.Root->nr << "." << endl;
    4046                 FragmentSearch.FragmentSet->clear();
    4047                 *out << Verbose(0) << "Preparing subset for this root and calling generator." << endl;
    4048                 // prepare the subset and call the generator
    4049                 BondsList = (bond **) Malloc(sizeof(bond *)*FragmentSearch.BondsPerSPCount[0], "molecule::PowerSetGenerator: **BondsList");
    4050                 BondsList[0] = FragmentSearch.BondsPerSPList[0]->next;  // on SP level 0 there's only the root bond
    4051 
    4052                 SPFragmentGenerator(out, &FragmentSearch, 0, BondsList, FragmentSearch.BondsPerSPCount[0], Order);
    4053 
    4054                 Free((void **)&BondsList, "molecule::PowerSetGenerator: **BondsList");
    4055         } else {
    4056                 *out << Verbose(0) << "Not enough total number of edges to build " << Order << "-body fragments." << endl;
    4057         }
    4058 
    4059         // as FragmentSearch structure is used only once, we don't have to clean it anymore
    4060         // remove root from stack
    4061         *out << Verbose(0) << "Removing root again from stack." << endl;
    4062         FragmentSearch.FragmentSet->erase(FragmentSearch.Root->nr);
    4063 
    4064         // free'ing the bonds lists
    4065         *out << Verbose(0) << "Free'ing all found lists. and resetting index lists" << endl;
    4066         for(int i=Order;i--;) {
    4067                 *out << Verbose(1) << "Current SP level is " << i << ": ";
    4068                 Binder = FragmentSearch.BondsPerSPList[2*i];
    4069                 while (Binder->next != FragmentSearch.BondsPerSPList[2*i+1]) {
    4070                         Binder = Binder->next;
    4071                         // *out << "Removing atom " << Binder->leftatom->nr << " and " << Binder->rightatom->nr << "." << endl; // make sure numbers are local
    4072                         FragmentSearch.ShortestPathList[Binder->leftatom->nr] = -1;
    4073                         FragmentSearch.ShortestPathList[Binder->rightatom->nr] = -1;
    4074                 }
    4075                 // delete added bonds
    4076                 cleanup(FragmentSearch.BondsPerSPList[2*i], FragmentSearch.BondsPerSPList[2*i+1]);
    4077                 // also start and end node
    4078                 *out << "cleaned." << endl;
    4079         }
    4080 
    4081         // return list
    4082         *out << Verbose(0) << "End of PowerSetGenerator." << endl;
    4083         return (FragmentSearch.FragmentCounter - Counter);
     3942  int SP, AtomKeyNr;
     3943  atom *Walker = NULL, *OtherWalker = NULL, *Predecessor = NULL;
     3944  bond *Binder = NULL;
     3945  bond *CurrentEdge = NULL;
     3946  bond **BondsList = NULL;
     3947  int RootKeyNr = FragmentSearch.Root->GetTrueFather()->nr;
     3948  int Counter = FragmentSearch.FragmentCounter;
     3949  int RemainingWalkers;
     3950
     3951  *out << endl;
     3952  *out << Verbose(0) << "Begin of PowerSetGenerator with order " << Order << " at Root " << *FragmentSearch.Root << "." << endl;
     3953
     3954  // prepare Label and SP arrays of the BFS search
     3955  FragmentSearch.ShortestPathList[FragmentSearch.Root->nr] = 0;
     3956
     3957  // prepare root level (SP = 0) and a loop bond denoting Root
     3958  for (int i=1;i<Order;i++)
     3959    FragmentSearch.BondsPerSPCount[i] = 0;
     3960  FragmentSearch.BondsPerSPCount[0] = 1;
     3961  Binder = new bond(FragmentSearch.Root, FragmentSearch.Root);
     3962  add(Binder, FragmentSearch.BondsPerSPList[1]);
     3963
     3964  // do a BFS search to fill the SP lists and label the found vertices
     3965  // Actually, we should construct a spanning tree vom the root atom and select all edges therefrom and put them into
     3966  // according shortest path lists. However, we don't. Rather we fill these lists right away, as they do form a spanning
     3967  // tree already sorted into various SP levels. That's why we just do loops over the depth (CurrentSP) and breadth
     3968  // (EdgeinSPLevel) of this tree ...
     3969  // In another picture, the bonds always contain a direction by rightatom being the one more distant from root and hence
     3970  // naturally leftatom forming its predecessor, preventing the BFS"seeker" from continuing in the wrong direction.
     3971  *out << endl;
     3972  *out << Verbose(0) << "Starting BFS analysis ..." << endl;
     3973  for (SP = 0; SP < (Order-1); SP++) {
     3974    *out << Verbose(1) << "New SP level reached: " << SP << ", creating new SP list with " << FragmentSearch.BondsPerSPCount[SP] << " item(s)";
     3975    if (SP > 0) {
     3976      *out << ", old level closed with " << FragmentSearch.BondsPerSPCount[SP-1] << " item(s)." << endl;
     3977      FragmentSearch.BondsPerSPCount[SP] = 0;
     3978    } else
     3979      *out << "." << endl;
     3980
     3981    RemainingWalkers = FragmentSearch.BondsPerSPCount[SP];
     3982    CurrentEdge = FragmentSearch.BondsPerSPList[2*SP];    /// start of this SP level's list
     3983    while (CurrentEdge->next != FragmentSearch.BondsPerSPList[2*SP+1]) {    /// end of this SP level's list
     3984      CurrentEdge = CurrentEdge->next;
     3985      RemainingWalkers--;
     3986      Walker = CurrentEdge->rightatom;    // rightatom is always the one more distant
     3987      Predecessor = CurrentEdge->leftatom;    // ... and leftatom is predecessor
     3988      AtomKeyNr = Walker->nr;
     3989      *out << Verbose(0) << "Current Walker is: " << *Walker << " with nr " << Walker->nr << " and SP of " << SP << ", with " << RemainingWalkers << " remaining walkers on this level." << endl;
     3990      // check for new sp level
     3991      // go through all its bonds
     3992      *out << Verbose(1) << "Going through all bonds of Walker." << endl;
     3993      for (int i=0;i<NumberOfBondsPerAtom[AtomKeyNr];i++) {
     3994        Binder = ListOfBondsPerAtom[AtomKeyNr][i];
     3995        OtherWalker = Binder->GetOtherAtom(Walker);
     3996        if ((RestrictedKeySet.find(OtherWalker->nr) != RestrictedKeySet.end())
     3997  #ifdef ADDHYDROGEN
     3998        && (OtherWalker->type->Z != 1)
     3999  #endif
     4000                                                              ) {  // skip hydrogens and restrict to fragment
     4001          *out << Verbose(2) << "Current partner is " << *OtherWalker << " with nr " << OtherWalker->nr << " in bond " << *Binder << "." << endl;
     4002          // set the label if not set (and push on root stack as well)
     4003          if ((OtherWalker != Predecessor) && (OtherWalker->GetTrueFather()->nr > RootKeyNr)) { // only pass through those with label bigger than Root's
     4004            FragmentSearch.ShortestPathList[OtherWalker->nr] = SP+1;
     4005            *out << Verbose(3) << "Set Shortest Path to " << FragmentSearch.ShortestPathList[OtherWalker->nr] << "." << endl;
     4006            // add the bond in between to the SP list
     4007            Binder = new bond(Walker, OtherWalker); // create a new bond in such a manner, that bond::rightatom is always the one more distant
     4008            add(Binder, FragmentSearch.BondsPerSPList[2*(SP+1)+1]);
     4009            FragmentSearch.BondsPerSPCount[SP+1]++;
     4010            *out << Verbose(3) << "Added its bond to SP list, having now " << FragmentSearch.BondsPerSPCount[SP+1] << " item(s)." << endl;
     4011          } else {
     4012            if (OtherWalker != Predecessor)
     4013              *out << Verbose(3) << "Not passing on, as index of " << *OtherWalker << " " << OtherWalker->GetTrueFather()->nr << " is smaller than that of Root " << RootKeyNr << "." << endl;
     4014            else
     4015              *out << Verbose(3) << "This is my predecessor " << *Predecessor << "." << endl;
     4016          }
     4017        } else *out << Verbose(2) << "Is not in the restricted keyset or skipping hydrogen " << *OtherWalker << "." << endl;
     4018      }
     4019    }
     4020  }
     4021
     4022  // outputting all list for debugging
     4023  *out << Verbose(0) << "Printing all found lists." << endl;
     4024  for(int i=1;i<Order;i++) {    // skip the root edge in the printing
     4025    Binder = FragmentSearch.BondsPerSPList[2*i];
     4026    *out << Verbose(1) << "Current SP level is " << i << "." << endl;
     4027    while (Binder->next != FragmentSearch.BondsPerSPList[2*i+1]) {
     4028      Binder = Binder->next;
     4029      *out << Verbose(2) << *Binder << endl;
     4030    }
     4031  }
     4032
     4033  // creating fragments with the found edge sets  (may be done in reverse order, faster)
     4034  SP = -1;  // the Root <-> Root edge must be subtracted!
     4035  for(int i=Order;i--;) { // sum up all found edges
     4036    Binder = FragmentSearch.BondsPerSPList[2*i];
     4037    while (Binder->next != FragmentSearch.BondsPerSPList[2*i+1]) {
     4038      Binder = Binder->next;
     4039      SP ++;
     4040    }
     4041  }
     4042  *out << Verbose(0) << "Total number of edges is " << SP << "." << endl;
     4043  if (SP >= (Order-1)) {
     4044    // start with root (push on fragment stack)
     4045    *out << Verbose(0) << "Starting fragment generation with " << *FragmentSearch.Root << ", local nr is " << FragmentSearch.Root->nr << "." << endl;
     4046    FragmentSearch.FragmentSet->clear();
     4047    *out << Verbose(0) << "Preparing subset for this root and calling generator." << endl;
     4048    // prepare the subset and call the generator
     4049    BondsList = (bond **) Malloc(sizeof(bond *)*FragmentSearch.BondsPerSPCount[0], "molecule::PowerSetGenerator: **BondsList");
     4050    BondsList[0] = FragmentSearch.BondsPerSPList[0]->next;  // on SP level 0 there's only the root bond
     4051
     4052    SPFragmentGenerator(out, &FragmentSearch, 0, BondsList, FragmentSearch.BondsPerSPCount[0], Order);
     4053
     4054    Free((void **)&BondsList, "molecule::PowerSetGenerator: **BondsList");
     4055  } else {
     4056    *out << Verbose(0) << "Not enough total number of edges to build " << Order << "-body fragments." << endl;
     4057  }
     4058
     4059  // as FragmentSearch structure is used only once, we don't have to clean it anymore
     4060  // remove root from stack
     4061  *out << Verbose(0) << "Removing root again from stack." << endl;
     4062  FragmentSearch.FragmentSet->erase(FragmentSearch.Root->nr);
     4063
     4064  // free'ing the bonds lists
     4065  *out << Verbose(0) << "Free'ing all found lists. and resetting index lists" << endl;
     4066  for(int i=Order;i--;) {
     4067    *out << Verbose(1) << "Current SP level is " << i << ": ";
     4068    Binder = FragmentSearch.BondsPerSPList[2*i];
     4069    while (Binder->next != FragmentSearch.BondsPerSPList[2*i+1]) {
     4070      Binder = Binder->next;
     4071      // *out << "Removing atom " << Binder->leftatom->nr << " and " << Binder->rightatom->nr << "." << endl; // make sure numbers are local
     4072      FragmentSearch.ShortestPathList[Binder->leftatom->nr] = -1;
     4073      FragmentSearch.ShortestPathList[Binder->rightatom->nr] = -1;
     4074    }
     4075    // delete added bonds
     4076    cleanup(FragmentSearch.BondsPerSPList[2*i], FragmentSearch.BondsPerSPList[2*i+1]);
     4077    // also start and end node
     4078    *out << "cleaned." << endl;
     4079  }
     4080
     4081  // return list
     4082  *out << Verbose(0) << "End of PowerSetGenerator." << endl;
     4083  return (FragmentSearch.FragmentCounter - Counter);
    40844084};
    40854085
     
    40924092void molecule::ScanForPeriodicCorrection(ofstream *out)
    40934093{
    4094         bond *Binder = NULL;
    4095         bond *OtherBinder = NULL;
    4096         atom *Walker = NULL;
    4097         atom *OtherWalker = NULL;
    4098         double *matrix = ReturnFullMatrixforSymmetric(cell_size);
    4099         enum Shading *ColorList = NULL;
    4100         double tmp;
    4101         Vector Translationvector;
    4102         //class StackClass<atom *> *CompStack = NULL;
    4103         class StackClass<atom *> *AtomStack = new StackClass<atom *>(AtomCount);
    4104         bool flag = true;
    4105 
    4106         *out << Verbose(2) << "Begin of ScanForPeriodicCorrection." << endl;
    4107 
    4108         ColorList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::ScanForPeriodicCorrection: *ColorList");
    4109         while (flag) {
    4110                 // remove bonds that are beyond bonddistance
    4111                 for(int i=NDIM;i--;)
    4112                         Translationvector.x[i] = 0.;
    4113                 // scan all bonds
    4114                 Binder = first;
    4115                 flag = false;
    4116                 while ((!flag) && (Binder->next != last)) {
    4117                         Binder = Binder->next;
    4118                         for (int i=NDIM;i--;) {
    4119                                 tmp = fabs(Binder->leftatom->x.x[i] - Binder->rightatom->x.x[i]);
    4120                                 //*out << Verbose(3) << "Checking " << i << "th distance of " << *Binder->leftatom << " to " << *Binder->rightatom << ": " << tmp << "." << endl;
    4121                                 if (tmp > BondDistance) {
    4122                                         OtherBinder = Binder->next; // note down binding partner for later re-insertion
    4123                                         unlink(Binder); // unlink bond
    4124                                         *out << Verbose(2) << "Correcting at bond " << *Binder << "." << endl;
    4125                                         flag = true;
    4126                                         break;
    4127                                 }
    4128                         }
    4129                 }
    4130                 if (flag) {
    4131                         // create translation vector from their periodically modified distance
    4132                         for (int i=NDIM;i--;) {
    4133                                 tmp = Binder->leftatom->x.x[i] - Binder->rightatom->x.x[i];
    4134                                 if (fabs(tmp) > BondDistance)
    4135                                         Translationvector.x[i] = (tmp < 0) ? +1. : -1.;
    4136                         }
    4137                         Translationvector.MatrixMultiplication(matrix);
    4138                         //*out << Verbose(3) << "Translation vector is ";
    4139                         Translationvector.Output(out);
    4140                         *out << endl;
    4141                         // apply to all atoms of first component via BFS
    4142                         for (int i=AtomCount;i--;)
    4143                                 ColorList[i] = white;
    4144                         AtomStack->Push(Binder->leftatom);
    4145                         while (!AtomStack->IsEmpty()) {
    4146                                 Walker = AtomStack->PopFirst();
    4147                                 //*out << Verbose (3) << "Current Walker is: " << *Walker << "." << endl;
    4148                                 ColorList[Walker->nr] = black;          // mark as explored
    4149                                 Walker->x.AddVector(&Translationvector); // translate
    4150                                 for (int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {  // go through all binding partners
    4151                                         if (ListOfBondsPerAtom[Walker->nr][i] != Binder) {
    4152                                                 OtherWalker = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
    4153                                                 if (ColorList[OtherWalker->nr] == white) {
    4154                                                         AtomStack->Push(OtherWalker); // push if yet unexplored
    4155                                                 }
    4156                                         }
    4157                                 }
    4158                         }
    4159                         // re-add bond
    4160                         link(Binder, OtherBinder);
    4161                 } else {
    4162                         *out << Verbose(3) << "No corrections for this fragment." << endl;
    4163                 }
    4164                 //delete(CompStack);
    4165         }
    4166 
    4167         // free allocated space from ReturnFullMatrixforSymmetric()
    4168         delete(AtomStack);
    4169         Free((void **)&ColorList, "molecule::ScanForPeriodicCorrection: *ColorList");
    4170         Free((void **)&matrix, "molecule::ScanForPeriodicCorrection: *matrix");
    4171         *out << Verbose(2) << "End of ScanForPeriodicCorrection." << endl;
     4094  bond *Binder = NULL;
     4095  bond *OtherBinder = NULL;
     4096  atom *Walker = NULL;
     4097  atom *OtherWalker = NULL;
     4098  double *matrix = ReturnFullMatrixforSymmetric(cell_size);
     4099  enum Shading *ColorList = NULL;
     4100  double tmp;
     4101  Vector Translationvector;
     4102  //class StackClass<atom *> *CompStack = NULL;
     4103  class StackClass<atom *> *AtomStack = new StackClass<atom *>(AtomCount);
     4104  bool flag = true;
     4105
     4106  *out << Verbose(2) << "Begin of ScanForPeriodicCorrection." << endl;
     4107
     4108  ColorList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::ScanForPeriodicCorrection: *ColorList");
     4109  while (flag) {
     4110    // remove bonds that are beyond bonddistance
     4111    for(int i=NDIM;i--;)
     4112      Translationvector.x[i] = 0.;
     4113    // scan all bonds
     4114    Binder = first;
     4115    flag = false;
     4116    while ((!flag) && (Binder->next != last)) {
     4117      Binder = Binder->next;
     4118      for (int i=NDIM;i--;) {
     4119        tmp = fabs(Binder->leftatom->x.x[i] - Binder->rightatom->x.x[i]);
     4120        //*out << Verbose(3) << "Checking " << i << "th distance of " << *Binder->leftatom << " to " << *Binder->rightatom << ": " << tmp << "." << endl;
     4121        if (tmp > BondDistance) {
     4122          OtherBinder = Binder->next; // note down binding partner for later re-insertion
     4123          unlink(Binder);  // unlink bond
     4124          *out << Verbose(2) << "Correcting at bond " << *Binder << "." << endl;
     4125          flag = true;
     4126          break;
     4127        }
     4128      }
     4129    }
     4130    if (flag) {
     4131      // create translation vector from their periodically modified distance
     4132      for (int i=NDIM;i--;) {
     4133        tmp = Binder->leftatom->x.x[i] - Binder->rightatom->x.x[i];
     4134        if (fabs(tmp) > BondDistance)
     4135          Translationvector.x[i] = (tmp < 0) ? +1. : -1.;
     4136      }
     4137      Translationvector.MatrixMultiplication(matrix);
     4138      //*out << Verbose(3) << "Translation vector is ";
     4139      Translationvector.Output(out);
     4140      *out << endl;
     4141      // apply to all atoms of first component via BFS
     4142      for (int i=AtomCount;i--;)
     4143        ColorList[i] = white;
     4144      AtomStack->Push(Binder->leftatom);
     4145      while (!AtomStack->IsEmpty()) {
     4146        Walker = AtomStack->PopFirst();
     4147        //*out << Verbose (3) << "Current Walker is: " << *Walker << "." << endl;
     4148        ColorList[Walker->nr] = black;    // mark as explored
     4149        Walker->x.AddVector(&Translationvector); // translate
     4150        for (int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {  // go through all binding partners
     4151          if (ListOfBondsPerAtom[Walker->nr][i] != Binder) {
     4152            OtherWalker = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
     4153            if (ColorList[OtherWalker->nr] == white) {
     4154              AtomStack->Push(OtherWalker); // push if yet unexplored
     4155            }
     4156          }
     4157        }
     4158      }
     4159      // re-add bond
     4160      link(Binder, OtherBinder);
     4161    } else {
     4162      *out << Verbose(3) << "No corrections for this fragment." << endl;
     4163    }
     4164    //delete(CompStack);
     4165  }
     4166
     4167  // free allocated space from ReturnFullMatrixforSymmetric()
     4168  delete(AtomStack);
     4169  Free((void **)&ColorList, "molecule::ScanForPeriodicCorrection: *ColorList");
     4170  Free((void **)&matrix, "molecule::ScanForPeriodicCorrection: *matrix");
     4171  *out << Verbose(2) << "End of ScanForPeriodicCorrection." << endl;
    41724172};
    41734173
     
    41784178double * molecule::ReturnFullMatrixforSymmetric(double *symm)
    41794179{
    4180         double *matrix = (double *) Malloc(sizeof(double)*NDIM*NDIM, "molecule::ReturnFullMatrixforSymmetric: *matrix");
    4181         matrix[0] = symm[0];
    4182         matrix[1] = symm[1];
    4183         matrix[2] = symm[2];
    4184         matrix[3] = symm[1];
    4185         matrix[4] = symm[3];
    4186         matrix[5] = symm[4];
    4187         matrix[6] = symm[2];
    4188         matrix[7] = symm[4];
    4189         matrix[8] = symm[5];
    4190         return matrix;
     4180  double *matrix = (double *) Malloc(sizeof(double)*NDIM*NDIM, "molecule::ReturnFullMatrixforSymmetric: *matrix");
     4181  matrix[0] = symm[0];
     4182  matrix[1] = symm[1];
     4183  matrix[2] = symm[2];
     4184  matrix[3] = symm[1];
     4185  matrix[4] = symm[3];
     4186  matrix[5] = symm[4];
     4187  matrix[6] = symm[2];
     4188  matrix[7] = symm[4];
     4189  matrix[8] = symm[5];
     4190  return matrix;
    41914191};
    41924192
    41934193bool KeyCompare::operator() (const KeySet SubgraphA, const KeySet SubgraphB) const
    41944194{
    4195         //cout << "my check is used." << endl;
    4196         if (SubgraphA.size() < SubgraphB.size()) {
    4197                 return true;
    4198         } else {
    4199                 if (SubgraphA.size() > SubgraphB.size()) {
    4200                         return false;
    4201                 } else {
    4202                         KeySet::iterator IteratorA = SubgraphA.begin();
    4203                         KeySet::iterator IteratorB = SubgraphB.begin();
    4204                         while ((IteratorA != SubgraphA.end()) && (IteratorB != SubgraphB.end())) {
    4205                                 if ((*IteratorA) <      (*IteratorB))
    4206                                         return true;
    4207                                 else if ((*IteratorA) > (*IteratorB)) {
    4208                                                 return false;
    4209                                         } // else, go on to next index
    4210                                 IteratorA++;
    4211                                 IteratorB++;
    4212                         } // end of while loop
    4213                 }// end of check in case of equal sizes
    4214         }
    4215         return false; // if we reach this point, they are equal
     4195  //cout << "my check is used." << endl;
     4196  if (SubgraphA.size() < SubgraphB.size()) {
     4197    return true;
     4198  } else {
     4199    if (SubgraphA.size() > SubgraphB.size()) {
     4200      return false;
     4201    } else {
     4202      KeySet::iterator IteratorA = SubgraphA.begin();
     4203      KeySet::iterator IteratorB = SubgraphB.begin();
     4204      while ((IteratorA != SubgraphA.end()) && (IteratorB != SubgraphB.end())) {
     4205        if ((*IteratorA) <  (*IteratorB))
     4206          return true;
     4207        else if ((*IteratorA) > (*IteratorB)) {
     4208            return false;
     4209          } // else, go on to next index
     4210        IteratorA++;
     4211        IteratorB++;
     4212      } // end of while loop
     4213    }// end of check in case of equal sizes
     4214  }
     4215  return false; // if we reach this point, they are equal
    42164216};
    42174217
    42184218//bool operator < (KeySet SubgraphA, KeySet SubgraphB)
    42194219//{
    4220 //      return KeyCompare(SubgraphA, SubgraphB);
     4220//  return KeyCompare(SubgraphA, SubgraphB);
    42214221//};
    42224222
     
    42304230inline void InsertFragmentIntoGraph(ofstream *out, struct UniqueFragments *Fragment)
    42314231{
    4232         GraphTestPair testGraphInsert;
    4233 
    4234         testGraphInsert = Fragment->Leaflet->insert(GraphPair (*Fragment->FragmentSet,pair<int,double>(Fragment->FragmentCounter,Fragment->TEFactor))); // store fragment number and current factor
    4235         if (testGraphInsert.second) {
    4236                 *out << Verbose(2) << "KeySet " << Fragment->FragmentCounter << " successfully inserted." << endl;
    4237                 Fragment->FragmentCounter++;
    4238         } else {
    4239                 *out << Verbose(2) << "KeySet " << Fragment->FragmentCounter << " failed to insert, present fragment is " << ((*(testGraphInsert.first)).second).first << endl;
    4240                 ((*(testGraphInsert.first)).second).second += Fragment->TEFactor;       // increase the "created" counter
    4241                 *out << Verbose(2) << "New factor is " << ((*(testGraphInsert.first)).second).second << "." << endl;
    4242         }
     4232  GraphTestPair testGraphInsert;
     4233
     4234  testGraphInsert = Fragment->Leaflet->insert(GraphPair (*Fragment->FragmentSet,pair<int,double>(Fragment->FragmentCounter,Fragment->TEFactor)));  // store fragment number and current factor
     4235  if (testGraphInsert.second) {
     4236    *out << Verbose(2) << "KeySet " << Fragment->FragmentCounter << " successfully inserted." << endl;
     4237    Fragment->FragmentCounter++;
     4238  } else {
     4239    *out << Verbose(2) << "KeySet " << Fragment->FragmentCounter << " failed to insert, present fragment is " << ((*(testGraphInsert.first)).second).first << endl;
     4240    ((*(testGraphInsert.first)).second).second += Fragment->TEFactor;  // increase the "created" counter
     4241    *out << Verbose(2) << "New factor is " << ((*(testGraphInsert.first)).second).second << "." << endl;
     4242  }
    42434243};
    42444244//void inline InsertIntoGraph(ofstream *out, KeyStack &stack, Graph &graph, int *counter, double factor)
    42454245//{
    4246 //      // copy stack contents to set and call overloaded function again
    4247 //      KeySet set;
    4248 //      for(KeyStack::iterator runner = stack.begin(); runner != stack.begin(); runner++)
    4249 //              set.insert((*runner));
    4250 //      InsertIntoGraph(out, set, graph, counter, factor);
     4246//  // copy stack contents to set and call overloaded function again
     4247//  KeySet set;
     4248//  for(KeyStack::iterator runner = stack.begin(); runner != stack.begin(); runner++)
     4249//    set.insert((*runner));
     4250//  InsertIntoGraph(out, set, graph, counter, factor);
    42514251//};
    42524252
     
    42594259inline void InsertGraphIntoGraph(ofstream *out, Graph &graph1, Graph &graph2, int *counter)
    42604260{
    4261         GraphTestPair testGraphInsert;
    4262 
    4263         for(Graph::iterator runner = graph2.begin(); runner != graph2.end(); runner++) {
    4264                 testGraphInsert = graph1.insert(GraphPair ((*runner).first,pair<int,double>((*counter)++,((*runner).second).second)));  // store fragment number and current factor
    4265                 if (testGraphInsert.second) {
    4266                         *out << Verbose(2) << "KeySet " << (*counter)-1 << " successfully inserted." << endl;
    4267                 } else {
    4268                         *out << Verbose(2) << "KeySet " << (*counter)-1 << " failed to insert, present fragment is " << ((*(testGraphInsert.first)).second).first << endl;
    4269                         ((*(testGraphInsert.first)).second).second += (*runner).second.second;
    4270                         *out << Verbose(2) << "New factor is " << (*(testGraphInsert.first)).second.second << "." << endl;
    4271                 }
    4272         }
     4261  GraphTestPair testGraphInsert;
     4262
     4263  for(Graph::iterator runner = graph2.begin(); runner != graph2.end(); runner++) {
     4264    testGraphInsert = graph1.insert(GraphPair ((*runner).first,pair<int,double>((*counter)++,((*runner).second).second)));  // store fragment number and current factor
     4265    if (testGraphInsert.second) {
     4266      *out << Verbose(2) << "KeySet " << (*counter)-1 << " successfully inserted." << endl;
     4267    } else {
     4268      *out << Verbose(2) << "KeySet " << (*counter)-1 << " failed to insert, present fragment is " << ((*(testGraphInsert.first)).second).first << endl;
     4269      ((*(testGraphInsert.first)).second).second += (*runner).second.second;
     4270      *out << Verbose(2) << "New factor is " << (*(testGraphInsert.first)).second.second << "." << endl;
     4271    }
     4272  }
    42734273};
    42744274
     
    42774277 * -# constructs a complete keyset of the molecule
    42784278 * -# In a loop over all possible roots from the given rootstack
    4279  *      -# increases order of root site
    4280  *      -# calls PowerSetGenerator with this order, the complete keyset and the rootkeynr
    4281  *      -# for all consecutive lower levels PowerSetGenerator is called with the suborder, the higher order keyset
     4279 *  -# increases order of root site
     4280 *  -# calls PowerSetGenerator with this order, the complete keyset and the rootkeynr
     4281 *  -# for all consecutive lower levels PowerSetGenerator is called with the suborder, the higher order keyset
    42824282as the restricted one and each site in the set as the root)
    4283  *      -# these are merged into a fragment list of keysets
     4283 *  -# these are merged into a fragment list of keysets
    42844284 * -# All fragment lists (for all orders, i.e. from all destination fields) are merged into one list for return
    42854285 * Important only is that we create all fragments, it is not important if we create them more than once
     
    42934293void molecule::FragmentBOSSANOVA(ofstream *out, Graph *&FragmentList, KeyStack &RootStack, int *MinimumRingSize)
    42944294{
    4295         Graph ***FragmentLowerOrdersList = NULL;
    4296         int NumLevels, NumMolecules, TotalNumMolecules = 0, *NumMoleculesOfOrder = NULL;
    4297         int counter = 0, Order;
    4298         int UpgradeCount = RootStack.size();
    4299         KeyStack FragmentRootStack;
    4300         int RootKeyNr, RootNr;
    4301         struct UniqueFragments FragmentSearch;
    4302 
    4303         *out << Verbose(0) << "Begin of FragmentBOSSANOVA." << endl;
    4304 
    4305         // FragmentLowerOrdersList is a 2D-array of pointer to MoleculeListClass objects, one dimension represents the ANOVA expansion of a single order (i.e. 5)
    4306         // with all needed lower orders that are subtracted, the other dimension is the BondOrder (i.e. from 1 to 5)
    4307         NumMoleculesOfOrder = (int *) Malloc(sizeof(int)*UpgradeCount, "molecule::FragmentBOSSANOVA: *NumMoleculesOfOrder");
    4308         FragmentLowerOrdersList = (Graph ***) Malloc(sizeof(Graph **)*UpgradeCount, "molecule::FragmentBOSSANOVA: ***FragmentLowerOrdersList");
    4309 
    4310         // initialise the fragments structure
    4311         FragmentSearch.ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::PowerSetGenerator: *ShortestPathList");
    4312         FragmentSearch.FragmentCounter = 0;
    4313         FragmentSearch.FragmentSet = new KeySet;
    4314         FragmentSearch.Root = FindAtom(RootKeyNr);
    4315         for (int i=AtomCount;i--;) {
    4316                 FragmentSearch.ShortestPathList[i] = -1;
    4317         }
    4318 
    4319         // Construct the complete KeySet which we need for topmost level only (but for all Roots)
    4320         atom *Walker = start;
    4321         KeySet CompleteMolecule;
    4322         while (Walker->next != end) {
    4323                 Walker = Walker->next;
    4324                 CompleteMolecule.insert(Walker->GetTrueFather()->nr);
    4325         }
    4326 
    4327         // this can easily be seen: if Order is 5, then the number of levels for each lower order is the total sum of the number of levels above, as
    4328         // each has to be split up. E.g. for the second level we have one from 5th, one from 4th, two from 3th (which in turn is one from 5th, one from 4th),
    4329         // hence we have overall four 2th order levels for splitting. This also allows for putting all into a single array (FragmentLowerOrdersList[])
    4330         // with the order along the cells as this: 5433222211111111 for BondOrder 5 needing 16=pow(2,5-1) cells (only we use bit-shifting which is faster)
    4331         RootNr = 0;      // counts through the roots in RootStack
    4332         while ((RootNr < UpgradeCount) && (!RootStack.empty())) {
    4333                 RootKeyNr = RootStack.front();
    4334                 RootStack.pop_front();
    4335                 Walker = FindAtom(RootKeyNr);
    4336                 // check cyclic lengths
    4337                 //if ((MinimumRingSize[Walker->GetTrueFather()->nr] != -1) && (Walker->GetTrueFather()->AdaptiveOrder+1 > MinimumRingSize[Walker->GetTrueFather()->nr])) {
    4338                 //      *out << Verbose(0) << "Bond order " << Walker->GetTrueFather()->AdaptiveOrder << " of Root " << *Walker << " greater than or equal to Minimum Ring size of " << MinimumRingSize << " found is not allowed." << endl;
    4339                 //} else
    4340                 {
    4341                         // increase adaptive order by one
    4342                         Walker->GetTrueFather()->AdaptiveOrder++;
    4343                         Order = Walker->AdaptiveOrder = Walker->GetTrueFather()->AdaptiveOrder;
    4344 
    4345                         // initialise Order-dependent entries of UniqueFragments structure
    4346                         FragmentSearch.BondsPerSPList = (bond **) Malloc(sizeof(bond *)*Order*2, "molecule::PowerSetGenerator: ***BondsPerSPList");
    4347                         FragmentSearch.BondsPerSPCount = (int *) Malloc(sizeof(int)*Order, "molecule::PowerSetGenerator: *BondsPerSPCount");
    4348                         for (int i=Order;i--;) {
    4349                                 FragmentSearch.BondsPerSPList[2*i] = new bond();                // start node
    4350                                 FragmentSearch.BondsPerSPList[2*i+1] = new bond();      // end node
    4351                                 FragmentSearch.BondsPerSPList[2*i]->next = FragmentSearch.BondsPerSPList[2*i+1];                // intertwine these two
    4352                                 FragmentSearch.BondsPerSPList[2*i+1]->previous = FragmentSearch.BondsPerSPList[2*i];
    4353                                 FragmentSearch.BondsPerSPCount[i] = 0;
    4354                         }
    4355 
    4356                         // allocate memory for all lower level orders in this 1D-array of ptrs
    4357                         NumLevels = 1 << (Order-1); // (int)pow(2,Order);
    4358                         FragmentLowerOrdersList[RootNr] = (Graph **) Malloc(sizeof(Graph *)*NumLevels, "molecule::FragmentBOSSANOVA: **FragmentLowerOrdersList[]");
    4359                         for (int i=0;i<NumLevels;i++)
    4360                                 FragmentLowerOrdersList[RootNr][i] = NULL;
    4361 
    4362                         // create top order where nothing is reduced
    4363                         *out << Verbose(0) << "==============================================================================================================" << endl;
    4364                         *out << Verbose(0) << "Creating KeySets of Bond Order " << Order << " for " << *Walker << ", " << (RootStack.size()-RootNr) << " Roots remaining." << endl; // , NumLevels is " << NumLevels << "
    4365 
    4366                         // Create list of Graphs of current Bond Order (i.e. F_{ij})
    4367                         FragmentLowerOrdersList[RootNr][0] =    new Graph;
    4368                         FragmentSearch.TEFactor = 1.;
    4369                         FragmentSearch.Leaflet = FragmentLowerOrdersList[RootNr][0];                    // set to insertion graph
    4370                         FragmentSearch.Root = Walker;
    4371                         NumMoleculesOfOrder[RootNr] = PowerSetGenerator(out, Walker->AdaptiveOrder, FragmentSearch, CompleteMolecule);
    4372                         *out << Verbose(1) << "Number of resulting KeySets is: " << NumMoleculesOfOrder[RootNr] << "." << endl;
    4373                         if (NumMoleculesOfOrder[RootNr] != 0) {
    4374                                 NumMolecules = 0;
    4375 
    4376                                 // we don't have to dive into suborders! These keysets are all already created on lower orders!
    4377                                 // this was all ancient stuff, when we still depended on the TEFactors (and for those the suborders were needed)
    4378 
    4379 //                              if ((NumLevels >> 1) > 0) {
    4380 //                                      // create lower order fragments
    4381 //                                      *out << Verbose(0) << "Creating list of unique fragments of lower Bond Order terms to be subtracted." << endl;
    4382 //                                      Order = Walker->AdaptiveOrder;
    4383 //                                      for (int source=0;source<(NumLevels >> 1);source++) { // 1-terms don't need any more splitting, that's why only half is gone through (shift again)
    4384 //                                              // step down to next order at (virtual) boundary of powers of 2 in array
    4385 //                                              while (source >= (1 << (Walker->AdaptiveOrder-Order))) // (int)pow(2,Walker->AdaptiveOrder-Order))
    4386 //                                                      Order--;
    4387 //                                              *out << Verbose(0) << "Current Order is: " << Order << "." << endl;
    4388 //                                              for (int SubOrder=Order-1;SubOrder>0;SubOrder--) {
    4389 //                                                      int dest = source + (1 << (Walker->AdaptiveOrder-(SubOrder+1)));
    4390 //                                                      *out << Verbose(0) << "--------------------------------------------------------------------------------------------------------------" << endl;
    4391 //                                                      *out << Verbose(0) << "Current SubOrder is: " << SubOrder << " with source " << source << " to destination " << dest << "." << endl;
     4295  Graph ***FragmentLowerOrdersList = NULL;
     4296  int NumLevels, NumMolecules, TotalNumMolecules = 0, *NumMoleculesOfOrder = NULL;
     4297  int counter = 0, Order;
     4298  int UpgradeCount = RootStack.size();
     4299  KeyStack FragmentRootStack;
     4300  int RootKeyNr, RootNr;
     4301  struct UniqueFragments FragmentSearch;
     4302
     4303  *out << Verbose(0) << "Begin of FragmentBOSSANOVA." << endl;
     4304
     4305  // FragmentLowerOrdersList is a 2D-array of pointer to MoleculeListClass objects, one dimension represents the ANOVA expansion of a single order (i.e. 5)
     4306  // with all needed lower orders that are subtracted, the other dimension is the BondOrder (i.e. from 1 to 5)
     4307  NumMoleculesOfOrder = (int *) Malloc(sizeof(int)*UpgradeCount, "molecule::FragmentBOSSANOVA: *NumMoleculesOfOrder");
     4308  FragmentLowerOrdersList = (Graph ***) Malloc(sizeof(Graph **)*UpgradeCount, "molecule::FragmentBOSSANOVA: ***FragmentLowerOrdersList");
     4309
     4310  // initialise the fragments structure
     4311  FragmentSearch.ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::PowerSetGenerator: *ShortestPathList");
     4312  FragmentSearch.FragmentCounter = 0;
     4313  FragmentSearch.FragmentSet = new KeySet;
     4314  FragmentSearch.Root = FindAtom(RootKeyNr);
     4315  for (int i=AtomCount;i--;) {
     4316    FragmentSearch.ShortestPathList[i] = -1;
     4317  }
     4318
     4319  // Construct the complete KeySet which we need for topmost level only (but for all Roots)
     4320  atom *Walker = start;
     4321  KeySet CompleteMolecule;
     4322  while (Walker->next != end) {
     4323    Walker = Walker->next;
     4324    CompleteMolecule.insert(Walker->GetTrueFather()->nr);
     4325  }
     4326
     4327  // this can easily be seen: if Order is 5, then the number of levels for each lower order is the total sum of the number of levels above, as
     4328  // each has to be split up. E.g. for the second level we have one from 5th, one from 4th, two from 3th (which in turn is one from 5th, one from 4th),
     4329  // hence we have overall four 2th order levels for splitting. This also allows for putting all into a single array (FragmentLowerOrdersList[])
     4330  // with the order along the cells as this: 5433222211111111 for BondOrder 5 needing 16=pow(2,5-1) cells (only we use bit-shifting which is faster)
     4331  RootNr = 0;  // counts through the roots in RootStack
     4332  while ((RootNr < UpgradeCount) && (!RootStack.empty())) {
     4333    RootKeyNr = RootStack.front();
     4334    RootStack.pop_front();
     4335    Walker = FindAtom(RootKeyNr);
     4336    // check cyclic lengths
     4337    //if ((MinimumRingSize[Walker->GetTrueFather()->nr] != -1) && (Walker->GetTrueFather()->AdaptiveOrder+1 > MinimumRingSize[Walker->GetTrueFather()->nr])) {
     4338    //  *out << Verbose(0) << "Bond order " << Walker->GetTrueFather()->AdaptiveOrder << " of Root " << *Walker << " greater than or equal to Minimum Ring size of " << MinimumRingSize << " found is not allowed." << endl;
     4339    //} else
     4340    {
     4341      // increase adaptive order by one
     4342      Walker->GetTrueFather()->AdaptiveOrder++;
     4343      Order = Walker->AdaptiveOrder = Walker->GetTrueFather()->AdaptiveOrder;
     4344
     4345      // initialise Order-dependent entries of UniqueFragments structure
     4346      FragmentSearch.BondsPerSPList = (bond **) Malloc(sizeof(bond *)*Order*2, "molecule::PowerSetGenerator: ***BondsPerSPList");
     4347      FragmentSearch.BondsPerSPCount = (int *) Malloc(sizeof(int)*Order, "molecule::PowerSetGenerator: *BondsPerSPCount");
     4348      for (int i=Order;i--;) {
     4349        FragmentSearch.BondsPerSPList[2*i] = new bond();    // start node
     4350        FragmentSearch.BondsPerSPList[2*i+1] = new bond();  // end node
     4351        FragmentSearch.BondsPerSPList[2*i]->next = FragmentSearch.BondsPerSPList[2*i+1];    // intertwine these two
     4352        FragmentSearch.BondsPerSPList[2*i+1]->previous = FragmentSearch.BondsPerSPList[2*i];
     4353        FragmentSearch.BondsPerSPCount[i] = 0;
     4354      }
     4355
     4356      // allocate memory for all lower level orders in this 1D-array of ptrs
     4357      NumLevels = 1 << (Order-1); // (int)pow(2,Order);
     4358      FragmentLowerOrdersList[RootNr] = (Graph **) Malloc(sizeof(Graph *)*NumLevels, "molecule::FragmentBOSSANOVA: **FragmentLowerOrdersList[]");
     4359      for (int i=0;i<NumLevels;i++)
     4360        FragmentLowerOrdersList[RootNr][i] = NULL;
     4361
     4362      // create top order where nothing is reduced
     4363      *out << Verbose(0) << "==============================================================================================================" << endl;
     4364      *out << Verbose(0) << "Creating KeySets of Bond Order " << Order << " for " << *Walker << ", " << (RootStack.size()-RootNr) << " Roots remaining." << endl; // , NumLevels is " << NumLevels << "
     4365
     4366      // Create list of Graphs of current Bond Order (i.e. F_{ij})
     4367      FragmentLowerOrdersList[RootNr][0] =  new Graph;
     4368      FragmentSearch.TEFactor = 1.;
     4369      FragmentSearch.Leaflet = FragmentLowerOrdersList[RootNr][0];      // set to insertion graph
     4370      FragmentSearch.Root = Walker;
     4371      NumMoleculesOfOrder[RootNr] = PowerSetGenerator(out, Walker->AdaptiveOrder, FragmentSearch, CompleteMolecule);
     4372      *out << Verbose(1) << "Number of resulting KeySets is: " << NumMoleculesOfOrder[RootNr] << "." << endl;
     4373      if (NumMoleculesOfOrder[RootNr] != 0) {
     4374        NumMolecules = 0;
     4375
     4376        // we don't have to dive into suborders! These keysets are all already created on lower orders!
     4377        // this was all ancient stuff, when we still depended on the TEFactors (and for those the suborders were needed)
     4378
     4379//        if ((NumLevels >> 1) > 0) {
     4380//          // create lower order fragments
     4381//          *out << Verbose(0) << "Creating list of unique fragments of lower Bond Order terms to be subtracted." << endl;
     4382//          Order = Walker->AdaptiveOrder;
     4383//          for (int source=0;source<(NumLevels >> 1);source++) { // 1-terms don't need any more splitting, that's why only half is gone through (shift again)
     4384//            // step down to next order at (virtual) boundary of powers of 2 in array
     4385//            while (source >= (1 << (Walker->AdaptiveOrder-Order))) // (int)pow(2,Walker->AdaptiveOrder-Order))
     4386//              Order--;
     4387//            *out << Verbose(0) << "Current Order is: " << Order << "." << endl;
     4388//            for (int SubOrder=Order-1;SubOrder>0;SubOrder--) {
     4389//              int dest = source + (1 << (Walker->AdaptiveOrder-(SubOrder+1)));
     4390//              *out << Verbose(0) << "--------------------------------------------------------------------------------------------------------------" << endl;
     4391//              *out << Verbose(0) << "Current SubOrder is: " << SubOrder << " with source " << source << " to destination " << dest << "." << endl;
    43924392//
    4393 //                                                      // every molecule is split into a list of again (Order - 1) molecules, while counting all molecules
    4394 //                                                      //*out << Verbose(1) << "Splitting the " << (*FragmentLowerOrdersList[RootNr][source]).size() << " molecules of the " << source << "th cell in the array." << endl;
    4395 //                                                      //NumMolecules = 0;
    4396 //                                                      FragmentLowerOrdersList[RootNr][dest] = new Graph;
    4397 //                                                      for(Graph::iterator runner = (*FragmentLowerOrdersList[RootNr][source]).begin();runner != (*FragmentLowerOrdersList[RootNr][source]).end(); runner++) {
    4398 //                                                              for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) {
    4399 //                                                                      Graph TempFragmentList;
    4400 //                                                                      FragmentSearch.TEFactor = -(*runner).second.second;
    4401 //                                                                      FragmentSearch.Leaflet = &TempFragmentList;                     // set to insertion graph
    4402 //                                                                      FragmentSearch.Root = FindAtom(*sprinter);
    4403 //                                                                      NumMoleculesOfOrder[RootNr] += PowerSetGenerator(out, SubOrder, FragmentSearch, (*runner).first);
    4404 //                                                                      // insert new keysets FragmentList into FragmentLowerOrdersList[Walker->AdaptiveOrder-1][dest]
    4405 //                                                                      *out << Verbose(1) << "Merging resulting key sets with those present in destination " << dest << "." << endl;
    4406 //                                                                      InsertGraphIntoGraph(out, *FragmentLowerOrdersList[RootNr][dest], TempFragmentList, &NumMolecules);
    4407 //                                                              }
    4408 //                                                      }
    4409 //                                                      *out << Verbose(1) << "Number of resulting molecules for SubOrder " << SubOrder << " is: " << NumMolecules << "." << endl;
    4410 //                                              }
    4411 //                                      }
    4412 //                              }
    4413                         } else {
    4414                                 Walker->GetTrueFather()->MaxOrder = true;
    4415 //                              *out << Verbose(1) << "Hence, we don't dive into SubOrders ... " << endl;
    4416                         }
    4417                         // now, we have completely filled each cell of FragmentLowerOrdersList[] for the current Walker->AdaptiveOrder
    4418                         //NumMoleculesOfOrder[Walker->AdaptiveOrder-1] = NumMolecules;
    4419                         TotalNumMolecules += NumMoleculesOfOrder[RootNr];
    4420 //                      *out << Verbose(1) << "Number of resulting molecules for Order " << (int)Walker->GetTrueFather()->AdaptiveOrder << " is: " << NumMoleculesOfOrder[RootNr] << "." << endl;
    4421                         RootStack.push_back(RootKeyNr); // put back on stack
    4422                         RootNr++;
    4423 
    4424                         // free Order-dependent entries of UniqueFragments structure for next loop cycle
    4425                         Free((void **)&FragmentSearch.BondsPerSPCount, "molecule::PowerSetGenerator: *BondsPerSPCount");
    4426                         for (int i=Order;i--;) {
    4427                                 delete(FragmentSearch.BondsPerSPList[2*i]);
    4428                                 delete(FragmentSearch.BondsPerSPList[2*i+1]);
    4429                         }
    4430                         Free((void **)&FragmentSearch.BondsPerSPList, "molecule::PowerSetGenerator: ***BondsPerSPList");
    4431                 }
    4432         }
    4433         *out << Verbose(0) << "==============================================================================================================" << endl;
    4434         *out << Verbose(1) << "Total number of resulting molecules is: " << TotalNumMolecules << "." << endl;
    4435         *out << Verbose(0) << "==============================================================================================================" << endl;
    4436 
    4437         // cleanup FragmentSearch structure
    4438         Free((void **)&FragmentSearch.ShortestPathList, "molecule::PowerSetGenerator: *ShortestPathList");
    4439         delete(FragmentSearch.FragmentSet);
    4440 
    4441         // now, FragmentLowerOrdersList is complete, it looks - for BondOrder 5 - as this (number is the ANOVA Order of the terms therein)
    4442         // 5433222211111111
    4443         // 43221111
    4444         // 3211
    4445         // 21
    4446         // 1
    4447 
    4448         // Subsequently, we combine all into a single list (FragmentList)
    4449 
    4450         *out << Verbose(0) << "Combining the lists of all orders per order and finally into a single one." << endl;
    4451         if (FragmentList == NULL) {
    4452                 FragmentList = new Graph;
    4453                 counter = 0;
    4454         } else {
    4455                 counter = FragmentList->size();
    4456         }
    4457         RootNr = 0;
    4458         while (!RootStack.empty()) {
    4459                 RootKeyNr = RootStack.front();
    4460                 RootStack.pop_front();
    4461                 Walker = FindAtom(RootKeyNr);
    4462                 NumLevels = 1 << (Walker->AdaptiveOrder - 1);
    4463                 for(int i=0;i<NumLevels;i++) {
    4464                         if (FragmentLowerOrdersList[RootNr][i] != NULL) {
    4465                                 InsertGraphIntoGraph(out, *FragmentList, (*FragmentLowerOrdersList[RootNr][i]), &counter);
    4466                                 delete(FragmentLowerOrdersList[RootNr][i]);
    4467                         }
    4468                 }
    4469                 Free((void **)&FragmentLowerOrdersList[RootNr], "molecule::FragmentBOSSANOVA: **FragmentLowerOrdersList[]");
    4470                 RootNr++;
    4471         }
    4472         Free((void **)&FragmentLowerOrdersList, "molecule::FragmentBOSSANOVA: ***FragmentLowerOrdersList");
    4473         Free((void **)&NumMoleculesOfOrder, "molecule::FragmentBOSSANOVA: *NumMoleculesOfOrder");
    4474 
    4475         *out << Verbose(0) << "End of FragmentBOSSANOVA." << endl;
     4393//              // every molecule is split into a list of again (Order - 1) molecules, while counting all molecules
     4394//              //*out << Verbose(1) << "Splitting the " << (*FragmentLowerOrdersList[RootNr][source]).size() << " molecules of the " << source << "th cell in the array." << endl;
     4395//              //NumMolecules = 0;
     4396//              FragmentLowerOrdersList[RootNr][dest] = new Graph;
     4397//              for(Graph::iterator runner = (*FragmentLowerOrdersList[RootNr][source]).begin();runner != (*FragmentLowerOrdersList[RootNr][source]).end(); runner++) {
     4398//                for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) {
     4399//                  Graph TempFragmentList;
     4400//                  FragmentSearch.TEFactor = -(*runner).second.second;
     4401//                  FragmentSearch.Leaflet = &TempFragmentList;      // set to insertion graph
     4402//                  FragmentSearch.Root = FindAtom(*sprinter);
     4403//                  NumMoleculesOfOrder[RootNr] += PowerSetGenerator(out, SubOrder, FragmentSearch, (*runner).first);
     4404//                  // insert new keysets FragmentList into FragmentLowerOrdersList[Walker->AdaptiveOrder-1][dest]
     4405//                  *out << Verbose(1) << "Merging resulting key sets with those present in destination " << dest << "." << endl;
     4406//                  InsertGraphIntoGraph(out, *FragmentLowerOrdersList[RootNr][dest], TempFragmentList, &NumMolecules);
     4407//                }
     4408//              }
     4409//              *out << Verbose(1) << "Number of resulting molecules for SubOrder " << SubOrder << " is: " << NumMolecules << "." << endl;
     4410//            }
     4411//          }
     4412//        }
     4413      } else {
     4414        Walker->GetTrueFather()->MaxOrder = true;
     4415//        *out << Verbose(1) << "Hence, we don't dive into SubOrders ... " << endl;
     4416      }
     4417      // now, we have completely filled each cell of FragmentLowerOrdersList[] for the current Walker->AdaptiveOrder
     4418      //NumMoleculesOfOrder[Walker->AdaptiveOrder-1] = NumMolecules;
     4419      TotalNumMolecules += NumMoleculesOfOrder[RootNr];
     4420//      *out << Verbose(1) << "Number of resulting molecules for Order " << (int)Walker->GetTrueFather()->AdaptiveOrder << " is: " << NumMoleculesOfOrder[RootNr] << "." << endl;
     4421      RootStack.push_back(RootKeyNr); // put back on stack
     4422      RootNr++;
     4423
     4424      // free Order-dependent entries of UniqueFragments structure for next loop cycle
     4425      Free((void **)&FragmentSearch.BondsPerSPCount, "molecule::PowerSetGenerator: *BondsPerSPCount");
     4426      for (int i=Order;i--;) {
     4427        delete(FragmentSearch.BondsPerSPList[2*i]);
     4428        delete(FragmentSearch.BondsPerSPList[2*i+1]);
     4429      }
     4430      Free((void **)&FragmentSearch.BondsPerSPList, "molecule::PowerSetGenerator: ***BondsPerSPList");
     4431    }
     4432  }
     4433  *out << Verbose(0) << "==============================================================================================================" << endl;
     4434  *out << Verbose(1) << "Total number of resulting molecules is: " << TotalNumMolecules << "." << endl;
     4435  *out << Verbose(0) << "==============================================================================================================" << endl;
     4436
     4437  // cleanup FragmentSearch structure
     4438  Free((void **)&FragmentSearch.ShortestPathList, "molecule::PowerSetGenerator: *ShortestPathList");
     4439  delete(FragmentSearch.FragmentSet);
     4440
     4441  // now, FragmentLowerOrdersList is complete, it looks - for BondOrder 5 - as this (number is the ANOVA Order of the terms therein)
     4442  // 5433222211111111
     4443  // 43221111
     4444  // 3211
     4445  // 21
     4446  // 1
     4447
     4448  // Subsequently, we combine all into a single list (FragmentList)
     4449
     4450  *out << Verbose(0) << "Combining the lists of all orders per order and finally into a single one." << endl;
     4451  if (FragmentList == NULL) {
     4452    FragmentList = new Graph;
     4453    counter = 0;
     4454  } else {
     4455    counter = FragmentList->size();
     4456  }
     4457  RootNr = 0;
     4458  while (!RootStack.empty()) {
     4459    RootKeyNr = RootStack.front();
     4460    RootStack.pop_front();
     4461    Walker = FindAtom(RootKeyNr);
     4462    NumLevels = 1 << (Walker->AdaptiveOrder - 1);
     4463    for(int i=0;i<NumLevels;i++) {
     4464      if (FragmentLowerOrdersList[RootNr][i] != NULL) {
     4465        InsertGraphIntoGraph(out, *FragmentList, (*FragmentLowerOrdersList[RootNr][i]), &counter);
     4466        delete(FragmentLowerOrdersList[RootNr][i]);
     4467      }
     4468    }
     4469    Free((void **)&FragmentLowerOrdersList[RootNr], "molecule::FragmentBOSSANOVA: **FragmentLowerOrdersList[]");
     4470    RootNr++;
     4471  }
     4472  Free((void **)&FragmentLowerOrdersList, "molecule::FragmentBOSSANOVA: ***FragmentLowerOrdersList");
     4473  Free((void **)&NumMoleculesOfOrder, "molecule::FragmentBOSSANOVA: *NumMoleculesOfOrder");
     4474
     4475  *out << Verbose(0) << "End of FragmentBOSSANOVA." << endl;
    44764476};
    44774477
     
    44834483inline int CompareDoubles (const void * a, const void * b)
    44844484{
    4485         if (*(double *)a > *(double *)b)
    4486                 return -1;
    4487         else if (*(double *)a < *(double *)b)
    4488                 return 1;
    4489         else
    4490                 return 0;
     4485  if (*(double *)a > *(double *)b)
     4486    return -1;
     4487  else if (*(double *)a < *(double *)b)
     4488    return 1;
     4489  else
     4490    return 0;
    44914491};
    44924492
     
    44994499int * molecule::IsEqualToWithinThreshold(ofstream *out, molecule *OtherMolecule, double threshold)
    45004500{
    4501         int flag;
    4502         double *Distances = NULL, *OtherDistances = NULL;
    4503         Vector CenterOfGravity, OtherCenterOfGravity;
    4504         size_t *PermMap = NULL, *OtherPermMap = NULL;
    4505         int *PermutationMap = NULL;
    4506         atom *Walker = NULL;
    4507         bool result = true; // status of comparison
    4508 
    4509         *out << Verbose(3) << "Begin of IsEqualToWithinThreshold." << endl;
    4510         /// first count both their atoms and elements and update lists thereby ...
    4511         //*out << Verbose(0) << "Counting atoms, updating list" << endl;
    4512         CountAtoms(out);
    4513         OtherMolecule->CountAtoms(out);
    4514         CountElements();
    4515         OtherMolecule->CountElements();
    4516 
    4517         /// ... and compare:
    4518         /// -# AtomCount
    4519         if (result) {
    4520                 if (AtomCount != OtherMolecule->AtomCount) {
    4521                         *out << Verbose(4) << "AtomCounts don't match: " << AtomCount << " == " << OtherMolecule->AtomCount << endl;
    4522                         result = false;
    4523                 } else *out << Verbose(4) << "AtomCounts match: " << AtomCount << " == " << OtherMolecule->AtomCount << endl;
    4524         }
    4525         /// -# ElementCount
    4526         if (result) {
    4527                 if (ElementCount != OtherMolecule->ElementCount) {
    4528                         *out << Verbose(4) << "ElementCount don't match: " << ElementCount << " == " << OtherMolecule->ElementCount << endl;
    4529                         result = false;
    4530                 } else *out << Verbose(4) << "ElementCount match: " << ElementCount << " == " << OtherMolecule->ElementCount << endl;
    4531         }
    4532         /// -# ElementsInMolecule
    4533         if (result) {
    4534                 for (flag=MAX_ELEMENTS;flag--;) {
    4535                         //*out << Verbose(5) << "Element " <<   flag << ": " << ElementsInMolecule[flag] << " <-> " << OtherMolecule->ElementsInMolecule[flag] << "." << endl;
    4536                         if (ElementsInMolecule[flag] != OtherMolecule->ElementsInMolecule[flag])
    4537                                 break;
    4538                 }
    4539                 if (flag < MAX_ELEMENTS) {
    4540                         *out << Verbose(4) << "ElementsInMolecule don't match." << endl;
    4541                         result = false;
    4542                 } else *out << Verbose(4) << "ElementsInMolecule match." << endl;
    4543         }
    4544         /// then determine and compare center of gravity for each molecule ...
    4545         if (result) {
    4546                 *out << Verbose(5) << "Calculating Centers of Gravity" << endl;
    4547                 DetermineCenter(CenterOfGravity);
    4548                 OtherMolecule->DetermineCenter(OtherCenterOfGravity);
    4549                 *out << Verbose(5) << "Center of Gravity: ";
    4550                 CenterOfGravity.Output(out);
    4551                 *out << endl << Verbose(5) << "Other Center of Gravity: ";
    4552                 OtherCenterOfGravity.Output(out);
    4553                 *out << endl;
    4554                 if (CenterOfGravity.DistanceSquared(&OtherCenterOfGravity) > threshold*threshold) {
    4555                         *out << Verbose(4) << "Centers of gravity don't match." << endl;
    4556                         result = false;
    4557                 }
    4558         }
    4559 
    4560         /// ... then make a list with the euclidian distance to this center for each atom of both molecules
    4561         if (result) {
    4562                 *out << Verbose(5) << "Calculating distances" << endl;
    4563                 Distances = (double *) Malloc(sizeof(double)*AtomCount, "molecule::IsEqualToWithinThreshold: Distances");
    4564                 OtherDistances = (double *) Malloc(sizeof(double)*AtomCount, "molecule::IsEqualToWithinThreshold: OtherDistances");
    4565                 Walker = start;
    4566                 while (Walker->next != end) {
    4567                         Walker = Walker->next;
    4568                         Distances[Walker->nr] = CenterOfGravity.DistanceSquared(&Walker->x);
    4569                 }
    4570                 Walker = OtherMolecule->start;
    4571                 while (Walker->next != OtherMolecule->end) {
    4572                         Walker = Walker->next;
    4573                         OtherDistances[Walker->nr] = OtherCenterOfGravity.DistanceSquared(&Walker->x);
    4574                 }
    4575 
    4576                 /// ... sort each list (using heapsort (o(N log N)) from GSL)
    4577                 *out << Verbose(5) << "Sorting distances" << endl;
    4578                 PermMap = (size_t *) Malloc(sizeof(size_t)*AtomCount, "molecule::IsEqualToWithinThreshold: *PermMap");
    4579                 OtherPermMap = (size_t *) Malloc(sizeof(size_t)*AtomCount, "molecule::IsEqualToWithinThreshold: *OtherPermMap");
    4580                 gsl_heapsort_index (PermMap, Distances, AtomCount, sizeof(double), CompareDoubles);
    4581                 gsl_heapsort_index (OtherPermMap, OtherDistances, AtomCount, sizeof(double), CompareDoubles);
    4582                 PermutationMap = (int *) Malloc(sizeof(int)*AtomCount, "molecule::IsEqualToWithinThreshold: *PermutationMap");
    4583                 *out << Verbose(5) << "Combining Permutation Maps" << endl;
    4584                 for(int i=AtomCount;i--;)
    4585                         PermutationMap[PermMap[i]] = (int) OtherPermMap[i];
    4586 
    4587                 /// ... and compare them step by step, whether the difference is individiually(!) below \a threshold for all
    4588                 *out << Verbose(4) << "Comparing distances" << endl;
    4589                 flag = 0;
    4590                 for (int i=0;i<AtomCount;i++) {
    4591                         *out << Verbose(5) << "Distances squared: |" << Distances[PermMap[i]] << " - " << OtherDistances[OtherPermMap[i]] << "| = " << fabs(Distances[PermMap[i]] - OtherDistances[OtherPermMap[i]]) << " ?<? " <<      threshold << endl;
    4592                         if (fabs(Distances[PermMap[i]] - OtherDistances[OtherPermMap[i]]) > threshold*threshold)
    4593                                 flag = 1;
    4594                 }
    4595                 Free((void **)&PermMap, "molecule::IsEqualToWithinThreshold: *PermMap");
    4596                 Free((void **)&OtherPermMap, "molecule::IsEqualToWithinThreshold: *OtherPermMap");
    4597 
    4598                 /// free memory
    4599                 Free((void **)&Distances, "molecule::IsEqualToWithinThreshold: Distances");
    4600                 Free((void **)&OtherDistances, "molecule::IsEqualToWithinThreshold: OtherDistances");
    4601                 if (flag) { // if not equal
    4602                         Free((void **)&PermutationMap, "molecule::IsEqualToWithinThreshold: *PermutationMap");
    4603                         result = false;
    4604                 }
    4605         }
    4606         /// return pointer to map if all distances were below \a threshold
    4607         *out << Verbose(3) << "End of IsEqualToWithinThreshold." << endl;
    4608         if (result) {
    4609                 *out << Verbose(3) << "Result: Equal." << endl;
    4610                 return PermutationMap;
    4611         } else {
    4612                 *out << Verbose(3) << "Result: Not equal." << endl;
    4613                 return NULL;
    4614         }
     4501  int flag;
     4502  double *Distances = NULL, *OtherDistances = NULL;
     4503  Vector CenterOfGravity, OtherCenterOfGravity;
     4504  size_t *PermMap = NULL, *OtherPermMap = NULL;
     4505  int *PermutationMap = NULL;
     4506  atom *Walker = NULL;
     4507  bool result = true; // status of comparison
     4508
     4509  *out << Verbose(3) << "Begin of IsEqualToWithinThreshold." << endl;
     4510  /// first count both their atoms and elements and update lists thereby ...
     4511  //*out << Verbose(0) << "Counting atoms, updating list" << endl;
     4512  CountAtoms(out);
     4513  OtherMolecule->CountAtoms(out);
     4514  CountElements();
     4515  OtherMolecule->CountElements();
     4516
     4517  /// ... and compare:
     4518  /// -# AtomCount
     4519  if (result) {
     4520    if (AtomCount != OtherMolecule->AtomCount) {
     4521      *out << Verbose(4) << "AtomCounts don't match: " << AtomCount << " == " << OtherMolecule->AtomCount << endl;
     4522      result = false;
     4523    } else *out << Verbose(4) << "AtomCounts match: " << AtomCount << " == " << OtherMolecule->AtomCount << endl;
     4524  }
     4525  /// -# ElementCount
     4526  if (result) {
     4527    if (ElementCount != OtherMolecule->ElementCount) {
     4528      *out << Verbose(4) << "ElementCount don't match: " << ElementCount << " == " << OtherMolecule->ElementCount << endl;
     4529      result = false;
     4530    } else *out << Verbose(4) << "ElementCount match: " << ElementCount << " == " << OtherMolecule->ElementCount << endl;
     4531  }
     4532  /// -# ElementsInMolecule
     4533  if (result) {
     4534    for (flag=MAX_ELEMENTS;flag--;) {
     4535      //*out << Verbose(5) << "Element " <<  flag << ": " << ElementsInMolecule[flag] << " <-> " << OtherMolecule->ElementsInMolecule[flag] << "." << endl;
     4536      if (ElementsInMolecule[flag] != OtherMolecule->ElementsInMolecule[flag])
     4537        break;
     4538    }
     4539    if (flag < MAX_ELEMENTS) {
     4540      *out << Verbose(4) << "ElementsInMolecule don't match." << endl;
     4541      result = false;
     4542    } else *out << Verbose(4) << "ElementsInMolecule match." << endl;
     4543  }
     4544  /// then determine and compare center of gravity for each molecule ...
     4545  if (result) {
     4546    *out << Verbose(5) << "Calculating Centers of Gravity" << endl;
     4547    DetermineCenter(CenterOfGravity);
     4548    OtherMolecule->DetermineCenter(OtherCenterOfGravity);
     4549    *out << Verbose(5) << "Center of Gravity: ";
     4550    CenterOfGravity.Output(out);
     4551    *out << endl << Verbose(5) << "Other Center of Gravity: ";
     4552    OtherCenterOfGravity.Output(out);
     4553    *out << endl;
     4554    if (CenterOfGravity.DistanceSquared(&OtherCenterOfGravity) > threshold*threshold) {
     4555      *out << Verbose(4) << "Centers of gravity don't match." << endl;
     4556      result = false;
     4557    }
     4558  }
     4559
     4560  /// ... then make a list with the euclidian distance to this center for each atom of both molecules
     4561  if (result) {
     4562    *out << Verbose(5) << "Calculating distances" << endl;
     4563    Distances = (double *) Malloc(sizeof(double)*AtomCount, "molecule::IsEqualToWithinThreshold: Distances");
     4564    OtherDistances = (double *) Malloc(sizeof(double)*AtomCount, "molecule::IsEqualToWithinThreshold: OtherDistances");
     4565    Walker = start;
     4566    while (Walker->next != end) {
     4567      Walker = Walker->next;
     4568      Distances[Walker->nr] = CenterOfGravity.DistanceSquared(&Walker->x);
     4569    }
     4570    Walker = OtherMolecule->start;
     4571    while (Walker->next != OtherMolecule->end) {
     4572      Walker = Walker->next;
     4573      OtherDistances[Walker->nr] = OtherCenterOfGravity.DistanceSquared(&Walker->x);
     4574    }
     4575
     4576    /// ... sort each list (using heapsort (o(N log N)) from GSL)
     4577    *out << Verbose(5) << "Sorting distances" << endl;
     4578    PermMap = (size_t *) Malloc(sizeof(size_t)*AtomCount, "molecule::IsEqualToWithinThreshold: *PermMap");
     4579    OtherPermMap = (size_t *) Malloc(sizeof(size_t)*AtomCount, "molecule::IsEqualToWithinThreshold: *OtherPermMap");
     4580    gsl_heapsort_index (PermMap, Distances, AtomCount, sizeof(double), CompareDoubles);
     4581    gsl_heapsort_index (OtherPermMap, OtherDistances, AtomCount, sizeof(double), CompareDoubles);
     4582    PermutationMap = (int *) Malloc(sizeof(int)*AtomCount, "molecule::IsEqualToWithinThreshold: *PermutationMap");
     4583    *out << Verbose(5) << "Combining Permutation Maps" << endl;
     4584    for(int i=AtomCount;i--;)
     4585      PermutationMap[PermMap[i]] = (int) OtherPermMap[i];
     4586
     4587    /// ... and compare them step by step, whether the difference is individiually(!) below \a threshold for all
     4588    *out << Verbose(4) << "Comparing distances" << endl;
     4589    flag = 0;
     4590    for (int i=0;i<AtomCount;i++) {
     4591      *out << Verbose(5) << "Distances squared: |" << Distances[PermMap[i]] << " - " << OtherDistances[OtherPermMap[i]] << "| = " << fabs(Distances[PermMap[i]] - OtherDistances[OtherPermMap[i]]) << " ?<? " <<  threshold << endl;
     4592      if (fabs(Distances[PermMap[i]] - OtherDistances[OtherPermMap[i]]) > threshold*threshold)
     4593        flag = 1;
     4594    }
     4595    Free((void **)&PermMap, "molecule::IsEqualToWithinThreshold: *PermMap");
     4596    Free((void **)&OtherPermMap, "molecule::IsEqualToWithinThreshold: *OtherPermMap");
     4597
     4598    /// free memory
     4599    Free((void **)&Distances, "molecule::IsEqualToWithinThreshold: Distances");
     4600    Free((void **)&OtherDistances, "molecule::IsEqualToWithinThreshold: OtherDistances");
     4601    if (flag) { // if not equal
     4602      Free((void **)&PermutationMap, "molecule::IsEqualToWithinThreshold: *PermutationMap");
     4603      result = false;
     4604    }
     4605  }
     4606  /// return pointer to map if all distances were below \a threshold
     4607  *out << Verbose(3) << "End of IsEqualToWithinThreshold." << endl;
     4608  if (result) {
     4609    *out << Verbose(3) << "Result: Equal." << endl;
     4610    return PermutationMap;
     4611  } else {
     4612    *out << Verbose(3) << "Result: Not equal." << endl;
     4613    return NULL;
     4614  }
    46154615};
    46164616
     
    46244624int * molecule::GetFatherSonAtomicMap(ofstream *out, molecule *OtherMolecule)
    46254625{
    4626         atom *Walker = NULL, *OtherWalker = NULL;
    4627         *out << Verbose(3) << "Begin of GetFatherAtomicMap." << endl;
    4628         int *AtomicMap = (int *) Malloc(sizeof(int)*AtomCount, "molecule::GetAtomicMap: *AtomicMap");   //Calloc
    4629         for (int i=AtomCount;i--;)
    4630                 AtomicMap[i] = -1;
    4631         if (OtherMolecule == this) {    // same molecule
    4632                 for (int i=AtomCount;i--;) // no need as -1 means already that there is trivial correspondence
    4633                         AtomicMap[i] = i;
    4634                 *out << Verbose(4) << "Map is trivial." << endl;
    4635         } else {
    4636                 *out << Verbose(4) << "Map is ";
    4637                 Walker = start;
    4638                 while (Walker->next != end) {
    4639                         Walker = Walker->next;
    4640                         if (Walker->father == NULL) {
    4641                                 AtomicMap[Walker->nr] = -2;
    4642                         } else {
    4643                                 OtherWalker = OtherMolecule->start;
    4644                                 while (OtherWalker->next != OtherMolecule->end) {
    4645                                         OtherWalker = OtherWalker->next;
    4646                         //for (int i=0;i<AtomCount;i++) { // search atom
    4647                                 //for (int j=0;j<OtherMolecule->AtomCount;j++) {
    4648                                         //*out << Verbose(4) << "Comparing father " << Walker->father << " with the other one " << OtherWalker->father << "." << endl;
    4649                                         if (Walker->father == OtherWalker)
    4650                                                 AtomicMap[Walker->nr] = OtherWalker->nr;
    4651                                 }
    4652                         }
    4653                         *out << AtomicMap[Walker->nr] << "\t";
    4654                 }
    4655                 *out << endl;
    4656         }
    4657         *out << Verbose(3) << "End of GetFatherAtomicMap." << endl;
    4658         return AtomicMap;
     4626  atom *Walker = NULL, *OtherWalker = NULL;
     4627  *out << Verbose(3) << "Begin of GetFatherAtomicMap." << endl;
     4628  int *AtomicMap = (int *) Malloc(sizeof(int)*AtomCount, "molecule::GetAtomicMap: *AtomicMap");  //Calloc
     4629  for (int i=AtomCount;i--;)
     4630    AtomicMap[i] = -1;
     4631  if (OtherMolecule == this) {  // same molecule
     4632    for (int i=AtomCount;i--;) // no need as -1 means already that there is trivial correspondence
     4633      AtomicMap[i] = i;
     4634    *out << Verbose(4) << "Map is trivial." << endl;
     4635  } else {
     4636    *out << Verbose(4) << "Map is ";
     4637    Walker = start;
     4638    while (Walker->next != end) {
     4639      Walker = Walker->next;
     4640      if (Walker->father == NULL) {
     4641        AtomicMap[Walker->nr] = -2;
     4642      } else {
     4643        OtherWalker = OtherMolecule->start;
     4644        while (OtherWalker->next != OtherMolecule->end) {
     4645          OtherWalker = OtherWalker->next;
     4646      //for (int i=0;i<AtomCount;i++) { // search atom
     4647        //for (int j=0;j<OtherMolecule->AtomCount;j++) {
     4648          //*out << Verbose(4) << "Comparing father " << Walker->father << " with the other one " << OtherWalker->father << "." << endl;
     4649          if (Walker->father == OtherWalker)
     4650            AtomicMap[Walker->nr] = OtherWalker->nr;
     4651        }
     4652      }
     4653      *out << AtomicMap[Walker->nr] << "\t";
     4654    }
     4655    *out << endl;
     4656  }
     4657  *out << Verbose(3) << "End of GetFatherAtomicMap." << endl;
     4658  return AtomicMap;
    46594659};
    46604660
     
    46704670bool molecule::OutputTemperatureFromTrajectories(ofstream *out, int startstep, int endstep, ofstream *output)
    46714671{
    4672         double temperature;
    4673         atom *Walker = NULL;
    4674         // test stream
    4675         if (output == NULL)
    4676                 return false;
    4677         else
    4678                 *output << "# Step Temperature [K] Temperature [a.u.]" << endl;
    4679         for (int step=startstep;step < endstep; step++) { // loop over all time steps
    4680                 temperature = 0.;
    4681                 Walker = start;
    4682                 while (Walker->next != end) {
    4683                         Walker = Walker->next;
    4684                         for (int i=NDIM;i--;)
    4685                                 temperature += Walker->type->mass * Trajectories[Walker].U.at(step).x[i]* Trajectories[Walker].U.at(step).x[i];
    4686                 }
    4687                 *output << step << "\t" << temperature*AtomicEnergyToKelvin << "\t" << temperature << endl;
    4688         }
    4689         return true;
    4690 };
     4672  double temperature;
     4673  atom *Walker = NULL;
     4674  // test stream
     4675  if (output == NULL)
     4676    return false;
     4677  else
     4678    *output << "# Step Temperature [K] Temperature [a.u.]" << endl;
     4679  for (int step=startstep;step < endstep; step++) { // loop over all time steps
     4680    temperature = 0.;
     4681    Walker = start;
     4682    while (Walker->next != end) {
     4683      Walker = Walker->next;
     4684      for (int i=NDIM;i--;)
     4685        temperature += Walker->type->mass * Trajectories[Walker].U.at(step).x[i]* Trajectories[Walker].U.at(step).x[i];
     4686    }
     4687    *output << step << "\t" << temperature*AtomicEnergyToKelvin << "\t" << temperature << endl;
     4688  }
     4689  return true;
     4690};
  • src/molecules.hpp

    r205ccd r042f82  
    7979struct KeyCompare
    8080{
    81         bool operator() (const KeySet SubgraphA, const KeySet SubgraphB) const;
     81  bool operator() (const KeySet SubgraphA, const KeySet SubgraphB) const;
    8282};
    8383
    8484struct Trajectory
    8585{
    86         vector<Vector> R;       //!< position vector
    87         vector<Vector> U;       //!< velocity vector
    88         vector<Vector> F;       //!< last force vector
    89         atom *ptr;                              //!< pointer to atom whose trajectory we contain
    90 };
    91 
    92 //bool operator < (KeySet SubgraphA, KeySet SubgraphB);  //note: this declaration is important, otherwise normal < is used (producing wrong order)
     86  vector<Vector> R;  //!< position vector
     87  vector<Vector> U;  //!< velocity vector
     88  vector<Vector> F;  //!< last force vector
     89  atom *ptr;        //!< pointer to atom whose trajectory we contain
     90};
     91
     92//bool operator < (KeySet SubgraphA, KeySet SubgraphB);  //note: this declaration is important, otherwise normal < is used (producing wrong order)
    9393inline void InsertFragmentIntoGraph(ofstream *out, struct UniqueFragments *Fragment); // Insert a KeySet into a Graph
    94 inline void InsertGraphIntoGraph(ofstream *out, Graph &graph1, Graph &graph2, int *counter);    // Insert all KeySet's in a Graph into another Graph
     94inline void InsertGraphIntoGraph(ofstream *out, Graph &graph1, Graph &graph2, int *counter);  // Insert all KeySet's in a Graph into another Graph
    9595int CompareDoubles (const void * a, const void * b);
    9696
     
    100100
    101101// some algebraic matrix stuff
    102 #define RDET3(a) ((a)[0]*(a)[4]*(a)[8] + (a)[3]*(a)[7]*(a)[2] + (a)[6]*(a)[1]*(a)[5] - (a)[2]*(a)[4]*(a)[6] - (a)[5]*(a)[7]*(a)[0] - (a)[8]*(a)[1]*(a)[3])      //!< hard-coded determinant of a 3x3 matrix
    103 #define RDET2(a0,a1,a2,a3) ((a0)*(a3)-(a1)*(a2))                                                                                        //!< hard-coded determinant of a 2x2 matrix
     102#define RDET3(a) ((a)[0]*(a)[4]*(a)[8] + (a)[3]*(a)[7]*(a)[2] + (a)[6]*(a)[1]*(a)[5] - (a)[2]*(a)[4]*(a)[6] - (a)[5]*(a)[7]*(a)[0] - (a)[8]*(a)[1]*(a)[3])  //!< hard-coded determinant of a 3x3 matrix
     103#define RDET2(a0,a1,a2,a3) ((a0)*(a3)-(a1)*(a2))                      //!< hard-coded determinant of a 2x2 matrix
    104104
    105105
     
    107107 */
    108108struct LSQ_params {
    109         Vector **vectors;
    110         int num;
     109  Vector **vectors;
     110  int num;
    111111};
    112112
     
    116116 */
    117117struct lsq_params {
    118         gsl_vector *x;
    119         const molecule *mol;
    120         element *type;
     118  gsl_vector *x;
     119  const molecule *mol;
     120  element *type;
    121121};
    122122
     
    125125 */
    126126class atom {
    127         public:
    128                 Vector x;                        //!< coordinate array of atom, giving position within cell
    129                 Vector v;                        //!< velocity array of atom
    130                 element *type;  //!< pointing to element
    131                 atom *previous; //!< previous atom in molecule list
    132                 atom *next;              //!< next atom in molecule list
    133                 atom *father;    //!< In many-body bond order fragmentations points to originating atom
    134                 atom *Ancestor; //!< "Father" in Depth-First-Search
    135                 char *Name;                     //!< unique name used during many-body bond-order fragmentation
    136                 int FixedIon;    //!< config variable that states whether forces act on the ion or not
    137                 int *sort;                      //!< sort criteria
    138                 int nr;                          //!< continuous, unique number
    139                 int GraphNr;                    //!< unique number, given in DepthFirstSearchAnalysis()
    140                 int *ComponentNr;//!< belongs to this nonseparable components, given in DepthFirstSearchAnalysis() (if more than one, then is SeparationVertex)
    141                 int LowpointNr; //!< needed in DepthFirstSearchAnalysis() to detect nonseparable components, is the lowest possible number of an atom to reach via tree edges only followed by at most one back edge.
    142                 bool SeparationVertex; //!< whether this atom separates off subsets of atoms or not, determined in DepthFirstSearchAnalysis()
    143                 bool IsCyclic;                          //!< whether atom belong to as cycle or not, determined in DepthFirstSearchAnalysis()
    144                 unsigned char AdaptiveOrder;    //!< current present bond order at site (0 means "not set")
    145                 bool MaxOrder;  //!< whether this atom as a root in fragmentation still creates more fragments on higher orders or not
    146 
    147         atom();
    148         ~atom();
    149 
    150         bool Output(int ElementNo, int AtomNo, ofstream *out, const char *comment = NULL) const;
    151         bool OutputXYZLine(ofstream *out) const;
    152         atom *GetTrueFather();
    153         bool Compare(atom &ptr);
    154 
    155         private:
     127  public:
     128    Vector x;      //!< coordinate array of atom, giving position within cell
     129    Vector v;      //!< velocity array of atom
     130    element *type;  //!< pointing to element
     131    atom *previous; //!< previous atom in molecule list
     132    atom *next;    //!< next atom in molecule list
     133    atom *father;  //!< In many-body bond order fragmentations points to originating atom
     134    atom *Ancestor; //!< "Father" in Depth-First-Search
     135    char *Name;      //!< unique name used during many-body bond-order fragmentation
     136    int FixedIon;  //!< config variable that states whether forces act on the ion or not
     137    int *sort;      //!< sort criteria
     138    int nr;        //!< continuous, unique number
     139    int GraphNr;      //!< unique number, given in DepthFirstSearchAnalysis()
     140    int *ComponentNr;//!< belongs to this nonseparable components, given in DepthFirstSearchAnalysis() (if more than one, then is SeparationVertex)
     141    int LowpointNr; //!< needed in DepthFirstSearchAnalysis() to detect nonseparable components, is the lowest possible number of an atom to reach via tree edges only followed by at most one back edge.
     142    bool SeparationVertex; //!< whether this atom separates off subsets of atoms or not, determined in DepthFirstSearchAnalysis()
     143    bool IsCyclic;        //!< whether atom belong to as cycle or not, determined in DepthFirstSearchAnalysis()
     144    unsigned char AdaptiveOrder;  //!< current present bond order at site (0 means "not set")
     145    bool MaxOrder;  //!< whether this atom as a root in fragmentation still creates more fragments on higher orders or not
     146
     147  atom();
     148  ~atom();
     149
     150  bool Output(int ElementNo, int AtomNo, ofstream *out, const char *comment = NULL) const;
     151  bool OutputXYZLine(ofstream *out) const;
     152  atom *GetTrueFather();
     153  bool Compare(atom &ptr);
     154
     155  private:
    156156};
    157157
     
    164164 */
    165165class bond {
    166         public:
    167                 atom *leftatom;         //!< first bond partner
    168                 atom *rightatom;        //!< second bond partner
    169                 bond *previous; //!< previous atom in molecule list
    170                 bond *next;              //!< next atom in molecule list
    171                 int HydrogenBond;       //!< Number of hydrogen atoms in the bond
    172                 int BondDegree;         //!< single, double, triple, ... bond
    173                 int nr;                                  //!< unique number in a molecule, updated by molecule::CreateAdjacencyList()
    174                 bool Cyclic;                    //!< flag whether bond is part of a cycle or not, given in DepthFirstSearchAnalysis()
    175                 enum EdgeType Type;//!< whether this is a tree or back edge
    176 
    177         atom * GetOtherAtom(atom *Atom) const;
    178         bond * GetFirstBond();
    179         bond * GetLastBond();
    180 
    181         bool MarkUsed(enum Shading color);
    182         enum Shading IsUsed();
    183         void ResetUsed();
    184         bool Contains(const atom *ptr);
    185         bool Contains(const int nr);
    186 
    187         bond();
    188         bond(atom *left, atom *right);
    189         bond(atom *left, atom *right, int degree);
    190         bond(atom *left, atom *right, int degree, int number);
    191         ~bond();
    192 
    193         private:
    194                 enum Shading Used;                              //!< marker in depth-first search, DepthFirstSearchAnalysis()
     166  public:
     167    atom *leftatom;    //!< first bond partner
     168    atom *rightatom;  //!< second bond partner
     169    bond *previous; //!< previous atom in molecule list
     170    bond *next;    //!< next atom in molecule list
     171    int HydrogenBond;  //!< Number of hydrogen atoms in the bond
     172    int BondDegree;    //!< single, double, triple, ... bond
     173    int nr;          //!< unique number in a molecule, updated by molecule::CreateAdjacencyList()
     174    bool Cyclic;      //!< flag whether bond is part of a cycle or not, given in DepthFirstSearchAnalysis()
     175    enum EdgeType Type;//!< whether this is a tree or back edge
     176
     177  atom * GetOtherAtom(atom *Atom) const;
     178  bond * GetFirstBond();
     179  bond * GetLastBond();
     180
     181  bool MarkUsed(enum Shading color);
     182  enum Shading IsUsed();
     183  void ResetUsed();
     184  bool Contains(const atom *ptr);
     185  bool Contains(const int nr);
     186
     187  bond();
     188  bond(atom *left, atom *right);
     189  bond(atom *left, atom *right, int degree);
     190  bond(atom *left, atom *right, int degree, int number);
     191  ~bond();
     192
     193  private:
     194    enum Shading Used;        //!< marker in depth-first search, DepthFirstSearchAnalysis()
    195195};
    196196
     
    203203 */
    204204class molecule {
    205         public:
    206                 double cell_size[6];//!< cell size
    207                 periodentafel *elemente; //!< periodic table with each element
    208                 atom *start;                            //!< start of atom list
    209                 atom *end;                                      //!< end of atom list
    210                 bond *first;                            //!< start of bond list
    211                 bond *last;                              //!< end of bond list
    212                 bond ***ListOfBondsPerAtom; //!< pointer list for each atom and each bond it has
    213                 map<atom *, struct Trajectory> Trajectories; //!< contains old trajectory points
    214                 int MDSteps;                            //!< The number of MD steps in Trajectories
    215                 int *NumberOfBondsPerAtom;      //!< Number of Bonds each atom has
    216                 int AtomCount;                                  //!< number of atoms, brought up-to-date by CountAtoms()
    217                 int BondCount;                                  //!< number of atoms, brought up-to-date by CountBonds()
    218                 int ElementCount;                        //!< how many unique elements are therein
    219                 int ElementsInMolecule[MAX_ELEMENTS]; //!< list whether element (sorted by atomic number) is alread present or not
    220                 int NoNonHydrogen;      //!< number of non-hydrogen atoms in molecule
    221                 int NoNonBonds;          //!< number of non-hydrogen bonds in molecule
    222                 int NoCyclicBonds;      //!< number of cyclic bonds in molecule, by DepthFirstSearchAnalysis()
    223                 double BondDistance;    //!< typical bond distance used in CreateAdjacencyList() and furtheron
    224                 bool ActiveFlag;    //!< in a MoleculeListClass used to discern active from inactive molecules
    225                 Vector Center;      //!< Center of molecule in a global box
    226                 char name[MAXSTRINGSIZE];         //!< arbitrary name
    227                 int IndexNr;        //!< index of molecule in a MoleculeListClass
    228 
    229         molecule(periodentafel *teil);
    230         ~molecule();
    231 
    232         /// remove atoms from molecule.
    233         bool AddAtom(atom *pointer);
    234         bool RemoveAtom(atom *pointer);
    235         bool UnlinkAtom(atom *pointer);
    236         bool CleanupMolecule();
    237 
    238         /// Add/remove atoms to/from molecule.
    239         atom * AddCopyAtom(atom *pointer);
    240         bool AddXYZFile(string filename);
    241         bool AddHydrogenReplacementAtom(ofstream *out, bond *Bond, atom *BottomOrigin, atom *TopOrigin, atom *TopReplacement, bond **BondList, int NumBond, bool IsAngstroem);
    242         bond * AddBond(atom *first, atom *second, int degree);
    243         bool RemoveBond(bond *pointer);
    244         bool RemoveBonds(atom *BondPartner);
    245 
    246         /// Find atoms.
    247         atom * FindAtom(int Nr) const;
    248         atom * AskAtom(string text);
    249 
    250         /// Count and change present atoms' coordination.
    251         void CountAtoms(ofstream *out);
    252         void CountElements();
    253         void CalculateOrbitals(class config &configuration);
    254         bool CenterInBox(ofstream *out);
    255         void CenterEdge(ofstream *out, Vector *max);
    256         void CenterOrigin(ofstream *out, Vector *max);
    257         void CenterGravity(ofstream *out, Vector *max);
    258         void Translate(const Vector *x);
    259         void TranslatePeriodically(const Vector *trans);
    260         void Mirror(const Vector *x);
    261         void Align(Vector *n);
    262         void Scale(double **factor);
    263         void DetermineCenter(Vector &center);
    264         Vector * DetermineCenterOfGravity(ofstream *out);
    265         Vector * DetermineCenterOfAll(ofstream *out);
    266         void SetNameFromFilename(char *filename);
    267         void SetBoxDimension(Vector *dim);
    268         double * ReturnFullMatrixforSymmetric(double *cell_size);
    269         void ScanForPeriodicCorrection(ofstream *out);
    270         void PrincipalAxisSystem(ofstream *out, bool DoRotate);
    271         double VolumeOfConvexEnvelope(ofstream *out, bool IsAngstroem);
    272         Vector* FindEmbeddingHole(ofstream *out, molecule *srcmol);
    273 
    274         bool VerletForceIntegration(char *file, double delta_t, bool IsAngstroem);
    275 
    276         bool CheckBounds(const Vector *x) const;
    277         void GetAlignvector(struct lsq_params * par) const;
    278 
    279         /// Initialising routines in fragmentation
    280         void CreateAdjacencyList2(ofstream *out, ifstream *output);
    281         void CreateAdjacencyList(ofstream *out, double bonddistance, bool IsAngstroem);
    282         void CreateListOfBondsPerAtom(ofstream *out);
    283 
    284         // Graph analysis
    285         MoleculeLeafClass * DepthFirstSearchAnalysis(ofstream *out, class StackClass<bond *> *&BackEdgeStack);
    286         void CyclicStructureAnalysis(ofstream *out, class StackClass<bond *> *BackEdgeStack, int *&MinimumRingSize);
    287         bool PickLocalBackEdges(ofstream *out, atom **ListOfLocalAtoms, class StackClass<bond *> *&ReferenceStack, class StackClass<bond *> *&LocalStack);
    288         bond * FindNextUnused(atom *vertex);
    289         void SetNextComponentNumber(atom *vertex, int nr);
    290         void InitComponentNumbers();
    291         void OutputComponentNumber(ofstream *out, atom *vertex);
    292         void ResetAllBondsToUnused();
    293         void ResetAllAtomNumbers();
    294         int CountCyclicBonds(ofstream *out);
    295         bool CheckForConnectedSubgraph(ofstream *out, KeySet *Fragment);
    296         string GetColor(enum Shading color);
    297 
    298         molecule *CopyMolecule();
    299 
    300         /// Fragment molecule by two different approaches:
    301         int FragmentMolecule(ofstream *out, int Order, config *configuration);
    302         bool CheckOrderAtSite(ofstream *out, bool *AtomMask, Graph *GlobalKeySetList, int Order, int *MinimumRingSize, char *path = NULL);
    303         bool StoreAdjacencyToFile(ofstream *out, char *path);
    304         bool CheckAdjacencyFileAgainstMolecule(ofstream *out, char *path, atom **ListOfAtoms);
    305         bool ParseOrderAtSiteFromFile(ofstream *out, char *path);
    306         bool StoreOrderAtSiteFile(ofstream *out, char *path);
    307         bool ParseKeySetFile(ofstream *out, char *filename, Graph *&FragmentList);
    308         bool StoreKeySetFile(ofstream *out, Graph &KeySetList, char *path);
    309         bool StoreForcesFile(ofstream *out, MoleculeListClass *BondFragments, char *path, int *SortIndex);
    310         bool CreateMappingLabelsToConfigSequence(ofstream *out, int *&SortIndex);
    311         bool ScanBufferIntoKeySet(ofstream *out, char *buffer, KeySet &CurrentSet);
    312         void BreadthFirstSearchAdd(ofstream *out, molecule *Mol, atom **&AddedAtomList, bond **&AddedBondList, atom *Root, bond *Bond, int BondOrder, bool IsAngstroem);
    313         /// -# BOSSANOVA
    314         void FragmentBOSSANOVA(ofstream *out, Graph *&FragmentList, KeyStack &RootStack, int *MinimumRingSize);
    315         int PowerSetGenerator(ofstream *out, int Order, struct UniqueFragments &FragmentSearch, KeySet RestrictedKeySet);
    316         bool BuildInducedSubgraph(ofstream *out, const molecule *Father);
    317         molecule * StoreFragmentFromKeySet(ofstream *out, KeySet &Leaflet, bool IsAngstroem);
    318         void SPFragmentGenerator(ofstream *out, struct UniqueFragments *FragmentSearch, int RootDistance, bond **BondsSet, int SetDimension, int SubOrder);
    319         int LookForRemovalCandidate(ofstream *&out, KeySet *&Leaf, int *&ShortestPathList);
    320         int GuesstimateFragmentCount(ofstream *out, int order);
    321 
    322         // Recognize doubly appearing molecules in a list of them
    323         int * IsEqualToWithinThreshold(ofstream *out, molecule *OtherMolecule, double threshold);
    324         int * GetFatherSonAtomicMap(ofstream *out, molecule *OtherMolecule);
    325 
    326         // Output routines.
    327         bool Output(ofstream *out);
    328         bool OutputTrajectories(ofstream *out);
    329         void OutputListOfBonds(ofstream *out) const;
    330         bool OutputXYZ(ofstream *out) const;
    331         bool OutputTrajectoriesXYZ(ofstream *out);
    332         bool Checkout(ofstream *out) const;
    333         bool OutputTemperatureFromTrajectories(ofstream *out, int startstep, int endstep, ofstream *output);
    334 
    335         private:
    336         int last_atom;                  //!< number given to last atom
     205  public:
     206    double cell_size[6];//!< cell size
     207    periodentafel *elemente; //!< periodic table with each element
     208    atom *start;        //!< start of atom list
     209    atom *end;          //!< end of atom list
     210    bond *first;        //!< start of bond list
     211    bond *last;        //!< end of bond list
     212    bond ***ListOfBondsPerAtom; //!< pointer list for each atom and each bond it has
     213    map<atom *, struct Trajectory> Trajectories; //!< contains old trajectory points
     214    int MDSteps;        //!< The number of MD steps in Trajectories
     215    int *NumberOfBondsPerAtom;  //!< Number of Bonds each atom has
     216    int AtomCount;          //!< number of atoms, brought up-to-date by CountAtoms()
     217    int BondCount;          //!< number of atoms, brought up-to-date by CountBonds()
     218    int ElementCount;      //!< how many unique elements are therein
     219    int ElementsInMolecule[MAX_ELEMENTS]; //!< list whether element (sorted by atomic number) is alread present or not
     220    int NoNonHydrogen;  //!< number of non-hydrogen atoms in molecule
     221    int NoNonBonds;    //!< number of non-hydrogen bonds in molecule
     222    int NoCyclicBonds;  //!< number of cyclic bonds in molecule, by DepthFirstSearchAnalysis()
     223    double BondDistance;  //!< typical bond distance used in CreateAdjacencyList() and furtheron
     224    bool ActiveFlag;    //!< in a MoleculeListClass used to discern active from inactive molecules
     225    Vector Center;      //!< Center of molecule in a global box
     226    char name[MAXSTRINGSIZE];         //!< arbitrary name
     227    int IndexNr;        //!< index of molecule in a MoleculeListClass
     228
     229  molecule(periodentafel *teil);
     230  ~molecule();
     231
     232  /// remove atoms from molecule.
     233  bool AddAtom(atom *pointer);
     234  bool RemoveAtom(atom *pointer);
     235  bool UnlinkAtom(atom *pointer);
     236  bool CleanupMolecule();
     237
     238  /// Add/remove atoms to/from molecule.
     239  atom * AddCopyAtom(atom *pointer);
     240  bool AddXYZFile(string filename);
     241  bool AddHydrogenReplacementAtom(ofstream *out, bond *Bond, atom *BottomOrigin, atom *TopOrigin, atom *TopReplacement, bond **BondList, int NumBond, bool IsAngstroem);
     242  bond * AddBond(atom *first, atom *second, int degree);
     243  bool RemoveBond(bond *pointer);
     244  bool RemoveBonds(atom *BondPartner);
     245
     246  /// Find atoms.
     247  atom * FindAtom(int Nr) const;
     248  atom * AskAtom(string text);
     249
     250  /// Count and change present atoms' coordination.
     251  void CountAtoms(ofstream *out);
     252  void CountElements();
     253  void CalculateOrbitals(class config &configuration);
     254  bool CenterInBox(ofstream *out);
     255  void CenterEdge(ofstream *out, Vector *max);
     256  void CenterOrigin(ofstream *out, Vector *max);
     257  void CenterGravity(ofstream *out, Vector *max);
     258  void Translate(const Vector *x);
     259  void TranslatePeriodically(const Vector *trans);
     260  void Mirror(const Vector *x);
     261  void Align(Vector *n);
     262  void Scale(double **factor);
     263  void DetermineCenter(Vector &center);
     264  Vector * DetermineCenterOfGravity(ofstream *out);
     265  Vector * DetermineCenterOfAll(ofstream *out);
     266  void SetNameFromFilename(char *filename);
     267  void SetBoxDimension(Vector *dim);
     268  double * ReturnFullMatrixforSymmetric(double *cell_size);
     269  void ScanForPeriodicCorrection(ofstream *out);
     270  void PrincipalAxisSystem(ofstream *out, bool DoRotate);
     271  double VolumeOfConvexEnvelope(ofstream *out, bool IsAngstroem);
     272  Vector* FindEmbeddingHole(ofstream *out, molecule *srcmol);
     273
     274  bool VerletForceIntegration(char *file, double delta_t, bool IsAngstroem);
     275
     276  bool CheckBounds(const Vector *x) const;
     277  void GetAlignvector(struct lsq_params * par) const;
     278
     279  /// Initialising routines in fragmentation
     280  void CreateAdjacencyList2(ofstream *out, ifstream *output);
     281  void CreateAdjacencyList(ofstream *out, double bonddistance, bool IsAngstroem);
     282  void CreateListOfBondsPerAtom(ofstream *out);
     283
     284  // Graph analysis
     285  MoleculeLeafClass * DepthFirstSearchAnalysis(ofstream *out, class StackClass<bond *> *&BackEdgeStack);
     286  void CyclicStructureAnalysis(ofstream *out, class StackClass<bond *> *BackEdgeStack, int *&MinimumRingSize);
     287  bool PickLocalBackEdges(ofstream *out, atom **ListOfLocalAtoms, class StackClass<bond *> *&ReferenceStack, class StackClass<bond *> *&LocalStack);
     288  bond * FindNextUnused(atom *vertex);
     289  void SetNextComponentNumber(atom *vertex, int nr);
     290  void InitComponentNumbers();
     291  void OutputComponentNumber(ofstream *out, atom *vertex);
     292  void ResetAllBondsToUnused();
     293  void ResetAllAtomNumbers();
     294  int CountCyclicBonds(ofstream *out);
     295  bool CheckForConnectedSubgraph(ofstream *out, KeySet *Fragment);
     296  string GetColor(enum Shading color);
     297
     298  molecule *CopyMolecule();
     299
     300  /// Fragment molecule by two different approaches:
     301  int FragmentMolecule(ofstream *out, int Order, config *configuration);
     302  bool CheckOrderAtSite(ofstream *out, bool *AtomMask, Graph *GlobalKeySetList, int Order, int *MinimumRingSize, char *path = NULL);
     303  bool StoreAdjacencyToFile(ofstream *out, char *path);
     304  bool CheckAdjacencyFileAgainstMolecule(ofstream *out, char *path, atom **ListOfAtoms);
     305  bool ParseOrderAtSiteFromFile(ofstream *out, char *path);
     306  bool StoreOrderAtSiteFile(ofstream *out, char *path);
     307  bool ParseKeySetFile(ofstream *out, char *filename, Graph *&FragmentList);
     308  bool StoreKeySetFile(ofstream *out, Graph &KeySetList, char *path);
     309  bool StoreForcesFile(ofstream *out, MoleculeListClass *BondFragments, char *path, int *SortIndex);
     310  bool CreateMappingLabelsToConfigSequence(ofstream *out, int *&SortIndex);
     311  bool ScanBufferIntoKeySet(ofstream *out, char *buffer, KeySet &CurrentSet);
     312  void BreadthFirstSearchAdd(ofstream *out, molecule *Mol, atom **&AddedAtomList, bond **&AddedBondList, atom *Root, bond *Bond, int BondOrder, bool IsAngstroem);
     313  /// -# BOSSANOVA
     314  void FragmentBOSSANOVA(ofstream *out, Graph *&FragmentList, KeyStack &RootStack, int *MinimumRingSize);
     315  int PowerSetGenerator(ofstream *out, int Order, struct UniqueFragments &FragmentSearch, KeySet RestrictedKeySet);
     316  bool BuildInducedSubgraph(ofstream *out, const molecule *Father);
     317  molecule * StoreFragmentFromKeySet(ofstream *out, KeySet &Leaflet, bool IsAngstroem);
     318  void SPFragmentGenerator(ofstream *out, struct UniqueFragments *FragmentSearch, int RootDistance, bond **BondsSet, int SetDimension, int SubOrder);
     319  int LookForRemovalCandidate(ofstream *&out, KeySet *&Leaf, int *&ShortestPathList);
     320  int GuesstimateFragmentCount(ofstream *out, int order);
     321
     322  // Recognize doubly appearing molecules in a list of them
     323  int * IsEqualToWithinThreshold(ofstream *out, molecule *OtherMolecule, double threshold);
     324  int * GetFatherSonAtomicMap(ofstream *out, molecule *OtherMolecule);
     325
     326  // Output routines.
     327  bool Output(ofstream *out);
     328  bool OutputTrajectories(ofstream *out);
     329  void OutputListOfBonds(ofstream *out) const;
     330  bool OutputXYZ(ofstream *out) const;
     331  bool OutputTrajectoriesXYZ(ofstream *out);
     332  bool Checkout(ofstream *out) const;
     333  bool OutputTemperatureFromTrajectories(ofstream *out, int startstep, int endstep, ofstream *output);
     334
     335  private:
     336  int last_atom;      //!< number given to last atom
    337337};
    338338
     
    340340 */
    341341class MoleculeListClass {
    342         public:
    343           MoleculeList ListOfMolecules; //!< List of the contained molecules
    344           int MaxIndex;
    345 
    346         MoleculeListClass();
    347         ~MoleculeListClass();
    348 
    349         bool AddHydrogenCorrection(ofstream *out, char *path);
    350         bool StoreForcesFile(ofstream *out, char *path, int *SortIndex);
    351         bool insert(molecule *mol);
    352         molecule * ReturnIndex(int index);
    353         bool OutputConfigForListOfFragments(ofstream *out, config *configuration, int *SortIndex);
    354         int NumberOfActiveMolecules();
    355         void Enumerate(ofstream *out);
    356         void Output(ofstream *out);
    357 
    358         // merging of molecules
     342  public:
     343    MoleculeList ListOfMolecules; //!< List of the contained molecules
     344    int MaxIndex;
     345
     346  MoleculeListClass();
     347  ~MoleculeListClass();
     348
     349  bool AddHydrogenCorrection(ofstream *out, char *path);
     350  bool StoreForcesFile(ofstream *out, char *path, int *SortIndex);
     351  bool insert(molecule *mol);
     352  molecule * ReturnIndex(int index);
     353  bool OutputConfigForListOfFragments(ofstream *out, config *configuration, int *SortIndex);
     354  int NumberOfActiveMolecules();
     355  void Enumerate(ofstream *out);
     356  void Output(ofstream *out);
     357
     358  // merging of molecules
    359359  bool SimpleMerge(molecule *mol, molecule *srcmol);
    360360  bool SimpleAdd(molecule *mol, molecule *srcmol);
     
    364364  bool EmbedMerge(molecule *mol, molecule *srcmol);
    365365
    366         private:
     366  private:
    367367};
    368368
     
    372372 */
    373373class MoleculeLeafClass {
    374         public:
    375                 molecule *Leaf;                                                                  //!< molecule of this leaf
    376                 //MoleculeLeafClass *UpLeaf;                            //!< Leaf one level up
    377                 //MoleculeLeafClass *DownLeaf;                  //!< First leaf one level down
    378                 MoleculeLeafClass *previous;    //!< Previous leaf on this level
    379                 MoleculeLeafClass *next;                        //!< Next leaf on this level
    380 
    381         //MoleculeLeafClass(MoleculeLeafClass *Up, MoleculeLeafClass *Previous);
    382         MoleculeLeafClass(MoleculeLeafClass *PreviousLeaf);
    383         ~MoleculeLeafClass();
    384 
    385         bool AddLeaf(molecule *ptr, MoleculeLeafClass *Previous);
    386         bool FillBondStructureFromReference(ofstream *out, molecule *reference, int &FragmentCounter, atom ***&ListOfLocalAtoms, bool FreeList = false);
    387         bool FillRootStackForSubgraphs(ofstream *out, KeyStack *&RootStack, bool *AtomMask, int &FragmentCounter);
    388         bool AssignKeySetsToFragment(ofstream *out, molecule *reference, Graph *KeySetList, atom ***&ListOfLocalAtoms, Graph **&FragmentList, int &FragmentCounter, bool FreeList = false);
    389         bool FillListOfLocalAtoms(ofstream *out, atom ***&ListOfLocalAtoms, const int FragmentCounter, const int GlobalAtomCount, bool &FreeList);
    390         void TranslateIndicesToGlobalIDs(ofstream *out, Graph **FragmentList, int &FragmentCounter, int &TotalNumberOfKeySets, Graph &TotalGraph);
    391         int Count() const;
     374  public:
     375    molecule *Leaf;                  //!< molecule of this leaf
     376    //MoleculeLeafClass *UpLeaf;        //!< Leaf one level up
     377    //MoleculeLeafClass *DownLeaf;      //!< First leaf one level down
     378    MoleculeLeafClass *previous;  //!< Previous leaf on this level
     379    MoleculeLeafClass *next;      //!< Next leaf on this level
     380
     381  //MoleculeLeafClass(MoleculeLeafClass *Up, MoleculeLeafClass *Previous);
     382  MoleculeLeafClass(MoleculeLeafClass *PreviousLeaf);
     383  ~MoleculeLeafClass();
     384
     385  bool AddLeaf(molecule *ptr, MoleculeLeafClass *Previous);
     386  bool FillBondStructureFromReference(ofstream *out, molecule *reference, int &FragmentCounter, atom ***&ListOfLocalAtoms, bool FreeList = false);
     387  bool FillRootStackForSubgraphs(ofstream *out, KeyStack *&RootStack, bool *AtomMask, int &FragmentCounter);
     388  bool AssignKeySetsToFragment(ofstream *out, molecule *reference, Graph *KeySetList, atom ***&ListOfLocalAtoms, Graph **&FragmentList, int &FragmentCounter, bool FreeList = false);
     389  bool FillListOfLocalAtoms(ofstream *out, atom ***&ListOfLocalAtoms, const int FragmentCounter, const int GlobalAtomCount, bool &FreeList);
     390  void TranslateIndicesToGlobalIDs(ofstream *out, Graph **FragmentList, int &FragmentCounter, int &TotalNumberOfKeySets, Graph &TotalGraph);
     391  int Count() const;
    392392};
    393393
     
    412412 */
    413413class config {
    414         public:
    415                 int PsiType;
    416                 int MaxPsiDouble;
    417                 int PsiMaxNoUp;
    418                 int PsiMaxNoDown;
    419                 int MaxMinStopStep;
    420                 int InitMaxMinStopStep;
    421                 int ProcPEGamma;
    422                 int ProcPEPsi;
    423                 char *configpath;
    424                 char *configname;
    425                 bool FastParsing;
    426                 double Deltat;
    427                 string basis;
     414  public:
     415    int PsiType;
     416    int MaxPsiDouble;
     417    int PsiMaxNoUp;
     418    int PsiMaxNoDown;
     419    int MaxMinStopStep;
     420    int InitMaxMinStopStep;
     421    int ProcPEGamma;
     422    int ProcPEPsi;
     423    char *configpath;
     424    char *configname;
     425    bool FastParsing;
     426    double Deltat;
     427    string basis;
    428428
    429429    char *databasepath;
    430430
    431         private:
    432                 char *mainname;
    433                 char *defaultpath;
    434                 char *pseudopotpath;
    435 
    436                 int DoOutVis;
    437                 int DoOutMes;
    438                 int DoOutNICS;
    439                 int DoOutOrbitals;
    440                 int DoOutCurrent;
    441                 int DoFullCurrent;
    442                 int DoPerturbation;
    443                 int DoWannier;
    444                 int CommonWannier;
    445                 double SawtoothStart;
    446                 int VectorPlane;
    447                 double VectorCut;
    448                 int UseAddGramSch;
    449                 int Seed;
    450 
    451                 int MaxOuterStep;
    452                 int OutVisStep;
    453                 int OutSrcStep;
    454                 double TargetTemp;
    455                 int ScaleTempStep;
    456                 int MaxPsiStep;
    457                 double EpsWannier;
    458 
    459                 int MaxMinStep;
    460                 double RelEpsTotalEnergy;
    461                 double RelEpsKineticEnergy;
    462                 int MaxMinGapStopStep;
    463                 int MaxInitMinStep;
    464                 double InitRelEpsTotalEnergy;
    465                 double InitRelEpsKineticEnergy;
    466                 int InitMaxMinGapStopStep;
    467 
    468                 //double BoxLength[NDIM*NDIM];
    469 
    470                 double ECut;
    471                 int MaxLevel;
    472                 int RiemannTensor;
    473                 int LevRFactor;
    474                 int RiemannLevel;
    475                 int Lev0Factor;
    476                 int RTActualUse;
    477                 int AddPsis;
    478 
    479                 double RCut;
    480                 int StructOpt;
    481                 int IsAngstroem;
    482                 int RelativeCoord;
    483                 int MaxTypes;
    484 
    485 
    486         int ParseForParameter(int verbose, ifstream *file, const char *name, int sequential, int const xth, int const yth, int type, void *value, int repetition, int critical);
    487         int ParseForParameter(int verbose, struct ConfigFileBuffer *FileBuffer, const char *name, int sequential, int const xth, int const yth, int type, void *value, int repetition, int critical);
    488 
    489         public:
    490         config();
    491         ~config();
    492 
    493         int TestSyntax(char *filename, periodentafel *periode, molecule *mol);
    494         void Load(char *filename, periodentafel *periode, molecule *mol);
    495         void LoadOld(char *filename, periodentafel *periode, molecule *mol);
    496         void RetrieveConfigPathAndName(string filename);
    497         bool Save(const char *filename, periodentafel *periode, molecule *mol) const;
    498         bool SaveMPQC(const char *filename, molecule *mol) const;
    499         void Edit();
    500         bool GetIsAngstroem() const;
    501         char *GetDefaultPath() const;
    502         void SetDefaultPath(const char *path);
     431  private:
     432    char *mainname;
     433    char *defaultpath;
     434    char *pseudopotpath;
     435
     436    int DoOutVis;
     437    int DoOutMes;
     438    int DoOutNICS;
     439    int DoOutOrbitals;
     440    int DoOutCurrent;
     441    int DoFullCurrent;
     442    int DoPerturbation;
     443    int DoWannier;
     444    int CommonWannier;
     445    double SawtoothStart;
     446    int VectorPlane;
     447    double VectorCut;
     448    int UseAddGramSch;
     449    int Seed;
     450
     451    int MaxOuterStep;
     452    int OutVisStep;
     453    int OutSrcStep;
     454    double TargetTemp;
     455    int ScaleTempStep;
     456    int MaxPsiStep;
     457    double EpsWannier;
     458
     459    int MaxMinStep;
     460    double RelEpsTotalEnergy;
     461    double RelEpsKineticEnergy;
     462    int MaxMinGapStopStep;
     463    int MaxInitMinStep;
     464    double InitRelEpsTotalEnergy;
     465    double InitRelEpsKineticEnergy;
     466    int InitMaxMinGapStopStep;
     467
     468    //double BoxLength[NDIM*NDIM];
     469
     470    double ECut;
     471    int MaxLevel;
     472    int RiemannTensor;
     473    int LevRFactor;
     474    int RiemannLevel;
     475    int Lev0Factor;
     476    int RTActualUse;
     477    int AddPsis;
     478
     479    double RCut;
     480    int StructOpt;
     481    int IsAngstroem;
     482    int RelativeCoord;
     483    int MaxTypes;
     484
     485
     486  int ParseForParameter(int verbose, ifstream *file, const char *name, int sequential, int const xth, int const yth, int type, void *value, int repetition, int critical);
     487  int ParseForParameter(int verbose, struct ConfigFileBuffer *FileBuffer, const char *name, int sequential, int const xth, int const yth, int type, void *value, int repetition, int critical);
     488
     489  public:
     490  config();
     491  ~config();
     492
     493  int TestSyntax(char *filename, periodentafel *periode, molecule *mol);
     494  void Load(char *filename, periodentafel *periode, molecule *mol);
     495  void LoadOld(char *filename, periodentafel *periode, molecule *mol);
     496  void RetrieveConfigPathAndName(string filename);
     497  bool Save(const char *filename, periodentafel *periode, molecule *mol) const;
     498  bool SaveMPQC(const char *filename, molecule *mol) const;
     499  void Edit();
     500  bool GetIsAngstroem() const;
     501  char *GetDefaultPath() const;
     502  void SetDefaultPath(const char *path);
    503503};
    504504
  • src/parser.cpp

    r205ccd r042f82  
    2424bool FilePresent(const char *filename, bool test)
    2525{
    26         ifstream input;
    27 
    28         input.open(filename, ios::in);
    29         if (input == NULL) {
    30                 if (!test)
    31                         cout << endl << "Unable to open " << filename << ", is the directory correct?" << endl;
    32                 return false;
    33         }
    34         input.close();
    35         return true;
     26  ifstream input;
     27
     28  input.open(filename, ios::in);
     29  if (input == NULL) {
     30    if (!test)
     31      cout << endl << "Unable to open " << filename << ", is the directory correct?" << endl;
     32    return false;
     33  }
     34  input.close();
     35  return true;
    3636};
    3737
     
    4343bool TestParams(int argc, char **argv)
    4444{
    45         ifstream input;
    46         stringstream line;
    47 
    48         line << argv[1] << FRAGMENTPREFIX << KEYSETFILE;
    49         return FilePresent(line.str().c_str(), false);
     45  ifstream input;
     46  stringstream line;
     47
     48  line << argv[1] << FRAGMENTPREFIX << KEYSETFILE;
     49  return FilePresent(line.str().c_str(), false);
    5050};
    5151
     
    5555 */
    5656MatrixContainer::MatrixContainer() {
    57         Indices = NULL;
    58         Header = (char *) Malloc(sizeof(char)*1023, "MatrixContainer::MatrixContainer: *Header");
    59         Matrix = (double ***) Malloc(sizeof(double **)*(1), "MatrixContainer::MatrixContainer: ***Matrix"); // one more each for the total molecule
    60         RowCounter = (int *) Malloc(sizeof(int)*(1), "MatrixContainer::MatrixContainer: *RowCounter");
    61         Matrix[0] = NULL;
    62         RowCounter[0] = -1;
    63         MatrixCounter = 0;
    64         ColumnCounter = 0;
     57  Indices = NULL;
     58  Header = (char *) Malloc(sizeof(char)*1023, "MatrixContainer::MatrixContainer: *Header");
     59  Matrix = (double ***) Malloc(sizeof(double **)*(1), "MatrixContainer::MatrixContainer: ***Matrix"); // one more each for the total molecule
     60  RowCounter = (int *) Malloc(sizeof(int)*(1), "MatrixContainer::MatrixContainer: *RowCounter");
     61  Matrix[0] = NULL;
     62  RowCounter[0] = -1;
     63  MatrixCounter = 0;
     64  ColumnCounter = 0;
    6565};
    6666
     
    6868 */
    6969MatrixContainer::~MatrixContainer() {
    70         if (Matrix != NULL) {
    71                 for(int i=MatrixCounter;i--;) {
    72                         if (RowCounter != NULL) {
    73                                         for(int j=RowCounter[i]+1;j--;)
    74                                                 Free((void **)&Matrix[i][j], "MatrixContainer::~MatrixContainer: *Matrix[][]");
    75                                 Free((void **)&Matrix[i], "MatrixContainer::~MatrixContainer: **Matrix[]");
    76                         }
    77                 }
    78                 if ((RowCounter != NULL) && (Matrix[MatrixCounter] != NULL))
    79                         for(int j=RowCounter[MatrixCounter]+1;j--;)
    80                                 Free((void **)&Matrix[MatrixCounter][j], "MatrixContainer::~MatrixContainer: *Matrix[MatrixCounter][]");
    81                 if (MatrixCounter != 0)
    82                         Free((void **)&Matrix[MatrixCounter], "MatrixContainer::~MatrixContainer: **Matrix[MatrixCounter]");
    83                 Free((void **)&Matrix, "MatrixContainer::~MatrixContainer: ***Matrix");
    84         }
    85         if (Indices != NULL)
    86                 for(int i=MatrixCounter+1;i--;) {
    87                         Free((void **)&Indices[i], "MatrixContainer::~MatrixContainer: *Indices[]");
    88                 }
    89         Free((void **)&Indices, "MatrixContainer::~MatrixContainer: **Indices");
    90 
    91         Free((void **)&Header, "MatrixContainer::~MatrixContainer: *Header");
    92         Free((void **)&RowCounter, "MatrixContainer::~MatrixContainer: *RowCounter");
     70  if (Matrix != NULL) {
     71    for(int i=MatrixCounter;i--;) {
     72      if (RowCounter != NULL) {
     73          for(int j=RowCounter[i]+1;j--;)
     74            Free((void **)&Matrix[i][j], "MatrixContainer::~MatrixContainer: *Matrix[][]");
     75        Free((void **)&Matrix[i], "MatrixContainer::~MatrixContainer: **Matrix[]");
     76      }
     77    }
     78    if ((RowCounter != NULL) && (Matrix[MatrixCounter] != NULL))
     79      for(int j=RowCounter[MatrixCounter]+1;j--;)
     80        Free((void **)&Matrix[MatrixCounter][j], "MatrixContainer::~MatrixContainer: *Matrix[MatrixCounter][]");
     81    if (MatrixCounter != 0)
     82      Free((void **)&Matrix[MatrixCounter], "MatrixContainer::~MatrixContainer: **Matrix[MatrixCounter]");
     83    Free((void **)&Matrix, "MatrixContainer::~MatrixContainer: ***Matrix");
     84  }
     85  if (Indices != NULL)
     86    for(int i=MatrixCounter+1;i--;) {
     87      Free((void **)&Indices[i], "MatrixContainer::~MatrixContainer: *Indices[]");
     88    }
     89  Free((void **)&Indices, "MatrixContainer::~MatrixContainer: **Indices");
     90
     91  Free((void **)&Header, "MatrixContainer::~MatrixContainer: *Header");
     92  Free((void **)&RowCounter, "MatrixContainer::~MatrixContainer: *RowCounter");
    9393};
    9494
    9595
    9696/** Parsing a number of matrices.
    97  *              -# open the matrix file
    98  *              -# skip some lines (\a skiplines)
    99  *              -# scan header lines for number of columns
    100  *              -# scan lines for number of rows
    101  *              -# allocate matrix
    102  *              -# loop over found column and row counts and parse in each entry
     97 *    -# open the matrix file
     98 *    -# skip some lines (\a skiplines)
     99 *    -# scan header lines for number of columns
     100 *    -# scan lines for number of rows
     101 *    -# allocate matrix
     102 *    -# loop over found column and row counts and parse in each entry
    103103 * \param *name directory with files
    104104 * \param skiplines number of inital lines to skip
     
    109109bool MatrixContainer::ParseMatrix(const char *name, int skiplines, int skipcolumns, int MatrixNr)
    110110{
    111         ifstream input;
    112         stringstream line;
    113         string token;
    114         char filename[1023];
    115 
    116         input.open(name, ios::in);
    117         //cout << "Opening " << name << " ... " << input << endl;
    118         if (input == NULL) {
    119                 cerr << endl << "Unable to open " << name << ", is the directory correct?" << endl;
    120                 return false;
    121         }
    122 
    123         // skip some initial lines
    124         for (int m=skiplines+1;m--;)
    125                 input.getline(Header, 1023);
    126 
    127         // scan header for number of columns
    128         line.str(Header);
    129         for(int k=skipcolumns;k--;)
    130                 line >> Header;
    131         //cout << line.str() << endl;
    132         ColumnCounter=0;
    133         while ( getline(line,token, '\t') ) {
    134                 if (token.length() > 0)
    135                         ColumnCounter++;
    136         }
    137         //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 
    142         // scan rest for number of rows/lines
    143         RowCounter[MatrixNr]=-1;                // counts one line too much
    144         while (!input.eof()) {
    145                 input.getline(filename, 1023);
    146                 //cout << "Comparing: " << strncmp(filename,"MeanForce",9) << endl;
    147                 RowCounter[MatrixNr]++; // then line was not last MeanForce
    148                 if (strncmp(filename,"MeanForce", 9) == 0) {
    149                         break;
    150                 }
    151         }
    152         //cout << "RowCounter[" << MatrixNr << "]: " << RowCounter[MatrixNr] << " from file " << name << "." << endl;
    153         if (RowCounter[MatrixNr] == 0)
    154                 cerr << "RowCounter[" << MatrixNr << "]: " << RowCounter[MatrixNr] << " from file " << name << ", this is probably an error!" << endl;
    155 
    156         // 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 
    160                 // parse in each entry for this matrix
    161                 input.clear();
    162                 input.seekg(ios::beg);
    163                 for (int m=skiplines+1;m--;)
    164                         input.getline(Header, 1023);            // skip header
    165                 line.str(Header);
    166                 for(int k=skipcolumns;k--;)     // skip columns in header too
    167                         line >> filename;
    168                 strncpy(Header, line.str().c_str(), 1023);
    169                 for(int j=0;j<RowCounter[MatrixNr];j++) {
    170                         Matrix[MatrixNr][j] = (double *) Malloc(sizeof(double)*ColumnCounter, "MatrixContainer::ParseFragmentMatrix: *Matrix[][]");
    171                         input.getline(filename, 1023);
    172                         stringstream lines(filename);
    173                         //cout << "Matrix at level " << j << ":";// << filename << endl;
    174                         for(int k=skipcolumns;k--;)
    175                                 lines >> filename;
    176                         for(int k=0;(k<ColumnCounter) && (!lines.eof());k++) {
    177                                 lines >> Matrix[MatrixNr][j][k];
    178                                 //cout << " " << setprecision(2) << Matrix[MatrixNr][j][k];;
    179                         }
    180                         //cout << endl;
    181                         Matrix[MatrixNr][ RowCounter[MatrixNr] ] = (double *) Malloc(sizeof(double)*ColumnCounter, "MatrixContainer::ParseFragmentMatrix: *Matrix[RowCounter[MatrixNr]][]");
    182                         for(int j=ColumnCounter;j--;)
    183                                 Matrix[MatrixNr][ RowCounter[MatrixNr] ][j] = 0.;
    184                 }
    185         } else {
    186                 cerr << "ERROR: Matrix nr. " << MatrixNr << " has column and row count of (" << ColumnCounter << "," << RowCounter[MatrixNr] << "), could not allocate nor parse!" << endl;
    187         }
    188         input.close();
    189         return true;
     111  ifstream input;
     112  stringstream line;
     113  string token;
     114  char filename[1023];
     115
     116  input.open(name, ios::in);
     117  //cout << "Opening " << name << " ... "  << input << endl;
     118  if (input == NULL) {
     119    cerr << endl << "Unable to open " << name << ", is the directory correct?" << endl;
     120    return false;
     121  }
     122
     123  // skip some initial lines
     124  for (int m=skiplines+1;m--;)
     125    input.getline(Header, 1023);
     126
     127  // scan header for number of columns
     128  line.str(Header);
     129  for(int k=skipcolumns;k--;)
     130    line >> Header;
     131  //cout << line.str() << endl;
     132  ColumnCounter=0;
     133  while ( getline(line,token, '\t') ) {
     134    if (token.length() > 0)
     135      ColumnCounter++;
     136  }
     137  //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
     142  // scan rest for number of rows/lines
     143  RowCounter[MatrixNr]=-1;    // counts one line too much
     144  while (!input.eof()) {
     145    input.getline(filename, 1023);
     146    //cout << "Comparing: " << strncmp(filename,"MeanForce",9) << endl;
     147    RowCounter[MatrixNr]++; // then line was not last MeanForce
     148    if (strncmp(filename,"MeanForce", 9) == 0) {
     149      break;
     150    }
     151  }
     152  //cout << "RowCounter[" << MatrixNr << "]: " << RowCounter[MatrixNr] << " from file " << name << "." << endl;
     153  if (RowCounter[MatrixNr] == 0)
     154    cerr << "RowCounter[" << MatrixNr << "]: " << RowCounter[MatrixNr] << " from file " << name << ", this is probably an error!" << endl;
     155
     156  // 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
     160    // parse in each entry for this matrix
     161    input.clear();
     162    input.seekg(ios::beg);
     163    for (int m=skiplines+1;m--;)
     164      input.getline(Header, 1023);    // skip header
     165    line.str(Header);
     166    for(int k=skipcolumns;k--;)  // skip columns in header too
     167      line >> filename;
     168    strncpy(Header, line.str().c_str(), 1023);
     169    for(int j=0;j<RowCounter[MatrixNr];j++) {
     170      Matrix[MatrixNr][j] = (double *) Malloc(sizeof(double)*ColumnCounter, "MatrixContainer::ParseFragmentMatrix: *Matrix[][]");
     171      input.getline(filename, 1023);
     172      stringstream lines(filename);
     173      //cout << "Matrix at level " << j << ":";// << filename << endl;
     174      for(int k=skipcolumns;k--;)
     175        lines >> filename;
     176      for(int k=0;(k<ColumnCounter) && (!lines.eof());k++) {
     177        lines >> Matrix[MatrixNr][j][k];
     178        //cout << " " << setprecision(2) << Matrix[MatrixNr][j][k];;
     179      }
     180      //cout << endl;
     181      Matrix[MatrixNr][ RowCounter[MatrixNr] ] = (double *) Malloc(sizeof(double)*ColumnCounter, "MatrixContainer::ParseFragmentMatrix: *Matrix[RowCounter[MatrixNr]][]");
     182      for(int j=ColumnCounter;j--;)
     183        Matrix[MatrixNr][ RowCounter[MatrixNr] ][j] = 0.;
     184    }
     185  } else {
     186    cerr << "ERROR: Matrix nr. " << MatrixNr << " has column and row count of (" << ColumnCounter << "," << RowCounter[MatrixNr] << "), could not allocate nor parse!" << endl;
     187  }
     188  input.close();
     189  return true;
    190190};
    191191
     
    193193 * -# First, count the number of matrices by counting lines in KEYSETFILE
    194194 * -# Then,
    195  *              -# construct the fragment number
    196  *              -# open the matrix file
    197  *              -# skip some lines (\a skiplines)
    198  *              -# scan header lines for number of columns
    199  *              -# scan lines for number of rows
    200  *              -# allocate matrix
    201  *              -# loop over found column and row counts and parse in each entry
     195 *    -# construct the fragment number
     196 *    -# open the matrix file
     197 *    -# skip some lines (\a skiplines)
     198 *    -# scan header lines for number of columns
     199 *    -# scan lines for number of rows
     200 *    -# allocate matrix
     201 *    -# loop over found column and row counts and parse in each entry
    202202 * -# Finally, allocate one additional matrix (\a MatrixCounter) containing combined or temporary values
    203203 * \param *name directory with files
     
    210210bool MatrixContainer::ParseFragmentMatrix(const char *name, const char *prefix, string suffix, int skiplines, int skipcolumns)
    211211{
    212         char filename[1023];
    213         ifstream input;
    214         char *FragmentNumber = NULL;
    215         stringstream file;
    216         string token;
    217 
    218         // count the number of matrices
    219         MatrixCounter = -1; // we count one too much
    220         file << name << FRAGMENTPREFIX << KEYSETFILE;
    221         input.open(file.str().c_str(), ios::in);
    222         if (input == NULL) {
    223                 cout << endl << "Unable to open " << file.str() << ", is the directory correct?" << endl;
    224                 return false;
    225         }
    226         while (!input.eof()) {
    227                 input.getline(filename, 1023);
    228                 stringstream zeile(filename);
    229                 MatrixCounter++;
    230         }
    231         input.close();
    232         cout << "Determined " << MatrixCounter << " fragments." << endl;
    233 
    234         cout << "Parsing through each fragment and retrieving " << prefix << suffix << "." << endl;
    235         Matrix = (double ***) ReAlloc(Matrix, sizeof(double **)*(MatrixCounter+1), "MatrixContainer::ParseFragmentMatrix: ***Matrix"); // one more each for the total molecule
    236         RowCounter = (int *) ReAlloc(RowCounter, sizeof(int)*(MatrixCounter+1), "MatrixContainer::ParseFragmentMatrix: *RowCounter");
    237         for(int i=MatrixCounter+1;i--;) {
    238                 Matrix[i] = NULL;
    239                 RowCounter[i] = -1;
    240         }
    241         for(int i=0; i < MatrixCounter;i++) {
    242                 // open matrix file
    243                 FragmentNumber = FixedDigitNumber(MatrixCounter, i);
    244                 file.str(" ");
    245                 file << name << FRAGMENTPREFIX << FragmentNumber << prefix << suffix;
    246                 if (!ParseMatrix(file.str().c_str(), skiplines, skipcolumns, i))
    247                         return false;
    248                 Free((void **)&FragmentNumber, "MatrixContainer::ParseFragmentMatrix: *FragmentNumber");
    249         }
    250         return true;
     212  char filename[1023];
     213  ifstream input;
     214  char *FragmentNumber = NULL;
     215  stringstream file;
     216  string token;
     217
     218  // count the number of matrices
     219  MatrixCounter = -1; // we count one too much
     220  file << name << FRAGMENTPREFIX << KEYSETFILE;
     221  input.open(file.str().c_str(), ios::in);
     222  if (input == NULL) {
     223    cout << endl << "Unable to open " << file.str() << ", is the directory correct?" << endl;
     224    return false;
     225  }
     226  while (!input.eof()) {
     227    input.getline(filename, 1023);
     228    stringstream zeile(filename);
     229    MatrixCounter++;
     230  }
     231  input.close();
     232  cout << "Determined " << MatrixCounter << " fragments." << endl;
     233
     234  cout << "Parsing through each fragment and retrieving " << prefix << suffix << "." << endl;
     235  Matrix = (double ***) ReAlloc(Matrix, sizeof(double **)*(MatrixCounter+1), "MatrixContainer::ParseFragmentMatrix: ***Matrix"); // one more each for the total molecule
     236  RowCounter = (int *) ReAlloc(RowCounter, sizeof(int)*(MatrixCounter+1), "MatrixContainer::ParseFragmentMatrix: *RowCounter");
     237  for(int i=MatrixCounter+1;i--;) {
     238    Matrix[i] = NULL;
     239    RowCounter[i] = -1;
     240  }
     241  for(int i=0; i < MatrixCounter;i++) {
     242    // open matrix file
     243    FragmentNumber = FixedDigitNumber(MatrixCounter, i);
     244    file.str(" ");
     245    file << name << FRAGMENTPREFIX << FragmentNumber << prefix << suffix;
     246    if (!ParseMatrix(file.str().c_str(), skiplines, skipcolumns, i))
     247      return false;
     248    Free((void **)&FragmentNumber, "MatrixContainer::ParseFragmentMatrix: *FragmentNumber");
     249  }
     250  return true;
    251251};
    252252
     
    260260bool MatrixContainer::AllocateMatrix(const char *GivenHeader, int MCounter, int *RCounter, int CCounter)
    261261{
    262         Header = (char *) Malloc(sizeof(char)*1024, "MatrixContainer::ParseFragmentMatrix: *EnergyHeader");
    263         strncpy(Header, GivenHeader, 1023);
    264 
    265         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");
    269         for(int i=MatrixCounter+1;i--;) {
    270                 RowCounter[i] = RCounter[i];
    271                 Matrix[i] = (double **) Malloc(sizeof(double *)*(RowCounter[i]+1), "MatrixContainer::ParseFragmentMatrix: **Matrix[]");
    272                 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--;)
    275                                 Matrix[i][j][k] = 0.;
    276                 }
    277         }
    278         return true;
     262  Header = (char *) Malloc(sizeof(char)*1024, "MatrixContainer::ParseFragmentMatrix: *EnergyHeader");
     263  strncpy(Header, GivenHeader, 1023);
     264
     265  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");
     269  for(int i=MatrixCounter+1;i--;) {
     270    RowCounter[i] = RCounter[i];
     271    Matrix[i] = (double **) Malloc(sizeof(double *)*(RowCounter[i]+1), "MatrixContainer::ParseFragmentMatrix: **Matrix[]");
     272    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--;)
     275        Matrix[i][j][k] = 0.;
     276    }
     277  }
     278  return true;
    279279};
    280280
     
    284284bool MatrixContainer::ResetMatrix()
    285285{
    286         for(int i=MatrixCounter+1;i--;)
    287                 for(int j=RowCounter[i]+1;j--;)
    288                         for(int k=ColumnCounter;k--;)
    289                                 Matrix[i][j][k] = 0.;
    290         return true;
     286  for(int i=MatrixCounter+1;i--;)
     287    for(int j=RowCounter[i]+1;j--;)
     288      for(int k=ColumnCounter;k--;)
     289        Matrix[i][j][k] = 0.;
     290  return true;
    291291};
    292292
     
    296296double MatrixContainer::FindMaxValue()
    297297{
    298         double max = Matrix[0][0][0];
    299         for(int i=MatrixCounter+1;i--;)
    300                 for(int j=RowCounter[i]+1;j--;)
    301                         for(int k=ColumnCounter;k--;)
    302                                 if (fabs(Matrix[i][j][k]) > max)
    303                                         max = fabs(Matrix[i][j][k]);
    304         if (fabs(max) < MYEPSILON)
    305                 max += MYEPSILON;
     298  double max = Matrix[0][0][0];
     299  for(int i=MatrixCounter+1;i--;)
     300    for(int j=RowCounter[i]+1;j--;)
     301      for(int k=ColumnCounter;k--;)
     302        if (fabs(Matrix[i][j][k]) > max)
     303          max = fabs(Matrix[i][j][k]);
     304  if (fabs(max) < MYEPSILON)
     305    max += MYEPSILON;
    306306 return max;
    307307};
     
    312312double MatrixContainer::FindMinValue()
    313313{
    314         double min = Matrix[0][0][0];
    315         for(int i=MatrixCounter+1;i--;)
    316                 for(int j=RowCounter[i]+1;j--;)
    317                         for(int k=ColumnCounter;k--;)
    318                                 if (fabs(Matrix[i][j][k]) < min)
    319                                         min = fabs(Matrix[i][j][k]);
    320         if (fabs(min) < MYEPSILON)
    321                 min += MYEPSILON;
    322         return min;
     314  double min = Matrix[0][0][0];
     315  for(int i=MatrixCounter+1;i--;)
     316    for(int j=RowCounter[i]+1;j--;)
     317      for(int k=ColumnCounter;k--;)
     318        if (fabs(Matrix[i][j][k]) < min)
     319          min = fabs(Matrix[i][j][k]);
     320  if (fabs(min) < MYEPSILON)
     321    min += MYEPSILON;
     322  return min;
    323323};
    324324
     
    330330bool MatrixContainer::SetLastMatrix(double value, int skipcolumns)
    331331{
    332         for(int j=RowCounter[MatrixCounter]+1;j--;)
    333                 for(int k=skipcolumns;k<ColumnCounter;k++)
    334                         Matrix[MatrixCounter][j][k] = value;
    335         return true;
     332  for(int j=RowCounter[MatrixCounter]+1;j--;)
     333    for(int k=skipcolumns;k<ColumnCounter;k++)
     334      Matrix[MatrixCounter][j][k] = value;
     335  return true;
    336336};
    337337
     
    343343bool MatrixContainer::SetLastMatrix(double **values, int skipcolumns)
    344344{
    345         for(int j=RowCounter[MatrixCounter]+1;j--;)
    346                 for(int k=skipcolumns;k<ColumnCounter;k++)
    347                         Matrix[MatrixCounter][j][k] = values[j][k];
    348         return true;
     345  for(int j=RowCounter[MatrixCounter]+1;j--;)
     346    for(int k=skipcolumns;k<ColumnCounter;k++)
     347      Matrix[MatrixCounter][j][k] = values[j][k];
     348  return true;
    349349};
    350350
     
    358358bool MatrixContainer::SumSubManyBodyTerms(class MatrixContainer &MatrixValues, class KeySetsContainer &KeySet, int Order)
    359359{
    360         // go through each order
    361         for (int CurrentFragment=0;CurrentFragment<KeySet.FragmentsPerOrder[Order];CurrentFragment++) {
    362                 //cout << "Current Fragment is " << CurrentFragment << "/" << KeySet.OrderSet[Order][CurrentFragment] << "." << endl;
    363                 // then go per order through each suborder and pick together all the terms that contain this fragment
    364                 for(int SubOrder=0;SubOrder<=Order;SubOrder++) { // go through all suborders up to the desired order
    365                         for (int j=0;j<KeySet.FragmentsPerOrder[SubOrder];j++) { // go through all possible fragments of size suborder
    366                                 if (KeySet.Contains(KeySet.OrderSet[Order][CurrentFragment], KeySet.OrderSet[SubOrder][j])) {
    367                                         //cout << "Current other fragment is " << j << "/" << KeySet.OrderSet[SubOrder][j] << "." << endl;
    368                                         // if the fragment's indices are all in the current fragment
    369                                         for(int k=0;k<RowCounter[ KeySet.OrderSet[SubOrder][j] ];k++) { // go through all atoms in this fragment
    370                                                 int m = MatrixValues.Indices[ KeySet.OrderSet[SubOrder][j] ][k];
    371                                                 //cout << "Current index is " << k << "/" << m << "." << endl;
    372                                                 if (m != -1) { // if it's not an added hydrogen
    373                                                         for (int l=0;l<RowCounter[ KeySet.OrderSet[Order][CurrentFragment] ];l++) { // look for the corresponding index in the current fragment
    374                                                                 //cout << "Comparing " << m << " with " << MatrixValues.Indices[ KeySet.OrderSet[Order][CurrentFragment] ][l] << "." << endl;
    375                                                                 if (m == MatrixValues.Indices[ KeySet.OrderSet[Order][CurrentFragment] ][l]) {
    376                                                                         m = l;
    377                                                                         break;
    378                                                                 }
    379                                                         }
    380                                                         //cout << "Corresponding index in CurrentFragment is " << m << "." << endl;
    381                                                         if (m > RowCounter[ KeySet.OrderSet[Order][CurrentFragment] ]) {
    382                                                                 cerr << "In fragment No. " << KeySet.OrderSet[Order][CurrentFragment]    << " current force index " << m << " is greater than " << RowCounter[ KeySet.OrderSet[Order][CurrentFragment] ] << "!" << endl;
    383                                                                 return false;
    384                                                         }
    385                                                         if (Order == SubOrder) { // equal order is always copy from Energies
    386                                                                 for(int l=ColumnCounter;l--;) // then adds/subtract each column
    387                                                                         Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][m][l] += MatrixValues.Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l];
    388                                                         } else {
    389                                                                 for(int l=ColumnCounter;l--;)
    390                                                                         Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][m][l] -= Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l];
    391                                                         }
    392                                                 }
    393                                                 //if ((ColumnCounter>1) && (RowCounter[0]-1 >= 1))
    394                                                  //cout << "Fragments[ KeySet.OrderSet[" << Order << "][" << CurrentFragment << "]=" << KeySet.OrderSet[Order][CurrentFragment] << " ][" << RowCounter[0]-1 << "][" << 1 << "] = " <<   Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][RowCounter[0]-1][1] << endl;
    395                                         }
    396                                 } else {
    397                                         //cout << "Fragment " << KeySet.OrderSet[SubOrder][j] << " is not contained in fragment " << KeySet.OrderSet[Order][CurrentFragment] << "." << endl;
    398                                 }
    399                         }
    400                 }
    401          //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;
    402         }
    403 
    404         return true;
     360  // go through each order
     361  for (int CurrentFragment=0;CurrentFragment<KeySet.FragmentsPerOrder[Order];CurrentFragment++) {
     362    //cout << "Current Fragment is " << CurrentFragment << "/" << KeySet.OrderSet[Order][CurrentFragment] << "." << endl;
     363    // then go per order through each suborder and pick together all the terms that contain this fragment
     364    for(int SubOrder=0;SubOrder<=Order;SubOrder++) { // go through all suborders up to the desired order
     365      for (int j=0;j<KeySet.FragmentsPerOrder[SubOrder];j++) { // go through all possible fragments of size suborder
     366        if (KeySet.Contains(KeySet.OrderSet[Order][CurrentFragment], KeySet.OrderSet[SubOrder][j])) {
     367          //cout << "Current other fragment is " << j << "/" << KeySet.OrderSet[SubOrder][j] << "." << endl;
     368          // if the fragment's indices are all in the current fragment
     369          for(int k=0;k<RowCounter[ KeySet.OrderSet[SubOrder][j] ];k++) { // go through all atoms in this fragment
     370            int m = MatrixValues.Indices[ KeySet.OrderSet[SubOrder][j] ][k];
     371            //cout << "Current index is " << k << "/" << m << "." << endl;
     372            if (m != -1) { // if it's not an added hydrogen
     373              for (int l=0;l<RowCounter[ KeySet.OrderSet[Order][CurrentFragment] ];l++) { // look for the corresponding index in the current fragment
     374                //cout << "Comparing " << m << " with " << MatrixValues.Indices[ KeySet.OrderSet[Order][CurrentFragment] ][l] << "." << endl;
     375                if (m == MatrixValues.Indices[ KeySet.OrderSet[Order][CurrentFragment] ][l]) {
     376                  m = l;
     377                  break;
     378                }
     379              }
     380              //cout << "Corresponding index in CurrentFragment is " << m << "." << endl;
     381              if (m > RowCounter[ KeySet.OrderSet[Order][CurrentFragment] ]) {
     382                cerr << "In fragment No. " << KeySet.OrderSet[Order][CurrentFragment]  << " current force index " << m << " is greater than " << RowCounter[ KeySet.OrderSet[Order][CurrentFragment] ] << "!" << endl;
     383                return false;
     384              }
     385              if (Order == SubOrder) { // equal order is always copy from Energies
     386                for(int l=ColumnCounter;l--;) // then adds/subtract each column
     387                  Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][m][l] += MatrixValues.Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l];
     388              } else {
     389                for(int l=ColumnCounter;l--;)
     390                  Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][m][l] -= Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l];
     391              }
     392            }
     393            //if ((ColumnCounter>1) && (RowCounter[0]-1 >= 1))
     394             //cout << "Fragments[ KeySet.OrderSet[" << Order << "][" << CurrentFragment << "]=" << KeySet.OrderSet[Order][CurrentFragment] << " ][" << RowCounter[0]-1 << "][" << 1 << "] = " <<  Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][RowCounter[0]-1][1] << endl;
     395          }
     396        } else {
     397          //cout << "Fragment " << KeySet.OrderSet[SubOrder][j] << " is not contained in fragment " << KeySet.OrderSet[Order][CurrentFragment] << "." << endl;
     398        }
     399      }
     400    }
     401   //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;
     402  }
     403
     404  return true;
    405405};
    406406
     
    412412bool MatrixContainer::WriteTotalFragments(const char *name, const char *prefix)
    413413{
    414         ofstream output;
    415         char *FragmentNumber = NULL;
    416 
    417         cout << "Writing fragment files." << endl;
    418         for(int i=0;i<MatrixCounter;i++) {
    419                 stringstream line;
    420                 FragmentNumber = FixedDigitNumber(MatrixCounter, i);
    421                 line << name << FRAGMENTPREFIX << FragmentNumber << "/" << prefix;
    422                 Free((void **)&FragmentNumber, "*FragmentNumber");
    423                 output.open(line.str().c_str(), ios::out);
    424                 if (output == NULL) {
    425                         cerr << "Unable to open output energy file " << line.str() << "!" << endl;
    426                         return false;
    427                 }
    428                 output << Header << endl;
    429                 for(int j=0;j<RowCounter[i];j++) {
    430                         for(int k=0;k<ColumnCounter;k++)
    431                                 output << scientific << Matrix[i][j][k] << "\t";
    432                         output << endl;
    433                 }
    434                 output.close();
    435         }
    436         return true;
     414  ofstream output;
     415  char *FragmentNumber = NULL;
     416
     417  cout << "Writing fragment files." << endl;
     418  for(int i=0;i<MatrixCounter;i++) {
     419    stringstream line;
     420    FragmentNumber = FixedDigitNumber(MatrixCounter, i);
     421    line << name << FRAGMENTPREFIX << FragmentNumber << "/" << prefix;
     422    Free((void **)&FragmentNumber, "*FragmentNumber");
     423    output.open(line.str().c_str(), ios::out);
     424    if (output == NULL) {
     425      cerr << "Unable to open output energy file " << line.str() << "!" << endl;
     426      return false;
     427    }
     428    output << Header << endl;
     429    for(int j=0;j<RowCounter[i];j++) {
     430      for(int k=0;k<ColumnCounter;k++)
     431        output << scientific << Matrix[i][j][k] << "\t";
     432      output << endl;
     433    }
     434    output.close();
     435  }
     436  return true;
    437437};
    438438
     
    445445bool MatrixContainer::WriteLastMatrix(const char *name, const char *prefix, const char *suffix)
    446446{
    447         ofstream output;
    448         stringstream line;
    449 
    450         cout << "Writing matrix values of " << suffix << "." << endl;
    451         line << name << prefix << suffix;
    452         output.open(line.str().c_str(), ios::out);
    453         if (output == NULL) {
    454                 cerr << "Unable to open output matrix file " << line.str() << "!" << endl;
    455                 return false;
    456         }
    457         output << Header << endl;
    458         for(int j=0;j<RowCounter[MatrixCounter];j++) {
    459                 for(int k=0;k<ColumnCounter;k++)
    460                         output << scientific << Matrix[MatrixCounter][j][k] << "\t";
    461                 output << endl;
    462         }
    463         output.close();
    464         return true;
     447  ofstream output;
     448  stringstream line;
     449
     450  cout << "Writing matrix values of " << suffix << "." << endl;
     451  line << name << prefix << suffix;
     452  output.open(line.str().c_str(), ios::out);
     453  if (output == NULL) {
     454    cerr << "Unable to open output matrix file " << line.str() << "!" << endl;
     455    return false;
     456  }
     457  output << Header << endl;
     458  for(int j=0;j<RowCounter[MatrixCounter];j++) {
     459    for(int k=0;k<ColumnCounter;k++)
     460      output << scientific << Matrix[MatrixCounter][j][k] << "\t";
     461    output << endl;
     462  }
     463  output.close();
     464  return true;
    465465};
    466466
     
    473473bool EnergyMatrix::ParseIndices()
    474474{
    475         cout << "Parsing energy indices." << endl;
    476         Indices = (int **) Malloc(sizeof(int *)*(MatrixCounter+1), "EnergyMatrix::ParseIndices: **Indices");
    477         for(int i=MatrixCounter+1;i--;) {
    478                 Indices[i] = (int *) Malloc(sizeof(int)*RowCounter[i], "EnergyMatrix::ParseIndices: *Indices[]");
    479                 for(int j=RowCounter[i];j--;)
    480                         Indices[i][j] = j;
    481         }
    482         return true;
     475  cout << "Parsing energy indices." << endl;
     476  Indices = (int **) Malloc(sizeof(int *)*(MatrixCounter+1), "EnergyMatrix::ParseIndices: **Indices");
     477  for(int i=MatrixCounter+1;i--;) {
     478    Indices[i] = (int *) Malloc(sizeof(int)*RowCounter[i], "EnergyMatrix::ParseIndices: *Indices[]");
     479    for(int j=RowCounter[i];j--;)
     480      Indices[i][j] = j;
     481  }
     482  return true;
    483483};
    484484
     
    494494bool EnergyMatrix::SumSubEnergy(class EnergyMatrix &Fragments, class EnergyMatrix *CorrectionFragments, class KeySetsContainer &KeySet, int Order, double sign)
    495495{
    496         // sum energy
    497         if (CorrectionFragments == NULL)
    498                 for(int i=KeySet.FragmentsPerOrder[Order];i--;)
    499                         for(int j=RowCounter[ KeySet.OrderSet[Order][i] ];j--;)
    500                                 for(int k=ColumnCounter;k--;)
    501                                         Matrix[MatrixCounter][j][k] += sign*Fragments.Matrix[ KeySet.OrderSet[Order][i] ][j][k];
    502         else
    503                 for(int i=KeySet.FragmentsPerOrder[Order];i--;)
    504                         for(int j=RowCounter[ KeySet.OrderSet[Order][i] ];j--;)
    505                                 for(int k=ColumnCounter;k--;)
    506                                         Matrix[MatrixCounter][j][k] += sign*(Fragments.Matrix[ KeySet.OrderSet[Order][i] ][j][k] + CorrectionFragments->Matrix[ KeySet.OrderSet[Order][i] ][j][k]);
    507         return true;
     496  // sum energy
     497  if (CorrectionFragments == NULL)
     498    for(int i=KeySet.FragmentsPerOrder[Order];i--;)
     499      for(int j=RowCounter[ KeySet.OrderSet[Order][i] ];j--;)
     500        for(int k=ColumnCounter;k--;)
     501          Matrix[MatrixCounter][j][k] += sign*Fragments.Matrix[ KeySet.OrderSet[Order][i] ][j][k];
     502  else
     503    for(int i=KeySet.FragmentsPerOrder[Order];i--;)
     504      for(int j=RowCounter[ KeySet.OrderSet[Order][i] ];j--;)
     505        for(int k=ColumnCounter;k--;)
     506          Matrix[MatrixCounter][j][k] += sign*(Fragments.Matrix[ KeySet.OrderSet[Order][i] ][j][k] + CorrectionFragments->Matrix[ KeySet.OrderSet[Order][i] ][j][k]);
     507  return true;
    508508};
    509509
     
    518518bool EnergyMatrix::ParseFragmentMatrix(const char *name, const char *prefix, string suffix, int skiplines, int skipcolumns)
    519519{
    520         char filename[1024];
    521         bool status = MatrixContainer::ParseFragmentMatrix(name, prefix, suffix, skiplines, skipcolumns);
    522 
    523         if (status) {
    524                 // count maximum of columns
    525                 RowCounter[MatrixCounter] = 0;
    526                 for(int j=0; j < MatrixCounter;j++) // (energy matrix might be bigger than number of atoms in terms of rows)
    527                         if (RowCounter[j] > RowCounter[MatrixCounter])
    528                                 RowCounter[MatrixCounter] = RowCounter[j];
    529                 // allocate last plus one matrix
    530                 cout << "Allocating last plus one matrix with " << (RowCounter[MatrixCounter]+1) << " rows and " << ColumnCounter << " columns." << endl;
    531                 Matrix[MatrixCounter] = (double **) Malloc(sizeof(double *)*(RowCounter[MatrixCounter]+1), "MatrixContainer::ParseFragmentMatrix: **Matrix[]");
    532                 for(int j=0;j<=RowCounter[MatrixCounter];j++)
    533                         Matrix[MatrixCounter][j] = (double *) Malloc(sizeof(double)*ColumnCounter, "MatrixContainer::ParseFragmentMatrix: *Matrix[][]");
    534 
    535                 // try independently to parse global energysuffix file if present
    536                 strncpy(filename, name, 1023);
    537                 strncat(filename, prefix, 1023-strlen(filename));
    538                 strncat(filename, suffix.c_str(), 1023-strlen(filename));
    539                 ParseMatrix(filename, skiplines, skipcolumns, MatrixCounter);
    540         }
    541         return status;
     520  char filename[1024];
     521  bool status = MatrixContainer::ParseFragmentMatrix(name, prefix, suffix, skiplines, skipcolumns);
     522
     523  if (status) {
     524    // count maximum of columns
     525    RowCounter[MatrixCounter] = 0;
     526    for(int j=0; j < MatrixCounter;j++) // (energy matrix might be bigger than number of atoms in terms of rows)
     527      if (RowCounter[j] > RowCounter[MatrixCounter])
     528        RowCounter[MatrixCounter] = RowCounter[j];
     529    // allocate last plus one matrix
     530    cout << "Allocating last plus one matrix with " << (RowCounter[MatrixCounter]+1) << " rows and " << ColumnCounter << " columns." << endl;
     531    Matrix[MatrixCounter] = (double **) Malloc(sizeof(double *)*(RowCounter[MatrixCounter]+1), "MatrixContainer::ParseFragmentMatrix: **Matrix[]");
     532    for(int j=0;j<=RowCounter[MatrixCounter];j++)
     533      Matrix[MatrixCounter][j] = (double *) Malloc(sizeof(double)*ColumnCounter, "MatrixContainer::ParseFragmentMatrix: *Matrix[][]");
     534
     535    // try independently to parse global energysuffix file if present
     536    strncpy(filename, name, 1023);
     537    strncat(filename, prefix, 1023-strlen(filename));
     538    strncat(filename, suffix.c_str(), 1023-strlen(filename));
     539    ParseMatrix(filename, skiplines, skipcolumns, MatrixCounter);
     540  }
     541  return status;
    542542};
    543543
     
    550550bool ForceMatrix::ParseIndices(const char *name)
    551551{
    552         ifstream input;
    553         char *FragmentNumber = NULL;
    554         char filename[1023];
    555         stringstream line;
    556 
    557         cout << "Parsing force indices for " << MatrixCounter << " matrices." << endl;
    558         Indices = (int **) Malloc(sizeof(int *)*(MatrixCounter+1), "ForceMatrix::ParseIndices: **Indices");
    559         line << name << FRAGMENTPREFIX << FORCESFILE;
    560         input.open(line.str().c_str(), ios::in);
    561         //cout << "Opening " << line.str() << " ... "   << input << endl;
    562         if (input == NULL) {
    563                 cout << endl << "Unable to open " << line.str() << ", is the directory correct?" << endl;
    564                 return false;
    565         }
    566         for (int i=0;(i<MatrixCounter) && (!input.eof());i++) {
    567                 // get the number of atoms for this fragment
    568                 input.getline(filename, 1023);
    569                 line.str(filename);
    570                 // parse the values
    571                 Indices[i] = (int *) Malloc(sizeof(int)*RowCounter[i], "ForceMatrix::ParseIndices: *Indices[]");
    572                 FragmentNumber = FixedDigitNumber(MatrixCounter, i);
    573                 //cout << FRAGMENTPREFIX << FragmentNumber << "[" << RowCounter[i] << "]:";
    574                 Free((void **)&FragmentNumber, "ForceMatrix::ParseIndices: *FragmentNumber");
    575                 for(int j=0;(j<RowCounter[i]) && (!line.eof());j++) {
    576                         line >> Indices[i][j];
    577                         //cout << " " << Indices[i][j];
    578                 }
    579                 //cout << endl;
    580         }
    581         Indices[MatrixCounter] = (int *) Malloc(sizeof(int)*RowCounter[MatrixCounter], "ForceMatrix::ParseIndices: *Indices[]");
    582         for(int j=RowCounter[MatrixCounter];j--;) {
    583                 Indices[MatrixCounter][j] = j;
    584         }
    585         input.close();
    586         return true;
     552  ifstream input;
     553  char *FragmentNumber = NULL;
     554  char filename[1023];
     555  stringstream line;
     556
     557  cout << "Parsing force indices for " << MatrixCounter << " matrices." << endl;
     558  Indices = (int **) Malloc(sizeof(int *)*(MatrixCounter+1), "ForceMatrix::ParseIndices: **Indices");
     559  line << name << FRAGMENTPREFIX << FORCESFILE;
     560  input.open(line.str().c_str(), ios::in);
     561  //cout << "Opening " << line.str() << " ... "  << input << endl;
     562  if (input == NULL) {
     563    cout << endl << "Unable to open " << line.str() << ", is the directory correct?" << endl;
     564    return false;
     565  }
     566  for (int i=0;(i<MatrixCounter) && (!input.eof());i++) {
     567    // get the number of atoms for this fragment
     568    input.getline(filename, 1023);
     569    line.str(filename);
     570    // parse the values
     571    Indices[i] = (int *) Malloc(sizeof(int)*RowCounter[i], "ForceMatrix::ParseIndices: *Indices[]");
     572    FragmentNumber = FixedDigitNumber(MatrixCounter, i);
     573    //cout << FRAGMENTPREFIX << FragmentNumber << "[" << RowCounter[i] << "]:";
     574    Free((void **)&FragmentNumber, "ForceMatrix::ParseIndices: *FragmentNumber");
     575    for(int j=0;(j<RowCounter[i]) && (!line.eof());j++) {
     576      line >> Indices[i][j];
     577      //cout << " " << Indices[i][j];
     578    }
     579    //cout << endl;
     580  }
     581  Indices[MatrixCounter] = (int *) Malloc(sizeof(int)*RowCounter[MatrixCounter], "ForceMatrix::ParseIndices: *Indices[]");
     582  for(int j=RowCounter[MatrixCounter];j--;) {
     583    Indices[MatrixCounter][j] = j;
     584  }
     585  input.close();
     586  return true;
    587587};
    588588
     
    592592 * \param KeySet KeySetContainer with bond Order and association mapping of each fragment to an order
    593593 * \param Order bond order
    594  *      \param sign +1 or -1
     594 *  \param sign +1 or -1
    595595 * \return true if summing was successful
    596596 */
    597597bool ForceMatrix::SumSubForces(class ForceMatrix &Fragments, class KeySetsContainer &KeySet, int Order, double sign)
    598598{
    599         int FragmentNr;
    600         // sum forces
    601         for(int i=0;i<KeySet.FragmentsPerOrder[Order];i++) {
    602                 FragmentNr = KeySet.OrderSet[Order][i];
    603                 for(int l=0;l<RowCounter[ FragmentNr ];l++) {
    604                         int j = Indices[ FragmentNr ][l];
    605                         if (j > RowCounter[MatrixCounter]) {
    606                                 cerr << "Current force index " << j << " is greater than " << RowCounter[MatrixCounter] << "!" << endl;
    607                                 return false;
    608                         }
    609                         if (j != -1) {
    610                                 //if (j == 0) cout << "Summing onto ion 0, type 0 from fragment " << FragmentNr << ", ion " << l << "." << endl;
    611                                 for(int k=2;k<ColumnCounter;k++)
    612                                         Matrix[MatrixCounter][j][k] += sign*Fragments.Matrix[ FragmentNr ][l][k];
    613                         }
    614                 }
    615         }
    616         return true;
     599  int FragmentNr;
     600  // sum forces
     601  for(int i=0;i<KeySet.FragmentsPerOrder[Order];i++) {
     602    FragmentNr = KeySet.OrderSet[Order][i];
     603    for(int l=0;l<RowCounter[ FragmentNr ];l++) {
     604      int j = Indices[ FragmentNr ][l];
     605      if (j > RowCounter[MatrixCounter]) {
     606        cerr << "Current force index " << j << " is greater than " << RowCounter[MatrixCounter] << "!" << endl;
     607        return false;
     608      }
     609      if (j != -1) {
     610        //if (j == 0) cout << "Summing onto ion 0, type 0 from fragment " << FragmentNr << ", ion " << l << "." << endl;
     611        for(int k=2;k<ColumnCounter;k++)
     612          Matrix[MatrixCounter][j][k] += sign*Fragments.Matrix[ FragmentNr ][l][k];
     613      }
     614    }
     615  }
     616  return true;
    617617};
    618618
     
    628628bool ForceMatrix::ParseFragmentMatrix(const char *name, const char *prefix, string suffix, int skiplines, int skipcolumns)
    629629{
    630         char filename[1023];
    631         ifstream input;
    632         stringstream file;
    633         int nr;
    634         bool status = MatrixContainer::ParseFragmentMatrix(name, prefix, suffix, skiplines, skipcolumns);
    635 
    636         if (status) {
    637                 // count number of atoms for last plus one matrix
    638                 file << name << FRAGMENTPREFIX << KEYSETFILE;
    639                 input.open(file.str().c_str(), ios::in);
    640                 if (input == NULL) {
    641                         cout << endl << "Unable to open " << file.str() << ", is the directory correct?" << endl;
    642                         return false;
    643                 }
    644                 RowCounter[MatrixCounter] = 0;
    645                 while (!input.eof()) {
    646                         input.getline(filename, 1023);
    647                         stringstream zeile(filename);
    648                         while (!zeile.eof()) {
    649                                 zeile >> nr;
    650                                 //cout << "Current index: " << nr << "." << endl;
    651                                 if (nr > RowCounter[MatrixCounter])
    652                                         RowCounter[MatrixCounter] = nr;
    653                         }
    654                 }
    655                 RowCounter[MatrixCounter]++;            // nr start at 0, count starts at 1
    656                 input.close();
    657 
    658                 // allocate last plus one matrix
    659                 cout << "Allocating last plus one matrix with " << (RowCounter[MatrixCounter]+1) << " rows and " << ColumnCounter << " columns." << endl;
    660                 Matrix[MatrixCounter] = (double **) Malloc(sizeof(double *)*(RowCounter[MatrixCounter]+1), "MatrixContainer::ParseFragmentMatrix: **Matrix[]");
    661                 for(int j=0;j<=RowCounter[MatrixCounter];j++)
    662                         Matrix[MatrixCounter][j] = (double *) Malloc(sizeof(double)*ColumnCounter, "MatrixContainer::ParseFragmentMatrix: *Matrix[][]");
    663 
    664                 // try independently to parse global forcesuffix file if present
    665                 strncpy(filename, name, 1023);
    666                 strncat(filename, prefix, 1023-strlen(filename));
    667                 strncat(filename, suffix.c_str(), 1023-strlen(filename));
    668                 ParseMatrix(filename, skiplines, skipcolumns, MatrixCounter);
    669         }
    670 
    671 
    672         return status;
     630  char filename[1023];
     631  ifstream input;
     632  stringstream file;
     633  int nr;
     634  bool status = MatrixContainer::ParseFragmentMatrix(name, prefix, suffix, skiplines, skipcolumns);
     635
     636  if (status) {
     637    // count number of atoms for last plus one matrix
     638    file << name << FRAGMENTPREFIX << KEYSETFILE;
     639    input.open(file.str().c_str(), ios::in);
     640    if (input == NULL) {
     641      cout << endl << "Unable to open " << file.str() << ", is the directory correct?" << endl;
     642      return false;
     643    }
     644    RowCounter[MatrixCounter] = 0;
     645    while (!input.eof()) {
     646      input.getline(filename, 1023);
     647      stringstream zeile(filename);
     648      while (!zeile.eof()) {
     649        zeile >> nr;
     650        //cout << "Current index: " << nr << "." << endl;
     651        if (nr > RowCounter[MatrixCounter])
     652          RowCounter[MatrixCounter] = nr;
     653      }
     654    }
     655    RowCounter[MatrixCounter]++;    // nr start at 0, count starts at 1
     656    input.close();
     657
     658    // allocate last plus one matrix
     659    cout << "Allocating last plus one matrix with " << (RowCounter[MatrixCounter]+1) << " rows and " << ColumnCounter << " columns." << endl;
     660    Matrix[MatrixCounter] = (double **) Malloc(sizeof(double *)*(RowCounter[MatrixCounter]+1), "MatrixContainer::ParseFragmentMatrix: **Matrix[]");
     661    for(int j=0;j<=RowCounter[MatrixCounter];j++)
     662      Matrix[MatrixCounter][j] = (double *) Malloc(sizeof(double)*ColumnCounter, "MatrixContainer::ParseFragmentMatrix: *Matrix[][]");
     663
     664    // try independently to parse global forcesuffix file if present
     665    strncpy(filename, name, 1023);
     666    strncat(filename, prefix, 1023-strlen(filename));
     667    strncat(filename, suffix.c_str(), 1023-strlen(filename));
     668    ParseMatrix(filename, skiplines, skipcolumns, MatrixCounter);
     669  }
     670
     671
     672  return status;
    673673};
    674674
     
    678678 */
    679679KeySetsContainer::KeySetsContainer() {
    680         KeySets = NULL;
    681         AtomCounter = NULL;
    682         FragmentCounter = 0;
    683         Order = 0;
    684         FragmentsPerOrder = 0;
    685         OrderSet = NULL;
     680  KeySets = NULL;
     681  AtomCounter = NULL;
     682  FragmentCounter = 0;
     683  Order = 0;
     684  FragmentsPerOrder = 0;
     685  OrderSet = NULL;
    686686};
    687687
     
    689689 */
    690690KeySetsContainer::~KeySetsContainer() {
    691         for(int i=FragmentCounter;i--;)
    692                 Free((void **)&KeySets[i], "KeySetsContainer::~KeySetsContainer: *KeySets[]");
    693         for(int i=Order;i--;)
    694                 Free((void **)&OrderSet[i], "KeySetsContainer::~KeySetsContainer: *OrderSet[]");
    695         Free((void **)&KeySets, "KeySetsContainer::~KeySetsContainer: **KeySets");
    696         Free((void **)&OrderSet, "KeySetsContainer::~KeySetsContainer: **OrderSet");
    697         Free((void **)&AtomCounter, "KeySetsContainer::~KeySetsContainer: *AtomCounter");
    698         Free((void **)&FragmentsPerOrder, "KeySetsContainer::~KeySetsContainer: *FragmentsPerOrder");
     691  for(int i=FragmentCounter;i--;)
     692    Free((void **)&KeySets[i], "KeySetsContainer::~KeySetsContainer: *KeySets[]");
     693  for(int i=Order;i--;)
     694    Free((void **)&OrderSet[i], "KeySetsContainer::~KeySetsContainer: *OrderSet[]");
     695  Free((void **)&KeySets, "KeySetsContainer::~KeySetsContainer: **KeySets");
     696  Free((void **)&OrderSet, "KeySetsContainer::~KeySetsContainer: **OrderSet");
     697  Free((void **)&AtomCounter, "KeySetsContainer::~KeySetsContainer: *AtomCounter");
     698  Free((void **)&FragmentsPerOrder, "KeySetsContainer::~KeySetsContainer: *FragmentsPerOrder");
    699699};
    700700
     
    706706 */
    707707bool KeySetsContainer::ParseKeySets(const char *name, const int *ACounter, const int FCounter) {
    708         ifstream input;
    709         char *FragmentNumber = NULL;
    710         stringstream file;
    711         char filename[1023];
    712 
    713         FragmentCounter = FCounter;
    714         cout << "Parsing key sets." << endl;
    715         KeySets = (int **) Malloc(sizeof(int *)*FragmentCounter, "KeySetsContainer::ParseKeySets: **KeySets");
    716         for(int i=FragmentCounter;i--;)
    717                 KeySets[i] = NULL;
    718         file << name << FRAGMENTPREFIX << KEYSETFILE;
    719         input.open(file.str().c_str(), ios::in);
    720         if (input == NULL) {
    721                 cout << endl << "Unable to open " << file.str() << ", is the directory correct?" << endl;
    722                 return false;
    723         }
    724 
    725         AtomCounter = (int *) Malloc(sizeof(int)*FragmentCounter, "KeySetsContainer::ParseKeySets: *RowCounter");
    726         for(int i=0;(i<FragmentCounter) && (!input.eof());i++) {
    727                 stringstream line;
    728                 AtomCounter[i] = ACounter[i];
    729                 // parse the values
    730                 KeySets[i] = (int *) Malloc(sizeof(int)*AtomCounter[i], "KeySetsContainer::ParseKeySets: *KeySets[]");
    731                 for(int j=AtomCounter[i];j--;)
    732                         KeySets[i][j] = -1;
    733                 FragmentNumber = FixedDigitNumber(FragmentCounter, i);
    734                 //cout << FRAGMENTPREFIX << FragmentNumber << "[" << AtomCounter[i] << "]:";
    735                 Free((void **)&FragmentNumber, "KeySetsContainer::ParseKeySets: *FragmentNumber");
    736                 input.getline(filename, 1023);
    737                 line.str(filename);
    738                 for(int j=0;(j<AtomCounter[i]) && (!line.eof());j++) {
    739                         line >> KeySets[i][j];
    740                         //cout << " " << KeySets[i][j];
    741                 }
    742                 //cout << endl;
    743         }
    744         input.close();
    745         return true;
     708  ifstream input;
     709  char *FragmentNumber = NULL;
     710  stringstream file;
     711  char filename[1023];
     712
     713  FragmentCounter = FCounter;
     714  cout << "Parsing key sets." << endl;
     715  KeySets = (int **) Malloc(sizeof(int *)*FragmentCounter, "KeySetsContainer::ParseKeySets: **KeySets");
     716  for(int i=FragmentCounter;i--;)
     717    KeySets[i] = NULL;
     718  file << name << FRAGMENTPREFIX << KEYSETFILE;
     719  input.open(file.str().c_str(), ios::in);
     720  if (input == NULL) {
     721    cout << endl << "Unable to open " << file.str() << ", is the directory correct?" << endl;
     722    return false;
     723  }
     724
     725  AtomCounter = (int *) Malloc(sizeof(int)*FragmentCounter, "KeySetsContainer::ParseKeySets: *RowCounter");
     726  for(int i=0;(i<FragmentCounter) && (!input.eof());i++) {
     727    stringstream line;
     728    AtomCounter[i] = ACounter[i];
     729    // parse the values
     730    KeySets[i] = (int *) Malloc(sizeof(int)*AtomCounter[i], "KeySetsContainer::ParseKeySets: *KeySets[]");
     731    for(int j=AtomCounter[i];j--;)
     732      KeySets[i][j] = -1;
     733    FragmentNumber = FixedDigitNumber(FragmentCounter, i);
     734    //cout << FRAGMENTPREFIX << FragmentNumber << "[" << AtomCounter[i] << "]:";
     735    Free((void **)&FragmentNumber, "KeySetsContainer::ParseKeySets: *FragmentNumber");
     736    input.getline(filename, 1023);
     737    line.str(filename);
     738    for(int j=0;(j<AtomCounter[i]) && (!line.eof());j++) {
     739      line >> KeySets[i][j];
     740      //cout << " " << KeySets[i][j];
     741    }
     742    //cout << endl;
     743  }
     744  input.close();
     745  return true;
    746746};
    747747
     
    751751bool KeySetsContainer::ParseManyBodyTerms()
    752752{
    753         int Counter;
    754 
    755         cout << "Creating Fragment terms." << endl;
    756         // scan through all to determine maximum order
    757         Order=0;
    758         for(int i=FragmentCounter;i--;) {
    759                 Counter=0;
    760                 for(int j=AtomCounter[i];j--;)
    761                         if (KeySets[i][j] != -1)
    762                                 Counter++;
    763                 if (Counter > Order)
    764                         Order = Counter;
    765         }
    766         cout << "Found Order is " << Order << "." << endl;
    767 
    768         // scan through all to determine fragments per order
    769         FragmentsPerOrder = (int *) Malloc(sizeof(int)*Order, "KeySetsContainer::ParseManyBodyTerms: *FragmentsPerOrder");
    770         for(int i=Order;i--;)
    771                 FragmentsPerOrder[i] = 0;
    772         for(int i=FragmentCounter;i--;) {
    773                 Counter=0;
    774                 for(int j=AtomCounter[i];j--;)
    775                         if (KeySets[i][j] != -1)
    776                                 Counter++;
    777                 FragmentsPerOrder[Counter-1]++;
    778         }
    779         for(int i=0;i<Order;i++)
    780                 cout << "Found No. of Fragments of Order " << i+1 << " is " << FragmentsPerOrder[i] << "." << endl;
    781 
    782         // scan through all to gather indices to each order set
    783         OrderSet = (int **) Malloc(sizeof(int *)*Order, "KeySetsContainer::ParseManyBodyTerms: **OrderSet");
    784         for(int i=Order;i--;)
    785                 OrderSet[i] = (int *) Malloc(sizeof(int)*FragmentsPerOrder[i], "KeySetsContainer::ParseManyBodyTermsKeySetsContainer::ParseManyBodyTerms: *OrderSet[]");
    786         for(int i=Order;i--;)
    787                 FragmentsPerOrder[i] = 0;
    788         for(int i=FragmentCounter;i--;) {
    789                 Counter=0;
    790                 for(int j=AtomCounter[i];j--;)
    791                         if (KeySets[i][j] != -1)
    792                                 Counter++;
    793                 OrderSet[Counter-1][FragmentsPerOrder[Counter-1]] = i;
    794                 FragmentsPerOrder[Counter-1]++;
    795         }
    796         cout << "Printing OrderSet." << endl;
    797         for(int i=0;i<Order;i++) {
    798                 for (int j=0;j<FragmentsPerOrder[i];j++) {
    799                         cout << " " << OrderSet[i][j];
    800                 }
    801                 cout << endl;
    802         }
    803         cout << endl;
    804 
    805 
    806         return true;
     753  int Counter;
     754
     755  cout << "Creating Fragment terms." << endl;
     756  // scan through all to determine maximum order
     757  Order=0;
     758  for(int i=FragmentCounter;i--;) {
     759    Counter=0;
     760    for(int j=AtomCounter[i];j--;)
     761      if (KeySets[i][j] != -1)
     762        Counter++;
     763    if (Counter > Order)
     764      Order = Counter;
     765  }
     766  cout << "Found Order is " << Order << "." << endl;
     767
     768  // scan through all to determine fragments per order
     769  FragmentsPerOrder = (int *) Malloc(sizeof(int)*Order, "KeySetsContainer::ParseManyBodyTerms: *FragmentsPerOrder");
     770  for(int i=Order;i--;)
     771    FragmentsPerOrder[i] = 0;
     772  for(int i=FragmentCounter;i--;) {
     773    Counter=0;
     774    for(int j=AtomCounter[i];j--;)
     775      if (KeySets[i][j] != -1)
     776        Counter++;
     777    FragmentsPerOrder[Counter-1]++;
     778  }
     779  for(int i=0;i<Order;i++)
     780    cout << "Found No. of Fragments of Order " << i+1 << " is " << FragmentsPerOrder[i] << "." << endl;
     781
     782  // scan through all to gather indices to each order set
     783  OrderSet = (int **) Malloc(sizeof(int *)*Order, "KeySetsContainer::ParseManyBodyTerms: **OrderSet");
     784  for(int i=Order;i--;)
     785    OrderSet[i] = (int *) Malloc(sizeof(int)*FragmentsPerOrder[i], "KeySetsContainer::ParseManyBodyTermsKeySetsContainer::ParseManyBodyTerms: *OrderSet[]");
     786  for(int i=Order;i--;)
     787    FragmentsPerOrder[i] = 0;
     788  for(int i=FragmentCounter;i--;) {
     789    Counter=0;
     790    for(int j=AtomCounter[i];j--;)
     791      if (KeySets[i][j] != -1)
     792        Counter++;
     793    OrderSet[Counter-1][FragmentsPerOrder[Counter-1]] = i;
     794    FragmentsPerOrder[Counter-1]++;
     795  }
     796  cout << "Printing OrderSet." << endl;
     797  for(int i=0;i<Order;i++) {
     798    for (int j=0;j<FragmentsPerOrder[i];j++) {
     799      cout << " " << OrderSet[i][j];
     800    }
     801    cout << endl;
     802  }
     803  cout << endl;
     804
     805
     806  return true;
    807807};
    808808
     
    814814bool KeySetsContainer::Contains(const int GreaterSet, const int SmallerSet)
    815815{
    816         bool result = true;
    817         bool intermediate;
    818         if ((GreaterSet < 0) || (SmallerSet < 0) || (GreaterSet > FragmentCounter) || (SmallerSet > FragmentCounter)) // index out of bounds
    819                 return false;
    820         for(int i=AtomCounter[SmallerSet];i--;) {
    821                 intermediate = false;
    822                 for (int j=AtomCounter[GreaterSet];j--;)
    823                         intermediate = (intermediate || ((KeySets[SmallerSet][i] == KeySets[GreaterSet][j]) || (KeySets[SmallerSet][i] == -1)));
    824                 result = result && intermediate;
    825         }
    826 
    827         return result;
     816  bool result = true;
     817  bool intermediate;
     818  if ((GreaterSet < 0) || (SmallerSet < 0) || (GreaterSet > FragmentCounter) || (SmallerSet > FragmentCounter)) // index out of bounds
     819    return false;
     820  for(int i=AtomCounter[SmallerSet];i--;) {
     821    intermediate = false;
     822    for (int j=AtomCounter[GreaterSet];j--;)
     823      intermediate = (intermediate || ((KeySets[SmallerSet][i] == KeySets[GreaterSet][j]) || (KeySets[SmallerSet][i] == -1)));
     824    result = result && intermediate;
     825  }
     826
     827  return result;
    828828};
    829829
  • src/parser.hpp

    r205ccd r042f82  
    4040
    4141class MatrixContainer {
    42         public:
    43                 double ***Matrix;
    44                 int **Indices;
    45                 char *Header;
    46                 int MatrixCounter;
    47                 int *RowCounter;
    48                 int ColumnCounter;
     42  public:
     43    double ***Matrix;
     44    int **Indices;
     45    char *Header;
     46    int MatrixCounter;
     47    int *RowCounter;
     48    int ColumnCounter;
    4949
    50         MatrixContainer();
    51         virtual ~MatrixContainer();
     50  MatrixContainer();
     51  virtual ~MatrixContainer();
    5252
    53         bool ParseMatrix(const char *name, int skiplines, int skipcolumns, int MatrixNr);
    54         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);
    56         bool ResetMatrix();
    57         double FindMinValue();
    58         double FindMaxValue();
    59         bool SetLastMatrix(double value, int skipcolumns);
    60         bool SetLastMatrix(double **values, int skipcolumns);
    61         //bool ParseIndices();
    62         //bool SumSubValues();
    63         bool SumSubManyBodyTerms(class MatrixContainer &Matrix, class KeySetsContainer &KeySet, int Order);
    64         bool WriteTotalFragments(const char *name, const char *prefix);
    65         bool WriteLastMatrix(const char *name, const char *prefix, const char *suffix);
     53  bool ParseMatrix(const char *name, int skiplines, int skipcolumns, int MatrixNr);
     54  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);
     56  bool ResetMatrix();
     57  double FindMinValue();
     58  double FindMaxValue();
     59  bool SetLastMatrix(double value, int skipcolumns);
     60  bool SetLastMatrix(double **values, int skipcolumns);
     61  //bool ParseIndices();
     62  //bool SumSubValues();
     63  bool SumSubManyBodyTerms(class MatrixContainer &Matrix, class KeySetsContainer &KeySet, int Order);
     64  bool WriteTotalFragments(const char *name, const char *prefix);
     65  bool WriteLastMatrix(const char *name, const char *prefix, const char *suffix);
    6666};
    6767
     
    6969
    7070class EnergyMatrix : public MatrixContainer {
    71         public:
    72                 bool ParseIndices();
    73                 bool SumSubEnergy(class EnergyMatrix &Fragments, class EnergyMatrix *CorrectionFragments, class KeySetsContainer &KeySet, int Order, double sign);
    74                 bool ParseFragmentMatrix(const char *name, const char *prefix, string suffix, int skiplines, int skipcolumns);
     71  public:
     72    bool ParseIndices();
     73    bool SumSubEnergy(class EnergyMatrix &Fragments, class EnergyMatrix *CorrectionFragments, class KeySetsContainer &KeySet, int Order, double sign);
     74    bool ParseFragmentMatrix(const char *name, const char *prefix, string suffix, int skiplines, int skipcolumns);
    7575};
    7676
     
    7878
    7979class ForceMatrix : public MatrixContainer {
    80         public:
    81                 bool ParseIndices(const char *name);
    82                 bool SumSubForces(class ForceMatrix &Fragments, class KeySetsContainer &KeySet, int Order, double sign);
    83                 bool ParseFragmentMatrix(const char *name, const char *prefix, string suffix, int skiplines, int skipcolumns);
     80  public:
     81    bool ParseIndices(const char *name);
     82    bool SumSubForces(class ForceMatrix &Fragments, class KeySetsContainer &KeySet, int Order, double sign);
     83    bool ParseFragmentMatrix(const char *name, const char *prefix, string suffix, int skiplines, int skipcolumns);
    8484};
    8585
     
    8787
    8888class KeySetsContainer {
    89         public:
    90                 int **KeySets;
    91                 int *AtomCounter;
    92                 int FragmentCounter;
    93                 int Order;
    94                 int *FragmentsPerOrder;
    95                 int **OrderSet;
     89  public:
     90    int **KeySets;
     91    int *AtomCounter;
     92    int FragmentCounter;
     93    int Order;
     94    int *FragmentsPerOrder;
     95    int **OrderSet;
    9696
    97         KeySetsContainer();
    98         ~KeySetsContainer();
     97  KeySetsContainer();
     98  ~KeySetsContainer();
    9999
    100         bool ParseKeySets(const char *name, const int *ACounter, const int FCounter);
    101         bool ParseManyBodyTerms();
    102         bool Contains(const int GreaterSet, const int SmallerSet);
     100  bool ParseKeySets(const char *name, const int *ACounter, const int FCounter);
     101  bool ParseManyBodyTerms();
     102  bool Contains(const int GreaterSet, const int SmallerSet);
    103103};
    104104
  • src/periodentafel.cpp

    r205ccd r042f82  
    1616periodentafel::periodentafel()
    1717{
    18         start = new element;
    19         end = new element;
    20         start->previous = NULL;
    21         start->next = end;
    22         end->previous = start;
    23         end->next = NULL;
     18  start = new element;
     19  end = new element;
     20  start->previous = NULL;
     21  start->next = end;
     22  end->previous = start;
     23  end->next = NULL;
    2424};
    2525
     
    2929periodentafel::~periodentafel()
    3030{
    31         CleanupPeriodtable();
    32         delete(end);
    33         delete(start);
     31  CleanupPeriodtable();
     32  delete(end);
     33  delete(start);
    3434};
    3535
     
    4040bool periodentafel::AddElement(element *pointer)
    4141{
    42         pointer->sort = &pointer->Z;
    43         if (pointer->Z < 1 && pointer->Z >= MAX_ELEMENTS)
    44                 cout << Verbose(0) << "Invalid Z number!\n";
    45         return add(pointer, end);
     42  pointer->sort = &pointer->Z;
     43  if (pointer->Z < 1 && pointer->Z >= MAX_ELEMENTS)
     44    cout << Verbose(0) << "Invalid Z number!\n";
     45  return add(pointer, end);
    4646};
    4747
     
    5252bool periodentafel::RemoveElement(element *pointer)
    5353{
    54         return remove(pointer, start, end);
     54  return remove(pointer, start, end);
    5555};
    5656
     
    6060bool periodentafel::CleanupPeriodtable()
    6161{
    62         return cleanup(start,end);
     62  return cleanup(start,end);
    6363};
    6464
     
    7070element * periodentafel::FindElement(int Z)
    7171{
    72         element *walker = find(&Z, start,end);
    73         if (walker == NULL) { // not found: enter and put into db
    74                 cout << Verbose(0) << "Element not found in database, please enter." << endl;
    75                 walker = new element;
    76                 cout << Verbose(0) << "Mass: " << endl;
    77                 cin >> walker->mass;
    78                 walker->Z = Z;
    79                 cout << Verbose(0) << "Atomic number: " << walker->Z << endl;
    80                 cout << Verbose(0) << "Name [max 64 chars]: " << endl;
    81                 cin >> walker->name;
    82                 cout << Verbose(0) << "Short form [max 3 chars]: " << endl;
    83                 cin >> walker->symbol;
    84                 periodentafel::AddElement(walker);
    85         }
    86         return(walker);
     72  element *walker = find(&Z, start,end);
     73  if (walker == NULL) { // not found: enter and put into db
     74    cout << Verbose(0) << "Element not found in database, please enter." << endl;
     75    walker = new element;
     76    cout << Verbose(0) << "Mass: " << endl;
     77    cin >> walker->mass;
     78    walker->Z = Z;
     79    cout << Verbose(0) << "Atomic number: " << walker->Z << endl;
     80    cout << Verbose(0) << "Name [max 64 chars]: " << endl;
     81    cin >> walker->name;
     82    cout << Verbose(0) << "Short form [max 3 chars]: " << endl;
     83    cin >> walker->symbol;
     84    periodentafel::AddElement(walker);
     85  }
     86  return(walker);
    8787};
    8888
     
    9494element * periodentafel::FindElement(const char *shorthand) const
    9595{
    96         element *walker =       periodentafel::start;
    97         while (walker->next != periodentafel::end) {
    98                 walker = walker->next;
    99                 if (strncmp(walker->symbol, shorthand, 3) == 0)
    100                         return(walker);
    101         }
    102         return (NULL);
     96  element *walker =  periodentafel::start;
     97  while (walker->next != periodentafel::end) {
     98    walker = walker->next;
     99    if (strncmp(walker->symbol, shorthand, 3) == 0)
     100      return(walker);
     101  }
     102  return (NULL);
    103103};
    104104
     
    107107element * periodentafel::AskElement()
    108108{
    109         element *walker = NULL;
    110         int Z;
    111         do {
    112                 cout << Verbose(0) << "Atomic number Z: ";
    113                 cin >> Z;
    114                 walker = this->FindElement(Z);  // give type
    115         } while (walker == NULL);
    116         return walker;
     109  element *walker = NULL;
     110  int Z;
     111  do {
     112    cout << Verbose(0) << "Atomic number Z: ";
     113    cin >> Z;
     114    walker = this->FindElement(Z);  // give type
     115  } while (walker == NULL);
     116  return walker;
    117117};
    118118
     
    122122bool periodentafel::Output(ofstream *output) const
    123123{
    124         bool result = true;
    125         element *walker = start;
    126         if (output != NULL) {
    127                 while (walker->next != end) {
    128                         walker = walker->next;
    129                         result = result && walker->Output(output);
    130                 }
    131                 return result;
    132         } else
    133                 return false;
     124  bool result = true;
     125  element *walker = start;
     126  if (output != NULL) {
     127    while (walker->next != end) {
     128      walker = walker->next;
     129      result = result && walker->Output(output);
     130    }
     131    return result;
     132  } else
     133    return false;
    134134};
    135135
     
    140140bool periodentafel::Checkout(ofstream *output, const int *checkliste) const
    141141{
    142         element *walker = start;
    143         bool result = true;
    144         int No = 1;
    145 
    146         if (output != NULL) {
    147                 *output << "# Ion type data (PP = PseudoPotential, Z = atomic number)" << endl;
    148                 *output << "#Ion_TypeNr.\tAmount\tZ\tRGauss\tL_Max(PP)L_Loc(PP)IonMass\t# chemical name, symbol" << endl;
    149                 while (walker->next != end) {
    150                         walker = walker->next;
    151                         if ((walker != NULL) && (walker->Z > 0) && (walker->Z < MAX_ELEMENTS) && (checkliste[walker->Z])) {
    152                                 walker->No = No;
    153                                 result = result && walker->Checkout(output, No++, checkliste[walker->Z]);
    154                         }
    155                 }
    156                 return result;
    157         } else
    158                 return false;
     142  element *walker = start;
     143  bool result = true;
     144  int No = 1;
     145
     146  if (output != NULL) {
     147    *output << "# Ion type data (PP = PseudoPotential, Z = atomic number)" << endl;
     148    *output << "#Ion_TypeNr.\tAmount\tZ\tRGauss\tL_Max(PP)L_Loc(PP)IonMass\t# chemical name, symbol" << endl;
     149    while (walker->next != end) {
     150      walker = walker->next;
     151      if ((walker != NULL) && (walker->Z > 0) && (walker->Z < MAX_ELEMENTS) && (checkliste[walker->Z])) {
     152        walker->No = No;
     153        result = result && walker->Checkout(output, No++, checkliste[walker->Z]);
     154      }
     155    }
     156    return result;
     157  } else
     158    return false;
    159159};
    160160
     
    164164bool periodentafel::LoadPeriodentafel(const char *path)
    165165{
    166         ifstream infile;
    167         double tmp;
    168         element *ptr;
    169         bool status = true;
    170         bool otherstatus = true;
    171         char filename[255];
    172 
    173         // fill elements DB
    174         strncpy(filename, path, MAXSTRINGSIZE);
    175         strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
    176         strncat(filename, STANDARDELEMENTSDB, MAXSTRINGSIZE-strlen(filename));
    177         infile.open(filename);
    178         if (infile != NULL) {
    179                 infile.getline(header1, MAXSTRINGSIZE);
    180                 infile.getline(header2, MAXSTRINGSIZE); // skip first two header lines
    181                 cout << "Parsed elements:";
    182                 while (!infile.eof()) {
    183                         element *neues = new element;
    184                         infile >> neues->name;
    185                         //infile >> ws;
    186                         infile >> neues->symbol;
    187                         //infile >> ws;
    188                         infile >> neues->period;
    189                         //infile >> ws;
    190                         infile >> neues->group;
    191                         //infile >> ws;
    192                         infile >> neues->block;
    193                         //infile >> ws;
    194                         infile >> neues->Z;
    195                         //infile >> ws;
    196                         infile >> neues->mass;
    197                         //infile >> ws;
    198                         infile >> neues->CovalentRadius;
    199                         //infile >> ws;
    200                         infile >> neues->VanDerWaalsRadius;
    201                         //infile >> ws;
    202                         infile >> ws;
    203                         cout << " " << neues->symbol;
    204                         //neues->Output((ofstream *)&cout);
    205                         if ((neues->Z > 0) && (neues->Z < MAX_ELEMENTS))
    206                                 periodentafel::AddElement(neues);
    207                         else {
    208                                 cout << "Could not parse element: ";
    209                                 neues->Output((ofstream *)&cout);
    210                         }
    211                 }
    212                 cout << endl;
    213                 infile.close();
    214                 infile.clear();
    215         } else
    216                 status = false;
    217 
    218         // fill valence DB per element
    219         strncpy(filename, path, MAXSTRINGSIZE);
    220         strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
    221         strncat(filename, STANDARDVALENCEDB, MAXSTRINGSIZE-strlen(filename));
    222         infile.open(filename);
    223         if (infile != NULL) {
    224                 while (!infile.eof()) {
    225                         infile >> tmp;
    226                         infile >> ws;
    227                         infile >> FindElement((int)tmp)->Valence;
    228                         infile >> ws;
    229                         //cout << Verbose(3) << "Element " << (int)tmp << " has " << FindElement((int)tmp)->Valence << " valence electrons." << endl;
    230                 }
    231                 infile.close();
    232                 infile.clear();
    233         } else
    234                 otherstatus = false;
    235 
    236         // fill valence DB per element
    237         strncpy(filename, path, MAXSTRINGSIZE);
    238         strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
    239         strncat(filename, STANDARDORBITALDB, MAXSTRINGSIZE-strlen(filename));
    240         infile.open(filename);
    241         if (infile != NULL) {
    242                 while (!infile.eof()) {
    243                         infile >> tmp;
    244                         infile >> ws;
    245                         infile >> FindElement((int)tmp)->NoValenceOrbitals;
    246                         infile >> ws;
    247                         //cout << Verbose(3) << "Element " << (int)tmp << " has " << FindElement((int)tmp)->NoValenceOrbitals << " number of singly occupied valence orbitals." << endl;
    248                 }
    249                 infile.close();
    250                 infile.clear();
    251         } else
    252                 otherstatus = false;
    253 
    254         // fill H-BondDistance DB per element
    255         strncpy(filename, path, MAXSTRINGSIZE);
    256         strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
    257         strncat(filename, STANDARDHBONDDISTANCEDB, MAXSTRINGSIZE-strlen(filename));
    258         infile.open(filename);
    259         if (infile != NULL) {
    260                 while (!infile.eof()) {
    261                         infile >> tmp;
    262                         ptr = FindElement((int)tmp);
    263                         infile >> ws;
    264                         infile >> ptr->HBondDistance[0];
    265                         infile >> ptr->HBondDistance[1];
    266                         infile >> ptr->HBondDistance[2];
    267                         infile >> ws;
    268                         //cout << Verbose(3) << "Element " << (int)tmp << " has " << FindElement((int)tmp)->HBondDistance[0] << " Angstrom typical distance to hydrogen." << endl;
    269                 }
    270                 infile.close();
    271                 infile.clear();
    272         } else
    273                 otherstatus = false;
    274 
    275         // fill H-BondAngle DB per element
    276         strncpy(filename, path, MAXSTRINGSIZE);
    277         strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
    278         strncat(filename, STANDARDHBONDANGLEDB, MAXSTRINGSIZE-strlen(filename));
    279         infile.open(filename);
    280         if (infile != NULL) {
    281                 while (!infile.eof()) {
    282                         infile >> tmp;
    283                         ptr = FindElement((int)tmp);
    284                         infile >> ws;
    285                         infile >> ptr->HBondAngle[0];
    286                         infile >> ptr->HBondAngle[1];
    287                         infile >> ptr->HBondAngle[2];
    288                         infile >> ws;
    289                         //cout << Verbose(3) << "Element " << (int)tmp << " has " << FindElement((int)tmp)->HBondAngle[0] << ", " << FindElement((int)tmp)->HBondAngle[1] << ", " << FindElement((int)tmp)->HBondAngle[2] << " degrees bond angle for one, two, three connected hydrogens." << endl;
    290                 }
    291                 infile.close();
    292         } else
    293                 otherstatus = false;
    294 
    295         if (!otherstatus)
    296                 cerr << "WARNING: Something went wrong while parsing the other databases!" << endl;
    297 
    298         return status;
     166  ifstream infile;
     167  double tmp;
     168  element *ptr;
     169  bool status = true;
     170  bool otherstatus = true;
     171  char filename[255];
     172
     173  // fill elements DB
     174  strncpy(filename, path, MAXSTRINGSIZE);
     175  strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
     176  strncat(filename, STANDARDELEMENTSDB, MAXSTRINGSIZE-strlen(filename));
     177  infile.open(filename);
     178  if (infile != NULL) {
     179    infile.getline(header1, MAXSTRINGSIZE);
     180    infile.getline(header2, MAXSTRINGSIZE); // skip first two header lines
     181    cout <<  "Parsed elements:";
     182    while (!infile.eof()) {
     183      element *neues = new element;
     184      infile >> neues->name;
     185      //infile >> ws;
     186      infile >> neues->symbol;
     187      //infile >> ws;
     188      infile >> neues->period;
     189      //infile >> ws;
     190      infile >> neues->group;
     191      //infile >> ws;
     192      infile >> neues->block;
     193      //infile >> ws;
     194      infile >> neues->Z;
     195      //infile >> ws;
     196      infile >> neues->mass;
     197      //infile >> ws;
     198      infile >> neues->CovalentRadius;
     199      //infile >> ws;
     200      infile >> neues->VanDerWaalsRadius;
     201      //infile >> ws;
     202      infile >> ws;
     203      cout << " " << neues->symbol;
     204      //neues->Output((ofstream *)&cout);
     205      if ((neues->Z > 0) && (neues->Z < MAX_ELEMENTS))
     206        periodentafel::AddElement(neues);
     207      else {
     208        cout << "Could not parse element: ";
     209        neues->Output((ofstream *)&cout);
     210      }
     211    }
     212    cout << endl;
     213    infile.close();
     214    infile.clear();
     215  } else
     216    status = false;
     217
     218  // fill valence DB per element
     219  strncpy(filename, path, MAXSTRINGSIZE);
     220  strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
     221  strncat(filename, STANDARDVALENCEDB, MAXSTRINGSIZE-strlen(filename));
     222  infile.open(filename);
     223  if (infile != NULL) {
     224    while (!infile.eof()) {
     225      infile >> tmp;
     226      infile >> ws;
     227      infile >> FindElement((int)tmp)->Valence;
     228      infile >> ws;
     229      //cout << Verbose(3) << "Element " << (int)tmp << " has " << FindElement((int)tmp)->Valence << " valence electrons." << endl;
     230    }
     231    infile.close();
     232    infile.clear();
     233  } else
     234    otherstatus = false;
     235
     236  // fill valence DB per element
     237  strncpy(filename, path, MAXSTRINGSIZE);
     238  strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
     239  strncat(filename, STANDARDORBITALDB, MAXSTRINGSIZE-strlen(filename));
     240  infile.open(filename);
     241  if (infile != NULL) {
     242    while (!infile.eof()) {
     243      infile >> tmp;
     244      infile >> ws;
     245      infile >> FindElement((int)tmp)->NoValenceOrbitals;
     246      infile >> ws;
     247      //cout << Verbose(3) << "Element " << (int)tmp << " has " << FindElement((int)tmp)->NoValenceOrbitals << " number of singly occupied valence orbitals." << endl;
     248    }
     249    infile.close();
     250    infile.clear();
     251  } else
     252    otherstatus = false;
     253
     254  // fill H-BondDistance DB per element
     255  strncpy(filename, path, MAXSTRINGSIZE);
     256  strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
     257  strncat(filename, STANDARDHBONDDISTANCEDB, MAXSTRINGSIZE-strlen(filename));
     258  infile.open(filename);
     259  if (infile != NULL) {
     260    while (!infile.eof()) {
     261      infile >> tmp;
     262      ptr = FindElement((int)tmp);
     263      infile >> ws;
     264      infile >> ptr->HBondDistance[0];
     265      infile >> ptr->HBondDistance[1];
     266      infile >> ptr->HBondDistance[2];
     267      infile >> ws;
     268      //cout << Verbose(3) << "Element " << (int)tmp << " has " << FindElement((int)tmp)->HBondDistance[0] << " Angstrom typical distance to hydrogen." << endl;
     269    }
     270    infile.close();
     271    infile.clear();
     272  } else
     273    otherstatus = false;
     274
     275  // fill H-BondAngle DB per element
     276  strncpy(filename, path, MAXSTRINGSIZE);
     277  strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
     278  strncat(filename, STANDARDHBONDANGLEDB, MAXSTRINGSIZE-strlen(filename));
     279  infile.open(filename);
     280  if (infile != NULL) {
     281    while (!infile.eof()) {
     282      infile >> tmp;
     283      ptr = FindElement((int)tmp);
     284      infile >> ws;
     285      infile >> ptr->HBondAngle[0];
     286      infile >> ptr->HBondAngle[1];
     287      infile >> ptr->HBondAngle[2];
     288      infile >> ws;
     289      //cout << Verbose(3) << "Element " << (int)tmp << " has " << FindElement((int)tmp)->HBondAngle[0] << ", " << FindElement((int)tmp)->HBondAngle[1] << ", " << FindElement((int)tmp)->HBondAngle[2] << " degrees bond angle for one, two, three connected hydrogens." << endl;
     290    }
     291    infile.close();
     292  } else
     293    otherstatus = false;
     294
     295  if (!otherstatus)
     296    cerr << "WARNING: Something went wrong while parsing the other databases!" << endl;
     297
     298  return status;
    299299};
    300300
     
    303303bool periodentafel::StorePeriodentafel(const char *path) const
    304304{
    305         bool result = true;
    306         ofstream f;
    307         char filename[MAXSTRINGSIZE];
    308 
    309         strncpy(filename, path, MAXSTRINGSIZE);
    310         strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
    311         strncat(filename, STANDARDELEMENTSDB, MAXSTRINGSIZE-strlen(filename));
    312         f.open(filename);
    313         if (f != NULL) {
    314                 f << header1 << endl;
    315                 f << header2 << endl;
    316                 element *walker = periodentafel::start;
    317                 while (walker->next != periodentafel::end) {
    318                         walker = walker->next;
    319                         result = result && walker->Output(&f);
    320                 }
    321                 f.close();
    322         } else
    323                 result = false;
    324         return result;
    325 };
     305  bool result = true;
     306  ofstream f;
     307  char filename[MAXSTRINGSIZE];
     308
     309  strncpy(filename, path, MAXSTRINGSIZE);
     310  strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
     311  strncat(filename, STANDARDELEMENTSDB, MAXSTRINGSIZE-strlen(filename));
     312  f.open(filename);
     313  if (f != NULL) {
     314    f << header1 << endl;
     315    f << header2 << endl;
     316    element *walker = periodentafel::start;
     317    while (walker->next != periodentafel::end) {
     318      walker = walker->next;
     319      result = result && walker->Output(&f);
     320    }
     321    f.close();
     322  } else
     323    result = false;
     324  return result;
     325};
  • src/periodentafel.hpp

    r205ccd r042f82  
    2121 */
    2222class element {
    23         public:
    24                 double mass;            //!< mass in g/mol
    25                 double CovalentRadius;  //!< covalent radius
    26                 double VanDerWaalsRadius;       //!< can-der-Waals radius
    27                 int Z;                                  //!< atomic number
    28                 char name[64];  //!< atom name, i.e. "Hydrogren"
    29                 char symbol[3]; //!< short form of the atom, i.e. "H"
    30                 char period[8];         //!< period: n quantum number
    31                 char group[8];          //!< group: l quantum number
    32                 char block[8];          //!< block: l quantum number
    33                 element *previous;      //!< previous item in list
    34                 element *next;  //!< next element in list
    35                 int *sort;                      //!< sorc criteria
    36                 int No;                          //!< number of element set on periodentafel::Output()
    37                 double Valence; //!< number of valence electrons for this element
    38                 int NoValenceOrbitals;  //!< number of valence orbitals, used for determining bond degree in molecule::CreateConnectmatrix()
    39                 double HBondDistance[NDIM]; //!< distance in Angstrom of this element to hydrogen       (for single, double and triple bonds)
    40                 double HBondAngle[NDIM];                //!< typical angle for one, two, three bonded hydrogen (in degrees)
     23  public:
     24    double mass;    //!< mass in g/mol
     25    double CovalentRadius;  //!< covalent radius
     26    double VanDerWaalsRadius;  //!< can-der-Waals radius
     27    int Z;          //!< atomic number
     28    char name[64];  //!< atom name, i.e. "Hydrogren"
     29    char symbol[3]; //!< short form of the atom, i.e. "H"
     30    char period[8];    //!< period: n quantum number
     31    char group[8];    //!< group: l quantum number
     32    char block[8];    //!< block: l quantum number
     33    element *previous;  //!< previous item in list
     34    element *next;  //!< next element in list
     35    int *sort;      //!< sorc criteria
     36    int No;        //!< number of element set on periodentafel::Output()
     37    double Valence;  //!< number of valence electrons for this element
     38    int NoValenceOrbitals;  //!< number of valence orbitals, used for determining bond degree in molecule::CreateConnectmatrix()
     39    double HBondDistance[NDIM]; //!< distance in Angstrom of this element to hydrogen  (for single, double and triple bonds)
     40    double HBondAngle[NDIM];    //!< typical angle for one, two, three bonded hydrogen (in degrees)
    4141
    42         element();
    43         ~element();
     42  element();
     43  ~element();
    4444
    45         //> print element entries to screen
    46         bool Output(ofstream *out) const;
    47         bool Checkout(ofstream *out, const int No, const int NoOfAtoms) const;
     45  //> print element entries to screen
     46  bool Output(ofstream *out) const;
     47  bool Checkout(ofstream *out, const int No, const int NoOfAtoms) const;
    4848
    49         private:
     49  private:
    5050};
    5151
     
    5353 */
    5454class periodentafel {
    55         public:
    56                 element *start; //!< start of element list
    57                 element *end;    //!< end of element list
    58                 char header1[MAXSTRINGSIZE]; //!< store first header line
    59                 char header2[MAXSTRINGSIZE]; //!< store second header line
     55  public:
     56    element *start; //!< start of element list
     57    element *end;  //!< end of element list
     58    char header1[MAXSTRINGSIZE]; //!< store first header line
     59    char header2[MAXSTRINGSIZE]; //!< store second header line
    6060
    61         periodentafel();
    62         ~periodentafel();
     61  periodentafel();
     62  ~periodentafel();
    6363
    64         bool AddElement(element *pointer);
    65         bool RemoveElement(element *pointer);
    66         bool CleanupPeriodtable();
    67         element * FindElement(int Z);
    68         element * FindElement(const char *shorthand) const;
    69         element * AskElement();
    70         bool Output(ofstream *output) const;
    71         bool Checkout(ofstream *output, const int *checkliste) const;
    72         bool LoadPeriodentafel(const char *path);
    73         bool StorePeriodentafel(const char *path) const;
     64  bool AddElement(element *pointer);
     65  bool RemoveElement(element *pointer);
     66  bool CleanupPeriodtable();
     67  element * FindElement(int Z);
     68  element * FindElement(const char *shorthand) const;
     69  element * AskElement();
     70  bool Output(ofstream *output) const;
     71  bool Checkout(ofstream *output, const int *checkliste) const;
     72  bool LoadPeriodentafel(const char *path);
     73  bool StorePeriodentafel(const char *path) const;
    7474
    75         private:
     75  private:
    7676};
    7777
  • src/stackclass.hpp

    r205ccd r042f82  
    1010 */
    1111template <typename T> class StackClass {
    12         public:
    13         StackClass<T>(int dimension);
    14         ~StackClass<T>();
    15 
    16         bool Push(T object);
    17         T PopFirst();
    18         T PopLast();
    19         bool RemoveItem(T ptr);
    20         void ClearStack();
    21         bool IsEmpty();
    22         bool IsFull();
    23         int ItemCount();
    24         void Output(ofstream *out) const;
    25         void TestImplementation(ofstream *out, T test);
    26 
    27         private:
    28                 T *StackList;    //!< the list containing the atom pointers
    29                 int EntryCount;          //!< number of entries in the stack
    30                 int CurrentLastEntry;    //!< Current last entry (newest item on stack)
    31                 int CurrentFirstEntry;  //!< Current first entry (oldest item on stack)
    32                 int NextFreeField;                      //!< Current index of next free field
     12  public:
     13  StackClass<T>(int dimension);
     14  ~StackClass<T>();
     15
     16  bool Push(T object);
     17  T PopFirst();
     18  T PopLast();
     19  bool RemoveItem(T ptr);
     20  void ClearStack();
     21  bool IsEmpty();
     22  bool IsFull();
     23  int ItemCount();
     24  void Output(ofstream *out) const;
     25  void TestImplementation(ofstream *out, T test);
     26
     27  private:
     28    T *StackList;  //!< the list containing the atom pointers
     29    int EntryCount;    //!< number of entries in the stack
     30    int CurrentLastEntry;  //!< Current last entry (newest item on stack)
     31    int CurrentFirstEntry;  //!< Current first entry (oldest item on stack)
     32    int NextFreeField;      //!< Current index of next free field
    3333};
    3434
     
    3737template <typename T> StackClass<T>::StackClass(int dimension)
    3838{
    39         CurrentLastEntry = 0;
    40         CurrentFirstEntry = 0;
    41         NextFreeField = 0;
    42         EntryCount = dimension;
    43         StackList = (T *) Malloc(sizeof(T)*EntryCount, "StackClass::StackClass: **StackList");
     39  CurrentLastEntry = 0;
     40  CurrentFirstEntry = 0;
     41  NextFreeField = 0;
     42  EntryCount = dimension;
     43  StackList = (T *) Malloc(sizeof(T)*EntryCount, "StackClass::StackClass: **StackList");
    4444};
    4545
     
    4848template <typename T> StackClass<T>::~StackClass()
    4949{
    50         Free((void **)&StackList, "StackClass::StackClass: **StackList");
     50  Free((void **)&StackList, "StackClass::StackClass: **StackList");
    5151};
    5252
     
    5757template <typename T> bool StackClass<T>::Push(T object)
    5858{
    59         if (!IsFull()) {                // check whether free field is really not occupied
    60                 StackList[NextFreeField] = object;
    61                 CurrentLastEntry = NextFreeField;
    62                 NextFreeField = (NextFreeField + 1) % EntryCount; // step on to next free field
    63                 return true;
    64         } else {
    65                 cerr << "ERROR: Stack is full, " << "Stack: CurrentLastEntry " << CurrentLastEntry<< "\tCurrentFirstEntry " << CurrentFirstEntry << "\tNextFreeField " << NextFreeField << "\tEntryCount " << EntryCount << "!" << endl;
    66                 return false;
    67         }
     59  if (!IsFull()) {    // check whether free field is really not occupied
     60    StackList[NextFreeField] = object;
     61    CurrentLastEntry = NextFreeField;
     62    NextFreeField = (NextFreeField + 1) % EntryCount; // step on to next free field
     63    return true;
     64  } else {
     65    cerr << "ERROR: Stack is full, " << "Stack: CurrentLastEntry " << CurrentLastEntry<< "\tCurrentFirstEntry " << CurrentFirstEntry << "\tNextFreeField " << NextFreeField << "\tEntryCount " << EntryCount << "!" << endl;
     66    return false;
     67  }
    6868};
    6969
     
    7474template <typename T> T StackClass<T>::PopFirst()
    7575{
    76         T Walker = NULL;
    77         if (!IsEmpty()) {
    78                 Walker = StackList[CurrentFirstEntry];
    79                 if (Walker == NULL)
    80                         cerr << "ERROR: Stack's field is empty!" << endl;
    81                 StackList[CurrentFirstEntry] = NULL;
    82                 if (CurrentFirstEntry != CurrentLastEntry) { // hasn't last item been popped as well?
    83                         CurrentFirstEntry = (CurrentFirstEntry + 1) % EntryCount; // step back from current free field to last used (somehow modulo does not work in -1)
    84                 } else {
    85                         CurrentFirstEntry = (CurrentFirstEntry + 1) % EntryCount; // step back from current free field to last used (somehow modulo does not work in -1)
    86                         CurrentLastEntry = CurrentFirstEntry;
    87                 }
    88         } else
    89                 cerr << "ERROR: Stack is empty!" << endl;
    90         return Walker;
     76  T Walker = NULL;
     77  if (!IsEmpty()) {
     78    Walker = StackList[CurrentFirstEntry];
     79    if (Walker == NULL)
     80      cerr << "ERROR: Stack's field is empty!" << endl;
     81    StackList[CurrentFirstEntry] = NULL;
     82    if (CurrentFirstEntry != CurrentLastEntry) { // hasn't last item been popped as well?
     83      CurrentFirstEntry = (CurrentFirstEntry + 1) % EntryCount; // step back from current free field to last used (somehow modulo does not work in -1)
     84    } else {
     85      CurrentFirstEntry = (CurrentFirstEntry + 1) % EntryCount; // step back from current free field to last used (somehow modulo does not work in -1)
     86      CurrentLastEntry = CurrentFirstEntry;
     87    }
     88  } else
     89    cerr << "ERROR: Stack is empty!" << endl;
     90  return Walker;
    9191};
    9292
     
    9797template <typename T> T StackClass<T>::PopLast()
    9898{
    99         T Walker = NULL;
    100         if (!IsEmpty()) {
    101                 Walker = StackList[CurrentLastEntry];
    102                 StackList[CurrentLastEntry] = NULL;
    103                 if (Walker == NULL)
    104                         cerr << "ERROR: Stack's field is empty!" << endl;
    105                 NextFreeField = CurrentLastEntry;
    106                 if (CurrentLastEntry != CurrentFirstEntry)      // has there been more than one item on stack
    107                         CurrentLastEntry = (CurrentLastEntry + (EntryCount-1)) % EntryCount; // step back from current free field to last (modulo does not work in -1, thus go EntryCount-1 instead)
    108         } else {
    109                 cerr << "ERROR: Stack is empty!" << endl;
    110         }
    111         return Walker;
     99  T Walker = NULL;
     100  if (!IsEmpty()) {
     101    Walker = StackList[CurrentLastEntry];
     102    StackList[CurrentLastEntry] = NULL;
     103    if (Walker == NULL)
     104      cerr << "ERROR: Stack's field is empty!" << endl;
     105    NextFreeField = CurrentLastEntry;
     106    if (CurrentLastEntry != CurrentFirstEntry)  // has there been more than one item on stack
     107      CurrentLastEntry = (CurrentLastEntry + (EntryCount-1)) % EntryCount; // step back from current free field to last (modulo does not work in -1, thus go EntryCount-1 instead)
     108  } else {
     109    cerr << "ERROR: Stack is empty!" << endl;
     110  }
     111  return Walker;
    112112};
    113113
     
    120120template <typename T> bool StackClass<T>::RemoveItem(T ptr)
    121121{
    122         bool found = false;
    123         cout << Verbose(5) << "First " << CurrentFirstEntry<< "\tLast " << CurrentLastEntry<< "\tNext " << NextFreeField<< "\tCount " << EntryCount<< "." << endl;
    124         int i=CurrentFirstEntry;
    125         if (!IsEmpty())
    126                 do {
    127                         if (StackList[i] == ptr) {      // if item found, remove
    128                                 cout << Verbose(5) << "Item " << *ptr << " was number " << i << " on stack, removing it." << endl;
    129                                 found = true;
    130                                 StackList[i] = NULL;
    131                         }
    132                         if ((found) && (StackList[i] != NULL)) {        // means we have to shift (and not the removed item)
    133                                 if (i == 0) { // we are down to first item in stack, have to put onto last item
    134                                         cout << Verbose(5) << "Shifting item 0 to place " << EntryCount-1 << "." << endl;
    135                                         StackList[EntryCount-1] = StackList[0];
    136                                 } else {
    137                                         cout << Verbose(5) << "Shifting item " << i << " to place " << i-1 << "." << endl;
    138                                         StackList[i-1] = StackList[i];
    139                                 }
    140                         }
    141                         i=((i + 1) % EntryCount); // step on
    142                 } while (i!=NextFreeField);
    143         else
    144                 cerr << "ERROR: Stack is already empty!" << endl;
    145         if (found) {
    146                 NextFreeField = CurrentLastEntry;
    147                 if (CurrentLastEntry != CurrentFirstEntry)      // has there been more than one item on stack
    148                         CurrentLastEntry = (CurrentLastEntry + (EntryCount-1)) % EntryCount;
    149         }
    150         return found;
     122  bool found = false;
     123  cout << Verbose(5) << "First " << CurrentFirstEntry<< "\tLast " << CurrentLastEntry<< "\tNext " << NextFreeField<< "\tCount " << EntryCount<< "." << endl;
     124  int i=CurrentFirstEntry;
     125  if (!IsEmpty())
     126    do {
     127      if (StackList[i] == ptr) {  // if item found, remove
     128        cout << Verbose(5) << "Item " << *ptr << " was number " << i << " on stack, removing it." << endl;
     129        found = true;
     130        StackList[i] = NULL;
     131      }
     132      if ((found) && (StackList[i] != NULL)) {  // means we have to shift (and not the removed item)
     133        if (i == 0) { // we are down to first item in stack, have to put onto last item
     134          cout << Verbose(5) << "Shifting item 0 to place " << EntryCount-1 << "." << endl;
     135          StackList[EntryCount-1] = StackList[0];
     136        } else {
     137          cout << Verbose(5) << "Shifting item " << i << " to place " << i-1 << "." << endl;
     138          StackList[i-1] = StackList[i];
     139        }
     140      }
     141      i=((i + 1) % EntryCount); // step on
     142    } while (i!=NextFreeField);
     143  else
     144    cerr << "ERROR: Stack is already empty!" << endl;
     145  if (found) {
     146    NextFreeField = CurrentLastEntry;
     147    if (CurrentLastEntry != CurrentFirstEntry)  // has there been more than one item on stack
     148      CurrentLastEntry = (CurrentLastEntry + (EntryCount-1)) % EntryCount;
     149  }
     150  return found;
    151151};
    152152
     
    158158template <typename T> void StackClass<T>::TestImplementation(ofstream *out, T test)
    159159{
    160         T Walker = test;
    161         *out << Verbose(1) << "Testing the snake stack..." << endl;
    162         for (int i=0;i<EntryCount;i++) {
    163                 *out << Verbose(2) << "Filling " << i << "th element of stack." << endl;
    164                 Push(Walker);
    165                 Walker=Walker->next;
    166         }
    167         *out << endl;
    168         Output(out);
    169         if (IsFull())
    170                 *out << "Stack is full as supposed to be!" << endl;
    171         else
    172                 *out << "ERROR: Stack is not as full as supposed to be!" << endl;
    173         //if (StackList[(EntryCount+1)/2] != NULL) {
    174                 *out << "Removing element in the middle ..." << endl;
    175                 RemoveItem(StackList[(EntryCount+1)/2]);
    176                 Output(out);
    177         //}
    178         //if (StackList[CurrentFirstEntry] != NULL) {
    179                 *out << "Removing first element ..." << endl;
    180                 RemoveItem(StackList[CurrentFirstEntry]);
    181                 Output(out);
    182         //}
    183         //if (StackList[CurrentLastEntry] != NULL) {
    184                 *out << "Removing last element ..." << endl;
    185                 RemoveItem(StackList[CurrentLastEntry]);
    186                 Output(out);
    187         //}
    188         *out << "Clearing stack ... " << endl;
    189         ClearStack();
    190         Output(out);
    191         if (IsEmpty())
    192                 *out << "Stack is empty as supposed to be!" << endl;
    193         else
    194                 *out << "ERROR: Stack is not as empty as supposed to be!" << endl;
    195         *out << "done." << endl;
     160  T Walker = test;
     161  *out << Verbose(1) << "Testing the snake stack..." << endl;
     162  for (int i=0;i<EntryCount;i++) {
     163    *out << Verbose(2) << "Filling " << i << "th element of stack." << endl;
     164    Push(Walker);
     165    Walker=Walker->next;
     166  }
     167  *out << endl;
     168  Output(out);
     169  if (IsFull())
     170    *out << "Stack is full as supposed to be!" << endl;
     171  else
     172    *out << "ERROR: Stack is not as full as supposed to be!" << endl;
     173  //if (StackList[(EntryCount+1)/2] != NULL) {
     174    *out << "Removing element in the middle ..." << endl;
     175    RemoveItem(StackList[(EntryCount+1)/2]);
     176    Output(out);
     177  //}
     178  //if (StackList[CurrentFirstEntry] != NULL) {
     179    *out << "Removing first element  ..." << endl;
     180    RemoveItem(StackList[CurrentFirstEntry]);
     181    Output(out);
     182  //}
     183  //if (StackList[CurrentLastEntry] != NULL) {
     184    *out << "Removing last element ..." << endl;
     185    RemoveItem(StackList[CurrentLastEntry]);
     186    Output(out);
     187  //}
     188  *out << "Clearing stack ... " << endl;
     189  ClearStack();
     190  Output(out);
     191  if (IsEmpty())
     192    *out << "Stack is empty as supposed to be!" << endl;
     193  else
     194    *out << "ERROR: Stack is not as empty as supposed to be!" << endl;
     195  *out << "done." << endl;
    196196};
    197197
     
    201201template <typename T> void StackClass<T>::Output(ofstream *out) const
    202202{
    203         *out << "Contents of Stack: ";
    204         for(int i=0;i<EntryCount;i++) {
    205                 *out << "\t";
    206                 if (i == CurrentFirstEntry)
    207                         *out << " 1";
    208                 if      (i == CurrentLastEntry)
    209                         *out << " "<< EntryCount;
    210                 if (i ==        NextFreeField)
    211                         *out << " F";
    212                 *out << ": " << StackList[i];
    213         }
    214         *out << endl;
     203  *out << "Contents of Stack: ";
     204  for(int i=0;i<EntryCount;i++) {
     205    *out << "\t";
     206    if (i == CurrentFirstEntry)
     207      *out << " 1";
     208    if  (i == CurrentLastEntry)
     209      *out << " "<< EntryCount;
     210    if (i ==  NextFreeField)
     211      *out << " F";
     212    *out << ": " << StackList[i];
     213  }
     214  *out << endl;
    215215};
    216216
     
    222222template <typename T> bool StackClass<T>::IsEmpty()
    223223{
    224         return((NextFreeField == CurrentFirstEntry) && (CurrentLastEntry == CurrentFirstEntry));
     224  return((NextFreeField == CurrentFirstEntry) && (CurrentLastEntry == CurrentFirstEntry));
    225225};
    226226
     
    232232template <typename T> bool StackClass<T>::IsFull()
    233233{
    234         return((NextFreeField == CurrentFirstEntry) && (CurrentLastEntry != CurrentFirstEntry));
     234  return((NextFreeField == CurrentFirstEntry) && (CurrentLastEntry != CurrentFirstEntry));
    235235};
    236236
     
    242242template <typename T> int StackClass<T>::ItemCount()
    243243{
    244         //cout << "Stack: CurrentLastEntry " << CurrentLastEntry<< "\tCurrentFirstEntry " << CurrentFirstEntry << "\tEntryCount " << EntryCount << "." << endl;
    245         return((NextFreeField + (EntryCount - CurrentFirstEntry)) % EntryCount);
     244  //cout << "Stack: CurrentLastEntry " << CurrentLastEntry<< "\tCurrentFirstEntry " << CurrentFirstEntry << "\tEntryCount " << EntryCount << "." << endl;
     245  return((NextFreeField + (EntryCount - CurrentFirstEntry)) % EntryCount);
    246246};
    247247
     
    251251template <typename T> void StackClass<T>::ClearStack()
    252252{
    253         for(int i=EntryCount; i--;)
    254                 StackList[i] = NULL;
    255         CurrentFirstEntry = 0;
    256         CurrentLastEntry = 0;
    257         NextFreeField = 0;
     253  for(int i=EntryCount; i--;)
     254    StackList[i] = NULL;
     255  CurrentFirstEntry = 0;
     256  CurrentLastEntry = 0;
     257  NextFreeField = 0;
    258258};
    259259
  • src/vector.cpp

    r205ccd r042f82  
    2828double Vector::DistanceSquared(const Vector *y) const
    2929{
    30         double res = 0.;
    31         for (int i=NDIM;i--;)
    32                 res += (x[i]-y->x[i])*(x[i]-y->x[i]);
    33         return (res);
     30  double res = 0.;
     31  for (int i=NDIM;i--;)
     32    res += (x[i]-y->x[i])*(x[i]-y->x[i]);
     33  return (res);
    3434};
    3535
     
    4040double Vector::Distance(const Vector *y) const
    4141{
    42         double res = 0.;
    43         for (int i=NDIM;i--;)
    44                 res += (x[i]-y->x[i])*(x[i]-y->x[i]);
    45         return (sqrt(res));
     42  double res = 0.;
     43  for (int i=NDIM;i--;)
     44    res += (x[i]-y->x[i])*(x[i]-y->x[i]);
     45  return (sqrt(res));
    4646};
    4747
     
    5353double Vector::PeriodicDistance(const Vector *y, const double *cell_size) const
    5454{
    55         double res = Distance(y), tmp, matrix[NDIM*NDIM];
    56         Vector Shiftedy, TranslationVector;
    57         int N[NDIM];
    58         matrix[0] = cell_size[0];
    59         matrix[1] = cell_size[1];
    60         matrix[2] = cell_size[3];
    61         matrix[3] = cell_size[1];
    62         matrix[4] = cell_size[2];
    63         matrix[5] = cell_size[4];
    64         matrix[6] = cell_size[3];
    65         matrix[7] = cell_size[4];
    66         matrix[8] = cell_size[5];
    67         // in order to check the periodic distance, translate one of the vectors into each of the 27 neighbouring cells
    68         for (N[0]=-1;N[0]<=1;N[0]++)
    69                 for (N[1]=-1;N[1]<=1;N[1]++)
    70                         for (N[2]=-1;N[2]<=1;N[2]++) {
    71                                 // create the translation vector
    72                                 TranslationVector.Zero();
    73                                 for (int i=NDIM;i--;)
    74                                         TranslationVector.x[i] = (double)N[i];
    75                                 TranslationVector.MatrixMultiplication(matrix);
    76                                 // add onto the original vector to compare with
    77                                 Shiftedy.CopyVector(y);
    78                                 Shiftedy.AddVector(&TranslationVector);
    79                                 // get distance and compare with minimum so far
    80                                 tmp = Distance(&Shiftedy);
    81                                 if (tmp < res) res = tmp;
    82                         }
    83         return (res);
     55  double res = Distance(y), tmp, matrix[NDIM*NDIM];
     56  Vector Shiftedy, TranslationVector;
     57  int N[NDIM];
     58  matrix[0] = cell_size[0];
     59  matrix[1] = cell_size[1];
     60  matrix[2] = cell_size[3];
     61  matrix[3] = cell_size[1];
     62  matrix[4] = cell_size[2];
     63  matrix[5] = cell_size[4];
     64  matrix[6] = cell_size[3];
     65  matrix[7] = cell_size[4];
     66  matrix[8] = cell_size[5];
     67  // in order to check the periodic distance, translate one of the vectors into each of the 27 neighbouring cells
     68  for (N[0]=-1;N[0]<=1;N[0]++)
     69    for (N[1]=-1;N[1]<=1;N[1]++)
     70      for (N[2]=-1;N[2]<=1;N[2]++) {
     71        // create the translation vector
     72        TranslationVector.Zero();
     73        for (int i=NDIM;i--;)
     74          TranslationVector.x[i] = (double)N[i];
     75        TranslationVector.MatrixMultiplication(matrix);
     76        // add onto the original vector to compare with
     77        Shiftedy.CopyVector(y);
     78        Shiftedy.AddVector(&TranslationVector);
     79        // get distance and compare with minimum so far
     80        tmp = Distance(&Shiftedy);
     81        if (tmp < res) res = tmp;
     82      }
     83  return (res);
    8484};
    8585
     
    9191double Vector::PeriodicDistanceSquared(const Vector *y, const double *cell_size) const
    9292{
    93         double res = DistanceSquared(y), tmp, matrix[NDIM*NDIM];
    94         Vector Shiftedy, TranslationVector;
    95         int N[NDIM];
    96         matrix[0] = cell_size[0];
    97         matrix[1] = cell_size[1];
    98         matrix[2] = cell_size[3];
    99         matrix[3] = cell_size[1];
    100         matrix[4] = cell_size[2];
    101         matrix[5] = cell_size[4];
    102         matrix[6] = cell_size[3];
    103         matrix[7] = cell_size[4];
    104         matrix[8] = cell_size[5];
    105         // in order to check the periodic distance, translate one of the vectors into each of the 27 neighbouring cells
    106         for (N[0]=-1;N[0]<=1;N[0]++)
    107                 for (N[1]=-1;N[1]<=1;N[1]++)
    108                         for (N[2]=-1;N[2]<=1;N[2]++) {
    109                                 // create the translation vector
    110                                 TranslationVector.Zero();
    111                                 for (int i=NDIM;i--;)
    112                                         TranslationVector.x[i] = (double)N[i];
    113                                 TranslationVector.MatrixMultiplication(matrix);
    114                                 // add onto the original vector to compare with
    115                                 Shiftedy.CopyVector(y);
    116                                 Shiftedy.AddVector(&TranslationVector);
    117                                 // get distance and compare with minimum so far
    118                                 tmp = DistanceSquared(&Shiftedy);
    119                                 if (tmp < res) res = tmp;
    120                         }
    121         return (res);
     93  double res = DistanceSquared(y), tmp, matrix[NDIM*NDIM];
     94  Vector Shiftedy, TranslationVector;
     95  int N[NDIM];
     96  matrix[0] = cell_size[0];
     97  matrix[1] = cell_size[1];
     98  matrix[2] = cell_size[3];
     99  matrix[3] = cell_size[1];
     100  matrix[4] = cell_size[2];
     101  matrix[5] = cell_size[4];
     102  matrix[6] = cell_size[3];
     103  matrix[7] = cell_size[4];
     104  matrix[8] = cell_size[5];
     105  // in order to check the periodic distance, translate one of the vectors into each of the 27 neighbouring cells
     106  for (N[0]=-1;N[0]<=1;N[0]++)
     107    for (N[1]=-1;N[1]<=1;N[1]++)
     108      for (N[2]=-1;N[2]<=1;N[2]++) {
     109        // create the translation vector
     110        TranslationVector.Zero();
     111        for (int i=NDIM;i--;)
     112          TranslationVector.x[i] = (double)N[i];
     113        TranslationVector.MatrixMultiplication(matrix);
     114        // add onto the original vector to compare with
     115        Shiftedy.CopyVector(y);
     116        Shiftedy.AddVector(&TranslationVector);
     117        // get distance and compare with minimum so far
     118        tmp = DistanceSquared(&Shiftedy);
     119        if (tmp < res) res = tmp;
     120      }
     121  return (res);
    122122};
    123123
     
    128128void Vector::KeepPeriodic(ofstream *out, double *matrix)
    129129{
    130 //      int N[NDIM];
    131 //      bool flag = false;
    132         //vector Shifted, TranslationVector;
    133         Vector TestVector;
    134 //      *out << Verbose(1) << "Begin of KeepPeriodic." << endl;
    135 //      *out << Verbose(2) << "Vector is: ";
    136 //      Output(out);
    137 //      *out << endl;
    138         TestVector.CopyVector(this);
    139         TestVector.InverseMatrixMultiplication(matrix);
    140         for(int i=NDIM;i--;) { // correct periodically
    141                 if (TestVector.x[i] < 0) {      // get every coefficient into the interval [0,1)
    142                         TestVector.x[i] += ceil(TestVector.x[i]);
    143                 } else {
    144                         TestVector.x[i] -= floor(TestVector.x[i]);
    145                 }
    146         }
    147         TestVector.MatrixMultiplication(matrix);
    148         CopyVector(&TestVector);
    149 //      *out << Verbose(2) << "New corrected vector is: ";
    150 //      Output(out);
    151 //      *out << endl;
    152 //      *out << Verbose(1) << "End of KeepPeriodic." << endl;
     130//  int N[NDIM];
     131//  bool flag = false;
     132  //vector Shifted, TranslationVector;
     133  Vector TestVector;
     134//  *out << Verbose(1) << "Begin of KeepPeriodic." << endl;
     135//  *out << Verbose(2) << "Vector is: ";
     136//  Output(out);
     137//  *out << endl;
     138  TestVector.CopyVector(this);
     139  TestVector.InverseMatrixMultiplication(matrix);
     140  for(int i=NDIM;i--;) { // correct periodically
     141    if (TestVector.x[i] < 0) {  // get every coefficient into the interval [0,1)
     142      TestVector.x[i] += ceil(TestVector.x[i]);
     143    } else {
     144      TestVector.x[i] -= floor(TestVector.x[i]);
     145    }
     146  }
     147  TestVector.MatrixMultiplication(matrix);
     148  CopyVector(&TestVector);
     149//  *out << Verbose(2) << "New corrected vector is: ";
     150//  Output(out);
     151//  *out << endl;
     152//  *out << Verbose(1) << "End of KeepPeriodic." << endl;
    153153};
    154154
     
    159159double Vector::ScalarProduct(const Vector *y) const
    160160{
    161         double res = 0.;
    162         for (int i=NDIM;i--;)
    163                 res += x[i]*y->x[i];
    164         return (res);
     161  double res = 0.;
     162  for (int i=NDIM;i--;)
     163    res += x[i]*y->x[i];
     164  return (res);
    165165};
    166166
    167167
    168168/** Calculates VectorProduct between this and another vector.
    169  *      -# returns the Product in place of vector from which it was initiated
    170  *      -# ATTENTION: Only three dim.
    171  *      \param *y array to vector with which to calculate crossproduct
    172  *      \return \f$ x \times y \f&
     169 *  -# returns the Product in place of vector from which it was initiated
     170 *  -# ATTENTION: Only three dim.
     171 *  \param *y array to vector with which to calculate crossproduct
     172 *  \return \f$ x \times y \f&
    173173 */
    174174void Vector::VectorProduct(const Vector *y)
    175175{
    176         Vector tmp;
    177         tmp.x[0] = x[1]* (y->x[2]) - x[2]* (y->x[1]);
    178         tmp.x[1] = x[2]* (y->x[0]) - x[0]* (y->x[2]);
    179         tmp.x[2] = x[0]* (y->x[1]) - x[1]* (y->x[0]);
    180         this->CopyVector(&tmp);
     176  Vector tmp;
     177  tmp.x[0] = x[1]* (y->x[2]) - x[2]* (y->x[1]);
     178  tmp.x[1] = x[2]* (y->x[0]) - x[0]* (y->x[2]);
     179  tmp.x[2] = x[0]* (y->x[1]) - x[1]* (y->x[0]);
     180  this->CopyVector(&tmp);
    181181
    182182};
     
    189189void Vector::ProjectOntoPlane(const Vector *y)
    190190{
    191         Vector tmp;
    192         tmp.CopyVector(y);
    193         tmp.Normalize();
    194         tmp.Scale(ScalarProduct(&tmp));
    195         this->SubtractVector(&tmp);
     191  Vector tmp;
     192  tmp.CopyVector(y);
     193  tmp.Normalize();
     194  tmp.Scale(ScalarProduct(&tmp));
     195  this->SubtractVector(&tmp);
    196196};
    197197
     
    202202double Vector::Projection(const Vector *y) const
    203203{
    204         return (ScalarProduct(y));
     204  return (ScalarProduct(y));
    205205};
    206206
     
    210210double Vector::Norm() const
    211211{
    212         double res = 0.;
    213         for (int i=NDIM;i--;)
    214                 res += this->x[i]*this->x[i];
    215         return (sqrt(res));
     212  double res = 0.;
     213  for (int i=NDIM;i--;)
     214    res += this->x[i]*this->x[i];
     215  return (sqrt(res));
    216216};
    217217
     
    220220void Vector::Normalize()
    221221{
    222         double res = 0.;
    223         for (int i=NDIM;i--;)
    224                 res += this->x[i]*this->x[i];
    225         if (fabs(res) > MYEPSILON)
    226                 res = 1./sqrt(res);
    227         Scale(&res);
     222  double res = 0.;
     223  for (int i=NDIM;i--;)
     224    res += this->x[i]*this->x[i];
     225  if (fabs(res) > MYEPSILON)
     226    res = 1./sqrt(res);
     227  Scale(&res);
    228228};
    229229
     
    232232void Vector::Zero()
    233233{
    234         for (int i=NDIM;i--;)
    235                 this->x[i] = 0.;
     234  for (int i=NDIM;i--;)
     235    this->x[i] = 0.;
    236236};
    237237
     
    240240void Vector::One(double one)
    241241{
    242         for (int i=NDIM;i--;)
    243                 this->x[i] = one;
     242  for (int i=NDIM;i--;)
     243    this->x[i] = one;
    244244};
    245245
     
    248248void Vector::Init(double x1, double x2, double x3)
    249249{
    250         x[0] = x1;
    251         x[1] = x2;
    252         x[2] = x3;
     250  x[0] = x1;
     251  x[1] = x2;
     252  x[2] = x3;
    253253};
    254254
     
    266266  if (angle > 1)
    267267    angle = 1;
    268         return acos(angle);
     268  return acos(angle);
    269269};
    270270
     
    275275void Vector::RotateVector(const Vector *axis, const double alpha)
    276276{
    277         Vector a,y;
    278         // normalise this vector with respect to axis
    279         a.CopyVector(this);
    280         a.Scale(Projection(axis));
    281         SubtractVector(&a);
    282         // construct normal vector
    283         y.MakeNormalVector(axis,this);
    284         y.Scale(Norm());
    285         // scale normal vector by sine and this vector by cosine
    286         y.Scale(sin(alpha));
    287         Scale(cos(alpha));
    288         // add scaled normal vector onto this vector
    289         AddVector(&y);
    290         // add part in axis direction
    291         AddVector(&a);
     277  Vector a,y;
     278  // normalise this vector with respect to axis
     279  a.CopyVector(this);
     280  a.Scale(Projection(axis));
     281  SubtractVector(&a);
     282  // construct normal vector
     283  y.MakeNormalVector(axis,this);
     284  y.Scale(Norm());
     285  // scale normal vector by sine and this vector by cosine
     286  y.Scale(sin(alpha));
     287  Scale(cos(alpha));
     288  // add scaled normal vector onto this vector
     289  AddVector(&y);
     290  // add part in axis direction
     291  AddVector(&a);
    292292};
    293293
     
    299299Vector& operator+=(Vector& a, const Vector& b)
    300300{
    301         a.AddVector(&b);
    302         return a;
     301  a.AddVector(&b);
     302  return a;
    303303};
    304304/** factor each component of \a a times a double \a m.
     
    309309Vector& operator*=(Vector& a, const double m)
    310310{
    311         a.Scale(m);
    312         return a;
    313 };
    314 
    315 /** Sums two vectors \a and \b component-wise.
     311  a.Scale(m);
     312  return a;
     313};
     314
     315/** Sums two vectors \a  and \b component-wise.
    316316 * \param a first vector
    317317 * \param b second vector
     
    320320Vector& operator+(const Vector& a, const Vector& b)
    321321{
    322         Vector *x = new Vector;
    323         x->CopyVector(&a);
    324         x->AddVector(&b);
    325         return *x;
     322  Vector *x = new Vector;
     323  x->CopyVector(&a);
     324  x->AddVector(&b);
     325  return *x;
    326326};
    327327
     
    333333Vector& operator*(const Vector& a, const double m)
    334334{
    335         Vector *x = new Vector;
    336         x->CopyVector(&a);
    337         x->Scale(m);
    338         return *x;
     335  Vector *x = new Vector;
     336  x->CopyVector(&a);
     337  x->Scale(m);
     338  return *x;
    339339};
    340340
     
    345345bool Vector::Output(ofstream *out) const
    346346{
    347         if (out != NULL) {
    348                 *out << "(";
    349                 for (int i=0;i<NDIM;i++) {
    350                         *out << x[i];
    351                         if (i != 2)
    352                                 *out << ",";
    353                 }
    354                 *out << ")";
    355                 return true;
    356         } else
    357                 return false;
     347  if (out != NULL) {
     348    *out << "(";
     349    for (int i=0;i<NDIM;i++) {
     350      *out << x[i];
     351      if (i != 2)
     352        *out << ",";
     353    }
     354    *out << ")";
     355    return true;
     356  } else
     357    return false;
    358358};
    359359
    360360ostream& operator<<(ostream& ost,Vector& m)
    361361{
    362         ost << "(";
    363         for (int i=0;i<NDIM;i++) {
    364                 ost << m.x[i];
    365                 if (i != 2)
    366                         ost << ",";
    367         }
    368         ost << ")";
    369         return ost;
     362  ost << "(";
     363  for (int i=0;i<NDIM;i++) {
     364    ost << m.x[i];
     365    if (i != 2)
     366      ost << ",";
     367  }
     368  ost << ")";
     369  return ost;
    370370};
    371371
     
    375375void Vector::Scale(double **factor)
    376376{
    377         for (int i=NDIM;i--;)
    378                 x[i] *= (*factor)[i];
     377  for (int i=NDIM;i--;)
     378    x[i] *= (*factor)[i];
    379379};
    380380
    381381void Vector::Scale(double *factor)
    382382{
    383         for (int i=NDIM;i--;)
    384                 x[i] *= *factor;
     383  for (int i=NDIM;i--;)
     384    x[i] *= *factor;
    385385};
    386386
    387387void Vector::Scale(double factor)
    388388{
    389         for (int i=NDIM;i--;)
    390                 x[i] *= factor;
     389  for (int i=NDIM;i--;)
     390    x[i] *= factor;
    391391};
    392392
     
    396396void Vector::Translate(const Vector *trans)
    397397{
    398         for (int i=NDIM;i--;)
    399                 x[i] += trans->x[i];
     398  for (int i=NDIM;i--;)
     399    x[i] += trans->x[i];
    400400};
    401401
     
    405405void Vector::MatrixMultiplication(double *M)
    406406{
    407         Vector C;
    408         // do the matrix multiplication
    409         C.x[0] = M[0]*x[0]+M[3]*x[1]+M[6]*x[2];
    410         C.x[1] = M[1]*x[0]+M[4]*x[1]+M[7]*x[2];
    411         C.x[2] = M[2]*x[0]+M[5]*x[1]+M[8]*x[2];
    412         // transfer the result into this
    413         for (int i=NDIM;i--;)
    414                 x[i] = C.x[i];
     407  Vector C;
     408  // do the matrix multiplication
     409  C.x[0] = M[0]*x[0]+M[3]*x[1]+M[6]*x[2];
     410  C.x[1] = M[1]*x[0]+M[4]*x[1]+M[7]*x[2];
     411  C.x[2] = M[2]*x[0]+M[5]*x[1]+M[8]*x[2];
     412  // transfer the result into this
     413  for (int i=NDIM;i--;)
     414    x[i] = C.x[i];
    415415};
    416416
     
    447447void Vector::InverseMatrixMultiplication(double *A)
    448448{
    449         Vector C;
    450         double B[NDIM*NDIM];
    451         double detA = RDET3(A);
    452         double detAReci;
    453 
    454         // calculate the inverse B
    455         if (fabs(detA) > MYEPSILON) {;  // RDET3(A) yields precisely zero if A irregular
    456                 detAReci = 1./detA;
    457                 B[0] =  detAReci*RDET2(A[4],A[5],A[7],A[8]);            // A_11
    458                 B[1] = -detAReci*RDET2(A[1],A[2],A[7],A[8]);            // A_12
    459                 B[2] =  detAReci*RDET2(A[1],A[2],A[4],A[5]);            // A_13
    460                 B[3] = -detAReci*RDET2(A[3],A[5],A[6],A[8]);            // A_21
    461                 B[4] =  detAReci*RDET2(A[0],A[2],A[6],A[8]);            // A_22
    462                 B[5] = -detAReci*RDET2(A[0],A[2],A[3],A[5]);            // A_23
    463                 B[6] =  detAReci*RDET2(A[3],A[4],A[6],A[7]);            // A_31
    464                 B[7] = -detAReci*RDET2(A[0],A[1],A[6],A[7]);            // A_32
    465                 B[8] =  detAReci*RDET2(A[0],A[1],A[3],A[4]);            // A_33
    466 
    467                 // do the matrix multiplication
    468                 C.x[0] = B[0]*x[0]+B[3]*x[1]+B[6]*x[2];
    469                 C.x[1] = B[1]*x[0]+B[4]*x[1]+B[7]*x[2];
    470                 C.x[2] = B[2]*x[0]+B[5]*x[1]+B[8]*x[2];
    471                 // transfer the result into this
    472                 for (int i=NDIM;i--;)
    473                         x[i] = C.x[i];
    474         } else {
    475                 cerr << "ERROR: inverse of matrix does not exists!" << endl;
    476         }
     449  Vector C;
     450  double B[NDIM*NDIM];
     451  double detA = RDET3(A);
     452  double detAReci;
     453
     454  // calculate the inverse B
     455  if (fabs(detA) > MYEPSILON) {;  // RDET3(A) yields precisely zero if A irregular
     456    detAReci = 1./detA;
     457    B[0] =  detAReci*RDET2(A[4],A[5],A[7],A[8]);    // A_11
     458    B[1] = -detAReci*RDET2(A[1],A[2],A[7],A[8]);    // A_12
     459    B[2] =  detAReci*RDET2(A[1],A[2],A[4],A[5]);    // A_13
     460    B[3] = -detAReci*RDET2(A[3],A[5],A[6],A[8]);    // A_21
     461    B[4] =  detAReci*RDET2(A[0],A[2],A[6],A[8]);    // A_22
     462    B[5] = -detAReci*RDET2(A[0],A[2],A[3],A[5]);    // A_23
     463    B[6] =  detAReci*RDET2(A[3],A[4],A[6],A[7]);    // A_31
     464    B[7] = -detAReci*RDET2(A[0],A[1],A[6],A[7]);    // A_32
     465    B[8] =  detAReci*RDET2(A[0],A[1],A[3],A[4]);    // A_33
     466
     467    // do the matrix multiplication
     468    C.x[0] = B[0]*x[0]+B[3]*x[1]+B[6]*x[2];
     469    C.x[1] = B[1]*x[0]+B[4]*x[1]+B[7]*x[2];
     470    C.x[2] = B[2]*x[0]+B[5]*x[1]+B[8]*x[2];
     471    // transfer the result into this
     472    for (int i=NDIM;i--;)
     473      x[i] = C.x[i];
     474  } else {
     475    cerr << "ERROR: inverse of matrix does not exists!" << endl;
     476  }
    477477};
    478478
     
    487487void Vector::LinearCombinationOfVectors(const Vector *x1, const Vector *x2, const Vector *x3, double *factors)
    488488{
    489         for(int i=NDIM;i--;)
    490                 x[i] = factors[0]*x1->x[i] + factors[1]*x2->x[i] + factors[2]*x3->x[i];
     489  for(int i=NDIM;i--;)
     490    x[i] = factors[0]*x1->x[i] + factors[1]*x2->x[i] + factors[2]*x3->x[i];
    491491};
    492492
     
    496496void Vector::Mirror(const Vector *n)
    497497{
    498         double projection;
    499         projection = ScalarProduct(n)/n->ScalarProduct(n);              // remove constancy from n (keep as logical one)
    500         // withdraw projected vector twice from original one
    501         cout << Verbose(1) << "Vector: ";
    502         Output((ofstream *)&cout);
    503         cout << "\t";
    504         for (int i=NDIM;i--;)
    505                 x[i] -= 2.*projection*n->x[i];
    506         cout << "Projected vector: ";
    507         Output((ofstream *)&cout);
    508         cout << endl;
     498  double projection;
     499  projection = ScalarProduct(n)/n->ScalarProduct(n);    // remove constancy from n (keep as logical one)
     500  // withdraw projected vector twice from original one
     501  cout << Verbose(1) << "Vector: ";
     502  Output((ofstream *)&cout);
     503  cout << "\t";
     504  for (int i=NDIM;i--;)
     505    x[i] -= 2.*projection*n->x[i];
     506  cout << "Projected vector: ";
     507  Output((ofstream *)&cout);
     508  cout << endl;
    509509};
    510510
     
    518518bool Vector::MakeNormalVector(const Vector *y1, const Vector *y2, const Vector *y3)
    519519{
    520         Vector x1, x2;
    521 
    522         x1.CopyVector(y1);
    523         x1.SubtractVector(y2);
    524         x2.CopyVector(y3);
    525         x2.SubtractVector(y2);
    526         if ((fabs(x1.Norm()) < MYEPSILON) || (fabs(x2.Norm()) < MYEPSILON) || (fabs(x1.Angle(&x2)) < MYEPSILON)) {
    527                 cout << Verbose(4) << "Given vectors are linear dependent." << endl;
    528                 return false;
    529         }
    530 //      cout << Verbose(4) << "relative, first plane coordinates:";
    531 //      x1.Output((ofstream *)&cout);
    532 //      cout << endl;
    533 //      cout << Verbose(4) << "second plane coordinates:";
    534 //      x2.Output((ofstream *)&cout);
    535 //      cout << endl;
    536 
    537         this->x[0] = (x1.x[1]*x2.x[2] - x1.x[2]*x2.x[1]);
    538         this->x[1] = (x1.x[2]*x2.x[0] - x1.x[0]*x2.x[2]);
    539         this->x[2] = (x1.x[0]*x2.x[1] - x1.x[1]*x2.x[0]);
    540         Normalize();
    541 
    542         return true;
     520  Vector x1, x2;
     521
     522  x1.CopyVector(y1);
     523  x1.SubtractVector(y2);
     524  x2.CopyVector(y3);
     525  x2.SubtractVector(y2);
     526  if ((fabs(x1.Norm()) < MYEPSILON) || (fabs(x2.Norm()) < MYEPSILON) || (fabs(x1.Angle(&x2)) < MYEPSILON)) {
     527    cout << Verbose(4) << "Given vectors are linear dependent." << endl;
     528    return false;
     529  }
     530//  cout << Verbose(4) << "relative, first plane coordinates:";
     531//  x1.Output((ofstream *)&cout);
     532//  cout << endl;
     533//  cout << Verbose(4) << "second plane coordinates:";
     534//  x2.Output((ofstream *)&cout);
     535//  cout << endl;
     536
     537  this->x[0] = (x1.x[1]*x2.x[2] - x1.x[2]*x2.x[1]);
     538  this->x[1] = (x1.x[2]*x2.x[0] - x1.x[0]*x2.x[2]);
     539  this->x[2] = (x1.x[0]*x2.x[1] - x1.x[1]*x2.x[0]);
     540  Normalize();
     541
     542  return true;
    543543};
    544544
     
    554554bool Vector::MakeNormalVector(const Vector *y1, const Vector *y2)
    555555{
    556         Vector x1,x2;
    557         x1.CopyVector(y1);
    558         x2.CopyVector(y2);
    559         Zero();
    560         if ((fabs(x1.Norm()) < MYEPSILON) || (fabs(x2.Norm()) < MYEPSILON) || (fabs(x1.Angle(&x2)) < MYEPSILON)) {
    561                 cout << Verbose(4) << "Given vectors are linear dependent." << endl;
    562                 return false;
    563         }
    564 //      cout << Verbose(4) << "relative, first plane coordinates:";
    565 //      x1.Output((ofstream *)&cout);
    566 //      cout << endl;
    567 //      cout << Verbose(4) << "second plane coordinates:";
    568 //      x2.Output((ofstream *)&cout);
    569 //      cout << endl;
    570 
    571         this->x[0] = (x1.x[1]*x2.x[2] - x1.x[2]*x2.x[1]);
    572         this->x[1] = (x1.x[2]*x2.x[0] - x1.x[0]*x2.x[2]);
    573         this->x[2] = (x1.x[0]*x2.x[1] - x1.x[1]*x2.x[0]);
    574         Normalize();
    575 
    576         return true;
     556  Vector x1,x2;
     557  x1.CopyVector(y1);
     558  x2.CopyVector(y2);
     559  Zero();
     560  if ((fabs(x1.Norm()) < MYEPSILON) || (fabs(x2.Norm()) < MYEPSILON) || (fabs(x1.Angle(&x2)) < MYEPSILON)) {
     561    cout << Verbose(4) << "Given vectors are linear dependent." << endl;
     562    return false;
     563  }
     564//  cout << Verbose(4) << "relative, first plane coordinates:";
     565//  x1.Output((ofstream *)&cout);
     566//  cout << endl;
     567//  cout << Verbose(4) << "second plane coordinates:";
     568//  x2.Output((ofstream *)&cout);
     569//  cout << endl;
     570
     571  this->x[0] = (x1.x[1]*x2.x[2] - x1.x[2]*x2.x[1]);
     572  this->x[1] = (x1.x[2]*x2.x[0] - x1.x[0]*x2.x[2]);
     573  this->x[2] = (x1.x[0]*x2.x[1] - x1.x[1]*x2.x[0]);
     574  Normalize();
     575
     576  return true;
    577577};
    578578
     
    584584bool Vector::MakeNormalVector(const Vector *y1)
    585585{
    586         bool result = false;
    587         Vector x1;
    588         x1.CopyVector(y1);
    589         x1.Scale(x1.Projection(this));
    590         SubtractVector(&x1);
    591         for (int i=NDIM;i--;)
    592                 result = result || (fabs(x[i]) > MYEPSILON);
    593 
    594         return result;
     586  bool result = false;
     587  Vector x1;
     588  x1.CopyVector(y1);
     589  x1.Scale(x1.Projection(this));
     590  SubtractVector(&x1);
     591  for (int i=NDIM;i--;)
     592    result = result || (fabs(x[i]) > MYEPSILON);
     593
     594  return result;
    595595};
    596596
     
    603603bool Vector::GetOneNormalVector(const Vector *GivenVector)
    604604{
    605         int Components[NDIM]; // contains indices of non-zero components
    606         int Last = 0;    // count the number of non-zero entries in vector
    607         int j;  // loop variables
    608         double norm;
    609 
    610         cout << Verbose(4);
    611         GivenVector->Output((ofstream *)&cout);
    612         cout << endl;
    613         for (j=NDIM;j--;)
    614                 Components[j] = -1;
    615         // find two components != 0
    616         for (j=0;j<NDIM;j++)
    617                 if (fabs(GivenVector->x[j]) > MYEPSILON)
    618                         Components[Last++] = j;
    619         cout << Verbose(4) << Last << " Components != 0: (" << Components[0] << "," << Components[1] << "," << Components[2] << ")" << endl;
    620 
    621         switch(Last) {
    622                 case 3: // threecomponent system
    623                 case 2: // two component system
    624                         norm = sqrt(1./(GivenVector->x[Components[1]]*GivenVector->x[Components[1]]) + 1./(GivenVector->x[Components[0]]*GivenVector->x[Components[0]]));
    625                         x[Components[2]] = 0.;
    626                         // in skp both remaining parts shall become zero but with opposite sign and third is zero
    627                         x[Components[1]] = -1./GivenVector->x[Components[1]] / norm;
    628                         x[Components[0]] = 1./GivenVector->x[Components[0]] / norm;
    629                         return true;
    630                         break;
    631                 case 1: // one component system
    632                         // set sole non-zero component to 0, and one of the other zero component pendants to 1
    633                         x[(Components[0]+2)%NDIM] = 0.;
    634                         x[(Components[0]+1)%NDIM] = 1.;
    635                         x[Components[0]] = 0.;
    636                         return true;
    637                         break;
    638                 default:
    639                         return false;
    640         }
     605  int Components[NDIM]; // contains indices of non-zero components
     606  int Last = 0;  // count the number of non-zero entries in vector
     607  int j;  // loop variables
     608  double norm;
     609
     610  cout << Verbose(4);
     611  GivenVector->Output((ofstream *)&cout);
     612  cout << endl;
     613  for (j=NDIM;j--;)
     614    Components[j] = -1;
     615  // find two components != 0
     616  for (j=0;j<NDIM;j++)
     617    if (fabs(GivenVector->x[j]) > MYEPSILON)
     618      Components[Last++] = j;
     619  cout << Verbose(4) << Last << " Components != 0: (" << Components[0] << "," << Components[1] << "," << Components[2] << ")" << endl;
     620
     621  switch(Last) {
     622    case 3:  // threecomponent system
     623    case 2:  // two component system
     624      norm = sqrt(1./(GivenVector->x[Components[1]]*GivenVector->x[Components[1]]) + 1./(GivenVector->x[Components[0]]*GivenVector->x[Components[0]]));
     625      x[Components[2]] = 0.;
     626      // in skp both remaining parts shall become zero but with opposite sign and third is zero
     627      x[Components[1]] = -1./GivenVector->x[Components[1]] / norm;
     628      x[Components[0]] = 1./GivenVector->x[Components[0]] / norm;
     629      return true;
     630      break;
     631    case 1: // one component system
     632      // set sole non-zero component to 0, and one of the other zero component pendants to 1
     633      x[(Components[0]+2)%NDIM] = 0.;
     634      x[(Components[0]+1)%NDIM] = 1.;
     635      x[Components[0]] = 0.;
     636      return true;
     637      break;
     638    default:
     639      return false;
     640  }
    641641};
    642642
     
    649649double Vector::CutsPlaneAt(Vector *A, Vector *B, Vector *C)
    650650{
    651 //      cout << Verbose(3) << "For comparison: ";
    652 //      cout << "A " << A->Projection(this) << "\t";
    653 //      cout << "B " << B->Projection(this) << "\t";
    654 //      cout << "C " << C->Projection(this) << "\t";
    655 //      cout << endl;
    656         return A->Projection(this);
     651//  cout << Verbose(3) << "For comparison: ";
     652//  cout << "A " << A->Projection(this) << "\t";
     653//  cout << "B " << B->Projection(this) << "\t";
     654//  cout << "C " << C->Projection(this) << "\t";
     655//  cout << endl;
     656  return A->Projection(this);
    657657};
    658658
     
    664664bool Vector::LSQdistance(Vector **vectors, int num)
    665665{
    666         int j;
    667 
    668         for (j=0;j<num;j++) {
    669                 cout << Verbose(1) << j << "th atom's vector: ";
    670                 (vectors[j])->Output((ofstream *)&cout);
    671                 cout << endl;
    672         }
    673 
    674         int np = 3;
    675         struct LSQ_params par;
    676 
    677         const gsl_multimin_fminimizer_type *T =
    678                 gsl_multimin_fminimizer_nmsimplex;
    679         gsl_multimin_fminimizer *s = NULL;
    680         gsl_vector *ss, *y;
    681         gsl_multimin_function minex_func;
    682 
    683         size_t iter = 0, i;
    684         int status;
    685         double size;
    686 
    687         /* Initial vertex size vector */
    688         ss = gsl_vector_alloc (np);
    689         y = gsl_vector_alloc (np);
    690 
    691         /* Set all step sizes to 1 */
    692         gsl_vector_set_all (ss, 1.0);
    693 
    694         /* Starting point */
    695         par.vectors = vectors;
    696         par.num = num;
    697 
    698         for (i=NDIM;i--;)
    699                 gsl_vector_set(y, i, (vectors[0]->x[i] - vectors[1]->x[i])/2.);
    700 
    701         /* Initialize method and iterate */
    702         minex_func.f = &LSQ;
    703         minex_func.n = np;
    704         minex_func.params = (void *)&par;
    705 
    706         s = gsl_multimin_fminimizer_alloc (T, np);
    707         gsl_multimin_fminimizer_set (s, &minex_func, y, ss);
    708 
    709         do
    710                 {
    711                         iter++;
    712                         status = gsl_multimin_fminimizer_iterate(s);
    713 
    714                         if (status)
    715                                 break;
    716 
    717                         size = gsl_multimin_fminimizer_size (s);
    718                         status = gsl_multimin_test_size (size, 1e-2);
    719 
    720                         if (status == GSL_SUCCESS)
    721                                 {
    722                                         printf ("converged to minimum at\n");
    723                                 }
    724 
    725                         printf ("%5d ", (int)iter);
    726                         for (i = 0; i < (size_t)np; i++)
    727                                 {
    728                                         printf ("%10.3e ", gsl_vector_get (s->x, i));
    729                                 }
    730                         printf ("f() = %7.3f size = %.3f\n", s->fval, size);
    731                 }
    732         while (status == GSL_CONTINUE && iter < 100);
    733 
    734         for (i=(size_t)np;i--;)
    735                 this->x[i] = gsl_vector_get(s->x, i);
    736         gsl_vector_free(y);
    737         gsl_vector_free(ss);
    738         gsl_multimin_fminimizer_free (s);
    739 
    740         return true;
     666  int j;
     667
     668  for (j=0;j<num;j++) {
     669    cout << Verbose(1) << j << "th atom's vector: ";
     670    (vectors[j])->Output((ofstream *)&cout);
     671    cout << endl;
     672  }
     673
     674  int np = 3;
     675  struct LSQ_params par;
     676
     677  const gsl_multimin_fminimizer_type *T =
     678    gsl_multimin_fminimizer_nmsimplex;
     679  gsl_multimin_fminimizer *s = NULL;
     680  gsl_vector *ss, *y;
     681  gsl_multimin_function minex_func;
     682
     683  size_t iter = 0, i;
     684  int status;
     685  double size;
     686
     687  /* Initial vertex size vector */
     688  ss = gsl_vector_alloc (np);
     689  y = gsl_vector_alloc (np);
     690
     691  /* Set all step sizes to 1 */
     692  gsl_vector_set_all (ss, 1.0);
     693
     694  /* Starting point */
     695  par.vectors = vectors;
     696  par.num = num;
     697
     698  for (i=NDIM;i--;)
     699    gsl_vector_set(y, i, (vectors[0]->x[i] - vectors[1]->x[i])/2.);
     700
     701  /* Initialize method and iterate */
     702  minex_func.f = &LSQ;
     703  minex_func.n = np;
     704  minex_func.params = (void *)&par;
     705
     706  s = gsl_multimin_fminimizer_alloc (T, np);
     707  gsl_multimin_fminimizer_set (s, &minex_func, y, ss);
     708
     709  do
     710    {
     711      iter++;
     712      status = gsl_multimin_fminimizer_iterate(s);
     713
     714      if (status)
     715        break;
     716
     717      size = gsl_multimin_fminimizer_size (s);
     718      status = gsl_multimin_test_size (size, 1e-2);
     719
     720      if (status == GSL_SUCCESS)
     721        {
     722          printf ("converged to minimum at\n");
     723        }
     724
     725      printf ("%5d ", (int)iter);
     726      for (i = 0; i < (size_t)np; i++)
     727        {
     728          printf ("%10.3e ", gsl_vector_get (s->x, i));
     729        }
     730      printf ("f() = %7.3f size = %.3f\n", s->fval, size);
     731    }
     732  while (status == GSL_CONTINUE && iter < 100);
     733
     734  for (i=(size_t)np;i--;)
     735    this->x[i] = gsl_vector_get(s->x, i);
     736  gsl_vector_free(y);
     737  gsl_vector_free(ss);
     738  gsl_multimin_fminimizer_free (s);
     739
     740  return true;
    741741};
    742742
     
    746746void Vector::AddVector(const Vector *y)
    747747{
    748         for (int i=NDIM;i--;)
    749                 this->x[i] += y->x[i];
     748  for (int i=NDIM;i--;)
     749    this->x[i] += y->x[i];
    750750}
    751751
     
    755755void Vector::SubtractVector(const Vector *y)
    756756{
    757         for (int i=NDIM;i--;)
    758                 this->x[i] -= y->x[i];
     757  for (int i=NDIM;i--;)
     758    this->x[i] -= y->x[i];
    759759}
    760760
     
    764764void Vector::CopyVector(const Vector *y)
    765765{
    766         for (int i=NDIM;i--;)
    767                 this->x[i] = y->x[i];
     766  for (int i=NDIM;i--;)
     767    this->x[i] = y->x[i];
    768768}
    769769
     
    775775void Vector::AskPosition(double *cell_size, bool check)
    776776{
    777         char coords[3] = {'x','y','z'};
    778         int j = -1;
    779         for (int i=0;i<3;i++) {
    780                 j += i+1;
    781                 do {
    782                         cout << Verbose(0) << coords[i] << "[0.." << cell_size[j] << "]: ";
    783                         cin >> x[i];
    784                 } while (((x[i] < 0) || (x[i] >= cell_size[j])) && (check));
    785         }
     777  char coords[3] = {'x','y','z'};
     778  int j = -1;
     779  for (int i=0;i<3;i++) {
     780    j += i+1;
     781    do {
     782      cout << Verbose(0) << coords[i] << "[0.." << cell_size[j] << "]: ";
     783      cin >> x[i];
     784    } while (((x[i] < 0) || (x[i] >= cell_size[j])) && (check));
     785  }
    786786};
    787787
     
    803803bool Vector::SolveSystem(Vector *x1, Vector *x2, Vector *y, double alpha, double beta, double c)
    804804{
    805         double D1,D2,D3,E1,E2,F1,F2,F3,p,q=0., A, B1, B2, C;
    806         double ang; // angle on testing
    807         double sign[3];
    808         int i,j,k;
    809         A = cos(alpha) * x1->Norm() * c;
    810         B1 = cos(beta + M_PI/2.) * y->Norm() * c;
    811         B2 = cos(beta) * x2->Norm() * c;
    812         C = c * c;
    813         cout << Verbose(2) << "A " << A << "\tB " << B1 << "\tC " << C << endl;
    814         int flag = 0;
    815         if (fabs(x1->x[0]) < MYEPSILON) { // check for zero components for the later flipping and back-flipping
    816                 if (fabs(x1->x[1]) > MYEPSILON) {
    817                         flag = 1;
    818                 } else if (fabs(x1->x[2]) > MYEPSILON) {
    819                         flag = 2;
    820                 } else {
    821                         return false;
    822                 }
    823         }
    824         switch (flag) {
    825                 default:
    826                 case 0:
    827                         break;
    828                 case 2:
    829                         flip(&x1->x[0],&x1->x[1]);
    830                         flip(&x2->x[0],&x2->x[1]);
    831                         flip(&y->x[0],&y->x[1]);
    832                         //flip(&x[0],&x[1]);
    833                         flip(&x1->x[1],&x1->x[2]);
    834                         flip(&x2->x[1],&x2->x[2]);
    835                         flip(&y->x[1],&y->x[2]);
    836                         //flip(&x[1],&x[2]);
    837                 case 1:
    838                         flip(&x1->x[0],&x1->x[1]);
    839                         flip(&x2->x[0],&x2->x[1]);
    840                         flip(&y->x[0],&y->x[1]);
    841                         //flip(&x[0],&x[1]);
    842                         flip(&x1->x[1],&x1->x[2]);
    843                         flip(&x2->x[1],&x2->x[2]);
    844                         flip(&y->x[1],&y->x[2]);
    845                         //flip(&x[1],&x[2]);
    846                         break;
    847         }
    848         // now comes the case system
    849         D1 = -y->x[0]/x1->x[0]*x1->x[1]+y->x[1];
    850         D2 = -y->x[0]/x1->x[0]*x1->x[2]+y->x[2];
    851         D3 = y->x[0]/x1->x[0]*A-B1;
    852         cout << Verbose(2) << "D1 " << D1 << "\tD2 " << D2 << "\tD3 " << D3 << "\n";
    853         if (fabs(D1) < MYEPSILON) {
    854                 cout << Verbose(2) << "D1 == 0!\n";
    855                 if (fabs(D2) > MYEPSILON) {
    856                         cout << Verbose(3) << "D2 != 0!\n";
    857                         x[2] = -D3/D2;
    858                         E1 = A/x1->x[0] + x1->x[2]/x1->x[0]*D3/D2;
    859                         E2 = -x1->x[1]/x1->x[0];
    860                         cout << Verbose(3) << "E1 " << E1 << "\tE2 " << E2 << "\n";
    861                         F1 = E1*E1 + 1.;
    862                         F2 = -E1*E2;
    863                         F3 = E1*E1 + D3*D3/(D2*D2) - C;
    864                         cout << Verbose(3) << "F1 " << F1 << "\tF2 " << F2 << "\tF3 " << F3 << "\n";
    865                         if (fabs(F1) < MYEPSILON) {
    866                                 cout << Verbose(4) << "F1 == 0!\n";
    867                                 cout << Verbose(4) << "Gleichungssystem linear\n";
    868                                 x[1] = F3/(2.*F2);
    869                         } else {
    870                                 p = F2/F1;
    871                                 q = p*p - F3/F1;
    872                                 cout << Verbose(4) << "p " << p << "\tq " << q << endl;
    873                                 if (q < 0) {
    874                                         cout << Verbose(4) << "q < 0" << endl;
    875                                         return false;
    876                                 }
    877                                 x[1] = p + sqrt(q);
    878                         }
    879                         x[0] =  A/x1->x[0] - x1->x[1]/x1->x[0]*x[1] + x1->x[2]/x1->x[0]*x[2];
    880                 } else {
    881                         cout << Verbose(2) << "Gleichungssystem unterbestimmt\n";
    882                         return false;
    883                 }
    884         } else {
    885                 E1 = A/x1->x[0]+x1->x[1]/x1->x[0]*D3/D1;
    886                 E2 = x1->x[1]/x1->x[0]*D2/D1 - x1->x[2];
    887                 cout << Verbose(2) << "E1 " << E1 << "\tE2 " << E2 << "\n";
    888                 F1 = E2*E2 + D2*D2/(D1*D1) + 1.;
    889                 F2 = -(E1*E2 + D2*D3/(D1*D1));
    890                 F3 = E1*E1 + D3*D3/(D1*D1) - C;
    891                 cout << Verbose(2) << "F1 " << F1 << "\tF2 " << F2 << "\tF3 " << F3 << "\n";
    892                 if (fabs(F1) < MYEPSILON) {
    893                         cout << Verbose(3) << "F1 == 0!\n";
    894                         cout << Verbose(3) << "Gleichungssystem linear\n";
    895                         x[2] = F3/(2.*F2);
    896                 } else {
    897                         p = F2/F1;
    898                         q = p*p - F3/F1;
    899                         cout << Verbose(3) << "p " << p << "\tq " << q << endl;
    900                         if (q < 0) {
    901                                 cout << Verbose(3) << "q < 0" << endl;
    902                                 return false;
    903                         }
    904                         x[2] = p + sqrt(q);
    905                 }
    906                 x[1] = (-D2 * x[2] - D3)/D1;
    907                 x[0] = A/x1->x[0] - x1->x[1]/x1->x[0]*x[1] + x1->x[2]/x1->x[0]*x[2];
    908         }
    909         switch (flag) { // back-flipping
    910                 default:
    911                 case 0:
    912                         break;
    913                 case 2:
    914                         flip(&x1->x[0],&x1->x[1]);
    915                         flip(&x2->x[0],&x2->x[1]);
    916                         flip(&y->x[0],&y->x[1]);
    917                         flip(&x[0],&x[1]);
    918                         flip(&x1->x[1],&x1->x[2]);
    919                         flip(&x2->x[1],&x2->x[2]);
    920                         flip(&y->x[1],&y->x[2]);
    921                         flip(&x[1],&x[2]);
    922                 case 1:
    923                         flip(&x1->x[0],&x1->x[1]);
    924                         flip(&x2->x[0],&x2->x[1]);
    925                         flip(&y->x[0],&y->x[1]);
    926                         //flip(&x[0],&x[1]);
    927                         flip(&x1->x[1],&x1->x[2]);
    928                         flip(&x2->x[1],&x2->x[2]);
    929                         flip(&y->x[1],&y->x[2]);
    930                         flip(&x[1],&x[2]);
    931                         break;
    932         }
    933         // one z component is only determined by its radius (without sign)
    934         // thus check eight possible sign flips and determine by checking angle with second vector
    935         for (i=0;i<8;i++) {
    936                 // set sign vector accordingly
    937                 for (j=2;j>=0;j--) {
    938                         k = (i & pot(2,j)) << j;
    939                         cout << Verbose(2) << "k " << k << "\tpot(2,j) " << pot(2,j) << endl;
    940                         sign[j] = (k == 0) ? 1. : -1.;
    941                 }
    942                 cout << Verbose(2) << i << ": sign matrix is " << sign[0] << "\t" << sign[1] << "\t" << sign[2] << "\n";
    943                 // apply sign matrix
    944                 for (j=NDIM;j--;)
    945                         x[j] *= sign[j];
    946                 // calculate angle and check
    947                 ang = x2->Angle (this);
    948                 cout << Verbose(1) << i << "th angle " << ang << "\tbeta " << cos(beta) << " :\t";
    949                 if (fabs(ang - cos(beta)) < MYEPSILON) {
    950                         break;
    951                 }
    952                 // unapply sign matrix (is its own inverse)
    953                 for (j=NDIM;j--;)
    954                         x[j] *= sign[j];
    955         }
    956         return true;
    957 };
     805  double D1,D2,D3,E1,E2,F1,F2,F3,p,q=0., A, B1, B2, C;
     806  double ang; // angle on testing
     807  double sign[3];
     808  int i,j,k;
     809  A = cos(alpha) * x1->Norm() * c;
     810  B1 = cos(beta + M_PI/2.) * y->Norm() * c;
     811  B2 = cos(beta) * x2->Norm() * c;
     812  C = c * c;
     813  cout << Verbose(2) << "A " << A << "\tB " << B1 << "\tC " << C << endl;
     814  int flag = 0;
     815  if (fabs(x1->x[0]) < MYEPSILON) { // check for zero components for the later flipping and back-flipping
     816    if (fabs(x1->x[1]) > MYEPSILON) {
     817      flag = 1;
     818    } else if (fabs(x1->x[2]) > MYEPSILON) {
     819      flag = 2;
     820    } else {
     821      return false;
     822    }
     823  }
     824  switch (flag) {
     825    default:
     826    case 0:
     827      break;
     828    case 2:
     829      flip(&x1->x[0],&x1->x[1]);
     830      flip(&x2->x[0],&x2->x[1]);
     831      flip(&y->x[0],&y->x[1]);
     832      //flip(&x[0],&x[1]);
     833      flip(&x1->x[1],&x1->x[2]);
     834      flip(&x2->x[1],&x2->x[2]);
     835      flip(&y->x[1],&y->x[2]);
     836      //flip(&x[1],&x[2]);
     837    case 1:
     838      flip(&x1->x[0],&x1->x[1]);
     839      flip(&x2->x[0],&x2->x[1]);
     840      flip(&y->x[0],&y->x[1]);
     841      //flip(&x[0],&x[1]);
     842      flip(&x1->x[1],&x1->x[2]);
     843      flip(&x2->x[1],&x2->x[2]);
     844      flip(&y->x[1],&y->x[2]);
     845      //flip(&x[1],&x[2]);
     846      break;
     847  }
     848  // now comes the case system
     849  D1 = -y->x[0]/x1->x[0]*x1->x[1]+y->x[1];
     850  D2 = -y->x[0]/x1->x[0]*x1->x[2]+y->x[2];
     851  D3 = y->x[0]/x1->x[0]*A-B1;
     852  cout << Verbose(2) << "D1 " << D1 << "\tD2 " << D2 << "\tD3 " << D3 << "\n";
     853  if (fabs(D1) < MYEPSILON) {
     854    cout << Verbose(2) << "D1 == 0!\n";
     855    if (fabs(D2) > MYEPSILON) {
     856      cout << Verbose(3) << "D2 != 0!\n";
     857      x[2] = -D3/D2;
     858      E1 = A/x1->x[0] + x1->x[2]/x1->x[0]*D3/D2;
     859      E2 = -x1->x[1]/x1->x[0];
     860      cout << Verbose(3) << "E1 " << E1 << "\tE2 " << E2 << "\n";
     861      F1 = E1*E1 + 1.;
     862      F2 = -E1*E2;
     863      F3 = E1*E1 + D3*D3/(D2*D2) - C;
     864      cout << Verbose(3) << "F1 " << F1 << "\tF2 " << F2 << "\tF3 " << F3 << "\n";
     865      if (fabs(F1) < MYEPSILON) {
     866        cout << Verbose(4) << "F1 == 0!\n";
     867        cout << Verbose(4) << "Gleichungssystem linear\n";
     868        x[1] = F3/(2.*F2);
     869      } else {
     870        p = F2/F1;
     871        q = p*p - F3/F1;
     872        cout << Verbose(4) << "p " << p << "\tq " << q << endl;
     873        if (q < 0) {
     874          cout << Verbose(4) << "q < 0" << endl;
     875          return false;
     876        }
     877        x[1] = p + sqrt(q);
     878      }
     879      x[0] =  A/x1->x[0] - x1->x[1]/x1->x[0]*x[1] + x1->x[2]/x1->x[0]*x[2];
     880    } else {
     881      cout << Verbose(2) << "Gleichungssystem unterbestimmt\n";
     882      return false;
     883    }
     884  } else {
     885    E1 = A/x1->x[0]+x1->x[1]/x1->x[0]*D3/D1;
     886    E2 = x1->x[1]/x1->x[0]*D2/D1 - x1->x[2];
     887    cout << Verbose(2) << "E1 " << E1 << "\tE2 " << E2 << "\n";
     888    F1 = E2*E2 + D2*D2/(D1*D1) + 1.;
     889    F2 = -(E1*E2 + D2*D3/(D1*D1));
     890    F3 = E1*E1 + D3*D3/(D1*D1) - C;
     891    cout << Verbose(2) << "F1 " << F1 << "\tF2 " << F2 << "\tF3 " << F3 << "\n";
     892    if (fabs(F1) < MYEPSILON) {
     893      cout << Verbose(3) << "F1 == 0!\n";
     894      cout << Verbose(3) << "Gleichungssystem linear\n";
     895      x[2] = F3/(2.*F2);
     896    } else {
     897      p = F2/F1;
     898      q = p*p - F3/F1;
     899      cout << Verbose(3) << "p " << p << "\tq " << q << endl;
     900      if (q < 0) {
     901        cout << Verbose(3) << "q < 0" << endl;
     902        return false;
     903      }
     904      x[2] = p + sqrt(q);
     905    }
     906    x[1] = (-D2 * x[2] - D3)/D1;
     907    x[0] = A/x1->x[0] - x1->x[1]/x1->x[0]*x[1] + x1->x[2]/x1->x[0]*x[2];
     908  }
     909  switch (flag) { // back-flipping
     910    default:
     911    case 0:
     912      break;
     913    case 2:
     914      flip(&x1->x[0],&x1->x[1]);
     915      flip(&x2->x[0],&x2->x[1]);
     916      flip(&y->x[0],&y->x[1]);
     917      flip(&x[0],&x[1]);
     918      flip(&x1->x[1],&x1->x[2]);
     919      flip(&x2->x[1],&x2->x[2]);
     920      flip(&y->x[1],&y->x[2]);
     921      flip(&x[1],&x[2]);
     922    case 1:
     923      flip(&x1->x[0],&x1->x[1]);
     924      flip(&x2->x[0],&x2->x[1]);
     925      flip(&y->x[0],&y->x[1]);
     926      //flip(&x[0],&x[1]);
     927      flip(&x1->x[1],&x1->x[2]);
     928      flip(&x2->x[1],&x2->x[2]);
     929      flip(&y->x[1],&y->x[2]);
     930      flip(&x[1],&x[2]);
     931      break;
     932  }
     933  // one z component is only determined by its radius (without sign)
     934  // thus check eight possible sign flips and determine by checking angle with second vector
     935  for (i=0;i<8;i++) {
     936    // set sign vector accordingly
     937    for (j=2;j>=0;j--) {
     938      k = (i & pot(2,j)) << j;
     939      cout << Verbose(2) << "k " << k << "\tpot(2,j) " << pot(2,j) << endl;
     940      sign[j] = (k == 0) ? 1. : -1.;
     941    }
     942    cout << Verbose(2) << i << ": sign matrix is " << sign[0] << "\t" << sign[1] << "\t" << sign[2] << "\n";
     943    // apply sign matrix
     944    for (j=NDIM;j--;)
     945      x[j] *= sign[j];
     946    // calculate angle and check
     947    ang = x2->Angle (this);
     948    cout << Verbose(1) << i << "th angle " << ang << "\tbeta " << cos(beta) << " :\t";
     949    if (fabs(ang - cos(beta)) < MYEPSILON) {
     950      break;
     951    }
     952    // unapply sign matrix (is its own inverse)
     953    for (j=NDIM;j--;)
     954      x[j] *= sign[j];
     955  }
     956  return true;
     957};
  • src/vector.hpp

    r205ccd r042f82  
    88 */
    99class Vector {
    10         public:
    11                 double x[NDIM];
     10  public:
     11    double x[NDIM];
    1212
    13         Vector();
    14         Vector(double x1, double x2, double x3);
    15         ~Vector();
     13  Vector();
     14  Vector(double x1, double x2, double x3);
     15  ~Vector();
    1616
    17         double Distance(const Vector *y) const;
    18         double DistanceSquared(const Vector *y) const;
    19         double PeriodicDistance(const Vector *y, const double *cell_size) const;
    20         double PeriodicDistanceSquared(const Vector *y, const double *cell_size) const;
    21         double ScalarProduct(const Vector *y) const;
    22         double Projection(const Vector *y) const;
    23         double Norm() const ;
    24         double Angle(const Vector *y) const;
     17  double Distance(const Vector *y) const;
     18  double DistanceSquared(const Vector *y) const;
     19  double PeriodicDistance(const Vector *y, const double *cell_size) const;
     20  double PeriodicDistanceSquared(const Vector *y, const double *cell_size) const;
     21  double ScalarProduct(const Vector *y) const;
     22  double Projection(const Vector *y) const;
     23  double Norm() const ;
     24  double Angle(const Vector *y) const;
    2525
    26         void AddVector(const Vector *y);
    27         void SubtractVector(const Vector *y);
    28         void CopyVector(const Vector *y);
    29         void RotateVector(const Vector *y, const double alpha);
    30         void VectorProduct(const Vector *y);
    31         void ProjectOntoPlane(const Vector *y);
    32         void Zero();
    33         void One(double one);
    34         void Init(double x1, double x2, double x3);
    35         void Normalize();
    36         void Translate(const Vector *x);
    37         void Mirror(const Vector *x);
    38         void Scale(double **factor);
    39         void Scale(double *factor);
    40         void Scale(double factor);
    41         void MatrixMultiplication(double *M);
    42         double * InverseMatrix(double *A);
    43         void InverseMatrixMultiplication(double *M);
    44         void KeepPeriodic(ofstream *out, double *matrix);
    45         void LinearCombinationOfVectors(const Vector *x1, const Vector *x2, const Vector *x3, double *factors);
    46         double CutsPlaneAt(Vector *A, Vector *B, Vector *C);
    47         bool GetOneNormalVector(const Vector *x1);
    48         bool MakeNormalVector(const Vector *y1);
    49         bool MakeNormalVector(const Vector *y1, const Vector *y2);
    50         bool MakeNormalVector(const Vector *x1, const Vector *x2, const Vector *x3);
    51         bool SolveSystem(Vector *x1, Vector *x2, Vector *y, double alpha, double beta, double c);
    52         bool LSQdistance(Vector **vectors, int dim);
    53         void AskPosition(double *cell_size, bool check);
    54         bool Output(ofstream *out) const;
     26  void AddVector(const Vector *y);
     27  void SubtractVector(const Vector *y);
     28  void CopyVector(const Vector *y);
     29  void RotateVector(const Vector *y, const double alpha);
     30  void VectorProduct(const Vector *y);
     31  void ProjectOntoPlane(const Vector *y);
     32  void Zero();
     33  void One(double one);
     34  void Init(double x1, double x2, double x3);
     35  void Normalize();
     36  void Translate(const Vector *x);
     37  void Mirror(const Vector *x);
     38  void Scale(double **factor);
     39  void Scale(double *factor);
     40  void Scale(double factor);
     41  void MatrixMultiplication(double *M);
     42  double * InverseMatrix(double *A);
     43  void InverseMatrixMultiplication(double *M);
     44  void KeepPeriodic(ofstream *out, double *matrix);
     45  void LinearCombinationOfVectors(const Vector *x1, const Vector *x2, const Vector *x3, double *factors);
     46  double CutsPlaneAt(Vector *A, Vector *B, Vector *C);
     47  bool GetOneNormalVector(const Vector *x1);
     48  bool MakeNormalVector(const Vector *y1);
     49  bool MakeNormalVector(const Vector *y1, const Vector *y2);
     50  bool MakeNormalVector(const Vector *x1, const Vector *x2, const Vector *x3);
     51  bool SolveSystem(Vector *x1, Vector *x2, Vector *y, double alpha, double beta, double c);
     52  bool LSQdistance(Vector **vectors, int dim);
     53  void AskPosition(double *cell_size, bool check);
     54  bool Output(ofstream *out) const;
    5555};
    5656
  • src/verbose.cpp

    r205ccd r042f82  
    77ostream& Verbose::print (ostream &ost) const
    88{
    9         for (int i=Verbosity;i--;)
    10                 ost.put('\t');
    11         //cout << "Verbose(.) called." << endl;
    12         return ost;
     9  for (int i=Verbosity;i--;)
     10    ost.put('\t');
     11  //cout << "Verbose(.) called." << endl;
     12  return ost;
    1313};
    1414
     
    2222ostream& operator<<(ostream& ost,const Verbose& m)
    2323{
    24         return m.print(ost);
     24  return m.print(ost);
    2525};
    2626
     
    3333ostream& Binary::print (ostream &ost) const
    3434{
    35         int bits = 1, counter = 1;
    36         while ((bits = 1 << counter) < BinaryNumber)
    37                 counter++;
    38         for (int i=0;i<counter-1;i++) {
    39                 if ((BinaryNumber & (1 << i)) == 0)
    40                         ost.put('0');
    41                 else
    42                         ost.put('1');
    43         }
    44         ost.put('b');
    45         //cout << "Binary(.) called." << endl;
    46         return ost;
     35  int bits = 1, counter = 1;
     36  while ((bits = 1 << counter) < BinaryNumber)
     37    counter++;
     38  for (int i=0;i<counter-1;i++) {
     39    if ((BinaryNumber & (1 << i)) == 0)
     40      ost.put('0');
     41     else
     42      ost.put('1');
     43  }
     44  ost.put('b');
     45  //cout << "Binary(.) called." << endl;
     46  return ost;
    4747};
    4848
     
    5656ostream& operator<<(ostream& ost,const Binary& m)
    5757{
    58         return m.print(ost);
     58  return m.print(ost);
    5959};
Note: See TracChangeset for help on using the changeset viewer.