Changes in / [986c80:edcda5]


Ignore:
Files:
6 deleted
43 edited

Legend:

Unmodified
Added
Removed
  • ChangeLog

    • Property mode changed from 100755 to 100644
  • Makefile.am

    • Property mode changed from 100755 to 100644
  • configure.ac

    • Property mode changed from 100755 to 100644
    r986c80 redcda5  
    1414AC_PROG_CC
    1515AM_MISSING_PROG([DOXYGEN], [doxygen])
     16
     17AC_ARG_ENABLE([debug],AS_HELP_STRING([--enable-debug],[debugging level of compiler. Argument is yes or debugging level. (default is no)]),
     18              [enable_debugging=$enableval], [enable_debugging=no])
     19AC_ARG_ENABLE([optimization],AS_HELP_STRING([--enable-optimization],[Optimization level of compiler. Argument is yes or optimization. (default is 2)]),
     20              [enable_optimization=$enableval], [enable_optimization=2])
     21AC_ARG_ENABLE([warnings], AS_HELP_STRING([--enable-warnings],[Output compiler warnings, argument is none, some or full (default is some).]),
     22              [enable_warnings=$enableval], [enable_warnings=some])
     23AC_SET_COMPILER_FLAGS([$enable_optimization], [$enable_debugging], [$enable_warnings])
    1624
    1725# Checks for libraries.
  • doc/Doxyfile

    • Property mode changed from 100755 to 100644
  • doc/Makefile.am

    • Property mode changed from 100755 to 100644
  • m4/ac_doxygen.m4

    • Property mode changed from 100644 to 120000
    r986c80 redcda5  
    1 # This file is part of Autoconf.                       -*- Autoconf -*-
    2 
    3 # Copyright (C) 2004 Oren Ben-Kiki
    4 # This file is distributed under the same terms as the Autoconf macro files.
    5 
    6 # Generate automatic documentation using Doxygen. Works in concert with the
    7 # aminclude.m4 file and a compatible doxygen configuration file. Defines the
    8 # following public macros:
    9 #
    10 # DX_???_FEATURE(ON|OFF) - control the default setting fo a Doxygen feature.
    11 # Supported features are 'DOXYGEN' itself, 'DOT' for generating graphics,
    12 # 'HTML' for plain HTML, 'CHM' for compressed HTML help (for MS users), 'CHI'
    13 # for generating a seperate .chi file by the .chm file, and 'MAN', 'RTF',
    14 # 'XML', 'PDF' and 'PS' for the appropriate output formats. The environment
    15 # variable DOXYGEN_PAPER_SIZE may be specified to override the default 'a4wide'
    16 # paper size.
    17 #
    18 # By default, HTML, PDF and PS documentation is generated as this seems to be
    19 # the most popular and portable combination. MAN pages created by Doxygen are
    20 # usually problematic, though by picking an appropriate subset and doing some
    21 # massaging they might be better than nothing. CHM and RTF are specific for MS
    22 # (note that you can't generate both HTML and CHM at the same time). The XML is
    23 # rather useless unless you apply specialized post-processing to it.
    24 #
    25 # The macro mainly controls the default state of the feature. The use can
    26 # override the default by specifying --enable or --disable. The macros ensure
    27 # that contradictory flags are not given (e.g., --enable-doxygen-html and
    28 # --enable-doxygen-chm, --enable-doxygen-anything with --disable-doxygen, etc.)
    29 # Finally, each feature will be automatically disabled (with a warning) if the
    30 # required programs are missing.
    31 #
    32 # Once all the feature defaults have been specified, call DX_INIT_DOXYGEN with
    33 # the following parameters: a one-word name for the project for use as a
    34 # filename base etc., an optional configuration file name (the default is
    35 # 'Doxyfile', the same as Doxygen's default), and an optional output directory
    36 # name (the default is 'doxygen-doc').
    37 
    38 ## ----------##
    39 ## Defaults. ##
    40 ## ----------##
    41 
    42 DX_ENV=""
    43 AC_DEFUN([DX_FEATURE_doc],  ON)
    44 AC_DEFUN([DX_FEATURE_dot],  ON)
    45 AC_DEFUN([DX_FEATURE_man],  OFF)
    46 AC_DEFUN([DX_FEATURE_html], ON)
    47 AC_DEFUN([DX_FEATURE_chm],  OFF)
    48 AC_DEFUN([DX_FEATURE_chi],  OFF)
    49 AC_DEFUN([DX_FEATURE_rtf],  OFF)
    50 AC_DEFUN([DX_FEATURE_xml],  OFF)
    51 AC_DEFUN([DX_FEATURE_pdf],  ON)
    52 AC_DEFUN([DX_FEATURE_ps],   ON)
    53 
    54 ## --------------- ##
    55 ## Private macros. ##
    56 ## --------------- ##
    57 
    58 # DX_ENV_APPEND(VARIABLE, VALUE)
    59 # ------------------------------
    60 # Append VARIABLE="VALUE" to DX_ENV for invoking doxygen.
    61 AC_DEFUN([DX_ENV_APPEND], [AC_SUBST([DX_ENV], ["$DX_ENV $1='$2'"])])
    62 
    63 # DX_DIRNAME_EXPR
    64 # ---------------
    65 # Expand into a shell expression prints the directory part of a path.
    66 AC_DEFUN([DX_DIRNAME_EXPR],
    67          [[expr ".$1" : '\(\.\)[^/]*$' \| "x$1" : 'x\(.*\)/[^/]*$']])
    68 
    69 # DX_IF_FEATURE(FEATURE, IF-ON, IF-OFF)
    70 # -------------------------------------
    71 # Expands according to the M4 (static) status of the feature.
    72 AC_DEFUN([DX_IF_FEATURE], [ifelse(DX_FEATURE_$1, ON, [$2], [$3])])
    73 
    74 # DX_REQUIRE_PROG(VARIABLE, PROGRAM)
    75 # ----------------------------------
    76 # Require the specified program to be found for the DX_CURRENT_FEATURE to work.
    77 AC_DEFUN([DX_REQUIRE_PROG], [
    78 AC_PATH_TOOL([$1], [$2])
    79 if test "$DX_FLAG_[]DX_CURRENT_FEATURE$$1" = 1; then
    80     AC_MSG_WARN([$2 not found - will not DX_CURRENT_DESCRIPTION])
    81     AC_SUBST([DX_FLAG_[]DX_CURRENT_FEATURE], 0)
    82 fi
    83 ])
    84 
    85 # DX_TEST_FEATURE(FEATURE)
    86 # ------------------------
    87 # Expand to a shell expression testing whether the feature is active.
    88 AC_DEFUN([DX_TEST_FEATURE], [test "$DX_FLAG_$1" = 1])
    89 
    90 # DX_CHECK_DEPEND(REQUIRED_FEATURE, REQUIRED_STATE)
    91 # -------------------------------------------------
    92 # Verify that a required features has the right state before trying to turn on
    93 # the DX_CURRENT_FEATURE.
    94 AC_DEFUN([DX_CHECK_DEPEND], [
    95 test "$DX_FLAG_$1" = "$2" \
    96 || AC_MSG_ERROR([doxygen-DX_CURRENT_FEATURE ifelse([$2], 1,
    97                             requires, contradicts) doxygen-DX_CURRENT_FEATURE])
    98 ])
    99 
    100 # DX_CLEAR_DEPEND(FEATURE, REQUIRED_FEATURE, REQUIRED_STATE)
    101 # ----------------------------------------------------------
    102 # Turn off the DX_CURRENT_FEATURE if the required feature is off.
    103 AC_DEFUN([DX_CLEAR_DEPEND], [
    104 test "$DX_FLAG_$1" = "$2" || AC_SUBST([DX_FLAG_[]DX_CURRENT_FEATURE], 0)
    105 ])
    106 
    107 # DX_FEATURE_ARG(FEATURE, DESCRIPTION,
    108 #                CHECK_DEPEND, CLEAR_DEPEND,
    109 #                REQUIRE, DO-IF-ON, DO-IF-OFF)
    110 # --------------------------------------------
    111 # Parse the command-line option controlling a feature. CHECK_DEPEND is called
    112 # if the user explicitly turns the feature on (and invokes DX_CHECK_DEPEND),
    113 # otherwise CLEAR_DEPEND is called to turn off the default state if a required
    114 # feature is disabled (using DX_CLEAR_DEPEND). REQUIRE performs additional
    115 # requirement tests (DX_REQUIRE_PROG). Finally, an automake flag is set and
    116 # DO-IF-ON or DO-IF-OFF are called according to the final state of the feature.
    117 AC_DEFUN([DX_ARG_ABLE], [
    118     AC_DEFUN([DX_CURRENT_FEATURE], [$1])
    119     AC_DEFUN([DX_CURRENT_DESCRIPTION], [$2])
    120     AC_ARG_ENABLE(doxygen-$1,
    121                   [AS_HELP_STRING(DX_IF_FEATURE([$1], [--disable-doxygen-$1],
    122                                                       [--enable-doxygen-$1]),
    123                                   DX_IF_FEATURE([$1], [don't $2], [$2]))],
    124                   [
    125 case "$enableval" in
    126 #(
    127 y|Y|yes|Yes|YES)
    128     AC_SUBST([DX_FLAG_$1], 1)
    129     $3
    130 ;; #(
    131 n|N|no|No|NO)
    132     AC_SUBST([DX_FLAG_$1], 0)
    133 ;; #(
    134 *)
    135     AC_MSG_ERROR([invalid value '$enableval' given to doxygen-$1])
    136 ;;
    137 esac
    138 ], [
    139 AC_SUBST([DX_FLAG_$1], [DX_IF_FEATURE([$1], 1, 0)])
    140 $4
    141 ])
    142 if DX_TEST_FEATURE([$1]); then
    143     $5
    144     :
    145 fi
    146 if DX_TEST_FEATURE([$1]); then
    147     AM_CONDITIONAL(DX_COND_$1, :)
    148     $6
    149     :
    150 else
    151     AM_CONDITIONAL(DX_COND_$1, false)
    152     $7
    153     :
    154 fi
    155 ])
    156 
    157 ## -------------- ##
    158 ## Public macros. ##
    159 ## -------------- ##
    160 
    161 # DX_XXX_FEATURE(DEFAULT_STATE)
    162 # -----------------------------
    163 AC_DEFUN([DX_DOXYGEN_FEATURE], [AC_DEFUN([DX_FEATURE_doc],  [$1])])
    164 AC_DEFUN([DX_MAN_FEATURE],     [AC_DEFUN([DX_FEATURE_man],  [$1])])
    165 AC_DEFUN([DX_HTML_FEATURE],    [AC_DEFUN([DX_FEATURE_html], [$1])])
    166 AC_DEFUN([DX_CHM_FEATURE],     [AC_DEFUN([DX_FEATURE_chm],  [$1])])
    167 AC_DEFUN([DX_CHI_FEATURE],     [AC_DEFUN([DX_FEATURE_chi],  [$1])])
    168 AC_DEFUN([DX_RTF_FEATURE],     [AC_DEFUN([DX_FEATURE_rtf],  [$1])])
    169 AC_DEFUN([DX_XML_FEATURE],     [AC_DEFUN([DX_FEATURE_xml],  [$1])])
    170 AC_DEFUN([DX_XML_FEATURE],     [AC_DEFUN([DX_FEATURE_xml],  [$1])])
    171 AC_DEFUN([DX_PDF_FEATURE],     [AC_DEFUN([DX_FEATURE_pdf],  [$1])])
    172 AC_DEFUN([DX_PS_FEATURE],      [AC_DEFUN([DX_FEATURE_ps],   [$1])])
    173 
    174 # DX_INIT_DOXYGEN(PROJECT, [CONFIG-FILE], [OUTPUT-DOC-DIR])
    175 # ---------------------------------------------------------
    176 # PROJECT also serves as the base name for the documentation files.
    177 # The default CONFIG-FILE is "Doxyfile" and OUTPUT-DOC-DIR is "doxygen-doc".
    178 AC_DEFUN([DX_INIT_DOXYGEN], [
    179 
    180 # Files:
    181 AC_SUBST([DX_PROJECT], [$1])
    182 AC_SUBST([DX_CONFIG], [ifelse([$2], [], Doxyfile, [$2])])
    183 AC_SUBST([DX_DOCDIR], [ifelse([$3], [], doxygen-doc, [$3])])
    184 
    185 # Environment variables used inside doxygen.cfg:
    186 DX_ENV_APPEND(SRCDIR, $srcdir)
    187 DX_ENV_APPEND(PROJECT, $DX_PROJECT)
    188 DX_ENV_APPEND(DOCDIR, $DX_DOCDIR)
    189 DX_ENV_APPEND(VERSION, $PACKAGE_VERSION)
    190 
    191 # Doxygen itself:
    192 DX_ARG_ABLE(doc, [generate any doxygen documentation],
    193             [],
    194             [],
    195             [DX_REQUIRE_PROG([DX_DOXYGEN], doxygen)
    196              DX_REQUIRE_PROG([DX_PERL], perl)],
    197             [DX_ENV_APPEND(PERL_PATH, $DX_PERL)])
    198 
    199 # Dot for graphics:
    200 DX_ARG_ABLE(dot, [generate graphics for doxygen documentation],
    201             [DX_CHECK_DEPEND(doc, 1)],
    202             [DX_CLEAR_DEPEND(doc, 1)],
    203             [DX_REQUIRE_PROG([DX_DOT], dot)],
    204             [DX_ENV_APPEND(HAVE_DOT, YES)
    205              DX_ENV_APPEND(DOT_PATH, [`DX_DIRNAME_EXPR($DX_DOT)`])],
    206             [DX_ENV_APPEND(HAVE_DOT, NO)])
    207 
    208 # Man pages generation:
    209 DX_ARG_ABLE(man, [generate doxygen manual pages],
    210             [DX_CHECK_DEPEND(doc, 1)],
    211             [DX_CLEAR_DEPEND(doc, 1)],
    212             [],
    213             [DX_ENV_APPEND(GENERATE_MAN, YES)],
    214             [DX_ENV_APPEND(GENERATE_MAN, NO)])
    215 
    216 # RTF file generation:
    217 DX_ARG_ABLE(rtf, [generate doxygen RTF documentation],
    218             [DX_CHECK_DEPEND(doc, 1)],
    219             [DX_CLEAR_DEPEND(doc, 1)],
    220             [],
    221             [DX_ENV_APPEND(GENERATE_RTF, YES)],
    222             [DX_ENV_APPEND(GENERATE_RTF, NO)])
    223 
    224 # XML file generation:
    225 DX_ARG_ABLE(xml, [generate doxygen XML documentation],
    226             [DX_CHECK_DEPEND(doc, 1)],
    227             [DX_CLEAR_DEPEND(doc, 1)],
    228             [],
    229             [DX_ENV_APPEND(GENERATE_XML, YES)],
    230             [DX_ENV_APPEND(GENERATE_XML, NO)])
    231 
    232 # (Compressed) HTML help generation:
    233 DX_ARG_ABLE(chm, [generate doxygen compressed HTML help documentation],
    234             [DX_CHECK_DEPEND(doc, 1)],
    235             [DX_CLEAR_DEPEND(doc, 1)],
    236             [DX_REQUIRE_PROG([DX_HHC], hhc)],
    237             [DX_ENV_APPEND(HHC_PATH, $DX_HHC)
    238              DX_ENV_APPEND(GENERATE_HTML, YES)
    239              DX_ENV_APPEND(GENERATE_HTMLHELP, YES)],
    240             [DX_ENV_APPEND(GENERATE_HTMLHELP, NO)])
    241 
    242 # Seperate CHI file generation.
    243 DX_ARG_ABLE(chi, [generate doxygen seperate compressed HTML help index file],
    244             [DX_CHECK_DEPEND(chm, 1)],
    245             [DX_CLEAR_DEPEND(chm, 1)],
    246             [],
    247             [DX_ENV_APPEND(GENERATE_CHI, YES)],
    248             [DX_ENV_APPEND(GENERATE_CHI, NO)])
    249 
    250 # Plain HTML pages generation:
    251 DX_ARG_ABLE(html, [generate doxygen plain HTML documentation],
    252             [DX_CHECK_DEPEND(doc, 1) DX_CHECK_DEPEND(chm, 0)],
    253             [DX_CLEAR_DEPEND(doc, 1) DX_CLEAR_DEPEND(chm, 0)],
    254             [],
    255             [DX_ENV_APPEND(GENERATE_HTML, YES)],
    256             [DX_TEST_FEATURE(chm) || DX_ENV_APPEND(GENERATE_HTML, NO)])
    257 
    258 # PostScript file generation:
    259 DX_ARG_ABLE(ps, [generate doxygen PostScript documentation],
    260             [DX_CHECK_DEPEND(doc, 1)],
    261             [DX_CLEAR_DEPEND(doc, 1)],
    262             [DX_REQUIRE_PROG([DX_LATEX], latex)
    263              DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)
    264              DX_REQUIRE_PROG([DX_DVIPS], dvips)
    265              DX_REQUIRE_PROG([DX_EGREP], egrep)])
    266 
    267 # PDF file generation:
    268 DX_ARG_ABLE(pdf, [generate doxygen PDF documentation],
    269             [DX_CHECK_DEPEND(doc, 1)],
    270             [DX_CLEAR_DEPEND(doc, 1)],
    271             [DX_REQUIRE_PROG([DX_PDFLATEX], pdflatex)
    272              DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)
    273              DX_REQUIRE_PROG([DX_EGREP], egrep)])
    274 
    275 # LaTeX generation for PS and/or PDF:
    276 if DX_TEST_FEATURE(ps) || DX_TEST_FEATURE(pdf); then
    277     AM_CONDITIONAL(DX_COND_latex, :)
    278     DX_ENV_APPEND(GENERATE_LATEX, YES)
    279 else
    280     AM_CONDITIONAL(DX_COND_latex, false)
    281     DX_ENV_APPEND(GENERATE_LATEX, NO)
    282 fi
    283 
    284 # Paper size for PS and/or PDF:
    285 AC_ARG_VAR(DOXYGEN_PAPER_SIZE,
    286            [a4wide (default), a4, letter, legal or executive])
    287 case "$DOXYGEN_PAPER_SIZE" in
    288 #(
    289 "")
    290     AC_SUBST(DOXYGEN_PAPER_SIZE, "")
    291 ;; #(
    292 a4wide|a4|letter|legal|executive)
    293     DX_ENV_APPEND(PAPER_SIZE, $DOXYGEN_PAPER_SIZE)
    294 ;; #(
    295 *)
    296     AC_MSG_ERROR([unknown DOXYGEN_PAPER_SIZE='$DOXYGEN_PAPER_SIZE'])
    297 ;;
    298 esac
    299 
    300 #For debugging:
    301 #echo DX_FLAG_doc=$DX_FLAG_doc
    302 #echo DX_FLAG_dot=$DX_FLAG_dot
    303 #echo DX_FLAG_man=$DX_FLAG_man
    304 #echo DX_FLAG_html=$DX_FLAG_html
    305 #echo DX_FLAG_chm=$DX_FLAG_chm
    306 #echo DX_FLAG_chi=$DX_FLAG_chi
    307 #echo DX_FLAG_rtf=$DX_FLAG_rtf
    308 #echo DX_FLAG_xml=$DX_FLAG_xml
    309 #echo DX_FLAG_pdf=$DX_FLAG_pdf
    310 #echo DX_FLAG_ps=$DX_FLAG_ps
    311 #echo DX_ENV=$DX_ENV
    312 ])
     1../../m4/ac_doxygen.m4
  • m4/acx_compilerflags.m4

    • Property mode changed from 100644 to 120000
    r986c80 redcda5  
    1 # AC_SET_COMPILER_FLAGS(optimization, debugging, warnings)
    2 #----------------------------------------------------------------
    3 AC_DEFUN([AC_SET_COMPILER_FLAGS],[
    4 AC_MSG_NOTICE([Using AC@&t@_SET_COMPILER_FLAGS macro])
    5 
    6 dnl optimization
    7 if test ! x"$1" = xno; then
    8         if test x"$2" = xno; then
    9                 if test x"$1" = xyes; then
    10                         optimization="-O2"
    11                 else
    12                         optimization="-O$1"
    13                 fi
    14         fi
    15 fi
    16 dnl debugging info
    17 if ! test x"$2" = xno; then
    18         if test x"$2" = xyes; then
    19                 debugging="-g3"
    20         else
    21                 debugging="-g$2"
    22         fi
    23   AC_DEFINE(HAVE_DEBUG,1, ["Output debugging info"])
    24   AC_SUBST(HAVE_DEBUG)
    25 fi
    26 
    27 dnl enable all warnings
    28 if test x"$3" = xsome; then
    29         dnl even without debugging we want some minimal info of something's utterly wrong
    30         Cwarnings="-Wall"
    31         CXXwarnings="-Wall"
    32 fi
    33 if test x"$3" = xfull; then
    34         Cwarnings="-Wall -W -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -Wshadow -Wpointer-arith -Wcast-align -Wcast-qual -Wwrite-strings -Wredundant-decls -Wnested-externs -Wmissing-noreturn -Wformat-security -Wmissing-format-attribute -Winit-self"
    35         CXXwarnings="-Wall -W -Wshadow -Wpointer-arith -Wcast-align -Wcast-qual -Wwrite-strings -Wredundant-decls -Wmissing-noreturn -Wformat-security -Wmissing-format-attribute -Winit-self"
    36 fi
    37 if test x"$3" = xnone; then
    38         unset Cwarnings
    39         unset CXXwarnings
    40 else
    41         AC_DEFINE(HAVE_WARNINGS,$enable_warnings, ["Output compiler warnings"])
    42 fi
    43 
    44 # finally, apply whatever was set
    45 CFLAGS="$CFLAGS $debugging $optimization $Cwarnings"
    46 CXXFLAGS="$CXXFLAGS $debugging $optimization $CXXwarnings"
    47 
    48 ])
     1../../m4/acx_compilerflags.m4
  • src/Hbondangle.db

    • Property mode changed from 100755 to 100644
    r986c80 redcda5  
    447       180     110     106.67
    558       180     104.5   -1
    6 14      180     120     109.47
     614      180     120     109.5
    7715      180     -1      -1
    8816      180     -1      -1
    9917      180 -1 -1
    10 20      180     120     109.47
    111034      180 -1 -1
    121135      180 -1 -1
  • src/Hbonddistance.db

    • Property mode changed from 100755 to 100644
    r986c80 redcda5  
    9916      1.35    -1      -1
    101017      1.29    -1      -1
    11 20      1.09    1.09    -1
    121134      1.47    -1      -1
    131235      1.44    -1      -1
  • src/Makefile.am

    • Property mode changed from 100755 to 100644
    r986c80 redcda5  
    1010
    1111
    12 EXTRA_DIST = ${molecuilder_DATA}
     12#EXTRA_DIST = ${molecuilder_DATA}
  • src/analyzer.cpp

    • Property mode changed from 100755 to 100644
    r986c80 redcda5  
    2525  periodentafel *periode = NULL; // and a period table of all elements
    2626  EnergyMatrix Energy;
    27   EnergyMatrix EnergyFragments;
     27  EnergyMatrix Hcorrection;
    2828  ForceMatrix Force;
    29   ForceMatrix ForceFragments;
    30   HessianMatrix Hessian;
    31   HessianMatrix HessianFragments;
    32   EnergyMatrix Hcorrection;
    33   EnergyMatrix HcorrectionFragments;
    3429  ForceMatrix Shielding;
    3530  ForceMatrix ShieldingPAS;
    36   ForceMatrix Chi;
    37   ForceMatrix ChiPAS;
    3831  EnergyMatrix Time;
     32  EnergyMatrix EnergyFragments;
     33  EnergyMatrix HcorrectionFragments;
     34  ForceMatrix ForceFragments;
    3935  ForceMatrix ShieldingFragments;
    4036  ForceMatrix ShieldingPASFragments;
    41   ForceMatrix ChiFragments;
    42   ForceMatrix ChiPASFragments;
    4337  KeySetsContainer KeySet;
    4438  ofstream output;
     
    5549  stringstream yrange;
    5650  char *dir = NULL;
    57   bool NoHCorrection = false;
    58   bool NoHessian = false;
    59   bool NoTime = false;
     51  bool Hcorrected = true;
     52  double norm;
    6053  int counter;
    6154 
     
    9184  // ------------- Parse through all Fragment subdirs --------
    9285  if (!Energy.ParseFragmentMatrix(argv[1], dir, EnergySuffix,0,0)) return 1;
    93   if (!Hcorrection.ParseFragmentMatrix(argv[1], "", HCORRECTIONSUFFIX,0,0)) {
    94     NoHCorrection = true;
    95     cout << "No HCorrection file found, skipping these." << endl;
    96   }
    97  
     86  Hcorrected = Hcorrection.ParseFragmentMatrix(argv[1], "", HCORRECTIONSUFFIX,0,0);
    9887  if (!Force.ParseFragmentMatrix(argv[1], dir, ForcesSuffix,0,0)) return 1;
    99   if (!Hessian.ParseFragmentMatrix(argv[1], dir, HessianSuffix,0,0)) {
    100     NoHessian = true;
    101     cout << "No Hessian file found, skipping these." << endl;
    102   }
    103   if (!Time.ParseFragmentMatrix(argv[1], dir, TimeSuffix, 10,1)) {
    104     NoTime = true;
    105     cout << "No speed file found, skipping these." << endl;
    106   }
     88  if (!Time.ParseFragmentMatrix(argv[1], dir, TimeSuffix, 10,1)) return 1;
    10789  if (periode != NULL) { // also look for PAS values
    10890    if (!Shielding.ParseFragmentMatrix(argv[1], dir, ShieldingSuffix, 1, 0)) return 1;
    10991    if (!ShieldingPAS.ParseFragmentMatrix(argv[1], dir, ShieldingPASSuffix, 1, 0)) return 1;
    110     if (!Chi.ParseFragmentMatrix(argv[1], dir, ChiSuffix, 1, 0)) return 1;
    111     if (!ChiPAS.ParseFragmentMatrix(argv[1], dir, ChiPASSuffix, 1, 0)) return 1;
    11292  }
    11393
    11494  // ---------- Parse the TE Factors into an array -----------------
    115   if (!Energy.InitialiseIndices()) return 1;
    116   if (!NoHCorrection)
    117     Hcorrection.InitialiseIndices();
     95  if (!Energy.ParseIndices()) return 1;
     96  if (Hcorrected) Hcorrection.ParseIndices();
    11897 
    11998  // ---------- Parse the Force indices into an array ---------------
    12099  if (!Force.ParseIndices(argv[1])) return 1;
    121100  if (!ForceFragments.AllocateMatrix(Force.Header, Force.MatrixCounter, Force.RowCounter, Force.ColumnCounter)) return 1;
    122   if (!ForceFragments.InitialiseIndices((class MatrixContainer *)&Force)) return 1;
    123 
    124   // ---------- Parse hessian indices into an array -----------------
    125   if (!NoHessian) {
    126     if (!Hessian.InitialiseIndices((class MatrixContainer *)&Force)) return 1;
    127     if (!HessianFragments.AllocateMatrix(Hessian.Header, Hessian.MatrixCounter, Hessian.RowCounter, Hessian.ColumnCounter)) return 1;
    128     if (!HessianFragments.InitialiseIndices((class MatrixContainer *)&Force)) return 1;
    129   }
     101  if (!ForceFragments.ParseIndices(argv[1])) return 1;
    130102
    131103  // ---------- Parse the shielding indices into an array ---------------
     
    133105    if(!Shielding.ParseIndices(argv[1])) return 1;
    134106    if(!ShieldingPAS.ParseIndices(argv[1])) return 1;
    135     if (!ShieldingFragments.AllocateMatrix(Shielding.Header, Shielding.MatrixCounter, Shielding.RowCounter, Shielding.ColumnCounter)) return 1;
    136     if (!ShieldingPASFragments.AllocateMatrix(ShieldingPAS.Header, ShieldingPAS.MatrixCounter, ShieldingPAS.RowCounter, ShieldingPAS.ColumnCounter)) return 1;
    137     if(!ShieldingFragments.ParseIndices(argv[1])) return 1;
    138     if(!ShieldingPASFragments.ParseIndices(argv[1])) return 1;
    139     if(!Chi.ParseIndices(argv[1])) return 1;
    140     if(!ChiPAS.ParseIndices(argv[1])) return 1;
    141     if (!ChiFragments.AllocateMatrix(Chi.Header, Chi.MatrixCounter, Chi.RowCounter, Chi.ColumnCounter)) return 1;
    142     if (!ChiPASFragments.AllocateMatrix(ChiPAS.Header, ChiPAS.MatrixCounter, ChiPAS.RowCounter, ChiPAS.ColumnCounter)) return 1;
    143     if(!ChiFragments.ParseIndices(argv[1])) return 1;
    144     if(!ChiPASFragments.ParseIndices(argv[1])) return 1;
    145107  }
    146108
     
    151113  // ---------- Parse fragment files created by 'joiner' into an array -------------
    152114  if (!EnergyFragments.ParseFragmentMatrix(argv[1], dir, EnergyFragmentSuffix,0,0)) return 1;
    153   if (!NoHCorrection)
    154     HcorrectionFragments.ParseFragmentMatrix(argv[1], dir, HcorrectionFragmentSuffix,0,0);
     115  if (Hcorrected) HcorrectionFragments.ParseFragmentMatrix(argv[1], dir, HcorrectionFragmentSuffix,0,0);
    155116  if (!ForceFragments.ParseFragmentMatrix(argv[1], dir, ForceFragmentSuffix,0,0)) return 1;
    156   if (!NoHessian)
    157     if (!HessianFragments.ParseFragmentMatrix(argv[1], dir, HessianFragmentSuffix,0,0)) return 1;
    158117  if (periode != NULL) { // also look for PAS values
    159     if (!ShieldingFragments.ParseFragmentMatrix(argv[1], dir, ShieldingFragmentSuffix, 1, 0)) return 1;
    160     if (!ShieldingPASFragments.ParseFragmentMatrix(argv[1], dir, ShieldingPASFragmentSuffix, 1, 0)) return 1;
    161     if (!ChiFragments.ParseFragmentMatrix(argv[1], dir, ChiFragmentSuffix, 1, 0)) return 1;
    162     if (!ChiPASFragments.ParseFragmentMatrix(argv[1], dir, ChiPASFragmentSuffix, 1, 0)) return 1;
     118    if (!ShieldingFragments.ParseFragmentMatrix(argv[1], dir, ShieldingSuffix, 1, 0)) return 1;
     119    if (!ShieldingPASFragments.ParseFragmentMatrix(argv[1], dir, ShieldingPASSuffix, 1, 0)) return 1;
    163120  }
    164121
     
    169126  filename << argv[3] << "/" << "energy-forces.all";
    170127  output.open(filename.str().c_str(), ios::out);
    171   output << endl << "Total Energy" << endl << "==============" << endl << Energy.Header[Energy.MatrixCounter] << endl;
     128  output << endl << "Total Energy" << endl << "==============" << endl << Energy.Header << endl;
    172129  for(int j=0;j<Energy.RowCounter[Energy.MatrixCounter];j++) {
    173     for(int k=0;k<Energy.ColumnCounter[Energy.MatrixCounter];k++)
     130    for(int k=0;k<Energy.ColumnCounter;k++)
    174131      output << scientific << Energy.Matrix[ Energy.MatrixCounter ][j][k] << "\t";
    175132    output << endl;
     
    177134  output << endl;
    178135 
    179   output << endl << "Total Forces" << endl << "===============" << endl << Force.Header[Force.MatrixCounter] << endl;
     136  output << endl << "Total Forces" << endl << "===============" << endl << Force.Header << endl;
    180137  for(int j=0;j<Force.RowCounter[Force.MatrixCounter];j++) {
    181     for(int k=0;k<Force.ColumnCounter[Force.MatrixCounter];k++)
     138    for(int k=0;k<Force.ColumnCounter;k++)
    182139      output << scientific << Force.Matrix[ Force.MatrixCounter ][j][k] << "\t";
    183140    output << endl;
     
    185142  output << endl;
    186143
    187   if (!NoHessian) {
    188     output << endl << "Total Hessian" << endl << "===============" << endl << Hessian.Header[Hessian.MatrixCounter] << endl;
    189     for(int j=0;j<Hessian.RowCounter[Hessian.MatrixCounter];j++) {
    190       for(int k=0;k<Hessian.ColumnCounter[Hessian.MatrixCounter];k++)
    191         output << scientific << Hessian.Matrix[ Hessian.MatrixCounter ][j][k] << "\t";
    192       output << endl;
    193     }
    194     output << endl;
    195   }
    196 
    197144  if (periode != NULL) { // also look for PAS values
    198     output << endl << "Total Shieldings" << endl << "===============" << endl << Shielding.Header[Hessian.MatrixCounter] << endl;
     145    output << endl << "Total Shieldings" << endl << "===============" << endl << Shielding.Header << endl;
    199146    for(int j=0;j<Shielding.RowCounter[Shielding.MatrixCounter];j++) {
    200       for(int k=0;k<Shielding.ColumnCounter[Shielding.MatrixCounter];k++)
     147      for(int k=0;k<Shielding.ColumnCounter;k++)
    201148        output << scientific << Shielding.Matrix[ Shielding.MatrixCounter ][j][k] << "\t";
    202149      output << endl;
     
    204151    output << endl;
    205152 
    206     output << endl << "Total Shieldings PAS" << endl << "===============" << endl << ShieldingPAS.Header[ShieldingPAS.MatrixCounter] << endl;
     153    output << endl << "Total Shieldings PAS" << endl << "===============" << endl << ShieldingPAS.Header << endl;
    207154    for(int j=0;j<ShieldingPAS.RowCounter[ShieldingPAS.MatrixCounter];j++) {
    208       for(int k=0;k<ShieldingPAS.ColumnCounter[ShieldingPAS.MatrixCounter];k++)
     155      for(int k=0;k<ShieldingPAS.ColumnCounter;k++)
    209156        output << scientific << ShieldingPAS.Matrix[ ShieldingPAS.MatrixCounter ][j][k] << "\t";
    210157      output << endl;
    211158    }
    212159    output << endl;
    213 
    214     output << endl << "Total Chis" << endl << "===============" << endl << Chi.Header[Chi.MatrixCounter] << endl;
    215     for(int j=0;j<Chi.RowCounter[Chi.MatrixCounter];j++) {
    216       for(int k=0;k<Chi.ColumnCounter[Chi.MatrixCounter];k++)
    217         output << scientific << Chi.Matrix[ Chi.MatrixCounter ][j][k] << "\t";
    218       output << endl;
    219     }
    220     output << endl;
    221  
    222     output << endl << "Total Chis PAS" << endl << "===============" << endl << ChiPAS.Header[ChiPAS.MatrixCounter] << endl;
    223     for(int j=0;j<ChiPAS.RowCounter[ChiPAS.MatrixCounter];j++) {
    224       for(int k=0;k<ChiPAS.ColumnCounter[ChiPAS.MatrixCounter];k++)
    225         output << scientific << ChiPAS.Matrix[ ChiPAS.MatrixCounter ][j][k] << "\t";
    226       output << endl;
    227     }
    228     output << endl;
    229   }
    230  
    231   if (!NoTime) {
    232     output << endl << "Total Times" << endl << "===============" << endl << Time.Header[Time.MatrixCounter] << endl;
    233     for(int j=0;j<Time.RowCounter[Time.MatrixCounter];j++) {
    234       for(int k=0;k<Time.ColumnCounter[Time.MatrixCounter];k++) {
    235         output << scientific << Time.Matrix[ Time.MatrixCounter ][j][k] << "\t";
    236       }
    237       output << endl;
    238     }
    239     output << endl;
    240   }
     160  }
     161 
     162  output << endl << "Total Times" << endl << "===============" << endl << Time.Header << endl;
     163  for(int j=0;j<Time.RowCounter[Time.MatrixCounter];j++) {
     164    for(int k=0;k<Time.ColumnCounter;k++) {
     165      output << scientific << Time.Matrix[ Time.MatrixCounter ][j][k] << "\t";
     166    }
     167    output << endl;
     168  }
     169  output << endl;
    241170  output.close();
    242   if (!NoTime)
    243     for(int k=0;k<Time.ColumnCounter[Time.MatrixCounter];k++)
    244       Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter] ][k] = Time.Matrix[ Time.MatrixCounter ][Time.RowCounter[Time.MatrixCounter]-1][k];
     171  for(int k=0;k<Time.ColumnCounter;k++)
     172    Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter] ][k] = Time.Matrix[ Time.MatrixCounter ][Time.RowCounter[Time.MatrixCounter]-1][k];
    245173
    246174  // +++++++++++++++ ANALYZING ++++++++++++++++++++++++++++++
     
    252180  // +++++++++++++++++++++++++++++++++++++++ Plotting Simtime vs Bond Order
    253181  // +++++++++++++++++++++++++++++++++++++++ Plotting Delta Simtime vs Bond Order
    254   if (!NoTime) {
    255     if (!OpenOutputFile(output, argv[3], "SimTime-Order.dat" )) return false;
    256     if (!OpenOutputFile(output2, argv[3], "DeltaSimTime-Order.dat" )) return false;
    257     for(int j=Time.RowCounter[Time.MatrixCounter];j--;)
    258       for(int k=Time.ColumnCounter[Time.MatrixCounter];k--;) {
    259         Time.Matrix[ Time.MatrixCounter ][j][k] = 0.;
    260       }
    261     counter = 0;
    262     output << "#Order\tFrag.No.\t" << Time.Header[Time.MatrixCounter] << endl;
    263     output2 << "#Order\tFrag.No.\t" << Time.Header[Time.MatrixCounter] << endl;
    264     for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
    265       for(int i=KeySet.FragmentsPerOrder[BondOrder];i--;)
    266         for(int j=Time.RowCounter[Time.MatrixCounter];j--;)
    267           for(int k=Time.ColumnCounter[Time.MatrixCounter];k--;) {
    268             Time.Matrix[ Time.MatrixCounter ][j][k] += Time.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k];
    269           }
    270       counter += KeySet.FragmentsPerOrder[BondOrder];
    271       output << BondOrder+1 << "\t" << counter;
    272       output2 << BondOrder+1 << "\t" << counter;
    273       for(int k=0;k<Time.ColumnCounter[Time.MatrixCounter];k++) {
    274         output << "\t" << scientific << Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter]-1 ][k];
    275         if (fabs(Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter] ][k]) > MYEPSILON)
    276           output2 << "\t" << scientific << Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter]-1 ][k] / Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter] ][k];
    277         else
    278           output2 << "\t" << scientific << Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter]-1 ][k];
    279       }
    280       output << endl;
    281       output2 << endl;
    282     }
    283     output.close();
    284     output2.close();
    285   }
    286 
    287   if (!NoHessian) {
    288     // +++++++++++++++++++++++++++++++++++++++ Plotting deviation in hessian to full QM
    289     if (!CreateDataDeltaHessianOrderPerAtom(Hessian, HessianFragments, KeySet, argv[3], "DeltaHessian_xx-Order", "Plot of error between approximated hessian and full hessian versus the Bond Order", datum)) return 1;
    290 
    291     if (!CreateDataDeltaFrobeniusOrderPerAtom(Hessian, HessianFragments, KeySet, argv[3], "DeltaFrobeniusHessian_xx-Order", "Plot of error between approximated hessian and full hessian in the frobenius norm versus the Bond Order", datum)) return 1;
    292 
    293     // ++++++++++++++++++++++++++++++++++++++Plotting Hessian vs. Order
    294     if (!CreateDataHessianOrderPerAtom(HessianFragments, KeySet, argv[3], "Hessian_xx-Order", "Plot of approximated hessian versus the Bond Order", datum)) return 1;
    295     if (!AppendOutputFile(output, argv[3], "Hessian_xx-Order.dat" )) return false;
    296     output << endl << "# Full" << endl;
    297     for(int j=0;j<Hessian.RowCounter[Hessian.MatrixCounter];j++) {
    298       output << j << "\t";
    299       for(int k=0;k<Hessian.ColumnCounter[Force.MatrixCounter];k++)
    300         output << scientific <<  Hessian.Matrix[ Hessian.MatrixCounter ][j][k] << "\t";
    301       output << endl;
    302     }
    303     output.close();
    304   }
    305 
    306   // +++++++++++++++++++++++++++++++++++++++ Plotting shieldings
    307   if (periode != NULL) { // also look for PAS values
    308     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;
    309     if (!CreateDataForcesOrderPerAtom(ShieldingPASFragments, KeySet, argv[3], "ShieldingsPAS-Order", "Plot of approximated shieldings versus the Bond Order", datum)) return 1;
    310     if (!AppendOutputFile(output, argv[3], "ShieldingsPAS-Order.dat" )) return false;
    311     output << endl << "# Full" << endl;
    312     for(int j=0;j<ShieldingPAS.RowCounter[ShieldingPAS.MatrixCounter];j++) {
    313       output << j << "\t";
    314       for(int k=0;k<ShieldingPAS.ColumnCounter[ShieldingPAS.MatrixCounter];k++)
    315         output << scientific <<  ShieldingPAS.Matrix[ ShieldingPAS.MatrixCounter ][j][k] << "\t"; //*(((k>1) && (k<6))? 1.e6 : 1.) << "\t";
    316       output << endl;
    317     }
    318     output.close();
    319     if (!CreateDataDeltaForcesOrderPerAtom(ChiPAS, ChiPASFragments, KeySet, argv[3], "DeltaChisPAS-Order", "Plot of error between approximated Chis and full Chis versus the Bond Order", datum)) return 1;
    320     if (!CreateDataForcesOrderPerAtom(ChiPASFragments, KeySet, argv[3], "ChisPAS-Order", "Plot of approximated Chis versus the Bond Order", datum)) return 1;
    321     if (!AppendOutputFile(output, argv[3], "ChisPAS-Order.dat" )) return false;
    322     output << endl << "# Full" << endl;
    323     for(int j=0;j<ChiPAS.RowCounter[ChiPAS.MatrixCounter];j++) {
    324       output << j << "\t";
    325       for(int k=0;k<ChiPAS.ColumnCounter[ChiPAS.MatrixCounter];k++)
    326         output << scientific <<  ChiPAS.Matrix[ ChiPAS.MatrixCounter ][j][k] << "\t"; //*(((k>1) && (k<6))? 1.e6 : 1.) << "\t";
    327       output << endl;
    328     }
    329     output.close();
    330   }
    331 
    332  
     182  if (!OpenOutputFile(output, argv[3], "SimTime-Order.dat" )) return false;
     183  if (!OpenOutputFile(output2, argv[3], "DeltaSimTime-Order.dat" )) return false;
     184  for(int j=Time.RowCounter[Time.MatrixCounter];j--;)
     185    for(int k=Time.ColumnCounter;k--;) {
     186      Time.Matrix[ Time.MatrixCounter ][j][k] = 0.;
     187    }
     188  counter = 0;
     189  output << "#Order\tFrag.No.\t" << Time.Header << endl;
     190  output2 << "#Order\tFrag.No.\t" << Time.Header << endl;
     191  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
     192    for(int i=KeySet.FragmentsPerOrder[BondOrder];i--;)
     193      for(int j=Time.RowCounter[Time.MatrixCounter];j--;)
     194        for(int k=Time.ColumnCounter;k--;) {
     195          Time.Matrix[ Time.MatrixCounter ][j][k] += Time.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k];
     196        }
     197    counter += KeySet.FragmentsPerOrder[BondOrder];
     198    output << BondOrder+1 << "\t" << counter;
     199    output2 << BondOrder+1 << "\t" << counter;
     200    for(int k=0;k<Time.ColumnCounter;k++) {
     201      output << "\t" << scientific << Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter]-1 ][k];
     202      if (fabs(Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter] ][k]) > MYEPSILON)
     203        output2 << "\t" << scientific << Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter]-1 ][k] / Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter] ][k];
     204      else
     205        output2 << "\t" << scientific << Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter]-1 ][k];
     206    }
     207    output << endl;
     208    output2 << endl;
     209  }
     210  output.close();
     211  output2.close();
     212
     213
    333214  // +++++++++++++++++++++++++++++++++++++++ Plotting deviation in energy to full QM
    334215  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;
     
    351232  // ++++++++++++++++++++++++++++++++++++++Plotting Forces vs. Order
    352233  if (!CreateDataForcesOrderPerAtom(ForceFragments, KeySet, argv[3], "Forces-Order", "Plot of approximated forces versus the Bond Order", datum)) return 1;
    353   if (!AppendOutputFile(output, argv[3], "Forces-Order.dat" )) return false;
    354   output << endl << "# Full" << endl;
    355   for(int j=0;j<Force.RowCounter[Force.MatrixCounter];j++) {
    356     output << j << "\t";
    357     for(int k=0;k<Force.ColumnCounter[Force.MatrixCounter];k++)
    358       output << scientific <<  Force.Matrix[ Force.MatrixCounter ][j][k] << "\t";
    359     output << endl;
    360   }
    361   output.close();
     234
    362235  // min force
    363236  if (!CreateDataForcesOrder(ForceFragments, KeySet, argv[3], "MinForces-Order", "Plot of min approximated forces versus the Bond Order", datum, CreateMinimumForce)) return 1;
     
    404277  yrange.str("[1e-8:1e+1]");
    405278 
    406   if (!NoTime) {
    407     // +++++++++++++++++++++++++++++++++++++++ Plotting Simtime vs Bond Order
    408     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;
    409   }
     279  // +++++++++++++++++++++++++++++++++++++++ Plotting Simtime vs Bond Order
     280  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;
    410281 
    411282  // +++++++++++++++++++++++++++++++++++++++ Plotting deviation in energy to full QM
     
    488359  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;
    489360 
    490   // +++++++++++++++++++++++++++++++=Ploting approximated and true shielding for each atom
    491   if (periode != NULL) { // also look for PAS values
    492     if(!OpenOutputFile(output, argv[3], "ShieldingsPAS-Order.pyx")) return 1;
    493     if(!OpenOutputFile(output2, argv[3], "DeltaShieldingsPAS-Order.pyx")) return 1;
    494     CreatePlotHeader(output, "ShieldingsPAS-Order", 1, "top right", NULL, NULL,  1, 5, "nuclei index", "iso chemical shielding value [ppm]");
    495     CreatePlotHeader(output2, "DeltaShieldingsPAS-Order", 1, "top right", NULL, NULL,  1, 5, "nuclei index", "iso chemical shielding value [ppm]");
    496     double step=0.8/KeySet.Order;
    497     output << "set boxwidth " << step << endl;
    498     output << "plot [0:" << ShieldingPAS.RowCounter[ShieldingPAS.MatrixCounter]+10 << "]\\" << endl;
    499     output2 << "plot [0:" << ShieldingPAS.RowCounter[ShieldingPAS.MatrixCounter]+10 << "]\\" << endl;
    500     for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
    501       output << "'ShieldingsPAS-Order.dat' index " << BondOrder << " title 'Order " << BondOrder+1 << "' using ($1+" << step*(double)BondOrder << "):7 with boxes, \\" << endl;
    502       output2 << "'DeltaShieldingsPAS-Order.dat' index " << BondOrder << " title 'Order " << BondOrder+1 << "' using ($1):7 with linespoints";
    503       if (BondOrder-1 != KeySet.Order)
    504         output2 << ", \\" << endl;
    505     }
    506     output << "'ShieldingsPAS-Order.dat' index " << KeySet.Order << " title 'Full' using ($1+" << step*(double)KeySet.Order << "):7 with boxes" << endl;
    507     output2.close(); 
    508 
    509     if(!OpenOutputFile(output, argv[3], "ChisPAS-Order.pyx")) return 1;
    510     if(!OpenOutputFile(output2, argv[3], "DeltaChisPAS-Order.pyx")) return 1;
    511     CreatePlotHeader(output, "ChisPAS-Order", 1, "top right", NULL, NULL,  1, 5, "nuclei index", "iso chemical Chi value [ppm]");
    512     CreatePlotHeader(output2, "DeltaChisPAS-Order", 1, "top right", NULL, NULL,  1, 5, "nuclei index", "iso chemical Chi value [ppm]");
    513     output << "set boxwidth " << step << endl;
    514     output << "plot [0:" << ChiPAS.RowCounter[ChiPAS.MatrixCounter]+10 << "]\\" << endl;
    515     output2 << "plot [0:" << ChiPAS.RowCounter[ChiPAS.MatrixCounter]+10 << "]\\" << endl;
    516     for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
    517       output << "'ChisPAS-Order.dat' index " << BondOrder << " title 'Order " << BondOrder+1 << "' using ($1+" << step*(double)BondOrder << "):7 with boxes, \\" << endl;
    518       output2 << "'DeltaChisPAS-Order.dat' index " << BondOrder << " title 'Order " << BondOrder+1 << "' using ($1):7 with linespoints";
    519       if (BondOrder-1 != KeySet.Order)
    520         output2 << ", \\" << endl;
    521     }
    522     output << "'ChisPAS-Order.dat' index " << KeySet.Order << " title 'Full' using ($1+" << step*(double)KeySet.Order << "):7 with boxes" << endl;
    523     output.close(); 
    524     output2.close(); 
    525 
    526     if(!OpenOutputFile(output, argv[3], "ChisPAS-Order.pyx")) return 1;
    527     if(!OpenOutputFile(output2, argv[3], "DeltaChisPAS-Order.pyx")) return 1;
    528     CreatePlotHeader(output, "ChisPAS-Order", 1, "top right", NULL, NULL,  1, 5, "nuclei index", "iso chemical Chi value [ppm]");
    529     CreatePlotHeader(output2, "DeltaChisPAS-Order", 1, "top right", NULL, NULL,  1, 5, "nuclei index", "iso chemical Chi value [ppm]");
    530     output << "set boxwidth " << step << endl;
    531     output << "plot [0:" << ChiPAS.RowCounter[ChiPAS.MatrixCounter]+10 << "]\\" << endl;
    532     output2 << "plot [0:" << ChiPAS.RowCounter[ChiPAS.MatrixCounter]+10 << "]\\" << endl;
    533     for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
    534       output << "'ChisPAS-Order.dat' index " << BondOrder << " title 'Order " << BondOrder+1 << "' using ($1+" << step*(double)BondOrder << "):7 with boxes, \\" << endl;
    535       output2 << "'DeltaChisPAS-Order.dat' index " << BondOrder << " title 'Order " << BondOrder+1 << "' using ($1):7 with linespoints";
    536       if (BondOrder-1 != KeySet.Order)
    537         output2 << ", \\" << endl;
    538     }
    539     output << "'ChisPAS-Order.dat' index " << KeySet.Order << " title 'Full' using ($1+" << step*(double)KeySet.Order << "):7 with boxes" << endl;
    540     output.close(); 
    541     output2.close(); 
    542   }
    543 
    544361  // create Makefile
    545362  if(!OpenOutputFile(output, argv[3], "Makefile")) return 1;
  • src/atom.cpp

    • Property mode changed from 100755 to 100644
    r986c80 redcda5  
    8585};
    8686
    87 ostream & operator << (ostream &ost, const atom &a)
     87ostream & operator << (ostream &ost, atom &a)
    8888{
    8989  ost << "[" << a.Name << "|" << &a << "]";
  • src/bond.cpp

    • Property mode changed from 100755 to 100644
    r986c80 redcda5  
    8282};
    8383
    84 ostream & operator << (ostream &ost, const bond &b)
     84ostream & operator << (ostream &ost, bond &b)
    8585{
    8686  ost << "[" << b.leftatom->Name << " <" << b.BondDegree << "(H" << b.HydrogenBond << ")>" << b.rightatom->Name << "]";
     
    9898  if(rightatom == Atom)
    9999    return leftatom;
    100   cerr << "Bond " << *this << " does not contain atom " << *Atom << "!" << endl;
    101100  return NULL;
    102101};
  • src/boundary.cpp

    • Property mode changed from 100755 to 100644
    r986c80 redcda5  
    22#include "boundary.hpp"
    33
    4 #define DEBUG 1
    5 #define DoTecplotOutput 0
    6 #define DoRaster3DOutput 1
    7 #define TecplotSuffix ".dat"
    8 #define Raster3DSuffix ".r3d"
    9 
    104// ======================================== Points on Boundary =================================
    115
     
    148  LinesCount = 0;
    159  Nr = -1;
    16 }
    17 ;
     10};
    1811
    1912BoundaryPointSet::BoundaryPointSet(atom *Walker)
     
    2215  LinesCount = 0;
    2316  Nr = Walker->nr;
    24 }
    25 ;
     17};
    2618
    2719BoundaryPointSet::~BoundaryPointSet()
     
    2921  cout << Verbose(5) << "Erasing point nr. " << Nr << "." << endl;
    3022  node = NULL;
    31   lines.clear();
    32 }
    33 ;
    34 
    35 void
    36 BoundaryPointSet::AddLine(class BoundaryLineSet *line)
    37 {
    38   cout << Verbose(6) << "Adding " << *this << " to line " << *line << "."
    39       << endl;
    40   if (line->endpoints[0] == this)
    41     {
    42       lines.insert(LinePair(line->endpoints[1]->Nr, line));
    43     }
    44   else
    45     {
    46       lines.insert(LinePair(line->endpoints[0]->Nr, line));
    47     }
     23};
     24
     25void BoundaryPointSet::AddLine(class BoundaryLineSet *line)
     26{
     27  cout << Verbose(6) << "Adding line " << *line << " to " << *this << "." << endl;
     28  if (line->endpoints[0] == this) {
     29    lines.insert ( LinePair( line->endpoints[1]->Nr, line) );
     30  } else {
     31    lines.insert ( LinePair( line->endpoints[0]->Nr, line) );
     32  }
    4833  LinesCount++;
    49 }
    50 ;
    51 
    52 ostream &
    53 operator <<(ostream &ost, BoundaryPointSet &a)
     34};
     35
     36ostream & operator << (ostream &ost, BoundaryPointSet &a)
    5437{
    5538  ost << "[" << a.Nr << "|" << a.node->Name << "]";
    5639  return ost;
    57 }
    58 ;
     40};
    5941
    6042// ======================================== Lines on Boundary =================================
     
    6244BoundaryLineSet::BoundaryLineSet()
    6345{
    64   for (int i = 0; i < 2; i++)
     46  for (int i=0;i<2;i++)
    6547    endpoints[i] = NULL;
    6648  TrianglesCount = 0;
    6749  Nr = -1;
    68 }
    69 ;
     50};
    7051
    7152BoundaryLineSet::BoundaryLineSet(class BoundaryPointSet *Point[2], int number)
     
    7657  SetEndpointsOrdered(endpoints, Point[0], Point[1]);
    7758  // add this line to the hash maps of both endpoints
    78   Point[0]->AddLine(this); //Taken out, to check whether we can avoid unwanted double adding.
    79   Point[1]->AddLine(this); //
     59  Point[0]->AddLine(this);
     60  Point[1]->AddLine(this);
    8061  // clear triangles list
    8162  TrianglesCount = 0;
    8263  cout << Verbose(5) << "New Line with endpoints " << *this << "." << endl;
    83 }
    84 ;
     64};
    8565
    8666BoundaryLineSet::~BoundaryLineSet()
    8767{
    88         for (int i = 0; i < 2; i++) {
    89                 cout << Verbose(5) << "Erasing Line Nr. " << Nr << " in boundary point " << *endpoints[i] << "." << endl;
    90                 endpoints[i]->lines.erase(Nr);
    91                 LineMap::iterator tester = endpoints[i]->lines.begin();
    92                 tester++;
    93                 if (tester == endpoints[i]->lines.end()) {
    94                         cout << Verbose(5) << *endpoints[i] << " has no more lines it's attached to, erasing." << endl;
    95                         if (endpoints[i] != NULL) {
    96                                 delete(endpoints[i]);
    97                                 endpoints[i] = NULL;
    98                         } else
    99                                 cerr << "ERROR: Endpoint " << i << " has already been free'd." << endl;
    100                 } else
    101                         cout << Verbose(5) << *endpoints[i] << " has still lines it's attached to." << endl;
    102         }
    103 }
    104 ;
    105 
    106 void
    107 BoundaryLineSet::AddTriangle(class BoundaryTriangleSet *triangle)
    108 {
    109   cout << Verbose(6) << "Add " << triangle->Nr << " to line " << *this << "."
    110       << endl;
    111   triangles.insert(TrianglePair(TrianglesCount, triangle));
     68  for (int i=0;i<2;i++) {
     69    cout << Verbose(5) << "Erasing Line Nr. " << Nr << " in boundary point " << *endpoints[i] << "." << endl;
     70    endpoints[i]->lines.erase(Nr);
     71    LineMap::iterator tester = endpoints[i]->lines.begin();
     72    tester++;
     73    if (tester == endpoints[i]->lines.end()) {
     74      cout << Verbose(5) << *endpoints[i] << " has no more lines it's attached to, erasing." << endl;
     75      delete(endpoints[i]);
     76    } else
     77      cout << Verbose(5) << *endpoints[i] << " has still lines it's attached to." << endl;
     78  }
     79};
     80
     81void BoundaryLineSet::AddTriangle(class BoundaryTriangleSet *triangle)
     82{
     83  cout << Verbose(6) << "Add " << triangle->Nr << " to line " << *this << "." << endl;
     84  triangles.insert ( TrianglePair( TrianglesCount, triangle) );
    11285  TrianglesCount++;
    113 }
    114 ;
    115 
    116 ostream &
    117 operator <<(ostream &ost, BoundaryLineSet &a)
    118 {
    119   ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << ","
    120       << a.endpoints[1]->node->Name << "]";
     86};
     87
     88ostream & operator << (ostream &ost, BoundaryLineSet &a)
     89{
     90  ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << "," << a.endpoints[1]->node->Name << "]";
    12191  return ost;
    122 }
    123 ;
     92};
    12493
    12594// ======================================== Triangles on Boundary =================================
     
    12897BoundaryTriangleSet::BoundaryTriangleSet()
    12998{
    130   for (int i = 0; i < 3; i++)
    131     {
    132       endpoints[i] = NULL;
    133       lines[i] = NULL;
    134     }
     99  for (int i=0;i<3;i++) {
     100    endpoints[i] = NULL;
     101    lines[i] = NULL;
     102  }
    135103  Nr = -1;
    136 }
    137 ;
    138 
    139 BoundaryTriangleSet::BoundaryTriangleSet(class BoundaryLineSet *line[3],
    140     int number)
     104};
     105
     106BoundaryTriangleSet::BoundaryTriangleSet(class BoundaryLineSet *line[3], int number)
    141107{
    142108  // set number
     
    144110  // set lines
    145111  cout << Verbose(5) << "New triangle " << Nr << ":" << endl;
    146   for (int i = 0; i < 3; i++)
    147     {
    148       lines[i] = line[i];
    149       lines[i]->AddTriangle(this);
     112  for (int i=0;i<3;i++) {
     113    lines[i] = line[i];
     114    lines[i]->AddTriangle(this);
     115  }
     116  // get ascending order of endpoints
     117  map <int, class BoundaryPointSet * > OrderMap;
     118  for(int i=0;i<3;i++)  // for all three lines
     119    for (int j=0;j<2;j++) { // for both endpoints
     120      OrderMap.insert ( pair <int, class BoundaryPointSet * >( line[i]->endpoints[j]->Nr, line[i]->endpoints[j]) );
     121      // and we don't care whether insertion fails
    150122    }
    151   // get ascending order of endpoints
    152   map<int, class BoundaryPointSet *> OrderMap;
    153   for (int i = 0; i < 3; i++)
    154     // for all three lines
    155     for (int j = 0; j < 2; j++)
    156       { // for both endpoints
    157         OrderMap.insert(pair<int, class BoundaryPointSet *> (
    158             line[i]->endpoints[j]->Nr, line[i]->endpoints[j]));
    159         // and we don't care whether insertion fails
    160       }
    161123  // set endpoints
    162124  int Counter = 0;
    163125  cout << Verbose(6) << " with end points ";
    164   for (map<int, class BoundaryPointSet *>::iterator runner = OrderMap.begin(); runner
    165       != OrderMap.end(); runner++)
    166     {
    167       endpoints[Counter] = runner->second;
    168       cout << " " << *endpoints[Counter];
    169       Counter++;
    170     }
    171   if (Counter < 3)
    172     {
    173       cerr << "ERROR! We have a triangle with only two distinct endpoints!"
    174           << endl;
    175       //exit(1);
    176     }
     126  for (map <int, class BoundaryPointSet * >::iterator runner = OrderMap.begin(); runner != OrderMap.end(); runner++) {
     127    endpoints[Counter] = runner->second;
     128    cout << " " << *endpoints[Counter];
     129    Counter++;
     130  }
     131  if (Counter < 3) {
     132    cerr << "ERROR! We have a triangle with only two distinct endpoints!" << endl;
     133    //exit(1);
     134  }
    177135  cout << "." << endl;
    178 }
    179 ;
     136};
    180137
    181138BoundaryTriangleSet::~BoundaryTriangleSet()
    182139{
    183         for (int i = 0; i < 3; i++) {
    184                 cout << Verbose(5) << "Erasing triangle Nr." << Nr << endl;
    185                 lines[i]->triangles.erase(Nr);
    186                 if (lines[i]->triangles.empty()) {
    187                         cout << Verbose(5) << *lines[i] << " is no more attached to any triangle, erasing." << endl;
    188                         if (lines[i] != NULL) {
    189                                 delete (lines[i]);
    190                                 lines[i] = NULL;
    191                         } else
    192                                 cerr << "ERROR: This line " << i << " has already been free'd." << endl;
    193                 } else
    194                         cout << Verbose(5) << *lines[i] << " is still attached to a triangle." << endl;
    195         }
    196 }
    197 ;
    198 
    199 void
    200 BoundaryTriangleSet::GetNormalVector(Vector &OtherVector)
     140  for (int i=0;i<3;i++) {
     141    cout << Verbose(5) << "Erasing triangle Nr." << Nr << endl;
     142    lines[i]->triangles.erase(Nr);
     143    TriangleMap::iterator tester = lines[i]->triangles.begin();
     144    tester++;
     145    if (tester == lines[i]->triangles.end()) {
     146      cout << Verbose(5) << *lines[i] << " is no more attached to any triangle, erasing." << endl;
     147      delete(lines[i]);
     148    } else
     149      cout << Verbose(5) << *lines[i] << " is still attached to a triangle." << endl;
     150  }
     151};
     152
     153void BoundaryTriangleSet::GetNormalVector(Vector &NormalVector)
    201154{
    202155  // get normal vector
    203   NormalVector.MakeNormalVector(&endpoints[0]->node->x, &endpoints[1]->node->x,
    204       &endpoints[2]->node->x);
    205 
     156  NormalVector.MakeNormalVector(&endpoints[0]->node->x, &endpoints[1]->node->x, &endpoints[2]->node->x);
     157 
    206158  // make it always point inward (any offset vector onto plane projected onto normal vector suffices)
    207   if (endpoints[0]->node->x.Projection(&OtherVector) > 0)
     159  if (endpoints[0]->node->x.Projection(&NormalVector) > 0)
    208160    NormalVector.Scale(-1.);
    209 }
    210 ;
    211 
    212 ostream &
    213 operator <<(ostream &ost, BoundaryTriangleSet &a)
    214 {
    215   ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << ","
    216       << a.endpoints[1]->node->Name << "," << a.endpoints[2]->node->Name << "]";
     161};
     162
     163ostream & operator << (ostream &ost, BoundaryTriangleSet &a)
     164{
     165  ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << "," << a.endpoints[1]->node->Name << "," << a.endpoints[2]->node->Name << "]";
    217166  return ost;
    218 }
    219 ;
     167};
    220168
    221169// ========================================== F U N C T I O N S =================================
     
    226174 * \return point which is shared or NULL if none
    227175 */
    228 class BoundaryPointSet *
    229 GetCommonEndpoint(class BoundaryLineSet * line1, class BoundaryLineSet * line2)
    230 {
    231   class BoundaryLineSet * lines[2] =
    232     { line1, line2 };
     176class BoundaryPointSet * GetCommonEndpoint(class BoundaryLineSet * line1, class BoundaryLineSet * line2)
     177{
     178  class BoundaryLineSet * lines[2] = {line1, line2};
    233179  class BoundaryPointSet *node = NULL;
    234   map<int, class BoundaryPointSet *> OrderMap;
    235   pair<map<int, class BoundaryPointSet *>::iterator, bool> OrderTest;
    236   for (int i = 0; i < 2; i++)
    237     // for both lines
    238     for (int j = 0; j < 2; j++)
    239       { // for both endpoints
    240         OrderTest = OrderMap.insert(pair<int, class BoundaryPointSet *> (
    241             lines[i]->endpoints[j]->Nr, lines[i]->endpoints[j]));
    242         if (!OrderTest.second)
    243           { // if insertion fails, we have common endpoint
    244             node = OrderTest.first->second;
    245             cout << Verbose(5) << "Common endpoint of lines " << *line1
    246                 << " and " << *line2 << " is: " << *node << "." << endl;
    247             j = 2;
    248             i = 2;
    249             break;
    250           }
     180  map <int, class BoundaryPointSet * > OrderMap;
     181  pair < map <int, class BoundaryPointSet * >::iterator, bool > OrderTest;
     182  for(int i=0;i<2;i++)  // for both lines
     183    for (int j=0;j<2;j++) { // for both endpoints
     184      OrderTest = OrderMap.insert ( pair <int, class BoundaryPointSet * >( lines[i]->endpoints[j]->Nr, lines[i]->endpoints[j]) );
     185      if (!OrderTest.second) { // if insertion fails, we have common endpoint
     186        node = OrderTest.first->second;
     187        cout << Verbose(5) << "Common endpoint of lines " << *line1 << " and " << *line2 << " is: " << *node << "." << endl;
     188        j=2;
     189        i=2;
     190        break;
    251191      }
     192    }
    252193  return node;
    253 }
    254 ;
     194};
    255195
    256196/** Determines the boundary points of a cluster.
     
    261201 * \param *mol molecule structure representing the cluster
    262202 */
    263 Boundaries *
    264 GetBoundaryPoints(ofstream *out, molecule *mol)
     203Boundaries * GetBoundaryPoints(ofstream *out, molecule *mol)
    265204{
    266205  atom *Walker = NULL;
     
    268207  LineMap LinesOnBoundary;
    269208  TriangleMap TrianglesOnBoundary;
    270 
     209 
    271210  *out << Verbose(1) << "Finding all boundary points." << endl;
    272   Boundaries *BoundaryPoints = new Boundaries[NDIM]; // first is alpha, second is (r, nr)
     211  Boundaries *BoundaryPoints = new Boundaries [NDIM]; // first is alpha, second is (r, nr)
    273212  BoundariesTestPair BoundaryTestPair;
    274213  Vector AxisVector, AngleReferenceVector, AngleReferenceNormalVector;
    275214  double radius, angle;
    276215  // 3a. Go through every axis
    277   for (int axis = 0; axis < NDIM; axis++)
    278     {
    279       AxisVector.Zero();
    280       AngleReferenceVector.Zero();
    281       AngleReferenceNormalVector.Zero();
    282       AxisVector.x[axis] = 1.;
    283       AngleReferenceVector.x[(axis + 1) % NDIM] = 1.;
    284       AngleReferenceNormalVector.x[(axis + 2) % NDIM] = 1.;
    285       //    *out << Verbose(1) << "Axisvector is ";
    286       //    AxisVector.Output(out);
    287       //    *out << " and AngleReferenceVector is ";
    288       //    AngleReferenceVector.Output(out);
    289       //    *out << "." << endl;
    290       //    *out << " and AngleReferenceNormalVector is ";
    291       //    AngleReferenceNormalVector.Output(out);
    292       //    *out << "." << endl;
    293       // 3b. construct set of all points, transformed into cylindrical system and with left and right neighbours
    294       Walker = mol->start;
    295       while (Walker->next != mol->end)
     216  for (int axis=0; axis<NDIM; axis++)  {
     217    AxisVector.Zero();
     218    AngleReferenceVector.Zero();
     219    AngleReferenceNormalVector.Zero();
     220    AxisVector.x[axis] = 1.;
     221    AngleReferenceVector.x[(axis+1)%NDIM] = 1.;
     222    AngleReferenceNormalVector.x[(axis+2)%NDIM] = 1.;
     223  //    *out << Verbose(1) << "Axisvector is ";
     224  //    AxisVector.Output(out);
     225  //    *out << " and AngleReferenceVector is ";
     226  //    AngleReferenceVector.Output(out);
     227  //    *out << "." << endl;
     228  //    *out << " and AngleReferenceNormalVector is ";
     229  //    AngleReferenceNormalVector.Output(out);
     230  //    *out << "." << endl;
     231    // 3b. construct set of all points, transformed into cylindrical system and with left and right neighbours
     232    Walker = mol->start;
     233    while (Walker->next != mol->end) {
     234      Walker = Walker->next;
     235      Vector ProjectedVector;
     236      ProjectedVector.CopyVector(&Walker->x);
     237      ProjectedVector.ProjectOntoPlane(&AxisVector);
     238      // correct for negative side
     239      //if (Projection(y) < 0)
     240        //angle = 2.*M_PI - angle;
     241      radius = ProjectedVector.Norm();
     242      if (fabs(radius) > MYEPSILON)
     243        angle = ProjectedVector.Angle(&AngleReferenceVector);
     244      else
     245        angle = 0.;  // otherwise it's a vector in Axis Direction and unimportant for boundary issues
     246       
     247      //*out << "Checking sign in quadrant : " << ProjectedVector.Projection(&AngleReferenceNormalVector) << "." << endl;
     248      if (ProjectedVector.Projection(&AngleReferenceNormalVector) > 0) {
     249        angle = 2.*M_PI - angle;
     250      }
     251      //*out << Verbose(2) << "Inserting " << *Walker << ": (r, alpha) = (" << radius << "," << angle << "): ";
     252      //ProjectedVector.Output(out);
     253      //*out << endl;
     254      BoundaryTestPair = BoundaryPoints[axis].insert( BoundariesPair (angle, DistancePair (radius, Walker) ) );
     255      if (BoundaryTestPair.second) { // successfully inserted
     256      } else { // same point exists, check first r, then distance of original vectors to center of gravity
     257        *out << Verbose(2) << "Encountered two vectors whose projection onto axis " << axis << " is equal: " << endl;
     258        *out << Verbose(2) << "Present vector: ";
     259        BoundaryTestPair.first->second.second->x.Output(out);
     260        *out << endl;
     261        *out << Verbose(2) << "New vector: ";
     262        Walker->x.Output(out);
     263        *out << endl;
     264        double tmp = ProjectedVector.Norm();
     265        if (tmp > BoundaryTestPair.first->second.first) {
     266          BoundaryTestPair.first->second.first = tmp;
     267          BoundaryTestPair.first->second.second = Walker;
     268          *out << Verbose(2) << "Keeping new vector." << endl;
     269        } else if (tmp == BoundaryTestPair.first->second.first) {
     270          if (BoundaryTestPair.first->second.second->x.ScalarProduct(&BoundaryTestPair.first->second.second->x) < Walker->x.ScalarProduct(&Walker->x)) { // Norm() does a sqrt, which makes it a lot slower
     271            BoundaryTestPair.first->second.second = Walker;
     272            *out << Verbose(2) << "Keeping new vector." << endl;
     273          } else {
     274            *out << Verbose(2) << "Keeping present vector." << endl;
     275          }
     276        } else {
     277            *out << Verbose(2) << "Keeping present vector." << endl;
     278        }
     279      }
     280    }
     281    // printing all inserted for debugging
     282  //    {
     283  //      *out << Verbose(2) << "Printing list of candidates for axis " << axis << " which we have inserted so far." << endl;
     284  //      int i=0;
     285  //      for(Boundaries::iterator runner = BoundaryPoints[axis].begin(); runner != BoundaryPoints[axis].end(); runner++) {
     286  //        if (runner != BoundaryPoints[axis].begin())
     287  //          *out << ", " << i << ": " << *runner->second.second;
     288  //        else
     289  //          *out << i << ": " << *runner->second.second;
     290  //        i++;
     291  //      }
     292  //      *out << endl;
     293  //    }
     294    // 3c. throw out points whose distance is less than the mean of left and right neighbours
     295    bool flag = false;
     296    do { // do as long as we still throw one out per round
     297      *out << Verbose(1) << "Looking for candidates to kick out by convex condition ... " << endl;
     298      flag = false;
     299      Boundaries::iterator left = BoundaryPoints[axis].end();
     300      Boundaries::iterator right = BoundaryPoints[axis].end();
     301      for(Boundaries::iterator runner = BoundaryPoints[axis].begin(); runner != BoundaryPoints[axis].end(); runner++) {
     302        // set neighbours correctly
     303        if (runner == BoundaryPoints[axis].begin()) {
     304          left = BoundaryPoints[axis].end();
     305        } else {
     306          left = runner;
     307        }
     308        left--;
     309        right = runner;
     310        right++;
     311        if (right == BoundaryPoints[axis].end()) {
     312          right = BoundaryPoints[axis].begin();
     313        }
     314        // check distance
     315       
     316        // construct the vector of each side of the triangle on the projected plane (defined by normal vector AxisVector)
    296317        {
    297           Walker = Walker->next;
    298           Vector ProjectedVector;
    299           ProjectedVector.CopyVector(&Walker->x);
    300           ProjectedVector.ProjectOntoPlane(&AxisVector);
    301           // correct for negative side
    302           //if (Projection(y) < 0)
    303           //angle = 2.*M_PI - angle;
    304           radius = ProjectedVector.Norm();
    305           if (fabs(radius) > MYEPSILON)
    306             angle = ProjectedVector.Angle(&AngleReferenceVector);
    307           else
    308             angle = 0.; // otherwise it's a vector in Axis Direction and unimportant for boundary issues
    309 
    310           //*out << "Checking sign in quadrant : " << ProjectedVector.Projection(&AngleReferenceNormalVector) << "." << endl;
    311           if (ProjectedVector.Projection(&AngleReferenceNormalVector) > 0)
    312             {
    313               angle = 2. * M_PI - angle;
    314             }
    315           //*out << Verbose(2) << "Inserting " << *Walker << ": (r, alpha) = (" << radius << "," << angle << "): ";
    316           //ProjectedVector.Output(out);
    317           //*out << endl;
    318           BoundaryTestPair = BoundaryPoints[axis].insert(BoundariesPair(angle,
    319               DistancePair (radius, Walker)));
    320           if (BoundaryTestPair.second)
    321             { // successfully inserted
    322             }
    323           else
    324             { // same point exists, check first r, then distance of original vectors to center of gravity
    325               *out << Verbose(2)
    326                   << "Encountered two vectors whose projection onto axis "
    327                   << axis << " is equal: " << endl;
    328               *out << Verbose(2) << "Present vector: ";
    329               BoundaryTestPair.first->second.second->x.Output(out);
    330               *out << endl;
    331               *out << Verbose(2) << "New vector: ";
    332               Walker->x.Output(out);
    333               *out << endl;
    334               double tmp = ProjectedVector.Norm();
    335               if (tmp > BoundaryTestPair.first->second.first)
    336                 {
    337                   BoundaryTestPair.first->second.first = tmp;
    338                   BoundaryTestPair.first->second.second = Walker;
    339                   *out << Verbose(2) << "Keeping new vector." << endl;
    340                 }
    341               else if (tmp == BoundaryTestPair.first->second.first)
    342                 {
    343                   if (BoundaryTestPair.first->second.second->x.ScalarProduct(
    344                       &BoundaryTestPair.first->second.second->x)
    345                       < Walker->x.ScalarProduct(&Walker->x))
    346                     { // Norm() does a sqrt, which makes it a lot slower
    347                       BoundaryTestPair.first->second.second = Walker;
    348                       *out << Verbose(2) << "Keeping new vector." << endl;
    349                     }
    350                   else
    351                     {
    352                       *out << Verbose(2) << "Keeping present vector." << endl;
    353                     }
    354                 }
    355               else
    356                 {
    357                   *out << Verbose(2) << "Keeping present vector." << endl;
    358                 }
    359             }
     318          Vector SideA, SideB, SideC, SideH;
     319          SideA.CopyVector(&left->second.second->x);
     320          SideA.ProjectOntoPlane(&AxisVector);
     321  //          *out << "SideA: ";
     322  //          SideA.Output(out);
     323  //          *out << endl;
     324         
     325          SideB.CopyVector(&right->second.second->x);
     326          SideB.ProjectOntoPlane(&AxisVector);
     327  //          *out << "SideB: ";
     328  //          SideB.Output(out);
     329  //          *out << endl;
     330         
     331          SideC.CopyVector(&left->second.second->x);
     332          SideC.SubtractVector(&right->second.second->x);
     333          SideC.ProjectOntoPlane(&AxisVector);
     334  //          *out << "SideC: ";
     335  //          SideC.Output(out);
     336  //          *out << endl;
     337 
     338          SideH.CopyVector(&runner->second.second->x);
     339          SideH.ProjectOntoPlane(&AxisVector);
     340  //          *out << "SideH: ";
     341  //          SideH.Output(out);
     342  //          *out << endl;
     343         
     344          // calculate each length
     345          double a = SideA.Norm();
     346          //double b = SideB.Norm();
     347          //double c = SideC.Norm();
     348          double h = SideH.Norm();
     349          // calculate the angles
     350          double alpha = SideA.Angle(&SideH);
     351          double beta = SideA.Angle(&SideC);
     352          double gamma = SideB.Angle(&SideH);
     353          double delta = SideC.Angle(&SideH);
     354          double MinDistance = a * sin(beta)/(sin(delta)) * (((alpha < M_PI/2.) || (gamma < M_PI/2.)) ? 1. : -1.);
     355  //          *out << Verbose(2) << " I calculated: a = " << a << ", h = " << h << ", beta(" << left->second.second->Name << "," << left->second.second->Name << "-" << right->second.second->Name << ") = " << beta << ", delta(" << left->second.second->Name << "," << runner->second.second->Name << ") = " << delta << ", Min = " << MinDistance << "." << endl;
     356          //*out << Verbose(1) << "Checking CoG distance of runner " << *runner->second.second << " " << h << " against triangle's side length spanned by (" << *left->second.second << "," << *right->second.second << ") of " << MinDistance << "." << endl;
     357          if ((fabs(h/fabs(h) - MinDistance/fabs(MinDistance)) < MYEPSILON) && (h <  MinDistance)) {
     358            // throw out point
     359            //*out << Verbose(1) << "Throwing out " << *runner->second.second << "." << endl;
     360            BoundaryPoints[axis].erase(runner);
     361            flag = true;
     362          }
    360363        }
    361       // printing all inserted for debugging
    362       //    {
    363       //      *out << Verbose(2) << "Printing list of candidates for axis " << axis << " which we have inserted so far." << endl;
    364       //      int i=0;
    365       //      for(Boundaries::iterator runner = BoundaryPoints[axis].begin(); runner != BoundaryPoints[axis].end(); runner++) {
    366       //        if (runner != BoundaryPoints[axis].begin())
    367       //          *out << ", " << i << ": " << *runner->second.second;
    368       //        else
    369       //          *out << i << ": " << *runner->second.second;
    370       //        i++;
    371       //      }
    372       //      *out << endl;
    373       //    }
    374       // 3c. throw out points whose distance is less than the mean of left and right neighbours
    375       bool flag = false;
    376       do
    377         { // do as long as we still throw one out per round
    378           *out << Verbose(1)
    379               << "Looking for candidates to kick out by convex condition ... "
    380               << endl;
    381           flag = false;
    382           Boundaries::iterator left = BoundaryPoints[axis].end();
    383           Boundaries::iterator right = BoundaryPoints[axis].end();
    384           for (Boundaries::iterator runner = BoundaryPoints[axis].begin(); runner
    385               != BoundaryPoints[axis].end(); runner++)
    386             {
    387               // set neighbours correctly
    388               if (runner == BoundaryPoints[axis].begin())
    389                 {
    390                   left = BoundaryPoints[axis].end();
    391                 }
    392               else
    393                 {
    394                   left = runner;
    395                 }
    396               left--;
    397               right = runner;
    398               right++;
    399               if (right == BoundaryPoints[axis].end())
    400                 {
    401                   right = BoundaryPoints[axis].begin();
    402                 }
    403               // check distance
    404 
    405               // construct the vector of each side of the triangle on the projected plane (defined by normal vector AxisVector)
    406                 {
    407                   Vector SideA, SideB, SideC, SideH;
    408                   SideA.CopyVector(&left->second.second->x);
    409                   SideA.ProjectOntoPlane(&AxisVector);
    410                   //          *out << "SideA: ";
    411                   //          SideA.Output(out);
    412                   //          *out << endl;
    413 
    414                   SideB.CopyVector(&right->second.second->x);
    415                   SideB.ProjectOntoPlane(&AxisVector);
    416                   //          *out << "SideB: ";
    417                   //          SideB.Output(out);
    418                   //          *out << endl;
    419 
    420                   SideC.CopyVector(&left->second.second->x);
    421                   SideC.SubtractVector(&right->second.second->x);
    422                   SideC.ProjectOntoPlane(&AxisVector);
    423                   //          *out << "SideC: ";
    424                   //          SideC.Output(out);
    425                   //          *out << endl;
    426 
    427                   SideH.CopyVector(&runner->second.second->x);
    428                   SideH.ProjectOntoPlane(&AxisVector);
    429                   //          *out << "SideH: ";
    430                   //          SideH.Output(out);
    431                   //          *out << endl;
    432 
    433                   // calculate each length
    434                   double a = SideA.Norm();
    435                   //double b = SideB.Norm();
    436                   //double c = SideC.Norm();
    437                   double h = SideH.Norm();
    438                   // calculate the angles
    439                   double alpha = SideA.Angle(&SideH);
    440                   double beta = SideA.Angle(&SideC);
    441                   double gamma = SideB.Angle(&SideH);
    442                   double delta = SideC.Angle(&SideH);
    443                   double MinDistance = a * sin(beta) / (sin(delta)) * (((alpha
    444                       < M_PI / 2.) || (gamma < M_PI / 2.)) ? 1. : -1.);
    445                   //          *out << Verbose(2) << " I calculated: a = " << a << ", h = " << h << ", beta(" << left->second.second->Name << "," << left->second.second->Name << "-" << right->second.second->Name << ") = " << beta << ", delta(" << left->second.second->Name << "," << runner->second.second->Name << ") = " << delta << ", Min = " << MinDistance << "." << endl;
    446                   //*out << Verbose(1) << "Checking CoG distance of runner " << *runner->second.second << " " << h << " against triangle's side length spanned by (" << *left->second.second << "," << *right->second.second << ") of " << MinDistance << "." << endl;
    447                   if ((fabs(h / fabs(h) - MinDistance / fabs(MinDistance))
    448                       < MYEPSILON) && (h < MinDistance))
    449                     {
    450                       // throw out point
    451                       //*out << Verbose(1) << "Throwing out " << *runner->second.second << "." << endl;
    452                       BoundaryPoints[axis].erase(runner);
    453                       flag = true;
    454                     }
    455                 }
    456             }
    457         }
    458       while (flag);
    459     }
     364      }
     365    } while (flag);
     366  }
    460367  return BoundaryPoints;
    461 }
    462 ;
     368};
    463369
    464370/** Determines greatest diameters of a cluster defined by its convex envelope.
     
    469375 * \param IsAngstroem whether we have angstroem or atomic units
    470376 * \return NDIM array of the diameters
    471  */
    472 double *
    473 GetDiametersOfCluster(ofstream *out, Boundaries *BoundaryPtr, molecule *mol,
    474     bool IsAngstroem)
     377 */
     378double * GetDiametersOfCluster(ofstream *out, Boundaries *BoundaryPtr, molecule *mol, bool IsAngstroem)
    475379{
    476380  // get points on boundary of NULL was given as parameter
    477381  bool BoundaryFreeFlag = false;
    478382  Boundaries *BoundaryPoints = BoundaryPtr;
    479   if (BoundaryPoints == NULL)
    480     {
    481       BoundaryFreeFlag = true;
    482       BoundaryPoints = GetBoundaryPoints(out, mol);
    483     }
    484   else
    485     {
    486       *out << Verbose(1) << "Using given boundary points set." << endl;
    487     }
     383  if (BoundaryPoints == NULL) {
     384    BoundaryFreeFlag = true;
     385    BoundaryPoints = GetBoundaryPoints(out, mol);
     386  } else {
     387    *out << Verbose(1) << "Using given boundary points set." << endl;
     388  }
     389 
    488390  // determine biggest "diameter" of cluster for each axis
    489391  Boundaries::iterator Neighbour, OtherNeighbour;
    490392  double *GreatestDiameter = new double[NDIM];
    491   for (int i = 0; i < NDIM; i++)
     393  for(int i=0;i<NDIM;i++)
    492394    GreatestDiameter[i] = 0.;
    493395  double OldComponent, tmp, w1, w2;
    494396  Vector DistanceVector, OtherVector;
    495397  int component, Othercomponent;
    496   for (int axis = 0; axis < NDIM; axis++)
    497     { // regard each projected plane
    498       //*out << Verbose(1) << "Current axis is " << axis << "." << endl;
    499       for (int j = 0; j < 2; j++)
    500         { // and for both axis on the current plane
    501           component = (axis + j + 1) % NDIM;
    502           Othercomponent = (axis + 1 + ((j + 1) & 1)) % NDIM;
    503           //*out << Verbose(1) << "Current component is " << component << ", Othercomponent is " << Othercomponent << "." << endl;
    504           for (Boundaries::iterator runner = BoundaryPoints[axis].begin(); runner
    505               != BoundaryPoints[axis].end(); runner++)
    506             {
    507               //*out << Verbose(2) << "Current runner is " << *(runner->second.second) << "." << endl;
    508               // seek for the neighbours pair where the Othercomponent sign flips
    509               Neighbour = runner;
    510               Neighbour++;
    511               if (Neighbour == BoundaryPoints[axis].end()) // make it wrap around
    512                 Neighbour = BoundaryPoints[axis].begin();
    513               DistanceVector.CopyVector(&runner->second.second->x);
    514               DistanceVector.SubtractVector(&Neighbour->second.second->x);
    515               do
    516                 { // seek for neighbour pair where it flips
    517                   OldComponent = DistanceVector.x[Othercomponent];
    518                   Neighbour++;
    519                   if (Neighbour == BoundaryPoints[axis].end()) // make it wrap around
    520                     Neighbour = BoundaryPoints[axis].begin();
    521                   DistanceVector.CopyVector(&runner->second.second->x);
    522                   DistanceVector.SubtractVector(&Neighbour->second.second->x);
    523                   //*out << Verbose(3) << "OldComponent is " << OldComponent << ", new one is " << DistanceVector.x[Othercomponent] << "." << endl;
    524                 }
    525               while ((runner != Neighbour) && (fabs(OldComponent / fabs(
    526                   OldComponent) - DistanceVector.x[Othercomponent] / fabs(
    527                   DistanceVector.x[Othercomponent])) < MYEPSILON)); // as long as sign does not flip
    528               if (runner != Neighbour)
    529                 {
    530                   OtherNeighbour = Neighbour;
    531                   if (OtherNeighbour == BoundaryPoints[axis].begin()) // make it wrap around
    532                     OtherNeighbour = BoundaryPoints[axis].end();
    533                   OtherNeighbour--;
    534                   //*out << Verbose(2) << "The pair, where the sign of OtherComponent flips, is: " << *(Neighbour->second.second) << " and " << *(OtherNeighbour->second.second) << "." << endl;
    535                   // now we have found the pair: Neighbour and OtherNeighbour
    536                   OtherVector.CopyVector(&runner->second.second->x);
    537                   OtherVector.SubtractVector(&OtherNeighbour->second.second->x);
    538                   //*out << Verbose(2) << "Distances to Neighbour and OtherNeighbour are " << DistanceVector.x[component] << " and " << OtherVector.x[component] << "." << endl;
    539                   //*out << Verbose(2) << "OtherComponents to Neighbour and OtherNeighbour are " << DistanceVector.x[Othercomponent] << " and " << OtherVector.x[Othercomponent] << "." << endl;
    540                   // do linear interpolation between points (is exact) to extract exact intersection between Neighbour and OtherNeighbour
    541                   w1 = fabs(OtherVector.x[Othercomponent]);
    542                   w2 = fabs(DistanceVector.x[Othercomponent]);
    543                   tmp = fabs((w1 * DistanceVector.x[component] + w2
    544                       * OtherVector.x[component]) / (w1 + w2));
    545                   // mark if it has greater diameter
    546                   //*out << Verbose(2) << "Comparing current greatest " << GreatestDiameter[component] << " to new " << tmp << "." << endl;
    547                   GreatestDiameter[component] = (GreatestDiameter[component]
    548                       > tmp) ? GreatestDiameter[component] : tmp;
    549                 } //else
    550               //*out << Verbose(2) << "Saw no sign flip, probably top or bottom node." << endl;
    551             }
    552         }
     398  for(int axis=0;axis<NDIM;axis++) { // regard each projected plane
     399    //*out << Verbose(1) << "Current axis is " << axis << "." << endl;
     400    for (int j=0;j<2;j++) { // and for both axis on the current plane
     401      component = (axis+j+1)%NDIM;
     402      Othercomponent = (axis+1+((j+1) & 1))%NDIM;
     403      //*out << Verbose(1) << "Current component is " << component << ", Othercomponent is " << Othercomponent << "." << endl;
     404      for(Boundaries::iterator runner = BoundaryPoints[axis].begin(); runner != BoundaryPoints[axis].end(); runner++) {
     405        //*out << Verbose(2) << "Current runner is " << *(runner->second.second) << "." << endl;
     406        // seek for the neighbours pair where the Othercomponent sign flips
     407        Neighbour = runner;
     408        Neighbour++;
     409        if (Neighbour == BoundaryPoints[axis].end())  // make it wrap around
     410          Neighbour = BoundaryPoints[axis].begin();
     411        DistanceVector.CopyVector(&runner->second.second->x);
     412        DistanceVector.SubtractVector(&Neighbour->second.second->x);
     413        do {  // seek for neighbour pair where it flips
     414          OldComponent = DistanceVector.x[Othercomponent];
     415          Neighbour++;
     416          if (Neighbour == BoundaryPoints[axis].end())  // make it wrap around
     417            Neighbour = BoundaryPoints[axis].begin();
     418          DistanceVector.CopyVector(&runner->second.second->x);
     419          DistanceVector.SubtractVector(&Neighbour->second.second->x);
     420          //*out << Verbose(3) << "OldComponent is " << OldComponent << ", new one is " << DistanceVector.x[Othercomponent] << "." << endl;
     421        } while ((runner != Neighbour) && ( fabs( OldComponent/fabs(OldComponent) - DistanceVector.x[Othercomponent]/fabs(DistanceVector.x[Othercomponent]) ) < MYEPSILON)); // as long as sign does not flip
     422        if (runner != Neighbour) {
     423          OtherNeighbour = Neighbour;
     424          if (OtherNeighbour == BoundaryPoints[axis].begin())  // make it wrap around
     425            OtherNeighbour = BoundaryPoints[axis].end();
     426          OtherNeighbour--;
     427          //*out << Verbose(2) << "The pair, where the sign of OtherComponent flips, is: " << *(Neighbour->second.second) << " and " << *(OtherNeighbour->second.second) << "." << endl;
     428          // now we have found the pair: Neighbour and OtherNeighbour
     429          OtherVector.CopyVector(&runner->second.second->x);
     430          OtherVector.SubtractVector(&OtherNeighbour->second.second->x);
     431          //*out << Verbose(2) << "Distances to Neighbour and OtherNeighbour are " << DistanceVector.x[component] << " and " << OtherVector.x[component] << "." << endl;
     432          //*out << Verbose(2) << "OtherComponents to Neighbour and OtherNeighbour are " << DistanceVector.x[Othercomponent] << " and " << OtherVector.x[Othercomponent] << "." << endl;
     433          // do linear interpolation between points (is exact) to extract exact intersection between Neighbour and OtherNeighbour
     434          w1 = fabs(OtherVector.x[Othercomponent]);
     435          w2 = fabs(DistanceVector.x[Othercomponent]);
     436          tmp = fabs((w1*DistanceVector.x[component] + w2*OtherVector.x[component])/(w1+w2));
     437          // mark if it has greater diameter
     438          //*out << Verbose(2) << "Comparing current greatest " << GreatestDiameter[component] << " to new " << tmp << "." << endl;
     439          GreatestDiameter[component] = (GreatestDiameter[component] > tmp) ? GreatestDiameter[component] : tmp;
     440        } //else
     441          //*out << Verbose(2) << "Saw no sign flip, probably top or bottom node." << endl;
     442      }
    553443    }
    554   *out << Verbose(0) << "RESULT: The biggest diameters are "
    555       << GreatestDiameter[0] << " and " << GreatestDiameter[1] << " and "
    556       << GreatestDiameter[2] << " " << (IsAngstroem ? "angstrom"
    557       : "atomiclength") << "." << endl;
     444  }
     445  *out << Verbose(0) << "RESULT: The biggest diameters are " << GreatestDiameter[0] << " and " << GreatestDiameter[1] << " and " << GreatestDiameter[2] << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "." << endl;
    558446
    559447  // free reference lists
    560448  if (BoundaryFreeFlag)
    561     delete[] (BoundaryPoints);
     449    delete[](BoundaryPoints);
    562450
    563451  return GreatestDiameter;
    564 }
    565 ;
    566 
    567 /** Creates the objects in a raster3d file (renderable with a header.r3d)
    568  * \param *out output stream for debugging
    569  * \param *tecplot output stream for tecplot data
    570  * \param *Tess Tesselation structure with constructed triangles
    571  * \param *mol molecule structure with atom positions
    572  */
    573 void write_raster3d_file(ofstream *out, ofstream *rasterfile, class Tesselation *Tess, class molecule *mol)
    574 {
    575         atom *Walker = mol->start;
    576         bond *Binder = mol->first;
    577         int i;
    578         Vector *center = mol->DetermineCenterOfAll(out);
    579         if (rasterfile != NULL) {
    580                 //cout << Verbose(1) << "Writing Raster3D file ... ";
    581                 *rasterfile << "# Raster3D object description, created by MoleCuilder" << endl;
    582                 *rasterfile << "@header.r3d" << endl;
    583                 *rasterfile << "# All atoms as spheres" << endl;
    584                 while (Walker->next != mol->end) {
    585                         Walker = Walker->next;
    586                         *rasterfile << "2" << endl << "  ";     // 2 is sphere type
    587                         for (i=0;i<NDIM;i++)
    588                                 *rasterfile << Walker->x.x[i]+center->x[i] << " ";
    589                         *rasterfile << "\t0.1\t1. 1. 1." << endl; // radius 0.05 and white as colour
    590                 }
    591 
    592                 *rasterfile << "# All bonds as vertices" << endl;
    593                 while (Binder->next != mol->last) {
    594                         Binder = Binder->next;
    595                         *rasterfile << "3" << endl << "  ";     // 2 is round-ended cylinder type
    596                         for (i=0;i<NDIM;i++)
    597                                 *rasterfile << Binder->leftatom->x.x[i]+center->x[i] << " ";
    598                         *rasterfile << "\t0.03\t";
    599                         for (i=0;i<NDIM;i++)
    600                                 *rasterfile << Binder->rightatom->x.x[i]+center->x[i] << " ";
    601                         *rasterfile << "\t0.03\t0. 0. 1." << endl; // radius 0.05 and blue as colour
    602                 }
    603 
    604                 *rasterfile << "# All tesselation triangles" << endl;
    605                 for (TriangleMap::iterator TriangleRunner = Tess->TrianglesOnBoundary.begin(); TriangleRunner != Tess->TrianglesOnBoundary.end(); TriangleRunner++) {
    606                         *rasterfile << "1" << endl << "  ";     // 1 is triangle type
    607                         for (i=0;i<3;i++) {     // print each node
    608                                 for (int j=0;j<NDIM;j++)        // and for each node all NDIM coordinates
    609                                         *rasterfile << TriangleRunner->second->endpoints[i]->node->x.x[j]+center->x[j] << " ";
    610                                 *rasterfile << "\t";
    611                         }
    612                         *rasterfile << "1. 0. 0." << endl;      // red as colour
    613                         *rasterfile << "18" << endl << "  0.5 0.5 0.5" << endl; // 18 is transparency type for previous object
    614                 }
    615         } else {
    616                 cerr << "ERROR: Given rasterfile is " << rasterfile << "." << endl;
    617         }
    618         delete(center);
    619 };
    620 
    621 /** This function creates the tecplot file, displaying the tesselation of the hull.
    622  * \param *out output stream for debugging
    623  * \param *tecplot output stream for tecplot data
    624  * \param N arbitrary number to differentiate various zones in the tecplot format
    625  */
    626 void
    627 write_tecplot_file(ofstream *out, ofstream *tecplot,
    628     class Tesselation *TesselStruct, class molecule *mol, int N)
    629 {
    630   if (tecplot != NULL)
    631     {
    632       *tecplot << "TITLE = \"3D CONVEX SHELL\"" << endl;
    633       *tecplot << "VARIABLES = \"X\" \"Y\" \"Z\"" << endl;
    634       *tecplot << "ZONE T=\"TRIANGLES" << N << "\", N="
    635           << TesselStruct->PointsOnBoundaryCount << ", E="
    636           << TesselStruct->TrianglesOnBoundaryCount
    637           << ", DATAPACKING=POINT, ZONETYPE=FETRIANGLE" << endl;
    638       int *LookupList = new int[mol->AtomCount];
    639       for (int i = 0; i < mol->AtomCount; i++)
    640         LookupList[i] = -1;
    641 
    642       // print atom coordinates
    643       *out << Verbose(2) << "The following triangles were created:";
    644       int Counter = 1;
    645       atom *Walker = NULL;
    646       for (PointMap::iterator target = TesselStruct->PointsOnBoundary.begin(); target
    647           != TesselStruct->PointsOnBoundary.end(); target++)
    648         {
    649           Walker = target->second->node;
    650           LookupList[Walker->nr] = Counter++;
    651           *tecplot << Walker->x.x[0] << " " << Walker->x.x[1] << " "
    652               << Walker->x.x[2] << " " << endl;
    653         }
    654       *tecplot << endl;
    655       // print connectivity
    656       for (TriangleMap::iterator runner =
    657           TesselStruct->TrianglesOnBoundary.begin(); runner
    658           != TesselStruct->TrianglesOnBoundary.end(); runner++)
    659         {
    660           *out << " " << runner->second->endpoints[0]->node->Name << "<->"
    661               << runner->second->endpoints[1]->node->Name << "<->"
    662               << runner->second->endpoints[2]->node->Name;
    663           *tecplot << LookupList[runner->second->endpoints[0]->node->nr] << " "
    664               << LookupList[runner->second->endpoints[1]->node->nr] << " "
    665               << LookupList[runner->second->endpoints[2]->node->nr] << endl;
    666         }
    667       delete[] (LookupList);
    668       *out << endl;
    669     }
    670 }
     452};
     453
    671454
    672455/** Determines the volume of a cluster.
    673456 * Determines first the convex envelope, then tesselates it and calculates its volume.
    674457 * \param *out output stream for debugging
    675  * \param *tecplot output stream for tecplot data
    676458 * \param *configuration needed for path to store convex envelope file
    677459 * \param *BoundaryPoints NDIM set of boundary points on the projected plane per axis, on return if desired
    678460 * \param *mol molecule structure representing the cluster
    679  * \return determined volume of the cluster in cubed config:GetIsAngstroem()
    680461 */
    681 double
    682 VolumeOfConvexEnvelope(ofstream *out, ofstream *tecplot, config *configuration,
    683     Boundaries *BoundaryPtr, molecule *mol)
     462double VolumeOfConvexEnvelope(ofstream *out, config *configuration, Boundaries *BoundaryPtr, molecule *mol)
    684463{
    685464  bool IsAngstroem = configuration->GetIsAngstroem();
     
    690469  double volume = 0.;
    691470  double PyramidVolume = 0.;
    692   double G, h;
    693   Vector x, y;
    694   double a, b, c;
    695 
    696   //Find_non_convex_border(out, tecplot, *TesselStruct, mol); // Is now called from command line.
     471  double G,h;
     472  Vector x,y;
     473  double a,b,c;
    697474
    698475  // 1. calculate center of gravity
    699476  *out << endl;
    700477  Vector *CenterOfGravity = mol->DetermineCenterOfGravity(out);
    701 
     478 
    702479  // 2. translate all points into CoG
    703480  *out << Verbose(1) << "Translating system to Center of Gravity." << endl;
    704481  Walker = mol->start;
    705   while (Walker->next != mol->end)
    706     {
    707       Walker = Walker->next;
    708       Walker->x.Translate(CenterOfGravity);
     482  while (Walker->next != mol->end) {
     483    Walker = Walker->next;
     484    Walker->x.Translate(CenterOfGravity);
     485  }
     486 
     487  // 3. Find all points on the boundary
     488  if (BoundaryPoints == NULL) {
     489    BoundaryFreeFlag = true;
     490    BoundaryPoints = GetBoundaryPoints(out, mol);
     491  } else {
     492    *out << Verbose(1) << "Using given boundary points set." << endl;
     493  }
     494 
     495  // 4. fill the boundary point list
     496  for (int axis=0;axis<NDIM;axis++)
     497    for(Boundaries::iterator runner = BoundaryPoints[axis].begin(); runner != BoundaryPoints[axis].end(); runner++) {
     498      TesselStruct->AddPoint(runner->second.second);
    709499    }
    710500
    711   // 3. Find all points on the boundary
    712   if (BoundaryPoints == NULL)
    713     {
    714       BoundaryFreeFlag = true;
    715       BoundaryPoints = GetBoundaryPoints(out, mol);
    716     }
    717   else
    718     {
    719       *out << Verbose(1) << "Using given boundary points set." << endl;
    720     }
    721 
    722   // 4. fill the boundary point list
    723   for (int axis = 0; axis < NDIM; axis++)
    724     for (Boundaries::iterator runner = BoundaryPoints[axis].begin(); runner
    725         != BoundaryPoints[axis].end(); runner++)
    726       {
    727         TesselStruct->AddPoint(runner->second.second);
    728       }
    729 
    730   *out << Verbose(2) << "I found " << TesselStruct->PointsOnBoundaryCount
    731       << " points on the convex boundary." << endl;
     501  *out << Verbose(2) << "I found " << TesselStruct->PointsOnBoundaryCount << " points on the convex boundary." << endl;
    732502  // now we have the whole set of edge points in the BoundaryList
    733503
     504
    734505  // listing for debugging
    735   //  *out << Verbose(1) << "Listing PointsOnBoundary:";
    736   //  for(PointMap::iterator runner = PointsOnBoundary.begin(); runner != PointsOnBoundary.end(); runner++) {
    737   //    *out << " " << *runner->second;
    738   //  }
    739   //  *out << endl;
    740 
     506//  *out << Verbose(1) << "Listing PointsOnBoundary:";
     507//  for(PointMap::iterator runner = PointsOnBoundary.begin(); runner != PointsOnBoundary.end(); runner++) {
     508//    *out << " " << *runner->second;
     509//  }
     510//  *out << endl;
     511 
    741512  // 5a. guess starting triangle
    742513  TesselStruct->GuessStartingTriangle(out);
    743 
     514 
    744515  // 5b. go through all lines, that are not yet part of two triangles (only of one so far)
    745516  TesselStruct->TesselateOnBoundary(out, configuration, mol);
    746517
    747   *out << Verbose(2) << "I created " << TesselStruct->TrianglesOnBoundaryCount
    748       << " triangles with " << TesselStruct->LinesOnBoundaryCount
    749       << " lines and " << TesselStruct->PointsOnBoundaryCount << " points."
    750       << endl;
     518  *out << Verbose(2) << "I created " << TesselStruct->TrianglesOnBoundaryCount << " triangles with " << TesselStruct->LinesOnBoundaryCount << " lines and " << TesselStruct->PointsOnBoundaryCount << " points." << endl;
    751519
    752520  // 6a. Every triangle forms a pyramid with the center of gravity as its peak, sum up the volumes
    753   *out << Verbose(1)
    754       << "Calculating the volume of the pyramids formed out of triangles and center of gravity."
    755       << endl;
    756   for (TriangleMap::iterator runner = TesselStruct->TrianglesOnBoundary.begin(); runner
    757       != TesselStruct->TrianglesOnBoundary.end(); runner++)
    758     { // go through every triangle, calculate volume of its pyramid with CoG as peak
    759       x.CopyVector(&runner->second->endpoints[0]->node->x);
    760       x.SubtractVector(&runner->second->endpoints[1]->node->x);
    761       y.CopyVector(&runner->second->endpoints[0]->node->x);
    762       y.SubtractVector(&runner->second->endpoints[2]->node->x);
    763       a = sqrt(runner->second->endpoints[0]->node->x.Distance(
    764           &runner->second->endpoints[1]->node->x));
    765       b = sqrt(runner->second->endpoints[0]->node->x.Distance(
    766           &runner->second->endpoints[2]->node->x));
    767       c = sqrt(runner->second->endpoints[2]->node->x.Distance(
    768           &runner->second->endpoints[1]->node->x));
    769       G = sqrt(((a * a + b * b + c * c) * (a * a + b * b + c * c) - 2 * (a * a
    770           * a * a + b * b * b * b + c * c * c * c)) / 16.); // area of tesselated triangle
    771       x.MakeNormalVector(&runner->second->endpoints[0]->node->x,
    772           &runner->second->endpoints[1]->node->x,
    773           &runner->second->endpoints[2]->node->x);
    774       x.Scale(runner->second->endpoints[1]->node->x.Projection(&x));
    775       h = x.Norm(); // distance of CoG to triangle
    776       PyramidVolume = (1. / 3.) * G * h; // this formula holds for _all_ pyramids (independent of n-edge base or (not) centered peak)
    777       *out << Verbose(2) << "Area of triangle is " << G << " "
    778           << (IsAngstroem ? "angstrom" : "atomiclength") << "^2, height is "
    779           << h << " and the volume is " << PyramidVolume << " "
    780           << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl;
    781       volume += PyramidVolume;
    782     }
    783   *out << Verbose(0) << "RESULT: The summed volume is " << setprecision(10)
    784       << volume << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3."
    785       << endl;
     521  *out << Verbose(1) << "Calculating the volume of the pyramids formed out of triangles and center of gravity." << endl;
     522  for (TriangleMap::iterator runner = TesselStruct->TrianglesOnBoundary.begin(); runner != TesselStruct->TrianglesOnBoundary.end(); runner++) { // go through every triangle, calculate volume of its pyramid with CoG as peak
     523    x.CopyVector(&runner->second->endpoints[0]->node->x);
     524    x.SubtractVector(&runner->second->endpoints[1]->node->x);
     525    y.CopyVector(&runner->second->endpoints[0]->node->x);
     526    y.SubtractVector(&runner->second->endpoints[2]->node->x);
     527    a = sqrt(runner->second->endpoints[0]->node->x.Distance(&runner->second->endpoints[1]->node->x));
     528    b = sqrt(runner->second->endpoints[0]->node->x.Distance(&runner->second->endpoints[2]->node->x));
     529    c = sqrt(runner->second->endpoints[2]->node->x.Distance(&runner->second->endpoints[1]->node->x));
     530    G =  sqrt( ( (a*a+b*b+c*c)*(a*a+b*b+c*c) - 2*(a*a*a*a + b*b*b*b + c*c*c*c) )/16.); // area of tesselated triangle
     531    x.MakeNormalVector(&runner->second->endpoints[0]->node->x, &runner->second->endpoints[1]->node->x, &runner->second->endpoints[2]->node->x);
     532    x.Scale(runner->second->endpoints[1]->node->x.Projection(&x));
     533    h = x.Norm(); // distance of CoG to triangle
     534    PyramidVolume = (1./3.) * G * h;    // this formula holds for _all_ pyramids (independent of n-edge base or (not) centered peak)
     535    *out << Verbose(2) << "Area of triangle is " << G << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^2, height is " << h << " and the volume is " << PyramidVolume << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl;
     536    volume += PyramidVolume;
     537  }
     538  *out << Verbose(0) << "RESULT: The summed volume is " << setprecision(10) << volume << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl;
     539
    786540
    787541  // 7. translate all points back from CoG
    788   *out << Verbose(1) << "Translating system back from Center of Gravity."
    789       << endl;
     542  *out << Verbose(1) << "Translating system back from Center of Gravity." << endl;
    790543  CenterOfGravity->Scale(-1);
    791544  Walker = mol->start;
    792   while (Walker->next != mol->end)
    793     {
    794       Walker = Walker->next;
    795       Walker->x.Translate(CenterOfGravity);
    796     }
    797 
    798   // 8. Store triangles in tecplot file
    799   write_tecplot_file(out, tecplot, TesselStruct, mol, 0);
     545  while (Walker->next != mol->end) {
     546    Walker = Walker->next;
     547    Walker->x.Translate(CenterOfGravity);
     548  }
    800549
    801550  // free reference lists
    802551  if (BoundaryFreeFlag)
    803     delete[] (BoundaryPoints);
    804 
     552    delete[](BoundaryPoints);
     553 
    805554  return volume;
    806 }
    807 ;
     555};
     556
    808557
    809558/** Creates multiples of the by \a *mol given cluster and suspends them in water with a given final density.
     
    815564 * \param celldensity desired average density in final cell
    816565 */
    817 void
    818 PrepareClustersinWater(ofstream *out, config *configuration, molecule *mol,
    819     double ClusterVolume, double celldensity)
     566void PrepareClustersinWater(ofstream *out, config *configuration, molecule *mol, double ClusterVolume, double celldensity)
    820567{
    821568  // transform to PAS
    822569  mol->PrincipalAxisSystem(out, true);
    823 
     570 
    824571  // some preparations beforehand
    825572  bool IsAngstroem = configuration->GetIsAngstroem();
     
    827574  double clustervolume;
    828575  if (ClusterVolume == 0)
    829     clustervolume = VolumeOfConvexEnvelope(out, NULL, configuration,
    830         BoundaryPoints, mol);
    831   else
     576    clustervolume = VolumeOfConvexEnvelope(out, configuration, BoundaryPoints, mol);
     577  else
    832578    clustervolume = ClusterVolume;
    833   double *GreatestDiameter = GetDiametersOfCluster(out, BoundaryPoints, mol,
    834       IsAngstroem);
     579  double *GreatestDiameter = GetDiametersOfCluster(out, BoundaryPoints, mol, IsAngstroem);
    835580  Vector BoxLengths;
    836   int repetition[NDIM] =
    837     { 1, 1, 1 };
     581  int repetition[NDIM] = {1, 1, 1};
    838582  int TotalNoClusters = 1;
    839   for (int i = 0; i < NDIM; i++)
     583  for (int i=0;i<NDIM;i++)
    840584    TotalNoClusters *= repetition[i];
    841585
     
    843587  double totalmass = 0.;
    844588  atom *Walker = mol->start;
    845   while (Walker->next != mol->end)
    846     {
    847       Walker = Walker->next;
    848       totalmass += Walker->type->mass;
    849     }
    850   *out << Verbose(0) << "RESULT: The summed mass is " << setprecision(10)
    851       << totalmass << " atomicmassunit." << endl;
    852 
    853   *out << Verbose(0) << "RESULT: The average density is " << setprecision(10)
    854       << totalmass / clustervolume << " atomicmassunit/"
    855       << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl;
    856 
     589  while (Walker->next != mol->end) {
     590    Walker = Walker->next;
     591    totalmass += Walker->type->mass;
     592  }
     593  *out << Verbose(0) << "RESULT: The summed mass is " << setprecision(10) << totalmass << " atomicmassunit." << endl;
     594 
     595  *out << Verbose(0) << "RESULT: The average density is " << setprecision(10) << totalmass/clustervolume << " atomicmassunit/" << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl;
     596 
    857597  // solve cubic polynomial
    858   *out << Verbose(1) << "Solving equidistant suspension in water problem ..."
    859       << endl;
     598  *out << Verbose(1) << "Solving equidistant suspension in water problem ..." << endl;
    860599  double cellvolume;
    861600  if (IsAngstroem)
    862     cellvolume = (TotalNoClusters * totalmass / SOLVENTDENSITY_A - (totalmass
    863         / clustervolume)) / (celldensity - 1);
     601    cellvolume = (TotalNoClusters*totalmass/SOLVENTDENSITY_A - (totalmass/clustervolume))/(celldensity-1);
    864602  else
    865     cellvolume = (TotalNoClusters * totalmass / SOLVENTDENSITY_a0 - (totalmass
    866         / clustervolume)) / (celldensity - 1);
    867   *out << Verbose(1) << "Cellvolume needed for a density of " << celldensity
    868       << " g/cm^3 is " << cellvolume << " " << (IsAngstroem ? "angstrom"
    869       : "atomiclength") << "^3." << endl;
    870 
    871   double minimumvolume = TotalNoClusters * (GreatestDiameter[0]
    872       * GreatestDiameter[1] * GreatestDiameter[2]);
    873   *out << Verbose(1)
    874       << "Minimum volume of the convex envelope contained in a rectangular box is "
    875       << minimumvolume << " atomicmassunit/" << (IsAngstroem ? "angstrom"
    876       : "atomiclength") << "^3." << endl;
    877   if (minimumvolume > cellvolume)
    878     {
    879       cerr << Verbose(0)
    880           << "ERROR: the containing box already has a greater volume than the envisaged cell volume!"
    881           << endl;
    882       cout << Verbose(0)
    883           << "Setting Box dimensions to minimum possible, the greatest diameters."
    884           << endl;
    885       for (int i = 0; i < NDIM; i++)
    886         BoxLengths.x[i] = GreatestDiameter[i];
    887       mol->CenterEdge(out, &BoxLengths);
     603    cellvolume = (TotalNoClusters*totalmass/SOLVENTDENSITY_a0 - (totalmass/clustervolume))/(celldensity-1);
     604  *out << Verbose(1) << "Cellvolume needed for a density of " << celldensity << " g/cm^3 is " << cellvolume << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl;
     605 
     606  double minimumvolume = TotalNoClusters*(GreatestDiameter[0]*GreatestDiameter[1]*GreatestDiameter[2]);
     607  *out << Verbose(1) << "Minimum volume of the convex envelope contained in a rectangular box is " << minimumvolume << " atomicmassunit/" << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl;
     608  if (minimumvolume > cellvolume) {
     609    cerr << Verbose(0) << "ERROR: the containing box already has a greater volume than the envisaged cell volume!" << endl;
     610    cout << Verbose(0) << "Setting Box dimensions to minimum possible, the greatest diameters." << endl;
     611    for(int i=0;i<NDIM;i++)
     612      BoxLengths.x[i] = GreatestDiameter[i];
     613    mol->CenterEdge(out, &BoxLengths);
     614  } else {
     615    BoxLengths.x[0] = (repetition[0]*GreatestDiameter[0] + repetition[1]*GreatestDiameter[1] + repetition[2]*GreatestDiameter[2]);
     616    BoxLengths.x[1] = (repetition[0]*repetition[1]*GreatestDiameter[0]*GreatestDiameter[1]
     617              + repetition[0]*repetition[2]*GreatestDiameter[0]*GreatestDiameter[2]
     618              + repetition[1]*repetition[2]*GreatestDiameter[1]*GreatestDiameter[2]);
     619    BoxLengths.x[2] = minimumvolume - cellvolume;
     620    double x0 = 0.,x1 = 0.,x2 = 0.;
     621    if (gsl_poly_solve_cubic(BoxLengths.x[0],BoxLengths.x[1],BoxLengths.x[2],&x0,&x1,&x2) == 1) // either 1 or 3 on return
     622      *out << Verbose(0) << "RESULT: The resulting spacing is: " << x0 << " ." << endl;
     623    else {
     624      *out << Verbose(0) << "RESULT: The resulting spacings are: " << x0 << " and " << x1 << " and " << x2 << " ." << endl;
     625      x0 = x2;  // sorted in ascending order
    888626    }
    889   else
    890     {
    891       BoxLengths.x[0] = (repetition[0] * GreatestDiameter[0] + repetition[1]
    892           * GreatestDiameter[1] + repetition[2] * GreatestDiameter[2]);
    893       BoxLengths.x[1] = (repetition[0] * repetition[1] * GreatestDiameter[0]
    894           * GreatestDiameter[1] + repetition[0] * repetition[2]
    895           * GreatestDiameter[0] * GreatestDiameter[2] + repetition[1]
    896           * repetition[2] * GreatestDiameter[1] * GreatestDiameter[2]);
    897       BoxLengths.x[2] = minimumvolume - cellvolume;
    898       double x0 = 0., x1 = 0., x2 = 0.;
    899       if (gsl_poly_solve_cubic(BoxLengths.x[0], BoxLengths.x[1],
    900           BoxLengths.x[2], &x0, &x1, &x2) == 1) // either 1 or 3 on return
    901         *out << Verbose(0) << "RESULT: The resulting spacing is: " << x0
    902             << " ." << endl;
    903       else
    904         {
    905           *out << Verbose(0) << "RESULT: The resulting spacings are: " << x0
    906               << " and " << x1 << " and " << x2 << " ." << endl;
    907           x0 = x2; // sorted in ascending order
    908         }
    909 
    910       cellvolume = 1;
    911       for (int i = 0; i < NDIM; i++)
    912         {
    913           BoxLengths.x[i] = repetition[i] * (x0 + GreatestDiameter[i]);
    914           cellvolume *= BoxLengths.x[i];
    915         }
    916 
    917       // set new box dimensions
    918       *out << Verbose(0) << "Translating to box with these boundaries." << endl;
    919       mol->CenterInBox((ofstream *) &cout, &BoxLengths);
     627 
     628    cellvolume = 1;
     629    for(int i=0;i<NDIM;i++) {
     630      BoxLengths.x[i] = repetition[i] * (x0 + GreatestDiameter[i]);
     631      cellvolume *= BoxLengths.x[i];
    920632    }
     633 
     634    // set new box dimensions
     635    *out << Verbose(0) << "Translating to box with these boundaries." << endl;
     636    mol->CenterInBox((ofstream *)&cout, &BoxLengths);
     637  }
    921638  // update Box of atoms by boundary
    922639  mol->SetBoxDimension(&BoxLengths);
    923   *out << Verbose(0) << "RESULT: The resulting cell dimensions are: "
    924       << BoxLengths.x[0] << " and " << BoxLengths.x[1] << " and "
    925       << BoxLengths.x[2] << " with total volume of " << cellvolume << " "
    926       << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl;
    927 }
    928 ;
     640  *out << Verbose(0) << "RESULT: The resulting cell dimensions are: " << BoxLengths.x[0] << " and " << BoxLengths.x[1] << " and " << BoxLengths.x[2] << " with total volume of " << cellvolume << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl;
     641};
     642
    929643
    930644// =========================================================== class TESSELATION ===========================================
     
    934648Tesselation::Tesselation()
    935649{
    936   PointsOnBoundaryCount = 0;
    937   LinesOnBoundaryCount = 0;
     650  PointsOnBoundaryCount = 0; 
     651  LinesOnBoundaryCount = 0; 
    938652  TrianglesOnBoundaryCount = 0;
    939   TriangleFilesWritten = 0;
    940 }
    941 ;
     653};
    942654
    943655/** Constructor of class Tesselation.
     
    946658Tesselation::~Tesselation()
    947659{
    948         cout << Verbose(1) << "Free'ing TesselStruct ... " << endl;
    949         for (TriangleMap::iterator runner = TrianglesOnBoundary.begin(); runner != TrianglesOnBoundary.end(); runner++) {
    950                 if (runner->second != NULL) {
    951                         delete (runner->second);
    952                         runner->second = NULL;
    953                 } else
    954                         cerr << "ERROR: The triangle " << runner->first << " has already been free'd." << endl;
    955         }
    956         for (LineMap::iterator runner = LinesOnBoundary.begin(); runner != LinesOnBoundary.end(); runner++) {
    957                 if (runner->second != NULL) {
    958                         delete (runner->second);
    959                         runner->second = NULL;
    960                 } else
    961                         cerr << "ERROR: The line " << runner->first << " has already been free'd." << endl;
    962         }
    963         for (PointMap::iterator runner = PointsOnBoundary.begin(); runner != PointsOnBoundary.end(); runner++) {
    964                 if (runner->second != NULL) {
    965                         delete (runner->second);
    966                         runner->second = NULL;
    967                 } else
    968                         cerr << "ERROR: The point " << runner->first << " has already been free'd." << endl;
    969         }
    970 }
    971 ;
     660  for (TriangleMap::iterator runner = TrianglesOnBoundary.begin(); runner != TrianglesOnBoundary.end(); runner++) {
     661    delete(runner->second);
     662  }
     663};
    972664
    973665/** Gueses first starting triangle of the convex envelope.
     
    975667 * \param *out output stream for debugging
    976668 * \param PointsOnBoundary set of boundary points defining the convex envelope of the cluster
    977  */
    978 void
    979 Tesselation::GuessStartingTriangle(ofstream *out)
     669 */
     670void Tesselation::GuessStartingTriangle(ofstream *out)
    980671{
    981672  // 4b. create a starting triangle
    982673  // 4b1. create all distances
    983674  DistanceMultiMap DistanceMMap;
    984   double distance, tmp;
    985   Vector PlaneVector, TrialVector;
    986   PointMap::iterator A, B, C; // three nodes of the first triangle
    987   A = PointsOnBoundary.begin(); // the first may be chosen arbitrarily
    988 
    989   // with A chosen, take each pair B,C and sort
    990   if (A != PointsOnBoundary.end())
    991     {
    992       B = A;
    993       B++;
    994       for (; B != PointsOnBoundary.end(); B++)
    995         {
    996           C = B;
    997           C++;
    998           for (; C != PointsOnBoundary.end(); C++)
    999             {
    1000               tmp = A->second->node->x.Distance(&B->second->node->x);
    1001               distance = tmp * tmp;
    1002               tmp = A->second->node->x.Distance(&C->second->node->x);
    1003               distance += tmp * tmp;
    1004               tmp = B->second->node->x.Distance(&C->second->node->x);
    1005               distance += tmp * tmp;
    1006               DistanceMMap.insert(DistanceMultiMapPair(distance, pair<
    1007                   PointMap::iterator, PointMap::iterator> (B, C)));
    1008             }
    1009         }
     675  double distance;
     676  for (PointMap::iterator runner = PointsOnBoundary.begin(); runner != PointsOnBoundary.end(); runner++) {
     677    for(PointMap::iterator sprinter = PointsOnBoundary.begin(); sprinter != PointsOnBoundary.end(); sprinter++) {
     678      if (runner->first < sprinter->first) {
     679        distance = runner->second->node->x.Distance(&sprinter->second->node->x);
     680        DistanceMMap.insert( DistanceMultiMapPair(distance, pair<PointMap::iterator, PointMap::iterator>(runner,sprinter) ) );
     681      }
    1010682    }
    1011   //    // listing distances
    1012   //    *out << Verbose(1) << "Listing DistanceMMap:";
    1013   //    for(DistanceMultiMap::iterator runner = DistanceMMap.begin(); runner != DistanceMMap.end(); runner++) {
    1014   //      *out << " " << runner->first << "(" << *runner->second.first->second << ", " << *runner->second.second->second << ")";
    1015   //    }
    1016   //    *out << endl;
    1017   // 4b2. pick three baselines forming a triangle
    1018   // 1. we take from the smallest sum of squared distance as the base line BC (with peak A) onward as the triangle candidate
     683  }
     684
     685//    // listing distances
     686//    *out << Verbose(1) << "Listing DistanceMMap:";
     687//    for(DistanceMultiMap::iterator runner = DistanceMMap.begin(); runner != DistanceMMap.end(); runner++) {
     688//      *out << " " << runner->first << "(" << *runner->second.first->second << ", " << *runner->second.second->second << ")";
     689//    }
     690//    *out << endl;
     691 
     692  // 4b2. take three smallest distance that form a triangle
     693  // we take the smallest distance as the base line
    1019694  DistanceMultiMap::iterator baseline = DistanceMMap.begin();
    1020   for (; baseline != DistanceMMap.end(); baseline++)
    1021     {
    1022       // we take from the smallest sum of squared distance as the base line BC (with peak A) onward as the triangle candidate
    1023       // 2. next, we have to check whether all points reside on only one side of the triangle
    1024       // 3. construct plane vector
    1025       PlaneVector.MakeNormalVector(&A->second->node->x,
    1026           &baseline->second.first->second->node->x,
    1027           &baseline->second.second->second->node->x);
    1028       *out << Verbose(2) << "Plane vector of candidate triangle is ";
    1029       PlaneVector.Output(out);
    1030       *out << endl;
    1031       // 4. loop over all points
    1032       double sign = 0.;
    1033       PointMap::iterator checker = PointsOnBoundary.begin();
    1034       for (; checker != PointsOnBoundary.end(); checker++)
    1035         {
    1036           // (neglecting A,B,C)
    1037           if ((checker == A) || (checker == baseline->second.first) || (checker
    1038               == baseline->second.second))
    1039             continue;
    1040           // 4a. project onto plane vector
    1041           TrialVector.CopyVector(&checker->second->node->x);
    1042           TrialVector.SubtractVector(&A->second->node->x);
    1043           distance = TrialVector.Projection(&PlaneVector);
    1044           if (fabs(distance) < 1e-4) // we need to have a small epsilon around 0 which is still ok
    1045             continue;
    1046           *out << Verbose(3) << "Projection of " << checker->second->node->Name
    1047               << " yields distance of " << distance << "." << endl;
    1048           tmp = distance / fabs(distance);
    1049           // 4b. Any have different sign to than before? (i.e. would lie outside convex hull with this starting triangle)
    1050           if ((sign != 0) && (tmp != sign))
    1051             {
    1052               // 4c. If so, break 4. loop and continue with next candidate in 1. loop
    1053               *out << Verbose(2) << "Current candidates: "
    1054                   << A->second->node->Name << ","
    1055                   << baseline->second.first->second->node->Name << ","
    1056                   << baseline->second.second->second->node->Name << " leave "
    1057                   << checker->second->node->Name << " outside the convex hull."
    1058                   << endl;
    1059               break;
    1060             }
    1061           else
    1062             { // note the sign for later
    1063               *out << Verbose(2) << "Current candidates: "
    1064                   << A->second->node->Name << ","
    1065                   << baseline->second.first->second->node->Name << ","
    1066                   << baseline->second.second->second->node->Name << " leave "
    1067                   << checker->second->node->Name << " inside the convex hull."
    1068                   << endl;
    1069               sign = tmp;
    1070             }
    1071           // 4d. Check whether the point is inside the triangle (check distance to each node
    1072           tmp = checker->second->node->x.Distance(&A->second->node->x);
    1073           int innerpoint = 0;
    1074           if ((tmp < A->second->node->x.Distance(
    1075               &baseline->second.first->second->node->x)) && (tmp
    1076               < A->second->node->x.Distance(
    1077                   &baseline->second.second->second->node->x)))
    1078             innerpoint++;
    1079           tmp = checker->second->node->x.Distance(
    1080               &baseline->second.first->second->node->x);
    1081           if ((tmp < baseline->second.first->second->node->x.Distance(
    1082               &A->second->node->x)) && (tmp
    1083               < baseline->second.first->second->node->x.Distance(
    1084                   &baseline->second.second->second->node->x)))
    1085             innerpoint++;
    1086           tmp = checker->second->node->x.Distance(
    1087               &baseline->second.second->second->node->x);
    1088           if ((tmp < baseline->second.second->second->node->x.Distance(
    1089               &baseline->second.first->second->node->x)) && (tmp
    1090               < baseline->second.second->second->node->x.Distance(
    1091                   &A->second->node->x)))
    1092             innerpoint++;
    1093           // 4e. If so, break 4. loop and continue with next candidate in 1. loop
    1094           if (innerpoint == 3)
    1095             break;
    1096         }
    1097       // 5. come this far, all on same side? Then break 1. loop and construct triangle
    1098       if (checker == PointsOnBoundary.end())
    1099         {
    1100           *out << "Looks like we have a candidate!" << endl;
    1101           break;
    1102         }
    1103     }
    1104   if (baseline != DistanceMMap.end())
    1105     {
    1106       BPS[0] = baseline->second.first->second;
    1107       BPS[1] = baseline->second.second->second;
    1108       BLS[0] = new class BoundaryLineSet(BPS, LinesOnBoundaryCount);
    1109       BPS[0] = A->second;
    1110       BPS[1] = baseline->second.second->second;
    1111       BLS[1] = new class BoundaryLineSet(BPS, LinesOnBoundaryCount);
    1112       BPS[0] = baseline->second.first->second;
    1113       BPS[1] = A->second;
    1114       BLS[2] = new class BoundaryLineSet(BPS, LinesOnBoundaryCount);
    1115 
    1116       // 4b3. insert created triangle
    1117       BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
    1118       TrianglesOnBoundary.insert(TrianglePair(TrianglesOnBoundaryCount, BTS));
    1119       TrianglesOnBoundaryCount++;
    1120       for (int i = 0; i < NDIM; i++)
    1121         {
    1122           LinesOnBoundary.insert(LinePair(LinesOnBoundaryCount, BTS->lines[i]));
    1123           LinesOnBoundaryCount++;
    1124         }
    1125 
    1126       *out << Verbose(1) << "Starting triangle is " << *BTS << "." << endl;
    1127     }
    1128   else
    1129     {
    1130       *out << Verbose(1) << "No starting triangle found." << endl;
    1131       exit(255);
    1132     }
    1133 }
    1134 ;
     695  BPS[0] = baseline->second.first->second;
     696  BPS[1] = baseline->second.second->second;
     697  BLS[0] = new class BoundaryLineSet(BPS , LinesOnBoundaryCount);
     698
     699  // take the second smallest as the second base line
     700  DistanceMultiMap::iterator secondline = DistanceMMap.begin();
     701  do {
     702    secondline++;
     703  } while (!(
     704      ((BPS[0] == secondline->second.first->second) && (BPS[1] != secondline->second.second->second)) ||
     705      ((BPS[0] == secondline->second.second->second) && (BPS[1] != secondline->second.first->second)) ||
     706      ((BPS[1] == secondline->second.first->second) && (BPS[0] != secondline->second.second->second)) ||
     707      ((BPS[1] == secondline->second.second->second) && (BPS[0] != secondline->second.first->second))
     708    ));
     709  BPS[0] = secondline->second.first->second;
     710  BPS[1] = secondline->second.second->second;
     711  BLS[1] = new class BoundaryLineSet(BPS , LinesOnBoundaryCount);
     712
     713  // connection yields the third line (note: first and second endpoint are sorted!)
     714  if (baseline->second.first->second == secondline->second.first->second) {
     715    SetEndpointsOrdered(BPS, baseline->second.second->second, secondline->second.second->second);
     716  } else if (baseline->second.first->second == secondline->second.second->second) {
     717    SetEndpointsOrdered(BPS, baseline->second.second->second, secondline->second.first->second);
     718  } else if (baseline->second.second->second == secondline->second.first->second) {
     719    SetEndpointsOrdered(BPS, baseline->second.first->second, baseline->second.second->second);
     720  } else if (baseline->second.second->second == secondline->second.second->second) {
     721    SetEndpointsOrdered(BPS, baseline->second.first->second, baseline->second.first->second);
     722  }
     723  BLS[2] = new class BoundaryLineSet(BPS, LinesOnBoundaryCount);
     724 
     725  // 4b3. insert created triangle
     726  BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
     727  TrianglesOnBoundary.insert( TrianglePair(TrianglesOnBoundaryCount, BTS) );
     728  TrianglesOnBoundaryCount++;
     729  for(int i=0;i<NDIM;i++) {
     730    LinesOnBoundary.insert( LinePair(LinesOnBoundaryCount, BTS->lines[i]) );
     731    LinesOnBoundaryCount++;
     732  }
     733
     734  *out << Verbose(1) << "Starting triangle is " << *BTS << "." << endl;
     735};
     736
    1135737
    1136738/** Tesselates the convex envelope of a cluster from a single starting triangle.
     
    1147749 * \param *mol the cluster as a molecule structure
    1148750 */
    1149 void
    1150 Tesselation::TesselateOnBoundary(ofstream *out, config *configuration,
    1151     molecule *mol)
     751void Tesselation::TesselateOnBoundary(ofstream *out, config *configuration, molecule *mol)
    1152752{
    1153753  bool flag;
     
    1155755  class BoundaryPointSet *peak = NULL;
    1156756  double SmallestAngle, TempAngle;
    1157   Vector NormalVector, VirtualNormalVector, CenterVector, TempVector,
    1158       PropagationVector;
     757  Vector NormalVector, VirtualNormalVector, CenterVector, TempVector, PropagationVector;
    1159758  LineMap::iterator LineChecker[2];
    1160   do
    1161     {
    1162       flag = false;
    1163       for (LineMap::iterator baseline = LinesOnBoundary.begin(); baseline
    1164           != LinesOnBoundary.end(); baseline++)
    1165         if (baseline->second->TrianglesCount == 1)
    1166           {
    1167             *out << Verbose(2) << "Current baseline is between "
    1168                 << *(baseline->second) << "." << endl;
    1169             // 5a. go through each boundary point if not _both_ edges between either endpoint of the current line and this point exist (and belong to 2 triangles)
    1170             SmallestAngle = M_PI;
    1171             BTS = baseline->second->triangles.begin()->second; // there is only one triangle so far
    1172             // get peak point with respect to this base line's only triangle
    1173             for (int i = 0; i < 3; i++)
    1174               if ((BTS->endpoints[i] != baseline->second->endpoints[0])
    1175                   && (BTS->endpoints[i] != baseline->second->endpoints[1]))
    1176                 peak = BTS->endpoints[i];
    1177             *out << Verbose(3) << " and has peak " << *peak << "." << endl;
    1178             // normal vector of triangle
    1179             BTS->GetNormalVector(NormalVector);
    1180             *out << Verbose(4) << "NormalVector of base triangle is ";
    1181             NormalVector.Output(out);
    1182             *out << endl;
    1183             // offset to center of triangle
    1184             CenterVector.Zero();
    1185             for (int i = 0; i < 3; i++)
    1186               CenterVector.AddVector(&BTS->endpoints[i]->node->x);
    1187             CenterVector.Scale(1. / 3.);
    1188             *out << Verbose(4) << "CenterVector of base triangle is ";
    1189             CenterVector.Output(out);
    1190             *out << endl;
    1191             // vector in propagation direction (out of triangle)
    1192             // project center vector onto triangle plane (points from intersection plane-NormalVector to plane-CenterVector intersection)
    1193             TempVector.CopyVector(&baseline->second->endpoints[0]->node->x);
    1194             TempVector.SubtractVector(&baseline->second->endpoints[1]->node->x);
    1195             PropagationVector.MakeNormalVector(&TempVector, &NormalVector);
    1196             TempVector.CopyVector(&CenterVector);
    1197             TempVector.SubtractVector(&baseline->second->endpoints[0]->node->x); // TempVector is vector on triangle plane pointing from one baseline egde towards center!
    1198             //*out << Verbose(2) << "Projection of propagation onto temp: " << PropagationVector.Projection(&TempVector) << "." << endl;
    1199             if (PropagationVector.Projection(&TempVector) > 0) // make sure normal propagation vector points outward from baseline
    1200               PropagationVector.Scale(-1.);
    1201             *out << Verbose(4) << "PropagationVector of base triangle is ";
    1202             PropagationVector.Output(out);
    1203             *out << endl;
    1204             winner = PointsOnBoundary.end();
    1205             for (PointMap::iterator target = PointsOnBoundary.begin(); target
    1206                 != PointsOnBoundary.end(); target++)
    1207               if ((target->second != baseline->second->endpoints[0])
    1208                   && (target->second != baseline->second->endpoints[1]))
    1209                 { // don't take the same endpoints
    1210                   *out << Verbose(3) << "Target point is " << *(target->second)
    1211                       << ":";
    1212                   bool continueflag = true;
    1213 
    1214                   VirtualNormalVector.CopyVector(
    1215                       &baseline->second->endpoints[0]->node->x);
    1216                   VirtualNormalVector.AddVector(
    1217                       &baseline->second->endpoints[0]->node->x);
    1218                   VirtualNormalVector.Scale(-1. / 2.); // points now to center of base line
    1219                   VirtualNormalVector.AddVector(&target->second->node->x); // points from center of base line to target
    1220                   TempAngle = VirtualNormalVector.Angle(&PropagationVector);
    1221                   continueflag = continueflag && (TempAngle < (M_PI/2.)); // no bends bigger than Pi/2 (90 degrees)
    1222                   if (!continueflag)
    1223                     {
    1224                       *out << Verbose(4)
    1225                           << "Angle between propagation direction and base line to "
    1226                           << *(target->second) << " is " << TempAngle
    1227                           << ", bad direction!" << endl;
    1228                       continue;
    1229                     }
    1230                   else
    1231                     *out << Verbose(4)
    1232                         << "Angle between propagation direction and base line to "
    1233                         << *(target->second) << " is " << TempAngle
    1234                         << ", good direction!" << endl;
    1235                   LineChecker[0] = baseline->second->endpoints[0]->lines.find(
    1236                       target->first);
    1237                   LineChecker[1] = baseline->second->endpoints[1]->lines.find(
    1238                       target->first);
    1239                   //            if (LineChecker[0] != baseline->second->endpoints[0]->lines.end())
    1240                   //              *out << Verbose(4) << *(baseline->second->endpoints[0]) << " has line " << *(LineChecker[0]->second) << " to " << *(target->second) << " as endpoint with " << LineChecker[0]->second->TrianglesCount << " triangles." << endl;
    1241                   //            else
    1242                   //              *out << Verbose(4) << *(baseline->second->endpoints[0]) << " has no line to " << *(target->second) << " as endpoint." << endl;
    1243                   //            if (LineChecker[1] != baseline->second->endpoints[1]->lines.end())
    1244                   //              *out << Verbose(4) << *(baseline->second->endpoints[1]) << " has line " << *(LineChecker[1]->second) << " to " << *(target->second) << " as endpoint with " << LineChecker[1]->second->TrianglesCount << " triangles." << endl;
    1245                   //            else
    1246                   //              *out << Verbose(4) << *(baseline->second->endpoints[1]) << " has no line to " << *(target->second) << " as endpoint." << endl;
    1247                   // check first endpoint (if any connecting line goes to target or at least not more than 1)
    1248                   continueflag = continueflag && (((LineChecker[0]
    1249                       == baseline->second->endpoints[0]->lines.end())
    1250                       || (LineChecker[0]->second->TrianglesCount == 1)));
    1251                   if (!continueflag)
    1252                     {
    1253                       *out << Verbose(4) << *(baseline->second->endpoints[0])
    1254                           << " has line " << *(LineChecker[0]->second)
    1255                           << " to " << *(target->second)
    1256                           << " as endpoint with "
    1257                           << LineChecker[0]->second->TrianglesCount
    1258                           << " triangles." << endl;
    1259                       continue;
    1260                     }
    1261                   // check second endpoint (if any connecting line goes to target or at least not more than 1)
    1262                   continueflag = continueflag && (((LineChecker[1]
    1263                       == baseline->second->endpoints[1]->lines.end())
    1264                       || (LineChecker[1]->second->TrianglesCount == 1)));
    1265                   if (!continueflag)
    1266                     {
    1267                       *out << Verbose(4) << *(baseline->second->endpoints[1])
    1268                           << " has line " << *(LineChecker[1]->second)
    1269                           << " to " << *(target->second)
    1270                           << " as endpoint with "
    1271                           << LineChecker[1]->second->TrianglesCount
    1272                           << " triangles." << endl;
    1273                       continue;
    1274                     }
    1275                   // check whether the envisaged triangle does not already exist (if both lines exist and have same endpoint)
    1276                   continueflag = continueflag && (!(((LineChecker[0]
    1277                       != baseline->second->endpoints[0]->lines.end())
    1278                       && (LineChecker[1]
    1279                           != baseline->second->endpoints[1]->lines.end())
    1280                       && (GetCommonEndpoint(LineChecker[0]->second,
    1281                           LineChecker[1]->second) == peak))));
    1282                   if (!continueflag)
    1283                     {
    1284                       *out << Verbose(4) << "Current target is peak!" << endl;
    1285                       continue;
    1286                     }
    1287                   // in case NOT both were found
    1288                   if (continueflag)
    1289                     { // create virtually this triangle, get its normal vector, calculate angle
    1290                       flag = true;
    1291                       VirtualNormalVector.MakeNormalVector(
    1292                           &baseline->second->endpoints[0]->node->x,
    1293                           &baseline->second->endpoints[1]->node->x,
    1294                           &target->second->node->x);
    1295                       // make it always point inward
    1296                       if (baseline->second->endpoints[0]->node->x.Projection(
    1297                           &VirtualNormalVector) > 0)
    1298                         VirtualNormalVector.Scale(-1.);
    1299                       // calculate angle
    1300                       TempAngle = NormalVector.Angle(&VirtualNormalVector);
    1301                       *out << Verbose(4) << "NormalVector is ";
    1302                       VirtualNormalVector.Output(out);
    1303                       *out << " and the angle is " << TempAngle << "." << endl;
    1304                       if (SmallestAngle > TempAngle)
    1305                         { // set to new possible winner
    1306                           SmallestAngle = TempAngle;
    1307                           winner = target;
    1308                         }
    1309                     }
    1310                 }
    1311             // 5b. The point of the above whose triangle has the greatest angle with the triangle the current line belongs to (it only belongs to one, remember!): New triangle
    1312             if (winner != PointsOnBoundary.end())
    1313               {
    1314                 *out << Verbose(2) << "Winning target point is "
    1315                     << *(winner->second) << " with angle " << SmallestAngle
    1316                     << "." << endl;
    1317                 // create the lins of not yet present
    1318                 BLS[0] = baseline->second;
    1319                 // 5c. add lines to the line set if those were new (not yet part of a triangle), delete lines that belong to two triangles)
    1320                 LineChecker[0] = baseline->second->endpoints[0]->lines.find(
    1321                     winner->first);
    1322                 LineChecker[1] = baseline->second->endpoints[1]->lines.find(
    1323                     winner->first);
    1324                 if (LineChecker[0]
    1325                     == baseline->second->endpoints[0]->lines.end())
    1326                   { // create
    1327                     BPS[0] = baseline->second->endpoints[0];
    1328                     BPS[1] = winner->second;
    1329                     BLS[1] = new class BoundaryLineSet(BPS,
    1330                         LinesOnBoundaryCount);
    1331                     LinesOnBoundary.insert(LinePair(LinesOnBoundaryCount,
    1332                         BLS[1]));
    1333                     LinesOnBoundaryCount++;
    1334                   }
    1335                 else
    1336                   BLS[1] = LineChecker[0]->second;
    1337                 if (LineChecker[1]
    1338                     == baseline->second->endpoints[1]->lines.end())
    1339                   { // create
    1340                     BPS[0] = baseline->second->endpoints[1];
    1341                     BPS[1] = winner->second;
    1342                     BLS[2] = new class BoundaryLineSet(BPS,
    1343                         LinesOnBoundaryCount);
    1344                     LinesOnBoundary.insert(LinePair(LinesOnBoundaryCount,
    1345                         BLS[2]));
    1346                     LinesOnBoundaryCount++;
    1347                   }
    1348                 else
    1349                   BLS[2] = LineChecker[1]->second;
    1350                 BTS = new class BoundaryTriangleSet(BLS,
    1351                     TrianglesOnBoundaryCount);
    1352                 TrianglesOnBoundary.insert(TrianglePair(
    1353                     TrianglesOnBoundaryCount, BTS));
    1354                 TrianglesOnBoundaryCount++;
     759  do {
     760    flag = false;
     761    for (LineMap::iterator baseline = LinesOnBoundary.begin(); baseline != LinesOnBoundary.end(); baseline++)
     762      if (baseline->second->TrianglesCount == 1) {
     763        *out << Verbose(2) << "Current baseline is between " << *(baseline->second) << "." << endl;
     764        // 5a. go through each boundary point if not _both_ edges between either endpoint of the current line and this point exist (and belong to 2 triangles)
     765        SmallestAngle = M_PI;
     766        BTS = baseline->second->triangles.begin()->second; // there is only one triangle so far
     767        // get peak point with respect to this base line's only triangle
     768        for(int i=0;i<3;i++)
     769          if ((BTS->endpoints[i] != baseline->second->endpoints[0]) && (BTS->endpoints[i] != baseline->second->endpoints[1]))
     770            peak = BTS->endpoints[i];
     771        *out << Verbose(3) << " and has peak " << *peak << "." << endl;
     772        // normal vector of triangle
     773        BTS->GetNormalVector(NormalVector);
     774        *out << Verbose(4) << "NormalVector of base triangle is ";
     775        NormalVector.Output(out);
     776        *out << endl;
     777        // offset to center of triangle
     778        CenterVector.Zero();
     779        for(int i=0;i<3;i++)
     780          CenterVector.AddVector(&BTS->endpoints[i]->node->x);
     781        CenterVector.Scale(1./3.);
     782        *out << Verbose(4) << "CenterVector of base triangle is ";
     783        CenterVector.Output(out);
     784        *out << endl;
     785        // vector in propagation direction (out of triangle)
     786        // project center vector onto triangle plane (points from intersection plane-NormalVector to plane-CenterVector intersection)
     787        TempVector.CopyVector(&baseline->second->endpoints[0]->node->x);
     788        TempVector.SubtractVector(&baseline->second->endpoints[1]->node->x);
     789        PropagationVector.MakeNormalVector(&TempVector, &NormalVector);
     790        TempVector.CopyVector(&CenterVector);
     791        TempVector.SubtractVector(&baseline->second->endpoints[0]->node->x);  // TempVector is vector on triangle plane pointing from one baseline egde towards center!
     792        //*out << Verbose(2) << "Projection of propagation onto temp: " << PropagationVector.Projection(&TempVector) << "." << endl;
     793        if (PropagationVector.Projection(&TempVector) > 0)  // make sure normal propagation vector points outward from baseline
     794          PropagationVector.Scale(-1.);
     795        *out << Verbose(4) << "PropagationVector of base triangle is ";
     796        PropagationVector.Output(out);
     797        *out << endl;
     798        winner = PointsOnBoundary.end();
     799        for (PointMap::iterator target = PointsOnBoundary.begin(); target != PointsOnBoundary.end(); target++)
     800          if ((target->second != baseline->second->endpoints[0]) && (target->second != baseline->second->endpoints[1])) { // don't take the same endpoints
     801            *out << Verbose(3) << "Target point is " << *(target->second) << ":";
     802            bool continueflag = true;
     803           
     804            VirtualNormalVector.CopyVector(&baseline->second->endpoints[0]->node->x);
     805            VirtualNormalVector.AddVector(&baseline->second->endpoints[0]->node->x);
     806            VirtualNormalVector.Scale(-1./2.);   // points now to center of base line
     807            VirtualNormalVector.AddVector(&target->second->node->x); // points from center of base line to target
     808            TempAngle = VirtualNormalVector.Angle(&PropagationVector);
     809            continueflag = continueflag && (TempAngle < (M_PI/2.)); // no bends bigger than Pi/2 (90 degrees)
     810            if (!continueflag) {
     811              *out << Verbose(4) << "Angle between propagation direction and base line to " << *(target->second) << " is " << TempAngle << ", bad direction!" << endl;
     812              continue;
     813            } else
     814              *out << Verbose(4) << "Angle between propagation direction and base line to " << *(target->second) << " is " << TempAngle << ", good direction!" << endl;
     815            LineChecker[0] = baseline->second->endpoints[0]->lines.find(target->first);
     816            LineChecker[1] = baseline->second->endpoints[1]->lines.find(target->first);
     817  //            if (LineChecker[0] != baseline->second->endpoints[0]->lines.end())
     818  //              *out << Verbose(4) << *(baseline->second->endpoints[0]) << " has line " << *(LineChecker[0]->second) << " to " << *(target->second) << " as endpoint with " << LineChecker[0]->second->TrianglesCount << " triangles." << endl;
     819  //            else
     820  //              *out << Verbose(4) << *(baseline->second->endpoints[0]) << " has no line to " << *(target->second) << " as endpoint." << endl;
     821  //            if (LineChecker[1] != baseline->second->endpoints[1]->lines.end())
     822  //              *out << Verbose(4) << *(baseline->second->endpoints[1]) << " has line " << *(LineChecker[1]->second) << " to " << *(target->second) << " as endpoint with " << LineChecker[1]->second->TrianglesCount << " triangles." << endl;
     823  //            else
     824  //              *out << Verbose(4) << *(baseline->second->endpoints[1]) << " has no line to " << *(target->second) << " as endpoint." << endl;
     825            // check first endpoint (if any connecting line goes to target or at least not more than 1)
     826            continueflag = continueflag && (( (LineChecker[0] == baseline->second->endpoints[0]->lines.end()) || (LineChecker[0]->second->TrianglesCount == 1)));
     827            if (!continueflag) {
     828              *out << Verbose(4) << *(baseline->second->endpoints[0]) << " has line " << *(LineChecker[0]->second) << " to " << *(target->second) << " as endpoint with " << LineChecker[0]->second->TrianglesCount << " triangles." << endl;
     829              continue;
     830            }
     831            // check second endpoint (if any connecting line goes to target or at least not more than 1)
     832            continueflag = continueflag && (( (LineChecker[1] == baseline->second->endpoints[1]->lines.end()) || (LineChecker[1]->second->TrianglesCount == 1)));
     833            if (!continueflag) {
     834              *out << Verbose(4) << *(baseline->second->endpoints[1]) << " has line " << *(LineChecker[1]->second) << " to " << *(target->second) << " as endpoint with " << LineChecker[1]->second->TrianglesCount << " triangles." << endl;
     835              continue;
     836            }
     837            // check whether the envisaged triangle does not already exist (if both lines exist and have same endpoint)
     838            continueflag = continueflag && (!(
     839                ((LineChecker[0] != baseline->second->endpoints[0]->lines.end()) && (LineChecker[1] != baseline->second->endpoints[1]->lines.end())
     840                && (GetCommonEndpoint(LineChecker[0]->second, LineChecker[1]->second) == peak))
     841               ));
     842            if (!continueflag) {
     843              *out << Verbose(4) << "Current target is peak!" << endl;
     844              continue;
     845            }
     846            // in case NOT both were found
     847            if (continueflag) {  // create virtually this triangle, get its normal vector, calculate angle
     848              flag = true;
     849              VirtualNormalVector.MakeNormalVector(&baseline->second->endpoints[0]->node->x, &baseline->second->endpoints[1]->node->x, &target->second->node->x);
     850              // make it always point inward
     851              if (baseline->second->endpoints[0]->node->x.Projection(&VirtualNormalVector) > 0)
     852                VirtualNormalVector.Scale(-1.);
     853              // calculate angle
     854              TempAngle = NormalVector.Angle(&VirtualNormalVector);
     855              *out << Verbose(4) << "NormalVector is ";
     856              VirtualNormalVector.Output(out);
     857              *out << " and the angle is " << TempAngle << "." << endl;
     858              if (SmallestAngle > TempAngle) {  // set to new possible winner
     859                SmallestAngle = TempAngle;
     860                winner = target;
    1355861              }
    1356             else
    1357               {
    1358                 *out << Verbose(1)
    1359                     << "I could not determine a winner for this baseline "
    1360                     << *(baseline->second) << "." << endl;
    1361               }
    1362 
    1363             // 5d. If the set of lines is not yet empty, go to 5. and continue
     862            }
    1364863          }
    1365         else
    1366           *out << Verbose(2) << "Baseline candidate " << *(baseline->second)
    1367               << " has a triangle count of "
    1368               << baseline->second->TrianglesCount << "." << endl;
    1369     }
    1370   while (flag);
    1371 
    1372 }
    1373 ;
     864        // 5b. The point of the above whose triangle has the greatest angle with the triangle the current line belongs to (it only belongs to one, remember!): New triangle
     865        if (winner != PointsOnBoundary.end()) {
     866          *out << Verbose(2) << "Winning target point is " << *(winner->second) << " with angle " << SmallestAngle << "." << endl;
     867          // create the lins of not yet present
     868          BLS[0] = baseline->second;
     869          // 5c. add lines to the line set if those were new (not yet part of a triangle), delete lines that belong to two triangles)
     870          LineChecker[0] = baseline->second->endpoints[0]->lines.find(winner->first);
     871          LineChecker[1] = baseline->second->endpoints[1]->lines.find(winner->first);
     872          if (LineChecker[0] == baseline->second->endpoints[0]->lines.end()) { // create
     873            BPS[0] = baseline->second->endpoints[0];
     874            BPS[1] = winner->second;
     875            BLS[1] = new class BoundaryLineSet(BPS , LinesOnBoundaryCount);
     876            LinesOnBoundary.insert( LinePair(LinesOnBoundaryCount, BLS[1]) );
     877            LinesOnBoundaryCount++;
     878          } else
     879            BLS[1] = LineChecker[0]->second;
     880          if (LineChecker[1] == baseline->second->endpoints[1]->lines.end()) { // create
     881            BPS[0] = baseline->second->endpoints[1];
     882            BPS[1] = winner->second;
     883            BLS[2] = new class BoundaryLineSet(BPS, LinesOnBoundaryCount);
     884            LinesOnBoundary.insert( LinePair(LinesOnBoundaryCount, BLS[2]) );
     885            LinesOnBoundaryCount++;
     886          } else
     887            BLS[2] = LineChecker[1]->second;
     888          BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
     889          TrianglesOnBoundary.insert( TrianglePair(TrianglesOnBoundaryCount, BTS) );
     890          TrianglesOnBoundaryCount++;
     891        } else {
     892          *out << Verbose(1) << "I could not determine a winner for this baseline " << *(baseline->second) << "." << endl;
     893        }
     894 
     895        // 5d. If the set of lines is not yet empty, go to 5. and continue
     896      } else
     897        *out << Verbose(2) << "Baseline candidate " << *(baseline->second) << " has a triangle count of " << baseline->second->TrianglesCount << "." << endl;
     898  } while (flag);
     899 
     900  stringstream line;
     901  line << configuration->configpath << "/" << CONVEXENVELOPE;
     902  *out << Verbose(1) << "Storing convex envelope in tecplot data file " << line.str() << "." << endl;
     903  ofstream output(line.str().c_str());
     904  output << "TITLE = \"3D CONVEX SHELL\"" << endl;
     905  output << "VARIABLES = \"X\" \"Y\" \"Z\"" << endl;
     906  output << "ZONE T=\"TRIANGLES\", N=" << PointsOnBoundaryCount << ", E=" << TrianglesOnBoundaryCount << ", DATAPACKING=POINT, ZONETYPE=FETRIANGLE" << endl;
     907  int *LookupList = new int[mol->AtomCount];
     908  for (int i=0;i<mol->AtomCount;i++)
     909    LookupList[i] = -1;
     910 
     911  // print atom coordinates
     912  *out << Verbose(2) << "The following triangles were created:";
     913  int Counter = 1;
     914  atom *Walker = NULL;
     915  for (PointMap::iterator target = PointsOnBoundary.begin(); target != PointsOnBoundary.end(); target++) {
     916    Walker = target->second->node;
     917    LookupList[Walker->nr] = Counter++;
     918    output << Walker->x.x[0] << " " << Walker->x.x[1] << " " << Walker->x.x[2] << " " << endl;
     919  }
     920  output << endl;
     921    // print connectivity
     922  for (TriangleMap::iterator runner = TrianglesOnBoundary.begin(); runner != TrianglesOnBoundary.end(); runner++) {
     923    *out << " " << runner->second->endpoints[0]->node->Name << "<->" << runner->second->endpoints[1]->node->Name << "<->" << runner->second->endpoints[2]->node->Name;
     924    output << LookupList[runner->second->endpoints[0]->node->nr] << " " << LookupList[runner->second->endpoints[1]->node->nr] << " " << LookupList[runner->second->endpoints[2]->node->nr] << endl;
     925  }
     926  output.close();
     927  delete[](LookupList);
     928  *out << endl;
     929};
    1374930
    1375931/** Adds an atom to the tesselation::PointsOnBoundary list.
    1376932 * \param *Walker atom to add
    1377933 */
    1378 void
    1379 Tesselation::AddPoint(atom *Walker)
    1380 {
    1381   PointTestPair InsertUnique;
     934void Tesselation::AddPoint(atom *Walker)
     935{
    1382936  BPS[0] = new class BoundaryPointSet(Walker);
    1383   InsertUnique = PointsOnBoundary.insert(PointPair(Walker->nr, BPS[0]));
    1384   if (InsertUnique.second) // if new point was not present before, increase counter
    1385     PointsOnBoundaryCount++;
    1386 }
    1387 ;
    1388 
    1389 /** Adds point to Tesselation::PointsOnBoundary if not yet present.
    1390  * Tesselation::TPS is set to either this new BoundaryPointSet or to the existing one of not unique.
    1391  * @param Candidate point to add
    1392  * @param n index for this point in Tesselation::TPS array
    1393  */
    1394 void
    1395 Tesselation::AddTrianglePoint(atom* Candidate, int n)
    1396 {
    1397   PointTestPair InsertUnique;
    1398   TPS[n] = new class BoundaryPointSet(Candidate);
    1399   InsertUnique = PointsOnBoundary.insert(PointPair(Candidate->nr, TPS[n]));
    1400   if (InsertUnique.second) // if new point was not present before, increase counter
    1401     {
    1402       PointsOnBoundaryCount++;
    1403     }
    1404   else
    1405     {
    1406       delete TPS[n];
    1407       cout << Verbose(2) << "Atom " << *((InsertUnique.first)->second->node)
    1408           << " gibt's schon in der PointMap." << endl;
    1409       TPS[n] = (InsertUnique.first)->second;
    1410     }
    1411 }
    1412 ;
    1413 
    1414 /** Function tries to add line from current Points in BPS to BoundaryLineSet.
    1415  * If succesful it raises the line count and inserts the new line into the BLS,
    1416  * if unsuccesful, it writes the line which had been present into the BLS, deleting the new constructed one.
    1417  * @param *a first endpoint
    1418  * @param *b second endpoint
    1419  * @param n index of Tesselation::BLS giving the line with both endpoints
    1420  */
    1421 void
    1422 Tesselation::AddTriangleLine(class BoundaryPointSet *a,
    1423     class BoundaryPointSet *b, int n)
    1424 {
    1425   LineMap::iterator LineWalker;
    1426   //cout << "Manually checking endpoints for line." << endl;
    1427   if ((a->lines.find(b->node->nr)) != a->lines.end()) // ->first == b->node->nr)
    1428   //If a line is there, how do I recognize that beyond a shadow of a doubt?
    1429     {
    1430       //cout << Verbose(2) << "Line exists already, retrieving it from LinesOnBoundarySet" << endl;
    1431 
    1432       LineWalker = LinesOnBoundary.end();
    1433       LineWalker--;
    1434 
    1435       while (LineWalker->second->endpoints[0]->node->nr != min(a->node->nr,
    1436           b->node->nr) or LineWalker->second->endpoints[1]->node->nr != max(
    1437           a->node->nr, b->node->nr))
    1438         {
    1439           //cout << Verbose(1) << "Looking for line which already exists"<< endl;
    1440           LineWalker--;
    1441         }
    1442       BPS[0] = LineWalker->second->endpoints[0];
    1443       BPS[1] = LineWalker->second->endpoints[1];
    1444       BLS[n] = LineWalker->second;
    1445 
    1446     }
    1447   else
    1448     {
    1449       cout << Verbose(2)
    1450           << "Adding line which has not been used before between "
    1451           << *(a->node) << " and " << *(b->node) << "." << endl;
    1452       BPS[0] = a;
    1453       BPS[1] = b;
    1454       BLS[n] = new class BoundaryLineSet(BPS, LinesOnBoundaryCount);
    1455 
    1456       LinesOnBoundary.insert(LinePair(LinesOnBoundaryCount, BLS[n]));
    1457       LinesOnBoundaryCount++;
    1458 
    1459     }
    1460 }
    1461 ;
    1462 
    1463 /** Function tries to add Triangle just created to Triangle and remarks if already existent (Failure of algorithm).
    1464  * Furthermore it adds the triangle to all of its lines, in order to recognize those which are saturated later.
    1465  */
    1466 void
    1467 Tesselation::AddTriangleToLines()
    1468 {
    1469 
    1470   cout << Verbose(1) << "Adding triangle to its lines" << endl;
    1471   TrianglesOnBoundary.insert(TrianglePair(TrianglesOnBoundaryCount, BTS));
    1472   TrianglesOnBoundaryCount++;
    1473 
    1474   /*
    1475    * this is apparently done when constructing triangle
    1476 
    1477    for (int i=0; i<3; i++)
    1478    {
    1479    BLS[i]->AddTriangle(BTS);
    1480    }
    1481    */
    1482 }
    1483 ;
    1484 
    1485 /**
    1486  * Function returns center of sphere with RADIUS, which rests on points a, b, c
    1487  * @param Center this vector will be used for return
    1488  * @param a vector first point of triangle
    1489  * @param b vector second point of triangle
    1490  * @param c vector third point of triangle
    1491  * @param *Umkreismittelpunkt new cneter point of circumference
    1492  * @param Direction vector indicates up/down
    1493  * @param AlternativeDirection vecotr, needed in case the triangles have 90 deg angle
    1494  * @param Halfplaneindicator double indicates whether Direction is up or down
    1495  * @param AlternativeIndicator doube indicates in case of orthogonal triangles which direction of AlternativeDirection is suitable
    1496  * @param alpha double angle at a
    1497  * @param beta double, angle at b
    1498  * @param gamma, double, angle at c
    1499  * @param Radius, double
    1500  * @param Umkreisradius double radius of circumscribing circle
    1501  */
    1502 
    1503   void Get_center_of_sphere(Vector* Center, Vector a, Vector b, Vector c, Vector *NewUmkreismittelpunkt, Vector* Direction, Vector* AlternativeDirection,
    1504       double HalfplaneIndicator, double AlternativeIndicator, double alpha, double beta, double gamma, double RADIUS, double Umkreisradius)
    1505   {
    1506     Vector TempNormal, helper;
    1507     double Restradius;
    1508     cout << Verbose(3) << "Begin of Get_center_of_sphere.\n";
    1509     Center->Zero();
    1510     helper.CopyVector(&a);
    1511     helper.Scale(sin(2.*alpha));
    1512     Center->AddVector(&helper);
    1513     helper.CopyVector(&b);
    1514     helper.Scale(sin(2.*beta));
    1515     Center->AddVector(&helper);
    1516     helper.CopyVector(&c);
    1517     helper.Scale(sin(2.*gamma));
    1518     Center->AddVector(&helper);
    1519     //*Center = a * sin(2.*alpha) + b * sin(2.*beta) + c * sin(2.*gamma) ;
    1520     Center->Scale(1./(sin(2.*alpha) + sin(2.*beta) + sin(2.*gamma)));
    1521     NewUmkreismittelpunkt->CopyVector(Center);
    1522     cout << Verbose(4) << "Center of new circumference is " << *NewUmkreismittelpunkt << ".\n";
    1523     // Here we calculated center of circumscribing circle, using barycentric coordinates
    1524     cout << Verbose(4) << "Center of circumference is " << *Center << " in direction " << *Direction << ".\n";
    1525 
    1526     TempNormal.CopyVector(&a);
    1527     TempNormal.SubtractVector(&b);
    1528     helper.CopyVector(&a);
    1529     helper.SubtractVector(&c);
    1530     TempNormal.VectorProduct(&helper);
    1531     if (fabs(HalfplaneIndicator) < MYEPSILON)
    1532       {
    1533         if ((TempNormal.ScalarProduct(AlternativeDirection) <0 and AlternativeIndicator >0) or (TempNormal.ScalarProduct(AlternativeDirection) >0 and AlternativeIndicator <0))
    1534           {
    1535             TempNormal.Scale(-1);
    1536           }
    1537       }
    1538     else
    1539       {
    1540         if (TempNormal.ScalarProduct(Direction)<0 && HalfplaneIndicator >0 || TempNormal.ScalarProduct(Direction)>0 && HalfplaneIndicator<0)
    1541           {
    1542             TempNormal.Scale(-1);
    1543           }
    1544       }
    1545 
    1546     TempNormal.Normalize();
    1547     Restradius = sqrt(RADIUS*RADIUS - Umkreisradius*Umkreisradius);
    1548     cout << Verbose(4) << "Height of center of circumference to center of sphere is " << Restradius << ".\n";
    1549     TempNormal.Scale(Restradius);
    1550     cout << Verbose(4) << "Shift vector to sphere of circumference is " << TempNormal << ".\n";
    1551 
    1552     Center->AddVector(&TempNormal);
    1553     cout << Verbose(4) << "Center of sphere of circumference is " << *Center << ".\n";
    1554     cout << Verbose(3) << "End of Get_center_of_sphere.\n";
    1555   }
    1556   ;
    1557 
    1558 
    1559 /** This recursive function finds a third point, to form a triangle with two given ones.
    1560  * Two atoms are fixed, a candidate is supplied, additionally two vectors for direction distinction, a Storage area to \
    1561  *  supply results to the calling function, the radius of the sphere which the triangle shall support and the molecule \
    1562  *  upon which we operate.
    1563  *  If the candidate is more fitting to support the sphere than the already stored atom is, then we write its general \
    1564  *  direction and angle into Storage.
    1565  *  We the determine the recursive level we have reached and if this is not on the threshold yet, call this function again, \
    1566  *  with all neighbours of the candidate.
    1567  * @param a first point
    1568  * @param b second point
    1569  * *param c atom old third point of old triangle
    1570  * @param Candidate base point along whose bonds to start looking from
    1571  * @param Parent point to avoid during search as its wrong direction
    1572  * @param RecursionLevel contains current recursion depth
    1573  * @param Chord baseline vector of first and second point
    1574  * @param direction1 second in plane vector (along with \a Chord) of the triangle the baseline belongs to
    1575  * @param OldNormal normal of the triangle which the baseline belongs to
    1576  * @param ReferencePoint Vector of center of circumscribing circle from which we look towards center of sphere
    1577  * @param Opt_Candidate candidate reference to return
    1578  * @param Storage array containing two angles of current Opt_Candidate
    1579  * @param RADIUS radius of ball
    1580  * @param mol molecule structure with atoms and bonds
    1581  */
    1582 
    1583 void Tesselation::Find_next_suitable_point_via_Angle_of_Sphere(atom* a, atom* b, atom* c, atom* Candidate, atom* Parent,
    1584     int RecursionLevel, Vector *Chord, Vector *direction1, Vector *OldNormal, Vector ReferencePoint,
    1585     atom*& Opt_Candidate, double *Storage, const double RADIUS, molecule* mol)
    1586 {
    1587         cout << Verbose(2) << "Begin of Find_next_suitable_point_via_Angle_of_Sphere, recursion level " << RecursionLevel << ".\n";
    1588         cout << Verbose(3) << "Candidate is "<< *Candidate << endl;
    1589         cout << Verbose(4) << "Baseline vector is " << *Chord << "." << endl;
    1590         cout << Verbose(4) << "ReferencePoint is " << ReferencePoint << "." << endl;
    1591         cout << Verbose(4) << "Normal of base triangle is " << *OldNormal << "." << endl;
    1592         cout << Verbose(4) << "Search direction is " << *direction1 << "." << endl;
    1593         /* OldNormal is normal vector on the old triangle
    1594          * direction1 is normal on the triangle line, from which we come, as well as on OldNormal.
    1595          * Chord points from b to a!!!
    1596          */
    1597         Vector dif_a; //Vector from a to candidate
    1598         Vector dif_b; //Vector from b to candidate
    1599         Vector AngleCheck;
    1600         Vector TempNormal, Umkreismittelpunkt;
    1601         Vector Mittelpunkt;
    1602 
    1603         double alpha, beta, gamma, SideA, SideB, SideC, sign, Umkreisradius;
    1604         double BallAngle, AlternativeSign;
    1605         atom *Walker; // variable atom point
    1606 
    1607         Vector NewUmkreismittelpunkt;
    1608 
    1609         if (a != Candidate and b != Candidate and c != Candidate) {
    1610                 cout << Verbose(3) << "We have a unique candidate!" << endl;
    1611                 dif_a.CopyVector(&(a->x));
    1612                 dif_a.SubtractVector(&(Candidate->x));
    1613                 dif_b.CopyVector(&(b->x));
    1614                 dif_b.SubtractVector(&(Candidate->x));
    1615                 AngleCheck.CopyVector(&(Candidate->x));
    1616                 AngleCheck.SubtractVector(&(a->x));
    1617                 AngleCheck.ProjectOntoPlane(Chord);
    1618 
    1619                 SideA = dif_b.Norm();
    1620                 SideB = dif_a.Norm();
    1621                 SideC = Chord->Norm();
    1622                 //Chord->Scale(-1);
    1623 
    1624                 alpha = Chord->Angle(&dif_a);
    1625                 beta = M_PI - Chord->Angle(&dif_b);
    1626                 gamma = dif_a.Angle(&dif_b);
    1627 
    1628                 cout << Verbose(2) << "Base triangle has sides " << dif_a << ", " << dif_b << ", " << *Chord << " with angles " << alpha/M_PI*180. << ", " << beta/M_PI*180. << ", " << gamma/M_PI*180. << "." << endl;
    1629 
    1630                 if (fabs(M_PI - alpha - beta - gamma) > MYEPSILON) {
    1631                         cerr << Verbose(0) << "WARNING: sum of angles for base triangle " << (alpha + beta + gamma)/M_PI*180. << " != 180.\n";
    1632                         cout << Verbose(1) << "Base triangle has sides " << dif_a << ", " << dif_b << ", " << *Chord << " with angles " << alpha/M_PI*180. << ", " << beta/M_PI*180. << ", " << gamma/M_PI*180. << "." << endl;
    1633                 }
    1634 
    1635                 if ((M_PI*4. > alpha*5.) && (M_PI*4. > beta*5.) && (M_PI*4 > gamma*5.)) {
    1636                         Umkreisradius = SideA / 2.0 / sin(alpha);
    1637                         //cout << Umkreisradius << endl;
    1638                         //cout << SideB / 2.0 / sin(beta) << endl;
    1639                         //cout << SideC / 2.0 / sin(gamma) << endl;
    1640 
    1641                         if (Umkreisradius < RADIUS) { //Checking whether ball will at least rest on points.
    1642                                 cout << Verbose(3) << "Circle of circumference would fit: " << Umkreisradius << " < " << RADIUS << "." << endl;
    1643                                 cout << Verbose(2) << "Candidate is "<< *Candidate << endl;
    1644                                 sign = AngleCheck.ScalarProduct(direction1);
    1645                                 if (fabs(sign)<MYEPSILON) {
    1646                                         if (AngleCheck.ScalarProduct(OldNormal)<0) {
    1647                                                 sign =0;
    1648                                                 AlternativeSign=1;
    1649                                         } else {
    1650                                                 sign =0;
    1651                                                 AlternativeSign=-1;
    1652                                         }
    1653                                 } else {
    1654                                         sign /= fabs(sign);
    1655                                         cout << Verbose(3) << "Candidate is in search direction: " << sign << "." << endl;
    1656                                 }
    1657 
    1658                                 Get_center_of_sphere(&Mittelpunkt, (a->x), (b->x), (Candidate->x), &NewUmkreismittelpunkt, OldNormal, direction1, sign, AlternativeSign, alpha, beta, gamma, RADIUS, Umkreisradius);
    1659 
    1660                                 AngleCheck.CopyVector(&ReferencePoint);
    1661                                 AngleCheck.Scale(-1);
    1662                                 //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl;
    1663                                 AngleCheck.AddVector(&Mittelpunkt);
    1664                                 //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl;
    1665                                 cout << Verbose(4) << "Reference vector to sphere's center is " << AngleCheck << "." << endl;
    1666 
    1667                                 BallAngle = AngleCheck.Angle(OldNormal);
    1668                                 cout << Verbose(3) << "Angle between normal of base triangle and center of ball sphere is :" << BallAngle << "." << endl;
    1669 
    1670                                 //cout << "direction1 is " << direction1->x[0] <<" "<< direction1->x[1] <<" "<< direction1->x[2] <<" " << endl;
    1671                                 //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl;
    1672 
    1673                                 cout << Verbose(3) << "BallAngle is " << BallAngle << " Sign is " << sign << endl;
    1674 
    1675                                 NewUmkreismittelpunkt.SubtractVector(&ReferencePoint);
    1676 
    1677                                 if ((AngleCheck.ScalarProduct(direction1) >=0) || (fabs(NewUmkreismittelpunkt.Norm()) < MYEPSILON)) {
    1678                                         if (Storage[0]< -1.5) { // first Candidate at all
    1679                                                 if (1) {//if (CheckPresenceOfTriangle((ofstream *)&cout,a,b,Candidate)) {
    1680                                                         cout << Verbose(2) << "First good candidate is " << *Candidate << " with ";
    1681                                                         Opt_Candidate = Candidate;
    1682                                                         Storage[0] = sign;
    1683                                                         Storage[1] = AlternativeSign;
    1684                                                         Storage[2] = BallAngle;
    1685                                                         cout << " angle " << Storage[2] << " and Up/Down "
    1686                                                         << Storage[0] << endl;
    1687                                                 } else
    1688                                                         cout << "Candidate " << *Candidate << " does not belong to a valid triangle." << endl;
    1689                                         } else {
    1690                                                 if ( Storage[2] > BallAngle) {
    1691                                                         if (1) { //if (CheckPresenceOfTriangle((ofstream *)&cout,a,b,Candidate)) {
    1692                                                                 cout << Verbose(2) << "Next better candidate is " << *Candidate << " with ";
    1693                                                                 Opt_Candidate = Candidate;
    1694                                                                 Storage[0] = sign;
    1695                                                                 Storage[1] = AlternativeSign;
    1696                                                                 Storage[2] = BallAngle;
    1697                                                                 cout << " angle " << Storage[2] << " and Up/Down "
    1698                                                                 << Storage[0] << endl;
    1699                                                         } else
    1700                                                                 cout << "Candidate " << *Candidate << " does not belong to a valid triangle." << endl;
    1701                                                 } else {
    1702                                                         if (DEBUG) {
    1703                                                                 cout << Verbose(3) << *Candidate << " looses against better candidate " << *Opt_Candidate << "." << endl;
    1704                                                         }
    1705                                                 }
    1706                                         }
    1707                                 } else {
    1708                                         if (DEBUG) {
    1709                                                 cout << Verbose(3) << *Candidate << " refused due to Up/Down sign which is " << sign << endl;
    1710                                         }
    1711                                 }
    1712                         } else {
    1713                                 if (DEBUG) {
    1714                                         cout << Verbose(3) << *Candidate << " would have circumference of " << Umkreisradius << " bigger than ball's radius " << RADIUS << "." << endl;
    1715                                 }
    1716                         }
    1717                 } else {
    1718                         if (DEBUG) {
    1719                                 cout << Verbose(0) << "Triangle consisting of " << *Candidate << ", " << *a << " and " << *b << " has an angle >150!" << endl;
    1720                         }
    1721                 }
    1722         } else {
    1723                 if (DEBUG) {
    1724                         cout << Verbose(3) << *Candidate << " is either " << *a << " or " << *b << "." << endl;
    1725                 }
    1726         }
    1727 
    1728         if (RecursionLevel < 5) { // Seven is the recursion level threshold.
    1729                 for (int i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) { // go through all bond
    1730                         Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(Candidate);
    1731                         if (Walker == Parent) { // don't go back the same bond
    1732                                 continue;
    1733                         } else {
    1734                                 Find_next_suitable_point_via_Angle_of_Sphere(a, b, c, Walker, Candidate, RecursionLevel+1, Chord, direction1, OldNormal, ReferencePoint, Opt_Candidate, Storage, RADIUS, mol); //call function again
    1735                         }
    1736                 }
    1737         }
    1738         cout << Verbose(2) << "End of Find_next_suitable_point_via_Angle_of_Sphere, recursion level " << RecursionLevel << ".\n";
    1739 }
    1740 ;
    1741 
    1742 
    1743   /** This recursive function finds a third point, to form a triangle with two given ones.
    1744    * Two atoms are fixed, a candidate is supplied, additionally two vectors for direction distinction, a Storage area to \
    1745    *  supply results to the calling function, the radius of the sphere which the triangle shall support and the molecule \
    1746    *  upon which we operate.
    1747    *  If the candidate is more fitting to support the sphere than the already stored atom is, then we write its general \
    1748    *  direction and angle into Storage.
    1749    *  We the determine the recursive level we have reached and if this is not on the threshold yet, call this function again, \
    1750    *  with all neighbours of the candidate.
    1751    * @param a first point
    1752    * @param b second point
    1753    * @param Candidate base point along whose bonds to start looking from
    1754    * @param Parent point to avoid during search as its wrong direction
    1755    * @param RecursionLevel contains current recursion depth
    1756    * @param Chord baseline vector of first and second point
    1757    * @param d1 second in plane vector (along with \a Chord) of the triangle the baseline belongs to
    1758    * @param OldNormal normal of the triangle which the baseline belongs to
    1759    * @param Opt_Candidate candidate reference to return
    1760    * @param Opt_Mittelpunkt Centerpoint of ball, when resting on Opt_Candidate
    1761    * @param Storage array containing two angles of current Opt_Candidate
    1762    * @param RADIUS radius of ball
    1763    * @param mol molecule structure with atoms and bonds
    1764    */
    1765 void Find_next_suitable_point(atom* a, atom* b, atom* Candidate, atom* Parent,
    1766     int RecursionLevel, Vector *Chord, Vector *d1, Vector *OldNormal,
    1767     atom*& Opt_Candidate, Vector *Opt_Mittelpunkt, double *Storage, const double RADIUS, molecule* mol)
    1768 {
    1769         /* OldNormal is normal vector on the old triangle
    1770          * d1 is normal on the triangle line, from which we come, as well as on OldNormal.
    1771          * Chord points from b to a!!!
    1772          */
    1773         Vector dif_a; //Vector from a to candidate
    1774         Vector dif_b; //Vector from b to candidate
    1775         Vector AngleCheck, AngleCheckReference, DirectionCheckPoint;
    1776         Vector TempNormal, Umkreismittelpunkt, Mittelpunkt, helper;
    1777 
    1778         double CurrentEpsilon = 0.1;
    1779         double alpha, beta, gamma, SideA, SideB, SideC, sign, Umkreisradius, Restradius;
    1780         double BallAngle;
    1781         atom *Walker; // variable atom point
    1782 
    1783 
    1784         dif_a.CopyVector(&(a->x));
    1785         dif_a.SubtractVector(&(Candidate->x));
    1786         dif_b.CopyVector(&(b->x));
    1787         dif_b.SubtractVector(&(Candidate->x));
    1788         DirectionCheckPoint.CopyVector(&dif_a);
    1789         DirectionCheckPoint.Scale(-1);
    1790         DirectionCheckPoint.ProjectOntoPlane(Chord);
    1791 
    1792         SideA = dif_b.Norm();
    1793         SideB = dif_a.Norm();
    1794         SideC = Chord->Norm();
    1795         //Chord->Scale(-1);
    1796 
    1797         alpha = Chord->Angle(&dif_a);
    1798         beta = M_PI - Chord->Angle(&dif_b);
    1799         gamma = dif_a.Angle(&dif_b);
    1800 
    1801 
    1802         if (DEBUG) {
    1803                 cout << "Atom number" << Candidate->nr << endl;
    1804                 Candidate->x.Output((ofstream *) &cout);
    1805                 cout << "number of bonds " << mol->NumberOfBondsPerAtom[Candidate->nr] << endl;
    1806         }
    1807 
    1808         if (a != Candidate and b != Candidate) {
    1809                 //      alpha = dif_a.Angle(&dif_b) / 2.;
    1810                 //      SideA = Chord->Norm() / 2.;// (Chord->Norm()/2.) / sin(0.5*alpha);
    1811                 //      SideB = dif_a.Norm();
    1812                 //      centerline = SideA * SideA + SideB * SideB - 2. * SideA * SideB * cos(
    1813                 //          alpha); // note this is squared of center line length
    1814                 //      centerline = (Chord->Norm()/2.) / sin(0.5*alpha);
    1815                 // Those are remains from Freddie. Needed?
    1816 
    1817                 Umkreisradius = SideA / 2.0 / sin(alpha);
    1818                 //cout << Umkreisradius << endl;
    1819                 //cout << SideB / 2.0 / sin(beta) << endl;
    1820                 //cout << SideC / 2.0 / sin(gamma) << endl;
    1821 
    1822                 if (Umkreisradius < RADIUS && DirectionCheckPoint.ScalarProduct(&(Candidate->x))>0) { //Checking whether ball will at least rest o points.
    1823                         // intermediate calculations to aquire centre of sphere, called Mittelpunkt:
    1824                         Umkreismittelpunkt.Zero();
    1825                         helper.CopyVector(&a->x);
    1826                         helper.Scale(sin(2.*alpha));
    1827                         Umkreismittelpunkt.AddVector(&helper);
    1828                         helper.CopyVector(&b->x);
    1829                         helper.Scale(sin(2.*beta));
    1830                         Umkreismittelpunkt.AddVector(&helper);
    1831                         helper.CopyVector(&Candidate->x);
    1832                         helper.Scale(sin(2.*gamma));
    1833                         Umkreismittelpunkt.AddVector(&helper);
    1834                         //Umkreismittelpunkt = (a->x) * sin(2.*alpha) + b->x * sin(2.*beta) + (Candidate->x) * sin(2.*gamma) ;
    1835                         Umkreismittelpunkt.Scale(1/(sin(2*alpha) + sin(2*beta) + sin(2*gamma)));
    1836 
    1837                         TempNormal.CopyVector(&dif_a);
    1838                         TempNormal.VectorProduct(&dif_b);
    1839                         if (TempNormal.ScalarProduct(OldNormal)<0 && sign>0 || TempNormal.ScalarProduct(OldNormal)>0 && sign<0) {
    1840                                 TempNormal.Scale(-1);
    1841                         }
    1842                         TempNormal.Normalize();
    1843                         Restradius = sqrt(RADIUS*RADIUS - Umkreisradius*Umkreisradius);
    1844                         TempNormal.Scale(Restradius);
    1845 
    1846                         Mittelpunkt.CopyVector(&Umkreismittelpunkt);
    1847                         Mittelpunkt.AddVector(&TempNormal);  //this is center of sphere supported by a, b and Candidate
    1848 
    1849                         AngleCheck.CopyVector(Chord);
    1850                         AngleCheck.Scale(-0.5);
    1851                         AngleCheck.SubtractVector(&(b->x));
    1852                         AngleCheckReference.CopyVector(&AngleCheck);
    1853                         AngleCheckReference.AddVector(Opt_Mittelpunkt);
    1854                         AngleCheck.AddVector(&Mittelpunkt);
    1855 
    1856                         BallAngle = AngleCheck.Angle(&AngleCheckReference);
    1857 
    1858                         d1->ProjectOntoPlane(&AngleCheckReference);
    1859                         sign = AngleCheck.ScalarProduct(d1);
    1860                         if (fabs(sign) < MYEPSILON)
    1861                                 sign = 0;
    1862                         else
    1863                                 sign /= fabs(sign); // +1 if in direction of triangle plane, -1 if in other direction...
    1864 
    1865 
    1866                         if (Storage[0]< -1.5) { // first Candidate at all
    1867                                 cout << "Next better candidate is " << *Candidate << " with ";
    1868                                 Opt_Candidate = Candidate;
    1869                                 Storage[0] = sign;
    1870                                 Storage[1] = BallAngle;
    1871                                 Opt_Mittelpunkt->CopyVector(&Mittelpunkt);
    1872                                 cout << "Angle is " << Storage[1] << ", Halbraum ist " << Storage[0] << endl;
    1873                         } else {
    1874                                 /*
    1875                                  * removed due to change in criterium, now checking angle of ball to old normal.
    1876                                 //We will now check for non interference, that is if the new candidate would have the Opt_Candidate
    1877                                 //within the ball.
    1878 
    1879                                 Distance = Opt_Candidate->x.Distance(&Mittelpunkt);
    1880                                 //cout << "Opt_Candidate " << Opt_Candidate << " has distance " << Distance << " to Center of Candidate " << endl;
    1881 
    1882 
    1883                                 if (Distance >RADIUS) { // We have no interference and may now check whether the new point is better.
    1884                                  */
    1885                                         //cout << "Atom " << Candidate << " has distance " << Candidate->x.Distance(Opt_Mittelpunkt) << " to Center of Candidate " << endl;
    1886 
    1887                                 if (((Storage[0] < 0 && fabs(sign - Storage[0]) > CurrentEpsilon))) { //This will give absolute preference to those in "right-hand" quadrants
    1888                                         //(Candidate->x.Distance(Opt_Mittelpunkt) < RADIUS))    //and those where Candidate would be within old Sphere.
    1889                                         cout << "Next better candidate is " << *Candidate << " with ";
    1890                                         Opt_Candidate = Candidate;
    1891                                         Storage[0] = sign;
    1892                                         Storage[1] = BallAngle;
    1893                                         Opt_Mittelpunkt->CopyVector(&Mittelpunkt);
    1894                                         cout << "Angle is " << Storage[1] << ", Halbraum ist " << Storage[0] << endl;
    1895                                 } else {
    1896                                         if ((fabs(sign - Storage[0]) < CurrentEpsilon && sign > 0 && Storage[1] > BallAngle) || (fabs(sign - Storage[0]) < CurrentEpsilon && sign < 0 && Storage[1] < BallAngle)) {
    1897                                                 //Depending on quadrant we prefer higher or lower atom with respect to Triangle normal first.
    1898                                                 cout << "Next better candidate is " << *Candidate << " with ";
    1899                                                 Opt_Candidate = Candidate;
    1900                                                 Storage[0] = sign;
    1901                                                 Storage[1] = BallAngle;
    1902                                                 Opt_Mittelpunkt->CopyVector(&Mittelpunkt);
    1903                                                 cout << "Angle is " << Storage[1] << ", Halbraum ist " << Storage[0] << endl;
    1904                                         }
    1905                                 }
    1906                         }
    1907 /*
    1908                * This is for checking point-angle and presence of Candidates in Ball, currently we are checking the ball Angle.
    1909                *
    1910                 else
    1911                 {
    1912                   if (sign>0 && BallAngle>0 && Storage[0]<0)
    1913                     {
    1914                       cout << "Next better candidate is " << *Candidate << " with ";
    1915                       Opt_Candidate = Candidate;
    1916                       Storage[0] = sign;
    1917                       Storage[1] = BallAngle;
    1918                       Opt_Mittelpunkt->CopyVector(&Mittelpunkt);
    1919                       cout << "Angle is " << Storage[1] << ", Halbraum ist "
    1920                       << Storage[0] << endl;
    1921 
    1922 //Debugging purposes only
    1923                       cout << "Umkreismittelpunkt has coordinates" << Umkreismittelpunkt.x[0] << " "<< Umkreismittelpunkt.x[1] <<" "<<Umkreismittelpunkt.x[2] << endl;
    1924                       cout << "Candidate has coordinates" << Candidate->x.x[0]<< " " << Candidate->x.x[1] << " " << Candidate->x.x[2] << endl;
    1925                       cout << "a has coordinates" << a->x.x[0]<< " " << a->x.x[1] << " " << a->x.x[2] << endl;
    1926                       cout << "b has coordinates" << b->x.x[0]<< " " << b->x.x[1] << " " << b->x.x[2] << endl;
    1927                       cout << "Mittelpunkt has coordinates" << Mittelpunkt.x[0] << " " << Mittelpunkt.x[1]<< " "  <<Mittelpunkt.x[2] << endl;
    1928                       cout << "Umkreisradius ist " << Umkreisradius << endl;
    1929                       cout << "Restradius ist " << Restradius << endl;
    1930                       cout << "TempNormal has coordinates " << TempNormal.x[0] << " " << TempNormal.x[1] << " " << TempNormal.x[2] << " " << endl;
    1931                       cout << "OldNormal has coordinates " << OldNormal->x[0] << " " << OldNormal->x[1] << " " << OldNormal->x[2] << " " << endl;
    1932                       cout << "Dist a to UmkreisMittelpunkt " << a->x.Distance(&Umkreismittelpunkt) << endl;
    1933                       cout << "Dist b to UmkreisMittelpunkt " << b->x.Distance(&Umkreismittelpunkt) << endl;
    1934                       cout << "Dist Candidate to UmkreisMittelpunkt " << Candidate->x.Distance(&Umkreismittelpunkt) << endl;
    1935                       cout << "Dist a to Mittelpunkt " << a->x.Distance(&Mittelpunkt) << endl;
    1936                       cout << "Dist b to Mittelpunkt " << b->x.Distance(&Mittelpunkt) << endl;
    1937                       cout << "Dist Candidate to Mittelpunkt " << Candidate->x.Distance(&Mittelpunkt) << endl;
    1938 
    1939 
    1940 
    1941                     }
    1942                   else
    1943                     {
    1944                       if (DEBUG)
    1945                         cout << "Looses to better candidate" << endl;
    1946                     }
    1947                 }
    1948                 */
    1949                 } else {
    1950                         if (DEBUG) {
    1951                                 cout << "Doesn't satisfy requirements for circumscribing circle" << endl;
    1952                         }
    1953                 }
    1954         } else {
    1955                 if (DEBUG) {
    1956                         cout << "identisch mit Ursprungslinie" << endl;
    1957                 }
    1958         }
    1959 
    1960         if (RecursionLevel < 9) { // Five is the recursion level threshold.
    1961                 for (int i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) { // go through all bond
    1962                         Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(Candidate);
    1963                         if (Walker == Parent) { // don't go back the same bond
    1964                                 continue;
    1965                         } else {
    1966                                 Find_next_suitable_point(a, b, Walker, Candidate, RecursionLevel+1, Chord, d1, OldNormal, Opt_Candidate, Opt_Mittelpunkt, Storage, RADIUS, mol); //call function again
    1967                         }
    1968                 }
    1969         }
    1970 };
    1971 
    1972 /** This function finds a triangle to a line, adjacent to an existing one.
    1973  * @param out   output stream for debugging
    1974  * @param tecplot output stream for writing found triangles in TecPlot format
    1975  * @param mol molecule structure with all atoms and bonds
    1976  * @param Line current baseline to search from
    1977  * @param T current triangle which \a Line is edge of
    1978  * @param RADIUS radius of the rolling ball
    1979  * @param N number of found triangles
    1980  * @param *filename filename base for intermediate envelopes
    1981  */
    1982 bool Tesselation::Find_next_suitable_triangle(ofstream *out, ofstream *tecplot,
    1983     molecule* mol, BoundaryLineSet &Line, BoundaryTriangleSet &T,
    1984     const double& RADIUS, int N, const char *tempbasename)
    1985 {
    1986         cout << Verbose(1) << "Begin of Find_next_suitable_triangle\n";
    1987         Vector direction1;
    1988         Vector helper;
    1989         Vector Chord;
    1990         ofstream *tempstream = NULL;
    1991         char NumberName[255];
    1992         double tmp;
    1993         //atom* Walker;
    1994         atom* OldThirdPoint;
    1995 
    1996         double Storage[3];
    1997         Storage[0] = -2.; // This direction is either +1 or -1 one, so any result will take precedence over initial values
    1998         Storage[1] = -2.; // This is also lower then any value produced by an eligible atom, which are all positive
    1999         Storage[2] = 9999999.;
    2000         atom* Opt_Candidate = NULL;
    2001         Vector Opt_Mittelpunkt;
    2002 
    2003         cout << Verbose(1) << "Current baseline is " << Line << " of triangle " << T << "." << endl;
    2004 
    2005         helper.CopyVector(&(Line.endpoints[0]->node->x));
    2006         for (int i = 0; i < 3; i++) {
    2007                 if (T.endpoints[i]->node->nr != Line.endpoints[0]->node->nr && T.endpoints[i]->node->nr != Line.endpoints[1]->node->nr) {
    2008                         OldThirdPoint = T.endpoints[i]->node;
    2009                         helper.SubtractVector(&T.endpoints[i]->node->x);
    2010                         break;
    2011                 }
    2012         }
    2013 
    2014         direction1.CopyVector(&Line.endpoints[0]->node->x);
    2015         direction1.SubtractVector(&Line.endpoints[1]->node->x);
    2016         direction1.VectorProduct(&(T.NormalVector));
    2017 
    2018         if (direction1.ScalarProduct(&helper) < 0) {
    2019                 direction1.Scale(-1);
    2020         }
    2021         cout << Verbose(2) << "Looking in direction " << direction1 << " for candidates.\n";
    2022 
    2023         Chord.CopyVector(&(Line.endpoints[0]->node->x)); // bring into calling function
    2024         Chord.SubtractVector(&(Line.endpoints[1]->node->x));
    2025         cout << Verbose(2) << "Baseline vector is " << Chord << ".\n";
    2026 
    2027 
    2028         Vector Umkreismittelpunkt, a, b, c;
    2029         double alpha, beta, gamma;
    2030         a.CopyVector(&(T.endpoints[0]->node->x));
    2031         b.CopyVector(&(T.endpoints[1]->node->x));
    2032         c.CopyVector(&(T.endpoints[2]->node->x));
    2033         a.SubtractVector(&(T.endpoints[1]->node->x));
    2034         b.SubtractVector(&(T.endpoints[2]->node->x));
    2035         c.SubtractVector(&(T.endpoints[0]->node->x));
    2036 
    2037         alpha = M_PI - a.Angle(&c);
    2038         beta = M_PI - b.Angle(&a);
    2039         gamma = M_PI - c.Angle(&b);
    2040         if (fabs(M_PI - alpha - beta - gamma) > MYEPSILON)
    2041                 cerr << Verbose(0) << "WARNING: sum of angles for candidate triangle " << (alpha + beta + gamma)/M_PI*180. << " != 180.\n";
    2042 
    2043         Umkreismittelpunkt.Zero();
    2044         helper.CopyVector(&T.endpoints[0]->node->x);
    2045         helper.Scale(sin(2.*alpha));
    2046         Umkreismittelpunkt.AddVector(&helper);
    2047         helper.CopyVector(&T.endpoints[1]->node->x);
    2048         helper.Scale(sin(2.*beta));
    2049         Umkreismittelpunkt.AddVector(&helper);
    2050         helper.CopyVector(&T.endpoints[2]->node->x);
    2051         helper.Scale(sin(2.*gamma));
    2052         Umkreismittelpunkt.AddVector(&helper);
    2053         //Umkreismittelpunkt = (T.endpoints[0]->node->x) * sin(2.*alpha) + T.endpoints[1]->node->x * sin(2.*beta) + (T.endpoints[2]->node->x) * sin(2.*gamma) ;
    2054         //cout << "UmkreisMittelpunkt is " << Umkreismittelpunkt.x[0] << " "<< Umkreismittelpunkt.x[1] << " "<< Umkreismittelpunkt.x[2] << " "<< endl;
    2055         Umkreismittelpunkt.Scale(1/(sin(2*alpha) + sin(2*beta) + sin(2*gamma)));
    2056         //cout << "UmkreisMittelpunkt is " << Umkreismittelpunkt.x[0] << " "<< Umkreismittelpunkt.x[1] << " "<< Umkreismittelpunkt.x[2] << " "<< endl;
    2057         cout << " We look over line " << Line << " in direction " << direction1.x[0] << " " << direction1.x[1] << " " << direction1.x[2] << " " << endl;
    2058         cout << " Old Normal is " <<  (T.NormalVector.x)[0] << " " << T.NormalVector.x[1] << " " << (T.NormalVector.x)[2] << " " << endl;
    2059 
    2060         cout << Verbose(2) << "Base triangle has sides " << a << ", " << b << ", " << c << " with angles " << alpha/M_PI*180. << ", " << beta/M_PI*180. << ", " << gamma/M_PI*180. << "." << endl;
    2061         cout << Verbose(2) << "Center of circumference is " << Umkreismittelpunkt << "." << endl;
    2062         if (DEBUG)
    2063                 cout << Verbose(3) << "Check of relative endpoints (same distance, equally spreaded): "<< endl;
    2064         tmp = 0;
    2065         for (int i=0;i<NDIM;i++) {
    2066                 helper.CopyVector(&T.endpoints[i]->node->x);
    2067                 helper.SubtractVector(&Umkreismittelpunkt);
    2068                 if (DEBUG)
    2069                         cout << Verbose(3) << "Endpoint[" << i << "]: " << helper << " with length " << helper.Norm() << "." << endl;
    2070                 if (tmp == 0) // set on first time for comparison against next ones
    2071                         tmp = helper.Norm();
    2072                 if (fabs(helper.Norm() - tmp) > MYEPSILON)
    2073                         cerr << Verbose(1) << "WARNING: center of circumference is wrong!" << endl;
    2074         }
    2075 
    2076         cout << Verbose(1) << "Looking for third point candidates for triangle ... " << endl;
    2077 
    2078         Find_next_suitable_point_via_Angle_of_Sphere(Line.endpoints[0]->node, Line.endpoints[1]->node, OldThirdPoint, Line.endpoints[0]->node, Line.endpoints[1]->node, 0, &Chord, &direction1, &(T.NormalVector), Umkreismittelpunkt, Opt_Candidate, Storage, RADIUS, mol);
    2079         Find_next_suitable_point_via_Angle_of_Sphere(Line.endpoints[0]->node, Line.endpoints[1]->node, OldThirdPoint, Line.endpoints[1]->node, Line.endpoints[0]->node, 0, &Chord, &direction1, &(T.NormalVector), Umkreismittelpunkt, Opt_Candidate, Storage, RADIUS, mol);
    2080         if (Opt_Candidate == NULL) {
    2081                 cerr << "WARNING: Could not find a suitable candidate." << endl;
    2082                 return false;
    2083         }
    2084         cout << Verbose(1) << " Optimal candidate is " << *Opt_Candidate << endl;
    2085 
    2086         // check whether all edges of the new triangle still have space for one more triangle (i.e. TriangleCount <2)
    2087         bool flag = CheckPresenceOfTriangle(out, Opt_Candidate, Line.endpoints[0]->node, Line.endpoints[1]->node);
    2088 
    2089         if (flag) { // if so, add
    2090                 AddTrianglePoint(Opt_Candidate, 0);
    2091                 AddTrianglePoint(Line.endpoints[0]->node, 1);
    2092                 AddTrianglePoint(Line.endpoints[1]->node, 2);
    2093 
    2094                 AddTriangleLine(TPS[0], TPS[1], 0);
    2095                 AddTriangleLine(TPS[0], TPS[2], 1);
    2096                 AddTriangleLine(TPS[1], TPS[2], 2);
    2097 
    2098                 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
    2099                 AddTriangleToLines();
    2100 
    2101                 BTS->GetNormalVector(BTS->NormalVector);
    2102 
    2103                 if ((BTS->NormalVector.ScalarProduct(&(T.NormalVector)) < 0 && Storage[0] > 0)  || (BTS->NormalVector.ScalarProduct(&(T.NormalVector)) > 0 && Storage[0] < 0) || (fabs(Storage[0]) < MYEPSILON && Storage[1]*BTS->NormalVector.ScalarProduct(&direction1) < 0) ) {
    2104                         BTS->NormalVector.Scale(-1);
    2105                 };
    2106                 cout << Verbose(1) << "New triangle with " << *BTS << " and normal vector " << BTS->NormalVector << " for this triangle ... " << endl;
    2107                 cout << Verbose(1) << "We have "<< TrianglesOnBoundaryCount << " for line " << Line << "." << endl;
    2108         } else { // else, yell and do nothing
    2109                 cout << Verbose(1) << "This triangle consisting of ";
    2110                 cout << *Opt_Candidate << ", ";
    2111                 cout << *Line.endpoints[0]->node << " and ";
    2112                 cout << *Line.endpoints[1]->node << " ";
    2113                 cout << "is invalid!" << endl;
    2114                 return false;
    2115         }
    2116 
    2117         if ((TrianglesOnBoundaryCount % 10) == 0) {
    2118                 sprintf(NumberName, "-%d", TriangleFilesWritten);
    2119                 if (DoTecplotOutput) {
    2120                         string NameofTempFile(tempbasename);
    2121                         NameofTempFile.append(NumberName);
    2122                         NameofTempFile.append(TecplotSuffix);
    2123                         cout << Verbose(1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n";
    2124                         tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc);
    2125                         write_tecplot_file(out, tempstream, this, mol, TriangleFilesWritten);
    2126                         tempstream->close();
    2127                         tempstream->flush();
    2128                         delete(tempstream);
    2129                 }
    2130 
    2131                 if (DoRaster3DOutput) {
    2132                         string NameofTempFile(tempbasename);
    2133                         NameofTempFile.append(NumberName);
    2134                         NameofTempFile.append(Raster3DSuffix);
    2135                         cout << Verbose(1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n";
    2136                         tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc);
    2137                         write_raster3d_file(out, tempstream, this, mol);
    2138                         tempstream->close();
    2139                         tempstream->flush();
    2140                         delete(tempstream);
    2141                 }
    2142                 if (DoTecplotOutput || DoRaster3DOutput)
    2143                         TriangleFilesWritten++;
    2144         }
    2145 
    2146         cout << Verbose(1) << "End of Find_next_suitable_triangle\n";
    2147         return true;
    2148 };
    2149 
    2150 /** Checks whether the triangle consisting of the three atoms is already present.
    2151  * Searches for the points in Tesselation::PointsOnBoundary and checks their
    2152  * lines. If any of the three edges already has two triangles attached, false is
    2153  * returned.
    2154  * \param *out output stream for debugging
    2155  * \param *a first endpoint
    2156  * \param *b second endpoint
    2157  * \param *c third endpoint
    2158  * \return false - triangle invalid due to edge criteria, true - triangle may be added.
    2159  */
    2160 bool Tesselation::CheckPresenceOfTriangle(ofstream *out, atom *a, atom *b, atom *c) {
    2161         LineMap::iterator TryAndError;
    2162         PointTestPair InsertPoint;
    2163         bool Present[3];
    2164 
    2165         *out << Verbose(2) << "Begin of CheckPresenceOfTriangle" << endl;
    2166         TPS[0] = new class BoundaryPointSet(a);
    2167         TPS[1] = new class BoundaryPointSet(b);
    2168         TPS[2] = new class BoundaryPointSet(c);
    2169         for (int i=0;i<3;i++) { // check through all endpoints
    2170                 InsertPoint = PointsOnBoundary.insert(PointPair(TPS[i]->node->nr, TPS[i]));
    2171                 Present[i] = !InsertPoint.second;
    2172                 if (Present[i]) { // if new point was not present before, increase counter
    2173                         delete TPS[i];
    2174                         *out << Verbose(2) << "Atom " << *((InsertPoint.first)->second->node) << " gibt's schon in der PointMap." << endl;
    2175                         TPS[i] = (InsertPoint.first)->second;
    2176                 }
    2177         }
    2178 
    2179         // check lines
    2180         for (int i=0;i<3;i++)
    2181                 if (Present[i])
    2182                         for (int j=i;j<3;j++)
    2183                                 if (Present[j]) {
    2184                                         TryAndError = TPS[i]->lines.find(TPS[j]->node->nr);
    2185                                         if ((TryAndError != TPS[i]->lines.end()) && (TryAndError->second->TrianglesCount > 1)) {
    2186                                                 *out << "WARNING: Line " << *TryAndError->second << " already present with " << TryAndError->second->TrianglesCount << " triangles attached." << endl;
    2187                                                 *out << Verbose(2) << "End of CheckPresenceOfTriangle" << endl;
    2188                                                 return false;
    2189                                         }
    2190                                 }
    2191         *out << Verbose(2) << "End of CheckPresenceOfTriangle" << endl;
    2192         return true;
    2193 };
    2194 
    2195 
    2196 void Find_second_point_for_Tesselation(atom* a, atom* Candidate, atom* Parent,
    2197     int RecursionLevel, Vector Oben, atom*& Opt_Candidate, double Storage[3],
    2198     molecule* mol, double RADIUS)
    2199 {
    2200         cout << Verbose(2) << "Begin of Find_second_point_for_Tesselation, recursive level " << RecursionLevel << endl;
    2201         int i;
    2202         Vector AngleCheck;
    2203         atom* Walker;
    2204         double norm = -1., angle;
    2205 
    2206         // check if we only have one unique point yet ...
    2207         if (a != Candidate) {
    2208                 cout << Verbose(3) << "Current candidate is " << *Candidate << ": ";
    2209                 AngleCheck.CopyVector(&(Candidate->x));
    2210                 AngleCheck.SubtractVector(&(a->x));
    2211                 norm = AngleCheck.Norm();
    2212                 // second point shall have smallest angle with respect to Oben vector
    2213                 if (norm < RADIUS) {
    2214                         angle = AngleCheck.Angle(&Oben);
    2215                         if (angle < Storage[0]) {
    2216                                 //cout << Verbose(1) << "Old values of Storage: %lf %lf \n", Storage[0], Storage[1]);
    2217                                 cout << "Is a better candidate with distance " << norm << " and " << angle << ".\n";
    2218                                 Opt_Candidate = Candidate;
    2219                                 Storage[0] = AngleCheck.Angle(&Oben);
    2220                                 //cout << Verbose(1) << "Changing something in Storage: %lf %lf. \n", Storage[0], Storage[2]);
    2221                         } else {
    2222                                 cout << "Looses with angle " << angle << " to a better candidate " << *Opt_Candidate << endl;
    2223                         }
    2224                 } else {
    2225                         cout << "Refused due to Radius " << norm << endl;
    2226                 }
    2227         }
    2228 
    2229         // if not recursed to deeply, look at all its bonds
    2230         if (RecursionLevel < 7) {
    2231                 for (i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) {
    2232                         Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(Candidate);
    2233                         if (Walker == Parent) // don't go back along the bond we came from
    2234                                 continue;
    2235                         else
    2236                                 Find_second_point_for_Tesselation(a, Walker, Candidate, RecursionLevel + 1, Oben, Opt_Candidate, Storage, mol, RADIUS);
    2237                 }
    2238         }
    2239         cout << Verbose(2) << "End of Find_second_point_for_Tesselation, recursive level " << RecursionLevel << endl;
    2240 };
    2241 
    2242 void Tesselation::Find_starting_triangle(molecule* mol, const double RADIUS)
    2243 {
    2244         cout << Verbose(1) << "Begin of Find_starting_triangle\n";
    2245         int i = 0;
    2246         atom* Walker;
    2247         atom* FirstPoint;
    2248         atom* SecondPoint;
    2249         atom* max_index[NDIM];
    2250         double max_coordinate[NDIM];
    2251         Vector Oben;
    2252         Vector helper;
    2253         Vector Chord;
    2254         Vector CenterOfFirstLine;
    2255 
    2256         Oben.Zero();
    2257 
    2258         for (i = 0; i < 3; i++) {
    2259                 max_index[i] = NULL;
    2260                 max_coordinate[i] = -1;
    2261         }
    2262         cout << Verbose(2) << "Molecule mol is there and has " << mol->AtomCount << " Atoms \n";
    2263 
    2264         // 1. searching topmost atom with respect to each axis
    2265         Walker = mol->start;
    2266         while (Walker->next != mol->end) {
    2267                 Walker = Walker->next;
    2268                 for (i = 0; i < 3; i++) {
    2269                         if (Walker->x.x[i] > max_coordinate[i]) {
    2270                                 max_coordinate[i] = Walker->x.x[i];
    2271                                 max_index[i] = Walker;
    2272                         }
    2273                 }
    2274         }
    2275 
    2276         cout << Verbose(2) << "Found maximum coordinates: ";
    2277         for (int i=0;i<NDIM;i++)
    2278                 cout << i << ": " << *max_index[i] << "\t";
    2279         cout << endl;
    2280   //Koennen dies fuer alle Richtungen, legen hier erstmal Richtung auf k=0
    2281         const int k = 1;
    2282         Oben.x[k] = 1.;
    2283         FirstPoint = max_index[k];
    2284 
    2285         cout << Verbose(1) << "Coordinates of start atom " << *FirstPoint << " at " << FirstPoint->x << " with " << mol->NumberOfBondsPerAtom[FirstPoint->nr] << " bonds." << endl;
    2286         double Storage[3];
    2287         atom* Opt_Candidate = NULL;
    2288         Storage[0] = 999999.; // This will contain the angle, which will be always positive (when looking for second point), when looking for third point this will be the quadrant.
    2289         Storage[1] = 999999.; // This will be an angle looking for the third point.
    2290         Storage[2] = 999999.;
    2291 
    2292         Find_second_point_for_Tesselation(FirstPoint, FirstPoint, FirstPoint, 0, Oben, Opt_Candidate, Storage, mol, RADIUS); // we give same point as next candidate as its bonds are looked into in find_second_...
    2293         SecondPoint = Opt_Candidate;
    2294         cout << Verbose(1) << "Found second point is " << *SecondPoint << " at " << SecondPoint->x << ".\n";
    2295 
    2296         helper.CopyVector(&(FirstPoint->x));
    2297         helper.SubtractVector(&(SecondPoint->x));
    2298         helper.Normalize();
    2299         Oben.ProjectOntoPlane(&helper);
    2300         Oben.Normalize();
    2301         helper.VectorProduct(&Oben);
    2302         Storage[0] = -2.; // This will indicate the quadrant.
    2303         Storage[1] = 9999999.; // This will be an angle looking for the third point.
    2304         Storage[2] = 9999999.;
    2305 
    2306         Chord.CopyVector(&(FirstPoint->x)); // bring into calling function
    2307         Chord.SubtractVector(&(SecondPoint->x));
    2308         // Now, oben and helper are two orthonormalized vectors in the plane defined by Chord (not normalized)
    2309 
    2310         cout << Verbose(2) << "Looking for third point candidates \n";
    2311         // look in one direction of baseline for initial candidate
    2312         Opt_Candidate = NULL;
    2313         CenterOfFirstLine.CopyVector(&Chord);
    2314         CenterOfFirstLine.Scale(0.5);
    2315         CenterOfFirstLine.AddVector(&(SecondPoint->x));
    2316 
    2317         cout << Verbose(1) << "Looking for third point candidates from " << *FirstPoint << " onward ...\n";
    2318         Find_next_suitable_point_via_Angle_of_Sphere(FirstPoint, SecondPoint, SecondPoint, SecondPoint, FirstPoint, 0, &Chord, &helper, &Oben, CenterOfFirstLine,  Opt_Candidate, Storage, RADIUS, mol);
    2319         // look in other direction of baseline for possible better candidate
    2320         cout << Verbose(1) << "Looking for third point candidates from " << *SecondPoint << " onward ...\n";
    2321         Find_next_suitable_point_via_Angle_of_Sphere(FirstPoint, SecondPoint, SecondPoint, FirstPoint, SecondPoint, 0, &Chord, &helper, &Oben, CenterOfFirstLine, Opt_Candidate, Storage, RADIUS, mol);
    2322         cout << Verbose(1) << "Third Point is " << *Opt_Candidate << endl;
    2323 
    2324         // FOUND Starting Triangle: FirstPoint, SecondPoint, Opt_Candidate
    2325 
    2326         // Finally, we only have to add the found points
    2327         AddTrianglePoint(FirstPoint, 0);
    2328         AddTrianglePoint(SecondPoint, 1);
    2329         AddTrianglePoint(Opt_Candidate, 2);
    2330         // ... and respective lines
    2331         AddTriangleLine(TPS[0], TPS[1], 0);
    2332         AddTriangleLine(TPS[1], TPS[2], 1);
    2333         AddTriangleLine(TPS[0], TPS[2], 2);
    2334         // ... and triangles to the Maps of the Tesselation class
    2335         BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
    2336         AddTriangleToLines();
    2337         // ... and calculate its normal vector (with correct orientation)
    2338         Oben.Scale(-1.);
    2339         BTS->GetNormalVector(Oben);
    2340         cout << Verbose(0) << "==> The found starting triangle consists of " << *FirstPoint << ", " << *SecondPoint << " and " << *Opt_Candidate << " with normal vector " << BTS->NormalVector << ".\n";
    2341         cout << Verbose(1) << "End of Find_starting_triangle\n";
    2342 };
    2343 
    2344 void Find_non_convex_border(ofstream *out, ofstream *tecplot, molecule* mol, const char *filename, const double RADIUS)
    2345 {
    2346         int N = 0;
    2347         struct Tesselation *Tess = new Tesselation;
    2348         cout << Verbose(1) << "Entering search for non convex hull. " << endl;
    2349         cout << flush;
    2350         LineMap::iterator baseline;
    2351         cout << Verbose(0) << "Begin of Find_non_convex_border\n";
    2352         bool flag = false;  // marks whether we went once through all baselines without finding any without two triangles
    2353         bool failflag = false;
    2354         if ((mol->first->next == mol->last) || (mol->last->previous == mol->first))
    2355                 mol->CreateAdjacencyList((ofstream *)&cout, 1.6, true);
    2356 
    2357         Tess->Find_starting_triangle(mol, RADIUS);
    2358 
    2359         baseline = Tess->LinesOnBoundary.begin();
    2360         while ((baseline != Tess->LinesOnBoundary.end()) || (flag)) {
    2361                 if (baseline->second->TrianglesCount == 1) {
    2362                         failflag = Tess->Find_next_suitable_triangle(out, tecplot, mol, *(baseline->second), *(((baseline->second->triangles.begin()))->second), RADIUS, N, filename); //the line is there, so there is a triangle, but only one.
    2363                         flag = flag || failflag;
    2364                         if (!failflag)
    2365                                 cerr << "WARNING: Find_next_suitable_triangle failed." << endl;
    2366                 } else {
    2367                         cout << Verbose(1) << "Line " << *baseline->second << " has " << baseline->second->TrianglesCount << " triangles adjacent" << endl;
    2368                 }
    2369                 N++;
    2370                 baseline++;
    2371                 if ((baseline == Tess->LinesOnBoundary.end()) && (flag)) {
    2372                         baseline = Tess->LinesOnBoundary.begin();   // restart if we reach end due to newly inserted lines
    2373                         flag = false;
    2374                 }
    2375         }
    2376         if (failflag) {
    2377                 cout << Verbose(1) << "Writing final tecplot file\n";
    2378                 if (DoTecplotOutput)
    2379                         write_tecplot_file(out, tecplot, Tess, mol, -1);
    2380                 if (DoRaster3DOutput)
    2381                         write_raster3d_file(out, tecplot, Tess, mol);
    2382         } else {
    2383                 cerr << "ERROR: Could definately not find all necessary triangles!" << endl;
    2384         }
    2385 
    2386         cout << Verbose(0) << "End of Find_non_convex_border\n";
    2387         delete(Tess);
    2388 };
    2389 
     937  PointsOnBoundary.insert( PointPair(Walker->nr, BPS[0]) );
     938  PointsOnBoundaryCount++;
     939};
  • src/boundary.hpp

    • Property mode changed from 100755 to 100644
    r986c80 redcda5  
    3636    BoundaryPointSet(atom *Walker);
    3737    ~BoundaryPointSet();
    38 
     38   
    3939    void AddLine(class BoundaryLineSet *line);
    40 
     40   
    4141    LineMap lines;
    4242    int LinesCount;
     
    6464    BoundaryTriangleSet(class BoundaryLineSet *line[3], int number);
    6565    ~BoundaryTriangleSet();
    66 
     66   
    6767    void GetNormalVector(Vector &NormalVector);
    68 
     68   
    6969    class BoundaryPointSet *endpoints[3];
    7070    class BoundaryLineSet *lines[3];
    71     Vector NormalVector;
    7271    int Nr;
    7372};
     
    7574class Tesselation {
    7675  public:
    77 
     76   
    7877    Tesselation();
    7978    ~Tesselation();
    80 
     79   
    8180    void TesselateOnBoundary(ofstream *out, config *configuration, molecule *mol);
    8281    void GuessStartingTriangle(ofstream *out);
    8382    void AddPoint(atom * Walker);
    84     void AddTrianglePoint(atom* Candidate, int n);
    85     void AddTriangleLine(class BoundaryPointSet *a, class BoundaryPointSet *b, int n);
    86     void AddTriangleToLines();
    87     void Find_starting_triangle(molecule* mol, const double RADIUS);
    88     bool Find_next_suitable_triangle(ofstream *out, ofstream *tecplot, molecule* mol, BoundaryLineSet &Line, BoundaryTriangleSet &T, const double& RADIUS, int N, const char *filename);
    89     bool CheckPresenceOfTriangle(ofstream *out, atom *a, atom *b, atom *c);
    90     void Find_next_suitable_point_via_Angle_of_Sphere(atom* a, atom* b, atom* c, atom* Candidate, atom* Parent, int RecursionLevel, Vector *Chord, Vector *direction1, Vector *OldNormal, Vector ReferencePoint, atom*& Opt_Candidate, double *Storage, const double RADIUS, molecule* mol);
    91 
     83   
    9284    PointMap PointsOnBoundary;
    9385    LineMap LinesOnBoundary;
    9486    TriangleMap TrianglesOnBoundary;
    95     class BoundaryPointSet *TPS[3]; //this is a Storage for pointers to triangle points, this and BPS[2] needed due to AddLine restrictions
    9687    class BoundaryPointSet *BPS[2];
    9788    class BoundaryLineSet *BLS[3];
     
    10091    int LinesOnBoundaryCount;
    10192    int TrianglesOnBoundaryCount;
    102     int TriangleFilesWritten;
    10393};
    10494
     
    10999
    110100
    111 double VolumeOfConvexEnvelope(ofstream *out, ofstream *tecplot, config *configuration, Boundaries *BoundaryPoints, molecule *mol);
     101double VolumeOfConvexEnvelope(ofstream *out, config *configuration, Boundaries *BoundaryPoints, molecule *mol);
    112102double * GetDiametersOfCluster(ofstream *out, Boundaries *BoundaryPtr, molecule *mol, bool IsAngstroem);
    113103void PrepareClustersinWater(ofstream *out, config *configuration, molecule *mol, double ClusterVolume, double celldensity);
    114 void Find_non_convex_border(ofstream *out, ofstream *tecplot, molecule* mol, const char *tempbasename, const double RADIUS);
    115 void Find_next_suitable_point(atom a, atom b, atom Candidate, int n, Vector *d1, Vector *d2, atom*& Opt_Candidate, double *Storage, const double RADIUS, molecule *mol, bool problem);
    116104
    117105
  • src/builder.cpp

    • Property mode changed from 100755 to 100644
    r986c80 redcda5  
    11/** \file builder.cpp
    2  *
     2 * 
    33 * By stating absolute positions or binding angles and distances atomic positions of a molecule can be constructed.
    44 * The output is the complete configuration file for PCP for direct use.
     
    66 * -# Atomic data is retrieved from a file, if not found requested and stored there for later re-use
    77 * -# step-by-step construction of the molecule beginning either at a centre of with a certain atom
    8  *
     8 *   
    99 */
    1010
    1111/*! \mainpage Molecuilder - a molecular set builder
    12  *
     12 * 
    1313 * This introductory shall briefly make aquainted with the program, helping in installing and a first run.
    14  *
     14 * 
    1515 * \section about About the Program
    16  *
     16 * 
    1717 *  Molecuilder is a short program, written in C++, that enables the construction of a coordinate set for the
    1818 *  atoms making up an molecule by the successive statement of binding angles and distances and referencing to
    1919 *  already constructed atoms.
    20  *
     20 * 
    2121 *  A configuration file may be written that is compatible to the format used by PCP - a parallel Car-Parrinello
    2222 *  molecular dynamics implementation.
    23  *
     23 * 
    2424 * \section install Installation
    25  *
     25 * 
    2626 *  Installation should without problems succeed as follows:
    2727 *  -# ./configure (or: mkdir build;mkdir run;cd build; ../configure --bindir=../run)
    2828 *  -# make
    2929 *  -# make install
    30  *
     30 * 
    3131 *  Further useful commands are
    3232 *  -# 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
    34  *
     33 *  -# make doxygen-doc: Creates these html pages out of the documented source 
     34 * 
    3535 * \section run Running
    36  *
     36 * 
    3737 *  The program can be executed by running: ./molecuilder
    38  *
     38 * 
    3939 *  Note, that it uses a database, called "elements.db", in the executable's directory. If the file is not found,
    4040 *  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.
    42  *
     41 *  later re-execution. 
     42 * 
    4343 * \section ref References
    44  *
     44 * 
    4545 *  For the special configuration file format, see the documentation of pcp.
    46  *
     46 * 
    4747 */
    4848
     
    8080  cout << Verbose(0) << "INPUT: ";
    8181  cin >> choice;
    82 
     82 
    8383  switch (choice) {
    8484      case 'a': // absolute coordinates of atom
     
    8989        mol->AddAtom(first);  // add to molecule
    9090        break;
    91 
     91       
    9292      case 'b': // relative coordinates of atom wrt to reference point
    9393        first = new atom;
     
    105105        mol->AddAtom(first);  // add to molecule
    106106        break;
    107 
     107       
    108108      case 'c': // relative coordinates of atom wrt to already placed atom
    109109        first = new atom;
     
    111111        do {
    112112          if (!valid) cout << Verbose(0) << "Resulting position out of cell." << endl;
    113           second = mol->AskAtom("Enter atom number: ");
     113          second = mol->AskAtom("Enter atom number: ");               
    114114          cout << Verbose(0) << "Enter relative coordinates." << endl;
    115115          first->x.AskPosition(mol->cell_size, false);
     
    121121        mol->AddAtom(first);  // add to molecule
    122122        break;
    123 
     123     
    124124      case 'd': // two atoms, two angles and a distance
    125125        first = new atom;
     
    152152          x.Copyvector(&fourth->x);
    153153          x.SubtractVector(&third->x);
    154 
     154         
    155155          if (!z.SolveSystem(&x,&y,&n, b, c, a)) {
    156156            cout << Verbose(0) << "Failure solving self-dependent linear system!" << endl;
     
    167167          cout << "x: ",
    168168          x.Output((ofstream *)&cout);
    169           cout << endl;
     169          cout << endl;         
    170170          z.MakeNormalVector(&second->x,&third->x,&fourth->x);
    171171          cout << "z: ",
    172172          z.Output((ofstream *)&cout);
    173           cout << endl;
     173          cout << endl;         
    174174          y.MakeNormalVector(&x,&z);
    175175          cout << "y: ",
    176176          y.Output((ofstream *)&cout);
    177           cout << endl;
    178 
     177          cout << endl;         
     178         
    179179          // rotate vector around first angle
    180180          first->x.CopyVector(&x);
     
    182182          cout << "Rotated vector: ",
    183183          first->x.Output((ofstream *)&cout);
    184           cout << endl;
     184          cout << endl;         
    185185          // remove the projection onto the rotation plane of the second angle
    186186          n.CopyVector(&y);
     
    188188          cout << "N1: ",
    189189          n.Output((ofstream *)&cout);
    190           cout << endl;
     190          cout << endl;         
    191191          first->x.SubtractVector(&n);
    192192          cout << "Subtracted vector: ",
    193193          first->x.Output((ofstream *)&cout);
    194           cout << endl;
     194          cout << endl;         
    195195          n.CopyVector(&z);
    196196          n.Scale(first->x.Projection(&z));
    197197          cout << "N2: ",
    198198          n.Output((ofstream *)&cout);
    199           cout << endl;
     199          cout << endl;         
    200200          first->x.SubtractVector(&n);
    201201          cout << "2nd subtracted vector: ",
    202202          first->x.Output((ofstream *)&cout);
    203           cout << endl;
    204 
     203          cout << endl;         
     204         
    205205          // rotate another vector around second angle
    206206          n.CopyVector(&y);
     
    208208          cout << "2nd Rotated vector: ",
    209209          n.Output((ofstream *)&cout);
    210           cout << endl;
    211 
     210          cout << endl;         
     211         
    212212          // add the two linear independent vectors
    213213          first->x.AddVector(&n);
    214           first->x.Normalize();
     214          first->x.Normalize();         
    215215          first->x.Scale(a);
    216216          first->x.AddVector(&second->x);
    217 
     217         
    218218          cout << Verbose(0) << "resulting coordinates: ";
    219219          first->x.Output((ofstream *)&cout);
     
    241241        } while ((j != -1) && (i<128));
    242242        if (i >= 2) {
    243           first->x.LSQdistance(atoms, i);
     243          first->x.LSQdistance(atoms, i);             
    244244
    245245          first->x.Output((ofstream *)&cout);
     
    259259static void CenterAtoms(molecule *mol)
    260260{
    261   Vector x, y, helper;
     261  Vector x, y;
    262262  char choice;  // menu choice char
    263 
     263 
    264264  cout << Verbose(0) << "===========CENTER ATOMS=========================" << endl;
    265265  cout << Verbose(0) << " a - on origin" << endl;
     
    271271  cout << Verbose(0) << "INPUT: ";
    272272  cin >> choice;
    273 
     273 
    274274  switch (choice) {
    275275    default:
     
    292292      mol->CenterEdge((ofstream *)&cout, &x);  // make every coordinate positive
    293293      mol->Translate(&y); // translate by boundary
    294       helper.CopyVector(&y);
    295       helper.Scale(2.);
    296       helper.AddVector(&x);
    297       mol->SetBoxDimension(&helper);  // update Box of atoms by boundary
     294      mol->SetBoxDimension(&(x+y*2));  // update Box of atoms by boundary
    298295      break;
    299296    case 'd':
     
    330327  cout << Verbose(0) << "INPUT: ";
    331328  cin >> choice;
    332 
     329 
    333330  switch (choice) {
    334331    default:
     
    349346      second = mol->AskAtom("Enter second atom: ");
    350347
    351       n.CopyVector((const Vector *)&first->x);
    352       n.SubtractVector((const Vector *)&second->x);
     348      n.CopyVector((const Vector *)&first->x); 
     349      n.SubtractVector((const Vector *)&second->x); 
    353350      n.Normalize();
    354       break;
     351      break;       
    355352    case 'd':
    356353      char shorthand[4];
     
    366363        x.x[i] = gsl_vector_get(param.x,i);
    367364        n.x[i] = gsl_vector_get(param.x,i+NDIM);
    368       }
     365      } 
    369366      gsl_vector_free(param.x);
    370367      cout << Verbose(0) << "Offset vector: ";
     
    372369      cout << Verbose(0) << endl;
    373370      n.Normalize();
    374       break;
     371      break;       
    375372  };
    376373  cout << Verbose(0) << "Alignment vector: ";
     
    388385  Vector n;
    389386  char choice;  // menu choice char
    390 
     387 
    391388  cout << Verbose(0) << "===========MIRROR ATOMS=========================" << endl;
    392389  cout << Verbose(0) << " a - state three atoms defining mirror plane" << endl;
     
    397394  cout << Verbose(0) << "INPUT: ";
    398395  cin >> choice;
    399 
     396 
    400397  switch (choice) {
    401398    default:
     
    416413      second = mol->AskAtom("Enter second atom: ");
    417414
    418       n.CopyVector((const Vector *)&first->x);
    419       n.SubtractVector((const Vector *)&second->x);
     415      n.CopyVector((const Vector *)&first->x); 
     416      n.SubtractVector((const Vector *)&second->x); 
    420417      n.Normalize();
    421       break;
     418      break;         
    422419  };
    423420  cout << Verbose(0) << "Normal vector: ";
     
    436433  double tmp1, tmp2;
    437434  char choice;  // menu choice char
    438 
     435 
    439436  cout << Verbose(0) << "===========REMOVE ATOMS=========================" << endl;
    440437  cout << Verbose(0) << " a - state atom for removal by number" << endl;
     
    445442  cout << Verbose(0) << "INPUT: ";
    446443  cin >> choice;
    447 
     444 
    448445  switch (choice) {
    449446    default:
     
    478475          mol->RemoveAtom(first);
    479476      }
    480       break;
     477      break;         
    481478  };
    482479  //mol->Output((ofstream *)&cout);
     
    495492  int Z;
    496493  char choice;  // menu choice char
    497 
     494 
    498495  cout << Verbose(0) << "===========MEASURE ATOMS=========================" << endl;
    499496  cout << Verbose(0) << " a - calculate bond length between one atom and all others" << endl;
     
    517514      for (int i=MAX_ELEMENTS;i--;)
    518515        min[i] = 0.;
    519 
    520       second = mol->start;
     516       
     517      second = mol->start;   
    521518      while ((second->next != mol->end)) {
    522519        second = second->next; // advance
     
    529526        }
    530527        if ((tmp1 != 0.) && ((min[Z] == 0.) || (tmp1 < min[Z]))) min[Z] = tmp1;
    531         //cout << Verbose(0) << "Bond length between Atom " << first->nr << " and " << second->nr << ": " << tmp1 << " a.u." << endl;
     528        //cout << Verbose(0) << "Bond length between Atom " << first->nr << " and " << second->nr << ": " << tmp1 << " a.u." << endl;         
    532529      }
    533530      for (int i=MAX_ELEMENTS;i--;)
    534531        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;
    535532      break;
    536 
     533     
    537534    case 'b':
    538535      first = mol->AskAtom("Enter first atom: ");
     
    559556      y.SubtractVector((const Vector *)&second->x);
    560557      cout << Verbose(0) << "Bond angle between first atom Nr." << first->nr << ", central atom Nr." << second->nr << " and last atom Nr." << third->nr << ": ";
    561       cout << Verbose(0) << (acos(x.ScalarProduct((const Vector *)&y)/(y.Norm()*x.Norm()))/M_PI*180.) << " degrees" << endl;
     558      cout << Verbose(0) << (acos(x.ScalarProduct((const Vector *)&y)/(y.Norm()*x.Norm()))/M_PI*180.) << " degrees" << endl;         
    562559      break;
    563560    case 'd':
     
    572569    case 'e':
    573570        cout << Verbose(0) << "Evaluating volume of the convex envelope.";
    574         VolumeOfConvexEnvelope((ofstream *)&cout, NULL, configuration, NULL, mol);
     571        VolumeOfConvexEnvelope((ofstream *)&cout, configuration, NULL, mol);
    575572        break;
    576573    case 'f':
     
    603600  int Order1;
    604601  clock_t start, end;
    605 
     602 
    606603  cout << Verbose(0) << "Fragmenting molecule with current connection matrix ..." << endl;
    607604  cout << Verbose(0) << "What's the desired bond order: ";
     
    612609    end = clock();
    613610    cout << Verbose(0) << "Clocks for this operation: " << (end-start) << ", time: " << ((double)(end-start)/CLOCKS_PER_SEC) << "s." << endl;
    614   } else
     611  } else 
    615612    cout << Verbose(0) << "Connection matrix has not yet been generated!" << endl;
    616613};
     
    626623  atom *Walker = mol->start;
    627624  int i, comp, counter=0;
    628 
     625 
    629626  // generate some KeySets
    630627  cout << "Generating KeySets." << endl;
     
    640637  cout << "Testing insertion of already present item in KeySets." << endl;
    641638  KeySetTestPair test;
    642   test = TestSets[mol->AtomCount-1].insert(Walker->nr);
     639  test = TestSets[mol->AtomCount-1].insert(Walker->nr); 
    643640  if (test.second) {
    644641    cout << Verbose(1) << "Insertion worked?!" << endl;
     
    649646  TestSets[mol->AtomCount].insert(mol->end->previous->previous->previous->nr);
    650647
    651   // constructing Graph structure
     648  // constructing Graph structure 
    652649  cout << "Generating Subgraph class." << endl;
    653650  Graph Subgraphs;
     
    660657  cout << "Testing insertion of already present item in Subgraph." << endl;
    661658  GraphTestPair test2;
    662   test2 = Subgraphs.insert(GraphPair (TestSets[mol->AtomCount],pair<int, double>(counter++, 1.)));
     659  test2 = Subgraphs.insert(GraphPair (TestSets[mol->AtomCount],pair<int, double>(counter++, 1.))); 
    663660  if (test2.second) {
    664661    cout << Verbose(1) << "Insertion worked?!" << endl;
     
    666663    cout << Verbose(1) << "Insertion rejected: Present object is " << (*(test2.first)).second.first << "." << endl;
    667664  }
    668 
     665 
    669666  // show graphs
    670667  cout << "Showing Subgraph's contents, checking that it's sorted." << endl;
     
    677674      if ((*key) > comp)
    678675        cout << (*key) << " ";
    679       else
     676      else 
    680677        cout << (*key) << "! ";
    681678      comp = (*key);
     
    697694  char filename[MAXSTRINGSIZE];
    698695  ofstream output;
    699   string basis("3-21G");
    700696
    701697  cout << Verbose(0) << "Storing configuration ... " << endl;
     
    703699  mol->CalculateOrbitals(*configuration);
    704700  configuration->InitMaxMinStopStep = configuration->MaxMinStopStep = configuration->MaxPsiDouble;
    705   strcpy(filename, ConfigFileName);
    706   if (ConfigFileName != NULL) { // test the file name
     701  if (ConfigFileName != NULL) {
    707702    output.open(ConfigFileName, ios::trunc);
    708703  } else if (strlen(configuration->configname) != 0) {
    709     strcpy(filename, configuration->configname);
    710704    output.open(configuration->configname, ios::trunc);
    711705    } else {
    712       strcpy(filename, DEFAULTCONFIG);
    713706      output.open(DEFAULTCONFIG, ios::trunc);
    714707    }
    715   output.close();
    716   output.clear();
    717708  cout << Verbose(0) << "Saving of config file ";
    718   if (configuration->Save(filename, periode, mol))
     709  if (configuration->Save(&output, periode, mol))
    719710    cout << "successful." << endl;
    720711  else
    721712    cout << "failed." << endl;
    722 
     713  output.close();
     714  output.clear();
     715 
    723716  // and save to xyz file
    724717  if (ConfigFileName != NULL) {
     
    731724    strcat(filename, ".xyz");
    732725    output.open(filename, ios::trunc);
    733   }
     726  } 
    734727  cout << Verbose(0) << "Saving of XYZ file ";
    735728  if (mol->MDSteps <= 1) {
     
    746739  output.close();
    747740  output.clear();
    748 
     741 
    749742  // and save as MPQC configuration
    750   if (ConfigFileName != NULL)
     743  if (ConfigFileName != NULL) {
    751744    strcpy(filename, ConfigFileName);
    752   if (output == NULL)
     745    strcat(filename, ".in");
     746    output.open(filename, ios::trunc);
     747  }
     748  if (output == NULL) {
    753749    strcpy(filename,"main_pcp_linux");
     750    strcat(filename, ".in");
     751    output.open(filename, ios::trunc);
     752  }
    754753  cout << Verbose(0) << "Saving as mpqc input ";
    755   if (configuration->SaveMPQC(filename, mol))
     754  if (configuration->SaveMPQC(&output, mol))
    756755    cout << "done." << endl;
    757756  else
    758757    cout << "failed." << endl;
    759 
     758  output.close();
     759  output.clear();
     760 
    760761  if (!strcmp(configuration->configpath, configuration->GetDefaultPath())) {
    761762    cerr << "WARNING: config is found under different path then stated in config file::defaultpath!" << endl;
     
    789790  int argptr;
    790791  PathToDatabases = LocalPath;
    791 
     792 
    792793  if (argc > 1) { // config file specified as option
    793794    // 1. : Parse options that just set variables or print help
     
    802803          case '?':
    803804            cout << "MoleCuilder suite" << endl << "==================" << endl << endl;
    804             cout << "Usage: " << argv[0] << "[config file] [-{acefpsthH?vfrp}] [further arguments]" << endl;
     805            cout << "Usage: " << argv[0] << "[config file] [-{acefpsthH?vfrp}] [further arguments]" << endl; 
    805806            cout << "or simply " << argv[0] << " without arguments for interactive session." << endl;
    806807            cout << "\t-a Z x1 x2 x3\tAdd new atom of element Z at coordinates (x1,x2,x3)." << endl;
    807             cout << "\t-A <source>\tCreate adjacency list from bonds parsed from 'dbond'-style file." <<endl;
    808808            cout << "\t-b x1 x2 x3\tCenter atoms in domain with given edge lengths of (x1,x2,x3)." << endl;
    809             cout << "\t-B <basis>\tgive gaussian basis for MPQC output." << endl;
    810809            cout << "\t-c x1 x2 x3\tCenter atoms in domain with a minimum distance to boundary of (x1,x2,x3)." << endl;
    811810            cout << "\t-D <bond distance>\tDepth-First-Search Analysis of the molecule, giving cycles and tree/back edges." << endl;
     
    818817            cout << "\t-m <0/1>\tCalculate (0)/ Align in(1) PAS with greatest EV along z axis." << endl;
    819818            cout << "\t-n\tFast parsing (i.e. no trajectories are looked for)." << endl;
    820             cout << "\t-N\tGet non-convex-envelope." << endl;
    821             cout << "\t-o <out>\tGet volume of the convex envelope (and store to tecplot file)." << endl;
     819            cout << "\t-o\tGet volume of the convex envelope (and store to tecplot file)." << endl;
    822820            cout << "\t-p <file>\tParse given xyz file and create raw config file from it." << endl;
    823821            cout << "\t-P <file>\tParse given forces file and append as an MD step to config file via Verlet." << endl;
     
    825823            cout << "\t-r\t\tConvert file from an old pcp syntax." << endl;
    826824            cout << "\t-t x1 x2 x3\tTranslate all atoms by this vector (x1,x2,x3)." << endl;
    827             cout << "\t-T <file> Store temperatures from the config file in <file>." << endl;
     825            cout << "\t-T <file> Store temperatures from the config file in <file>." << endl; 
    828826            cout << "\t-s x1 x2 x3\tScale all atom coordinates by this vector (x1,x2,x3)." << endl;
    829             cout << "\t-u rho\tsuspend in water solution and output necessary cell lengths, average density rho and repetition." << endl;
     827            cout << "\t-u rho\tsuspend in water solution and output necessary cell lengths, average density rho and repetition." << endl; 
    830828            cout << "\t-v/-V\t\tGives version information." << endl;
    831829            cout << "Note: config files must not begin with '-' !" << endl;
     
    843841            break;
    844842          case 'e':
    845             if ((argptr >= argc) || (argv[argptr][0] == '-')) {
    846               cerr << "Not enough or invalid arguments for specifying element db: -e <db file>" << endl;
    847             } else {
    848               cout << "Using " << argv[argptr] << " as elements database." << endl;
    849               PathToDatabases = argv[argptr];
    850               argptr+=1;
    851             }
     843            cout << "Using " << argv[argptr] << " as elements database." << endl;
     844            PathToDatabases = argv[argptr];
     845            argptr+=1;
    852846            break;
    853847          case 'n':
     
    862856        argptr++;
    863857    } while (argptr < argc);
    864 
     858   
    865859    // 2. Parse the element database
    866860    if (periode->LoadPeriodentafel(PathToDatabases)) {
     
    871865      return 1;
    872866    }
    873 
     867   
    874868    // 3. Find config file name and parse if possible
    875869    if (argv[1][0] != '-') {
     
    910904    } else
    911905      config_present = absent;
    912 
     906   
    913907    // 4. parse again through options, now for those depending on elements db and config presence
    914908    argptr = 1;
     
    921915            case 'p':
    922916              ExitFlag = 1;
    923               if ((argptr >= argc) || (argv[argptr][0] == '-')) {
    924                 ExitFlag = 255;
    925                 cerr << "Not enough arguments for parsing: -p <xyz file>" << endl;
    926               } else {
    927                 SaveFlag = true;
    928                 cout << Verbose(1) << "Parsing xyz file for new atoms." << endl;
    929                 if (!mol->AddXYZFile(argv[argptr]))
    930                   cout << Verbose(2) << "File not found." << endl;
    931                 else {
    932                   cout << Verbose(2) << "File found and parsed." << endl;
     917              SaveFlag = true;
     918              cout << Verbose(1) << "Parsing xyz file for new atoms." << endl;
     919              if (!mol->AddXYZFile(argv[argptr]))
     920                cout << Verbose(2) << "File not found." << endl;
     921              else {
     922                cout << Verbose(2) << "File found and parsed." << endl;
     923                config_present = present;
     924              }
     925              break;
     926            case 'a':
     927              ExitFlag = 1;
     928              SaveFlag = true;
     929              cout << Verbose(1) << "Adding new atom with element " << argv[argptr] << " at (" << argv[argptr+1] << "," << argv[argptr+2] << "," << argv[argptr+3] << "), ";
     930              first = new atom;
     931              first->type = periode->FindElement(atoi(argv[argptr]));
     932              if (first->type != NULL)
     933                cout << Verbose(2) << "found element " << first->type->name << endl;
     934              for (int i=NDIM;i--;)
     935                first->x.x[i] = atof(argv[argptr+1+i]);
     936              if (first->type != NULL) {
     937                mol->AddAtom(first);  // add to molecule
     938                if ((config_present == empty) && (mol->AtomCount != 0))
    933939                  config_present = present;
    934                 }
    935               }
    936               break;
    937             case 'a':
    938               ExitFlag = 1;
    939               if ((argptr >= argc) || (argv[argptr][0] == '-') || (!IsValidNumber(argv[argptr+1]))) {
    940                 ExitFlag = 255;
    941                 cerr << "Not enough or invalid arguments for adding atom: -a <element> <x> <y> <z>" << endl;
    942               } else {
    943                 SaveFlag = true;
    944                 cout << Verbose(1) << "Adding new atom with element " << argv[argptr] << " at (" << argv[argptr+1] << "," << argv[argptr+2] << "," << argv[argptr+3] << "), ";
    945                 first = new atom;
    946                 first->type = periode->FindElement(atoi(argv[argptr]));
    947                 if (first->type != NULL)
    948                   cout << Verbose(2) << "found element " << first->type->name << endl;
    949                 for (int i=NDIM;i--;)
    950                   first->x.x[i] = atof(argv[argptr+1+i]);
    951                 if (first->type != NULL) {
    952                   mol->AddAtom(first);  // add to molecule
    953                   if ((config_present == empty) && (mol->AtomCount != 0))
    954                     config_present = present;
    955                 } else
    956                   cerr << Verbose(1) << "Could not find the specified element." << endl;
    957                 argptr+=4;
    958               }
     940              } else
     941                cerr << Verbose(1) << "Could not find the specified element." << endl;
     942              argptr+=4;
    959943              break;
    960944            default:   // no match? Don't step on (this is done in next switch's default)
     
    964948        if (config_present == present) {
    965949          switch(argv[argptr-1][1]) {
    966             case 'B':
    967               if ((argptr >= argc) || (!IsValidNumber(argv[argptr])) || (argv[argptr][0] == '-')) {
    968                 ExitFlag = 255;
    969                 cerr << "Not enough or invalid arguments given for giving gaussian basis: -B <basis>" << endl;
    970               } else {
    971                 cout << Verbose(1) << "Setting gaussian basis to " << argv[argptr] << "." << endl;
    972                 configuration.basis.copy(argv[argptr],strlen(argv[argptr]));
    973                 argptr+=1;
    974               }
    975               break;
    976             case 'D':
     950            case 'D':
    977951              ExitFlag = 1;
    978952              {
     
    1005979                delete[](MinimumRingSize);
    1006980              }
    1007               //argptr+=1;
     981              argptr+=1;
    1008982              break;
    1009983            case 'E':
    1010984              ExitFlag = 1;
    1011               if ((argptr+1 >= argc) || (!IsValidNumber(argv[argptr])) || (argv[argptr+1][0] == '-')) {
    1012                 ExitFlag = 255;
    1013                 cerr << "Not enough or invalid arguments given for changing element: -E <atom nr.> <element>" << endl;
    1014               } else {
    1015                 SaveFlag = true;
    1016                 cout << Verbose(1) << "Changing atom " << argv[argptr] << " to element " << argv[argptr+1] << "." << endl;
    1017                 first = mol->FindAtom(atoi(argv[argptr]));
    1018                 first->type = periode->FindElement(atoi(argv[argptr+1]));
    1019                 argptr+=2;
    1020               }
    1021               break;
    1022                                                 case 'A':
    1023                                                         ExitFlag = 1;
    1024                                                         if ((argptr >= argc) || (!IsValidNumber(argv[argptr])) || (argv[argptr][0] == '-')) {
    1025                                                                 ExitFlag =255;
    1026                                                                 cerr << "Missing source file for bonds in molecule: -A <bond sourcefile>" << endl;
    1027                                                         } else {
    1028                                                                 cout << "Parsing bonds from " << argv[argptr] << "." << endl;
    1029                                                                 ifstream *input = new ifstream(argv[argptr]);
    1030                                                                 mol->CreateAdjacencyList2((ofstream *)&cout, input);
    1031                                                                 input->close();
    1032                                                         }
    1033                                                         break;
    1034                                                 case 'N':
    1035                                                         ExitFlag = 1;
    1036                                                         if ((argptr+1 >= argc) || (argv[argptr+1][0] == '-')){
    1037                                                                 ExitFlag = 255;
    1038                                                                 cerr << "Not enough or invalid arguments given for non-convex envelope: -o <radius> <tecplot output file>" << endl;
    1039                                                         } else {
    1040                                                                 cout << Verbose(0) << "Evaluating npn-convex envelope.";
    1041                                                                 string TempName(argv[argptr+1]);
    1042                                                                 TempName.append(".r3d");
    1043                                                                 ofstream *output = new ofstream(TempName.c_str(), ios::trunc);
    1044                                                                 cout << Verbose(1) << "Using rolling ball of radius " << atof(argv[argptr]) << " and storing tecplot data in " << argv[argptr+1] << "." << endl;
    1045                                                                 Find_non_convex_border((ofstream *)&cout, output, mol, argv[argptr+1], atof(argv[argptr]));
    1046                                                                 output->close();
    1047                                                                 delete(output);
    1048                                                                 argptr+=2;
    1049                                                         }
    1050                                                         break;
     985              SaveFlag = true;
     986              cout << Verbose(1) << "Changing atom " << argv[argptr] << " to element " << argv[argptr+1] << "." << endl;
     987              first = mol->FindAtom(atoi(argv[argptr]));
     988              first->type = periode->FindElement(atoi(argv[argptr+1]));
     989              argptr+=2;
     990              break;
    1051991            case 'T':
    1052992              ExitFlag = 1;
    1053               if ((argptr >= argc) || (argv[argptr][0] == '-')) {
    1054                 ExitFlag = 255;
    1055                 cerr << "Not enough or invalid arguments given for storing tempature: -T <temperature file>" << endl;
    1056               } else {
     993              {
    1057994                cout << Verbose(1) << "Storing temperatures in " << argv[argptr] << "." << endl;
    1058995                ofstream *output = new ofstream(argv[argptr], ios::trunc);
     
    10631000                output->close();
    10641001                delete(output);
    1065                 argptr+=1;
    10661002              }
     1003              argptr+=1;
    10671004              break;
    10681005            case 'L':
     
    10781015            case 'P':
    10791016              ExitFlag = 1;
    1080               if ((argptr >= argc) || (argv[argptr][0] == '-')) {
    1081                 ExitFlag = 255;
    1082                 cerr << "Not enough or invalid arguments given for parsing and integrating forces: -P <forces file>" << endl;
    1083               } else {
    1084                 SaveFlag = true;
    1085                 cout << Verbose(1) << "Parsing forces file and Verlet integrating." << endl;
    1086                 if (!mol->VerletForceIntegration((ofstream *)&cout, argv[argptr], configuration))
    1087                   cout << Verbose(2) << "File not found." << endl;
    1088                 else
    1089                   cout << Verbose(2) << "File found and parsed." << endl;
    1090                 argptr+=1;
     1017              SaveFlag = true;
     1018              cout << Verbose(1) << "Parsing forces file and Verlet integrating." << endl;
     1019              if (!mol->VerletForceIntegration((ofstream *)&cout, argv[argptr], configuration.Deltat, configuration.GetIsAngstroem(), configuration.DoConstrainedMD))
     1020                cout << Verbose(2) << "File not found." << endl;
     1021              else {
     1022                cout << Verbose(2) << "File found and parsed." << endl;
     1023                if (configuration.DoConstrainedMD)
     1024                  // increase source step in expectancy of a new step in the config
     1025                  configuration.DoConstrainedMD++;
    10911026              }
     1027              argptr+=1;
    10921028              break;
    10931029            case 't':
    10941030              ExitFlag = 1;
    1095               if ((argptr+2 >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) {
    1096                 ExitFlag = 255;
    1097                 cerr << "Not enough or invalid arguments given for translation: -t <x> <y> <z>" << endl;
    1098               } else {
    1099                 ExitFlag = 1;
    1100                 SaveFlag = true;
    1101                 cout << Verbose(1) << "Translating all ions to new origin." << endl;
    1102                 for (int i=NDIM;i--;)
    1103                   x.x[i] = atof(argv[argptr+i]);
    1104                 mol->Translate((const Vector *)&x);
    1105                 argptr+=3;
     1031              SaveFlag = true;
     1032              cout << Verbose(1) << "Translating all ions to new origin." << endl;
     1033              for (int i=NDIM;i--;)
     1034                x.x[i] = atof(argv[argptr+i]);
     1035              mol->Translate((const Vector *)&x);
     1036              argptr+=3;
     1037              break;
     1038            case 's':
     1039              ExitFlag = 1;
     1040              SaveFlag = true;
     1041              j = -1;
     1042              cout << Verbose(1) << "Scaling all ion positions by factor." << endl;
     1043              factor = new double[NDIM];
     1044              factor[0] = atof(argv[argptr]);
     1045              if (argc > argptr+1)
     1046                argptr++;
     1047              factor[1] = atof(argv[argptr]);
     1048              if (argc > argptr+1)
     1049                argptr++;
     1050              factor[2] = atof(argv[argptr]);
     1051              mol->Scale(&factor);
     1052              for (int i=0;i<NDIM;i++) {
     1053                j += i+1;
     1054                x.x[i] = atof(argv[NDIM+i]);
     1055                mol->cell_size[j]*=factor[i];
    11061056              }
    1107               break;
    1108             case 's':
    1109               ExitFlag = 1;
    1110               if ((argptr >= argc) || (!IsValidNumber(argv[argptr])) ) {
    1111                 ExitFlag = 255;
    1112                 cerr << "Not enough or invalid arguments given for scaling: -s <factor/[factor_x]> [factor_y] [factor_z]" << endl;
    1113               } else {
    1114                 SaveFlag = true;
    1115                 j = -1;
    1116                 cout << Verbose(1) << "Scaling all ion positions by factor." << endl;
    1117                 factor = new double[NDIM];
    1118                 factor[0] = atof(argv[argptr]);
    1119                 if ((argptr < argc) && (IsValidNumber(argv[argptr])))
    1120                   argptr++;
    1121                 factor[1] = atof(argv[argptr]);
    1122                 if ((argptr < argc) && (IsValidNumber(argv[argptr])))
    1123                   argptr++;
    1124                 factor[2] = atof(argv[argptr]);
    1125                 mol->Scale(&factor);
    1126                 for (int i=0;i<NDIM;i++) {
    1127                   j += i+1;
    1128                   x.x[i] = atof(argv[NDIM+i]);
    1129                   mol->cell_size[j]*=factor[i];
    1130                 }
    1131                 delete[](factor);
    1132                 argptr+=1;
     1057              delete[](factor);
     1058              argptr+=1;
     1059              break;
     1060            case 'b':
     1061              ExitFlag = 1;
     1062              SaveFlag = true;
     1063              j = -1;
     1064              cout << Verbose(1) << "Centering atoms in config file within given simulation box." << endl;
     1065              j=-1;
     1066              for (int i=0;i<NDIM;i++) {
     1067                j += i+1;
     1068                x.x[i] = atof(argv[argptr++]);
     1069                mol->cell_size[j] += x.x[i]*2.;
    11331070              }
    1134               break;
    1135             case 'b':
    1136               ExitFlag = 1;
    1137               if ((argptr+2 >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) {
    1138                 ExitFlag = 255;
    1139                 cerr << "Not enough or invalid arguments given for centering in box: -b <length_x> <length_y> <length_z>" << endl;
    1140               } else {
    1141                 SaveFlag = true;
    1142                 j = -1;
    1143                 cout << Verbose(1) << "Centering atoms in config file within given simulation box." << endl;
    1144                 j=-1;
    1145                 for (int i=0;i<NDIM;i++) {
    1146                   j += i+1;
    1147                   x.x[i] = atof(argv[argptr++]);
    1148                   mol->cell_size[j] += x.x[i]*2.;
    1149                 }
    1150                 // center
    1151                 mol->CenterInBox((ofstream *)&cout, &x);
    1152                 // update Box of atoms by boundary
    1153                 mol->SetBoxDimension(&x);
     1071              // center
     1072              mol->CenterInBox((ofstream *)&cout, &x);
     1073              // update Box of atoms by boundary
     1074              mol->SetBoxDimension(&x);
     1075              break;
     1076            case 'c':
     1077              ExitFlag = 1;
     1078              SaveFlag = true;
     1079              j = -1;
     1080              cout << Verbose(1) << "Centering atoms in config file within given additional boundary." << endl;
     1081              // make every coordinate positive
     1082              mol->CenterEdge((ofstream *)&cout, &x);
     1083              // update Box of atoms by boundary
     1084              mol->SetBoxDimension(&x);
     1085              // translate each coordinate by boundary
     1086              j=-1;
     1087              for (int i=0;i<NDIM;i++) {
     1088                j += i+1;
     1089                x.x[i] = atof(argv[argptr++]);
     1090                mol->cell_size[j] += x.x[i]*2.;
    11541091              }
    1155               break;
    1156             case 'c':
    1157               ExitFlag = 1;
    1158               if ((argptr+2 >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) {
    1159                 ExitFlag = 255;
    1160                 cerr << "Not enough or invalid arguments given for centering with boundary: -c <boundary_x> <boundary_y> <boundary_z>" << endl;
    1161               } else {
    1162                 SaveFlag = true;
    1163                 j = -1;
    1164                 cout << Verbose(1) << "Centering atoms in config file within given additional boundary." << endl;
    1165                 // make every coordinate positive
    1166                 mol->CenterEdge((ofstream *)&cout, &x);
    1167                 // update Box of atoms by boundary
    1168                 mol->SetBoxDimension(&x);
    1169                 // translate each coordinate by boundary
    1170                 j=-1;
    1171                 for (int i=0;i<NDIM;i++) {
    1172                   j += i+1;
    1173                   x.x[i] = atof(argv[argptr++]);
    1174                   mol->cell_size[j] += x.x[i]*2.;
    1175                 }
    1176                 mol->Translate((const Vector *)&x);
    1177               }
     1092              mol->Translate((const Vector *)&x);
    11781093              break;
    11791094            case 'O':
     
    11921107            case 'f':
    11931108              ExitFlag = 1;
    1194               if ((argptr+1 >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1]))) {
    1195                 ExitFlag = 255;
    1196                 cerr << "Not enough or invalid arguments for fragmentation: -f <max. bond distance> <bond order>" << endl;
    1197               } else {
    1198                 cout << "Fragmenting molecule with bond distance " << argv[argptr] << " angstroem, order of " << argv[argptr+1] << "." << endl;
     1109              cout << "Fragmenting molecule with bond distance " << argv[argptr] << " angstroem, order of " << argv[argptr+1] << "." << endl;
     1110              if (argc >= argptr+2) {
    11991111                cout << Verbose(0) << "Creating connection matrix..." << endl;
    12001112                start = clock();
     
    12061118                end = clock();
    12071119                cout << Verbose(0) << "Clocks for this operation: " << (end-start) << ", time: " << ((double)(end-start)/CLOCKS_PER_SEC) << "s." << endl;
    1208                 argptr+=2;
     1120                argptr+=1;
     1121              } else {
     1122                cerr << "Not enough arguments for fragmentation: -f <max. bond distance> <bond order>" << endl;
    12091123              }
    12101124              break;
     
    12251139            case 'o':
    12261140              ExitFlag = 1;
    1227               if ((argptr >= argc) || (argv[argptr][0] == '-')){
    1228                 ExitFlag = 255;
    1229                 cerr << "Not enough or invalid arguments given for convex envelope: -o <tecplot output file>" << endl;
    1230               } else {
    1231                 cout << Verbose(0) << "Evaluating volume of the convex envelope.";
    1232                 ofstream *output = new ofstream(argv[argptr], ios::trunc);
    1233                 //$$$
    1234                 cout << Verbose(1) << "Storing tecplot data in " << argv[argptr] << "." << endl;
    1235                 VolumeOfConvexEnvelope((ofstream *)&cout, output, &configuration, NULL, mol);
    1236                 output->close();
    1237                 delete(output);
    1238                 argptr+=1;
    1239               }
     1141              SaveFlag = true;
     1142              cout << Verbose(0) << "Evaluating volume of the convex envelope.";
     1143              VolumeOfConvexEnvelope((ofstream *)&cout, &configuration, NULL, mol);
    12401144              break;
    12411145            case 'U':
    12421146              ExitFlag = 1;
    1243               if ((argptr+1 >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) ) {
    1244                 ExitFlag = 255;
    1245                 cerr << "Not enough or invalid arguments given for suspension with specified volume: -U <volume> <density>" << endl;
    1246                 volume = -1; // for case 'u': don't print error again
    1247               } else {
    1248                 volume = atof(argv[argptr++]);
    1249                 cout << Verbose(0) << "Using " << volume << " angstrom^3 as the volume instead of convex envelope one's." << endl;
    1250               }
     1147              volume = atof(argv[argptr++]);
     1148              cout << Verbose(0) << "Using " << volume << " angstrom^3 as the volume instead of convex envelope one's." << endl; 
    12511149            case 'u':
    12521150              ExitFlag = 1;
    1253               if ((argptr >= argc) || (!IsValidNumber(argv[argptr])) ) {
    1254                 if (volume != -1)
    1255                   ExitFlag = 255;
    1256                   cerr << "Not enough arguments given for suspension: -u <density>" << endl;
    1257               } else {
     1151              {
    12581152                double density;
    12591153                SaveFlag = true;
     
    12701164//                  repetition[i] = 1;
    12711165//                }
    1272                 PrepareClustersinWater((ofstream *)&cout, &configuration, mol, volume, density);  // if volume == 0, will calculate from ConvexEnvelope
     1166                PrepareClustersinWater((ofstream *)&cout, &configuration, mol, volume, density);
    12731167              }
    12741168              break;
    12751169            case 'd':
    12761170              ExitFlag = 1;
    1277               if ((argptr+2 >= argc) || (!IsValidNumber(argv[argptr])) || (!IsValidNumber(argv[argptr+1])) || (!IsValidNumber(argv[argptr+2])) ) {
    1278                 ExitFlag = 255;
    1279                 cerr << "Not enough or invalid arguments given for repeating cells: -d <repeat_x> <repeat_y> <repeat_z>" << endl;
    1280               } else {
    1281                 SaveFlag = true;
    1282                 for (int axis = 1; axis <= NDIM; axis++) {
    1283                   int faktor = atoi(argv[argptr++]);
    1284                   int count;
    1285                   element ** Elements;
    1286                   Vector ** vectors;
    1287                   if (faktor < 1) {
    1288                     cerr << Verbose(0) << "ERROR: Repetition faktor mus be greater than 1!" << endl;
    1289                     faktor = 1;
     1171              SaveFlag = true;
     1172              for (int axis = 1; axis <= NDIM; axis++) {
     1173                int faktor = atoi(argv[argptr++]);
     1174                int count;
     1175                element ** Elements;
     1176                Vector ** vectors;
     1177                if (faktor < 1) {
     1178                  cerr << Verbose(0) << "ERROR: Repetition faktor mus be greater than 1!" << endl;
     1179                  faktor = 1;
     1180                }
     1181                mol->CountAtoms((ofstream *)&cout);  // recount atoms
     1182                if (mol->AtomCount != 0) {  // if there is more than none
     1183                  count = mol->AtomCount;   // is changed becausing of adding, thus has to be stored away beforehand
     1184                  Elements = new element *[count];
     1185                  vectors = new Vector *[count];
     1186                  j = 0;
     1187                  first = mol->start;
     1188                  while (first->next != mol->end) {  // make a list of all atoms with coordinates and element
     1189                    first = first->next;
     1190                    Elements[j] = first->type;
     1191                    vectors[j] = &first->x;
     1192                    j++;
    12901193                  }
    1291                   mol->CountAtoms((ofstream *)&cout);  // recount atoms
    1292                   if (mol->AtomCount != 0) {  // if there is more than none
    1293                     count = mol->AtomCount;   // is changed becausing of adding, thus has to be stored away beforehand
    1294                     Elements = new element *[count];
    1295                     vectors = new Vector *[count];
    1296                     j = 0;
    1297                     first = mol->start;
    1298                     while (first->next != mol->end) {  // make a list of all atoms with coordinates and element
    1299                       first = first->next;
    1300                       Elements[j] = first->type;
    1301                       vectors[j] = &first->x;
    1302                       j++;
     1194                  if (count != j)
     1195                    cout << Verbose(0) << "ERROR: AtomCount " << count << " is not equal to number of atoms in molecule " << j << "!" << endl;
     1196                  x.Zero();
     1197                  y.Zero();
     1198                  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
     1199                  for (int i=1;i<faktor;i++) {  // then add this list with respective translation factor times
     1200                    x.AddVector(&y); // per factor one cell width further
     1201                    for (int k=count;k--;) { // go through every atom of the original cell
     1202                      first = new atom(); // create a new body
     1203                      first->x.CopyVector(vectors[k]);  // use coordinate of original atom
     1204                      first->x.AddVector(&x);      // translate the coordinates
     1205                      first->type = Elements[k];  // insert original element
     1206                      mol->AddAtom(first);        // and add to the molecule (which increments ElementsInMolecule, AtomCount, ...)
    13031207                    }
    1304                     if (count != j)
    1305                       cout << Verbose(0) << "ERROR: AtomCount " << count << " is not equal to number of atoms in molecule " << j << "!" << endl;
     1208                  }
     1209                  // free memory
     1210                  delete[](Elements);
     1211                  delete[](vectors);
     1212                  // correct cell size
     1213                  if (axis < 0) { // if sign was negative, we have to translate everything
    13061214                    x.Zero();
    1307                     y.Zero();
    1308                     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
    1309                     for (int i=1;i<faktor;i++) {  // then add this list with respective translation factor times
    1310                       x.AddVector(&y); // per factor one cell width further
    1311                       for (int k=count;k--;) { // go through every atom of the original cell
    1312                         first = new atom(); // create a new body
    1313                         first->x.CopyVector(vectors[k]);  // use coordinate of original atom
    1314                         first->x.AddVector(&x);      // translate the coordinates
    1315                         first->type = Elements[k];  // insert original element
    1316                         mol->AddAtom(first);        // and add to the molecule (which increments ElementsInMolecule, AtomCount, ...)
    1317                       }
    1318                     }
    1319                     // free memory
    1320                     delete[](Elements);
    1321                     delete[](vectors);
    1322                     // correct cell size
    1323                     if (axis < 0) { // if sign was negative, we have to translate everything
    1324                       x.Zero();
    1325                       x.AddVector(&y);
    1326                       x.Scale(-(faktor-1));
    1327                       mol->Translate(&x);
    1328                     }
    1329                     mol->cell_size[(abs(axis) == 2) ? 2 : ((abs(axis) == 3) ? 5 : 0)] *= faktor;
     1215                    x.AddVector(&y);
     1216                    x.Scale(-(faktor-1));
     1217                    mol->Translate(&x);
    13301218                  }
     1219                  mol->cell_size[(abs(axis) == 2) ? 2 : ((abs(axis) == 3) ? 5 : 0)] *= faktor;
    13311220                }
    13321221              }
     
    13901279  if (j == 1) return 0; // just for -v and -h options
    13911280  if (j) return j;  // something went wrong
    1392 
     1281 
    13931282  // General stuff
    13941283  if (mol->cell_size[0] == 0.) {
     
    14041293  // now the main construction loop
    14051294  cout << Verbose(0) << endl << "Now comes the real construction..." << endl;
    1406   do {
     1295  do {   
    14071296    cout << Verbose(0) << endl << endl;
    14081297    cout << Verbose(0) << "============Element list=======================" << endl;
     
    14231312    cout << Verbose(0) << "-----------------------------------------------" << endl;
    14241313    cout << Verbose(0) << "d - duplicate molecule/periodic cell" << endl;
    1425     cout << Verbose(0) << "i - realign molecule" << endl;
    1426     cout << Verbose(0) << "m - mirror all molecules" << endl;
     1314    cout << Verbose(0) << "i - realign molecule" << endl; 
     1315    cout << Verbose(0) << "m - mirror all molecules" << endl; 
    14271316    cout << Verbose(0) << "t - translate molecule by vector" << endl;
    14281317    cout << Verbose(0) << "c - scale by unit transformation" << endl;
     
    14351324    cout << Verbose(0) << "Input: ";
    14361325    cin >> choice;
    1437 
     1326   
    14381327    switch (choice) {
    14391328      default:
    14401329      case 'a': // add atom
    14411330        AddAtoms(periode, mol);
    1442         choice = 'a';
    1443         break;
    1444 
     1331        choice = 'a'; 
     1332        break;
     1333     
    14451334      case 'b': // scale a bond
    14461335        cout << Verbose(0) << "Scaling bond length between two atoms." << endl;
     
    14581347        }
    14591348        //cout << Verbose(0) << "New coordinates of Atom " << second->nr << " are: ";
    1460         //second->Output(second->type->No, 1, (ofstream *)&cout);
    1461         break;
    1462 
    1463       case 'c': // unit scaling of the metric
     1349        //second->Output(second->type->No, 1, (ofstream *)&cout);       
     1350        break;
     1351
     1352      case 'c': // unit scaling of the metric 
    14641353       cout << Verbose(0) << "Angstroem -> Bohrradius: 1.8897261\t\tBohrradius -> Angstroem: 0.52917721" << endl;
    14651354       cout << Verbose(0) << "Enter three factors: ";
     
    14721361       delete[](factor);
    14731362       break;
    1474 
     1363       
    14751364      case 'd': // duplicate the periodic cell along a given axis, given times
    14761365        cout << Verbose(0) << "State the axis [(+-)123]: ";
     
    14781367        cout << Verbose(0) << "State the factor: ";
    14791368        cin >> faktor;
    1480 
     1369       
    14811370        mol->CountAtoms((ofstream *)&cout);  // recount atoms
    14821371        if (mol->AtomCount != 0) {  // if there is more than none
     
    15191408            mol->Translate(&x);
    15201409          }
    1521           mol->cell_size[(abs(axis) == 2) ? 2 : ((abs(axis) == 3) ? 5 : 0)] *= faktor;
     1410          mol->cell_size[(abs(axis) == 2) ? 2 : ((abs(axis) == 3) ? 5 : 0)] *= faktor; 
    15221411        }
    15231412        break;
    1524 
     1413     
    15251414      case 'e': // edit each field of the configuration
    15261415       configuration.Edit(mol);
    15271416       break;
    1528 
     1417 
    15291418      case 'f':
    15301419        FragmentAtoms(mol, &configuration);
    15311420        break;
    1532 
     1421       
    15331422      case 'g': // center the atoms
    15341423        CenterAtoms(mol);
    15351424        break;
    1536 
    1537       case 'i': // align all atoms
     1425       
     1426      case 'i': // align all atoms 
    15381427        AlignAtoms(periode, mol);
    15391428        break;
     
    15461435        MirrorAtoms(mol);
    15471436        break;
    1548 
     1437       
    15491438      case 'o': // create the connection matrix
    15501439        {
     
    15671456        }
    15681457        break;
    1569 
     1458       
    15701459      case 'p': // parse and XYZ file
    15711460        cout << Verbose(0) << "Format should be XYZ with: ShorthandOfElement\tX\tY\tZ" << endl;
     
    15761465        break;
    15771466
    1578       case 'q': // quit
    1579         break;
    1580 
     1467      case 'q': // quit 
     1468        break;
     1469       
    15811470      case 'r': // remove atom
    1582         RemoveAtoms(mol);
    1583         break;
    1584 
     1471        RemoveAtoms(mol);       
     1472        break;
     1473       
    15851474      case 's': // save to config file
    15861475        SaveConfig(ConfigFileName, &configuration, periode, mol);
     
    15881477
    15891478      case 't': // translate all atoms
    1590        cout << Verbose(0) << "Enter translation vector." << endl;
     1479       cout << Verbose(0) << "Enter translation vector." << endl;       
    15911480       x.AskPosition(mol->cell_size,0);
    15921481       mol->Translate((const Vector *)&x);
    15931482       break;
    1594 
     1483 
    15951484      case 'T':
    15961485        testroutine(mol);
    15971486        break;
    1598 
     1487     
    15991488      case 'u': // change an atom's element
    16001489        first = NULL;
     
    16031492          cin >> Z;
    16041493        } while ((first = mol->FindAtom(Z)) == NULL);
    1605         cout << Verbose(0) << "New element by atomic number Z: ";
     1494        cout << Verbose(0) << "New element by atomic number Z: ";       
    16061495        cin >> Z;
    16071496        first->type = periode->FindElement(Z);
    1608         cout << Verbose(0) << "Atom " << first->nr << "'s element is " << first->type->name << "." << endl;
     1497        cout << Verbose(0) << "Atom " << first->nr << "'s element is " << first->type->name << "." << endl;   
    16091498        break;
    16101499    };
    16111500  } while (choice != 'q');
    1612 
     1501 
    16131502  // save element data base
    16141503  if (periode->StorePeriodentafel(ElementsFileName)) //ElementsFileName
  • src/config.cpp

    • Property mode changed from 100755 to 100644
    r986c80 redcda5  
    1818  configpath = (char *) MallocString(sizeof(char)*MAXSTRINGSIZE,"config constructor: mainname");
    1919  configname = (char *) MallocString(sizeof(char)*MAXSTRINGSIZE,"config constructor: mainname");
    20   ThermostatImplemented = (int *) Malloc((MaxThermostats)*(sizeof(int)), "IonsInitRead: *ThermostatImplemented");
    21   ThermostatNames = (char **) Malloc((MaxThermostats)*(sizeof(char *)), "IonsInitRead: *ThermostatNames");
    22   for (int j=0;j<MaxThermostats;j++)
    23     ThermostatNames[j] = (char *) MallocString(12*(sizeof(char)), "IonsInitRead: ThermostatNames[]");
    24   Thermostat = 4;
    25   alpha = 0.;
    26   ScaleTempStep = 25;
    27   TempFrequency = 2.5;
    2820  strcpy(mainname,"pcp");
    2921  strcpy(defaultpath,"not specified");
     
    3123  configpath[0]='\0';
    3224  configname[0]='\0';
    33   basis="3-21G";
    34  
    35 
    36   strcpy(ThermostatNames[0],"None");
    37   ThermostatImplemented[0] = 1;
    38   strcpy(ThermostatNames[1],"Woodcock");
    39   ThermostatImplemented[1] = 1;
    40   strcpy(ThermostatNames[2],"Gaussian");
    41   ThermostatImplemented[2] = 1;
    42   strcpy(ThermostatNames[3],"Langevin");
    43   ThermostatImplemented[3] = 1;
    44   strcpy(ThermostatNames[4],"Berendsen");
    45   ThermostatImplemented[4] = 1;
    46   strcpy(ThermostatNames[5],"NoseHoover");
    47   ThermostatImplemented[5] = 1;
    48 
     25 
    4926  FastParsing = false;
    5027  ProcPEGamma=8;
     
    6542  UseAddGramSch=1;
    6643  Seed=1;
     44 
    6745  MaxOuterStep=0;
    68   Deltat=0.01;
     46  Deltat=1;
    6947  OutVisStep=10;
    7048  OutSrcStep=5;
     
    11896  Free((void **)&configname, "config::~config: *configname");
    11997};
    120 
    121 /** Readin of Thermostat related values from parameter file.
    122  * \param *source parameter file
    123  */
    124 void config::InitThermostats(ifstream *source)
    125 {
    126   char *thermo = MallocString(12, "IonsInitRead: thermo");
    127   int verbose = 0;
    128 
    129   // read desired Thermostat from file along with needed additional parameters
    130   if (ParseForParameter(verbose,source,"Thermostat", 0, 1, 1, string_type, thermo, 1, optional)) {
    131     if (strcmp(thermo, ThermostatNames[0]) == 0) { // None
    132       if (ThermostatImplemented[0] == 1) {
    133         Thermostat = None;
    134       } else {
    135         cout << Verbose(1) << "Warning: " << ThermostatNames[0] << " thermostat not implemented, falling back to None." << endl;
    136         Thermostat = None;
    137       }
    138     } else if (strcmp(thermo, ThermostatNames[1]) == 0) { // Woodcock
    139       if (ThermostatImplemented[1] == 1) {
    140         Thermostat = Woodcock;
    141         ParseForParameter(verbose,source,"Thermostat", 0, 2, 1, int_type, &ScaleTempStep, 1, critical); // read scaling frequency
    142       } else {
    143         cout << Verbose(1) << "Warning: " << ThermostatNames[0] << " thermostat not implemented, falling back to None." << endl;
    144         Thermostat = None;
    145       }
    146     } else if (strcmp(thermo, ThermostatNames[2]) == 0) { // Gaussian
    147       if (ThermostatImplemented[2] == 1) {
    148         Thermostat = Gaussian;
    149         ParseForParameter(verbose,source,"Thermostat", 0, 2, 1, int_type, &ScaleTempStep, 1, critical); // read collision rate
    150       } else {
    151         cout << Verbose(1) << "Warning: " << ThermostatNames[0] << " thermostat not implemented, falling back to None." << endl;
    152         Thermostat = None;
    153       }
    154     } else if (strcmp(thermo, ThermostatNames[3]) == 0) { // Langevin
    155       if (ThermostatImplemented[3] == 1) {
    156         Thermostat = Langevin;
    157         ParseForParameter(verbose,source,"Thermostat", 0, 2, 1, double_type, &TempFrequency, 1, critical); // read gamma
    158         if (ParseForParameter(verbose,source,"Thermostat", 0, 3, 1, double_type, &alpha, 1, optional)) {
    159           cout << Verbose(2) << "Extended Stochastic Thermostat detected with interpolation coefficient " << alpha << "." << endl;
    160         } else {
    161           alpha = 1.;
    162         }
    163       } else {
    164         cout << Verbose(1) << "Warning: " << ThermostatNames[0] << " thermostat not implemented, falling back to None." << endl;
    165         Thermostat = None;
    166       }
    167     } else if (strcmp(thermo, ThermostatNames[4]) == 0) { // Berendsen
    168       if (ThermostatImplemented[4] == 1) {
    169         Thermostat = Berendsen;
    170         ParseForParameter(verbose,source,"Thermostat", 0, 2, 1, double_type, &TempFrequency, 1, critical); // read \tau_T
    171       } else {
    172         cout << Verbose(1) << "Warning: " << ThermostatNames[0] << " thermostat not implemented, falling back to None." << endl;
    173         Thermostat = None;
    174       }
    175     } else if (strcmp(thermo, ThermostatNames[5]) == 0) { // Nose-Hoover
    176       if (ThermostatImplemented[5] == 1) {
    177         Thermostat = NoseHoover;
    178         ParseForParameter(verbose,source,"Thermostat", 0, 2, 1, double_type, &HooverMass, 1, critical); // read Hoovermass
    179         alpha = 0.;
    180       } else {
    181         cout << Verbose(1) << "Warning: " << ThermostatNames[0] << " thermostat not implemented, falling back to None." << endl;
    182         Thermostat = None;
    183       }
    184     } else {
    185       cout << Verbose(1) << " Warning: thermostat name was not understood!" << endl;
    186       Thermostat = None;
    187     }
    188   } else {
    189     if ((MaxOuterStep > 0) && (TargetTemp != 0))
    190       cout << Verbose(2) <<  "No thermostat chosen despite finite temperature MD, falling back to None." << endl;
    191     Thermostat = None;
    192   }
    193   Free((void **)&thermo, "InitThermostats: thermo");
    194 };
    195 
    19698
    19799/** Displays menu for editing each entry of the config file.
     
    563465  double value[3];
    564466 
    565   InitThermostats(file);
    566  
    567467  /* Namen einlesen */
    568468
     
    1075975
    1076976/** Stores all elements of config structure from which they can be re-read.
    1077  * \param *filename name of file
     977 * \param output open output *file stream to write to
    1078978 * \param *periode pointer to a periodentafel class with all elements
    1079979 * \param *mol pointer to molecule containing all atoms of the molecule
    1080980 */
    1081 bool config::Save(const char *filename, periodentafel *periode, molecule *mol) const
     981bool config::Save(ofstream *output, periodentafel *periode, molecule *mol) const
    1082982{
    1083983  bool result = true;
    1084984        // bring MaxTypes up to date
    1085985        mol->CountElements();
    1086   ofstream *output = NULL;
    1087   output = new ofstream(filename, ios::out);
    1088986  if (output != NULL) {
    1089987    *output << "# ParallelCarParinello - main configuration file - created with molecuilder" << endl;
     
    11031001    *output << "DoFullCurrent\t" << config::DoFullCurrent << "\t# Do full perturbation" << endl;
    11041002    *output << "DoConstrainedMD\t" << config::DoConstrainedMD << "\t# Do perform a constrained (>0, relating to current MD step) instead of unconstrained (0) MD" << endl;
    1105     *output << "Thermostat\t" << ThermostatNames[Thermostat] << "\t";
    1106     switch(Thermostat) {
    1107       default:
    1108       case None:
    1109         break;
    1110       case Woodcock:
    1111         *output << ScaleTempStep;
    1112         break;
    1113       case Gaussian:
    1114         *output << ScaleTempStep;
    1115         break;
    1116       case Langevin:
    1117         *output << TempFrequency << "\t" << alpha;
    1118         break;
    1119       case Berendsen:
    1120         *output << TempFrequency;
    1121         break;
    1122       case NoseHoover:
    1123         *output << HooverMass;
    1124         break;
    1125     };
    1126     *output << "\t# Which Thermostat and its parameters to use in MD case." << endl;
    11271003    *output << "CommonWannier\t" << config::CommonWannier << "\t# Put virtual centers at indivual orbits, all common, merged by variance, to grid point, to cell center" << endl;
    11281004    *output << "SawtoothStart\t" << config::SawtoothStart << "\t# Absolute value for smooth transition at cell border " << endl;
     
    11961072    else
    11971073      result = result && mol->OutputTrajectories(output);
    1198     output->close();
    1199     output->clear();
    1200     delete(output);
    12011074    return result;
    12021075  } else
     
    12061079/** Stores all elements in a MPQC input file.
    12071080 * Note that this format cannot be parsed again.
    1208  * \param *filename name of file (without ".in" suffix!)
     1081 * \param output open output *file stream to write to
    12091082 * \param *mol pointer to molecule containing all atoms of the molecule
    12101083 */
    1211 bool config::SaveMPQC(const char *filename, molecule *mol) const
     1084bool config::SaveMPQC(ofstream *output, molecule *mol) const
    12121085{
    12131086  int ElementNo = 0;
    12141087  int AtomNo;
    12151088  atom *Walker = NULL;
    1216   element *runner = NULL;
     1089  element *runner = mol->elemente->start;
    12171090  Vector *center = NULL;
    1218   ofstream *output = NULL;
    1219   stringstream *fname = NULL;
    1220  
    1221   // first without hessian
    1222   fname = new stringstream;
    1223   *fname << filename << ".in";
    1224   output = new ofstream(fname->str().c_str(), ios::out);
     1091
    12251092  *output << "% Created by MoleCuilder" << endl;
    12261093  *output << "mpqc: (" << endl;
     
    12281095  *output << "\tdo_gradient = yes" << endl;
    12291096  *output << "\tmole<CLHF>: (" << endl;
    1230   *output << "\t\tmaxiter = 200" << endl;
    1231   *output << "\t\tbasis = $:basis" << endl;
    1232   *output << "\t\tmolecule = $:molecule" << endl;
    1233   *output << "\t)" << endl;
    1234   *output << ")" << endl;
    1235   *output << "molecule<Molecule>: (" << endl;
    1236   *output << "\tunit = " << (IsAngstroem ? "angstrom" : "bohr" ) << endl;
    1237   *output << "\t{ atoms geometry } = {" << endl;
     1097  *output << "\t\tmolecule<Molecule>: (" << endl;
     1098  *output << "\t\t\tunit = " << (IsAngstroem ? "angstrom" : "bohr" ) << endl;
     1099  *output << "\t\t\t{ atoms geometry } = {" << endl;
    12381100  center = mol->DetermineCenterOfAll(output);
    12391101  // output of atoms
    1240   runner = mol->elemente->start;
    12411102  while (runner->next != mol->elemente->end) { // go through every element
    12421103    runner = runner->next;
     
    12491110        if (Walker->type == runner) { // if this atom fits to element
    12501111          AtomNo++;
    1251           *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;
     1112          *output << "\t\t\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;
    12521113        }
    12531114      }
     
    12551116  }
    12561117  delete(center);
    1257   *output << "\t}" << endl;
    1258   *output << ")" << endl;
    1259   *output << "basis<GaussianBasisSet>: (" << endl;
    1260   *output << "\tname = \"" << basis << "\"" << endl;
    1261   *output << "\tmolecule = $:molecule" << endl;
    1262   *output << ")" << endl;
    1263   output->close();
    1264   delete(output);
    1265   delete(fname);
    1266 
    1267   // second with hessian
    1268   fname = new stringstream;
    1269   *fname << filename << ".hess.in";
    1270   output = new ofstream(fname->str().c_str(), ios::out);
    1271   *output << "% Created by MoleCuilder" << endl;
    1272   *output << "mpqc: (" << endl;
    1273   *output << "\tsavestate = no" << endl;
    1274   *output << "\tdo_gradient = yes" << endl;
    1275   *output << "\tmole<CLHF>: (" << endl;
    1276   *output << "\t\tmaxiter = 200" << endl;
    1277   *output << "\t\tbasis = $:basis" << endl;
    1278   *output << "\t\tmolecule = $:molecule" << endl;
    1279   *output << "\t)" << endl;
    1280   *output << "\tfreq<MolecularFrequencies>: (" << endl;
    1281   *output << "\t\tmolecule=$:molecule" << endl;
     1118  *output << "\t\t\t}" << endl;
     1119  *output << "\t\t)" << endl;
     1120  *output << "\t\tbasis<GaussianBasisSet>: (" << endl;
     1121  *output << "\t\t\tname = \"STO-3G\"" << endl;
     1122  *output << "\t\t\tmolecule = $:mpqc:mole:molecule" << endl;
     1123  *output << "\t\t)" << endl;
    12821124  *output << "\t)" << endl;
    12831125  *output << ")" << endl;
    1284   *output << "molecule<Molecule>: (" << endl;
    1285   *output << "\tunit = " << (IsAngstroem ? "angstrom" : "bohr" ) << endl;
    1286   *output << "\t{ atoms geometry } = {" << endl;
    1287   center = mol->DetermineCenterOfAll(output);
    1288   // output of atoms
    1289   runner = mol->elemente->start;
    1290   while (runner->next != mol->elemente->end) { // go through every element
    1291     runner = runner->next;
    1292     if (mol->ElementsInMolecule[runner->Z]) { // if this element got atoms
    1293       ElementNo++;
    1294       AtomNo = 0;
    1295       Walker = mol->start;
    1296       while (Walker->next != mol->end) { // go through every atom of this element
    1297         Walker = Walker->next;
    1298         if (Walker->type == runner) { // if this atom fits to element
    1299           AtomNo++;
    1300           *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;
    1301         }
    1302       }
    1303     }
    1304   }
    1305   delete(center);
    1306   *output << "\t}" << endl;
    1307   *output << ")" << endl;
    1308   *output << "basis<GaussianBasisSet>: (" << endl;
    1309   *output << "\tname = \"3-21G\"" << endl;
    1310   *output << "\tmolecule = $:molecule" << endl;
    1311   *output << ")" << endl;
    1312   output->close();
    1313   delete(output);
    1314   delete(fname);
    1315  
    13161126  return true;
    13171127};
  • src/datacreator.cpp

    • Property mode changed from 100755 to 100644
    r986c80 redcda5  
    2929};
    3030
    31 /** Opens a file for appending with \a *filename in \a *dir.
    32  * \param output file handle on return
    33  * \param *dir directory
    34  * \param *filename name of file
    35  * \return true if file has been opened
    36  */
    37 bool AppendOutputFile(ofstream &output, const char *dir, const char *filename)
    38 {
    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;
    47 };
    48 
    4931/** Plots an energy vs. order.
    5032 * \param &Fragments EnergyMatrix class containing matrix values
     
    6345  cout << msg << endl;
    6446  output << "# " << msg << ", created on " << datum;
    65   output << "#Order\tFrag.No.\t" << Fragments.Header[Fragments.MatrixCounter] << endl;
     47  output << "#Order\tFrag.No.\t" << Fragments.Header << endl;
    6648  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
    6749    for(int i=KeySet.FragmentsPerOrder[BondOrder];i--;) {
    6850      for(int j=Fragments.RowCounter[ KeySet.OrderSet[BondOrder][i] ];j--;)
    69         for(int k=Fragments.ColumnCounter[ KeySet.OrderSet[BondOrder][i] ];k--;)
     51        for(int k=Fragments.ColumnCounter;k--;)
    7052          Fragments.Matrix[Fragments.MatrixCounter][j][k] += Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k];
    7153    }
    7254    output << BondOrder+1 << "\t" << KeySet.FragmentsPerOrder[BondOrder];
    73     for (int l=0;l<Fragments.ColumnCounter[Fragments.MatrixCounter];l++)
     55    for (int l=0;l<Fragments.ColumnCounter;l++)
    7456      output << scientific << "\t" << Fragments.Matrix[Fragments.MatrixCounter][ Fragments.RowCounter[Fragments.MatrixCounter]-1 ][l];
    7557    output << endl;
     
    9678  cout << msg << endl;
    9779  output << "# " << msg << ", created on " << datum;
    98   output << "#Order\tFrag.No.\t" << Fragments.Header[Fragments.MatrixCounter] << endl;
     80  output << "#Order\tFrag.No.\t" << Fragments.Header << endl;
    9981  Fragments.SetLastMatrix(Energy.Matrix[Energy.MatrixCounter],0);
    10082  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
    10183    for(int i=KeySet.FragmentsPerOrder[BondOrder];i--;) {
    10284      for(int j=Fragments.RowCounter[ KeySet.OrderSet[BondOrder][i] ];j--;)
    103         for(int k=Fragments.ColumnCounter[ KeySet.OrderSet[BondOrder][i] ];k--;)
     85        for(int k=Fragments.ColumnCounter;k--;)
    10486          Fragments.Matrix[Fragments.MatrixCounter][j][k] -= Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k];
    10587    }
    10688    output << BondOrder+1 << "\t" << KeySet.FragmentsPerOrder[BondOrder];
    107     for (int l=0;l<Fragments.ColumnCounter[Energy.MatrixCounter];l++)
     89    for (int l=0;l<Fragments.ColumnCounter;l++)
    10890      if (fabs(Energy.Matrix[Energy.MatrixCounter][ Energy.RowCounter[Energy.MatrixCounter]-1 ][l]) < MYEPSILON)
    10991        output << scientific << "\t" << Fragments.Matrix[Fragments.MatrixCounter][ Fragments.RowCounter[Fragments.MatrixCounter]-1 ][l];
     
    133115  cout << msg << endl;
    134116  output << "# " << msg << ", created on " << datum;
    135   output << "# Order\tFrag.No.\t" << Fragments.Header[Fragments.MatrixCounter] << endl;
     117  output << "# Order\tFrag.No.\t" << Fragments.Header << endl;
    136118  Fragments.SetLastMatrix(0.,0);
    137119  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
     
    139121    output << BondOrder+1 << "\t" << KeySet.FragmentsPerOrder[BondOrder];
    140122    CreateForce(Fragments, Fragments.MatrixCounter);
    141     for (int l=0;l<Fragments.ColumnCounter[Fragments.MatrixCounter];l++)
     123    for (int l=0;l<Fragments.ColumnCounter;l++)
    142124       output << scientific << "\t" << Fragments.Matrix[Fragments.MatrixCounter][ Fragments.RowCounter[Fragments.MatrixCounter] ][l];
    143125    output << endl;
     
    165147  cout << msg << endl;
    166148  output << "# " << msg << ", created on " << datum;
    167   output << "# Order\tFrag.No.\t" << Fragments.Header[Fragments.MatrixCounter] << endl;
     149  output << "# Order\tFrag.No.\t" << Fragments.Header << endl;
    168150  Fragments.SetLastMatrix(Force.Matrix[Force.MatrixCounter],0);
    169151  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
     
    171153    output << BondOrder+1 << "\t" << KeySet.FragmentsPerOrder[BondOrder];
    172154    CreateForce(Fragments, Fragments.MatrixCounter);
    173     for (int l=0;l<Fragments.ColumnCounter[Fragments.MatrixCounter];l++)
     155    for (int l=0;l<Fragments.ColumnCounter;l++)
    174156       output << scientific << "\t" << Fragments.Matrix[Fragments.MatrixCounter][ Fragments.RowCounter[Fragments.MatrixCounter] ][l];
    175157    output << endl;
     
    198180  cout << msg << endl;
    199181  output << "# " << msg << ", created on " << datum;
    200   output << "# AtomNo\t" << Fragments.Header[Fragments.MatrixCounter] << endl;
     182  output << "# AtomNo\t" << Fragments.Header << endl;
    201183  Fragments.SetLastMatrix(Force.Matrix[Force.MatrixCounter], 0);
    202184  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
     
    204186    Fragments.SumSubForces(Fragments, KeySet, BondOrder, -1.);
    205187    // errors per atom
    206     output << endl << "#Order\t" << BondOrder+1 << endl;
     188    output << "#Order\t" << BondOrder+1 << endl;
    207189    for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) {
    208190      output << Fragments.Indices[Fragments.MatrixCounter][j] << "\t";
    209       for (int l=0;l<Fragments.ColumnCounter[ Fragments.MatrixCounter ];l++) {
     191      for (int l=0;l<Fragments.ColumnCounter;l++) {
    210192        if (((l+1) % 3) == 0) {
    211193          norm = 0.;
     
    244226  cout << msg << endl;
    245227  output << "# " << msg << ", created on " << datum;
    246   output << "# AtomNo\t" << Fragments.Header[Fragments.MatrixCounter] << endl;
     228  output << "# AtomNo\t" << Fragments.Header << endl;
    247229  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
    248230    //cout << "Current order is " << BondOrder << "." << endl;
    249231    Fragments.SumSubForces(Fragments, KeySet, BondOrder, 1.);
    250232    // errors per atom
    251     output << endl << "#Order\t" << BondOrder+1 << endl;
     233    output << "#Order\t" << BondOrder+1 << endl;
    252234    for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) {
    253235      output << Fragments.Indices[Fragments.MatrixCounter][j] << "\t";
    254       for (int l=0;l<Fragments.ColumnCounter[ Fragments.MatrixCounter ];l++)
     236      for (int l=0;l<Fragments.ColumnCounter;l++)
    255237        output << scientific << Fragments.Matrix[Fragments.MatrixCounter][ j ][l] << "\t";
    256238      output << endl;
     
    262244};
    263245
    264 
    265 /** Plot hessian error vs. vs atom vs. order.
    266  * \param &Hessian HessianMatrix containing reference values (in MatrixCounter matrix)
    267  * \param &Fragments HessianMatrix class containing matrix values
    268  * \param KeySet KeySetContainer class holding bond KeySetContainer::Order
    269  * \param *prefix prefix in filename (without ending)
    270  * \param *msg message to be place in first line as a comment
    271  * \param *datum current date and time
    272  * \return true if file was written successfully
    273  */
    274 bool CreateDataDeltaHessianOrderPerAtom(class HessianMatrix &Hessian, class HessianMatrix &Fragments, class KeySetsContainer &KeySet, char *dir, char *prefix, char *msg, char *datum)
    275 {
    276   stringstream filename;
    277   ofstream output;
    278 
    279   filename << prefix << ".dat";
    280   if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
    281   cout << msg << endl;
    282   output << "# " << msg << ", created on " << datum;
    283   output << "# AtomNo\t" << Fragments.Header[Fragments.MatrixCounter] << endl;
    284   Fragments.SetLastMatrix(Hessian.Matrix[Hessian.MatrixCounter], 0);
    285   for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
    286     //cout << "Current order is " << BondOrder << "." << endl;
    287     Fragments.SumSubHessians(Fragments, KeySet, BondOrder, -1.);
    288     // errors per atom
    289     output << endl << "#Order\t" << BondOrder+1 << endl;
    290     for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) {
    291       output << Fragments.Indices[Fragments.MatrixCounter][j] << "\t";
    292       for (int l=0;l<Fragments.ColumnCounter[ Fragments.MatrixCounter ];l++) {
    293         output << scientific << Fragments.Matrix[Fragments.MatrixCounter][ j ][l] << "\t";
    294       }
    295       output << endl;
    296     }
    297     output << endl;
    298   }
    299   output.close();
    300   return true;
    301 };
    302 
    303 /** Plot hessian error vs. vs atom vs. order in the frobenius norm.
    304  * \param &Hessian HessianMatrix containing reference values (in MatrixCounter matrix)
    305  * \param &Fragments HessianMatrix class containing matrix values
    306  * \param KeySet KeySetContainer class holding bond KeySetContainer::Order
    307  * \param *prefix prefix in filename (without ending)
    308  * \param *msg message to be place in first line as a comment
    309  * \param *datum current date and time
    310  * \return true if file was written successfully
    311  */
    312 bool CreateDataDeltaFrobeniusOrderPerAtom(class HessianMatrix &Hessian, class HessianMatrix &Fragments, class KeySetsContainer &KeySet, char *dir, char *prefix, char *msg, char *datum)
    313 {
    314   stringstream filename;
    315   ofstream output;
    316   double norm = 0;
    317   double tmp;
    318 
    319   filename << prefix << ".dat";
    320   if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
    321   cout << msg << endl;
    322   output << "# " << msg << ", created on " << datum;
    323   output << "# AtomNo\t";
    324   Fragments.SetLastMatrix(Hessian.Matrix[Hessian.MatrixCounter], 0);
    325   for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
    326     output << "Order" << BondOrder+1 << "\t";
    327   }
    328   output << endl;
    329   output << Fragments.RowCounter[ Fragments.MatrixCounter ] << "\t";
    330   for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
    331     //cout << "Current order is " << BondOrder << "." << endl;
    332     Fragments.SumSubHessians(Fragments, KeySet, BondOrder, -1.);
    333     // frobenius norm of errors per atom
    334     norm = 0.;
    335     for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) {
    336       for (int l=0;l<Fragments.ColumnCounter[ Fragments.MatrixCounter ];l++) {
    337         tmp = Fragments.Matrix[Fragments.MatrixCounter][ j ][l];
    338         norm += tmp*tmp;
    339       }
    340     }
    341     output << scientific << sqrt(norm)/(Fragments.RowCounter[ Fragments.MatrixCounter ]*Fragments.ColumnCounter[ Fragments.MatrixCounter] ) << "\t";
    342   }
    343   output << endl;
    344   output.close();
    345   return true;
    346 };
    347 
    348 /** Plot hessian error vs. vs atom vs. order.
    349  * \param &Fragments HessianMatrix class containing matrix values
    350  * \param KeySet KeySetContainer class holding bond KeySetContainer::Order
    351  * \param *prefix prefix in filename (without ending)
    352  * \param *msg message to be place in first line as a comment
    353  * \param *datum current date and time
    354  * \return true if file was written successfully
    355  */
    356 bool CreateDataHessianOrderPerAtom(class HessianMatrix &Fragments, class KeySetsContainer &KeySet, char *dir, char *prefix, char *msg, char *datum)
    357 {
    358   stringstream filename;
    359   ofstream output;
    360 
    361   filename << prefix << ".dat";
    362   if (!OpenOutputFile(output, dir, filename.str().c_str())) return false;
    363   cout << msg << endl;
    364   output << "# " << msg << ", created on " << datum;
    365   output << "# AtomNo\t" << Fragments.Header[ Fragments.MatrixCounter ] << endl;
    366   Fragments.SetLastMatrix(0., 0);
    367   for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
    368     //cout << "Current order is " << BondOrder << "." << endl;
    369     Fragments.SumSubHessians(Fragments, KeySet, BondOrder, 1.);
    370     // errors per atom
    371     output << endl << "#Order\t" << BondOrder+1 << endl;
    372     for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) {
    373       output << Fragments.Indices[Fragments.MatrixCounter][j] << "\t";
    374       for (int l=0;l<Fragments.ColumnCounter[ Fragments.MatrixCounter ];l++)
    375         output << scientific << Fragments.Matrix[Fragments.MatrixCounter][ j ][l] << "\t";
    376       output << endl;
    377     }
    378     output << endl;
    379   }
    380   output.close();
    381   return true;
    382 };
    383 
    384246/** Plot matrix vs. fragment.
    385247 */
     
    393255  cout << msg << endl;
    394256  output << "# " << msg << ", created on " << datum << endl;
    395   output << "#Order\tFrag.No.\t" << Fragment.Header[ Fragment.MatrixCounter ] << endl;
     257  output << "#Order\tFrag.No.\t" << Fragment.Header << endl;
    396258  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
    397259    for(int i=0;i<KeySet.FragmentsPerOrder[BondOrder];i++) {
    398260      output << BondOrder+1 << "\t" << KeySet.OrderSet[BondOrder][i]+1;
    399261      CreateFragment(Fragment, KeySet.OrderSet[BondOrder][i]);
    400       for (int l=0;l<Fragment.ColumnCounter[ KeySet.OrderSet[BondOrder][i] ];l++)
     262      for (int l=0;l<Fragment.ColumnCounter;l++)
    401263        output << scientific << "\t" << Fragment.Matrix[ KeySet.OrderSet[BondOrder][i] ][ Fragment.RowCounter[ KeySet.OrderSet[BondOrder][i] ] ][l];
    402264      output << endl;
     
    417279    for(int i=KeySet.FragmentsPerOrder[BondOrder];i--;) {
    418280      if (fabs(Fragments.Matrix[ Fragments.MatrixCounter ][j][1]) < fabs(Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][1])) {
    419         for (int k=Fragments.ColumnCounter[ Fragments.MatrixCounter ];k--;)
     281        for (int k=Fragments.ColumnCounter;k--;)
    420282          Fragments.Matrix[ Fragments.MatrixCounter ][j][k] = Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k];
    421283      }
     
    434296    int i=0;
    435297    do {  // first get a minimum value unequal to 0
    436       for (int k=Fragments.ColumnCounter[ Fragments.MatrixCounter ];k--;)
     298      for (int k=Fragments.ColumnCounter;k--;)
    437299        Fragments.Matrix[ Fragments.MatrixCounter ][j][k] = Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k];
    438300      i++;
     
    440302    for(;i<KeySet.FragmentsPerOrder[BondOrder];i++) { // then find lowest
    441303      if (fabs(Fragments.Matrix[ Fragments.MatrixCounter ][j][1]) > fabs(Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][1])) {
    442         for (int k=Fragments.ColumnCounter[ Fragments.MatrixCounter ];k--;)
     304        for (int k=Fragments.ColumnCounter;k--;)
    443305          Fragments.Matrix[ Fragments.MatrixCounter ][j][k] = Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k];
    444306      }
     
    458320  cout << msg << endl;
    459321  output << "# " << msg << ", created on " << datum;
    460   output << "#Order\tFrag.No.\t" << Fragment.Header[ Fragment.MatrixCounter ] << endl;
     322  output << "#Order\tFrag.No.\t" << Fragment.Header << endl;
    461323  // max
    462324  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
     
    464326    CreateFragmentOrder(Fragment, KeySet, BondOrder);
    465327    output << BondOrder+1 << "\t" << KeySet.FragmentsPerOrder[BondOrder];
    466     for (int l=0;l<Fragment.ColumnCounter[ Fragment.MatrixCounter ];l++)
     328    for (int l=0;l<Fragment.ColumnCounter;l++)
    467329      output << scientific << "\t" << Fragment.Matrix[ Fragment.MatrixCounter ][ Fragment.RowCounter[ Fragment.MatrixCounter ]-1 ][l];
    468330    output << endl;
     
    478340void CreateEnergy(class MatrixContainer &Energy, int MatrixNumber)
    479341{
    480   for(int k=0;k<Energy.ColumnCounter[MatrixNumber];k++)
     342  for(int k=0;k<Energy.ColumnCounter;k++)
    481343    Energy.Matrix[MatrixNumber][ Energy.RowCounter[MatrixNumber] ] [k] =  Energy.Matrix[MatrixNumber][ Energy.RowCounter[MatrixNumber]-1 ] [k];
    482344};
     
    489351void CreateMinimumForce(class MatrixContainer &Force, int MatrixNumber)
    490352{
    491   for (int l=Force.ColumnCounter[MatrixNumber];l--;)
     353  for (int l=Force.ColumnCounter;l--;)
    492354    Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l] = 0.;
    493   for (int l=5;l<Force.ColumnCounter[MatrixNumber];l+=3) {
     355  for (int l=5;l<Force.ColumnCounter;l+=3) {
    494356    double stored = 0;
    495357    int k=0;
     
    524386{
    525387  int divisor = 0;
    526   for (int l=Force.ColumnCounter[MatrixNumber];l--;)
     388  for (int l=Force.ColumnCounter;l--;)
    527389    Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l] = 0.;
    528   for (int l=5;l<Force.ColumnCounter[MatrixNumber];l+=3) {
     390  for (int l=5;l<Force.ColumnCounter;l+=3) {
    529391    double tmp = 0;
    530392    for (int k=Force.RowCounter[MatrixNumber];k--;) {
     
    548410void CreateMaximumForce(class MatrixContainer &Force, int MatrixNumber)
    549411{
    550   for (int l=5;l<Force.ColumnCounter[MatrixNumber];l+=3) {
     412  for (int l=5;l<Force.ColumnCounter;l+=3) {
    551413    double stored = 0;
    552414    for (int k=Force.RowCounter[MatrixNumber];k--;) {
     
    580442void CreateVectorSumForce(class MatrixContainer &Force, int MatrixNumber)
    581443{
    582   for (int l=Force.ColumnCounter[MatrixNumber];l--;)
     444  for (int l=Force.ColumnCounter;l--;)
    583445    Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l] = 0.;
    584   for (int l=0;l<Force.ColumnCounter[MatrixNumber];l++) {
     446  for (int l=0;l<Force.ColumnCounter;l++) {
    585447    for (int k=Force.RowCounter[MatrixNumber];k--;)
    586448      Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l] += Force.Matrix[MatrixNumber][k][l];
     
    658520void AbsEnergyPlotLine(ofstream &output, class MatrixContainer &Energy, const char *prefix, const char *xargument, const char *uses)
    659521{
    660   stringstream line(Energy.Header[ Energy.MatrixCounter ]);
     522  stringstream line(Energy.Header);
    661523  string token;
    662524
    663525  getline(line, token, '\t');
    664   for (int i=2; i<= Energy.ColumnCounter[Energy.MatrixCounter];i++) {
     526  for (int i=2; i<= Energy.ColumnCounter;i++) {
    665527    getline(line, token, '\t');
    666528    while (token[0] == ' ') // remove leading white spaces
    667529      token.erase(0,1);
    668530    output << "'" << prefix << ".dat' title '" << token << "' using " << xargument << ":(abs($" << i+2 << ")) " << uses;
    669     if (i != (Energy.ColumnCounter[Energy.MatrixCounter]))
     531    if (i != (Energy.ColumnCounter))
    670532      output << ", \\";
    671533    output << endl;
     
    682544void EnergyPlotLine(ofstream &output, class MatrixContainer &Energy, const char *prefix, const char *xargument, const char *uses)
    683545{
    684   stringstream line(Energy.Header[Energy.MatrixCounter]);
     546  stringstream line(Energy.Header);
    685547  string token;
    686548
    687549  getline(line, token, '\t');
    688   for (int i=1; i<= Energy.ColumnCounter[Energy.MatrixCounter];i++) {
     550  for (int i=1; i<= Energy.ColumnCounter;i++) {
    689551    getline(line, token, '\t');
    690552    while (token[0] == ' ') // remove leading white spaces
    691553      token.erase(0,1);
    692554    output << "'" << prefix << ".dat' title '" << token << "' using " << xargument << ":" << i+2 << " " << uses;
    693     if (i != (Energy.ColumnCounter[Energy.MatrixCounter]))
     555    if (i != (Energy.ColumnCounter))
    694556      output << ", \\";
    695557    output << endl;
     
    706568void ForceMagnitudePlotLine(ofstream &output, class MatrixContainer &Force, const char *prefix, const char *xargument, const char *uses)
    707569{
    708   stringstream line(Force.Header[Force.MatrixCounter]);
     570  stringstream line(Force.Header);
    709571  string token;
    710572
     
    714576  getline(line, token, '\t');
    715577  getline(line, token, '\t');
    716   for (int i=7; i< Force.ColumnCounter[Force.MatrixCounter];i+=NDIM) {
     578  for (int i=7; i< Force.ColumnCounter;i+=NDIM) {
    717579    getline(line, token, '\t');
    718580    while (token[0] == ' ') // remove leading white spaces
     
    720582    token.erase(token.length(), 1);  // kill residual index char (the '0')
    721583    output << "'" << prefix << ".dat' title '" << token << "' using " << xargument << ":(sqrt($" << i+1 << "*$" << i+1 << "+$" << i+2 << "*$" << i+2 << "+$" << i+3 << "*$" << i+3 << ")) " << uses;
    722     if (i != (Force.ColumnCounter[Force.MatrixCounter]-1))
     584    if (i != (Force.ColumnCounter-1))
    723585      output << ", \\";
    724586    output << endl;
     
    737599void AbsFirstForceValuePlotLine(ofstream &output, class MatrixContainer &Force, const char *prefix, const char *xargument, const char *uses)
    738600{
    739   stringstream line(Force.Header[Force.MatrixCounter]);
     601  stringstream line(Force.Header);
    740602  string token;
    741603
     
    745607  getline(line, token, '\t');
    746608  getline(line, token, '\t');
    747   for (int i=7; i< Force.ColumnCounter[Force.MatrixCounter];i+=NDIM) {
     609  for (int i=7; i< Force.ColumnCounter;i+=NDIM) {
    748610    getline(line, token, '\t');
    749611    while (token[0] == ' ') // remove leading white spaces
     
    751613    token.erase(token.length(), 1);  // kill residual index char (the '0')
    752614    output << "'" << prefix << ".dat' title '" << token << "' using " << xargument << ":(abs($" << i+1 << ")) " << uses;
    753     if (i != (Force.ColumnCounter[Force.MatrixCounter]-1))
     615    if (i != (Force.ColumnCounter-1))
    754616      output << ", \\";
    755617    output << endl;
     
    768630void BoxesForcePlotLine(ofstream &output, class MatrixContainer &Force, const char *prefix, const char *xargument, const char *uses)
    769631{
    770   stringstream line(Force.Header[Force.MatrixCounter]);
     632  stringstream line(Force.Header);
    771633  char *fillcolor[5] = {"black", "red", "blue", "green", "cyan"};
    772634  string token;
     
    777639  getline(line, token, '\t');
    778640  getline(line, token, '\t');
    779   for (int i=7; i< Force.ColumnCounter[Force.MatrixCounter];i+=NDIM) {
     641  for (int i=7; i< Force.ColumnCounter;i+=NDIM) {
    780642    getline(line, token, '\t');
    781643    while (token[0] == ' ') // remove leading white spaces
     
    783645    token.erase(token.length(), 1);  // kill residual index char (the '0')
    784646    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];
    785     if (i != (Force.ColumnCounter[Force.MatrixCounter]-1))
     647    if (i != (Force.ColumnCounter-1))
    786648      output << ", \\";
    787649    output << endl;
     
    800662void BoxesFirstForceValuePlotLine(ofstream &output, class MatrixContainer &Force, const char *prefix, const char *xargument, const char *uses)
    801663{
    802   stringstream line(Force.Header[Force.MatrixCounter]);
     664  stringstream line(Force.Header);
    803665  char *fillcolor[5] = {"black", "red", "blue", "green", "cyan"};
    804666  string token;
     
    809671  getline(line, token, '\t');
    810672  getline(line, token, '\t');
    811   for (int i=7; i< Force.ColumnCounter[Force.MatrixCounter];i+=NDIM) {
     673  for (int i=7; i< Force.ColumnCounter;i+=NDIM) {
    812674    getline(line, token, '\t');
    813675    while (token[0] == ' ') // remove leading white spaces
     
    815677    token.erase(token.length(), 1);  // kill residual index char (the '0')
    816678    output << "'" << prefix << ".dat' title '" << token << "' using ($" << xargument << "+" << fixed << setprecision(1) << (double)((i-7)/3)*0.2 << "):" << i+1 << " " << uses << " " << fillcolor[(i-7)/3];
    817     if (i != (Force.ColumnCounter[Force.MatrixCounter]-1))
     679    if (i != (Force.ColumnCounter-1))
    818680      output << ", \\";
    819681    output << endl;
  • src/datacreator.hpp

    • Property mode changed from 100755 to 100644
    r986c80 redcda5  
    1818
    1919bool OpenOutputFile(ofstream &output, const char *dir, const char *filename);
    20 bool AppendOutputFile(ofstream &output, const char *dir, const char *filename);
    2120
    2221bool CreateDataEnergyOrder(class EnergyMatrix &Fragments, class KeySetsContainer &KeySet, char *dir, char *prefix, char *msg, char *datum);
     
    2625bool CreateDataDeltaForcesOrder(class ForceMatrix &Force, class ForceMatrix &Fragments, class KeySetsContainer &KeySet, char *dir, char *prefix, char *msg, char *datum, void (*CreateForce)(class MatrixContainer &, int));
    2726bool CreateDataDeltaForcesOrderPerAtom(class ForceMatrix &Force, class ForceMatrix &Fragments, class KeySetsContainer &KeySet, char *dir, char *prefix, char *msg, char *datum);
    28 bool CreateDataHessianOrderPerAtom(class HessianMatrix &Fragments, class KeySetsContainer &KeySet, char *dir, char *prefix, char *msg, char *datum);
    29 bool CreateDataDeltaHessianOrderPerAtom(class HessianMatrix &Hessian, class HessianMatrix &Fragments, class KeySetsContainer &KeySet, char *dir, char *prefix, char *msg, char *datum);
    30 bool CreateDataDeltaFrobeniusOrderPerAtom(class HessianMatrix &Hessian, class HessianMatrix &Fragments, class KeySetsContainer &KeySet, char *dir, char *prefix, char *msg, char *datum);
    3127bool CreateDataFragment(class MatrixContainer &ForceFragments, class KeySetsContainer &KeySet, char *dir, char *prefix, char *msg, char *datum, void (*CreateForce)(class MatrixContainer &, int));
    3228bool CreateDataFragmentOrder(class MatrixContainer &Fragment, class KeySetsContainer &KeySet, char *dir, char *prefix, char *msg, char *datum, void (*CreateFragmentOrder)(class MatrixContainer &, class KeySetsContainer &, int));
  • src/defs.hpp

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

    • Property mode changed from 100755 to 100644
  • src/elements.db

    • Property mode changed from 100755 to 100644
  • src/graph.cpp

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

    • Property mode changed from 100755 to 100644
    r986c80 redcda5  
    182182};
    183183
    184 /** Tests whether a given string contains a valid number or not.
    185  * \param *string
    186  * \return true - is a number, false - is not a valid number
    187  */
    188 bool IsValidNumber( const char *string)
    189 {
    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;
    196 };
    197 
    198 
  • src/helpers.hpp

    • Property mode changed from 100755 to 100644
    r986c80 redcda5  
    5959void Free(void ** buffer, const char* output);
    6060char *FixedDigitNumber(const int FragmentNumber, const int digits);
    61 bool IsValidNumber( const char *string);
    6261
    6362/********************************************** helpful template functions *********************************/
  • src/joiner.cpp

    • Property mode changed from 100755 to 100644
    r986c80 redcda5  
    1919  periodentafel *periode = NULL; // and a period table of all elements
    2020  EnergyMatrix Energy;
     21  EnergyMatrix Hcorrection;
     22  ForceMatrix Force;
    2123  EnergyMatrix EnergyFragments;
    22  
    23   EnergyMatrix Hcorrection;
    2424  EnergyMatrix HcorrectionFragments;
    25  
    26   ForceMatrix Force;
    2725  ForceMatrix ForceFragments;
    28 
    29   HessianMatrix Hessian;
    30   HessianMatrix HessianFragments;
    31  
    3226  ForceMatrix Shielding;
    3327  ForceMatrix ShieldingPAS;
    3428  ForceMatrix ShieldingFragments;
    3529  ForceMatrix ShieldingPASFragments;
    36   ForceMatrix Chi;
    37   ForceMatrix ChiPAS;
    38   ForceMatrix ChiFragments;
    39   ForceMatrix ChiPASFragments;
    4030  KeySetsContainer KeySet; 
    4131  stringstream prefix;
    4232  char *dir = NULL;
    43   bool NoHCorrection = false;
    44   bool NoHessian = false;
     33  bool Hcorrected = true;
    4534
    4635  cout << "Joiner" << endl;
     
    7261  // ------------- Parse through all Fragment subdirs --------
    7362  if (!Energy.ParseFragmentMatrix(argv[1], dir, EnergySuffix, 0,0)) return 1;
    74   if (!Hcorrection.ParseFragmentMatrix(argv[1], "", HCORRECTIONSUFFIX, 0,0)) {
    75     NoHCorrection = true;
    76     cout << "No HCorrection matrices found, skipping these." << endl;
    77   }
     63  Hcorrected = Hcorrection.ParseFragmentMatrix(argv[1], "", HCORRECTIONSUFFIX, 0,0);
    7864  if (!Force.ParseFragmentMatrix(argv[1], dir, ForcesSuffix, 0,0)) return 1;
    79   if (!Hessian.ParseFragmentMatrix(argv[1], dir, HessianSuffix, 0,0)) {
    80     NoHessian = true;
    81     cout << "No hessian matrices found, skipping these." << endl;
    82   }
    8365  if (periode != NULL) { // also look for PAS values
    8466    if (!Shielding.ParseFragmentMatrix(argv[1], dir, ShieldingSuffix, 1, 0)) return 1;
    8567    if (!ShieldingPAS.ParseFragmentMatrix(argv[1], dir, ShieldingPASSuffix, 1, 0)) return 1;
    86     if (!Chi.ParseFragmentMatrix(argv[1], dir, ChiSuffix, 1, 0)) return 1;
    87     if (!ChiPAS.ParseFragmentMatrix(argv[1], dir, ChiPASSuffix, 1, 0)) return 1;
    8868  }
    8969
    9070  // ---------- Parse the TE Factors into an array -----------------
    91   if (!Energy.InitialiseIndices()) return 1;
    92   if (!NoHCorrection)
    93     Hcorrection.InitialiseIndices();
     71  if (!Energy.ParseIndices()) return 1;
     72  if (Hcorrected) Hcorrection.ParseIndices();
    9473 
    9574  // ---------- Parse the Force indices into an array ---------------
    9675  if (!Force.ParseIndices(argv[1])) return 1;
    97 
    98   // ---------- Parse the Hessian (=force) indices into an array ---------------
    99   if (!NoHessian)
    100     if (!Hessian.InitialiseIndices((class MatrixContainer *)&Force)) return 1;
    10176
    10277  // ---------- Parse the shielding indices into an array ---------------
     
    10479    if(!Shielding.ParseIndices(argv[1])) return 1;
    10580    if(!ShieldingPAS.ParseIndices(argv[1])) return 1;
    106     if(!Chi.ParseIndices(argv[1])) return 1;
    107     if(!ChiPAS.ParseIndices(argv[1])) return 1;
    10881  }
    10982
    11083  // ---------- Parse the KeySets into an array ---------------
    11184  if (!KeySet.ParseKeySets(argv[1], Force.RowCounter, Force.MatrixCounter)) return 1;
     85
    11286  if (!KeySet.ParseManyBodyTerms()) return 1;
    113 
    11487  if (!EnergyFragments.AllocateMatrix(Energy.Header, Energy.MatrixCounter, Energy.RowCounter, Energy.ColumnCounter)) return 1;
    115   if (!NoHCorrection) 
    116     HcorrectionFragments.AllocateMatrix(Hcorrection.Header, Hcorrection.MatrixCounter, Hcorrection.RowCounter, Hcorrection.ColumnCounter);
     88  if (Hcorrected)  HcorrectionFragments.AllocateMatrix(Hcorrection.Header, Hcorrection.MatrixCounter, Hcorrection.RowCounter, Hcorrection.ColumnCounter);
    11789  if (!ForceFragments.AllocateMatrix(Force.Header, Force.MatrixCounter, Force.RowCounter, Force.ColumnCounter)) return 1;
    118   if (!NoHessian)
    119     if (!HessianFragments.AllocateMatrix(Hessian.Header, Hessian.MatrixCounter, Hessian.RowCounter, Hessian.ColumnCounter)) return 1;
    12090  if (periode != NULL) { // also look for PAS values
    12191    if (!ShieldingFragments.AllocateMatrix(Shielding.Header, Shielding.MatrixCounter, Shielding.RowCounter, Shielding.ColumnCounter)) return 1;
    12292    if (!ShieldingPASFragments.AllocateMatrix(ShieldingPAS.Header, ShieldingPAS.MatrixCounter, ShieldingPAS.RowCounter, ShieldingPAS.ColumnCounter)) return 1;
    123     if (!ChiFragments.AllocateMatrix(Chi.Header, Chi.MatrixCounter, Chi.RowCounter, Chi.ColumnCounter)) return 1;
    124     if (!ChiPASFragments.AllocateMatrix(ChiPAS.Header, ChiPAS.MatrixCounter, ChiPAS.RowCounter, ChiPAS.ColumnCounter)) return 1;
    12593  }
    12694 
     
    12896  if(!Energy.SetLastMatrix(0., 0)) return 1;
    12997  if(!Force.SetLastMatrix(0., 2)) return 1;
    130   if (!NoHessian)
    131     if (!Hessian.SetLastMatrix(0., 0)) return 1;
    13298  if (periode != NULL) { // also look for PAS values
    13399    if(!Shielding.SetLastMatrix(0., 2)) return 1;
    134100    if(!ShieldingPAS.SetLastMatrix(0., 2)) return 1;
    135     if(!Chi.SetLastMatrix(0., 2)) return 1;
    136     if(!ChiPAS.SetLastMatrix(0., 2)) return 1;
    137101  }
    138102
     
    144108    cout << "Summing energy of order " << BondOrder+1 << " ..." << endl;
    145109    if (!EnergyFragments.SumSubManyBodyTerms(Energy, KeySet, BondOrder)) return 1;
    146     if (!NoHCorrection) {
     110    if (Hcorrected) {
    147111      HcorrectionFragments.SumSubManyBodyTerms(Hcorrection, KeySet, BondOrder);
    148112      if (!Energy.SumSubEnergy(EnergyFragments, &HcorrectionFragments, KeySet, BondOrder, 1.)) return 1;
    149       Hcorrection.SumSubEnergy(HcorrectionFragments, NULL, KeySet, BondOrder, 1.);
     113      if (Hcorrected) Hcorrection.SumSubEnergy(HcorrectionFragments, NULL, KeySet, BondOrder, 1.);
    150114    } else
    151115      if (!Energy.SumSubEnergy(EnergyFragments, NULL, KeySet, BondOrder, 1.)) return 1;
     
    154118    if (!ForceFragments.SumSubManyBodyTerms(Force, KeySet, BondOrder)) return 1;
    155119    if (!Force.SumSubForces(ForceFragments, KeySet, BondOrder, 1.)) return 1;
    156     // --------- sum up Hessian --------------------
    157     if (!NoHessian) {
    158       cout << "Summing Hessian of order " << BondOrder+1 << " ..." << endl;
    159       if (!HessianFragments.SumSubManyBodyTerms(Hessian, KeySet, BondOrder)) return 1;
    160       if (!Hessian.SumSubHessians(HessianFragments, KeySet, BondOrder, 1.)) return 1;
    161     }
    162120    if (periode != NULL) { // also look for PAS values
    163       cout << "Summing shieldings and susceptibilities of order " << BondOrder+1 << " ..." << endl;
     121      cout << "Summing shieldings of order " << BondOrder+1 << " ..." << endl;
    164122      if (!ShieldingFragments.SumSubManyBodyTerms(Shielding, KeySet, BondOrder)) return 1;
    165123      if (!Shielding.SumSubForces(ShieldingFragments, KeySet, BondOrder, 1.)) return 1;
    166124      if (!ShieldingPASFragments.SumSubManyBodyTerms(ShieldingPAS, KeySet, BondOrder)) return 1;
    167125      if (!ShieldingPAS.SumSubForces(ShieldingPASFragments, KeySet, BondOrder, 1.)) return 1;
    168       if (!ChiFragments.SumSubManyBodyTerms(Chi, KeySet, BondOrder)) return 1;
    169       if (!Chi.SumSubForces(ChiFragments, KeySet, BondOrder, 1.)) return 1;
    170       if (!ChiPASFragments.SumSubManyBodyTerms(ChiPAS, KeySet, BondOrder)) return 1;
    171       if (!ChiPAS.SumSubForces(ChiPASFragments, KeySet, BondOrder, 1.)) return 1;
    172126    }
    173127
     
    180134    // forces
    181135    if (!Force.WriteLastMatrix(argv[1], (prefix.str()).c_str(), ForcesSuffix)) return 1;
    182     // hessian
    183     if (!NoHessian)
    184       if (!Hessian.WriteLastMatrix(argv[1], (prefix.str()).c_str(), HessianSuffix)) return 1;
    185136    // shieldings
    186137    if (periode != NULL) { // also look for PAS values
    187138      if (!Shielding.WriteLastMatrix(argv[1], (prefix.str()).c_str(), ShieldingSuffix)) return 1;
    188139      if (!ShieldingPAS.WriteLastMatrix(argv[1], (prefix.str()).c_str(), ShieldingPASSuffix)) return 1;
    189       if (!Chi.WriteLastMatrix(argv[1], (prefix.str()).c_str(), ChiSuffix)) return 1;
    190       if (!ChiPAS.WriteLastMatrix(argv[1], (prefix.str()).c_str(), ChiPASSuffix)) return 1;
    191140    }
    192141  }
     
    195144  prefix << dir << EnergyFragmentSuffix;
    196145  if (!EnergyFragments.WriteTotalFragments(argv[1], (prefix.str()).c_str())) return 1;
    197   if (!NoHCorrection) {
     146  if (Hcorrected) {
    198147    prefix.str(" ");
    199148    prefix << dir << HcorrectionFragmentSuffix;
     
    204153  if (!ForceFragments.WriteTotalFragments(argv[1], (prefix.str()).c_str())) return 1;
    205154  if (!CreateDataFragment(EnergyFragments, KeySet, argv[1], FRAGMENTPREFIX ENERGYPERFRAGMENT, "fragment energy versus the Fragment No", "today", CreateEnergy)) return 1;
    206   if (!NoHessian) {
    207     prefix.str(" ");
    208     prefix << dir << HessianFragmentSuffix;
    209     if (!HessianFragments.WriteTotalFragments(argv[1], (prefix.str()).c_str())) return 1;
    210   }
    211155  if (periode != NULL) { // also look for PAS values
    212156    prefix.str(" ");
     
    216160    prefix << dir << ShieldingPASFragmentSuffix;
    217161    if (!ShieldingPASFragments.WriteTotalFragments(argv[1], (prefix.str()).c_str())) return 1;
    218     prefix.str(" ");
    219     prefix << dir << ChiFragmentSuffix;
    220     if (!ChiFragments.WriteTotalFragments(argv[1], (prefix.str()).c_str())) return 1;
    221     prefix.str(" ");
    222     prefix << dir << ChiPASFragmentSuffix;
    223     if (!ChiPASFragments.WriteTotalFragments(argv[1], (prefix.str()).c_str())) return 1;
    224162  }
    225163
    226164  // write last matrices as fragments into central dir (not subdir as above), for analyzer to know index bounds
    227165  if (!Energy.WriteLastMatrix(argv[1], dir, EnergyFragmentSuffix)) return 1;
    228   if (!NoHCorrection) Hcorrection.WriteLastMatrix(argv[1], dir, HcorrectionFragmentSuffix);
     166  if (Hcorrected) Hcorrection.WriteLastMatrix(argv[1], dir, HcorrectionFragmentSuffix);
    229167  if (!Force.WriteLastMatrix(argv[1], dir, ForceFragmentSuffix)) return 1;
    230   if (!NoHessian)
    231     if (!Hessian.WriteLastMatrix(argv[1], dir, HessianFragmentSuffix)) return 1;
    232168  if (periode != NULL) { // also look for PAS values
    233169    if (!Shielding.WriteLastMatrix(argv[1], dir, ShieldingFragmentSuffix)) return 1;
    234170    if (!ShieldingPAS.WriteLastMatrix(argv[1], dir, ShieldingPASFragmentSuffix)) return 1;
    235     if (!Chi.WriteLastMatrix(argv[1], dir, ChiFragmentSuffix)) return 1;
    236     if (!ChiPAS.WriteLastMatrix(argv[1], dir, ChiPASFragmentSuffix)) return 1;
    237171  }
    238172
  • src/moleculelist.cpp

    • Property mode changed from 100755 to 100644
    r986c80 redcda5  
    395395  int FragmentCounter = 0;
    396396  ofstream output;
    397   string basis("3-21G");
    398397 
    399398  // store the fragments as config and as xyz
     
    456455    // and save as config
    457456    sprintf(FragmentName, "%s/%s%s.conf", configuration->configpath, fragmentprefix, FragmentNumber);
     457    outputFragment.open(FragmentName, ios::out);
    458458    *out << Verbose(2) << "Saving " << fragmentprefix << " No. " << FragmentNumber << "/" << FragmentCounter-1 << " as config ...";
    459     if ((intermediateResult = configuration->Save(FragmentName, ListOfMolecules[i]->elemente, ListOfMolecules[i])))
     459    if ((intermediateResult = configuration->Save(&outputFragment, ListOfMolecules[i]->elemente, ListOfMolecules[i])))
    460460      *out << " done." << endl;
    461461    else
    462462      *out << " failed." << endl;
    463     result = result && intermediateResult;
    464463
    465464    // restore old config
    466465    configuration->SetDefaultPath(PathBackup);
    467466
     467    result = result && intermediateResult;
     468    outputFragment.close();
     469    outputFragment.clear();
    468470
    469471    // and save as mpqc input file
    470472    sprintf(FragmentName, "%s/%s%s.in", configuration->configpath, fragmentprefix, FragmentNumber);
     473    outputFragment.open(FragmentName, ios::out);
    471474    *out << Verbose(2) << "Saving " << fragmentprefix << " No. " << FragmentNumber << "/" << FragmentCounter-1 << " as mpqc input ...";
    472     if ((intermediateResult = configuration->SaveMPQC(FragmentName, ListOfMolecules[i])))
     475    if ((intermediateResult = configuration->SaveMPQC(&outputFragment, ListOfMolecules[i])))
    473476      *out << " done." << endl;
    474477    else
     
    476479       
    477480    result = result && intermediateResult;
    478     //outputFragment.close();
    479     //outputFragment.clear();
     481    outputFragment.close();
     482    outputFragment.clear();
    480483    delete(FragmentNumber);
    481484    //Free((void **)&FragmentNumber, "MoleculeListClass::OutputConfigForListOfFragments: *FragmentNumber");
  • src/molecules.cpp

    • Property mode changed from 100755 to 100644
    r986c80 redcda5  
    11/** \file molecules.cpp
    2  *
     2 * 
    33 * Functions for the class molecule.
    4  *
     4 * 
    55 */
    66
     
    2525      sum += (gsl_vector_get(x,j) - (vectors[i])->x[j])*(gsl_vector_get(x,j) - (vectors[i])->x[j]);
    2626  }
    27 
     27 
    2828  return sum;
    2929};
     
    3434 * Initialises molecule list with correctly referenced start and end, and sets molecule::last_atom to zero.
    3535 */
    36 molecule::molecule(periodentafel *teil)
    37 {
     36molecule::molecule(periodentafel *teil) 
     37{ 
    3838  // init atom chain list
    39   start = new atom;
     39  start = new atom; 
    4040  end = new atom;
    41   start->father = NULL;
     41  start->father = NULL; 
    4242  end->father = NULL;
    4343  link(start,end);
     
    4646  last = new bond(start, end, 1, -1);
    4747  link(first,last);
    48   // other stuff
     48  // other stuff 
    4949  MDSteps = 0;
    50   last_atom = 0;
     50  last_atom = 0; 
    5151  elemente = teil;
    5252  AtomCount = 0;
     
    6767 * Initialises molecule list with correctly referenced start and end, and sets molecule::last_atom to zero.
    6868 */
    69 molecule::~molecule()
     69molecule::~molecule() 
    7070{
    7171  if (ListOfBondsPerAtom != NULL)
     
    7878  delete(last);
    7979  delete(end);
    80   delete(start);
     80  delete(start); 
    8181};
    8282
    8383/** Adds given atom \a *pointer from molecule list.
    84  * Increases molecule::last_atom and gives last number to added atom and names it according to its element::abbrev and molecule::AtomCount
     84 * Increases molecule::last_atom and gives last number to added atom and names it according to its element::abbrev and molecule::AtomCount 
    8585 * \param *pointer allocated and set atom
    8686 * \return true - succeeded, false - atom not found in list
    8787 */
    8888bool molecule::AddAtom(atom *pointer)
    89 {
     89{ 
    9090  if (pointer != NULL) {
    91     pointer->sort = &pointer->nr;
     91    pointer->sort = &pointer->nr; 
    9292    pointer->nr = last_atom++;  // increase number within molecule
    9393    AtomCount++;
     
    106106    return add(pointer, end);
    107107  } else
    108     return false;
     108    return false; 
    109109};
    110110
     
    115115 */
    116116atom * molecule::AddCopyAtom(atom *pointer)
    117 {
     117{ 
    118118  if (pointer != NULL) {
    119119        atom *walker = new atom();
     
    122122    walker->v.CopyVector(&pointer->v); // copy velocity
    123123    walker->FixedIon = pointer->FixedIon;
    124     walker->sort = &walker->nr;
     124    walker->sort = &walker->nr; 
    125125    walker->nr = last_atom++;  // increase number within molecule
    126126    walker->father = pointer; //->GetTrueFather();
     
    133133    return walker;
    134134  } else
    135     return NULL;
     135    return NULL; 
    136136};
    137137
     
    156156 *    The lengths for these are \f$f\f$ and \f$g\f$ (from triangle H1-H2-(center of H1-H2-H3)) with knowledge that
    157157 *    the median lines in an isosceles triangle meet in the center point with a ratio 2:1.
    158  *    \f[ f = \frac{b}{\sqrt{3}} \qquad g = \frac{b}{2}
     158 *    \f[ f = \frac{b}{\sqrt{3}} \qquad g = \frac{b}{2} 
    159159 *    \f]
    160  *    as the coordination of all three atoms in the coordinate system of these three vectors:
     160 *    as the coordination of all three atoms in the coordinate system of these three vectors: 
    161161 *    \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$.
    162  *
     162 * 
    163163 * \param *out output stream for debugging
    164  * \param *Bond pointer to bond between \a *origin and \a *replacement
    165  * \param *TopOrigin son of \a *origin of upper level molecule (the atom added to this molecule as a copy of \a *origin)
     164 * \param *Bond pointer to bond between \a *origin and \a *replacement 
     165 * \param *TopOrigin son of \a *origin of upper level molecule (the atom added to this molecule as a copy of \a *origin) 
    166166 * \param *origin pointer to atom which acts as the origin for scaling the added hydrogen to correct bond length
    167167 * \param *replacement pointer to the atom which shall be copied as a hydrogen atom in this molecule
     
    191191  InBondvector.SubtractVector(&TopOrigin->x);
    192192  bondlength = InBondvector.Norm();
    193 
     193   
    194194   // is greater than typical bond distance? Then we have to correct periodically
    195195   // the problem is not the H being out of the box, but InBondvector have the wrong direction
    196    // due to TopReplacement or Origin being on the wrong side!
    197   if (bondlength > BondDistance) {
     196   // due to TopReplacement or Origin being on the wrong side! 
     197  if (bondlength > BondDistance) { 
    198198//    *out << Verbose(4) << "InBondvector is: ";
    199199//    InBondvector.Output(out);
     
    215215//    *out << endl;
    216216  } // periodic correction finished
    217 
     217 
    218218  InBondvector.Normalize();
    219219  // get typical bond length and store as scale factor for later
    220220  BondRescale = TopOrigin->type->HBondDistance[TopBond->BondDegree-1];
    221221  if (BondRescale == -1) {
    222     cerr << Verbose(3) << "ERROR: There is no typical hydrogen bond distance in replacing bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") of degree " << TopBond->BondDegree << "!" << endl;
    223     return false;
    224     BondRescale = bondlength;
     222    cerr << Verbose(3) << "WARNING: There is no typical bond distance for bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") of degree " << TopBond->BondDegree << "!" << endl;
     223    BondRescale = bondlength;
    225224  } else {
    226225    if (!IsAngstroem)
     
    273272      if (FirstOtherAtom != NULL) { // then we just have this double bond and the plane does not matter at all
    274273//        *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;
    275 
     274       
    276275        // determine the plane of these two with the *origin
    277276        AllWentWell = AllWentWell && Orthovector1.MakeNormalVector(&TopOrigin->x, &FirstOtherAtom->x, &SecondOtherAtom->x);
     
    286285      Orthovector1.Normalize();
    287286      //*out << Verbose(3) << "ReScaleCheck: " << Orthovector1.Norm() << " and " << InBondvector.Norm() << "." << endl;
    288 
     287     
    289288      // create the two Hydrogens ...
    290289      FirstOtherAtom = new atom();
     
    300299      bondangle = TopOrigin->type->HBondAngle[1];
    301300      if (bondangle == -1) {
    302         *out << Verbose(3) << "ERROR: There is no typical hydrogen bond angle in replacing bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") of degree " << TopBond->BondDegree << "!" << endl;
    303         return false;
     301        *out << Verbose(3) << "WARNING: There is no typical bond angle for bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") of degree " << TopBond->BondDegree << "!" << endl;
    304302        bondangle = 0;
    305303      }
     
    318316        SecondOtherAtom->x.x[i] = InBondvector.x[i] * cos(bondangle) + Orthovector1.x[i] * (-sin(bondangle));
    319317      }
    320       FirstOtherAtom->x.Scale(&BondRescale);  // rescale by correct BondDistance
     318      FirstOtherAtom->x.Scale(&BondRescale);  // rescale by correct BondDistance 
    321319      SecondOtherAtom->x.Scale(&BondRescale);
    322320      //*out << Verbose(3) << "ReScaleCheck: " << FirstOtherAtom->x.Norm() << " and " << SecondOtherAtom->x.Norm() << "." << endl;
    323321      for(int i=NDIM;i--;) { // and make relative to origin atom
    324         FirstOtherAtom->x.x[i] += TopOrigin->x.x[i];
     322        FirstOtherAtom->x.x[i] += TopOrigin->x.x[i]; 
    325323        SecondOtherAtom->x.x[i] += TopOrigin->x.x[i];
    326324      }
     
    365363//      *out << endl;
    366364      AllWentWell = AllWentWell && Orthovector2.MakeNormalVector(&InBondvector, &Orthovector1);
    367 //      *out << Verbose(3) << "Orthovector2: ";
     365//      *out << Verbose(3) << "Orthovector2: "; 
    368366//      Orthovector2.Output(out);
    369367//      *out << endl;
    370 
     368     
    371369      // create correct coordination for the three atoms
    372370      alpha = (TopOrigin->type->HBondAngle[2])/180.*M_PI/2.;  // retrieve triple bond angle from database
     
    380378      factors[0] = d;
    381379      factors[1] = f;
    382       factors[2] = 0.;
     380      factors[2] = 0.; 
    383381      FirstOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
    384382      factors[1] = -0.5*f;
    385       factors[2] = g;
     383      factors[2] = g; 
    386384      SecondOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
    387       factors[2] = -g;
     385      factors[2] = -g; 
    388386      ThirdOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
    389387
     
    437435 */
    438436bool molecule::AddXYZFile(string filename)
    439 {
     437{ 
    440438  istringstream *input = NULL;
    441439  int NumberOfAtoms = 0; // atom number in xyz read
     
    446444  string line;    // currently parsed line
    447445  double x[3];    // atom coordinates
    448 
     446 
    449447  xyzfile.open(filename.c_str());
    450448  if (!xyzfile)
     
    454452  input = new istringstream(line);
    455453  *input >> NumberOfAtoms;
    456   cout << Verbose(0) << "Parsing " << NumberOfAtoms << " atoms in file." << endl;
     454  cout << Verbose(0) << "Parsing " << NumberOfAtoms << " atoms in file." << endl; 
    457455  getline(xyzfile,line,'\n'); // Read comment
    458456  cout << Verbose(1) << "Comment: " << line << endl;
    459 
     457 
    460458  if (MDSteps == 0) // no atoms yet present
    461459    MDSteps++;
     
    491489  xyzfile.close();
    492490  delete(input);
    493   return true;
     491  return true; 
    494492};
    495493
     
    503501  atom *LeftAtom = NULL, *RightAtom = NULL;
    504502  atom *Walker = NULL;
    505 
     503 
    506504  // copy all atoms
    507505  Walker = start;
     
    510508    CurrentAtom = copy->AddCopyAtom(Walker);
    511509  }
    512 
     510 
    513511  // copy all bonds
    514512  bond *Binder = first;
     
    534532      copy->NoCyclicBonds++;
    535533    NewBond->Type = Binder->Type;
    536   }
     534  } 
    537535  // correct fathers
    538536  Walker = copy->start;
     
    551549    copy->CreateListOfBondsPerAtom((ofstream *)&cout);
    552550  }
    553 
     551 
    554552  return copy;
    555553};
     
    576574
    577575/** Remove bond from bond chain list.
    578  * \todo Function not implemented yet
     576 * \todo Function not implemented yet 
    579577 * \param *pointer bond pointer
    580578 * \return true - bound found and removed, false - bond not found/removed
     
    588586
    589587/** Remove every bond from bond chain list that atom \a *BondPartner is a constituent of.
    590  * \todo Function not implemented yet
     588 * \todo Function not implemented yet 
    591589 * \param *BondPartner atom to be removed
    592590 * \return true - bounds found and removed, false - bonds not found/removed
     
    621619  Vector *min = new Vector;
    622620  Vector *max = new Vector;
    623 
     621 
    624622  // gather min and max for each axis
    625623  ptr = start->next;  // start at first in list
     
    667665{
    668666  Vector *min = new Vector;
    669 
     667 
    670668//  *out << Verbose(3) << "Begin of CenterEdge." << endl;
    671669  atom *ptr = start->next;  // start at first in list
     
    683681      }
    684682    }
    685 //    *out << Verbose(4) << "Maximum is ";
     683//    *out << Verbose(4) << "Maximum is "; 
    686684//    max->Output(out);
    687685//    *out << ", Minimum is ";
     
    691689    max->AddVector(min);
    692690    Translate(min);
    693   }
     691  } 
    694692  delete(min);
    695693//  *out << Verbose(3) << "End of CenterEdge." << endl;
    696 };
     694}; 
    697695
    698696/** Centers the center of the atoms at (0,0,0).
     
    704702  int Num = 0;
    705703  atom *ptr = start->next;  // start at first in list
    706 
     704 
    707705  for(int i=NDIM;i--;) // zero center vector
    708706    center->x[i] = 0.;
    709 
     707   
    710708  if (ptr != end) {   //list not empty?
    711709    while (ptr->next != end) {  // continue with second if present
    712710      ptr = ptr->next;
    713711      Num++;
    714       center->AddVector(&ptr->x);
     712      center->AddVector(&ptr->x);       
    715713    }
    716714    center->Scale(-1./Num); // divide through total number (and sign for direction)
    717715    Translate(center);
    718716  }
    719 };
     717}; 
    720718
    721719/** Returns vector pointing to center of gravity.
     
    729727  Vector tmp;
    730728  double Num = 0;
    731 
     729 
    732730  a->Zero();
    733731
     
    737735      Num += 1.;
    738736      tmp.CopyVector(&ptr->x);
    739       a->AddVector(&tmp);
     737      a->AddVector(&tmp);       
    740738    }
    741739    a->Scale(-1./Num); // divide through total mass (and sign for direction)
     
    757755        Vector tmp;
    758756  double Num = 0;
    759 
     757       
    760758        a->Zero();
    761759
     
    766764      tmp.CopyVector(&ptr->x);
    767765      tmp.Scale(ptr->type->mass);  // scale by mass
    768       a->AddVector(&tmp);
     766      a->AddVector(&tmp);       
    769767    }
    770768    a->Scale(-1./Num); // divide through total mass (and sign for direction)
     
    789787    Translate(center);
    790788  }
    791 };
     789}; 
    792790
    793791/** Scales all atoms by \a *factor.
     
    803801      Trajectories[ptr].R.at(j).Scale(factor);
    804802    ptr->x.Scale(factor);
    805   }
    806 };
    807 
    808 /** Translate all atoms by given vector.
     803  }     
     804};
     805
     806/** Translate all atoms by given vector. 
    809807 * \param trans[] translation vector.
    810808 */
     
    818816      Trajectories[ptr].R.at(j).Translate(trans);
    819817    ptr->x.Translate(trans);
    820   }
    821 };
    822 
    823 /** Mirrors all atoms against a given plane.
     818  }     
     819};
     820
     821/** Mirrors all atoms against a given plane. 
    824822 * \param n[] normal vector of mirror plane.
    825823 */
     
    833831      Trajectories[ptr].R.at(j).Mirror(n);
    834832    ptr->x.Mirror(n);
    835   }
     833  }     
    836834};
    837835
     
    847845  bool flag;
    848846  Vector Testvector, Translationvector;
    849 
     847 
    850848  do {
    851849    Center.Zero();
     
    863861          if (Walker->nr < Binder->GetOtherAtom(Walker)->nr) // otherwise we shift one to, the other fro and gain nothing
    864862            for (int j=0;j<NDIM;j++) {
    865               tmp = Walker->x.x[j] - Binder->GetOtherAtom(Walker)->x.x[j];
     863              tmp = Walker->x.x[j] - Binder->GetOtherAtom(Walker)->x.x[j]; 
    866864              if ((fabs(tmp)) > BondDistance) {
    867865                flag = false;
     
    879877        cout << Verbose(1) << "vector is: ";
    880878        Testvector.Output((ofstream *)&cout);
    881         cout << endl;
     879        cout << endl;     
    882880#ifdef ADDHYDROGEN
    883881        // now also change all hydrogens
     
    892890            cout << Verbose(1) << "Hydrogen vector is: ";
    893891            Testvector.Output((ofstream *)&cout);
    894             cout << endl;
     892            cout << endl;     
    895893          }
    896894        }
     
    914912
    915913        CenterGravity(out, CenterOfGravity);
    916 
    917         // reset inertia tensor
     914       
     915        // reset inertia tensor 
    918916        for(int i=0;i<NDIM*NDIM;i++)
    919917                InertiaTensor[i] = 0.;
    920 
     918       
    921919        // sum up inertia tensor
    922920        while (ptr->next != end) {
     
    943941        }
    944942        *out << endl;
    945 
     943       
    946944        // diagonalize to determine principal axis system
    947945        gsl_eigen_symmv_workspace *T = gsl_eigen_symmv_alloc(NDIM);
     
    952950        gsl_eigen_symmv_free(T);
    953951        gsl_eigen_symmv_sort(eval, evec, GSL_EIGEN_SORT_ABS_DESC);
    954 
     952       
    955953        for(int i=0;i<NDIM;i++) {
    956954                *out << Verbose(1) << "eigenvalue = " << gsl_vector_get(eval, i);
    957955                *out << ", eigenvector = (" << evec->data[i * evec->tda + 0] << "," << evec->data[i * evec->tda + 1] << "," << evec->data[i * evec->tda + 2] << ")" << endl;
    958956        }
    959 
     957       
    960958        // check whether we rotate or not
    961959        if (DoRotate) {
    962           *out << Verbose(1) << "Transforming molecule into PAS ... ";
     960          *out << Verbose(1) << "Transforming molecule into PAS ... "; 
    963961          // the eigenvectors specify the transformation matrix
    964962          ptr = start;
     
    972970
    973971          // summing anew for debugging (resulting matrix has to be diagonal!)
    974           // reset inertia tensor
     972          // reset inertia tensor 
    975973    for(int i=0;i<NDIM*NDIM;i++)
    976974      InertiaTensor[i] = 0.;
    977 
     975   
    978976    // sum up inertia tensor
    979977    ptr = start;
     
    10021000    *out << endl;
    10031001        }
    1004 
     1002       
    10051003        // free everything
    10061004        delete(CenterOfGravity);
     
    10191017 * \sa molecule::MinimiseConstrainedPotential(), molecule::VerletForceIntegration()
    10201018 * \param *out output stream for debugging
    1021  * \param *PermutationMap gives target ptr for each atom, array of size molecule::AtomCount (this is "x" in \f$ V^{con}(x) \f$ )
     1019 * \param *PermutationMap gives target ptr for each atom, array of size molecule::AtomCount (this is "x" in \f$V^{con}(x)\f$)
    10221020 * \param startstep start configuration (MDStep in molecule::trajectories)
    10231021 * \param endstep end configuration (MDStep in molecule::trajectories)
     
    14811479 * \param *out output stream for debugging
    14821480 * \param *file filename
    1483  * \param config structure with config::Deltat, config::IsAngstroem, config::DoConstrained
    14841481 * \param delta_t time step width in atomic units
    14851482 * \param IsAngstroem whether coordinates are in angstroem (true) or bohrradius (false)
     
    14881485 * \todo This is not yet checked if it is correctly working with DoConstrained set to true.
    14891486 */
    1490 bool molecule::VerletForceIntegration(ofstream *out, char *file, config &configuration)
    1491 {
     1487bool molecule::VerletForceIntegration(ofstream *out, char *file, double delta_t, bool IsAngstroem, int DoConstrained)
     1488{
     1489  element *runner = elemente->start;
    14921490  atom *walker = NULL;
     1491  int AtomNo;
    14931492  ifstream input(file);
    14941493  string token;
    14951494  stringstream item;
    1496   double IonMass, Vector[NDIM], ConstrainedPotentialEnergy, ActualTemp;
     1495  double a, IonMass, Vector[NDIM], ConstrainedPotentialEnergy;
    14971496  ForceMatrix Force;
    14981497
    14991498  CountElements();  // make sure ElementsInMolecule is up to date
    1500 
     1499 
    15011500  // check file
    15021501  if (input == NULL) {
     
    15241523      }
    15251524    // solve a constrained potential if we are meant to
    1526     if (configuration.DoConstrainedMD) {
     1525    if (DoConstrained) {
    15271526      // calculate forces and potential
    15281527      atom **PermutationMap = NULL;
    1529       ConstrainedPotentialEnergy = MinimiseConstrainedPotential(out, PermutationMap,configuration.DoConstrainedMD, 0, configuration.GetIsAngstroem());
    1530       EvaluateConstrainedForces(out, configuration.DoConstrainedMD, 0, PermutationMap, &Force);
     1528      ConstrainedPotentialEnergy = MinimiseConstrainedPotential(out, PermutationMap, DoConstrained, 0, IsAngstroem);
     1529      EvaluateConstrainedForces(out, DoConstrained, 0, PermutationMap, &Force);
    15311530      Free((void **)&PermutationMap, "molecule::MinimiseConstrainedPotential: *PermutationMap");
    15321531    }
    15331532   
    15341533    // and perform Verlet integration for each atom with position, velocity and force vector
    1535     walker = start;
    1536     while (walker->next != end) { // go through every atom of this element
    1537       walker = walker->next;
    1538       //a = configuration.Deltat*0.5/walker->type->mass;        // (F+F_old)/2m = a and thus: v = (F+F_old)/2m * t = (F + F_old) * a
    1539       // check size of vectors
    1540       if (Trajectories[walker].R.size() <= (unsigned int)(MDSteps)) {
    1541         //out << "Increasing size for trajectory array of " << *walker << " to " << (size+10) << "." << endl;
    1542         Trajectories[walker].R.resize(MDSteps+10);
    1543         Trajectories[walker].U.resize(MDSteps+10);
    1544         Trajectories[walker].F.resize(MDSteps+10);
    1545       }
    1546      
    1547       // Update R (and F)
    1548       for (int d=0; d<NDIM; d++) {
    1549         Trajectories[walker].F.at(MDSteps).x[d] = -Force.Matrix[0][walker->nr][d+5]*(configuration.GetIsAngstroem() ? AtomicLengthToAngstroem : 1.);
    1550         Trajectories[walker].R.at(MDSteps).x[d] = Trajectories[walker].R.at(MDSteps-1).x[d];
    1551         Trajectories[walker].R.at(MDSteps).x[d] += configuration.Deltat*(Trajectories[walker].U.at(MDSteps-1).x[d]);     // s(t) = s(0) + v * deltat + 1/2 a * deltat^2
    1552         Trajectories[walker].R.at(MDSteps).x[d] += 0.5*configuration.Deltat*configuration.Deltat*(Trajectories[walker].F.at(MDSteps).x[d]/walker->type->mass);     // F = m * a and s = 0.5 * F/m * t^2 = F * a * t
    1553       }
    1554       // Update U
    1555       for (int d=0; d<NDIM; d++) {
    1556         Trajectories[walker].U.at(MDSteps).x[d] = Trajectories[walker].U.at(MDSteps-1).x[d];
    1557         Trajectories[walker].U.at(MDSteps).x[d] += configuration.Deltat * (Trajectories[walker].F.at(MDSteps).x[d]+Trajectories[walker].F.at(MDSteps-1).x[d]/walker->type->mass); // v = F/m * t
    1558       }
    1559 //      out << "Integrated position&velocity of step " << (MDSteps) << ": (";
    1560 //      for (int d=0;d<NDIM;d++)
    1561 //        out << Trajectories[walker].R.at(MDSteps).x[d] << " ";          // next step
    1562 //      out << ")\t(";
    1563 //      for (int d=0;d<NDIM;d++)
    1564 //        cout << Trajectories[walker].U.at(MDSteps).x[d] << " ";          // next step
    1565 //      out << ")" << endl;
    1566             // next atom
    1567     }
    1568   }
    1569   // correct velocities (rather momenta) so that center of mass remains motionless
    1570   for(int d=0;d<NDIM;d++)
    1571     Vector[d] = 0.;
    1572   IonMass = 0.;
    1573   walker = start;
    1574   while (walker->next != end) { // go through every atom
    1575     walker = walker->next;
    1576     IonMass += walker->type->mass;  // sum up total mass
    1577     for(int d=0;d<NDIM;d++) {
    1578       Vector[d] += Trajectories[walker].U.at(MDSteps).x[d]*walker->type->mass;
    1579     }
    1580   }
    1581   // correct velocities (rather momenta) so that center of mass remains motionless
    1582   for(int d=0;d<NDIM;d++)
    1583     Vector[d] /= IonMass;
    1584   ActualTemp = 0.;
    1585   walker = start;
    1586   while (walker->next != end) { // go through every atom of this element
    1587     walker = walker->next;
    1588     for(int d=0;d<NDIM;d++) {
    1589       Trajectories[walker].U.at(MDSteps).x[d] -= Vector[d];
    1590       ActualTemp += 0.5 * walker->type->mass * Trajectories[walker].U.at(MDSteps).x[d] * Trajectories[walker].U.at(MDSteps).x[d];
    1591     }
    1592   }
    1593   Thermostats(configuration, ActualTemp, Berendsen);
    1594   MDSteps++;
    1595 
    1596 
    1597   // exit
    1598   return true;
    1599 };
    1600 
    1601 /** Implementation of various thermostats.
    1602  * All these thermostats apply an additional force which has the following forms:
    1603  * -# Woodcock
    1604  *  \f$p_i \rightarrow \sqrt{\frac{T_0}{T}} \cdot p_i\f$
    1605  * -# Gaussian
    1606  *  \f$ \frac{ \sum_i \frac{p_i}{m_i} \frac{\partial V}{\partial q_i}} {\sum_i \frac{p^2_i}{m_i}} \cdot p_i\f$
    1607  * -# Langevin
    1608  *  \f$p_{i,n} \rightarrow \sqrt{1-\alpha^2} p_{i,0} + \alpha p_r\f$ 
    1609  * -# Berendsen
    1610  *  \f$p_i \rightarrow \left [ 1+ \frac{\delta t}{\tau_T} \left ( \frac{T_0}{T} \right ) \right ]^{\frac{1}{2}} \cdot p_i\f$
    1611  * -# Nose-Hoover
    1612  *  \f$\zeta p_i \f$ with \f$\frac{\partial \zeta}{\partial t} = \frac{1}{M_s} \left ( \sum^N_{i=1} \frac{p_i^2}{m_i} - g k_B T \right )\f$
    1613  * These Thermostats either simply rescale the velocities, thus this function should be called after ion velocities have been updated, and/or
    1614  * have a constraint force acting additionally on the ions. In the latter case, the ion speeds have to be modified
    1615  * belatedly and the constraint force set.
    1616  * \param *P Problem at hand
    1617  * \param i which of the thermostats to take: 0 - none, 1 - Woodcock, 2 - Gaussian, 3 - Langevin, 4 - Berendsen, 5 - Nose-Hoover
    1618  * \sa InitThermostat()
    1619  */
    1620 void molecule::Thermostats(config &configuration, double ActualTemp, int Thermostat)
    1621 {
    1622   double ekin = 0.;
    1623   double E = 0., G = 0.;
    1624   double delta_alpha = 0.;
    1625   double ScaleTempFactor;
    1626   double sigma;
    1627   double IonMass;
    1628   int d;
    1629   gsl_rng * r;
    1630   const gsl_rng_type * T;
    1631   double *U = NULL, *F = NULL, FConstraint[NDIM];
    1632   atom *walker = NULL;
    1633  
    1634   // calculate scale configuration
    1635   ScaleTempFactor = configuration.TargetTemp/ActualTemp;
    1636    
    1637   // differentating between the various thermostats
    1638   switch(Thermostat) {
    1639      case None:
    1640       cout << Verbose(2) <<  "Applying no thermostat..." << endl;
    1641       break;
    1642      case Woodcock:
    1643       if ((configuration.ScaleTempStep > 0) && ((MDSteps-1) % configuration.ScaleTempStep == 0)) {
    1644         cout << Verbose(2) <<  "Applying Woodcock thermostat..." << endl;
     1534    runner = elemente->start;
     1535    while (runner->next != elemente->end) { // go through every element
     1536      runner = runner->next;
     1537      IonMass = runner->mass;
     1538      a = delta_t*0.5/IonMass;        // (F+F_old)/2m = a and thus: v = (F+F_old)/2m * t = (F + F_old) * a
     1539      if (ElementsInMolecule[runner->Z]) { // if this element got atoms
     1540        AtomNo = 0;
    16451541        walker = start;
    16461542        while (walker->next != end) { // go through every atom of this element
    16471543          walker = walker->next;
    1648           IonMass = walker->type->mass;
    1649           U = Trajectories[walker].U.at(MDSteps).x;
    1650           if (walker->FixedIon == 0) // even FixedIon moves, only not by other's forces
    1651             for (d=0; d<NDIM; d++) {
    1652               U[d] *= sqrt(ScaleTempFactor);
    1653               ekin += 0.5*IonMass * U[d]*U[d];
     1544          if (walker->type == runner) { // if this atom fits to element
     1545            // check size of vectors
     1546            if (Trajectories[walker].R.size() <= (unsigned int)(MDSteps)) {
     1547              //out << "Increasing size for trajectory array of " << *walker << " to " << (size+10) << "." << endl;
     1548              Trajectories[walker].R.resize(MDSteps+10);
     1549              Trajectories[walker].U.resize(MDSteps+10);
     1550              Trajectories[walker].F.resize(MDSteps+10);
    16541551            }
    1655         }
    1656       }
    1657       break;
    1658      case Gaussian:
    1659       cout << Verbose(2) <<  "Applying Gaussian thermostat..." << endl;
    1660       walker = start;
    1661       while (walker->next != end) { // go through every atom of this element
    1662         walker = walker->next;
    1663         IonMass = walker->type->mass;
    1664         U = Trajectories[walker].U.at(MDSteps).x;
    1665         F = Trajectories[walker].F.at(MDSteps).x;
    1666         if (walker->FixedIon == 0) // even FixedIon moves, only not by other's forces
    1667           for (d=0; d<NDIM; d++) {
    1668             G += U[d] * F[d];
    1669             E += U[d]*U[d]*IonMass;
    1670           }
    1671       }
    1672       cout << Verbose(1) << "Gaussian Least Constraint constant is " << G/E << "." << endl;
    1673       walker = start;
    1674       while (walker->next != end) { // go through every atom of this element
    1675         walker = walker->next;
    1676         IonMass = walker->type->mass;
    1677         U = Trajectories[walker].U.at(MDSteps).x;
    1678         F = Trajectories[walker].F.at(MDSteps).x;
    1679         if (walker->FixedIon == 0) // even FixedIon moves, only not by other's forces
    1680           for (d=0; d<NDIM; d++) {
    1681             FConstraint[d] = (G/E) * (U[d]*IonMass);
    1682             U[d] += configuration.Deltat/IonMass * (FConstraint[d]);
    1683             ekin += IonMass * U[d]*U[d];
    1684           }
    1685       }
    1686       break;
    1687      case Langevin:
    1688       cout << Verbose(2) <<  "Applying Langevin thermostat..." << endl;
    1689       // init random number generator
    1690       gsl_rng_env_setup();
    1691       T = gsl_rng_default;
    1692       r = gsl_rng_alloc (T);
    1693       // Go through each ion
    1694       walker = start;
    1695       while (walker->next != end) { // go through every atom of this element
    1696         walker = walker->next;
    1697         IonMass = walker->type->mass;
    1698         sigma  = sqrt(configuration.TargetTemp/IonMass); // sigma = (k_b T)/m (Hartree/atomicmass = atomiclength/atomictime)
    1699         U = Trajectories[walker].U.at(MDSteps).x;
    1700         F = Trajectories[walker].F.at(MDSteps).x;
    1701         if (walker->FixedIon == 0) { // even FixedIon moves, only not by other's forces
    1702           // throw a dice to determine whether it gets hit by a heat bath particle
    1703           if (((((rand()/(double)RAND_MAX))*configuration.TempFrequency) < 1.)) { 
    1704             cout << Verbose(3) << "Particle " << *walker << " was hit (sigma " << sigma << "): " << sqrt(U[0]*U[0]+U[1]*U[1]+U[2]*U[2]) << " -> ";
    1705             // pick three random numbers from a Boltzmann distribution around the desired temperature T for each momenta axis
    1706             for (d=0; d<NDIM; d++) {
    1707               U[d] = gsl_ran_gaussian (r, sigma);
     1552           
     1553            // Update R (and F)
     1554            for (int d=0; d<NDIM; d++) {
     1555              Trajectories[walker].F.at(MDSteps).x[d] = -Force.Matrix[0][AtomNo][d+5]*(IsAngstroem ? AtomicLengthToAngstroem : 1.);
     1556              Trajectories[walker].R.at(MDSteps).x[d] = Trajectories[walker].R.at(MDSteps-1).x[d];
     1557              Trajectories[walker].R.at(MDSteps).x[d] += delta_t*(Trajectories[walker].U.at(MDSteps-1).x[d]);
     1558              Trajectories[walker].R.at(MDSteps).x[d] += delta_t*a*(Trajectories[walker].F.at(MDSteps).x[d]);     // F = m * a and s = 0.5 * F/m * t^2 = F * a * t
    17081559            }
    1709             cout << sqrt(U[0]*U[0]+U[1]*U[1]+U[2]*U[2]) << endl;
    1710           }
    1711           for (d=0; d<NDIM; d++)
    1712             ekin += 0.5*IonMass * U[d]*U[d];
    1713         }
    1714       }
    1715       break;
    1716      case Berendsen:
    1717       cout << Verbose(2) <<  "Applying Berendsen-VanGunsteren thermostat..." << endl;
    1718       walker = start;
    1719       while (walker->next != end) { // go through every atom of this element
    1720         walker = walker->next;
    1721         IonMass = walker->type->mass;
    1722         U = Trajectories[walker].U.at(MDSteps).x;
    1723         F = Trajectories[walker].F.at(MDSteps).x;
    1724         if (walker->FixedIon == 0) { // even FixedIon moves, only not by other's forces
    1725           for (d=0; d<NDIM; d++) {
    1726             U[d] *= sqrt(1+(configuration.Deltat/configuration.TempFrequency)*(ScaleTempFactor-1));
    1727             ekin += 0.5*IonMass * U[d]*U[d];
     1560            // Update U
     1561            for (int d=0; d<NDIM; d++) {
     1562              Trajectories[walker].U.at(MDSteps).x[d] = Trajectories[walker].U.at(MDSteps-1).x[d];
     1563              Trajectories[walker].U.at(MDSteps).x[d] += a * (Trajectories[walker].F.at(MDSteps).x[d]+Trajectories[walker].F.at(MDSteps-1).x[d]);
     1564            }
     1565//            out << "Integrated position&velocity of step " << (MDSteps) << ": (";
     1566//            for (int d=0;d<NDIM;d++)
     1567//              out << Trajectories[walker].R.at(MDSteps).x[d] << " ";          // next step
     1568//            out << ")\t(";
     1569//            for (int d=0;d<NDIM;d++)
     1570//              cout << Trajectories[walker].U.at(MDSteps).x[d] << " ";          // next step
     1571//            out << ")" << endl;
     1572            // next atom
     1573            AtomNo++;
    17281574          }
    17291575        }
    17301576      }
    1731       break;
    1732      case NoseHoover:
    1733       cout << Verbose(2) <<  "Applying Nose-Hoover thermostat..." << endl;
    1734       // dynamically evolve alpha (the additional degree of freedom)
    1735       delta_alpha = 0.;
    1736       walker = start;
    1737       while (walker->next != end) { // go through every atom of this element
    1738         walker = walker->next;
    1739         IonMass = walker->type->mass;
    1740         U = Trajectories[walker].U.at(MDSteps).x;
    1741         if (walker->FixedIon == 0) { // even FixedIon moves, only not by other's forces
    1742           for (d=0; d<NDIM; d++) {
    1743             delta_alpha += U[d]*U[d]*IonMass;
    1744           }
    1745         }
    1746       }
    1747       delta_alpha = (delta_alpha - (3.*AtomCount+1.) * configuration.TargetTemp)/(configuration.HooverMass*Units2Electronmass);
    1748       configuration.alpha += delta_alpha*configuration.Deltat;
    1749       cout << Verbose(3) << "alpha = " << delta_alpha << " * " << configuration.Deltat << " = " << configuration.alpha << "." << endl;
    1750       // apply updated alpha as additional force
    1751       walker = start;
    1752       while (walker->next != end) { // go through every atom of this element
    1753         walker = walker->next;
    1754         IonMass = walker->type->mass;
    1755         U = Trajectories[walker].U.at(MDSteps).x;
    1756         if (walker->FixedIon == 0) { // even FixedIon moves, only not by other's forces
    1757           for (d=0; d<NDIM; d++) {
    1758               FConstraint[d] = - configuration.alpha * (U[d] * IonMass);
    1759               U[d] += configuration.Deltat/IonMass * (FConstraint[d]);
    1760               ekin += (0.5*IonMass) * U[d]*U[d];
    1761             }
    1762         }
    1763       }
    1764       break;
    1765   }   
    1766   cout << Verbose(1) << "Kinetic energy is " << ekin << "." << endl;
     1577    }
     1578  }
     1579//  // correct velocities (rather momenta) so that center of mass remains motionless
     1580//  for(int d=0;d<NDIM;d++)
     1581//    Vector[d] = 0.;
     1582//  IonMass = 0.;
     1583//  walker = start;
     1584//  while (walker->next != end) { // go through every atom
     1585//    walker = walker->next;
     1586//    IonMass += walker->type->mass;  // sum up total mass
     1587//    for(int d=0;d<NDIM;d++) {
     1588//      Vector[d] += Trajectories[walker].U.at(MDSteps).x[d]*walker->type->mass;
     1589//    }
     1590//  }
     1591//  walker = start;
     1592//  while (walker->next != end) { // go through every atom of this element
     1593//    walker = walker->next;
     1594//    for(int d=0;d<NDIM;d++) {
     1595//      Trajectories[walker].U.at(MDSteps).x[d] -= Vector[d]*walker->type->mass/IonMass;
     1596//    }
     1597//  }
     1598  MDSteps++;
     1599
     1600 
     1601  // exit
     1602  return true;
    17671603};
    17681604
     
    17861622    ptr = ptr->next;
    17871623    tmp = ptr->x.x[0];
    1788     ptr->x.x[0] =  cos(alpha) * tmp + sin(alpha) * ptr->x.x[2];
     1624    ptr->x.x[0] =  cos(alpha) * tmp + sin(alpha) * ptr->x.x[2]; 
    17891625    ptr->x.x[2] = -sin(alpha) * tmp + cos(alpha) * ptr->x.x[2];
    17901626    for (int j=0;j<MDSteps;j++) {
    17911627      tmp = Trajectories[ptr].R.at(j).x[0];
    1792       Trajectories[ptr].R.at(j).x[0] =  cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2];
     1628      Trajectories[ptr].R.at(j).x[0] =  cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2]; 
    17931629      Trajectories[ptr].R.at(j).x[2] = -sin(alpha) * tmp + cos(alpha) * Trajectories[ptr].R.at(j).x[2];
    17941630    }
    1795   }
     1631  }     
    17961632  // rotate n vector
    17971633  tmp = n->x[0];
     
    18011637  n->Output((ofstream *)&cout);
    18021638  cout << endl;
    1803 
     1639 
    18041640  // rotate on z-y plane
    18051641  ptr = start;
     
    18091645    ptr = ptr->next;
    18101646    tmp = ptr->x.x[1];
    1811     ptr->x.x[1] =  cos(alpha) * tmp + sin(alpha) * ptr->x.x[2];
     1647    ptr->x.x[1] =  cos(alpha) * tmp + sin(alpha) * ptr->x.x[2]; 
    18121648    ptr->x.x[2] = -sin(alpha) * tmp + cos(alpha) * ptr->x.x[2];
    18131649    for (int j=0;j<MDSteps;j++) {
    18141650      tmp = Trajectories[ptr].R.at(j).x[1];
    1815       Trajectories[ptr].R.at(j).x[1] =  cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2];
     1651      Trajectories[ptr].R.at(j).x[1] =  cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2]; 
    18161652      Trajectories[ptr].R.at(j).x[2] = -sin(alpha) * tmp + cos(alpha) * Trajectories[ptr].R.at(j).x[2];
    18171653    }
    1818   }
     1654  }     
    18191655  // rotate n vector (for consistency check)
    18201656  tmp = n->x[1];
    18211657  n->x[1] =  cos(alpha) * tmp +  sin(alpha) * n->x[2];
    18221658  n->x[2] = -sin(alpha) * tmp +  cos(alpha) * n->x[2];
    1823 
     1659 
    18241660  cout << Verbose(1) << "alignment vector after second rotation: ";
    18251661  n->Output((ofstream *)&cout);
     
    18321668 * \return true - succeeded, false - atom not found in list
    18331669 */
    1834 bool molecule::RemoveAtom(atom *pointer)
    1835 {
     1670bool molecule::RemoveAtom(atom *pointer) 
     1671{ 
    18361672  if (ElementsInMolecule[pointer->type->Z] != 0)  // this would indicate an error
    18371673    ElementsInMolecule[pointer->type->Z]--;  // decrease number of atom of this element
    18381674  else
    1839     cerr << "ERROR: Atom " << pointer->Name << " is of element " << pointer->type->Z << " but the entry in the table of the molecule is 0!" << endl;
     1675    cerr << "ERROR: Atom " << pointer->Name << " is of element " << pointer->type->Z << " but the entry in the table of the molecule is 0!" << endl; 
    18401676  if (ElementsInMolecule[pointer->type->Z] == 0)  // was last atom of this element?
    18411677    ElementCount--;
     
    18471683 * \return true - succeeded, false - atom not found in list
    18481684 */
    1849 bool molecule::CleanupMolecule()
    1850 {
    1851   return (cleanup(start,end) && cleanup(first,last));
     1685bool molecule::CleanupMolecule() 
     1686{ 
     1687  return (cleanup(start,end) && cleanup(first,last)); 
    18521688};
    18531689
     
    18631699  } else {
    18641700    cout << Verbose(0) << "Atom not found in list." << endl;
    1865     return NULL;
     1701    return NULL; 
    18661702  }
    18671703};
     
    19121748  struct lsq_params *par = (struct lsq_params *)params;
    19131749  atom *ptr = par->mol->start;
    1914 
     1750 
    19151751  // initialize vectors
    19161752  a.x[0] = gsl_vector_get(x,0);
     
    19421778{
    19431779    int np = 6;
    1944 
     1780   
    19451781   const gsl_multimin_fminimizer_type *T =
    19461782     gsl_multimin_fminimizer_nmsimplex;
     
    19481784   gsl_vector *ss;
    19491785   gsl_multimin_function minex_func;
    1950 
     1786 
    19511787   size_t iter = 0, i;
    19521788   int status;
    19531789   double size;
    1954 
     1790 
    19551791   /* Initial vertex size vector */
    19561792   ss = gsl_vector_alloc (np);
    1957 
     1793 
    19581794   /* Set all step sizes to 1 */
    19591795   gsl_vector_set_all (ss, 1.0);
    1960 
     1796 
    19611797   /* Starting point */
    19621798   par->x = gsl_vector_alloc (np);
    19631799   par->mol = this;
    1964 
     1800 
    19651801   gsl_vector_set (par->x, 0, 0.0);  // offset
    19661802   gsl_vector_set (par->x, 1, 0.0);
     
    19691805   gsl_vector_set (par->x, 4, 0.0);
    19701806   gsl_vector_set (par->x, 5, 1.0);
    1971 
     1807 
    19721808   /* Initialize method and iterate */
    19731809   minex_func.f = &LeastSquareDistance;
    19741810   minex_func.n = np;
    19751811   minex_func.params = (void *)par;
    1976 
     1812 
    19771813   s = gsl_multimin_fminimizer_alloc (T, np);
    19781814   gsl_multimin_fminimizer_set (s, &minex_func, par->x, ss);
    1979 
     1815 
    19801816   do
    19811817     {
    19821818       iter++;
    19831819       status = gsl_multimin_fminimizer_iterate(s);
    1984 
     1820 
    19851821       if (status)
    19861822         break;
    1987 
     1823 
    19881824       size = gsl_multimin_fminimizer_size (s);
    19891825       status = gsl_multimin_test_size (size, 1e-2);
    1990 
     1826 
    19911827       if (status == GSL_SUCCESS)
    19921828         {
    19931829           printf ("converged to minimum at\n");
    19941830         }
    1995 
     1831 
    19961832       printf ("%5d ", (int)iter);
    19971833       for (i = 0; i < (size_t)np; i++)
     
    20021838     }
    20031839   while (status == GSL_CONTINUE && iter < 100);
    2004 
     1840 
    20051841  for (i=0;i<(size_t)np;i++)
    20061842    gsl_vector_set(par->x, i, gsl_vector_get(s->x, i));
     
    20191855  int ElementNo, AtomNo;
    20201856  CountElements();
    2021 
     1857 
    20221858  if (out == NULL) {
    20231859    return false;
     
    20541890  int ElementNo, AtomNo;
    20551891  CountElements();
    2056 
     1892 
    20571893  if (out == NULL) {
    20581894    return false;
     
    21011937  atom *Walker = start;
    21021938  while (Walker->next != end) {
    2103     Walker = Walker->next;
     1939    Walker = Walker->next; 
    21041940#ifdef ADDHYDROGEN
    21051941    if (Walker->type->Z != 1) {   // regard only non-hydrogen
     
    21321968  int No = 0;
    21331969  time_t now;
    2134 
     1970 
    21351971  now = time((time_t *)NULL);   // Get the system time and put it into 'now' as 'calender time'
    21361972  walker = start;
     
    21591995{
    21601996  atom *walker = NULL;
    2161   int AtomNo = 0, ElementNo;
     1997  int No = 0;
    21621998  time_t now;
    2163   element *runner = NULL;
    2164 
     1999 
    21652000  now = time((time_t *)NULL);   // Get the system time and put it into 'now' as 'calender time'
    21662001  walker = start;
    21672002  while (walker->next != end) { // go through every atom and count
    21682003    walker = walker->next;
    2169     AtomNo++;
     2004    No++;
    21702005  }
    21712006  if (out != NULL) {
    2172     *out << AtomNo << "\n\tCreated by molecuilder on " << ctime(&now);
    2173     ElementNo = 0;
    2174     runner = elemente->start;
    2175     while (runner->next != elemente->end) { // go through every element
    2176                 runner = runner->next;
    2177       if (ElementsInMolecule[runner->Z]) { // if this element got atoms
    2178         ElementNo++;
    2179         walker = start;
    2180         while (walker->next != end) { // go through every atom of this element
    2181           walker = walker->next;
    2182           if (walker->type == runner) { // if this atom fits to element
    2183             walker->OutputXYZLine(out);
    2184           }
    2185         }
    2186       }
     2007    *out << No << "\n\tCreated by molecuilder on " << ctime(&now);
     2008    walker = start;
     2009    while (walker->next != end) { // go through every atom of this element
     2010      walker = walker->next;
     2011      walker->OutputXYZLine(out);
    21872012    }
    21882013    return true;
     
    22152040              Walker->nr = i;   // update number in molecule (for easier referencing in FragmentMolecule lateron)
    22162041              if (Walker->type->Z != 1) // count non-hydrogen atoms whilst at it
    2217                 NoNonHydrogen++;
     2042                NoNonHydrogen++; 
    22182043              Free((void **)&Walker->Name, "molecule::CountAtoms: *walker->Name");
    22192044              Walker->Name = (char *) Malloc(sizeof(char)*6, "molecule::CountAtoms: *walker->Name");
     
    22232048            }
    22242049    } else
    2225         *out << Verbose(3) << "AtomCount is still " << AtomCount << ", thus counting nothing." << endl;
     2050        *out << Verbose(3) << "AtomCount is still " << AtomCount << ", thus counting nothing." << endl; 
    22262051  }
    22272052};
     
    22352060        ElementsInMolecule[i] = 0;
    22362061        ElementCount = 0;
    2237 
     2062       
    22382063  atom *walker = start;
    22392064  while (walker->next != end) {
     
    22712096    Binder = Binder->next;
    22722097    if (Binder->Cyclic)
    2273       No++;
     2098      No++;   
    22742099  }
    22752100  delete(BackEdgeStack);
     
    23292154
    23302155/** Creates an adjacency list of the molecule.
    2331  * We obtain an outside file with the indices of atoms which are bondmembers.
    2332  */
    2333 void molecule::CreateAdjacencyList2(ofstream *out, ifstream *input)
    2334 {
    2335 
    2336         // 1 We will parse bonds out of the dbond file created by tremolo.
    2337                         int atom1, atom2, temp;
    2338                         atom *Walker, *OtherWalker;
    2339 
    2340                 if (!input)
    2341                 {
    2342                         cout << Verbose(1) << "Opening silica failed \n";
    2343                 };
    2344 
    2345                         *input >> ws >> atom1;
    2346                         *input >> ws >> atom2;
    2347                 cout << Verbose(1) << "Scanning file\n";
    2348                 while (!input->eof()) // Check whether we read everything already
    2349                 {
    2350                                 *input >> ws >> atom1;
    2351                                 *input >> ws >> atom2;
    2352                         if(atom2<atom1) //Sort indices of atoms in order
    2353                         {
    2354                                 temp=atom1;
    2355                                 atom1=atom2;
    2356                                 atom2=temp;
    2357                         };
    2358 
    2359                         Walker=start;
    2360                         while(Walker-> nr != atom1) // Find atom corresponding to first index
    2361                         {
    2362                                 Walker = Walker->next;
    2363                         };
    2364                         OtherWalker = Walker->next;
    2365                         while(OtherWalker->nr != atom2) // Find atom corresponding to second index
    2366                         {
    2367                                 OtherWalker= OtherWalker->next;
    2368                         };
    2369                         AddBond(Walker, OtherWalker); //Add the bond between the two atoms with respective indices.
    2370                        
    2371                 }
    2372 
    2373                 CreateListOfBondsPerAtom(out);
    2374 
    2375 };
    2376 
    2377 
    2378 /** Creates an adjacency list of the molecule.
    23792156 * Generally, we use the CSD approach to bond recognition, that is the the distance
    23802157 * between two atoms A and B must be within [Rcov(A)+Rcov(B)-t,Rcov(A)+Rcov(B)+t] with
    2381  * a threshold t = 0.4 Angstroem.
     2158 * a threshold t = 0.4 Angstroem. 
    23822159 * To make it O(N log N) the function uses the linked-cell technique as follows:
    23832160 * The procedure is step-wise:
     
    23962173void molecule::CreateAdjacencyList(ofstream *out, double bonddistance, bool IsAngstroem)
    23972174{
    2398 
    23992175  atom *Walker = NULL, *OtherWalker = NULL, *Candidate = NULL;
    24002176  int No, NoBonds, CandidateBondNo;
     
    24122188    cleanup(first,last);
    24132189  }
    2414 
     2190       
    24152191  // count atoms in molecule = dimension of matrix (also give each unique name and continuous numbering)
    24162192  CountAtoms(out);
     
    24312207    for (int i=NumberCells;i--;)
    24322208      CellList[i] = NULL;
    2433 
     2209 
    24342210    // 2b. put all atoms into its corresponding list
    24352211    Walker = start;
     
    24522228      if (CellList[index] == NULL)  // allocate molecule if not done
    24532229        CellList[index] = new molecule(elemente);
    2454       OtherWalker = CellList[index]->AddCopyAtom(Walker); // add a copy of walker to this atom, father will be walker for later reference
    2455       //*out << Verbose(1) << "Copy Atom is " << *OtherWalker << "." << endl;
     2230      OtherWalker = CellList[index]->AddCopyAtom(Walker); // add a copy of walker to this atom, father will be walker for later reference 
     2231      //*out << Verbose(1) << "Copy Atom is " << *OtherWalker << "." << endl; 
    24562232    }
    24572233    //for (int i=0;i<NumberCells;i++)
    24582234      //*out << Verbose(1) << "Cell number " << i << ": " << CellList[i] << "." << endl;
    2459 
    2460 
     2235     
    24612236    // 3a. go through every cell
    24622237    for (N[0]=divisor[0];N[0]--;)
     
    24712246              Walker = Walker->next;
    24722247              //*out << Verbose(0) << "Current Atom is " << *Walker << "." << endl;
    2473               // 3c. check for possible bond between each atom in this and every one in the 27 cells
     2248              // 3c. check for possible bond between each atom in this and every one in the 27 cells 
    24742249              for (n[0]=-1;n[0]<=1;n[0]++)
    24752250                for (n[1]=-1;n[1]<=1;n[1]++)
     
    25032278          }
    25042279        }
    2505 
    2506 
    2507 
    25082280    // 4. free the cell again
    25092281    for (int i=NumberCells;i--;)
     
    25122284      }
    25132285    Free((void **)&CellList, "molecule::CreateAdjacencyList - ** CellList");
    2514 
     2286   
    25152287    // create the adjacency list per atom
    25162288    CreateListOfBondsPerAtom(out);
    2517 
     2289               
    25182290    // correct Bond degree of each bond by checking both bond partners for a mismatch between valence and current sum of bond degrees,
    25192291    // iteratively increase the one first where the other bond partner has the fewest number of bonds (i.e. in general bonds oxygene
     
    25742346    *out << endl;
    25752347  } else
    2576         *out << Verbose(1) << "AtomCount is " << AtomCount << ", thus no bonds, no connections!." << endl;
     2348        *out << Verbose(1) << "AtomCount is " << AtomCount << ", thus no bonds, no connections!." << endl; 
    25772349  *out << Verbose(0) << "End of CreateAdjacencyList." << endl;
    25782350  Free((void **)&matrix, "molecule::CreateAdjacencyList: *matrix");
    2579 
    2580 };
    2581 
    2582 
     2351};
    25832352
    25842353/** Performs a Depth-First search on this molecule.
     
    26012370  bond *Binder = NULL;
    26022371  bool BackStepping = false;
    2603 
     2372 
    26042373  *out << Verbose(0) << "Begin of DepthFirstSearchAnalysis" << endl;
    2605 
     2374 
    26062375  ResetAllBondsToUnused();
    26072376  ResetAllAtomNumbers();
     
    26162385    LeafWalker->Leaf = new molecule(elemente);
    26172386    LeafWalker->Leaf->AddCopyAtom(Root);
    2618 
     2387   
    26192388    OldGraphNr = CurrentGraphNr;
    26202389    Walker = Root;
     
    26272396          AtomStack->Push(Walker);
    26282397          CurrentGraphNr++;
    2629         }
     2398        }     
    26302399        do { // (3) if Walker has no unused egdes, go to (5)
    26312400          BackStepping = false; // reset backstepping flag for (8)
     
    26612430          Binder = NULL;
    26622431      } while (1);  // (2)
    2663 
     2432     
    26642433      // 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!
    26652434      if ((Walker == Root) && (Binder == NULL))
    26662435        break;
    2667 
    2668       // (5) if Ancestor of Walker is ...
     2436       
     2437      // (5) if Ancestor of Walker is ... 
    26692438      *out << Verbose(1) << "(5) Number of Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "] is " << Walker->Ancestor->GraphNr << "." << endl;
    26702439      if (Walker->Ancestor->GraphNr != Root->GraphNr) {
     
    27092478        } while (OtherAtom != Walker);
    27102479        ComponentNumber++;
    2711 
     2480   
    27122481        // (11) Root is separation vertex,  set Walker to Root and go to (4)
    27132482        Walker = Root;
     
    27222491
    27232492    // From OldGraphNr to CurrentGraphNr ranges an disconnected subgraph
    2724     *out << Verbose(0) << "Disconnected subgraph ranges from " << OldGraphNr << " to " << CurrentGraphNr << "." << endl;
     2493    *out << Verbose(0) << "Disconnected subgraph ranges from " << OldGraphNr << " to " << CurrentGraphNr << "." << endl;   
    27252494    LeafWalker->Leaf->Output(out);
    27262495    *out << endl;
     
    27302499      //*out << Verbose(1) << "Current next subgraph root candidate is " << Root->Name << "." << endl;
    27312500      if (Root->GraphNr != -1) // if already discovered, step on
    2732         Root = Root->next;
     2501        Root = Root->next; 
    27332502    }
    27342503  }
     
    27522521    *out << " with Lowpoint " << Walker->LowpointNr << " and Graph Nr. " << Walker->GraphNr << "." << endl;
    27532522  }
    2754 
     2523 
    27552524  *out << Verbose(1) << "Final graph info for each bond is:" << endl;
    27562525  Binder = first;
     
    27632532    *out << ((Binder->rightatom->SeparationVertex) ? "SP," : "") << "L" << Binder->rightatom->LowpointNr << " G" << Binder->rightatom->GraphNr << " Comp.";
    27642533    OutputComponentNumber(out, Binder->rightatom);
    2765     *out << ">." << endl;
     2534    *out << ">." << endl; 
    27662535    if (Binder->Cyclic) // cyclic ??
    27672536      *out << Verbose(3) << "Lowpoint at each side are equal: CYCLIC!" << endl;
     
    27782547 * the other our initial Walker - and do a Breadth First Search for the Root. We mark down each Predecessor and as soon as
    27792548 * we have found the Root via BFS, we may climb back the closed cycle via the Predecessors. Thereby we mark atoms and bonds
    2780  * as cyclic and print out the cycles.
     2549 * as cyclic and print out the cycles. 
    27812550 * \param *out output stream for debugging
    27822551 * \param *BackEdgeStack stack with all back edges found during DFS scan. Beware: This stack contains the bonds from the total molecule, not from the subgraph!
     
    27892558  int *ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::CyclicStructureAnalysis: *ShortestPathList");
    27902559  enum Shading *ColorList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::CyclicStructureAnalysis: *ColorList");
    2791   class StackClass<atom *> *BFSStack = new StackClass<atom *> (AtomCount);   // will hold the current ring
     2560  class StackClass<atom *> *BFSStack = new StackClass<atom *> (AtomCount);   // will hold the current ring 
    27922561  class StackClass<atom *> *TouchedStack = new StackClass<atom *> (AtomCount);   // contains all "touched" atoms (that need to be reset after BFS loop)
    27932562  atom *Walker = NULL, *OtherAtom = NULL, *Root = NULL;
     
    28042573  *out << Verbose(1) << "Back edge list - ";
    28052574  BackEdgeStack->Output(out);
    2806 
     2575 
    28072576  *out << Verbose(1) << "Analysing cycles ... " << endl;
    28082577  NumCycles = 0;
     
    28102579    BackEdge = BackEdgeStack->PopFirst();
    28112580    // this is the target
    2812     Root = BackEdge->leftatom;
     2581    Root = BackEdge->leftatom; 
    28132582    // this is the source point
    2814     Walker = BackEdge->rightatom;
     2583    Walker = BackEdge->rightatom; 
    28152584    ShortestPathList[Walker->nr] = 0;
    28162585    BFSStack->ClearStack();  // start with empty BFS stack
     
    28262595        if (Binder != BackEdge) { // only walk along DFS spanning tree (otherwise we always find SP of one being backedge Binder)
    28272596          OtherAtom = Binder->GetOtherAtom(Walker);
    2828 #ifdef ADDHYDROGEN
     2597#ifdef ADDHYDROGEN         
    28292598          if (OtherAtom->type->Z != 1) {
    28302599#endif
     
    28352604              PredecessorList[OtherAtom->nr] = Walker;  // Walker is the predecessor
    28362605              ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
    2837               *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;
     2606              *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; 
    28382607              //if (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr]) { // Check for maximum distance
    28392608                *out << Verbose(3) << "Putting OtherAtom into queue." << endl;
     
    28452614            if (OtherAtom == Root)
    28462615              break;
    2847 #ifdef ADDHYDROGEN
     2616#ifdef ADDHYDROGEN         
    28482617          } else {
    28492618            *out << Verbose(2) << "Skipping hydrogen atom " << *OtherAtom << "." << endl;
     
    28832652      }
    28842653    } while ((!BFSStack->IsEmpty()) && (OtherAtom != Root) && (OtherAtom != NULL)); // || (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr])));
    2885 
     2654   
    28862655    if (OtherAtom == Root) {
    28872656      // now climb back the predecessor list and thus find the cycle members
     
    29112680      *out << Verbose(1) << "No ring containing " << *Root << " with length equal to or smaller than " << MinimumRingSize[Walker->GetTrueFather()->nr] << " found." << endl;
    29122681    }
    2913 
     2682   
    29142683    // now clean the lists
    29152684    while (!TouchedStack->IsEmpty()){
     
    29212690  }
    29222691  if (MinRingSize != -1) {
    2923     // go over all atoms
     2692    // go over all atoms 
    29242693    Root = start;
    29252694    while(Root->next != end) {
    29262695      Root = Root->next;
    2927 
     2696     
    29282697      if (MinimumRingSize[Root->GetTrueFather()->nr] == AtomCount) { // check whether MinimumRingSize is set, if not BFS to next where it is
    29292698        Walker = Root;
     
    29622731          }
    29632732          ColorList[Walker->nr] = black;
    2964           //*out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
     2733          //*out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl; 
    29652734        }
    2966 
     2735   
    29672736        // now clean the lists
    29682737        while (!TouchedStack->IsEmpty()){
     
    30132782void molecule::OutputComponentNumber(ofstream *out, atom *vertex)
    30142783{
    3015   for(int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++)
     2784  for(int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++) 
    30162785    *out << vertex->ComponentNr[i] << "  ";
    30172786};
     
    30912860{
    30922861  int c = 0;
    3093   int FragmentCount;
     2862  int FragmentCount; 
    30942863  // get maximum bond degree
    30952864  atom *Walker = start;
     
    31012870  *out << Verbose(1) << "Upper limit for this subgraph is " << FragmentCount << " for " << NoNonHydrogen << " non-H atoms with maximum bond degree of " << c << "." << endl;
    31022871  return FragmentCount;
    3103 };
     2872}; 
    31042873
    31052874/** Scans a single line for number and puts them into \a KeySet.
    31062875 * \param *out output stream for debugging
    31072876 * \param *buffer buffer to scan
    3108  * \param &CurrentSet filled KeySet on return
     2877 * \param &CurrentSet filled KeySet on return 
    31092878 * \return true - at least one valid atom id parsed, false - CurrentSet is empty
    31102879 */
     
    31142883  int AtomNr;
    31152884  int status = 0;
    3116 
     2885 
    31172886  line.str(buffer);
    31182887  while (!line.eof()) {
     
    31502919  double TEFactor;
    31512920  char *filename = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::ParseKeySetFile - filename");
    3152 
     2921 
    31532922  if (FragmentList == NULL) { // check list pointer
    31542923    FragmentList = new Graph;
    31552924  }
    3156 
     2925 
    31572926  // 1st pass: open file and read
    31582927  *out << Verbose(1) << "Parsing the KeySet file ... " << endl;
     
    31832952    status = false;
    31842953  }
    3185 
     2954 
    31862955  // 2nd pass: open TEFactors file and read
    31872956  *out << Verbose(1) << "Parsing the TEFactors file ... " << endl;
     
    31952964        InputFile >> TEFactor;
    31962965        (*runner).second.second = TEFactor;
    3197         *out << Verbose(2) << "Setting " << ++NumberOfFragments << " fragment's TEFactor to " << (*runner).second.second << "." << endl;
     2966        *out << Verbose(2) << "Setting " << ++NumberOfFragments << " fragment's TEFactor to " << (*runner).second.second << "." << endl; 
    31982967      } else {
    31992968        status = false;
     
    32363005  if(output != NULL) {
    32373006    for(Graph::iterator runner = KeySetList.begin(); runner != KeySetList.end(); runner++) {
    3238       for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) {
     3007      for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) { 
    32393008        if (sprinter != (*runner).first.begin())
    32403009          output << "\t";
     
    33023071    status = false;
    33033072  }
    3304 
     3073 
    33053074  return status;
    33063075};
     
    33113080 * \param **ListOfAtoms allocated (molecule::AtomCount) and filled lookup table for ids (Atom::nr) to *Atom
    33123081 * \return true - structure is equal, false - not equivalence
    3313  */
     3082 */ 
    33143083bool molecule::CheckAdjacencyFileAgainstMolecule(ofstream *out, char *path, atom **ListOfAtoms)
    33153084{
     
    33183087  bool status = true;
    33193088  char *buffer = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer");
    3320 
     3089 
    33213090  filename << path << "/" << FRAGMENTPREFIX << ADJACENCYFILE;
    33223091  File.open(filename.str().c_str(), ios::out);
     
    33773146  *out << endl;
    33783147  Free((void **)&buffer, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer");
    3379 
     3148 
    33803149  return status;
    33813150};
     
    33993168  for(int i=AtomCount;i--;)
    34003169    AtomMask[i] = false;
    3401 
     3170 
    34023171  if (Order < 0) { // adaptive increase of BondOrder per site
    34033172    if (AtomMask[AtomCount] == true)  // break after one step
     
    34393208          line >> ws >> Value; // skip time entry
    34403209          line >> ws >> Value;
    3441           No -= 1;  // indices start at 1 in file, not 0
     3210          No -= 1;  // indices start at 1 in file, not 0 
    34423211          //*out << Verbose(2) << " - yields (" << No << "," << Value << ", " << FragOrder << ")" << endl;
    34433212
     
    34483217            // 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
    34493218            pair <map<int, pair<double,int> >::iterator, bool> InsertedElement = AdaptiveCriteriaList.insert( make_pair(*((*marker).second.begin()), pair<double,int>( fabs(Value), FragOrder) ));
    3450             map<int, pair<double,int> >::iterator PresentItem = InsertedElement.first;
     3219            map<int, pair<double,int> >::iterator PresentItem = InsertedElement.first; 
    34513220            if (!InsertedElement.second) { // this root is already present
    3452               if ((*PresentItem).second.second < FragOrder)  // if order there is lower, update entry with higher-order term
    3453                 //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)
     3221              if ((*PresentItem).second.second < FragOrder)  // if order there is lower, update entry with higher-order term 
     3222                //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) 
    34543223                {  // if value is smaller, update value and order
    34553224                (*PresentItem).second.first = fabs(Value);
     
    34893258        Walker = FindAtom(No);
    34903259        //if (Walker->AdaptiveOrder < MinimumRingSize[Walker->nr]) {
    3491           *out << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", setting entry " << No << " of Atom mask to true." << endl;
     3260          *out << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", setting entry " << No << " of Atom mask to true." << endl; 
    34923261          AtomMask[No] = true;
    34933262          status = true;
    34943263        //} else
    3495           //*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;
     3264          //*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; 
    34963265      }
    34973266      // close and done
     
    35273296    if ((Order == 0) && (AtomMask[AtomCount] == false))  // single stepping, just check
    35283297      status = true;
    3529 
     3298     
    35303299    if (!status) {
    35313300      if (Order == 0)
     
    35353304    }
    35363305  }
    3537 
     3306 
    35383307  // print atom mask for debugging
    35393308  *out << "              ";
     
    35443313    *out << (AtomMask[i] ? "t" : "f");
    35453314  *out << endl;
    3546 
     3315 
    35473316  return status;
    35483317};
     
    35583327  int AtomNo = 0;
    35593328  atom *Walker = NULL;
    3560 
     3329 
    35613330  if (SortIndex != NULL) {
    35623331    *out << Verbose(1) << "SortIndex is " << SortIndex << " and not NULL as expected." << endl;
     
    36163385  atom **ListOfAtoms = NULL;
    36173386  atom ***ListOfLocalAtoms = NULL;
    3618   bool *AtomMask = NULL;
    3619 
     3387  bool *AtomMask = NULL; 
     3388 
    36203389  *out << endl;
    36213390#ifdef ADDHYDROGEN
     
    36263395
    36273396  // ++++++++++++++++++++++++++++ INITIAL STUFF: Bond structure analysis, file parsing, ... ++++++++++++++++++++++++++++++++++++++++++
    3628 
     3397 
    36293398  // ===== 1. Check whether bond structure is same as stored in files ====
    3630 
     3399 
    36313400  // fill the adjacency list
    36323401  CreateListOfBondsPerAtom(out);
     
    36343403  // create lookup table for Atom::nr
    36353404  FragmentationToDo = FragmentationToDo && CreateFatherLookupTable(out, start, end, ListOfAtoms, AtomCount);
    3636 
     3405 
    36373406  // === compare it with adjacency file ===
    3638   FragmentationToDo = FragmentationToDo && CheckAdjacencyFileAgainstMolecule(out, configuration->configpath, ListOfAtoms);
     3407  FragmentationToDo = FragmentationToDo && CheckAdjacencyFileAgainstMolecule(out, configuration->configpath, ListOfAtoms); 
    36393408  Free((void **)&ListOfAtoms, "molecule::FragmentMolecule - **ListOfAtoms");
    36403409
     
    36593428//      else
    36603429//        *out << "\t" << ListOfLocalAtoms[FragmentCounter][i]->Name;
    3661     *out << Verbose(0) << "Gathering local back edges for subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
    36623430    MolecularWalker->Leaf->PickLocalBackEdges(out, ListOfLocalAtoms[FragmentCounter++], BackEdgeStack, LocalBackEdgeStack);
    3663     *out << Verbose(0) << "Analysing the cycles of subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
    36643431    MolecularWalker->Leaf->CyclicStructureAnalysis(out, LocalBackEdgeStack, MinimumRingSize);
    3665     *out << Verbose(0) << "Done with Analysing the cycles of subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
    36663432    delete(LocalBackEdgeStack);
    36673433  }
     
    36853451    FragmentationToDo = FragmentationToDo || CheckOrder;
    36863452    AtomMask[AtomCount] = true;   // last plus one entry is used as marker that we have been through this loop once already in CheckOrderAtSite()
    3687     // ===== 6b. fill RootStack for each subgraph (second adaptivity check) =====
     3453    // ===== 6b. fill RootStack for each subgraph (second adaptivity check) ===== 
    36883454    Subgraphs->next->FillRootStackForSubgraphs(out, RootStack, AtomMask, (FragmentCounter = 0));
    36893455
     
    36943460      MolecularWalker = MolecularWalker->next;
    36953461      *out << Verbose(1) << "Fragmenting subgraph " << MolecularWalker << "." << endl;
    3696       //MolecularWalker->Leaf->OutputListOfBonds(out);  // output ListOfBondsPerAtom for debugging
     3462      // output ListOfBondsPerAtom for debugging
     3463      MolecularWalker->Leaf->OutputListOfBonds(out);
    36973464      if (MolecularWalker->Leaf->first->next != MolecularWalker->Leaf->last) {
     3465     
    36983466        // call BOSSANOVA method
    36993467        *out << Verbose(0) << endl << " ========== BOND ENERGY of subgraph " << FragmentCounter << " ========================= " << endl;
     
    37153483  // ===== 8a. translate list into global numbers (i.e. ones that are valid in "this" molecule, not in MolecularWalker->Leaf)
    37163484  Subgraphs->next->TranslateIndicesToGlobalIDs(out, FragmentList, (FragmentCounter = 0), TotalNumberOfKeySets, TotalGraph);
    3717 
     3485 
    37183486  // free subgraph memory again
    37193487  FragmentCounter = 0;
     
    37403508    }
    37413509    *out << k << "/" << BondFragments->NumberOfMolecules << " fragments generated from the keysets." << endl;
    3742 
     3510   
    37433511    // ===== 9. Save fragments' configuration and keyset files et al to disk ===
    37443512    if (BondFragments->NumberOfMolecules != 0) {
    37453513      // create the SortIndex from BFS labels to order in the config file
    37463514      CreateMappingLabelsToConfigSequence(out, SortIndex);
    3747 
     3515     
    37483516      *out << Verbose(1) << "Writing " << BondFragments->NumberOfMolecules << " possible bond fragmentation configs" << endl;
    37493517      if (BondFragments->OutputConfigForListOfFragments(out, FRAGMENTPREFIX, configuration, SortIndex, true, true))
     
    37513519      else
    37523520        *out << Verbose(1) << "Some config writing failed." << endl;
    3753 
     3521 
    37543522      // store force index reference file
    37553523      BondFragments->StoreForcesFile(out, configuration->configpath, SortIndex);
    3756 
    3757       // store keysets file
     3524     
     3525      // store keysets file 
    37583526      StoreKeySetFile(out, TotalGraph, configuration->configpath);
    3759 
    3760       // store Adjacency file
     3527 
     3528      // store Adjacency file 
    37613529      StoreAdjacencyToFile(out, configuration->configpath);
    3762 
     3530 
    37633531      // store Hydrogen saturation correction file
    37643532      BondFragments->AddHydrogenCorrection(out, configuration->configpath);
    3765 
     3533     
    37663534      // store adaptive orders into file
    37673535      StoreOrderAtSiteFile(out, configuration->configpath);
    3768 
     3536     
    37693537      // restore orbital and Stop values
    37703538      CalculateOrbitals(*configuration);
    3771 
     3539     
    37723540      // free memory for bond part
    37733541      *out << Verbose(1) << "Freeing bond memory" << endl;
    37743542      delete(FragmentList); // remove bond molecule from memory
    3775       Free((void **)&SortIndex, "molecule::FragmentMolecule: *SortIndex");
     3543      Free((void **)&SortIndex, "molecule::FragmentMolecule: *SortIndex"); 
    37763544    } else
    37773545      *out << Verbose(1) << "FragmentList is zero on return, splitting failed." << endl;
    3778   //} else
     3546  //} else 
    37793547  //  *out << Verbose(1) << "No fragments to store." << endl;
    37803548  *out << Verbose(0) << "End of bond fragmentation." << endl;
     
    38053573  do {  // go through all bonds and push local ones
    38063574    Walker = ListOfLocalAtoms[Binder->leftatom->nr];  // get one atom in the reference molecule
    3807     if (Walker != NULL) // if this Walker exists in the subgraph ...
    3808         for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {    // go through the local list of bonds
    3809         OtherAtom = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
    3810               if (OtherAtom == ListOfLocalAtoms[Binder->rightatom->nr]) { // found the bond
    3811                 LocalStack->Push(ListOfBondsPerAtom[Walker->nr][i]);
    3812                 *out << Verbose(3) << "Found local edge " << *(ListOfBondsPerAtom[Walker->nr][i]) << "." << endl;
    3813                 break;
    3814             }
    3815         }
     3575    if (Walker == NULL) // if this Walker exists in the subgraph ...
     3576      continue;
     3577    for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {    // go through the local list of bonds
     3578      OtherAtom = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
     3579      if (OtherAtom == ListOfLocalAtoms[Binder->rightatom->nr]) { // found the bond
     3580        LocalStack->Push(ListOfBondsPerAtom[Walker->nr][i]);
     3581        break;
     3582      }
     3583    }
    38163584    Binder = ReferenceStack->PopFirst();  // loop the stack for next item
    3817     *out << Verbose(3) << "Current candidate edge " << Binder << "." << endl;
    38183585    ReferenceStack->Push(Binder);
    38193586  } while (FirstBond != Binder);
     
    38943661      Walker->AdaptiveOrder = OrderArray[Walker->nr];
    38953662      Walker->MaxOrder = MaxArray[Walker->nr];
    3896       *out << Verbose(2) << *Walker << " gets order " << (int)Walker->AdaptiveOrder << " and is " << (!Walker->MaxOrder ? "not " : " ") << "maxed." << endl;
     3663      *out << Verbose(2) << *Walker << " gets order " << (int)Walker->AdaptiveOrder << " and is " << (!Walker->MaxOrder ? "not " : " ") << "maxed." << endl; 
    38973664    }
    38983665    file.close();
     
    39053672  Free((void **)&OrderArray, "molecule::ParseOrderAtSiteFromFile - *OrderArray");
    39063673  Free((void **)&MaxArray, "molecule::ParseOrderAtSiteFromFile - *MaxArray");
    3907 
     3674 
    39083675  *out << Verbose(1) << "End of ParseOrderAtSiteFromFile" << endl;
    39093676  return status;
     
    39713738    }
    39723739    *out << " -- TotalDegree: " << TotalDegree << endl;
    3973   }
     3740  }     
    39743741  *out << Verbose(1) << "End of Creating ListOfBondsPerAtom." << endl << endl;
    39753742};
     
    39773744/** Adds atoms up to \a BondCount distance from \a *Root and notes them down in \a **AddedAtomList.
    39783745 * Gray vertices are always enqueued in an StackClass<atom *> FIFO queue, the rest is usual BFS with adding vertices found was
    3979  * white and putting into queue.
     3746 * white and putting into queue. 
    39803747 * \param *out output stream for debugging
    39813748 * \param *Mol Molecule class to add atoms to
     
    39863753 * \param BondOrder maximum distance for vertices to add
    39873754 * \param IsAngstroem lengths are in angstroem or bohrradii
    3988  */
     3755 */ 
    39893756void molecule::BreadthFirstSearchAdd(ofstream *out, molecule *Mol, atom **&AddedAtomList, bond **&AddedBondList, atom *Root, bond *Bond, int BondOrder, bool IsAngstroem)
    39903757{
     
    40123779  }
    40133780  ShortestPathList[Root->nr] = 0;
    4014 
     3781 
    40153782  // and go on ... Queue always contains all lightgray vertices
    40163783  while (!AtomStack->IsEmpty()) {
     
    40203787    // followed by n+1 till top of stack.
    40213788    Walker = AtomStack->PopFirst(); // pop oldest added
    4022     *out << Verbose(1) << "Current Walker is: " << Walker->Name << ", and has " << NumberOfBondsPerAtom[Walker->nr] << " bonds." << endl;
     3789    *out << Verbose(1) << "Current Walker is: " << Walker->Name << ", and has " << NumberOfBondsPerAtom[Walker->nr] << " bonds." << endl; 
    40233790    for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
    40243791      Binder = ListOfBondsPerAtom[Walker->nr][i];
     
    40273794        *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
    40283795        if (ColorList[OtherAtom->nr] == white) {
    4029           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)
     3796          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) 
    40303797            ColorList[OtherAtom->nr] = lightgray;
    40313798          PredecessorList[OtherAtom->nr] = Walker;  // Walker is the predecessor
    40323799          ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
    4033           *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;
     3800          *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; 
    40343801          if ((((ShortestPathList[OtherAtom->nr] < BondOrder) && (Binder != Bond))) ) { // Check for maximum distance
    40353802            *out << Verbose(3);
     
    40693836              } else {
    40703837#ifdef ADDHYDROGEN
    4071                 if (!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem))
    4072                   exit(1);
     3838                Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem);
    40733839#endif
    40743840              }
     
    40793845          // This has to be a cyclic bond, check whether it's present ...
    40803846          if (AddedBondList[Binder->nr] == NULL) {
    4081             if ((Binder != Bond) && (Binder->Cyclic) && (((ShortestPathList[Walker->nr]+1) < BondOrder))) {
     3847            if ((Binder != Bond) && (Binder->Cyclic) && (((ShortestPathList[Walker->nr]+1) < BondOrder))) { 
    40823848              AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
    40833849              AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
     
    40853851            } else { // if it's root bond it has to broken (otherwise we would not create the fragments)
    40863852#ifdef ADDHYDROGEN
    4087               if(!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem))
    4088                 exit(1);
     3853              Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem);
    40893854#endif
    40903855            }
     
    40943859    }
    40953860    ColorList[Walker->nr] = black;
    4096     *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
     3861    *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl; 
    40973862  }
    40983863  Free((void **)&PredecessorList, "molecule::BreadthFirstSearchAdd: **PredecessorList");
     
    41183883
    41193884  *out << Verbose(2) << "Begin of BuildInducedSubgraph." << endl;
    4120 
     3885 
    41213886  // reset parent list
    41223887  *out << Verbose(3) << "Resetting ParentList." << endl;
    41233888  for (int i=Father->AtomCount;i--;)
    41243889    ParentList[i] = NULL;
    4125 
     3890 
    41263891  // fill parent list with sons
    41273892  *out << Verbose(3) << "Filling Parent List." << endl;
     
    41643929 * \param *&Leaf KeySet to look through
    41653930 * \param *&ShortestPathList list of the shortest path to decide which atom to suggest as removal candidate in the end
    4166  * \param index of the atom suggested for removal
     3931 * \param index of the atom suggested for removal 
    41673932 */
    41683933int molecule::LookForRemovalCandidate(ofstream *&out, KeySet *&Leaf, int *&ShortestPathList)
     
    41703935  atom *Runner = NULL;
    41713936  int SP, Removal;
    4172 
     3937 
    41733938  *out << Verbose(2) << "Looking for removal candidate." << endl;
    41743939  SP = -1; //0;  // not -1, so that Root is never removed
     
    41883953/** Stores a fragment from \a KeySet into \a molecule.
    41893954 * First creates the minimal set of atoms from the KeySet, then creates the bond structure from the complete
    4190  * molecule and adds missing hydrogen where bonds were cut.
     3955 * molecule and adds missing hydrogen where bonds were cut. 
    41913956 * \param *out output stream for debugging messages
    4192  * \param &Leaflet pointer to KeySet structure
     3957 * \param &Leaflet pointer to KeySet structure 
    41933958 * \param IsAngstroem whether we have Ansgtroem or bohrradius
    41943959 * \return pointer to constructed molecule
     
    42013966  bool LonelyFlag = false;
    42023967  int size;
    4203 
     3968 
    42043969//  *out << Verbose(1) << "Begin of StoreFragmentFromKeyset." << endl;
    4205 
     3970 
    42063971  Leaf->BondDistance = BondDistance;
    42073972  for(int i=NDIM*2;i--;)
    4208     Leaf->cell_size[i] = cell_size[i];
     3973    Leaf->cell_size[i] = cell_size[i]; 
    42093974
    42103975  // initialise SonList (indicates when we need to replace a bond with hydrogen instead)
     
    42193984    size++;
    42203985  }
    4221 
     3986 
    42223987  // create the bonds between all: Make it an induced subgraph and add hydrogen
    42233988//  *out << Verbose(2) << "Creating bonds from father graph (i.e. induced subgraph creation)." << endl;
     
    42293994    if (SonList[FatherOfRunner->nr] != NULL)  {  // check if this, our father, is present in list
    42303995      // create all bonds
    4231       for (int i=0;i<NumberOfBondsPerAtom[FatherOfRunner->nr];i++) { // go through every bond of father
     3996      for (int i=0;i<NumberOfBondsPerAtom[FatherOfRunner->nr];i++) { // go through every bond of father 
    42323997        OtherFather = ListOfBondsPerAtom[FatherOfRunner->nr][i]->GetOtherAtom(FatherOfRunner);
    42333998//        *out << Verbose(2) << "Father " << *FatherOfRunner << " of son " << *SonList[FatherOfRunner->nr] << " is bound to " << *OtherFather;
    42343999        if (SonList[OtherFather->nr] != NULL) {
    4235 //          *out << ", whose son is " << *SonList[OtherFather->nr] << "." << endl;
     4000//          *out << ", whose son is " << *SonList[OtherFather->nr] << "." << endl; 
    42364001          if (OtherFather->nr > FatherOfRunner->nr) { // add bond (nr check is for adding only one of both variants: ab, ba)
    42374002//            *out << Verbose(3) << "Adding Bond: ";
    4238 //            *out <<
     4003//            *out << 
    42394004            Leaf->AddBond(Runner, SonList[OtherFather->nr], ListOfBondsPerAtom[FatherOfRunner->nr][i]->BondDegree);
    42404005//            *out << "." << endl;
    42414006            //NumBonds[Runner->nr]++;
    4242           } else {
     4007          } else { 
    42434008//            *out << Verbose(3) << "Not adding bond, labels in wrong order." << endl;
    42444009          }
    42454010          LonelyFlag = false;
    42464011        } else {
    4247 //          *out << ", who has no son in this fragment molecule." << endl;
     4012//          *out << ", who has no son in this fragment molecule." << endl; 
    42484013#ifdef ADDHYDROGEN
    42494014          //*out << Verbose(3) << "Adding Hydrogen to " << Runner->Name << " and a bond in between." << endl;
    4250           if(!Leaf->AddHydrogenReplacementAtom(out, ListOfBondsPerAtom[FatherOfRunner->nr][i], Runner, FatherOfRunner, OtherFather, ListOfBondsPerAtom[FatherOfRunner->nr],NumberOfBondsPerAtom[FatherOfRunner->nr], IsAngstroem))
    4251             exit(1);
     4015          Leaf->AddHydrogenReplacementAtom(out, ListOfBondsPerAtom[FatherOfRunner->nr][i], Runner, FatherOfRunner, OtherFather, ListOfBondsPerAtom[FatherOfRunner->nr],NumberOfBondsPerAtom[FatherOfRunner->nr], IsAngstroem);
    42524016#endif
    42534017          //NumBonds[Runner->nr] += ListOfBondsPerAtom[FatherOfRunner->nr][i]->BondDegree;
     
    42634027    while ((Runner->next != Leaf->end) && (Runner->next->type->Z == 1)) // skip added hydrogen
    42644028      Runner = Runner->next;
    4265 #endif
     4029#endif       
    42664030  }
    42674031  Leaf->CreateListOfBondsPerAtom(out);
     
    42964060  StackClass<atom *> *TouchedStack = new StackClass<atom *>((int)pow(4,Order)+2); // number of atoms reached from one with maximal 4 bonds plus Root itself
    42974061  StackClass<atom *> *SnakeStack = new StackClass<atom *>(Order+1); // equal to Order is not possible, as then the StackClass<atom *> cannot discern between full and empty stack!
    4298   MoleculeLeafClass *Leaflet = NULL, *TempLeaf = NULL;
     4062  MoleculeLeafClass *Leaflet = NULL, *TempLeaf = NULL; 
    42994063  MoleculeListClass *FragmentList = NULL;
    43004064  atom *Walker = NULL, *OtherAtom = NULL, *Root = NULL, *Removal = NULL;
     
    43464110                // clear snake stack
    43474111          SnakeStack->ClearStack();
    4348     //SnakeStack->TestImplementation(out, start->next);
     4112    //SnakeStack->TestImplementation(out, start->next);   
    43494113
    43504114    ///// INNER LOOP ////////////
     
    43674131        }
    43684132        if (ShortestPathList[Walker->nr] == -1) {
    4369           ShortestPathList[Walker->nr] = ShortestPathList[PredecessorList[Walker->nr]->nr]+1;
     4133          ShortestPathList[Walker->nr] = ShortestPathList[PredecessorList[Walker->nr]->nr]+1; 
    43704134          TouchedStack->Push(Walker); // mark every atom for lists cleanup later, whose shortest path has been changed
    43714135        }
     
    44054169                                OtherAtom = Binder->GetOtherAtom(Walker);
    44064170            if ((Labels[OtherAtom->nr] != -1) && (Labels[OtherAtom->nr] < Labels[Root->nr])) { // we don't step up to labels bigger than us
    4407               *out << "Label " << Labels[OtherAtom->nr] << " is smaller than Root's " << Labels[Root->nr] << "." << endl;
     4171              *out << "Label " << Labels[OtherAtom->nr] << " is smaller than Root's " << Labels[Root->nr] << "." << endl; 
    44084172              //ColorVertexList[OtherAtom->nr] = lightgray;    // mark as explored
    44094173            } else { // otherwise check its colour and element
    44104174                                if (
    44114175#ifdef ADDHYDROGEN
    4412               (OtherAtom->type->Z != 1) &&
     4176              (OtherAtom->type->Z != 1) && 
    44134177#endif
    44144178                    (ColorEdgeList[Binder->nr] == white)) {  // skip hydrogen, look for unexplored vertices
     
    44204184                //} else {
    44214185                //  *out << Verbose(3) << "Predecessor of " << OtherAtom->Name << " is " << PredecessorList[OtherAtom->nr]->Name << "." << endl;
    4422                 //}
     4186                //} 
    44234187                Walker = OtherAtom;
    44244188                break;
    44254189              } else {
    4426                 if (OtherAtom->type->Z == 1)
     4190                if (OtherAtom->type->Z == 1) 
    44274191                  *out << "Links to a hydrogen atom." << endl;
    4428                 else
     4192                else                 
    44294193                  *out << "Bond has not white but " << GetColor(ColorEdgeList[Binder->nr]) << " color." << endl;
    44304194              }
     
    44364200          *out << Verbose(3) << "We have gone too far, stepping back to " << Walker->Name << "." << endl;
    44374201        }
    4438                         if (Walker != OtherAtom) {      // if no white neighbours anymore, color it black
     4202                        if (Walker != OtherAtom) {      // if no white neighbours anymore, color it black 
    44394203          *out << Verbose(2) << "Coloring " << Walker->Name << " black." << endl;
    44404204                                ColorVertexList[Walker->nr] = black;
     
    44434207      }
    44444208        } while ((Walker != Root) || (ColorVertexList[Root->nr] != black));
    4445     *out << Verbose(2) << "Inner Looping is finished." << endl;
     4209    *out << Verbose(2) << "Inner Looping is finished." << endl;   
    44464210
    44474211    // if we reset all AtomCount atoms, we have again technically O(N^2) ...
     
    44594223    }
    44604224  }
    4461   *out << Verbose(1) << "Outer Looping over all vertices is done." << endl;
     4225  *out << Verbose(1) << "Outer Looping over all vertices is done." << endl; 
    44624226
    44634227  // copy together
    4464   *out << Verbose(1) << "Copying all fragments into MoleculeList structure." << endl;
     4228  *out << Verbose(1) << "Copying all fragments into MoleculeList structure." << endl; 
    44654229  FragmentList = new MoleculeListClass(FragmentCounter, AtomCount);
    44664230  RunningIndex = 0;
     
    45334297
    45344298  NumCombinations = 1 << SetDimension;
    4535 
     4299 
    45364300  // Hier muessen von 1 bis NumberOfBondsPerAtom[Walker->nr] alle Kombinationen
    45374301  // von Endstuecken (aus den Bonds) hinzugefᅵᅵgt werden und fᅵᅵr verbleibende ANOVAOrder
    45384302  // rekursiv GraphCrawler in der nᅵᅵchsten Ebene aufgerufen werden
    4539 
     4303 
    45404304  *out << Verbose(1+verbosity) << "Begin of SPFragmentGenerator." << endl;
    45414305  *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;
    45424306
    4543   // initialised touched list (stores added atoms on this level)
     4307  // initialised touched list (stores added atoms on this level) 
    45444308  *out << Verbose(1+verbosity) << "Clearing touched list." << endl;
    45454309  for (TouchedIndex=SubOrder+1;TouchedIndex--;)  // empty touched list
    45464310    TouchedList[TouchedIndex] = -1;
    45474311  TouchedIndex = 0;
    4548 
     4312 
    45494313  // create every possible combination of the endpieces
    45504314  *out << Verbose(1+verbosity) << "Going through all combinations of the power set." << endl;
     
    45544318    for (int j=SetDimension;j--;)
    45554319      bits += (i & (1 << j)) >> j;
    4556 
     4320     
    45574321    *out << Verbose(1+verbosity) << "Current set is " << Binary(i | (1 << SetDimension)) << ", number of bits is " << bits << "." << endl;
    45584322    if (bits <= SubOrder) { // if not greater than additional atoms allowed on stack, continue
     
    45624326        bit = ((i & (1 << j)) != 0);  // mask the bit for the j-th bond
    45634327        if (bit) {  // if bit is set, we add this bond partner
    4564                 OtherWalker = BondsSet[j]->rightatom;   // rightatom is always the one more distant, i.e. the one to add
     4328                OtherWalker = BondsSet[j]->rightatom;   // rightatom is always the one more distant, i.e. the one to add 
    45654329          //*out << Verbose(1+verbosity) << "Current Bond is " << ListOfBondsPerAtom[Walker->nr][i] << ", checking on " << *OtherWalker << "." << endl;
    45664330          *out << Verbose(2+verbosity) << "Adding " << *OtherWalker << " with nr " << OtherWalker->nr << "." << endl;
    4567           TestKeySetInsert = FragmentSearch->FragmentSet->insert(OtherWalker->nr);
     4331          TestKeySetInsert = FragmentSearch->FragmentSet->insert(OtherWalker->nr); 
    45684332          if (TestKeySetInsert.second) {
    45694333            TouchedList[TouchedIndex++] = OtherWalker->nr;  // note as added
     
    45784342        }
    45794343      }
    4580 
    4581       SpaceLeft = SubOrder - Added ;// SubOrder - bits; // due to item's maybe being already present, this does not work anymore
     4344     
     4345      SpaceLeft = SubOrder - Added ;// SubOrder - bits; // due to item's maybe being already present, this does not work anymore 
    45824346      if (SpaceLeft > 0) {
    45834347        *out << Verbose(1+verbosity) << "There's still some space left on stack: " << SpaceLeft << "." << endl;
     
    46074371          }
    46084372          *out << Verbose(2+verbosity) << "Calling subset generator " << SP << " away from root " << *FragmentSearch->Root << " with sub set dimension " << SubSetDimension << "." << endl;
    4609           SPFragmentGenerator(out, FragmentSearch, SP, BondsList, SubSetDimension, SubOrder-bits);
     4373          SPFragmentGenerator(out, FragmentSearch, SP, BondsList, SubSetDimension, SubOrder-bits); 
    46104374          Free((void **)&BondsList, "molecule::SPFragmentGenerator: **BondsList");
    46114375        }
     
    46164380        *out << Verbose(2) << "Found a new fragment[" << FragmentSearch->FragmentCounter << "], local nr.s are: ";
    46174381        for(KeySet::iterator runner = FragmentSearch->FragmentSet->begin(); runner != FragmentSearch->FragmentSet->end(); runner++)
    4618           *out << (*runner) << " ";
     4382          *out << (*runner) << " "; 
    46194383        *out << endl;
    46204384        //if (!CheckForConnectedSubgraph(out, FragmentSearch->FragmentSet))
     
    46244388        //Removal = StoreFragmentFromStack(out, FragmentSearch->Root, FragmentSearch->Leaflet, FragmentSearch->FragmentStack, FragmentSearch->ShortestPathList, &FragmentSearch->FragmentCounter, FragmentSearch->configuration);
    46254389      }
    4626 
     4390     
    46274391      // --3-- remove all added items in this level from snake stack
    46284392      *out << Verbose(1+verbosity) << "Removing all items that were added on this SP level " << RootDistance << "." << endl;
     
    46354399      *out << Verbose(2) << "Remaining local nr.s on snake stack are: ";
    46364400      for(KeySet::iterator runner = FragmentSearch->FragmentSet->begin(); runner != FragmentSearch->FragmentSet->end(); runner++)
    4637         *out << (*runner) << " ";
     4401        *out << (*runner) << " "; 
    46384402      *out << endl;
    46394403      TouchedIndex = 0; // set Index to 0 for list of atoms added on this level
     
    46424406    }
    46434407  }
    4644   Free((void **)&TouchedList, "molecule::SPFragmentGenerator: *TouchedList");
     4408  Free((void **)&TouchedList, "molecule::SPFragmentGenerator: *TouchedList"); 
    46454409  *out << Verbose(1+verbosity) << "End of SPFragmentGenerator, " << RootDistance << " away from Root " << *FragmentSearch->Root << " and SubOrder is " << SubOrder << "." << endl;
    46464410};
     
    46514415 * \return true - connected, false - disconnected
    46524416 * \note this is O(n^2) for it's just a bug checker not meant for permanent use!
    4653  */
     4417 */ 
    46544418bool molecule::CheckForConnectedSubgraph(ofstream *out, KeySet *Fragment)
    46554419{
     
    46574421  bool BondStatus = false;
    46584422  int size;
    4659 
     4423 
    46604424  *out << Verbose(1) << "Begin of CheckForConnectedSubgraph" << endl;
    46614425  *out << Verbose(2) << "Disconnected atom: ";
    4662 
     4426 
    46634427  // count number of atoms in graph
    46644428  size = 0;
     
    47064470 * \param *out output stream for debugging
    47074471 * \param Order bond order (limits BFS exploration and "number of digits" in power set generation
    4708  * \param FragmentSearch UniqueFragments structure containing TEFactor, root atom and so on
     4472 * \param FragmentSearch UniqueFragments structure containing TEFactor, root atom and so on 
    47094473 * \param RestrictedKeySet Restricted vertex set to use in context of molecule
    47104474 * \return number of inserted fragments
    47114475 * \note ShortestPathList in FragmentSearch structure is probably due to NumberOfAtomsSPLevel and SP not needed anymore
    47124476 */
    4713 int molecule::PowerSetGenerator(ofstream *out, int Order, struct UniqueFragments &FragmentSearch, KeySet RestrictedKeySet)
     4477int molecule::PowerSetGenerator(ofstream *out, int Order, struct UniqueFragments &FragmentSearch, KeySet RestrictedKeySet) 
    47144478{
    47154479  int SP, AtomKeyNr;
     
    47324496    FragmentSearch.BondsPerSPCount[i] = 0;
    47334497  FragmentSearch.BondsPerSPCount[0] = 1;
    4734   Binder = new bond(FragmentSearch.Root, FragmentSearch.Root);
     4498  Binder = new bond(FragmentSearch.Root, FragmentSearch.Root); 
    47354499  add(Binder, FragmentSearch.BondsPerSPList[1]);
    4736 
     4500 
    47374501  // do a BFS search to fill the SP lists and label the found vertices
    47384502  // Actually, we should construct a spanning tree vom the root atom and select all edges therefrom and put them into
    47394503  // according shortest path lists. However, we don't. Rather we fill these lists right away, as they do form a spanning
    47404504  // tree already sorted into various SP levels. That's why we just do loops over the depth (CurrentSP) and breadth
    4741   // (EdgeinSPLevel) of this tree ...
     4505  // (EdgeinSPLevel) of this tree ... 
    47424506  // In another picture, the bonds always contain a direction by rightatom being the one more distant from root and hence
    47434507  // naturally leftatom forming its predecessor, preventing the BFS"seeker" from continuing in the wrong direction.
     
    47924556    }
    47934557  }
    4794 
     4558 
    47954559  // outputting all list for debugging
    47964560  *out << Verbose(0) << "Printing all found lists." << endl;
     
    48014565      Binder = Binder->next;
    48024566      *out << Verbose(2) << *Binder << endl;
    4803     }
    4804   }
    4805 
     4567    } 
     4568  }
     4569 
    48064570  // creating fragments with the found edge sets  (may be done in reverse order, faster)
    48074571  SP = -1;  // the Root <-> Root edge must be subtracted!
     
    48104574    while (Binder->next != FragmentSearch.BondsPerSPList[2*i+1]) {
    48114575      Binder = Binder->next;
    4812       SP ++;
     4576      SP ++; 
    48134577    }
    48144578  }
     
    48174581    // start with root (push on fragment stack)
    48184582    *out << Verbose(0) << "Starting fragment generation with " << *FragmentSearch.Root << ", local nr is " << FragmentSearch.Root->nr << "." << endl;
    4819     FragmentSearch.FragmentSet->clear();
     4583    FragmentSearch.FragmentSet->clear(); 
    48204584    *out << Verbose(0) << "Preparing subset for this root and calling generator." << endl;
    48214585    // prepare the subset and call the generator
    48224586    BondsList = (bond **) Malloc(sizeof(bond *)*FragmentSearch.BondsPerSPCount[0], "molecule::PowerSetGenerator: **BondsList");
    48234587    BondsList[0] = FragmentSearch.BondsPerSPList[0]->next;  // on SP level 0 there's only the root bond
    4824 
     4588   
    48254589    SPFragmentGenerator(out, &FragmentSearch, 0, BondsList, FragmentSearch.BondsPerSPCount[0], Order);
    4826 
     4590   
    48274591    Free((void **)&BondsList, "molecule::PowerSetGenerator: **BondsList");
    48284592  } else {
     
    48334597  // remove root from stack
    48344598  *out << Verbose(0) << "Removing root again from stack." << endl;
    4835   FragmentSearch.FragmentSet->erase(FragmentSearch.Root->nr);
     4599  FragmentSearch.FragmentSet->erase(FragmentSearch.Root->nr);   
    48364600
    48374601  // free'ing the bonds lists
     
    48524616  }
    48534617
    4854   // return list
     4618  // return list 
    48554619  *out << Verbose(0) << "End of PowerSetGenerator." << endl;
    48564620  return (FragmentSearch.FragmentCounter - Counter);
     
    48834647    // remove bonds that are beyond bonddistance
    48844648    for(int i=NDIM;i--;)
    4885       Translationvector.x[i] = 0.;
     4649      Translationvector.x[i] = 0.; 
    48864650    // scan all bonds
    48874651    Binder = first;
     
    49304694        }
    49314695      }
    4932       // re-add bond
     4696      // re-add bond   
    49334697      link(Binder, OtherBinder);
    49344698    } else {
     
    49844748        IteratorB++;
    49854749      } // end of while loop
    4986     }// end of check in case of equal sizes
     4750    }// end of check in case of equal sizes 
    49874751  }
    49884752  return false; // if we reach this point, they are equal
     
    50284792 * \param graph1 first (dest) graph
    50294793 * \param graph2 second (source) graph
    5030  * \param *counter keyset counter that gets increased
     4794 * \param *counter keyset counter that gets increased 
    50314795 */
    50324796inline void InsertGraphIntoGraph(ofstream *out, Graph &graph1, Graph &graph2, int *counter)
     
    50734837  int RootKeyNr, RootNr;
    50744838  struct UniqueFragments FragmentSearch;
    5075 
     4839 
    50764840  *out << Verbose(0) << "Begin of FragmentBOSSANOVA." << endl;
    50774841
     
    50964860    Walker = Walker->next;
    50974861    CompleteMolecule.insert(Walker->GetTrueFather()->nr);
    5098   }
     4862  } 
    50994863
    51004864  // 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
     
    51104874    //if ((MinimumRingSize[Walker->GetTrueFather()->nr] != -1) && (Walker->GetTrueFather()->AdaptiveOrder+1 > MinimumRingSize[Walker->GetTrueFather()->nr])) {
    51114875    //  *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;
    5112     //} else
     4876    //} else 
    51134877    {
    51144878      // increase adaptive order by one
    51154879      Walker->GetTrueFather()->AdaptiveOrder++;
    51164880      Order = Walker->AdaptiveOrder = Walker->GetTrueFather()->AdaptiveOrder;
    5117 
     4881 
    51184882      // initialise Order-dependent entries of UniqueFragments structure
    51194883      FragmentSearch.BondsPerSPList = (bond **) Malloc(sizeof(bond *)*Order*2, "molecule::PowerSetGenerator: ***BondsPerSPList");
     
    51224886        FragmentSearch.BondsPerSPList[2*i] = new bond();    // start node
    51234887        FragmentSearch.BondsPerSPList[2*i+1] = new bond();  // end node
    5124         FragmentSearch.BondsPerSPList[2*i]->next = FragmentSearch.BondsPerSPList[2*i+1];     // intertwine these two
     4888        FragmentSearch.BondsPerSPList[2*i]->next = FragmentSearch.BondsPerSPList[2*i+1];     // intertwine these two 
    51254889        FragmentSearch.BondsPerSPList[2*i+1]->previous = FragmentSearch.BondsPerSPList[2*i];
    51264890        FragmentSearch.BondsPerSPCount[i] = 0;
    5127       }
    5128 
     4891      } 
     4892 
    51294893      // allocate memory for all lower level orders in this 1D-array of ptrs
    51304894      NumLevels = 1 << (Order-1); // (int)pow(2,Order);
     
    51324896      for (int i=0;i<NumLevels;i++)
    51334897        FragmentLowerOrdersList[RootNr][i] = NULL;
    5134 
     4898     
    51354899      // create top order where nothing is reduced
    51364900      *out << Verbose(0) << "==============================================================================================================" << endl;
    51374901      *out << Verbose(0) << "Creating KeySets of Bond Order " << Order << " for " << *Walker << ", " << (RootStack.size()-RootNr) << " Roots remaining." << endl; // , NumLevels is " << NumLevels << "
    5138 
     4902 
    51394903      // Create list of Graphs of current Bond Order (i.e. F_{ij})
    51404904      FragmentLowerOrdersList[RootNr][0] =  new Graph;
     
    51494913        // we don't have to dive into suborders! These keysets are all already created on lower orders!
    51504914        // this was all ancient stuff, when we still depended on the TEFactors (and for those the suborders were needed)
    5151 
     4915       
    51524916//        if ((NumLevels >> 1) > 0) {
    51534917//          // create lower order fragments
     
    51564920//          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)
    51574921//            // step down to next order at (virtual) boundary of powers of 2 in array
    5158 //            while (source >= (1 << (Walker->AdaptiveOrder-Order))) // (int)pow(2,Walker->AdaptiveOrder-Order))
     4922//            while (source >= (1 << (Walker->AdaptiveOrder-Order))) // (int)pow(2,Walker->AdaptiveOrder-Order))   
    51594923//              Order--;
    51604924//            *out << Verbose(0) << "Current Order is: " << Order << "." << endl;
     
    51634927//              *out << Verbose(0) << "--------------------------------------------------------------------------------------------------------------" << endl;
    51644928//              *out << Verbose(0) << "Current SubOrder is: " << SubOrder << " with source " << source << " to destination " << dest << "." << endl;
    5165 //
     4929//       
    51664930//              // every molecule is split into a list of again (Order - 1) molecules, while counting all molecules
    51674931//              //*out << Verbose(1) << "Splitting the " << (*FragmentLowerOrdersList[RootNr][source]).size() << " molecules of the " << source << "th cell in the array." << endl;
     
    51944958      RootStack.push_back(RootKeyNr); // put back on stack
    51954959      RootNr++;
    5196 
     4960 
    51974961      // free Order-dependent entries of UniqueFragments structure for next loop cycle
    51984962      Free((void **)&FragmentSearch.BondsPerSPCount, "molecule::PowerSetGenerator: *BondsPerSPCount");
     
    52004964        delete(FragmentSearch.BondsPerSPList[2*i]);
    52014965        delete(FragmentSearch.BondsPerSPList[2*i+1]);
    5202       }
     4966      } 
    52034967      Free((void **)&FragmentSearch.BondsPerSPList, "molecule::PowerSetGenerator: ***BondsPerSPList");
    52044968    }
     
    52114975  Free((void **)&FragmentSearch.ShortestPathList, "molecule::PowerSetGenerator: *ShortestPathList");
    52124976  delete(FragmentSearch.FragmentSet);
    5213 
    5214   // now, FragmentLowerOrdersList is complete, it looks - for BondOrder 5 - as this (number is the ANOVA Order of the terms therein)
     4977 
     4978  // now, FragmentLowerOrdersList is complete, it looks - for BondOrder 5 - as this (number is the ANOVA Order of the terms therein) 
    52154979  // 5433222211111111
    52164980  // 43221111
     
    52324996    RootKeyNr = RootStack.front();
    52334997    RootStack.pop_front();
    5234     Walker = FindAtom(RootKeyNr);
     4998    Walker = FindAtom(RootKeyNr); 
    52354999    NumLevels = 1 << (Walker->AdaptiveOrder - 1);
    52365000    for(int i=0;i<NumLevels;i++) {
     
    52455009  Free((void **)&FragmentLowerOrdersList, "molecule::FragmentBOSSANOVA: ***FragmentLowerOrdersList");
    52465010  Free((void **)&NumMoleculesOfOrder, "molecule::FragmentBOSSANOVA: *NumMoleculesOfOrder");
    5247 
     5011 
    52485012  *out << Verbose(0) << "End of FragmentBOSSANOVA." << endl;
    52495013};
     
    52795043  atom *Walker = NULL;
    52805044  bool result = true; // status of comparison
    5281 
    5282   *out << Verbose(3) << "Begin of IsEqualToWithinThreshold." << endl;
     5045 
     5046  *out << Verbose(3) << "Begin of IsEqualToWithinThreshold." << endl; 
    52835047  /// first count both their atoms and elements and update lists thereby ...
    52845048  //*out << Verbose(0) << "Counting atoms, updating list" << endl;
     
    53275091    if (CenterOfGravity.Distance(&OtherCenterOfGravity) > threshold) {
    53285092      *out << Verbose(4) << "Centers of gravity don't match." << endl;
    5329       result = false;
    5330     }
    5331   }
    5332 
     5093      result = false; 
     5094    }
     5095  }
     5096 
    53335097  /// ... then make a list with the euclidian distance to this center for each atom of both molecules
    53345098  if (result) {
     
    53465110      OtherDistances[Walker->nr] = OtherCenterOfGravity.Distance(&Walker->x);
    53475111    }
    5348 
     5112 
    53495113    /// ... sort each list (using heapsort (o(N log N)) from GSL)
    53505114    *out << Verbose(5) << "Sorting distances" << endl;
     
    53575121    for(int i=AtomCount;i--;)
    53585122      PermutationMap[PermMap[i]] = (int) OtherPermMap[i];
    5359 
     5123   
    53605124    /// ... and compare them step by step, whether the difference is individiually(!) below \a threshold for all
    53615125    *out << Verbose(4) << "Comparing distances" << endl;
     
    53685132    Free((void **)&PermMap, "molecule::IsEqualToWithinThreshold: *PermMap");
    53695133    Free((void **)&OtherPermMap, "molecule::IsEqualToWithinThreshold: *OtherPermMap");
    5370 
     5134     
    53715135    /// free memory
    53725136    Free((void **)&Distances, "molecule::IsEqualToWithinThreshold: Distances");
     
    53765140      result = false;
    53775141    }
    5378   }
     5142  } 
    53795143  /// return pointer to map if all distances were below \a threshold
    53805144  *out << Verbose(3) << "End of IsEqualToWithinThreshold." << endl;
     
    53855149    *out << Verbose(3) << "Result: Not equal." << endl;
    53865150    return NULL;
    5387   }
     5151  } 
    53885152};
    53895153
     
    54405204 * \param *output output stream of temperature file
    54415205 * \return file written (true), failure on writing file (false)
    5442  */
     5206 */ 
    54435207bool molecule::OutputTemperatureFromTrajectories(ofstream *out, int startstep, int endstep, ofstream *output)
    54445208{
     
    54485212  if (output == NULL)
    54495213    return false;
    5450   else
     5214  else 
    54515215    *output << "# Step Temperature [K] Temperature [a.u.]" << endl;
    54525216  for (int step=startstep;step < endstep; step++) { // loop over all time steps
  • src/molecules.hpp

    • Property mode changed from 100755 to 100644
    r986c80 redcda5  
    11/** \file molecules.hpp
    22 *
    3  * Class definitions of atom and molecule, element and periodentafel
     3 * Class definitions of atom and molecule, element and periodentafel 
    44 */
    55
     
    1616#include <gsl/gsl_multimin.h>
    1717#include <gsl/gsl_vector.h>
    18 #include <gsl/gsl_randist.h>
    1918
    2019// STL headers
     
    5655#define BoundariesTestPair pair< Boundaries::iterator, bool>
    5756
    58 #define PointMap map < int, class BoundaryPointSet * >
    59 #define PointPair pair < int, class BoundaryPointSet * >
    60 #define PointTestPair pair < PointMap::iterator, bool >
    61 
    62 #define LineMap map < int, class BoundaryLineSet * >
    63 #define LinePair pair < int, class BoundaryLineSet * >
    64 #define LineTestPair pair < LineMap::iterator, bool >
    65 
    66 #define TriangleMap map < int, class BoundaryTriangleSet * >
    67 #define TrianglePair pair < int, class BoundaryTriangleSet * >
    68 #define TriangleTestPair pair < TrianglePair::iterator, bool >
     57#define PointMap map < int, class BoundaryPointSet * > 
     58#define PointPair pair < int, class BoundaryPointSet * > 
     59#define PointTestPair pair < PointMap::iterator, bool > 
     60
     61#define LineMap map < int, class BoundaryLineSet * > 
     62#define LinePair pair < int, class BoundaryLineSet * > 
     63#define LineTestPair pair < LinePair::iterator, bool >
     64
     65#define TriangleMap map < int, class BoundaryTriangleSet * > 
     66#define TrianglePair pair < int, class BoundaryTriangleSet * > 
     67#define TriangleTestPair pair < TrianglePair::iterator, bool > 
    6968
    7069#define DistanceMultiMap multimap <double, pair < PointMap::iterator, PointMap::iterator> >
     
    8887//bool operator < (KeySet SubgraphA, KeySet SubgraphB);   //note: this declaration is important, otherwise normal < is used (producing wrong order)
    8988inline void InsertFragmentIntoGraph(ofstream *out, struct UniqueFragments *Fragment); // Insert a KeySet into a Graph
    90 inline void InsertGraphIntoGraph(ofstream *out, Graph &graph1, Graph &graph2, int *counter);  // Insert all KeySet's in a Graph into another Graph
     89inline void InsertGraphIntoGraph(ofstream *out, Graph &graph1, Graph &graph2, int *counter);  // Insert all KeySet's in a Graph into another Graph 
    9190int CompareDoubles (const void * a, const void * b);
    9291
     
    142141    unsigned char AdaptiveOrder;  //!< current present bond order at site (0 means "not set")
    143142    bool MaxOrder;  //!< whether this atom as a root in fragmentation still creates more fragments on higher orders or not
    144 
     143 
    145144  atom();
    146145  ~atom();
    147 
     146 
    148147  bool Output(int ElementNo, int AtomNo, ofstream *out) const;
    149148  bool OutputXYZLine(ofstream *out) const;
    150149  atom *GetTrueFather();
    151150  bool Compare(atom &ptr);
    152 
     151 
    153152  private:
    154153};
    155154
    156 ostream & operator << (ostream &ost, const atom &a);
     155ostream & operator << (ostream &ost, atom &a);
    157156
    158157/** Bonds between atoms.
     
    171170    int nr;           //!< unique number in a molecule, updated by molecule::CreateAdjacencyList()
    172171    bool Cyclic;      //!< flag whether bond is part of a cycle or not, given in DepthFirstSearchAnalysis()
    173     enum EdgeType Type;//!< whether this is a tree or back edge
    174 
     172    enum EdgeType Type;//!< whether this is a tree or back edge 
     173       
    175174  atom * GetOtherAtom(atom *Atom) const;
    176175  bond * GetFirstBond();
    177176  bond * GetLastBond();
    178 
     177 
    179178  bool MarkUsed(enum Shading color);
    180179  enum Shading IsUsed();
     
    182181  bool Contains(const atom *ptr);
    183182  bool Contains(const int nr);
    184 
     183 
    185184  bond();
    186185  bond(atom *left, atom *right);
     
    188187  bond(atom *left, atom *right, int degree, int number);
    189188  ~bond();
    190 
    191   private:
     189   
     190  private: 
    192191    enum Shading Used;        //!< marker in depth-first search, DepthFirstSearchAnalysis()
    193192};
    194193
    195 
    196 ostream & operator << (ostream &ost, const bond &b);
     194ostream & operator << (ostream &ost, bond &b);
    197195
    198196class MoleculeLeafClass;
    199 
    200 
    201 #define MaxThermostats 6      //!< maximum number of thermostat entries in Ions#ThermostatNames and Ions#ThermostatImplemented
    202 enum thermostats { None, Woodcock, Gaussian, Langevin, Berendsen, NoseHoover };   //!< Thermostat names for output
    203 
    204197
    205198/** The complete molecule.
     
    226219    int NoCyclicBonds;  //!< number of cyclic bonds in molecule, by DepthFirstSearchAnalysis()
    227220    double BondDistance;  //!< typical bond distance used in CreateAdjacencyList() and furtheron
    228 
     221 
    229222  molecule(periodentafel *teil);
    230223  ~molecule();
    231 
     224 
    232225  /// remove atoms from molecule.
    233226  bool AddAtom(atom *pointer);
     
    238231  atom * AddCopyAtom(atom *pointer);
    239232  bool AddXYZFile(string filename);
    240   bool AddHydrogenReplacementAtom(ofstream *out, bond *Bond, atom *BottomOrigin, atom *TopOrigin, atom *TopReplacement, bond **BondList, int NumBond, bool IsAngstroem);
     233  bool AddHydrogenReplacementAtom(ofstream *out, bond *Bond, atom *BottomOrigin, atom *TopOrigin, atom *TopReplacement, bond **BondList, int NumBond, bool IsAngstroem); 
    241234  bond * AddBond(atom *first, atom *second, int degree);
    242235  bool RemoveBond(bond *pointer);
    243236  bool RemoveBonds(atom *BondPartner);
    244 
     237   
    245238  /// Find atoms.
    246   atom * FindAtom(int Nr) const;
     239  atom * FindAtom(int Nr) const; 
    247240  atom * AskAtom(string text);
    248241
     
    252245  void CalculateOrbitals(class config &configuration);
    253246  bool CenterInBox(ofstream *out, Vector *BoxLengths);
    254   void CenterEdge(ofstream *out, Vector *max);
    255   void CenterOrigin(ofstream *out, Vector *max);
     247  void CenterEdge(ofstream *out, Vector *max); 
     248  void CenterOrigin(ofstream *out, Vector *max); 
    256249  void CenterGravity(ofstream *out, Vector *max);
    257250  void Translate(const Vector *x);
     
    267260        void PrincipalAxisSystem(ofstream *out, bool DoRotate);
    268261        double VolumeOfConvexEnvelope(ofstream *out, bool IsAngstroem);
    269        
    270   bool VerletForceIntegration(ofstream *out, char *file, config &configuration);
    271   void Thermostats(config &configuration, double ActualTemp, int Thermostat);
    272 
    273   double ConstrainedPotential(ofstream *out, atom **permutation, int start, int end, double *constants, bool IsAngstroem);
    274   double MinimiseConstrainedPotential(ofstream *out, atom **&permutation, int startstep, int endstep, bool IsAngstroem);
    275   void EvaluateConstrainedForces(ofstream *out, int startstep, int endstep, atom **PermutationMap, ForceMatrix *Force);
    276   bool LinearInterpolationBetweenConfiguration(ofstream *out, int startstep, int endstep, const char *prefix, config &configuration);
     262        bool VerletForceIntegration(ofstream *out, char *file, double delta_t, bool IsAngstroem, int DoConstrained);
     263        double ConstrainedPotential(ofstream *out, atom **permutation, int start, int end, double *constants, bool IsAngstroem);
     264        double MinimiseConstrainedPotential(ofstream *out, atom **&permutation, int startstep, int endstep, bool IsAngstroem);
     265        void EvaluateConstrainedForces(ofstream *out, int startstep, int endstep, atom **PermutationMap, ForceMatrix *Force);
     266        bool LinearInterpolationBetweenConfiguration(ofstream *out, int startstep, int endstep, const char *prefix, config &configuration);
    277267       
    278268  bool CheckBounds(const Vector *x) const;
    279269  void GetAlignvector(struct lsq_params * par) const;
    280270
    281   /// Initialising routines in fragmentation
    282   void CreateAdjacencyList2(ofstream *out, ifstream *output);
     271  /// Initialising routines in fragmentation 
    283272  void CreateAdjacencyList(ofstream *out, double bonddistance, bool IsAngstroem);
    284273  void CreateListOfBondsPerAtom(ofstream *out);
    285 
     274 
    286275  // Graph analysis
    287276  MoleculeLeafClass * DepthFirstSearchAnalysis(ofstream *out, class StackClass<bond *> *&BackEdgeStack);
     
    299288
    300289  molecule *CopyMolecule();
    301 
     290 
    302291  /// Fragment molecule by two different approaches:
    303292  int FragmentMolecule(ofstream *out, int Order, config *configuration);
     
    321310  int LookForRemovalCandidate(ofstream *&out, KeySet *&Leaf, int *&ShortestPathList);
    322311  int GuesstimateFragmentCount(ofstream *out, int order);
    323 
    324   // Recognize doubly appearing molecules in a list of them
     312         
     313  // Recognize doubly appearing molecules in a list of them   
    325314  int * IsEqualToWithinThreshold(ofstream *out, molecule *OtherMolecule, double threshold);
    326315  int * GetFatherSonAtomicMap(ofstream *out, molecule *OtherMolecule);
    327 
     316       
    328317  // Output routines.
    329318  bool Output(ofstream *out);
     
    346335    int NumberOfMolecules;        //!< Number of entries in \a **FragmentList and of to be returned one.
    347336    int NumberOfTopAtoms;         //!< Number of atoms in the molecule from which all fragments originate
    348 
     337   
    349338  MoleculeListClass();
    350339  MoleculeListClass(int Num, int NumAtoms);
     
    356345  bool OutputConfigForListOfFragments(ofstream *out, const char *fragmentprefix, config *configuration, int *SortIndex, bool DoPeriodic, bool DoCentering);
    357346  void Output(ofstream *out);
    358 
     347 
    359348  private:
    360349};
     
    366355class MoleculeLeafClass {
    367356  public:
    368     molecule *Leaf;                   //!< molecule of this leaf
     357    molecule *Leaf;                   //!< molecule of this leaf 
    369358    //MoleculeLeafClass *UpLeaf;        //!< Leaf one level up
    370359    //MoleculeLeafClass *DownLeaf;      //!< First leaf one level down
     
    402391    bool FastParsing;
    403392    double Deltat;
    404     string basis;
    405 
    406393    int DoConstrainedMD;
    407394    int MaxOuterStep;
    408     int Thermostat;
    409     int *ThermostatImplemented;
    410     char **ThermostatNames;
    411     double TempFrequency;
    412     double alpha;
    413     double HooverMass;
    414     double TargetTemp;
    415     int ScaleTempStep;
    416395   
    417396    private:
     
    419398    char *defaultpath;
    420399    char *pseudopotpath;
    421 
     400   
    422401    int DoOutVis;
    423402    int DoOutMes;
     
    434413    int UseAddGramSch;
    435414    int Seed;
    436 
     415   
    437416    int OutVisStep;
    438417    int OutSrcStep;
     418    double TargetTemp;
     419    int ScaleTempStep;
    439420    int MaxPsiStep;
    440421    double EpsWannier;
    441 
     422   
    442423    int MaxMinStep;
    443424    double RelEpsTotalEnergy;
     
    448429    double InitRelEpsKineticEnergy;
    449430    int InitMaxMinGapStopStep;
    450 
     431   
    451432    //double BoxLength[NDIM*NDIM];
    452 
     433   
    453434    double ECut;
    454435    int MaxLevel;
     
    459440    int RTActualUse;
    460441    int AddPsis;
    461 
     442   
    462443    double RCut;
    463444    int StructOpt;
     
    466447    int MaxTypes;
    467448
    468 
     449 
    469450  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);
    470 
     451 
    471452  public:
    472453  config();
     
    477458  void LoadOld(char *filename, periodentafel *periode, molecule *mol);
    478459  void RetrieveConfigPathAndName(string filename);
    479   bool Save(const char *filename, periodentafel *periode, molecule *mol) const;
    480   bool SaveMPQC(const char *filename, molecule *mol) const;
     460  bool Save(ofstream *file, periodentafel *periode, molecule *mol) const;
     461  bool SaveMPQC(ofstream *file, molecule *mol) const;
    481462  void Edit(molecule *mol);
    482463  bool GetIsAngstroem() const;
    483464  char *GetDefaultPath() const;
    484465  void SetDefaultPath(const char *path);
    485   void InitThermostats(ifstream *source);
    486466};
    487467
  • src/orbitals.db

    • Property mode changed from 100755 to 100644
    r986c80 redcda5  
    181818      0
    191919      1
    20 20      4
     2020      2
    212121      3
    222222      4
  • src/parser.cpp

    • Property mode changed from 100755 to 100644
    r986c80 redcda5  
    5656MatrixContainer::MatrixContainer() {
    5757  Indices = NULL;
    58   Header = (char **) Malloc(sizeof(char)*1, "MatrixContainer::MatrixContainer: **Header");
     58  Header = (char *) Malloc(sizeof(char)*1023, "MatrixContainer::MatrixContainer: *Header");
    5959  Matrix = (double ***) Malloc(sizeof(double **)*(1), "MatrixContainer::MatrixContainer: ***Matrix"); // one more each for the total molecule
    6060  RowCounter = (int *) Malloc(sizeof(int)*(1), "MatrixContainer::MatrixContainer: *RowCounter");
    61   ColumnCounter = (int *) Malloc(sizeof(int)*(1), "MatrixContainer::MatrixContainer: *ColumnCounter");
    62   Header[0] = NULL;
    6361  Matrix[0] = NULL;
    6462  RowCounter[0] = -1;
    6563  MatrixCounter = 0;
    66   ColumnCounter[0] = -1;
     64  ColumnCounter = 0;
    6765};
    6866
     
    7270  if (Matrix != NULL) {
    7371    for(int i=MatrixCounter;i--;) {
    74       if ((ColumnCounter != NULL) && (RowCounter != NULL)) {
     72      if (RowCounter != NULL) {
    7573          for(int j=RowCounter[i]+1;j--;)
    7674            Free((void **)&Matrix[i][j], "MatrixContainer::~MatrixContainer: *Matrix[][]");
     
    7876      }
    7977    }
    80     if ((ColumnCounter != NULL) && (RowCounter != NULL) && (Matrix[MatrixCounter] != NULL))
     78    if ((RowCounter != NULL) && (Matrix[MatrixCounter] != NULL))
    8179      for(int j=RowCounter[MatrixCounter]+1;j--;)
    8280        Free((void **)&Matrix[MatrixCounter][j], "MatrixContainer::~MatrixContainer: *Matrix[MatrixCounter][]");
     
    9189  Free((void **)&Indices, "MatrixContainer::~MatrixContainer: **Indices");
    9290 
    93   if (Header != NULL)
    94     for(int i=MatrixCounter+1;i--;)
    95       Free((void **)&Header[i], "MatrixContainer::~MatrixContainer: *Header[]");
    96   Free((void **)&Header, "MatrixContainer::~MatrixContainer: **Header");
     91  Free((void **)&Header, "MatrixContainer::~MatrixContainer: *Header");
    9792  Free((void **)&RowCounter, "MatrixContainer::~MatrixContainer: *RowCounter");
    98   Free((void **)&ColumnCounter, "MatrixContainer::~MatrixContainer: *RowCounter");
    99 };
    100 
    101 /** Either copies index matrix from another MatrixContainer or initialises with trivial mapping if NULL.
    102  * This either copies the index matrix or just maps 1 to 1, 2 to 2 and so on for all fragments.
    103  * \param *Matrix pointer to other MatrixContainer
    104  * \return true - copy/initialisation sucessful, false - dimension false for copying
    105  */
    106 bool MatrixContainer::InitialiseIndices(class MatrixContainer *Matrix)
    107 {
    108   cout << "Initialising indices";
    109   if (Matrix == NULL) {
    110     cout << " with trivial mapping." << endl;
    111     Indices = (int **) Malloc(sizeof(int *)*(MatrixCounter+1), "MatrixContainer::InitialiseIndices: **Indices");
    112     for(int i=MatrixCounter+1;i--;) {
    113       Indices[i] = (int *) Malloc(sizeof(int)*RowCounter[i], "MatrixContainer::InitialiseIndices: *Indices[]");
    114       for(int j=RowCounter[i];j--;)
    115         Indices[i][j] = j;
    116     }
    117   } else {
    118     cout << " from other MatrixContainer." << endl;
    119     if (MatrixCounter != Matrix->MatrixCounter)
    120       return false;
    121     Indices = (int **) Malloc(sizeof(int *)*(MatrixCounter+1), "MatrixContainer::InitialiseIndices: **Indices");
    122     for(int i=MatrixCounter+1;i--;) {
    123       if (RowCounter[i] != Matrix->RowCounter[i])
    124         return false;
    125       Indices[i] = (int *) Malloc(sizeof(int)*Matrix->RowCounter[i], "MatrixContainer::InitialiseIndices: *Indices[]");
    126       for(int j=Matrix->RowCounter[i];j--;) {
    127         Indices[i][j] = Matrix->Indices[i][j];
    128         //cout << Indices[i][j] << "\t";
    129       }
    130       //cout << endl;
    131     }
    132   }
    133   return true;
    134 };
     93};
     94
    13595
    13696/** Parsing a number of matrices.
     
    160120    return false;
    161121  }
    162 
    163   // parse header
    164   Header[MatrixNr] = (char *) Malloc(sizeof(char)*1024, "MatrixContainer::ParseMatrix: *Header[]");
     122 
     123  // skip some initial lines
    165124  for (int m=skiplines+1;m--;)
    166     input.getline(Header[MatrixNr], 1023);
     125    input.getline(Header, 1023);
    167126 
    168127  // scan header for number of columns
    169   line.str(Header[MatrixNr]);
     128  line.str(Header);
    170129  for(int k=skipcolumns;k--;)
    171     line >> Header[MatrixNr];
     130    line >> Header;
    172131  //cout << line.str() << endl;
    173   ColumnCounter[MatrixNr]=0;
     132  ColumnCounter=0;
    174133  while ( getline(line,token, '\t') ) {
    175134    if (token.length() > 0)
    176       ColumnCounter[MatrixNr]++;
     135      ColumnCounter++;
    177136  }
    178137  //cout << line.str() << endl;
    179   //cout << "ColumnCounter[" << MatrixNr << "]: " << ColumnCounter[MatrixNr] << "." << endl;
    180   if (ColumnCounter[MatrixNr] == 0)
    181     cerr << "ColumnCounter[" << MatrixNr << "]: " << ColumnCounter[MatrixNr] << " from file " << name << ", this is probably an error!" << endl;
     138  //cout << "ColumnCounter: " << ColumnCounter << "." << endl;
     139  if (ColumnCounter == 0)
     140    cerr << "ColumnCounter: " << ColumnCounter << " from file " << name << ", this is probably an error!" << endl;
    182141 
    183142  // scan rest for number of rows/lines
     
    196155 
    197156  // allocate matrix if it's not zero dimension in one direction
    198   if ((ColumnCounter[MatrixNr] > 0) && (RowCounter[MatrixNr] > -1)) {
    199     Matrix[MatrixNr] = (double **) Malloc(sizeof(double *)*(RowCounter[MatrixNr]+1), "MatrixContainer::ParseMatrix: **Matrix[]");
     157  if ((ColumnCounter > 0) && (RowCounter[MatrixNr] > -1)) {
     158    Matrix[MatrixNr] = (double **) Malloc(sizeof(double *)*(RowCounter[MatrixNr]+1), "MatrixContainer::ParseFragmentMatrix: **Matrix[]");
    200159 
    201160    // parse in each entry for this matrix
     
    203162    input.seekg(ios::beg);
    204163    for (int m=skiplines+1;m--;)
    205       input.getline(Header[MatrixNr], 1023);    // skip header
    206     line.str(Header[MatrixNr]);
     164      input.getline(Header, 1023);    // skip header
     165    line.str(Header);
    207166    for(int k=skipcolumns;k--;)  // skip columns in header too
    208167      line >> filename;
    209     strncpy(Header[MatrixNr], line.str().c_str(), 1023); 
     168    strncpy(Header, line.str().c_str(), 1023); 
    210169    for(int j=0;j<RowCounter[MatrixNr];j++) {
    211       Matrix[MatrixNr][j] = (double *) Malloc(sizeof(double)*ColumnCounter[MatrixNr], "MatrixContainer::ParseMatrix: *Matrix[][]");
     170      Matrix[MatrixNr][j] = (double *) Malloc(sizeof(double)*ColumnCounter, "MatrixContainer::ParseFragmentMatrix: *Matrix[][]");
    212171      input.getline(filename, 1023);
    213172      stringstream lines(filename);
     
    215174      for(int k=skipcolumns;k--;)
    216175        lines >> filename;
    217       for(int k=0;(k<ColumnCounter[MatrixNr]) && (!lines.eof());k++) {
     176      for(int k=0;(k<ColumnCounter) && (!lines.eof());k++) {
    218177        lines >> Matrix[MatrixNr][j][k];
    219178        //cout << " " << setprecision(2) << Matrix[MatrixNr][j][k];;
    220179      }
    221180      //cout << endl;
    222       Matrix[MatrixNr][ RowCounter[MatrixNr] ] = (double *) Malloc(sizeof(double)*ColumnCounter[MatrixNr], "MatrixContainer::ParseMatrix: *Matrix[RowCounter[MatrixNr]][]");
    223       for(int j=ColumnCounter[MatrixNr];j--;)
     181      Matrix[MatrixNr][ RowCounter[MatrixNr] ] = (double *) Malloc(sizeof(double)*ColumnCounter, "MatrixContainer::ParseFragmentMatrix: *Matrix[RowCounter[MatrixNr]][]");
     182      for(int j=ColumnCounter;j--;)
    224183        Matrix[MatrixNr][ RowCounter[MatrixNr] ][j] = 0.;
    225184    }
    226185  } else {
    227     cerr << "ERROR: Matrix nr. " << MatrixNr << " has column and row count of (" << ColumnCounter[MatrixNr] << "," << RowCounter[MatrixNr] << "), could not allocate nor parse!" << endl;
     186    cerr << "ERROR: Matrix nr. " << MatrixNr << " has column and row count of (" << ColumnCounter << "," << RowCounter[MatrixNr] << "), could not allocate nor parse!" << endl;
    228187  }
    229188  input.close();
     
    274233 
    275234  cout << "Parsing through each fragment and retrieving " << prefix << suffix << "." << endl;
    276   Header = (char **) ReAlloc(Header, sizeof(char *)*(MatrixCounter+1), "MatrixContainer::ParseFragmentMatrix: **Header"); // one more each for the total molecule
    277235  Matrix = (double ***) ReAlloc(Matrix, sizeof(double **)*(MatrixCounter+1), "MatrixContainer::ParseFragmentMatrix: ***Matrix"); // one more each for the total molecule
    278236  RowCounter = (int *) ReAlloc(RowCounter, sizeof(int)*(MatrixCounter+1), "MatrixContainer::ParseFragmentMatrix: *RowCounter");
    279   ColumnCounter = (int *) ReAlloc(ColumnCounter, sizeof(int)*(MatrixCounter+1), "MatrixContainer::ParseFragmentMatrix: *ColumnCounter");
    280237  for(int i=MatrixCounter+1;i--;) {
    281238    Matrix[i] = NULL;
    282     Header[i] = NULL;
    283239    RowCounter[i] = -1;
    284     ColumnCounter[i] = -1;
    285240  }
    286241  for(int i=0; i < MatrixCounter;i++) {
     
    297252
    298253/** Allocates and resets the memory for a number \a MCounter of matrices.
    299  * \param **GivenHeader Header line for each matrix
     254 * \param *GivenHeader Header line
    300255 * \param MCounter number of matrices
    301256 * \param *RCounter number of rows for each matrix
    302  * \param *CCounter number of columns for each matrix
     257 * \param CCounter number of columns for all matrices
    303258 * \return Allocation successful
    304259 */
    305 bool MatrixContainer::AllocateMatrix(char **GivenHeader, int MCounter, int *RCounter, int *CCounter)
    306 {
     260bool MatrixContainer::AllocateMatrix(char *GivenHeader, int MCounter, int *RCounter, int CCounter)
     261{
     262  Header = (char *) Malloc(sizeof(char)*1024, "MatrixContainer::ParseFragmentMatrix: *EnergyHeader");
     263  strncpy(Header, GivenHeader, 1023);
     264
    307265  MatrixCounter = MCounter;
    308   Header = (char **) Malloc(sizeof(char *)*(MatrixCounter+1), "MatrixContainer::AllocateMatrix: *Header");
    309   Matrix = (double ***) Malloc(sizeof(double **)*(MatrixCounter+1), "MatrixContainer::AllocateMatrix: ***Matrix"); // one more each for the total molecule
    310   RowCounter = (int *) Malloc(sizeof(int)*(MatrixCounter+1), "MatrixContainer::AllocateMatrix: *RowCounter");
    311   ColumnCounter = (int *) Malloc(sizeof(int)*(MatrixCounter+1), "MatrixContainer::AllocateMatrix: *ColumnCounter");
     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");
    312269  for(int i=MatrixCounter+1;i--;) {
    313     Header[i] = (char *) Malloc(sizeof(char)*1024, "MatrixContainer::AllocateMatrix: *Header[i]");
    314     strncpy(Header[i], GivenHeader[i], 1023);
    315270    RowCounter[i] = RCounter[i];
    316     ColumnCounter[i] = CCounter[i];
    317     Matrix[i] = (double **) Malloc(sizeof(double *)*(RowCounter[i]+1), "MatrixContainer::AllocateMatrix: **Matrix[]"); 
     271    Matrix[i] = (double **) Malloc(sizeof(double *)*(RowCounter[i]+1), "MatrixContainer::ParseFragmentMatrix: **Matrix[]"); 
    318272    for(int j=RowCounter[i]+1;j--;) {
    319       Matrix[i][j] = (double *) Malloc(sizeof(double)*ColumnCounter[i], "MatrixContainer::AllocateMatrix: *Matrix[][]");
    320       for(int k=ColumnCounter[i];k--;)
     273      Matrix[i][j] = (double *) Malloc(sizeof(double)*ColumnCounter, "MatrixContainer::ParseFragmentMatrix: *Matrix[][]");
     274      for(int k=ColumnCounter;k--;)
    321275        Matrix[i][j][k] = 0.;
    322276    }
     
    332286  for(int i=MatrixCounter+1;i--;)
    333287    for(int j=RowCounter[i]+1;j--;)
    334       for(int k=ColumnCounter[i];k--;)
     288      for(int k=ColumnCounter;k--;)
    335289        Matrix[i][j][k] = 0.;
    336290   return true;
     
    345299  for(int i=MatrixCounter+1;i--;)
    346300    for(int j=RowCounter[i]+1;j--;)
    347       for(int k=ColumnCounter[i];k--;)
     301      for(int k=ColumnCounter;k--;)
    348302        if (fabs(Matrix[i][j][k]) > max)
    349303          max = fabs(Matrix[i][j][k]);
     
    361315  for(int i=MatrixCounter+1;i--;)
    362316    for(int j=RowCounter[i]+1;j--;)
    363       for(int k=ColumnCounter[i];k--;)
     317      for(int k=ColumnCounter;k--;)
    364318        if (fabs(Matrix[i][j][k]) < min)
    365319          min = fabs(Matrix[i][j][k]);
     
    377331{
    378332  for(int j=RowCounter[MatrixCounter]+1;j--;)
    379     for(int k=skipcolumns;k<ColumnCounter[MatrixCounter];k++)
     333    for(int k=skipcolumns;k<ColumnCounter;k++)
    380334      Matrix[MatrixCounter][j][k] = value;
    381335   return true;
     
    390344{
    391345  for(int j=RowCounter[MatrixCounter]+1;j--;)
    392     for(int k=skipcolumns;k<ColumnCounter[MatrixCounter];k++)
     346    for(int k=skipcolumns;k<ColumnCounter;k++)
    393347      Matrix[MatrixCounter][j][k] = values[j][k];
    394348   return true;
    395349};
    396350
    397 /** Sums the entries with each factor and put into last element of \a ***Matrix.
     351/** Sums the energy with each factor and put into last element of \a ***Energies.
    398352 * Sums over "E"-terms to create the "F"-terms
    399  * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies.
     353 * \param Matrix MatrixContainer with matrices (LevelCounter by ColumnCounter) with all the energies.
    400354 * \param KeySet KeySetContainer with bond Order and association mapping of each fragment to an order
    401355 * \param Order bond order
     
    430384              }
    431385              if (Order == SubOrder) { // equal order is always copy from Energies
    432                 for(int l=ColumnCounter[ KeySet.OrderSet[SubOrder][j] ];l--;) // then adds/subtract each column
     386                for(int l=ColumnCounter;l--;) // then adds/subtract each column
    433387                  Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][m][l] += MatrixValues.Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l];
    434388              } else {
    435                 for(int l=ColumnCounter[ KeySet.OrderSet[SubOrder][j] ];l--;)
     389                for(int l=ColumnCounter;l--;)
    436390                  Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][m][l] -= Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l];
    437391              }
    438392            }
    439             //if ((ColumnCounter[ KeySet.OrderSet[SubOrder][j] ]>1) && (RowCounter[0]-1 >= 1))
     393            //if ((ColumnCounter>1) && (RowCounter[0]-1 >= 1))
    440394             //cout << "Fragments[ KeySet.OrderSet[" << Order << "][" << CurrentFragment << "]=" << KeySet.OrderSet[Order][CurrentFragment] << " ][" << RowCounter[0]-1 << "][" << 1 << "] = " <<  Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][RowCounter[0]-1][1] << endl;
    441395          }
     
    472426      return false;
    473427    }
    474     output << Header[i] << endl;
     428    output << Header << endl;
    475429    for(int j=0;j<RowCounter[i];j++) {
    476       for(int k=0;k<ColumnCounter[i];k++)
     430      for(int k=0;k<ColumnCounter;k++)
    477431        output << scientific << Matrix[i][j][k] << "\t";
    478432      output << endl;
     
    501455    return false;
    502456  }
    503   output << Header[MatrixCounter] << endl;
     457  output << Header << endl;
    504458  for(int j=0;j<RowCounter[MatrixCounter];j++) {
    505     for(int k=0;k<ColumnCounter[MatrixCounter];k++)
     459    for(int k=0;k<ColumnCounter;k++)
    506460      output << scientific << Matrix[MatrixCounter][j][k] << "\t";
    507461    output << endl;
     
    513467// ======================================= CLASS EnergyMatrix =============================
    514468
     469/** Create a trivial energy index mapping.
     470 * This just maps 1 to 1, 2 to 2 and so on for all fragments.
     471 * \return creation sucessful
     472 */
     473bool EnergyMatrix::ParseIndices()
     474{
     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;
     483};
     484
    515485/** Sums the energy with each factor and put into last element of \a EnergyMatrix::Matrix.
    516486 * Sums over the "F"-terms in ANOVA decomposition.
    517  * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies.
     487 * \param Matrix MatrixContainer with matrices (LevelCounter by ColumnCounter) with all the energies.
    518488 * \param CorrectionFragments MatrixContainer with hydrogen saturation correction per fragments
    519489 * \param KeySet KeySetContainer with bond Order and association mapping of each fragment to an order
     
    528498    for(int i=KeySet.FragmentsPerOrder[Order];i--;)
    529499      for(int j=RowCounter[ KeySet.OrderSet[Order][i] ];j--;)
    530         for(int k=ColumnCounter[ KeySet.OrderSet[Order][i] ];k--;)
     500        for(int k=ColumnCounter;k--;)
    531501          Matrix[MatrixCounter][j][k] += sign*Fragments.Matrix[ KeySet.OrderSet[Order][i] ][j][k];
    532502  else
    533503    for(int i=KeySet.FragmentsPerOrder[Order];i--;)
    534504      for(int j=RowCounter[ KeySet.OrderSet[Order][i] ];j--;)
    535         for(int k=ColumnCounter[ KeySet.OrderSet[Order][i] ];k--;)
     505        for(int k=ColumnCounter;k--;)
    536506          Matrix[MatrixCounter][j][k] += sign*(Fragments.Matrix[ KeySet.OrderSet[Order][i] ][j][k] + CorrectionFragments->Matrix[ KeySet.OrderSet[Order][i] ][j][k]);
    537507  return true;
     
    554524    // count maximum of columns
    555525    RowCounter[MatrixCounter] = 0;
    556     ColumnCounter[MatrixCounter] = 0;
    557     for(int j=0; j < MatrixCounter;j++) { // (energy matrix might be bigger than number of atoms in terms of rows)
     526    for(int j=0; j < MatrixCounter;j++) // (energy matrix might be bigger than number of atoms in terms of rows)
    558527      if (RowCounter[j] > RowCounter[MatrixCounter])
    559528        RowCounter[MatrixCounter] = RowCounter[j];
    560       if (ColumnCounter[j] > ColumnCounter[MatrixCounter])  // take maximum of all for last matrix
    561         ColumnCounter[MatrixCounter] = ColumnCounter[j];
    562     }
    563529    // allocate last plus one matrix
    564     cout << "Allocating last plus one matrix with " << (RowCounter[MatrixCounter]+1) << " rows and " << ColumnCounter[MatrixCounter] << " columns." << endl;
     530    cout << "Allocating last plus one matrix with " << (RowCounter[MatrixCounter]+1) << " rows and " << ColumnCounter << " columns." << endl;
    565531    Matrix[MatrixCounter] = (double **) Malloc(sizeof(double *)*(RowCounter[MatrixCounter]+1), "MatrixContainer::ParseFragmentMatrix: **Matrix[]");
    566532    for(int j=0;j<=RowCounter[MatrixCounter];j++)
    567       Matrix[MatrixCounter][j] = (double *) Malloc(sizeof(double)*ColumnCounter[MatrixCounter], "MatrixContainer::ParseFragmentMatrix: *Matrix[][]");
     533      Matrix[MatrixCounter][j] = (double *) Malloc(sizeof(double)*ColumnCounter, "MatrixContainer::ParseFragmentMatrix: *Matrix[][]");
    568534   
    569535    // try independently to parse global energysuffix file if present
     
    623589
    624590/** Sums the forces and puts into last element of \a ForceMatrix::Matrix.
    625  * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies.
     591 * \param Matrix MatrixContainer with matrices (LevelCounter by ColumnCounter) with all the energies.
    626592 * \param KeySet KeySetContainer with bond Order and association mapping of each fragment to an order
    627593 * \param Order bond order
     
    643609      if (j != -1) {
    644610        //if (j == 0) cout << "Summing onto ion 0, type 0 from fragment " << FragmentNr << ", ion " << l << "." << endl;
    645         for(int k=2;k<ColumnCounter[MatrixCounter];k++)
     611        for(int k=2;k<ColumnCounter;k++)
    646612          Matrix[MatrixCounter][j][k] += sign*Fragments.Matrix[ FragmentNr ][l][k];
    647613      }
     
    689655    RowCounter[MatrixCounter]++;    // nr start at 0, count starts at 1
    690656    input.close();
    691 
    692     ColumnCounter[MatrixCounter] = 0;
    693     for(int j=0; j < MatrixCounter;j++) { // (energy matrix might be bigger than number of atoms in terms of rows)
    694       if (ColumnCounter[j] > ColumnCounter[MatrixCounter])  // take maximum of all for last matrix
    695         ColumnCounter[MatrixCounter] = ColumnCounter[j];
    696     }
    697657 
    698658    // allocate last plus one matrix
    699     cout << "Allocating last plus one matrix with " << (RowCounter[MatrixCounter]+1) << " rows and " << ColumnCounter[MatrixCounter] << " columns." << endl;
     659    cout << "Allocating last plus one matrix with " << (RowCounter[MatrixCounter]+1) << " rows and " << ColumnCounter << " columns." << endl;
    700660    Matrix[MatrixCounter] = (double **) Malloc(sizeof(double *)*(RowCounter[MatrixCounter]+1), "MatrixContainer::ParseFragmentMatrix: **Matrix[]");
    701661    for(int j=0;j<=RowCounter[MatrixCounter];j++)
    702       Matrix[MatrixCounter][j] = (double *) Malloc(sizeof(double)*ColumnCounter[MatrixCounter], "MatrixContainer::ParseFragmentMatrix: *Matrix[][]");
    703 
    704     // try independently to parse global forcesuffix file if present
    705     strncpy(filename, name, 1023);
    706     strncat(filename, prefix, 1023-strlen(filename));
    707     strncat(filename, suffix.c_str(), 1023-strlen(filename));
    708     ParseMatrix(filename, skiplines, skipcolumns, MatrixCounter);
    709   }
    710  
    711 
    712   return status;
    713 };
    714 
    715 // ======================================= CLASS HessianMatrix =============================
    716 
    717 /** Parsing force Indices of each fragment
    718  * \param *name directory with \a ForcesFile
    719  * \return parsing successful
    720  */
    721 bool HessianMatrix::ParseIndices(char *name)
    722 {
    723   ifstream input;
    724   char *FragmentNumber = NULL;
    725   char filename[1023];
    726   stringstream line;
    727  
    728   cout << "Parsing hessian indices for " << MatrixCounter << " matrices." << endl;
    729   Indices = (int **) Malloc(sizeof(int *)*(MatrixCounter+1), "HessianMatrix::ParseIndices: **Indices");
    730   line << name << FRAGMENTPREFIX << FORCESFILE;
    731   input.open(line.str().c_str(), ios::in);
    732   //cout << "Opening " << line.str() << " ... "  << input << endl;
    733   if (input == NULL) {
    734     cout << endl << "Unable to open " << line.str() << ", is the directory correct?" << endl;
    735     return false;
    736   }
    737   for (int i=0;(i<MatrixCounter) && (!input.eof());i++) {
    738     // get the number of atoms for this fragment
    739     input.getline(filename, 1023);
    740     line.str(filename);
    741     // parse the values
    742     Indices[i] = (int *) Malloc(sizeof(int)*RowCounter[i], "HessianMatrix::ParseIndices: *Indices[]");
    743     FragmentNumber = FixedDigitNumber(MatrixCounter, i);
    744     //cout << FRAGMENTPREFIX << FragmentNumber << "[" << RowCounter[i] << "]:";
    745     Free((void **)&FragmentNumber, "HessianMatrix::ParseIndices: *FragmentNumber");
    746     for(int j=0;(j<RowCounter[i]) && (!line.eof());j++) {
    747       line >> Indices[i][j];
    748       //cout << " " << Indices[i][j];
    749     }
    750     //cout << endl;
    751   }
    752   Indices[MatrixCounter] = (int *) Malloc(sizeof(int)*RowCounter[MatrixCounter], "HessianMatrix::ParseIndices: *Indices[]");
    753   for(int j=RowCounter[MatrixCounter];j--;) {
    754     Indices[MatrixCounter][j] = j;
    755   }
    756   input.close();
    757   return true;
    758 };
    759 
    760 
    761 /** Sums the hessian entries and puts into last element of \a HessianMatrix::Matrix.
    762  * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies.
    763  * \param KeySet KeySetContainer with bond Order and association mapping of each fragment to an order
    764  * \param Order bond order
    765  *  \param sign +1 or -1
    766  * \return true if summing was successful
    767  */
    768 bool HessianMatrix::SumSubHessians(class HessianMatrix &Fragments, class KeySetsContainer &KeySet, int Order, double sign)
    769 {
    770   int FragmentNr;
    771   // sum forces
    772   for(int i=0;i<KeySet.FragmentsPerOrder[Order];i++) {
    773     FragmentNr = KeySet.OrderSet[Order][i];
    774     for(int l=0;l<RowCounter[ FragmentNr ];l++) {
    775       int j = Indices[ FragmentNr ][l];
    776       if (j > RowCounter[MatrixCounter]) {
    777         cerr << "Current hessian index " << j << " is greater than " << RowCounter[MatrixCounter] << ", where i=" << i << ", Order=" << Order << ", l=" << l << " and FragmentNr=" << FragmentNr << "!" << endl;
    778         return false;
    779       }
    780       if (j != -1) {
    781         for(int m=0;m<ColumnCounter[ FragmentNr ];m++) {
    782           int k = Indices[ FragmentNr ][m];
    783           if (k > ColumnCounter[MatrixCounter]) {
    784             cerr << "Current hessian index " << k << " is greater than " << ColumnCounter[MatrixCounter] << ", where m=" << m << ", j=" << j << ", i=" << i << ", Order=" << Order << ", l=" << l << " and FragmentNr=" << FragmentNr << "!" << endl;
    785             return false;
    786           }
    787           if (k != -1) {
    788                 //cout << "Adding " << sign*Fragments.Matrix[ FragmentNr ][l][m] << " from [" << l << "][" << m << "] onto [" << j << "][" << k << "]." << endl;
    789             Matrix[MatrixCounter][j][k] += sign*Fragments.Matrix[ FragmentNr ][l][m];
    790           }
    791         }
    792       }
    793     }
    794   }
    795   return true;
    796 };
    797 
    798 /** Constructor for class HessianMatrix.
    799  */
    800 HessianMatrix::HessianMatrix() : MatrixContainer()
    801 {
    802    IsSymmetric = true;
    803 }
    804 
    805 /** Sums the hessian entries with each factor and put into last element of \a ***Matrix.
    806  * Sums over "E"-terms to create the "F"-terms
    807  * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies.
    808  * \param KeySet KeySetContainer with bond Order and association mapping of each fragment to an order
    809  * \param Order bond order
    810  * \return true if summing was successful
    811  */
    812 bool HessianMatrix::SumSubManyBodyTerms(class MatrixContainer &MatrixValues, class KeySetsContainer &KeySet, int Order)
    813 {
    814   // go through each order
    815   for (int CurrentFragment=0;CurrentFragment<KeySet.FragmentsPerOrder[Order];CurrentFragment++) {
    816     //cout << "Current Fragment is " << CurrentFragment << "/" << KeySet.OrderSet[Order][CurrentFragment] << "." << endl;
    817     // then go per order through each suborder and pick together all the terms that contain this fragment
    818     for(int SubOrder=0;SubOrder<=Order;SubOrder++) { // go through all suborders up to the desired order
    819       for (int j=0;j<KeySet.FragmentsPerOrder[SubOrder];j++) { // go through all possible fragments of size suborder
    820         if (KeySet.Contains(KeySet.OrderSet[Order][CurrentFragment], KeySet.OrderSet[SubOrder][j])) {
    821           //cout << "Current other fragment is " << j << "/" << KeySet.OrderSet[SubOrder][j] << "." << endl;
    822           // if the fragment's indices are all in the current fragment
    823           for(int k=0;k<RowCounter[ KeySet.OrderSet[SubOrder][j] ];k++) { // go through all atoms in this fragment
    824             int m = MatrixValues.Indices[ KeySet.OrderSet[SubOrder][j] ][k];
    825             //cout << "Current row index is " << k << "/" << m << "." << endl;
    826             if (m != -1) { // if it's not an added hydrogen
    827               for (int l=0;l<RowCounter[ KeySet.OrderSet[Order][CurrentFragment] ];l++) { // look for the corresponding index in the current fragment
    828                 //cout << "Comparing " << m << " with " << MatrixValues.Indices[ KeySet.OrderSet[Order][CurrentFragment] ][l] << "." << endl;
    829                 if (m == MatrixValues.Indices[ KeySet.OrderSet[Order][CurrentFragment] ][l]) {
    830                   m = l;
    831                   break; 
    832                 }
    833               }
    834               //cout << "Corresponding row index for " << k << " in CurrentFragment is " << m << "." << endl;
    835               if (m > RowCounter[ KeySet.OrderSet[Order][CurrentFragment] ]) {
    836                 cerr << "In fragment No. " << KeySet.OrderSet[Order][CurrentFragment]   << " current row index " << m << " is greater than " << RowCounter[ KeySet.OrderSet[Order][CurrentFragment] ] << "!" << endl;
    837                 return false;
    838               }
    839              
    840               for(int l=0;l<ColumnCounter[ KeySet.OrderSet[SubOrder][j] ];l++) {
    841                 int n = MatrixValues.Indices[ KeySet.OrderSet[SubOrder][j] ][l];
    842                 //cout << "Current column index is " << l << "/" << n << "." << endl;
    843                 if (n != -1) { // if it's not an added hydrogen
    844                   for (int p=0;p<ColumnCounter[ KeySet.OrderSet[Order][CurrentFragment] ];p++) { // look for the corresponding index in the current fragment
    845                     //cout << "Comparing " << n << " with " << MatrixValues.Indices[ KeySet.OrderSet[Order][CurrentFragment] ][p] << "." << endl;
    846                     if (n == MatrixValues.Indices[ KeySet.OrderSet[Order][CurrentFragment] ][p]) {
    847                       n = p;
    848                       break; 
    849                     }
    850                   }
    851                   //cout << "Corresponding column index for " << l << " in CurrentFragment is " << n << "." << endl;
    852                   if (n > ColumnCounter[ KeySet.OrderSet[Order][CurrentFragment] ]) {
    853                     cerr << "In fragment No. " << KeySet.OrderSet[Order][CurrentFragment]   << " current column index " << n << " is greater than " << ColumnCounter[ KeySet.OrderSet[Order][CurrentFragment] ] << "!" << endl;
    854                     return false;
    855                   }
    856                   if (Order == SubOrder) { // equal order is always copy from Energies
    857                         //cout << "Adding " << MatrixValues.Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l] << " from [" << k << "][" << l << "] onto [" << m << "][" << n << "]." << endl;
    858                     Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][m][n] += MatrixValues.Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l];
    859                   } else {
    860                         //cout << "Subtracting " << Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l] << " from [" << k << "][" << l << "] onto [" << m << "][" << n << "]." << endl;
    861                     Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][m][n] -= Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l];
    862                   }
    863                 }
    864               }
    865             }
    866             //if ((ColumnCounter[ KeySet.OrderSet[SubOrder][j] ]>1) && (RowCounter[0]-1 >= 1))
    867              //cout << "Fragments[ KeySet.OrderSet[" << Order << "][" << CurrentFragment << "]=" << KeySet.OrderSet[Order][CurrentFragment] << " ][" << RowCounter[0]-1 << "][" << 1 << "] = " <<  Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][RowCounter[0]-1][1] << endl;
    868           }
    869         } else {
    870           //cout << "Fragment " << KeySet.OrderSet[SubOrder][j] << " is not contained in fragment " << KeySet.OrderSet[Order][CurrentFragment] << "." << endl;
    871         }
    872       }
    873     }
    874    //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;
    875   }
    876  
    877   return true;
    878 };
    879 
    880 /** Calls MatrixContainer::ParseFragmentMatrix() and additionally allocates last plus one matrix.
    881  * \param *name directory with files
    882  * \param *prefix prefix of each matrix file
    883  * \param *suffix suffix of each matrix file
    884  * \param skiplines number of inital lines to skip
    885  * \param skiplines number of inital columns to skip
    886  * \return parsing successful
    887  */
    888 bool HessianMatrix::ParseFragmentMatrix(char *name, char *prefix, string suffix, int skiplines, int skipcolumns)
    889 {
    890   char filename[1023];
    891   ifstream input;
    892   stringstream file;
    893   int nr;
    894   bool status = MatrixContainer::ParseFragmentMatrix(name, prefix, suffix, skiplines, skipcolumns);
    895 
    896   if (status) {
    897     // count number of atoms for last plus one matrix
    898     file << name << FRAGMENTPREFIX << KEYSETFILE;
    899     input.open(file.str().c_str(), ios::in);
    900     if (input == NULL) {
    901       cout << endl << "Unable to open " << file.str() << ", is the directory correct?" << endl;
    902       return false;
    903     }
    904     RowCounter[MatrixCounter] = 0;
    905     ColumnCounter[MatrixCounter] = 0;
    906     while (!input.eof()) {
    907       input.getline(filename, 1023);
    908       stringstream zeile(filename);
    909       while (!zeile.eof()) {
    910         zeile >> nr;
    911         //cout << "Current index: " << nr << "." << endl;
    912         if (nr > RowCounter[MatrixCounter]) {
    913           RowCounter[MatrixCounter] = nr;
    914           ColumnCounter[MatrixCounter] = nr;
    915         }
    916       }
    917     }
    918     RowCounter[MatrixCounter]++;    // nr start at 0, count starts at 1
    919     ColumnCounter[MatrixCounter]++;    // nr start at 0, count starts at 1
    920     input.close();
    921  
    922     // allocate last plus one matrix
    923     cout << "Allocating last plus one matrix with " << (RowCounter[MatrixCounter]+1) << " rows and " << ColumnCounter[MatrixCounter] << " columns." << endl;
    924     Matrix[MatrixCounter] = (double **) Malloc(sizeof(double *)*(RowCounter[MatrixCounter]+1), "MatrixContainer::ParseFragmentMatrix: **Matrix[]");
    925     for(int j=0;j<=RowCounter[MatrixCounter];j++)
    926       Matrix[MatrixCounter][j] = (double *) Malloc(sizeof(double)*ColumnCounter[MatrixCounter], "MatrixContainer::ParseFragmentMatrix: *Matrix[][]");
     662      Matrix[MatrixCounter][j] = (double *) Malloc(sizeof(double)*ColumnCounter, "MatrixContainer::ParseFragmentMatrix: *Matrix[][]");
    927663
    928664    // try independently to parse global forcesuffix file if present
  • src/parser.hpp

    • Property mode changed from 100755 to 100644
    r986c80 redcda5  
    1919
    2020#define EnergySuffix ".energy.all"
    21 #define EnergyFragmentSuffix ".energyfragment.all"
     21#define HcorrectionSuffix ".Hcorrection.all"
    2222#define ForcesSuffix ".forces.all"
    23 #define ForceFragmentSuffix ".forcefragment.all"
    24 #define HcorrectionSuffix ".Hcorrection.all"
    25 #define HcorrectionFragmentSuffix ".Hcorrectionfragment.all"
    26 #define HessianSuffix ".hessian_xx.all"
    27 #define HessianFragmentSuffix ".hessianfragment_xx.all"
    28 #define OrderSuffix ".Order"
    2923#define ShieldingSuffix ".sigma_all.csv"
    3024#define ShieldingPASSuffix ".sigma_all_PAS.csv"
    3125#define ShieldingFragmentSuffix ".sigma_all_fragment.all"
    3226#define ShieldingPASFragmentSuffix ".sigma_all_PAS_fragment.all"
    33 #define ChiSuffix ".chi_all.csv"
    34 #define ChiPASSuffix ".chi_all_PAS.csv"
    35 #define ChiFragmentSuffix ".chi_all_fragment.all"
    36 #define ChiPASFragmentSuffix ".chi_all_PAS_fragment.all"
    3727#define TimeSuffix ".speed"
     28#define EnergyFragmentSuffix ".energyfragment.all"
     29#define HcorrectionFragmentSuffix ".Hcorrectionfragment.all"
     30#define ForceFragmentSuffix ".forcefragment.all"
     31#define OrderSuffix ".Order"
    3832
    3933// ======================================= FUNCTIONS ==========================================
     
    4943    double ***Matrix;
    5044    int **Indices;
    51     char **Header;
     45    char *Header;
    5246    int MatrixCounter;
    5347    int *RowCounter;
    54     int *ColumnCounter;
     48    int ColumnCounter;
    5549 
    5650  MatrixContainer();
    5751  ~MatrixContainer();
    5852 
    59   bool InitialiseIndices(class MatrixContainer *Matrix = NULL);
    6053  bool ParseMatrix(const char *name, int skiplines, int skipcolumns, int MatrixNr);
    6154  virtual bool ParseFragmentMatrix(char *name, char *prefix, string suffix, int skiplines, int skipcolumns);
    62   bool AllocateMatrix(char **GivenHeader, int MCounter, int *RCounter, int *CCounter);
     55  bool AllocateMatrix(char *GivenHeader, int MCounter, int *RCounter, int CCounter);
    6356  bool ResetMatrix();
    6457  double FindMinValue();
     
    7770class EnergyMatrix : public MatrixContainer {
    7871  public:
     72    bool ParseIndices();
    7973    bool SumSubEnergy(class EnergyMatrix &Fragments, class EnergyMatrix *CorrectionFragments, class KeySetsContainer &KeySet, int Order, double sign);
    8074    bool ParseFragmentMatrix(char *name, char *prefix, string suffix, int skiplines, int skipcolumns);
     
    8882    bool SumSubForces(class ForceMatrix &Fragments, class KeySetsContainer &KeySet, int Order, double sign);
    8983    bool ParseFragmentMatrix(char *name, char *prefix, string suffix, int skiplines, int skipcolumns);
    90 };
    91 
    92 // ======================================= CLASS HessianMatrix =============================
    93 
    94 class HessianMatrix : public MatrixContainer {
    95   public:
    96     HessianMatrix();
    97     //~HessianMatrix();
    98     bool ParseIndices(char *name);
    99     bool SumSubManyBodyTerms(class MatrixContainer &MatrixValues, class KeySetsContainer &KeySet, int Order);
    100     bool SumSubHessians(class HessianMatrix &Fragments, class KeySetsContainer &KeySet, int Order, double sign);
    101     bool ParseFragmentMatrix(char *name, char *prefix, string suffix, int skiplines, int skipcolumns);
    102   private:
    103     bool IsSymmetric;
    10484};
    10585
  • src/periodentafel.cpp

    • Property mode changed from 100755 to 100644
    r986c80 redcda5  
    11/** \file periodentafel.cpp
    2  *
     2 * 
    33 * Function implementations for the class periodentafel.
    4  *
     4 * 
    55 */
    66
     
    1414 * Initialises start and end of list and resets periodentafel::checkliste to false.
    1515 */
    16 periodentafel::periodentafel()
    17 {
    18   start = new element;
    19   end = new element;
    20   start->previous = NULL;
    21   start->next = end;
    22   end->previous = start;
     16periodentafel::periodentafel() 
     17{ 
     18  start = new element; 
     19  end = new element; 
     20  start->previous = NULL; 
     21  start->next = end; 
     22  end->previous = start; 
    2323  end->next = NULL;
    2424};
     
    2727 * Removes every element and afterwards deletes start and end of list.
    2828 */
    29 periodentafel::~periodentafel()
    30 {
    31   CleanupPeriodtable();
    32   delete(end);
    33   delete(start);
    34 };
     29periodentafel::~periodentafel() 
     30{ 
     31  CleanupPeriodtable(); 
     32  delete(end); 
     33  delete(start); 
     34}; 
    3535
    3636/** Adds element to period table list
     
    3838 * \return true - succeeded, false - does not occur
    3939 */
    40 bool periodentafel::AddElement(element *pointer)
    41 {
     40bool periodentafel::AddElement(element *pointer) 
     41{ 
    4242  pointer->sort = &pointer->Z;
    4343  if (pointer->Z < 1 && pointer->Z >= MAX_ELEMENTS)
    4444    cout << Verbose(0) << "Invalid Z number!\n";
    45   return add(pointer, end);
     45  return add(pointer, end); 
    4646};
    4747
     
    5050 * \return true - succeeded, false - element not found
    5151 */
    52 bool periodentafel::RemoveElement(element *pointer)
    53 {
    54   return remove(pointer, start, end);
     52bool periodentafel::RemoveElement(element *pointer) 
     53{ 
     54  return remove(pointer, start, end); 
    5555};
    5656
     
    5858 * \return true - succeeded, false - does not occur
    5959 */
    60 bool periodentafel::CleanupPeriodtable()
    61 {
    62   return cleanup(start,end);
     60bool periodentafel::CleanupPeriodtable() 
     61{ 
     62  return cleanup(start,end); 
    6363};
    6464
     
    7676    cout << Verbose(0) << "Mass: " << endl;
    7777    cin >> walker->mass;
    78     walker->Z = Z;
    79     cout << Verbose(0) << "Atomic number: " << walker->Z << endl;
     78    walker->Z = Z; 
     79    cout << Verbose(0) << "Atomic number: " << walker->Z << endl; 
    8080    cout << Verbose(0) << "Name [max 64 chars]: " << endl;
    8181    cin >> walker->name;
     
    105105/** Asks for element number and returns pointer to element
    106106 */
    107 element * periodentafel::AskElement()
     107element * periodentafel::AskElement() 
    108108{
    109109  element *walker = NULL;
     
    117117};
    118118
     119
    119120/** Prints period table to given stream.
    120121 * \param output stream
    121  */
     122 */ 
    122123bool periodentafel::Output(ofstream *output) const
    123124{
     
    130131    }
    131132    return result;
    132   } else
     133  } else 
    133134    return false;
    134135};
     
    137138 * \param *output output stream
    138139 * \param *checkliste elements table for this molecule
    139  */
     140 */ 
    140141bool periodentafel::Checkout(ofstream *output, const int *checkliste) const
    141142{
     
    151152      if ((walker != NULL) && (walker->Z > 0) && (walker->Z < MAX_ELEMENTS) && (checkliste[walker->Z])) {
    152153        walker->No = No;
    153         result = result && walker->Checkout(output, No++, checkliste[walker->Z]);
     154        result = result && walker->Checkout(output, No++, checkliste[walker->Z]);     
    154155      }
    155156    }
    156157    return result;
    157   } else
     158  } else 
    158159    return false;
    159160};
     161
    160162
    161163/** Loads element list from file.
     
    169171  bool status = true;
    170172  bool otherstatus = true;
    171   char filename[255];
    172 
     173  char *filename = new char[MAXSTRINGSIZE];
     174 
    173175  // fill elements DB
    174176  strncpy(filename, path, MAXSTRINGSIZE);
     
    223225  if (infile != NULL) {
    224226    while (!infile.eof()) {
     227        infile >> tmp;
     228        infile >> ws;
     229        infile >> FindElement((int)tmp)->Valence;
     230        infile >> ws;
     231        //cout << Verbose(3) << "Element " << (int)tmp << " has " << FindElement((int)tmp)->Valence << " valence electrons." << endl;
     232    }
     233    infile.close();
     234    infile.clear();
     235  } else
     236    otherstatus = false;
     237
     238  // fill valence DB per element
     239  strncpy(filename, path, MAXSTRINGSIZE);
     240  strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
     241  strncat(filename, STANDARDORBITALDB, MAXSTRINGSIZE-strlen(filename));
     242  infile.open(filename);
     243  if (infile != NULL) {
     244    while (!infile.eof()) {
    225245      infile >> tmp;
    226246      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;
     247      infile >> FindElement((int)tmp)->NoValenceOrbitals;
     248      infile >> ws;
     249      //cout << Verbose(3) << "Element " << (int)tmp << " has " << FindElement((int)tmp)->NoValenceOrbitals << " number of singly occupied valence orbitals." << endl;
    230250    }
    231251    infile.close();
     
    233253  } else
    234254    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 
     255 
    254256  // fill H-BondDistance DB per element
    255257  strncpy(filename, path, MAXSTRINGSIZE);
     
    259261  if (infile != NULL) {
    260262    while (!infile.eof()) {
    261       infile >> tmp;
     263        infile >> tmp;
    262264      ptr = FindElement((int)tmp);
    263       infile >> ws;
     265        infile >> ws;
    264266      infile >> ptr->HBondDistance[0];
    265267      infile >> ptr->HBondDistance[1];
    266268      infile >> ptr->HBondDistance[2];
    267       infile >> ws;
     269        infile >> ws;
    268270      //cout << Verbose(3) << "Element " << (int)tmp << " has " << FindElement((int)tmp)->HBondDistance[0] << " Angstrom typical distance to hydrogen." << endl;
    269271    }
     
    272274  } else
    273275    otherstatus = false;
    274 
     276 
    275277  // fill H-BondAngle DB per element
    276278  strncpy(filename, path, MAXSTRINGSIZE);
     
    292294  } else
    293295    otherstatus = false;
    294 
     296 
    295297  if (!otherstatus)
    296     cerr << "WARNING: Something went wrong while parsing the other databases!" << endl;
    297 
     298    cerr << "ERROR: Something went wrong while parsing the databases!" << endl;
     299 
    298300  return status;
    299301};
     
    306308  ofstream f;
    307309  char filename[MAXSTRINGSIZE];
    308 
     310 
    309311  strncpy(filename, path, MAXSTRINGSIZE);
    310312  strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
  • src/periodentafel.hpp

    • Property mode changed from 100755 to 100644
  • src/stackclass.hpp

    • Property mode changed from 100755 to 100644
  • src/valence.db

    • Property mode changed from 100755 to 100644
    r986c80 redcda5  
    181818      0.80000000000000E+01
    191919      0.30000000000000E+01
    20 20      0.40000000000000E+01
     2020      0.20000000000000E+01
    212121      0.30000000000000E+01
    222222      0.40000000000000E+01
  • src/vector.cpp

    • Property mode changed from 100755 to 100644
    r986c80 redcda5  
    11/** \file vector.cpp
    2  *
     2 * 
    33 * Function implementations for the class vector.
    4  *
    5  */
    6 
     4 * 
     5 */
     6 
    77#include "molecules.hpp"
    8 
     8 
    99
    1010/************************************ Functions for class vector ************************************/
     
    2222Vector::~Vector() {};
    2323
    24 /** Calculates square of distance between this and another vector.
     24/** Calculates distance between this and another vector.
    2525 * \param *y array to second vector
    2626 * \return \f$| x - y |^2\f$
    2727 */
    28 double Vector::DistanceSquared(const Vector *y) const
     28double Vector::Distance(const Vector *y) const
    2929{
    3030  double res = 0.;
    3131  for (int i=NDIM;i--;)
    3232    res += (x[i]-y->x[i])*(x[i]-y->x[i]);
    33   return (res);
    34 };
    35 
    36 /** Calculates distance between this and another vector.
    37  * \param *y array to second vector
    38  * \return \f$| x - y |\f$
    39  */
    40 double Vector::Distance(const Vector *y) const
    41 {
    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));
     33  return (res); 
    4634};
    4735
     
    8169        if (tmp < res) res = tmp;
    8270      }
    83   return (res);
     71  return (res); 
    8472};
    8573
     
    124112  for (int i=NDIM;i--;)
    125113    res += x[i]*y->x[i];
    126   return (res);
    127 };
    128 
    129 
    130 /** Calculates VectorProduct between this and another vector.
    131  *  -# returns the Product in place of vector from which it was initiated
    132  *  -# ATTENTION: Only three dim.
    133  *  \param *y array to vector with which to calculate crossproduct
    134  *  \return \f$ x \times y \f&
    135  */
    136 void Vector::VectorProduct(const Vector *y)
    137 {
    138   Vector tmp;
    139   tmp.x[0] = x[1]* (y->x[2]) - x[2]* (y->x[1]);
    140   tmp.x[1] = x[2]* (y->x[0]) - x[0]* (y->x[2]);
    141   tmp.x[2] = x[0]* (y->x[1]) - x[1]* (y->x[0]);
    142   this->CopyVector(&tmp);
    143 
    144 };
    145 
     114  return (res); 
     115};
    146116
    147117/** projects this vector onto plane defined by \a *y.
    148  * \param *y normal vector of plane
     118 * \param *y array to normal vector of plane
    149119 * \return \f$\langle x, y \rangle\f$
    150120 */
     
    153123  Vector tmp;
    154124  tmp.CopyVector(y);
    155   tmp.Normalize();
    156   tmp.Scale(ScalarProduct(&tmp));
     125  tmp.Scale(Projection(y));
    157126  this->SubtractVector(&tmp);
    158127};
     
    175144  for (int i=NDIM;i--;)
    176145    res += this->x[i]*this->x[i];
    177   return (sqrt(res));
     146  return (sqrt(res)); 
    178147};
    179148
     
    209178 */
    210179void Vector::Init(double x1, double x2, double x3)
    211 {
     180{ 
    212181  x[0] = x1;
    213182  x[1] = x2;
     
    219188 * \return \f$\acos\bigl(frac{\langle x, y \rangle}{|x||y|}\bigr)\f$
    220189 */
    221 double Vector::Angle(const Vector *y) const
    222 {
    223   return acos(this->ScalarProduct(y)/Norm()/y->Norm());
     190double Vector::Angle(Vector *y) const
     191{
     192  return acos(this->ScalarProduct(y)/Norm()/y->Norm()); 
    224193};
    225194
     
    269238
    270239/** Sums two vectors \a  and \b component-wise.
    271  * \param a first vector
     240 * \param a first vector 
    272241 * \param b second vector
    273242 * \return a + b
     
    282251
    283252/** Factors given vector \a a times \a m.
    284  * \param a vector
     253 * \param a vector 
    285254 * \param m factor
    286255 * \return a + b
     
    313282};
    314283
    315 /** Prints a 3dim vector to a stream.
    316  * \param ost output stream
    317  * \param v Vector to be printed
    318  * \return output stream
    319  */
    320 ostream& operator<<(ostream& ost,Vector& m)
    321 {
    322   ost << "(";
    323   for (int i=0;i<NDIM;i++) {
    324     ost << m.x[i];
    325     if (i != 2)
    326       ost << ",";
    327   }
    328   ost << ")";
     284ofstream& operator<<(ofstream& ost,Vector& m)
     285{
     286        m.Output(&ost);
    329287        return ost;
    330288};
     
    351309};
    352310
    353 /** Translate atom by given vector.
     311/** Translate atom by given vector. 
    354312 * \param trans[] translation vector.
    355313 */
     
    358316  for (int i=NDIM;i--;)
    359317    x[i] += trans->x[i];
    360 };
     318}; 
    361319
    362320/** Do a matrix multiplication.
     
    397355    B[7] = -detAReci*RDET2(A[0],A[1],A[6],A[7]);    // A_32
    398356    B[8] =  detAReci*RDET2(A[0],A[1],A[3],A[4]);    // A_33
    399 
     357 
    400358    // do the matrix multiplication
    401359    C.x[0] = B[0]*x[0]+B[3]*x[1]+B[6]*x[2];
     
    421379{
    422380  for(int i=NDIM;i--;)
    423     x[i] = factors[0]*x1->x[i] + factors[1]*x2->x[i] + factors[2]*x3->x[i];
    424 };
    425 
    426 /** Mirrors atom against a given plane.
     381    x[i] = factors[0]*x1->x[i] + factors[1]*x2->x[i] + factors[2]*x3->x[i]; 
     382};
     383
     384/** Mirrors atom against a given plane. 
    427385 * \param n[] normal vector of mirror plane.
    428386 */
     
    440398  Output((ofstream *)&cout);
    441399  cout << endl;
    442 };
     400}; 
    443401
    444402/** Calculates normal vector for three given vectors (being three points in space).
     
    472430  this->x[2] = (x1.x[0]*x2.x[1] - x1.x[1]*x2.x[0]);
    473431  Normalize();
    474 
     432 
    475433  return true;
    476434};
     
    530488/** Creates this vector as one of the possible orthonormal ones to the given one.
    531489 * Just scan how many components of given *vector are unequal to zero and
    532  * try to get the skp of both to be zero accordingly.
     490 * try to get the skp of both to be zero accordingly. 
    533491 * \param *vector given vector
    534492 * \return true - success, false - failure (null vector given)
     
    551509      Components[Last++] = j;
    552510  cout << Verbose(4) << Last << " Components != 0: (" << Components[0] << "," << Components[1] << "," << Components[2] << ")" << endl;
    553 
     511       
    554512  switch(Last) {
    555513    case 3:  // threecomponent system
     
    564522    case 1: // one component system
    565523      // set sole non-zero component to 0, and one of the other zero component pendants to 1
    566       x[(Components[0]+2)%NDIM] = 0.;
    567       x[(Components[0]+1)%NDIM] = 1.;
    568       x[Components[0]] = 0.;
     524      x[(Components[0]+2)%NDIM] = 0.;   
     525      x[(Components[0]+1)%NDIM] = 1.;   
     526      x[Components[0]] = 0.;   
    569527      return true;
    570528      break;
     
    583541{
    584542//  cout << Verbose(3) << "For comparison: ";
    585 //  cout << "A " << A->Projection(this) << "\t";
    586 //  cout << "B " << B->Projection(this) << "\t";
    587 //  cout << "C " << C->Projection(this) << "\t";
     543//  cout << "A " << A->Projection(this) << "\t"; 
     544//  cout << "B " << B->Projection(this) << "\t"; 
     545//  cout << "C " << C->Projection(this) << "\t"; 
    588546//  cout << endl;
    589547  return A->Projection(this);
     
    595553 * \return true if success, false if failed due to linear dependency
    596554 */
    597 bool Vector::LSQdistance(Vector **vectors, int num)
     555bool Vector::LSQdistance(Vector **vectors, int num) 
    598556{
    599557        int j;
    600 
     558                               
    601559        for (j=0;j<num;j++) {
    602560                cout << Verbose(1) << j << "th atom's vector: ";
     
    607565  int np = 3;
    608566        struct LSQ_params par;
    609 
     567   
    610568   const gsl_multimin_fminimizer_type *T =
    611569     gsl_multimin_fminimizer_nmsimplex;
     
    613571   gsl_vector *ss, *y;
    614572   gsl_multimin_function minex_func;
    615 
     573 
    616574   size_t iter = 0, i;
    617575   int status;
    618576   double size;
    619 
     577 
    620578   /* Initial vertex size vector */
    621579   ss = gsl_vector_alloc (np);
    622580   y = gsl_vector_alloc (np);
    623 
     581 
    624582   /* Set all step sizes to 1 */
    625583   gsl_vector_set_all (ss, 1.0);
    626 
     584 
    627585   /* Starting point */
    628586   par.vectors = vectors;
    629587         par.num = num;
    630 
     588       
    631589         for (i=NDIM;i--;)
    632                 gsl_vector_set(y, i, (vectors[0]->x[i] - vectors[1]->x[i])/2.);
    633 
     590                gsl_vector_set(y, i, (vectors[0]->x[i] - vectors[1]->x[i])/2.); 
     591         
    634592   /* Initialize method and iterate */
    635593   minex_func.f = &LSQ;
    636594   minex_func.n = np;
    637595   minex_func.params = (void *)&par;
    638 
     596 
    639597   s = gsl_multimin_fminimizer_alloc (T, np);
    640598   gsl_multimin_fminimizer_set (s, &minex_func, y, ss);
    641 
     599 
    642600   do
    643601     {
    644602       iter++;
    645603       status = gsl_multimin_fminimizer_iterate(s);
    646 
     604 
    647605       if (status)
    648606         break;
    649 
     607 
    650608       size = gsl_multimin_fminimizer_size (s);
    651609       status = gsl_multimin_test_size (size, 1e-2);
    652 
     610 
    653611       if (status == GSL_SUCCESS)
    654612         {
    655613           printf ("converged to minimum at\n");
    656614         }
    657 
     615 
    658616       printf ("%5d ", (int)iter);
    659617       for (i = 0; i < (size_t)np; i++)
     
    664622     }
    665623   while (status == GSL_CONTINUE && iter < 100);
    666 
     624 
    667625  for (i=(size_t)np;i--;)
    668626    this->x[i] = gsl_vector_get(s->x, i);
     
    730688 * \param alpha first angle
    731689 * \param beta second angle
    732  * \param c norm of final vector
     690 * \param c norm of final vector 
    733691 * \return a vector with \f$\langle x1,x2 \rangle=A\f$, \f$\langle x1,y \rangle = B\f$ and with norm \a c.
    734  * \bug this is not yet working properly
     692 * \bug this is not yet working properly 
    735693 */
    736694bool Vector::SolveSystem(Vector *x1, Vector *x2, Vector *y, double alpha, double beta, double c)
     
    748706  if (fabs(x1->x[0]) < MYEPSILON) { // check for zero components for the later flipping and back-flipping
    749707    if (fabs(x1->x[1]) > MYEPSILON) {
    750       flag = 1;
     708      flag = 1;   
    751709    } else if (fabs(x1->x[2]) > MYEPSILON) {
    752710       flag = 2;
     
    781739  // now comes the case system
    782740  D1 = -y->x[0]/x1->x[0]*x1->x[1]+y->x[1];
    783   D2 = -y->x[0]/x1->x[0]*x1->x[2]+y->x[2];
     741  D2 = -y->x[0]/x1->x[0]*x1->x[2]+y->x[2]; 
    784742  D3 = y->x[0]/x1->x[0]*A-B1;
    785743  cout << Verbose(2) << "D1 " << D1 << "\tD2 " << D2 << "\tD3 " << D3 << "\n";
    786744  if (fabs(D1) < MYEPSILON) {
    787     cout << Verbose(2) << "D1 == 0!\n";
     745    cout << Verbose(2) << "D1 == 0!\n"; 
    788746    if (fabs(D2) > MYEPSILON) {
    789       cout << Verbose(3) << "D2 != 0!\n";
     747      cout << Verbose(3) << "D2 != 0!\n"; 
    790748      x[2] = -D3/D2;
    791749      E1 = A/x1->x[0] + x1->x[2]/x1->x[0]*D3/D2;
     
    797755      cout << Verbose(3) << "F1 " << F1 << "\tF2 " << F2 << "\tF3 " << F3 << "\n";
    798756      if (fabs(F1) < MYEPSILON) {
    799         cout << Verbose(4) << "F1 == 0!\n";
     757        cout << Verbose(4) << "F1 == 0!\n"; 
    800758        cout << Verbose(4) << "Gleichungssystem linear\n";
    801         x[1] = F3/(2.*F2);
     759        x[1] = F3/(2.*F2); 
    802760      } else {
    803761        p = F2/F1;
    804762        q = p*p - F3/F1;
    805         cout << Verbose(4) << "p " << p << "\tq " << q << endl;
     763        cout << Verbose(4) << "p " << p << "\tq " << q << endl; 
    806764        if (q < 0) {
    807765          cout << Verbose(4) << "q < 0" << endl;
     
    824782    cout << Verbose(2) << "F1 " << F1 << "\tF2 " << F2 << "\tF3 " << F3 << "\n";
    825783    if (fabs(F1) < MYEPSILON) {
    826       cout << Verbose(3) << "F1 == 0!\n";
     784      cout << Verbose(3) << "F1 == 0!\n"; 
    827785      cout << Verbose(3) << "Gleichungssystem linear\n";
    828       x[2] = F3/(2.*F2);
     786      x[2] = F3/(2.*F2);     
    829787    } else {
    830788      p = F2/F1;
    831789      q = p*p - F3/F1;
    832       cout << Verbose(3) << "p " << p << "\tq " << q << endl;
     790      cout << Verbose(3) << "p " << p << "\tq " << q << endl; 
    833791      if (q < 0) {
    834792        cout << Verbose(3) << "q < 0" << endl;
     
    874832    }
    875833    cout << Verbose(2) << i << ": sign matrix is " << sign[0] << "\t" << sign[1] << "\t" << sign[2] << "\n";
    876     // apply sign matrix
     834    // apply sign matrix 
    877835    for (j=NDIM;j--;)
    878836      x[j] *= sign[j];
     
    880838    ang = x2->Angle (this);
    881839    cout << Verbose(1) << i << "th angle " << ang << "\tbeta " << cos(beta) << " :\t";
    882     if (fabs(ang - cos(beta)) < MYEPSILON) {
     840    if (fabs(ang - cos(beta)) < MYEPSILON) { 
    883841      break;
    884842    }
  • src/vector.hpp

    • Property mode changed from 100755 to 100644
    r986c80 redcda5  
    77 * basically, just a x[3] but with helpful functions
    88 */
    9 class Vector {
     9class Vector {   
    1010  public:
    1111    double x[NDIM];
     
    1616
    1717  double Distance(const Vector *y) const;
    18   double DistanceSquared(const Vector *y) const;
    1918  double PeriodicDistance(const Vector *y, const double *cell_size) const;
    2019  double ScalarProduct(const Vector *y) const;
    2120  double Projection(const Vector *y) const;
    2221  double Norm() const ;
    23   double Angle(const Vector *y) const;
     22  double Angle(Vector *y) const;
    2423
    2524  void AddVector(const Vector *y);
     
    2726  void CopyVector(const Vector *y);
    2827  void RotateVector(const Vector *y, const double alpha);
    29   void VectorProduct(const Vector *y);
    3028  void ProjectOntoPlane(const Vector *y);
    31   void Zero();
     29  void Zero(); 
    3230  void One(double one);
    3331  void Init(double x1, double x2, double x3);
     
    4240  void KeepPeriodic(ofstream *out, double *matrix);
    4341  void LinearCombinationOfVectors(const Vector *x1, const Vector *x2, const Vector *x3, double *factors);
    44 
     42 
    4543  double CutsPlaneAt(Vector *A, Vector *B, Vector *C);
    4644  bool GetOneNormalVector(const Vector *x1);
     
    5553};
    5654
    57 ostream & operator << (ostream& ost, Vector &m);
    58 //Vector& operator+=(Vector& a, const Vector& b);
    59 //Vector& operator*=(Vector& a, const double m);
    60 //Vector& operator*(const Vector& a, const double m);
    61 //Vector& operator+(const Vector& a, const Vector& b);
     55ofstream& operator<<(ofstream& ost, Vector& m);
     56Vector& operator+=(Vector& a, const Vector& b);
     57Vector& operator*=(Vector& a, const double m);
     58Vector& operator*(const Vector& a, const double m);
     59Vector& operator+(const Vector& a, const Vector& b);
    6260
    6361#endif /*VECTOR_HPP_*/
  • src/verbose.cpp

    • Property mode changed from 100755 to 100644
  • tests/Makefile.am

    • Property mode changed from 100755 to 100644
  • tests/atlocal.in

    • Property mode changed from 100755 to 100644
  • tests/molecuilder.in

    • Property mode changed from 100755 to 100644
  • tests/testsuite.at

    • Property mode changed from 100755 to 100644
    r986c80 redcda5  
    1212AT_CHECK([../../molecuilder -h], 0, [stdout], [ignore])
    1313AT_CHECK([fgrep "Give this help screen" stdout], 0, [ignore], [ignore])
    14 AT_CHECK([../../molecuilder -e], 0, [ignore], [stderr])
    15 AT_CHECK([fgrep "Not enough or invalid arguments" stderr], 0, [ignore], [ignore])
    16 AT_CHECK([../../molecuilder test.conf], 0, [stdout], [stderr])
    17 AT_CHECK([fgrep "Element list loading failed" stdout], 0, [ignore], [ignore])
    1814AT_CLEANUP
    1915
     
    4238AT_CHECK([../../molecuilder -e ./ <input], 0, [ignore], [ignore])
    4339AT_CHECK([diff main_pcp_linux test.conf], 0, [ignore], [ignore])
    44 # 4. test some more configuration
    45 AT_CHECK([../../molecuilder test.conf -e ./ -t -s -b -F -E -c -b -a -U -T -u], 0, [ignore], [stderr])
    46 AT_CHECK([fgrep -c "Not enough or invalid" stderr], 0, [10
    47 ], [ignore])
    4840AT_CLEANUP
    4941
Note: See TracChangeset for help on using the changeset viewer.