Changes in / [fcbfc8:631dcb]


Ignore:
Files:
6 added
43 edited

Legend:

Unmodified
Added
Removed
  • ChangeLog

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

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

    • Property mode changed from 100644 to 100755
    rfcbfc8 r631dcb  
    1414AC_PROG_CC
    1515AM_MISSING_PROG([DOXYGEN], [doxygen])
    16 
    17 AC_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])
    19 AC_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])
    21 AC_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])
    23 AC_SET_COMPILER_FLAGS([$enable_optimization], [$enable_debugging], [$enable_warnings])
    2416
    2517# Checks for libraries.
  • doc/Doxyfile

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

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

    • Property mode changed from 120000 to 100644
    rfcbfc8 r631dcb  
    1 ../../m4/ac_doxygen.m4
     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
     42DX_ENV=""
     43AC_DEFUN([DX_FEATURE_doc],  ON)
     44AC_DEFUN([DX_FEATURE_dot],  ON)
     45AC_DEFUN([DX_FEATURE_man],  OFF)
     46AC_DEFUN([DX_FEATURE_html], ON)
     47AC_DEFUN([DX_FEATURE_chm],  OFF)
     48AC_DEFUN([DX_FEATURE_chi],  OFF)
     49AC_DEFUN([DX_FEATURE_rtf],  OFF)
     50AC_DEFUN([DX_FEATURE_xml],  OFF)
     51AC_DEFUN([DX_FEATURE_pdf],  ON)
     52AC_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.
     61AC_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.
     66AC_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.
     72AC_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.
     77AC_DEFUN([DX_REQUIRE_PROG], [
     78AC_PATH_TOOL([$1], [$2])
     79if 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)
     82fi
     83])
     84
     85# DX_TEST_FEATURE(FEATURE)
     86# ------------------------
     87# Expand to a shell expression testing whether the feature is active.
     88AC_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.
     94AC_DEFUN([DX_CHECK_DEPEND], [
     95test "$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.
     103AC_DEFUN([DX_CLEAR_DEPEND], [
     104test "$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.
     117AC_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                  [
     125case "$enableval" in
     126#(
     127y|Y|yes|Yes|YES)
     128    AC_SUBST([DX_FLAG_$1], 1)
     129    $3
     130;; #(
     131n|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;;
     137esac
     138], [
     139AC_SUBST([DX_FLAG_$1], [DX_IF_FEATURE([$1], 1, 0)])
     140$4
     141])
     142if DX_TEST_FEATURE([$1]); then
     143    $5
     144    :
     145fi
     146if DX_TEST_FEATURE([$1]); then
     147    AM_CONDITIONAL(DX_COND_$1, :)
     148    $6
     149    :
     150else
     151    AM_CONDITIONAL(DX_COND_$1, false)
     152    $7
     153    :
     154fi
     155])
     156
     157## -------------- ##
     158## Public macros. ##
     159## -------------- ##
     160
     161# DX_XXX_FEATURE(DEFAULT_STATE)
     162# -----------------------------
     163AC_DEFUN([DX_DOXYGEN_FEATURE], [AC_DEFUN([DX_FEATURE_doc],  [$1])])
     164AC_DEFUN([DX_MAN_FEATURE],     [AC_DEFUN([DX_FEATURE_man],  [$1])])
     165AC_DEFUN([DX_HTML_FEATURE],    [AC_DEFUN([DX_FEATURE_html], [$1])])
     166AC_DEFUN([DX_CHM_FEATURE],     [AC_DEFUN([DX_FEATURE_chm],  [$1])])
     167AC_DEFUN([DX_CHI_FEATURE],     [AC_DEFUN([DX_FEATURE_chi],  [$1])])
     168AC_DEFUN([DX_RTF_FEATURE],     [AC_DEFUN([DX_FEATURE_rtf],  [$1])])
     169AC_DEFUN([DX_XML_FEATURE],     [AC_DEFUN([DX_FEATURE_xml],  [$1])])
     170AC_DEFUN([DX_XML_FEATURE],     [AC_DEFUN([DX_FEATURE_xml],  [$1])])
     171AC_DEFUN([DX_PDF_FEATURE],     [AC_DEFUN([DX_FEATURE_pdf],  [$1])])
     172AC_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".
     178AC_DEFUN([DX_INIT_DOXYGEN], [
     179
     180# Files:
     181AC_SUBST([DX_PROJECT], [$1])
     182AC_SUBST([DX_CONFIG], [ifelse([$2], [], Doxyfile, [$2])])
     183AC_SUBST([DX_DOCDIR], [ifelse([$3], [], doxygen-doc, [$3])])
     184
     185# Environment variables used inside doxygen.cfg:
     186DX_ENV_APPEND(SRCDIR, $srcdir)
     187DX_ENV_APPEND(PROJECT, $DX_PROJECT)
     188DX_ENV_APPEND(DOCDIR, $DX_DOCDIR)
     189DX_ENV_APPEND(VERSION, $PACKAGE_VERSION)
     190
     191# Doxygen itself:
     192DX_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:
     200DX_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:
     209DX_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:
     217DX_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:
     225DX_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:
     233DX_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.
     243DX_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:
     251DX_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:
     259DX_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:
     268DX_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:
     276if DX_TEST_FEATURE(ps) || DX_TEST_FEATURE(pdf); then
     277    AM_CONDITIONAL(DX_COND_latex, :)
     278    DX_ENV_APPEND(GENERATE_LATEX, YES)
     279else
     280    AM_CONDITIONAL(DX_COND_latex, false)
     281    DX_ENV_APPEND(GENERATE_LATEX, NO)
     282fi
     283
     284# Paper size for PS and/or PDF:
     285AC_ARG_VAR(DOXYGEN_PAPER_SIZE,
     286           [a4wide (default), a4, letter, legal or executive])
     287case "$DOXYGEN_PAPER_SIZE" in
     288#(
     289"")
     290    AC_SUBST(DOXYGEN_PAPER_SIZE, "")
     291;; #(
     292a4wide|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;;
     298esac
     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])
  • m4/acx_compilerflags.m4

    • Property mode changed from 120000 to 100644
    rfcbfc8 r631dcb  
    1 ../../m4/acx_compilerflags.m4
     1# AC_SET_COMPILER_FLAGS(optimization, debugging, warnings)
     2#----------------------------------------------------------------
     3AC_DEFUN([AC_SET_COMPILER_FLAGS],[
     4AC_MSG_NOTICE([Using AC@&t@_SET_COMPILER_FLAGS macro])
     5
     6dnl optimization
     7if 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
     15fi
     16dnl debugging info
     17if ! 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)
     25fi
     26
     27dnl enable all warnings
     28if 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"
     32fi
     33if 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"
     36fi
     37if test x"$3" = xnone; then
     38        unset Cwarnings
     39        unset CXXwarnings
     40else
     41        AC_DEFINE(HAVE_WARNINGS,$enable_warnings, ["Output compiler warnings"])
     42fi
     43
     44# finally, apply whatever was set
     45CFLAGS="$CFLAGS $debugging $optimization $Cwarnings"
     46CXXFLAGS="$CXXFLAGS $debugging $optimization $CXXwarnings"
     47
     48])
  • src/Hbondangle.db

    • Property mode changed from 100644 to 100755
    rfcbfc8 r631dcb  
    447       180     110     106.67
    558       180     104.5   -1
    6 14      180     120     109.5
     614      180     120     109.47
    7715      180     -1      -1
    8816      180     -1      -1
    9917      180 -1 -1
     1020      180     120     109.47
    101134      180 -1 -1
    111235      180 -1 -1
  • src/Hbonddistance.db

    • Property mode changed from 100644 to 100755
    rfcbfc8 r631dcb  
    9916      1.35    -1      -1
    101017      1.29    -1      -1
     1120      1.09    1.09    -1
    111234      1.47    -1      -1
    121335      1.44    -1      -1
  • src/Makefile.am

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

    • Property mode changed from 100644 to 100755
    rfcbfc8 r631dcb  
    2525  periodentafel *periode = NULL; // and a period table of all elements
    2626  EnergyMatrix Energy;
     27  EnergyMatrix EnergyFragments;
     28  ForceMatrix Force;
     29  ForceMatrix ForceFragments;
     30  HessianMatrix Hessian;
     31  HessianMatrix HessianFragments;
    2732  EnergyMatrix Hcorrection;
    28   ForceMatrix Force;
     33  EnergyMatrix HcorrectionFragments;
    2934  ForceMatrix Shielding;
    3035  ForceMatrix ShieldingPAS;
     36  ForceMatrix Chi;
     37  ForceMatrix ChiPAS;
    3138  EnergyMatrix Time;
    32   EnergyMatrix EnergyFragments;
    33   EnergyMatrix HcorrectionFragments;
    34   ForceMatrix ForceFragments;
    3539  ForceMatrix ShieldingFragments;
    3640  ForceMatrix ShieldingPASFragments;
     41  ForceMatrix ChiFragments;
     42  ForceMatrix ChiPASFragments;
    3743  KeySetsContainer KeySet;
    3844  ofstream output;
     
    4955  stringstream yrange;
    5056  char *dir = NULL;
    51   bool Hcorrected = true;
    52   double norm;
     57  bool NoHCorrection = false;
     58  bool NoHessian = false;
     59  bool NoTime = false;
    5360  int counter;
    5461 
     
    8491  // ------------- Parse through all Fragment subdirs --------
    8592  if (!Energy.ParseFragmentMatrix(argv[1], dir, EnergySuffix,0,0)) return 1;
    86   Hcorrected = Hcorrection.ParseFragmentMatrix(argv[1], "", HCORRECTIONSUFFIX,0,0);
     93  if (!Hcorrection.ParseFragmentMatrix(argv[1], "", HCORRECTIONSUFFIX,0,0)) {
     94    NoHCorrection = true;
     95    cout << "No HCorrection file found, skipping these." << endl;
     96  }
     97 
    8798  if (!Force.ParseFragmentMatrix(argv[1], dir, ForcesSuffix,0,0)) return 1;
    88   if (!Time.ParseFragmentMatrix(argv[1], dir, TimeSuffix, 10,1)) return 1;
     99  if (!Hessian.ParseFragmentMatrix(argv[1], dir, HessianSuffix,0,0)) {
     100    NoHessian = true;
     101    cout << "No Hessian file found, skipping these." << endl;
     102  }
     103  if (!Time.ParseFragmentMatrix(argv[1], dir, TimeSuffix, 10,1)) {
     104    NoTime = true;
     105    cout << "No speed file found, skipping these." << endl;
     106  }
    89107  if (periode != NULL) { // also look for PAS values
    90108    if (!Shielding.ParseFragmentMatrix(argv[1], dir, ShieldingSuffix, 1, 0)) return 1;
    91109    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;
    92112  }
    93113
    94114  // ---------- Parse the TE Factors into an array -----------------
    95   if (!Energy.ParseIndices()) return 1;
    96   if (Hcorrected) Hcorrection.ParseIndices();
     115  if (!Energy.InitialiseIndices()) return 1;
     116  if (!NoHCorrection)
     117    Hcorrection.InitialiseIndices();
    97118 
    98119  // ---------- Parse the Force indices into an array ---------------
    99120  if (!Force.ParseIndices(argv[1])) return 1;
    100121  if (!ForceFragments.AllocateMatrix(Force.Header, Force.MatrixCounter, Force.RowCounter, Force.ColumnCounter)) return 1;
    101   if (!ForceFragments.ParseIndices(argv[1])) 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  }
    102130
    103131  // ---------- Parse the shielding indices into an array ---------------
     
    105133    if(!Shielding.ParseIndices(argv[1])) return 1;
    106134    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;
    107145  }
    108146
     
    113151  // ---------- Parse fragment files created by 'joiner' into an array -------------
    114152  if (!EnergyFragments.ParseFragmentMatrix(argv[1], dir, EnergyFragmentSuffix,0,0)) return 1;
    115   if (Hcorrected) HcorrectionFragments.ParseFragmentMatrix(argv[1], dir, HcorrectionFragmentSuffix,0,0);
     153  if (!NoHCorrection)
     154    HcorrectionFragments.ParseFragmentMatrix(argv[1], dir, HcorrectionFragmentSuffix,0,0);
    116155  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;
    117158  if (periode != NULL) { // also look for PAS values
    118159    if (!ShieldingFragments.ParseFragmentMatrix(argv[1], dir, ShieldingFragmentSuffix, 1, 0)) return 1;
    119160    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;
    120163  }
    121164
     
    126169  filename << argv[3] << "/" << "energy-forces.all";
    127170  output.open(filename.str().c_str(), ios::out);
    128   output << endl << "Total Energy" << endl << "==============" << endl << Energy.Header << endl;
     171  output << endl << "Total Energy" << endl << "==============" << endl << Energy.Header[Energy.MatrixCounter] << endl;
    129172  for(int j=0;j<Energy.RowCounter[Energy.MatrixCounter];j++) {
    130     for(int k=0;k<Energy.ColumnCounter;k++)
     173    for(int k=0;k<Energy.ColumnCounter[Energy.MatrixCounter];k++)
    131174      output << scientific << Energy.Matrix[ Energy.MatrixCounter ][j][k] << "\t";
    132175    output << endl;
     
    134177  output << endl;
    135178 
    136   output << endl << "Total Forces" << endl << "===============" << endl << Force.Header << endl;
     179  output << endl << "Total Forces" << endl << "===============" << endl << Force.Header[Force.MatrixCounter] << endl;
    137180  for(int j=0;j<Force.RowCounter[Force.MatrixCounter];j++) {
    138     for(int k=0;k<Force.ColumnCounter;k++)
     181    for(int k=0;k<Force.ColumnCounter[Force.MatrixCounter];k++)
    139182      output << scientific << Force.Matrix[ Force.MatrixCounter ][j][k] << "\t";
    140183    output << endl;
     
    142185  output << endl;
    143186
     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
    144197  if (periode != NULL) { // also look for PAS values
    145     output << endl << "Total Shieldings" << endl << "===============" << endl << Shielding.Header << endl;
     198    output << endl << "Total Shieldings" << endl << "===============" << endl << Shielding.Header[Hessian.MatrixCounter] << endl;
    146199    for(int j=0;j<Shielding.RowCounter[Shielding.MatrixCounter];j++) {
    147       for(int k=0;k<Shielding.ColumnCounter;k++)
     200      for(int k=0;k<Shielding.ColumnCounter[Shielding.MatrixCounter];k++)
    148201        output << scientific << Shielding.Matrix[ Shielding.MatrixCounter ][j][k] << "\t";
    149202      output << endl;
     
    151204    output << endl;
    152205 
    153     output << endl << "Total Shieldings PAS" << endl << "===============" << endl << ShieldingPAS.Header << endl;
     206    output << endl << "Total Shieldings PAS" << endl << "===============" << endl << ShieldingPAS.Header[ShieldingPAS.MatrixCounter] << endl;
    154207    for(int j=0;j<ShieldingPAS.RowCounter[ShieldingPAS.MatrixCounter];j++) {
    155       for(int k=0;k<ShieldingPAS.ColumnCounter;k++)
     208      for(int k=0;k<ShieldingPAS.ColumnCounter[ShieldingPAS.MatrixCounter];k++)
    156209        output << scientific << ShieldingPAS.Matrix[ ShieldingPAS.MatrixCounter ][j][k] << "\t";
    157210      output << endl;
    158211    }
    159212    output << endl;
    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;
     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[Chi.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  }
    170241  output.close();
    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];
     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];
    173245
    174246  // +++++++++++++++ ANALYZING ++++++++++++++++++++++++++++++
     
    180252  // +++++++++++++++++++++++++++++++++++++++ Plotting Simtime vs Bond Order
    181253  // +++++++++++++++++++++++++++++++++++++++ Plotting Delta Simtime vs Bond Order
    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();
     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  }
    212305
    213306  // +++++++++++++++++++++++++++++++++++++++ Plotting shieldings
    214307  if (periode != NULL) { // also look for PAS values
    215     if (!OpenOutputFile(output, argv[3], "ShieldingPAS-Atom.dat" )) return false;
    216     output << "#" << ShieldingPAS.Header << endl;
     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;
    217312    for(int j=0;j<ShieldingPAS.RowCounter[ShieldingPAS.MatrixCounter];j++) {
    218       for(int k=0;k<ShieldingPAS.ColumnCounter;k++)
    219         output << scientific << ShieldingPAS.Matrix[ ShieldingPAS.MatrixCounter ][j][k]*(((k>1) && (k<6))? 1.e6 : 1.) << "\t";
    220       output << endl;
    221     }
    222     output << endl << endl; // another two newlines to partition the data
    223     for(int j=0;j<ShieldingPASFragments.RowCounter[ShieldingPASFragments.MatrixCounter];j++) {
    224       for(int k=0;k<ShieldingPASFragments.ColumnCounter;k++)
    225         output << scientific << ShieldingPASFragments.Matrix[ ShieldingPASFragments.MatrixCounter ][j][k]*(((k>1) && (k<6))? 1.e6 : 1.) << "\t";
    226       output << endl;
    227     }
    228     output << endl;
    229   }
    230   output.close();
     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  }
    231331
    232332 
     
    251351  // ++++++++++++++++++++++++++++++++++++++Plotting Forces vs. Order
    252352  if (!CreateDataForcesOrderPerAtom(ForceFragments, KeySet, argv[3], "Forces-Order", "Plot of approximated forces versus the Bond Order", datum)) return 1;
    253 
     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();
    254362  // min force
    255363  if (!CreateDataForcesOrder(ForceFragments, KeySet, argv[3], "MinForces-Order", "Plot of min approximated forces versus the Bond Order", datum, CreateMinimumForce)) return 1;
     
    296404  yrange.str("[1e-8:1e+1]");
    297405 
    298   // +++++++++++++++++++++++++++++++++++++++ Plotting Simtime vs Bond Order
    299   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;
     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  }
    300410 
    301411  // +++++++++++++++++++++++++++++++++++++++ Plotting deviation in energy to full QM
     
    380490  // +++++++++++++++++++++++++++++++=Ploting approximated and true shielding for each atom
    381491  if (periode != NULL) { // also look for PAS values
    382     if(!OpenOutputFile(output, argv[3], "ShieldingPAS-Atom.pyx")) return 1;
    383     CreatePlotHeader(output, "ShieldingPAS-Atom", 1, "top right", NULL, NULL,  1, 5, "nuclei index", "chemical shielding value [ppm]");
    384     output << "plot \\" << endl; 
    385     output << "'ShieldingPAS-Atom.dat' index 0 title 'DFT' using 2:6 with linespoints, \\" << endl;
    386     output << "'ShieldingPAS-Atom.dat' index 1 title 'BOSSANOVA' using 2:6 with linespoints" << endl;
     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;
    387523    output.close(); 
     524    output2.close(); 
    388525  }
    389526
  • src/atom.cpp

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

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

    • Property mode changed from 100644 to 100755
    rfcbfc8 r631dcb  
    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
    410// ======================================== Points on Boundary =================================
    511
     
    814  LinesCount = 0;
    915  Nr = -1;
    10 };
     16}
     17;
    1118
    1219BoundaryPointSet::BoundaryPointSet(atom *Walker)
     
    1522  LinesCount = 0;
    1623  Nr = Walker->nr;
    17 };
     24}
     25;
    1826
    1927BoundaryPointSet::~BoundaryPointSet()
     
    2129  cout << Verbose(5) << "Erasing point nr. " << Nr << "." << endl;
    2230  node = NULL;
    23 };
    24 
    25 void 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   }
     31  lines.clear();
     32}
     33;
     34
     35void
     36BoundaryPointSet::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    }
    3348  LinesCount++;
    34 };
    35 
    36 ostream & operator << (ostream &ost, BoundaryPointSet &a)
     49}
     50;
     51
     52ostream &
     53operator <<(ostream &ost, BoundaryPointSet &a)
    3754{
    3855  ost << "[" << a.Nr << "|" << a.node->Name << "]";
    3956  return ost;
    40 };
     57}
     58;
    4159
    4260// ======================================== Lines on Boundary =================================
     
    4462BoundaryLineSet::BoundaryLineSet()
    4563{
    46   for (int i=0;i<2;i++)
     64  for (int i = 0; i < 2; i++)
    4765    endpoints[i] = NULL;
    4866  TrianglesCount = 0;
    4967  Nr = -1;
    50 };
     68}
     69;
    5170
    5271BoundaryLineSet::BoundaryLineSet(class BoundaryPointSet *Point[2], int number)
     
    5776  SetEndpointsOrdered(endpoints, Point[0], Point[1]);
    5877  // add this line to the hash maps of both endpoints
    59   Point[0]->AddLine(this);
    60   Point[1]->AddLine(this);
     78  Point[0]->AddLine(this); //Taken out, to check whether we can avoid unwanted double adding.
     79  Point[1]->AddLine(this); //
    6180  // clear triangles list
    6281  TrianglesCount = 0;
    6382  cout << Verbose(5) << "New Line with endpoints " << *this << "." << endl;
    64 };
     83}
     84;
    6585
    6686BoundaryLineSet::~BoundaryLineSet()
    6787{
    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 
    81 void BoundaryLineSet::AddTriangle(class BoundaryTriangleSet *triangle)
    82 {
    83   cout << Verbose(6) << "Add " << triangle->Nr << " to line " << *this << "." << endl;
    84   triangles.insert ( TrianglePair( TrianglesCount, triangle) );
     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
     106void
     107BoundaryLineSet::AddTriangle(class BoundaryTriangleSet *triangle)
     108{
     109  cout << Verbose(6) << "Add " << triangle->Nr << " to line " << *this << "."
     110      << endl;
     111  triangles.insert(TrianglePair(TrianglesCount, triangle));
    85112  TrianglesCount++;
    86 };
    87 
    88 ostream & operator << (ostream &ost, BoundaryLineSet &a)
    89 {
    90   ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << "," << a.endpoints[1]->node->Name << "]";
     113}
     114;
     115
     116ostream &
     117operator <<(ostream &ost, BoundaryLineSet &a)
     118{
     119  ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << ","
     120      << a.endpoints[1]->node->Name << "]";
    91121  return ost;
    92 };
     122}
     123;
    93124
    94125// ======================================== Triangles on Boundary =================================
     
    97128BoundaryTriangleSet::BoundaryTriangleSet()
    98129{
    99   for (int i=0;i<3;i++) {
    100     endpoints[i] = NULL;
    101     lines[i] = NULL;
    102   }
     130  for (int i = 0; i < 3; i++)
     131    {
     132      endpoints[i] = NULL;
     133      lines[i] = NULL;
     134    }
    103135  Nr = -1;
    104 };
    105 
    106 BoundaryTriangleSet::BoundaryTriangleSet(class BoundaryLineSet *line[3], int number)
     136}
     137;
     138
     139BoundaryTriangleSet::BoundaryTriangleSet(class BoundaryLineSet *line[3],
     140    int number)
    107141{
    108142  // set number
     
    110144  // set lines
    111145  cout << Verbose(5) << "New triangle " << Nr << ":" << endl;
    112   for (int i=0;i<3;i++) {
    113     lines[i] = line[i];
    114     lines[i]->AddTriangle(this);
    115   }
     146  for (int i = 0; i < 3; i++)
     147    {
     148      lines[i] = line[i];
     149      lines[i]->AddTriangle(this);
     150    }
    116151  // 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
    122     }
     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      }
    123161  // set endpoints
    124162  int Counter = 0;
    125163  cout << Verbose(6) << " with end points ";
    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   }
     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    }
    135177  cout << "." << endl;
    136 };
     178}
     179;
    137180
    138181BoundaryTriangleSet::~BoundaryTriangleSet()
    139182{
    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 
    153 void BoundaryTriangleSet::GetNormalVector(Vector &NormalVector)
     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
     199void
     200BoundaryTriangleSet::GetNormalVector(Vector &OtherVector)
    154201{
    155202  // get normal vector
    156   NormalVector.MakeNormalVector(&endpoints[0]->node->x, &endpoints[1]->node->x, &endpoints[2]->node->x);
    157  
     203  NormalVector.MakeNormalVector(&endpoints[0]->node->x, &endpoints[1]->node->x,
     204      &endpoints[2]->node->x);
     205
    158206  // make it always point inward (any offset vector onto plane projected onto normal vector suffices)
    159   if (endpoints[0]->node->x.Projection(&NormalVector) > 0)
     207  if (endpoints[0]->node->x.Projection(&OtherVector) > 0)
    160208    NormalVector.Scale(-1.);
    161 };
    162 
    163 ostream & 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 << "]";
     209}
     210;
     211
     212ostream &
     213operator <<(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 << "]";
    166217  return ost;
    167 };
     218}
     219;
    168220
    169221// ========================================== F U N C T I O N S =================================
     
    174226 * \return point which is shared or NULL if none
    175227 */
    176 class BoundaryPointSet * GetCommonEndpoint(class BoundaryLineSet * line1, class BoundaryLineSet * line2)
    177 {
    178   class BoundaryLineSet * lines[2] = {line1, line2};
     228class BoundaryPointSet *
     229GetCommonEndpoint(class BoundaryLineSet * line1, class BoundaryLineSet * line2)
     230{
     231  class BoundaryLineSet * lines[2] =
     232    { line1, line2 };
    179233  class BoundaryPointSet *node = NULL;
    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;
     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          }
    191251      }
    192     }
    193252  return node;
    194 };
     253}
     254;
    195255
    196256/** Determines the boundary points of a cluster.
     
    201261 * \param *mol molecule structure representing the cluster
    202262 */
    203 Boundaries * GetBoundaryPoints(ofstream *out, molecule *mol)
     263Boundaries *
     264GetBoundaryPoints(ofstream *out, molecule *mol)
    204265{
    205266  atom *Walker = NULL;
     
    207268  LineMap LinesOnBoundary;
    208269  TriangleMap TrianglesOnBoundary;
    209  
     270
    210271  *out << Verbose(1) << "Finding all boundary points." << endl;
    211   Boundaries *BoundaryPoints = new Boundaries [NDIM]; // first is alpha, second is (r, nr)
     272  Boundaries *BoundaryPoints = new Boundaries[NDIM]; // first is alpha, second is (r, nr)
    212273  BoundariesTestPair BoundaryTestPair;
    213274  Vector AxisVector, AngleReferenceVector, AngleReferenceNormalVector;
    214275  double radius, angle;
    215276  // 3a. Go through every axis
    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;
     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)
     296        {
     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            }
    278360        }
    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;
     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            }
    307457        }
    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)
    317         {
    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           }
    363         }
    364       }
    365     } while (flag);
    366   }
     458      while (flag);
     459    }
    367460  return BoundaryPoints;
    368 };
     461}
     462;
    369463
    370464/** Determines greatest diameters of a cluster defined by its convex envelope.
     
    375469 * \param IsAngstroem whether we have angstroem or atomic units
    376470 * \return NDIM array of the diameters
    377  */
    378 double * GetDiametersOfCluster(ofstream *out, Boundaries *BoundaryPtr, molecule *mol, bool IsAngstroem)
     471 */
     472double *
     473GetDiametersOfCluster(ofstream *out, Boundaries *BoundaryPtr, molecule *mol,
     474    bool IsAngstroem)
    379475{
    380476  // get points on boundary of NULL was given as parameter
    381477  bool BoundaryFreeFlag = false;
    382478  Boundaries *BoundaryPoints = BoundaryPtr;
    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  
     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    }
    390488  // determine biggest "diameter" of cluster for each axis
    391489  Boundaries::iterator Neighbour, OtherNeighbour;
    392490  double *GreatestDiameter = new double[NDIM];
    393   for(int i=0;i<NDIM;i++)
     491  for (int i = 0; i < NDIM; i++)
    394492    GreatestDiameter[i] = 0.;
    395493  double OldComponent, tmp, w1, w2;
    396494  Vector DistanceVector, OtherVector;
    397495  int component, Othercomponent;
    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       }
    443     }
    444   }
    445   *out << Verbose(0) << "RESULT: The biggest diameters are " << GreatestDiameter[0] << " and " << GreatestDiameter[1] << " and " << GreatestDiameter[2] << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "." << endl;
     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        }
     553    }
     554  *out << Verbose(0) << "RESULT: The biggest diameters are "
     555      << GreatestDiameter[0] << " and " << GreatestDiameter[1] << " and "
     556      << GreatestDiameter[2] << " " << (IsAngstroem ? "angstrom"
     557      : "atomiclength") << "." << endl;
    446558
    447559  // free reference lists
    448560  if (BoundaryFreeFlag)
    449     delete[](BoundaryPoints);
     561    delete[] (BoundaryPoints);
    450562
    451563  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 */
     573void 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);
    452619};
    453620
     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 */
     626void
     627write_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}
    454671
    455672/** Determines the volume of a cluster.
    456673 * Determines first the convex envelope, then tesselates it and calculates its volume.
    457674 * \param *out output stream for debugging
     675 * \param *tecplot output stream for tecplot data
    458676 * \param *configuration needed for path to store convex envelope file
    459677 * \param *BoundaryPoints NDIM set of boundary points on the projected plane per axis, on return if desired
    460678 * \param *mol molecule structure representing the cluster
     679 * \return determined volume of the cluster in cubed config:GetIsAngstroem()
    461680 */
    462 double VolumeOfConvexEnvelope(ofstream *out, config *configuration, Boundaries *BoundaryPtr, molecule *mol)
     681double
     682VolumeOfConvexEnvelope(ofstream *out, ofstream *tecplot, config *configuration,
     683    Boundaries *BoundaryPtr, molecule *mol)
    463684{
    464685  bool IsAngstroem = configuration->GetIsAngstroem();
     
    469690  double volume = 0.;
    470691  double PyramidVolume = 0.;
    471   double G,h;
    472   Vector x,y;
    473   double a,b,c;
     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.
    474697
    475698  // 1. calculate center of gravity
    476699  *out << endl;
    477700  Vector *CenterOfGravity = mol->DetermineCenterOfGravity(out);
    478  
     701
    479702  // 2. translate all points into CoG
    480703  *out << Verbose(1) << "Translating system to Center of Gravity." << endl;
    481704  Walker = mol->start;
    482   while (Walker->next != mol->end) {
    483     Walker = Walker->next;
    484     Walker->x.Translate(CenterOfGravity);
    485   }
    486  
     705  while (Walker->next != mol->end)
     706    {
     707      Walker = Walker->next;
     708      Walker->x.Translate(CenterOfGravity);
     709    }
     710
    487711  // 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  
     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
    495722  // 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);
    499     }
    500 
    501   *out << Verbose(2) << "I found " << TesselStruct->PointsOnBoundaryCount << " points on the convex boundary." << endl;
     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;
    502732  // now we have the whole set of edge points in the BoundaryList
    503733
    504 
    505734  // listing for debugging
    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  
     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
    512741  // 5a. guess starting triangle
    513742  TesselStruct->GuessStartingTriangle(out);
    514  
     743
    515744  // 5b. go through all lines, that are not yet part of two triangles (only of one so far)
    516745  TesselStruct->TesselateOnBoundary(out, configuration, mol);
    517746
    518   *out << Verbose(2) << "I created " << TesselStruct->TrianglesOnBoundaryCount << " triangles with " << TesselStruct->LinesOnBoundaryCount << " lines and " << TesselStruct->PointsOnBoundaryCount << " points." << endl;
     747  *out << Verbose(2) << "I created " << TesselStruct->TrianglesOnBoundaryCount
     748      << " triangles with " << TesselStruct->LinesOnBoundaryCount
     749      << " lines and " << TesselStruct->PointsOnBoundaryCount << " points."
     750      << endl;
    519751
    520752  // 6a. Every triangle forms a pyramid with the center of gravity as its peak, sum up the volumes
    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 
     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;
    540786
    541787  // 7. translate all points back from CoG
    542   *out << Verbose(1) << "Translating system back from Center of Gravity." << endl;
     788  *out << Verbose(1) << "Translating system back from Center of Gravity."
     789      << endl;
    543790  CenterOfGravity->Scale(-1);
    544791  Walker = mol->start;
    545   while (Walker->next != mol->end) {
    546     Walker = Walker->next;
    547     Walker->x.Translate(CenterOfGravity);
    548   }
     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);
    549800
    550801  // free reference lists
    551802  if (BoundaryFreeFlag)
    552     delete[](BoundaryPoints);
    553  
     803    delete[] (BoundaryPoints);
     804
    554805  return volume;
    555 };
    556 
     806}
     807;
    557808
    558809/** Creates multiples of the by \a *mol given cluster and suspends them in water with a given final density.
     
    564815 * \param celldensity desired average density in final cell
    565816 */
    566 void PrepareClustersinWater(ofstream *out, config *configuration, molecule *mol, double ClusterVolume, double celldensity)
     817void
     818PrepareClustersinWater(ofstream *out, config *configuration, molecule *mol,
     819    double ClusterVolume, double celldensity)
    567820{
    568821  // transform to PAS
    569822  mol->PrincipalAxisSystem(out, true);
    570  
     823
    571824  // some preparations beforehand
    572825  bool IsAngstroem = configuration->GetIsAngstroem();
     
    574827  double clustervolume;
    575828  if (ClusterVolume == 0)
    576     clustervolume = VolumeOfConvexEnvelope(out, configuration, BoundaryPoints, mol);
    577   else
     829    clustervolume = VolumeOfConvexEnvelope(out, NULL, configuration,
     830        BoundaryPoints, mol);
     831  else
    578832    clustervolume = ClusterVolume;
    579   double *GreatestDiameter = GetDiametersOfCluster(out, BoundaryPoints, mol, IsAngstroem);
     833  double *GreatestDiameter = GetDiametersOfCluster(out, BoundaryPoints, mol,
     834      IsAngstroem);
    580835  Vector BoxLengths;
    581   int repetition[NDIM] = {1, 1, 1};
     836  int repetition[NDIM] =
     837    { 1, 1, 1 };
    582838  int TotalNoClusters = 1;
    583   for (int i=0;i<NDIM;i++)
     839  for (int i = 0; i < NDIM; i++)
    584840    TotalNoClusters *= repetition[i];
    585841
     
    587843  double totalmass = 0.;
    588844  atom *Walker = mol->start;
    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  
     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
    597857  // solve cubic polynomial
    598   *out << Verbose(1) << "Solving equidistant suspension in water problem ..." << endl;
     858  *out << Verbose(1) << "Solving equidistant suspension in water problem ..."
     859      << endl;
    599860  double cellvolume;
    600861  if (IsAngstroem)
    601     cellvolume = (TotalNoClusters*totalmass/SOLVENTDENSITY_A - (totalmass/clustervolume))/(celldensity-1);
     862    cellvolume = (TotalNoClusters * totalmass / SOLVENTDENSITY_A - (totalmass
     863        / clustervolume)) / (celldensity - 1);
    602864  else
    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
    626     }
    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];
    632     }
    633  
    634     // set new box dimensions
    635     *out << Verbose(0) << "Translating to box with these boundaries." << endl;
    636     mol->CenterInBox((ofstream *)&cout, &BoxLengths);
    637   }
     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);
     888    }
     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);
     920    }
    638921  // update Box of atoms by boundary
    639922  mol->SetBoxDimension(&BoxLengths);
    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 
     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;
    643929
    644930// =========================================================== class TESSELATION ===========================================
     
    648934Tesselation::Tesselation()
    649935{
    650   PointsOnBoundaryCount = 0; 
    651   LinesOnBoundaryCount = 0; 
     936  PointsOnBoundaryCount = 0;
     937  LinesOnBoundaryCount = 0;
    652938  TrianglesOnBoundaryCount = 0;
    653 };
     939  TriangleFilesWritten = 0;
     940}
     941;
    654942
    655943/** Constructor of class Tesselation.
     
    658946Tesselation::~Tesselation()
    659947{
    660   for (TriangleMap::iterator runner = TrianglesOnBoundary.begin(); runner != TrianglesOnBoundary.end(); runner++) {
    661     delete(runner->second);
    662   }
    663 };
     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;
    664972
    665973/** Gueses first starting triangle of the convex envelope.
     
    667975 * \param *out output stream for debugging
    668976 * \param PointsOnBoundary set of boundary points defining the convex envelope of the cluster
    669  */
    670 void Tesselation::GuessStartingTriangle(ofstream *out)
     977 */
     978void
     979Tesselation::GuessStartingTriangle(ofstream *out)
    671980{
    672981  // 4b. create a starting triangle
    673982  // 4b1. create all distances
    674983  DistanceMultiMap DistanceMMap;
    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       }
    682     }
    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
     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        }
     1010    }
     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
    6941019  DistanceMultiMap::iterator baseline = DistanceMMap.begin();
    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 
     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;
    7371135
    7381136/** Tesselates the convex envelope of a cluster from a single starting triangle.
     
    7491147 * \param *mol the cluster as a molecule structure
    7501148 */
    751 void Tesselation::TesselateOnBoundary(ofstream *out, config *configuration, molecule *mol)
     1149void
     1150Tesselation::TesselateOnBoundary(ofstream *out, config *configuration,
     1151    molecule *mol)
    7521152{
    7531153  bool flag;
     
    7551155  class BoundaryPointSet *peak = NULL;
    7561156  double SmallestAngle, TempAngle;
    757   Vector NormalVector, VirtualNormalVector, CenterVector, TempVector, PropagationVector;
     1157  Vector NormalVector, VirtualNormalVector, CenterVector, TempVector,
     1158      PropagationVector;
    7581159  LineMap::iterator LineChecker[2];
    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;
     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++;
    8611355              }
    862             }
     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
    8631364          }
    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 };
     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;
    9301374
    9311375/** Adds an atom to the tesselation::PointsOnBoundary list.
    9321376 * \param *Walker atom to add
    9331377 */
    934 void Tesselation::AddPoint(atom *Walker)
    935 {
     1378void
     1379Tesselation::AddPoint(atom *Walker)
     1380{
     1381  PointTestPair InsertUnique;
    9361382  BPS[0] = new class BoundaryPointSet(Walker);
    937   PointsOnBoundary.insert( PointPair(Walker->nr, BPS[0]) );
    938   PointsOnBoundaryCount++;
     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 */
     1394void
     1395Tesselation::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 */
     1421void
     1422Tesselation::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 */
     1466void
     1467Tesselation::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
     1583void 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   */
     1765void 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        }
    9391970};
     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 */
     1982bool 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 */
     2160bool 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
     2196void 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
     2242void 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
     2344void 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
  • src/boundary.hpp

    • Property mode changed from 100644 to 100755
    rfcbfc8 r631dcb  
    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;
    7172    int Nr;
    7273};
     
    7475class Tesselation {
    7576  public:
    76    
     77
    7778    Tesselation();
    7879    ~Tesselation();
    79    
     80
    8081    void TesselateOnBoundary(ofstream *out, config *configuration, molecule *mol);
    8182    void GuessStartingTriangle(ofstream *out);
    8283    void AddPoint(atom * Walker);
    83    
     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
    8492    PointMap PointsOnBoundary;
    8593    LineMap LinesOnBoundary;
    8694    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
    8796    class BoundaryPointSet *BPS[2];
    8897    class BoundaryLineSet *BLS[3];
     
    91100    int LinesOnBoundaryCount;
    92101    int TrianglesOnBoundaryCount;
     102    int TriangleFilesWritten;
    93103};
    94104
     
    99109
    100110
    101 double VolumeOfConvexEnvelope(ofstream *out, config *configuration, Boundaries *BoundaryPoints, molecule *mol);
     111double VolumeOfConvexEnvelope(ofstream *out, ofstream *tecplot, config *configuration, Boundaries *BoundaryPoints, molecule *mol);
    102112double * GetDiametersOfCluster(ofstream *out, Boundaries *BoundaryPtr, molecule *mol, bool IsAngstroem);
    103113void PrepareClustersinWater(ofstream *out, config *configuration, molecule *mol, double ClusterVolume, double celldensity);
     114void Find_non_convex_border(ofstream *out, ofstream *tecplot, molecule* mol, const char *tempbasename, const double RADIUS);
     115void 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);
    104116
    105117
  • src/builder.cpp

    • Property mode changed from 100644 to 100755
    rfcbfc8 r631dcb  
    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;
     261  Vector x, y, helper;
    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       mol->SetBoxDimension(&(x+y*2));  // update Box of atoms by boundary
     294      helper.CopyVector(&y);
     295      helper.Scale(2.);
     296      helper.AddVector(&x);
     297      mol->SetBoxDimension(&helper);  // update Box of atoms by boundary
    295298      break;
    296299    case 'd':
     
    327330  cout << Verbose(0) << "INPUT: ";
    328331  cin >> choice;
    329  
     332
    330333  switch (choice) {
    331334    default:
     
    346349      second = mol->AskAtom("Enter second atom: ");
    347350
    348       n.CopyVector((const Vector *)&first->x); 
    349       n.SubtractVector((const Vector *)&second->x); 
     351      n.CopyVector((const Vector *)&first->x);
     352      n.SubtractVector((const Vector *)&second->x);
    350353      n.Normalize();
    351       break;       
     354      break;
    352355    case 'd':
    353356      char shorthand[4];
     
    363366        x.x[i] = gsl_vector_get(param.x,i);
    364367        n.x[i] = gsl_vector_get(param.x,i+NDIM);
    365       } 
     368      }
    366369      gsl_vector_free(param.x);
    367370      cout << Verbose(0) << "Offset vector: ";
     
    369372      cout << Verbose(0) << endl;
    370373      n.Normalize();
    371       break;       
     374      break;
    372375  };
    373376  cout << Verbose(0) << "Alignment vector: ";
     
    385388  Vector n;
    386389  char choice;  // menu choice char
    387  
     390
    388391  cout << Verbose(0) << "===========MIRROR ATOMS=========================" << endl;
    389392  cout << Verbose(0) << " a - state three atoms defining mirror plane" << endl;
     
    394397  cout << Verbose(0) << "INPUT: ";
    395398  cin >> choice;
    396  
     399
    397400  switch (choice) {
    398401    default:
     
    413416      second = mol->AskAtom("Enter second atom: ");
    414417
    415       n.CopyVector((const Vector *)&first->x); 
    416       n.SubtractVector((const Vector *)&second->x); 
     418      n.CopyVector((const Vector *)&first->x);
     419      n.SubtractVector((const Vector *)&second->x);
    417420      n.Normalize();
    418       break;         
     421      break;
    419422  };
    420423  cout << Verbose(0) << "Normal vector: ";
     
    433436  double tmp1, tmp2;
    434437  char choice;  // menu choice char
    435  
     438
    436439  cout << Verbose(0) << "===========REMOVE ATOMS=========================" << endl;
    437440  cout << Verbose(0) << " a - state atom for removal by number" << endl;
     
    442445  cout << Verbose(0) << "INPUT: ";
    443446  cin >> choice;
    444  
     447
    445448  switch (choice) {
    446449    default:
     
    475478          mol->RemoveAtom(first);
    476479      }
    477       break;         
     480      break;
    478481  };
    479482  //mol->Output((ofstream *)&cout);
     
    492495  int Z;
    493496  char choice;  // menu choice char
    494  
     497
    495498  cout << Verbose(0) << "===========MEASURE ATOMS=========================" << endl;
    496499  cout << Verbose(0) << " a - calculate bond length between one atom and all others" << endl;
     
    514517      for (int i=MAX_ELEMENTS;i--;)
    515518        min[i] = 0.;
    516        
    517       second = mol->start;   
     519
     520      second = mol->start;
    518521      while ((second->next != mol->end)) {
    519522        second = second->next; // advance
     
    526529        }
    527530        if ((tmp1 != 0.) && ((min[Z] == 0.) || (tmp1 < min[Z]))) min[Z] = tmp1;
    528         //cout << Verbose(0) << "Bond length between Atom " << first->nr << " and " << second->nr << ": " << tmp1 << " a.u." << endl;         
     531        //cout << Verbose(0) << "Bond length between Atom " << first->nr << " and " << second->nr << ": " << tmp1 << " a.u." << endl;
    529532      }
    530533      for (int i=MAX_ELEMENTS;i--;)
    531534        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;
    532535      break;
    533      
     536
    534537    case 'b':
    535538      first = mol->AskAtom("Enter first atom: ");
     
    556559      y.SubtractVector((const Vector *)&second->x);
    557560      cout << Verbose(0) << "Bond angle between first atom Nr." << first->nr << ", central atom Nr." << second->nr << " and last atom Nr." << third->nr << ": ";
    558       cout << Verbose(0) << (acos(x.ScalarProduct((const Vector *)&y)/(y.Norm()*x.Norm()))/M_PI*180.) << " degrees" << endl;         
     561      cout << Verbose(0) << (acos(x.ScalarProduct((const Vector *)&y)/(y.Norm()*x.Norm()))/M_PI*180.) << " degrees" << endl;
    559562      break;
    560563    case 'd':
     
    569572    case 'e':
    570573        cout << Verbose(0) << "Evaluating volume of the convex envelope.";
    571         VolumeOfConvexEnvelope((ofstream *)&cout, configuration, NULL, mol);
     574        VolumeOfConvexEnvelope((ofstream *)&cout, NULL, configuration, NULL, mol);
    572575        break;
    573576    case 'f':
     
    600603  int Order1;
    601604  clock_t start, end;
    602  
     605
    603606  cout << Verbose(0) << "Fragmenting molecule with current connection matrix ..." << endl;
    604607  cout << Verbose(0) << "What's the desired bond order: ";
     
    609612    end = clock();
    610613    cout << Verbose(0) << "Clocks for this operation: " << (end-start) << ", time: " << ((double)(end-start)/CLOCKS_PER_SEC) << "s." << endl;
    611   } else 
     614  } else
    612615    cout << Verbose(0) << "Connection matrix has not yet been generated!" << endl;
    613616};
     
    623626  atom *Walker = mol->start;
    624627  int i, comp, counter=0;
    625  
     628
    626629  // generate some KeySets
    627630  cout << "Generating KeySets." << endl;
     
    637640  cout << "Testing insertion of already present item in KeySets." << endl;
    638641  KeySetTestPair test;
    639   test = TestSets[mol->AtomCount-1].insert(Walker->nr); 
     642  test = TestSets[mol->AtomCount-1].insert(Walker->nr);
    640643  if (test.second) {
    641644    cout << Verbose(1) << "Insertion worked?!" << endl;
     
    646649  TestSets[mol->AtomCount].insert(mol->end->previous->previous->previous->nr);
    647650
    648   // constructing Graph structure 
     651  // constructing Graph structure
    649652  cout << "Generating Subgraph class." << endl;
    650653  Graph Subgraphs;
     
    657660  cout << "Testing insertion of already present item in Subgraph." << endl;
    658661  GraphTestPair test2;
    659   test2 = Subgraphs.insert(GraphPair (TestSets[mol->AtomCount],pair<int, double>(counter++, 1.))); 
     662  test2 = Subgraphs.insert(GraphPair (TestSets[mol->AtomCount],pair<int, double>(counter++, 1.)));
    660663  if (test2.second) {
    661664    cout << Verbose(1) << "Insertion worked?!" << endl;
     
    663666    cout << Verbose(1) << "Insertion rejected: Present object is " << (*(test2.first)).second.first << "." << endl;
    664667  }
    665  
     668
    666669  // show graphs
    667670  cout << "Showing Subgraph's contents, checking that it's sorted." << endl;
     
    674677      if ((*key) > comp)
    675678        cout << (*key) << " ";
    676       else 
     679      else
    677680        cout << (*key) << "! ";
    678681      comp = (*key);
     
    694697  char filename[MAXSTRINGSIZE];
    695698  ofstream output;
     699  string basis("3-21G");
    696700
    697701  cout << Verbose(0) << "Storing configuration ... " << endl;
     
    699703  mol->CalculateOrbitals(*configuration);
    700704  configuration->InitMaxMinStopStep = configuration->MaxMinStopStep = configuration->MaxPsiDouble;
    701   if (ConfigFileName != NULL) {
     705  strcpy(filename, ConfigFileName);
     706  if (ConfigFileName != NULL) { // test the file name
    702707    output.open(ConfigFileName, ios::trunc);
    703708  } else if (strlen(configuration->configname) != 0) {
     709    strcpy(filename, configuration->configname);
    704710    output.open(configuration->configname, ios::trunc);
    705711    } else {
     712      strcpy(filename, DEFAULTCONFIG);
    706713      output.open(DEFAULTCONFIG, ios::trunc);
    707714    }
     715  output.close();
     716  output.clear();
    708717  cout << Verbose(0) << "Saving of config file ";
    709   if (configuration->Save(&output, periode, mol))
     718  if (configuration->Save(filename, periode, mol))
    710719    cout << "successful." << endl;
    711720  else
    712721    cout << "failed." << endl;
    713   output.close();
    714   output.clear();
    715  
     722
    716723  // and save to xyz file
    717724  if (ConfigFileName != NULL) {
     
    724731    strcat(filename, ".xyz");
    725732    output.open(filename, ios::trunc);
    726   } 
     733  }
    727734  cout << Verbose(0) << "Saving of XYZ file ";
    728735  if (mol->MDSteps <= 1) {
     
    739746  output.close();
    740747  output.clear();
    741  
     748
    742749  // and save as MPQC configuration
    743   if (ConfigFileName != NULL) {
     750  if (ConfigFileName != NULL)
    744751    strcpy(filename, ConfigFileName);
    745     strcat(filename, ".in");
    746     output.open(filename, ios::trunc);
    747   }
    748   if (output == NULL) {
     752  if (output == NULL)
    749753    strcpy(filename,"main_pcp_linux");
    750     strcat(filename, ".in");
    751     output.open(filename, ios::trunc);
    752   }
    753754  cout << Verbose(0) << "Saving as mpqc input ";
    754   if (configuration->SaveMPQC(&output, mol))
     755  if (configuration->SaveMPQC(filename, mol))
    755756    cout << "done." << endl;
    756757  else
    757758    cout << "failed." << endl;
    758   output.close();
    759   output.clear();
    760  
     759
    761760  if (!strcmp(configuration->configpath, configuration->GetDefaultPath())) {
    762761    cerr << "WARNING: config is found under different path then stated in config file::defaultpath!" << endl;
     
    790789  int argptr;
    791790  PathToDatabases = LocalPath;
    792  
     791
    793792  if (argc > 1) { // config file specified as option
    794793    // 1. : Parse options that just set variables or print help
     
    803802          case '?':
    804803            cout << "MoleCuilder suite" << endl << "==================" << endl << endl;
    805             cout << "Usage: " << argv[0] << "[config file] [-{acefpsthH?vfrp}] [further arguments]" << endl; 
     804            cout << "Usage: " << argv[0] << "[config file] [-{acefpsthH?vfrp}] [further arguments]" << endl;
    806805            cout << "or simply " << argv[0] << " without arguments for interactive session." << endl;
    807806            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;
    809810            cout << "\t-c x1 x2 x3\tCenter atoms in domain with a minimum distance to boundary of (x1,x2,x3)." << endl;
    810811            cout << "\t-D <bond distance>\tDepth-First-Search Analysis of the molecule, giving cycles and tree/back edges." << endl;
     
    817818            cout << "\t-m <0/1>\tCalculate (0)/ Align in(1) PAS with greatest EV along z axis." << endl;
    818819            cout << "\t-n\tFast parsing (i.e. no trajectories are looked for)." << endl;
    819             cout << "\t-o\tGet volume of the convex envelope (and store to tecplot file)." << 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;
    820822            cout << "\t-p <file>\tParse given xyz file and create raw config file from it." << endl;
    821823            cout << "\t-P <file>\tParse given forces file and append as an MD step to config file via Verlet." << endl;
     
    823825            cout << "\t-r\t\tConvert file from an old pcp syntax." << endl;
    824826            cout << "\t-t x1 x2 x3\tTranslate all atoms by this vector (x1,x2,x3)." << endl;
    825             cout << "\t-T <file> Store temperatures from the config file in <file>." << endl; 
     827            cout << "\t-T <file> Store temperatures from the config file in <file>." << endl;
    826828            cout << "\t-s x1 x2 x3\tScale all atom coordinates by this vector (x1,x2,x3)." << endl;
    827             cout << "\t-u rho\tsuspend in water solution and output necessary cell lengths, average density rho and repetition." << endl; 
     829            cout << "\t-u rho\tsuspend in water solution and output necessary cell lengths, average density rho and repetition." << endl;
    828830            cout << "\t-v/-V\t\tGives version information." << endl;
    829831            cout << "Note: config files must not begin with '-' !" << endl;
     
    841843            break;
    842844          case 'e':
    843             cout << "Using " << argv[argptr] << " as elements database." << endl;
    844             PathToDatabases = argv[argptr];
    845             argptr+=1;
     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            }
    846852            break;
    847853          case 'n':
     
    856862        argptr++;
    857863    } while (argptr < argc);
    858    
     864
    859865    // 2. Parse the element database
    860866    if (periode->LoadPeriodentafel(PathToDatabases)) {
     
    865871      return 1;
    866872    }
    867    
     873
    868874    // 3. Find config file name and parse if possible
    869875    if (argv[1][0] != '-') {
     
    904910    } else
    905911      config_present = absent;
    906    
     912
    907913    // 4. parse again through options, now for those depending on elements db and config presence
    908914    argptr = 1;
     
    915921            case 'p':
    916922              ExitFlag = 1;
    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;
     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;
     933                  config_present = present;
     934                }
    924935              }
    925936              break;
    926937            case 'a':
    927938              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))
    939                   config_present = present;
    940               } else
    941                 cerr << Verbose(1) << "Could not find the specified element." << endl;
    942               argptr+=4;
     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              }
    943959              break;
    944960            default:   // no match? Don't step on (this is done in next switch's default)
     
    948964        if (config_present == present) {
    949965          switch(argv[argptr-1][1]) {
    950             case 'D':
     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':
    951977              ExitFlag = 1;
    952978              {
     
    9791005                delete[](MinimumRingSize);
    9801006              }
    981               argptr+=1;
     1007              //argptr+=1;
    9821008              break;
    9831009            case 'E':
    9841010              ExitFlag = 1;
    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;
     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;
    9911051            case 'T':
    9921052              ExitFlag = 1;
    993               {
     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 {
    9941057                cout << Verbose(1) << "Storing temperatures in " << argv[argptr] << "." << endl;
    9951058                ofstream *output = new ofstream(argv[argptr], ios::trunc);
     
    10001063                output->close();
    10011064                delete(output);
     1065                argptr+=1;
    10021066              }
    1003               argptr+=1;
    10041067              break;
    10051068            case 'L':
     
    10151078            case 'P':
    10161079              ExitFlag = 1;
    1017               SaveFlag = true;
    1018               cout << Verbose(1) << "Parsing forces file and Verlet integrating." << endl;
    1019               if (!mol->VerletForceIntegration((ofstream *)&cout, argv[argptr], configuration))
    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++;
     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;
    10261091              }
    1027               argptr+=1;
    10281092              break;
    10291093            case 't':
    10301094              ExitFlag = 1;
    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;
     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;
     1106              }
    10371107              break;
    10381108            case 's':
    10391109              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];
     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;
    10561133              }
    1057               delete[](factor);
    1058               argptr+=1;
    10591134              break;
    10601135            case 'b':
    10611136              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.;
     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);
    10701154              }
    1071               // center
    1072               mol->CenterInBox((ofstream *)&cout, &x);
    1073               // update Box of atoms by boundary
    1074               mol->SetBoxDimension(&x);
    10751155              break;
    10761156            case 'c':
    10771157              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.;
     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);
    10911177              }
    1092               mol->Translate((const Vector *)&x);
    10931178              break;
    10941179            case 'O':
     
    11071192            case 'f':
    11081193              ExitFlag = 1;
    1109               cout << "Fragmenting molecule with bond distance " << argv[argptr] << " angstroem, order of " << argv[argptr+1] << "." << endl;
    1110               if (argc >= argptr+2) {
     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;
    11111199                cout << Verbose(0) << "Creating connection matrix..." << endl;
    11121200                start = clock();
     
    11181206                end = clock();
    11191207                cout << Verbose(0) << "Clocks for this operation: " << (end-start) << ", time: " << ((double)(end-start)/CLOCKS_PER_SEC) << "s." << endl;
    1120                 argptr+=1;
    1121               } else {
    1122                 cerr << "Not enough arguments for fragmentation: -f <max. bond distance> <bond order>" << endl;
     1208                argptr+=2;
    11231209              }
    11241210              break;
     
    11391225            case 'o':
    11401226              ExitFlag = 1;
    1141               SaveFlag = true;
    1142               cout << Verbose(0) << "Evaluating volume of the convex envelope.";
    1143               VolumeOfConvexEnvelope((ofstream *)&cout, &configuration, NULL, mol);
     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              }
    11441240              break;
    11451241            case 'U':
    11461242              ExitFlag = 1;
    1147               volume = atof(argv[argptr++]);
    1148               cout << Verbose(0) << "Using " << volume << " angstrom^3 as the volume instead of convex envelope one's." << endl; 
     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              }
    11491251            case 'u':
    11501252              ExitFlag = 1;
    1151               {
     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 {
    11521258                double density;
    11531259                SaveFlag = true;
     
    11641270//                  repetition[i] = 1;
    11651271//                }
    1166                 PrepareClustersinWater((ofstream *)&cout, &configuration, mol, volume, density);
     1272                PrepareClustersinWater((ofstream *)&cout, &configuration, mol, volume, density);  // if volume == 0, will calculate from ConvexEnvelope
    11671273              }
    11681274              break;
    11691275            case 'd':
    11701276              ExitFlag = 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++;
     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;
    11931290                  }
    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, ...)
     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++;
    12071303                    }
     1304                    if (count != j)
     1305                      cout << Verbose(0) << "ERROR: AtomCount " << count << " is not equal to number of atoms in molecule " << j << "!" << endl;
     1306                    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;
    12081330                  }
    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
    1214                     x.Zero();
    1215                     x.AddVector(&y);
    1216                     x.Scale(-(faktor-1));
    1217                     mol->Translate(&x);
    1218                   }
    1219                   mol->cell_size[(abs(axis) == 2) ? 2 : ((abs(axis) == 3) ? 5 : 0)] *= faktor;
    12201331                }
    12211332              }
     
    12791390  if (j == 1) return 0; // just for -v and -h options
    12801391  if (j) return j;  // something went wrong
    1281  
     1392
    12821393  // General stuff
    12831394  if (mol->cell_size[0] == 0.) {
     
    12931404  // now the main construction loop
    12941405  cout << Verbose(0) << endl << "Now comes the real construction..." << endl;
    1295   do {   
     1406  do {
    12961407    cout << Verbose(0) << endl << endl;
    12971408    cout << Verbose(0) << "============Element list=======================" << endl;
     
    13121423    cout << Verbose(0) << "-----------------------------------------------" << endl;
    13131424    cout << Verbose(0) << "d - duplicate molecule/periodic cell" << endl;
    1314     cout << Verbose(0) << "i - realign molecule" << endl; 
    1315     cout << Verbose(0) << "m - mirror all molecules" << endl; 
     1425    cout << Verbose(0) << "i - realign molecule" << endl;
     1426    cout << Verbose(0) << "m - mirror all molecules" << endl;
    13161427    cout << Verbose(0) << "t - translate molecule by vector" << endl;
    13171428    cout << Verbose(0) << "c - scale by unit transformation" << endl;
     
    13241435    cout << Verbose(0) << "Input: ";
    13251436    cin >> choice;
    1326    
     1437
    13271438    switch (choice) {
    13281439      default:
    13291440      case 'a': // add atom
    13301441        AddAtoms(periode, mol);
    1331         choice = 'a'; 
    1332         break;
    1333      
     1442        choice = 'a';
     1443        break;
     1444
    13341445      case 'b': // scale a bond
    13351446        cout << Verbose(0) << "Scaling bond length between two atoms." << endl;
     
    13471458        }
    13481459        //cout << Verbose(0) << "New coordinates of Atom " << second->nr << " are: ";
    1349         //second->Output(second->type->No, 1, (ofstream *)&cout);       
    1350         break;
    1351 
    1352       case 'c': // unit scaling of the metric 
     1460        //second->Output(second->type->No, 1, (ofstream *)&cout);
     1461        break;
     1462
     1463      case 'c': // unit scaling of the metric
    13531464       cout << Verbose(0) << "Angstroem -> Bohrradius: 1.8897261\t\tBohrradius -> Angstroem: 0.52917721" << endl;
    13541465       cout << Verbose(0) << "Enter three factors: ";
     
    13611472       delete[](factor);
    13621473       break;
    1363        
     1474
    13641475      case 'd': // duplicate the periodic cell along a given axis, given times
    13651476        cout << Verbose(0) << "State the axis [(+-)123]: ";
     
    13671478        cout << Verbose(0) << "State the factor: ";
    13681479        cin >> faktor;
    1369        
     1480
    13701481        mol->CountAtoms((ofstream *)&cout);  // recount atoms
    13711482        if (mol->AtomCount != 0) {  // if there is more than none
     
    14081519            mol->Translate(&x);
    14091520          }
    1410           mol->cell_size[(abs(axis) == 2) ? 2 : ((abs(axis) == 3) ? 5 : 0)] *= faktor; 
     1521          mol->cell_size[(abs(axis) == 2) ? 2 : ((abs(axis) == 3) ? 5 : 0)] *= faktor;
    14111522        }
    14121523        break;
    1413      
     1524
    14141525      case 'e': // edit each field of the configuration
    14151526       configuration.Edit(mol);
    14161527       break;
    1417  
     1528
    14181529      case 'f':
    14191530        FragmentAtoms(mol, &configuration);
    14201531        break;
    1421        
     1532
    14221533      case 'g': // center the atoms
    14231534        CenterAtoms(mol);
    14241535        break;
    1425        
    1426       case 'i': // align all atoms 
     1536
     1537      case 'i': // align all atoms
    14271538        AlignAtoms(periode, mol);
    14281539        break;
     
    14351546        MirrorAtoms(mol);
    14361547        break;
    1437        
     1548
    14381549      case 'o': // create the connection matrix
    14391550        {
     
    14561567        }
    14571568        break;
    1458        
     1569
    14591570      case 'p': // parse and XYZ file
    14601571        cout << Verbose(0) << "Format should be XYZ with: ShorthandOfElement\tX\tY\tZ" << endl;
     
    14651576        break;
    14661577
    1467       case 'q': // quit 
    1468         break;
    1469        
     1578      case 'q': // quit
     1579        break;
     1580
    14701581      case 'r': // remove atom
    1471         RemoveAtoms(mol);       
    1472         break;
    1473        
     1582        RemoveAtoms(mol);
     1583        break;
     1584
    14741585      case 's': // save to config file
    14751586        SaveConfig(ConfigFileName, &configuration, periode, mol);
     
    14771588
    14781589      case 't': // translate all atoms
    1479        cout << Verbose(0) << "Enter translation vector." << endl;       
     1590       cout << Verbose(0) << "Enter translation vector." << endl;
    14801591       x.AskPosition(mol->cell_size,0);
    14811592       mol->Translate((const Vector *)&x);
    14821593       break;
    1483  
     1594
    14841595      case 'T':
    14851596        testroutine(mol);
    14861597        break;
    1487      
     1598
    14881599      case 'u': // change an atom's element
    14891600        first = NULL;
     
    14921603          cin >> Z;
    14931604        } while ((first = mol->FindAtom(Z)) == NULL);
    1494         cout << Verbose(0) << "New element by atomic number Z: ";       
     1605        cout << Verbose(0) << "New element by atomic number Z: ";
    14951606        cin >> Z;
    14961607        first->type = periode->FindElement(Z);
    1497         cout << Verbose(0) << "Atom " << first->nr << "'s element is " << first->type->name << "." << endl;   
     1608        cout << Verbose(0) << "Atom " << first->nr << "'s element is " << first->type->name << "." << endl;
    14981609        break;
    14991610    };
    15001611  } while (choice != 'q');
    1501  
     1612
    15021613  // save element data base
    15031614  if (periode->StorePeriodentafel(ElementsFileName)) //ElementsFileName
  • src/config.cpp

    • Property mode changed from 100644 to 100755
    rfcbfc8 r631dcb  
    3131  configpath[0]='\0';
    3232  configname[0]='\0';
     33  basis="3-21G";
     34 
    3335
    3436  strcpy(ThermostatNames[0],"None");
     
    10731075
    10741076/** Stores all elements of config structure from which they can be re-read.
    1075  * \param output open output *file stream to write to
     1077 * \param *filename name of file
    10761078 * \param *periode pointer to a periodentafel class with all elements
    10771079 * \param *mol pointer to molecule containing all atoms of the molecule
    10781080 */
    1079 bool config::Save(ofstream *output, periodentafel *periode, molecule *mol) const
     1081bool config::Save(const char *filename, periodentafel *periode, molecule *mol) const
    10801082{
    10811083  bool result = true;
    10821084        // bring MaxTypes up to date
    10831085        mol->CountElements();
     1086  ofstream *output = NULL;
     1087  output = new ofstream(filename, ios::out);
    10841088  if (output != NULL) {
    10851089    *output << "# ParallelCarParinello - main configuration file - created with molecuilder" << endl;
     
    11921196    else
    11931197      result = result && mol->OutputTrajectories(output);
     1198    output->close();
     1199    output->clear();
     1200    delete(output);
    11941201    return result;
    11951202  } else
     
    11991206/** Stores all elements in a MPQC input file.
    12001207 * Note that this format cannot be parsed again.
    1201  * \param output open output *file stream to write to
     1208 * \param *filename name of file (without ".in" suffix!)
    12021209 * \param *mol pointer to molecule containing all atoms of the molecule
    12031210 */
    1204 bool config::SaveMPQC(ofstream *output, molecule *mol) const
     1211bool config::SaveMPQC(const char *filename, molecule *mol) const
    12051212{
    12061213  int ElementNo = 0;
    12071214  int AtomNo;
    12081215  atom *Walker = NULL;
    1209   element *runner = mol->elemente->start;
     1216  element *runner = NULL;
    12101217  Vector *center = NULL;
    1211 
     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);
    12121225  *output << "% Created by MoleCuilder" << endl;
    12131226  *output << "mpqc: (" << endl;
     
    12151228  *output << "\tdo_gradient = yes" << endl;
    12161229  *output << "\tmole<CLHF>: (" << endl;
    1217   *output << "\t\tmolecule<Molecule>: (" << endl;
    1218   *output << "\t\t\tunit = " << (IsAngstroem ? "angstrom" : "bohr" ) << endl;
    1219   *output << "\t\t\t{ atoms geometry } = {" << 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;
    12201238  center = mol->DetermineCenterOfAll(output);
    12211239  // output of atoms
     1240  runner = mol->elemente->start;
    12221241  while (runner->next != mol->elemente->end) { // go through every element
    12231242    runner = runner->next;
     
    12301249        if (Walker->type == runner) { // if this atom fits to element
    12311250          AtomNo++;
    1232           *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;
     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;
    12331252        }
    12341253      }
     
    12361255  }
    12371256  delete(center);
    1238   *output << "\t\t\t}" << endl;
    1239   *output << "\t\t)" << endl;
    1240   *output << "\t\tbasis<GaussianBasisSet>: (" << endl;
    1241   *output << "\t\t\tname = \"STO-3G\"" << endl;
    1242   *output << "\t\t\tmolecule = $:mpqc:mole:molecule" << endl;
    1243   *output << "\t\t)" << endl;
     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;
    12441282  *output << "\t)" << endl;
    12451283  *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 
    12461316  return true;
    12471317};
  • src/datacreator.cpp

    • Property mode changed from 100644 to 100755
    rfcbfc8 r631dcb  
    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 */
     37bool 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
    3149/** Plots an energy vs. order.
    3250 * \param &Fragments EnergyMatrix class containing matrix values
     
    4563  cout << msg << endl;
    4664  output << "# " << msg << ", created on " << datum;
    47   output << "#Order\tFrag.No.\t" << Fragments.Header << endl;
     65  output << "#Order\tFrag.No.\t" << Fragments.Header[Fragments.MatrixCounter] << endl;
    4866  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
    4967    for(int i=KeySet.FragmentsPerOrder[BondOrder];i--;) {
    5068      for(int j=Fragments.RowCounter[ KeySet.OrderSet[BondOrder][i] ];j--;)
    51         for(int k=Fragments.ColumnCounter;k--;)
     69        for(int k=Fragments.ColumnCounter[ KeySet.OrderSet[BondOrder][i] ];k--;)
    5270          Fragments.Matrix[Fragments.MatrixCounter][j][k] += Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k];
    5371    }
    5472    output << BondOrder+1 << "\t" << KeySet.FragmentsPerOrder[BondOrder];
    55     for (int l=0;l<Fragments.ColumnCounter;l++)
     73    for (int l=0;l<Fragments.ColumnCounter[Fragments.MatrixCounter];l++)
    5674      output << scientific << "\t" << Fragments.Matrix[Fragments.MatrixCounter][ Fragments.RowCounter[Fragments.MatrixCounter]-1 ][l];
    5775    output << endl;
     
    7896  cout << msg << endl;
    7997  output << "# " << msg << ", created on " << datum;
    80   output << "#Order\tFrag.No.\t" << Fragments.Header << endl;
     98  output << "#Order\tFrag.No.\t" << Fragments.Header[Fragments.MatrixCounter] << endl;
    8199  Fragments.SetLastMatrix(Energy.Matrix[Energy.MatrixCounter],0);
    82100  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
    83101    for(int i=KeySet.FragmentsPerOrder[BondOrder];i--;) {
    84102      for(int j=Fragments.RowCounter[ KeySet.OrderSet[BondOrder][i] ];j--;)
    85         for(int k=Fragments.ColumnCounter;k--;)
     103        for(int k=Fragments.ColumnCounter[ KeySet.OrderSet[BondOrder][i] ];k--;)
    86104          Fragments.Matrix[Fragments.MatrixCounter][j][k] -= Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k];
    87105    }
    88106    output << BondOrder+1 << "\t" << KeySet.FragmentsPerOrder[BondOrder];
    89     for (int l=0;l<Fragments.ColumnCounter;l++)
     107    for (int l=0;l<Fragments.ColumnCounter[Energy.MatrixCounter];l++)
    90108      if (fabs(Energy.Matrix[Energy.MatrixCounter][ Energy.RowCounter[Energy.MatrixCounter]-1 ][l]) < MYEPSILON)
    91109        output << scientific << "\t" << Fragments.Matrix[Fragments.MatrixCounter][ Fragments.RowCounter[Fragments.MatrixCounter]-1 ][l];
     
    115133  cout << msg << endl;
    116134  output << "# " << msg << ", created on " << datum;
    117   output << "# Order\tFrag.No.\t" << Fragments.Header << endl;
     135  output << "# Order\tFrag.No.\t" << Fragments.Header[Fragments.MatrixCounter] << endl;
    118136  Fragments.SetLastMatrix(0.,0);
    119137  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
     
    121139    output << BondOrder+1 << "\t" << KeySet.FragmentsPerOrder[BondOrder];
    122140    CreateForce(Fragments, Fragments.MatrixCounter);
    123     for (int l=0;l<Fragments.ColumnCounter;l++)
     141    for (int l=0;l<Fragments.ColumnCounter[Fragments.MatrixCounter];l++)
    124142       output << scientific << "\t" << Fragments.Matrix[Fragments.MatrixCounter][ Fragments.RowCounter[Fragments.MatrixCounter] ][l];
    125143    output << endl;
     
    147165  cout << msg << endl;
    148166  output << "# " << msg << ", created on " << datum;
    149   output << "# Order\tFrag.No.\t" << Fragments.Header << endl;
     167  output << "# Order\tFrag.No.\t" << Fragments.Header[Fragments.MatrixCounter] << endl;
    150168  Fragments.SetLastMatrix(Force.Matrix[Force.MatrixCounter],0);
    151169  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
     
    153171    output << BondOrder+1 << "\t" << KeySet.FragmentsPerOrder[BondOrder];
    154172    CreateForce(Fragments, Fragments.MatrixCounter);
    155     for (int l=0;l<Fragments.ColumnCounter;l++)
     173    for (int l=0;l<Fragments.ColumnCounter[Fragments.MatrixCounter];l++)
    156174       output << scientific << "\t" << Fragments.Matrix[Fragments.MatrixCounter][ Fragments.RowCounter[Fragments.MatrixCounter] ][l];
    157175    output << endl;
     
    180198  cout << msg << endl;
    181199  output << "# " << msg << ", created on " << datum;
    182   output << "# AtomNo\t" << Fragments.Header << endl;
     200  output << "# AtomNo\t" << Fragments.Header[Fragments.MatrixCounter] << endl;
    183201  Fragments.SetLastMatrix(Force.Matrix[Force.MatrixCounter], 0);
    184202  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
     
    186204    Fragments.SumSubForces(Fragments, KeySet, BondOrder, -1.);
    187205    // errors per atom
    188     output << "#Order\t" << BondOrder+1 << endl;
     206    output << endl << "#Order\t" << BondOrder+1 << endl;
    189207    for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) {
    190208      output << Fragments.Indices[Fragments.MatrixCounter][j] << "\t";
    191       for (int l=0;l<Fragments.ColumnCounter;l++) {
     209      for (int l=0;l<Fragments.ColumnCounter[ Fragments.MatrixCounter ];l++) {
    192210        if (((l+1) % 3) == 0) {
    193211          norm = 0.;
     
    226244  cout << msg << endl;
    227245  output << "# " << msg << ", created on " << datum;
    228   output << "# AtomNo\t" << Fragments.Header << endl;
     246  output << "# AtomNo\t" << Fragments.Header[Fragments.MatrixCounter] << endl;
    229247  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
    230248    //cout << "Current order is " << BondOrder << "." << endl;
    231249    Fragments.SumSubForces(Fragments, KeySet, BondOrder, 1.);
    232250    // errors per atom
    233     output << "#Order\t" << BondOrder+1 << endl;
     251    output << endl << "#Order\t" << BondOrder+1 << endl;
    234252    for(int j=0;j<Fragments.RowCounter[ Fragments.MatrixCounter ];j++) {
    235253      output << Fragments.Indices[Fragments.MatrixCounter][j] << "\t";
    236       for (int l=0;l<Fragments.ColumnCounter;l++)
     254      for (int l=0;l<Fragments.ColumnCounter[ Fragments.MatrixCounter ];l++)
    237255        output << scientific << Fragments.Matrix[Fragments.MatrixCounter][ j ][l] << "\t";
    238256      output << endl;
     
    244262};
    245263
     264
     265/** Plot hessian error vs. vs atom vs. order.
     266 * \param &Hessian HessianMatrix containing reference values (in MatrixCounter matrix)
     267 * \param &Fragments HessianMatrix class containing matrix values
     268 * \param KeySet KeySetContainer class holding bond KeySetContainer::Order
     269 * \param *prefix prefix in filename (without ending)
     270 * \param *msg message to be place in first line as a comment
     271 * \param *datum current date and time
     272 * \return true if file was written successfully
     273 */
     274bool CreateDataDeltaHessianOrderPerAtom(class HessianMatrix &Hessian, class HessianMatrix &Fragments, class KeySetsContainer &KeySet, 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 */
     312bool 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 */
     356bool 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
    246384/** Plot matrix vs. fragment.
    247385 */
     
    255393  cout << msg << endl;
    256394  output << "# " << msg << ", created on " << datum << endl;
    257   output << "#Order\tFrag.No.\t" << Fragment.Header << endl;
     395  output << "#Order\tFrag.No.\t" << Fragment.Header[ Fragment.MatrixCounter ] << endl;
    258396  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
    259397    for(int i=0;i<KeySet.FragmentsPerOrder[BondOrder];i++) {
    260398      output << BondOrder+1 << "\t" << KeySet.OrderSet[BondOrder][i]+1;
    261399      CreateFragment(Fragment, KeySet.OrderSet[BondOrder][i]);
    262       for (int l=0;l<Fragment.ColumnCounter;l++)
     400      for (int l=0;l<Fragment.ColumnCounter[ KeySet.OrderSet[BondOrder][i] ];l++)
    263401        output << scientific << "\t" << Fragment.Matrix[ KeySet.OrderSet[BondOrder][i] ][ Fragment.RowCounter[ KeySet.OrderSet[BondOrder][i] ] ][l];
    264402      output << endl;
     
    279417    for(int i=KeySet.FragmentsPerOrder[BondOrder];i--;) {
    280418      if (fabs(Fragments.Matrix[ Fragments.MatrixCounter ][j][1]) < fabs(Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][1])) {
    281         for (int k=Fragments.ColumnCounter;k--;)
     419        for (int k=Fragments.ColumnCounter[ Fragments.MatrixCounter ];k--;)
    282420          Fragments.Matrix[ Fragments.MatrixCounter ][j][k] = Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k];
    283421      }
     
    296434    int i=0;
    297435    do {  // first get a minimum value unequal to 0
    298       for (int k=Fragments.ColumnCounter;k--;)
     436      for (int k=Fragments.ColumnCounter[ Fragments.MatrixCounter ];k--;)
    299437        Fragments.Matrix[ Fragments.MatrixCounter ][j][k] = Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k];
    300438      i++;
     
    302440    for(;i<KeySet.FragmentsPerOrder[BondOrder];i++) { // then find lowest
    303441      if (fabs(Fragments.Matrix[ Fragments.MatrixCounter ][j][1]) > fabs(Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][1])) {
    304         for (int k=Fragments.ColumnCounter;k--;)
     442        for (int k=Fragments.ColumnCounter[ Fragments.MatrixCounter ];k--;)
    305443          Fragments.Matrix[ Fragments.MatrixCounter ][j][k] = Fragments.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k];
    306444      }
     
    320458  cout << msg << endl;
    321459  output << "# " << msg << ", created on " << datum;
    322   output << "#Order\tFrag.No.\t" << Fragment.Header << endl;
     460  output << "#Order\tFrag.No.\t" << Fragment.Header[ Fragment.MatrixCounter ] << endl;
    323461  // max
    324462  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
     
    326464    CreateFragmentOrder(Fragment, KeySet, BondOrder);
    327465    output << BondOrder+1 << "\t" << KeySet.FragmentsPerOrder[BondOrder];
    328     for (int l=0;l<Fragment.ColumnCounter;l++)
     466    for (int l=0;l<Fragment.ColumnCounter[ Fragment.MatrixCounter ];l++)
    329467      output << scientific << "\t" << Fragment.Matrix[ Fragment.MatrixCounter ][ Fragment.RowCounter[ Fragment.MatrixCounter ]-1 ][l];
    330468    output << endl;
     
    340478void CreateEnergy(class MatrixContainer &Energy, int MatrixNumber)
    341479{
    342   for(int k=0;k<Energy.ColumnCounter;k++)
     480  for(int k=0;k<Energy.ColumnCounter[MatrixNumber];k++)
    343481    Energy.Matrix[MatrixNumber][ Energy.RowCounter[MatrixNumber] ] [k] =  Energy.Matrix[MatrixNumber][ Energy.RowCounter[MatrixNumber]-1 ] [k];
    344482};
     
    351489void CreateMinimumForce(class MatrixContainer &Force, int MatrixNumber)
    352490{
    353   for (int l=Force.ColumnCounter;l--;)
     491  for (int l=Force.ColumnCounter[MatrixNumber];l--;)
    354492    Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l] = 0.;
    355   for (int l=5;l<Force.ColumnCounter;l+=3) {
     493  for (int l=5;l<Force.ColumnCounter[MatrixNumber];l+=3) {
    356494    double stored = 0;
    357495    int k=0;
     
    386524{
    387525  int divisor = 0;
    388   for (int l=Force.ColumnCounter;l--;)
     526  for (int l=Force.ColumnCounter[MatrixNumber];l--;)
    389527    Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l] = 0.;
    390   for (int l=5;l<Force.ColumnCounter;l+=3) {
     528  for (int l=5;l<Force.ColumnCounter[MatrixNumber];l+=3) {
    391529    double tmp = 0;
    392530    for (int k=Force.RowCounter[MatrixNumber];k--;) {
     
    410548void CreateMaximumForce(class MatrixContainer &Force, int MatrixNumber)
    411549{
    412   for (int l=5;l<Force.ColumnCounter;l+=3) {
     550  for (int l=5;l<Force.ColumnCounter[MatrixNumber];l+=3) {
    413551    double stored = 0;
    414552    for (int k=Force.RowCounter[MatrixNumber];k--;) {
     
    442580void CreateVectorSumForce(class MatrixContainer &Force, int MatrixNumber)
    443581{
    444   for (int l=Force.ColumnCounter;l--;)
     582  for (int l=Force.ColumnCounter[MatrixNumber];l--;)
    445583    Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l] = 0.;
    446   for (int l=0;l<Force.ColumnCounter;l++) {
     584  for (int l=0;l<Force.ColumnCounter[MatrixNumber];l++) {
    447585    for (int k=Force.RowCounter[MatrixNumber];k--;)
    448586      Force.Matrix[MatrixNumber][ Force.RowCounter[MatrixNumber] ][l] += Force.Matrix[MatrixNumber][k][l];
     
    520658void AbsEnergyPlotLine(ofstream &output, class MatrixContainer &Energy, const char *prefix, const char *xargument, const char *uses)
    521659{
    522   stringstream line(Energy.Header);
     660  stringstream line(Energy.Header[ Energy.MatrixCounter ]);
    523661  string token;
    524662
    525663  getline(line, token, '\t');
    526   for (int i=2; i<= Energy.ColumnCounter;i++) {
     664  for (int i=2; i<= Energy.ColumnCounter[Energy.MatrixCounter];i++) {
    527665    getline(line, token, '\t');
    528666    while (token[0] == ' ') // remove leading white spaces
    529667      token.erase(0,1);
    530668    output << "'" << prefix << ".dat' title '" << token << "' using " << xargument << ":(abs($" << i+2 << ")) " << uses;
    531     if (i != (Energy.ColumnCounter))
     669    if (i != (Energy.ColumnCounter[Energy.MatrixCounter]))
    532670      output << ", \\";
    533671    output << endl;
     
    544682void EnergyPlotLine(ofstream &output, class MatrixContainer &Energy, const char *prefix, const char *xargument, const char *uses)
    545683{
    546   stringstream line(Energy.Header);
     684  stringstream line(Energy.Header[Energy.MatrixCounter]);
    547685  string token;
    548686
    549687  getline(line, token, '\t');
    550   for (int i=1; i<= Energy.ColumnCounter;i++) {
     688  for (int i=1; i<= Energy.ColumnCounter[Energy.MatrixCounter];i++) {
    551689    getline(line, token, '\t');
    552690    while (token[0] == ' ') // remove leading white spaces
    553691      token.erase(0,1);
    554692    output << "'" << prefix << ".dat' title '" << token << "' using " << xargument << ":" << i+2 << " " << uses;
    555     if (i != (Energy.ColumnCounter))
     693    if (i != (Energy.ColumnCounter[Energy.MatrixCounter]))
    556694      output << ", \\";
    557695    output << endl;
     
    568706void ForceMagnitudePlotLine(ofstream &output, class MatrixContainer &Force, const char *prefix, const char *xargument, const char *uses)
    569707{
    570   stringstream line(Force.Header);
     708  stringstream line(Force.Header[Force.MatrixCounter]);
    571709  string token;
    572710
     
    576714  getline(line, token, '\t');
    577715  getline(line, token, '\t');
    578   for (int i=7; i< Force.ColumnCounter;i+=NDIM) {
     716  for (int i=7; i< Force.ColumnCounter[Force.MatrixCounter];i+=NDIM) {
    579717    getline(line, token, '\t');
    580718    while (token[0] == ' ') // remove leading white spaces
     
    582720    token.erase(token.length(), 1);  // kill residual index char (the '0')
    583721    output << "'" << prefix << ".dat' title '" << token << "' using " << xargument << ":(sqrt($" << i+1 << "*$" << i+1 << "+$" << i+2 << "*$" << i+2 << "+$" << i+3 << "*$" << i+3 << ")) " << uses;
    584     if (i != (Force.ColumnCounter-1))
     722    if (i != (Force.ColumnCounter[Force.MatrixCounter]-1))
    585723      output << ", \\";
    586724    output << endl;
     
    599737void AbsFirstForceValuePlotLine(ofstream &output, class MatrixContainer &Force, const char *prefix, const char *xargument, const char *uses)
    600738{
    601   stringstream line(Force.Header);
     739  stringstream line(Force.Header[Force.MatrixCounter]);
    602740  string token;
    603741
     
    607745  getline(line, token, '\t');
    608746  getline(line, token, '\t');
    609   for (int i=7; i< Force.ColumnCounter;i+=NDIM) {
     747  for (int i=7; i< Force.ColumnCounter[Force.MatrixCounter];i+=NDIM) {
    610748    getline(line, token, '\t');
    611749    while (token[0] == ' ') // remove leading white spaces
     
    613751    token.erase(token.length(), 1);  // kill residual index char (the '0')
    614752    output << "'" << prefix << ".dat' title '" << token << "' using " << xargument << ":(abs($" << i+1 << ")) " << uses;
    615     if (i != (Force.ColumnCounter-1))
     753    if (i != (Force.ColumnCounter[Force.MatrixCounter]-1))
    616754      output << ", \\";
    617755    output << endl;
     
    630768void BoxesForcePlotLine(ofstream &output, class MatrixContainer &Force, const char *prefix, const char *xargument, const char *uses)
    631769{
    632   stringstream line(Force.Header);
     770  stringstream line(Force.Header[Force.MatrixCounter]);
    633771  char *fillcolor[5] = {"black", "red", "blue", "green", "cyan"};
    634772  string token;
     
    639777  getline(line, token, '\t');
    640778  getline(line, token, '\t');
    641   for (int i=7; i< Force.ColumnCounter;i+=NDIM) {
     779  for (int i=7; i< Force.ColumnCounter[Force.MatrixCounter];i+=NDIM) {
    642780    getline(line, token, '\t');
    643781    while (token[0] == ' ') // remove leading white spaces
     
    645783    token.erase(token.length(), 1);  // kill residual index char (the '0')
    646784    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];
    647     if (i != (Force.ColumnCounter-1))
     785    if (i != (Force.ColumnCounter[Force.MatrixCounter]-1))
    648786      output << ", \\";
    649787    output << endl;
     
    662800void BoxesFirstForceValuePlotLine(ofstream &output, class MatrixContainer &Force, const char *prefix, const char *xargument, const char *uses)
    663801{
    664   stringstream line(Force.Header);
     802  stringstream line(Force.Header[Force.MatrixCounter]);
    665803  char *fillcolor[5] = {"black", "red", "blue", "green", "cyan"};
    666804  string token;
     
    671809  getline(line, token, '\t');
    672810  getline(line, token, '\t');
    673   for (int i=7; i< Force.ColumnCounter;i+=NDIM) {
     811  for (int i=7; i< Force.ColumnCounter[Force.MatrixCounter];i+=NDIM) {
    674812    getline(line, token, '\t');
    675813    while (token[0] == ' ') // remove leading white spaces
     
    677815    token.erase(token.length(), 1);  // kill residual index char (the '0')
    678816    output << "'" << prefix << ".dat' title '" << token << "' using ($" << xargument << "+" << fixed << setprecision(1) << (double)((i-7)/3)*0.2 << "):" << i+1 << " " << uses << " " << fillcolor[(i-7)/3];
    679     if (i != (Force.ColumnCounter-1))
     817    if (i != (Force.ColumnCounter[Force.MatrixCounter]-1))
    680818      output << ", \\";
    681819    output << endl;
  • src/datacreator.hpp

    • Property mode changed from 100644 to 100755
    rfcbfc8 r631dcb  
    1818
    1919bool OpenOutputFile(ofstream &output, const char *dir, const char *filename);
     20bool AppendOutputFile(ofstream &output, const char *dir, const char *filename);
    2021
    2122bool CreateDataEnergyOrder(class EnergyMatrix &Fragments, class KeySetsContainer &KeySet, char *dir, char *prefix, char *msg, char *datum);
     
    2526bool CreateDataDeltaForcesOrder(class ForceMatrix &Force, class ForceMatrix &Fragments, class KeySetsContainer &KeySet, char *dir, char *prefix, char *msg, char *datum, void (*CreateForce)(class MatrixContainer &, int));
    2627bool CreateDataDeltaForcesOrderPerAtom(class ForceMatrix &Force, class ForceMatrix &Fragments, class KeySetsContainer &KeySet, char *dir, char *prefix, char *msg, char *datum);
     28bool CreateDataHessianOrderPerAtom(class HessianMatrix &Fragments, class KeySetsContainer &KeySet, char *dir, char *prefix, char *msg, char *datum);
     29bool CreateDataDeltaHessianOrderPerAtom(class HessianMatrix &Hessian, class HessianMatrix &Fragments, class KeySetsContainer &KeySet, char *dir, char *prefix, char *msg, char *datum);
     30bool CreateDataDeltaFrobeniusOrderPerAtom(class HessianMatrix &Hessian, class HessianMatrix &Fragments, class KeySetsContainer &KeySet, char *dir, char *prefix, char *msg, char *datum);
    2731bool CreateDataFragment(class MatrixContainer &ForceFragments, class KeySetsContainer &KeySet, char *dir, char *prefix, char *msg, char *datum, void (*CreateForce)(class MatrixContainer &, int));
    2832bool 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 100644 to 100755
  • src/element.cpp

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

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

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

    • Property mode changed from 100644 to 100755
    rfcbfc8 r631dcb  
    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 */
     188bool 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 100644 to 100755
    rfcbfc8 r631dcb  
    5959void Free(void ** buffer, const char* output);
    6060char *FixedDigitNumber(const int FragmentNumber, const int digits);
     61bool IsValidNumber( const char *string);
    6162
    6263/********************************************** helpful template functions *********************************/
  • src/joiner.cpp

    • Property mode changed from 100644 to 100755
    rfcbfc8 r631dcb  
    1919  periodentafel *periode = NULL; // and a period table of all elements
    2020  EnergyMatrix Energy;
     21  EnergyMatrix EnergyFragments;
     22 
    2123  EnergyMatrix Hcorrection;
     24  EnergyMatrix HcorrectionFragments;
     25 
    2226  ForceMatrix Force;
    23   EnergyMatrix EnergyFragments;
    24   EnergyMatrix HcorrectionFragments;
    2527  ForceMatrix ForceFragments;
     28
     29  HessianMatrix Hessian;
     30  HessianMatrix HessianFragments;
     31 
    2632  ForceMatrix Shielding;
    2733  ForceMatrix ShieldingPAS;
    2834  ForceMatrix ShieldingFragments;
    2935  ForceMatrix ShieldingPASFragments;
     36  EnergyMatrix Chi;
     37  EnergyMatrix ChiPAS;
     38  EnergyMatrix ChiFragments;
     39  EnergyMatrix ChiPASFragments;
    3040  KeySetsContainer KeySet; 
    3141  stringstream prefix;
    3242  char *dir = NULL;
    33   bool Hcorrected = true;
     43  bool NoHCorrection = false;
     44  bool NoHessian = false;
    3445
    3546  cout << "Joiner" << endl;
     
    6172  // ------------- Parse through all Fragment subdirs --------
    6273  if (!Energy.ParseFragmentMatrix(argv[1], dir, EnergySuffix, 0,0)) return 1;
    63   Hcorrected = Hcorrection.ParseFragmentMatrix(argv[1], "", HCORRECTIONSUFFIX, 0,0);
     74  if (!Hcorrection.ParseFragmentMatrix(argv[1], "", HCORRECTIONSUFFIX, 0,0)) {
     75    NoHCorrection = true;
     76    cout << "No HCorrection matrices found, skipping these." << endl;
     77  }
    6478  if (!Force.ParseFragmentMatrix(argv[1], dir, ForcesSuffix, 0,0)) return 1;
     79  if (!Hessian.ParseFragmentMatrix(argv[1], dir, HessianSuffix, 0,0)) {
     80    NoHessian = true;
     81    cout << "No hessian matrices found, skipping these." << endl;
     82  }
    6583  if (periode != NULL) { // also look for PAS values
    6684    if (!Shielding.ParseFragmentMatrix(argv[1], dir, ShieldingSuffix, 1, 0)) return 1;
    6785    if (!ShieldingPAS.ParseFragmentMatrix(argv[1], dir, ShieldingPASSuffix, 1, 0)) return 1;
     86    if (!Chi.ParseFragmentMatrix(argv[1], dir, ChiSuffix, 1, 0)) return 1;
     87    if (!ChiPAS.ParseFragmentMatrix(argv[1], dir, ChiPASSuffix, 1, 0)) return 1;
    6888  }
    6989
    7090  // ---------- Parse the TE Factors into an array -----------------
    71   if (!Energy.ParseIndices()) return 1;
    72   if (Hcorrected) Hcorrection.ParseIndices();
     91  if (!Energy.InitialiseIndices()) return 1;
     92  if (!NoHCorrection)
     93    Hcorrection.InitialiseIndices();
    7394 
    7495  // ---------- Parse the Force indices into an array ---------------
    7596  if (!Force.ParseIndices(argv[1])) return 1;
    7697
     98  // ---------- Parse the Hessian (=force) indices into an array ---------------
     99  if (!NoHessian)
     100    if (!Hessian.InitialiseIndices((class MatrixContainer *)&Force)) return 1;
     101
    77102  // ---------- Parse the shielding indices into an array ---------------
    78103  if (periode != NULL) { // also look for PAS values
    79104    if(!Shielding.ParseIndices(argv[1])) return 1;
    80105    if(!ShieldingPAS.ParseIndices(argv[1])) return 1;
     106    //if(!Chi.ParseIndices()) return 1;
     107    //if(!ChiPAS.ParseIndices()) return 1;
    81108  }
    82109
    83110  // ---------- Parse the KeySets into an array ---------------
    84111  if (!KeySet.ParseKeySets(argv[1], Force.RowCounter, Force.MatrixCounter)) return 1;
    85 
    86112  if (!KeySet.ParseManyBodyTerms()) return 1;
     113
    87114  if (!EnergyFragments.AllocateMatrix(Energy.Header, Energy.MatrixCounter, Energy.RowCounter, Energy.ColumnCounter)) return 1;
    88   if (Hcorrected)  HcorrectionFragments.AllocateMatrix(Hcorrection.Header, Hcorrection.MatrixCounter, Hcorrection.RowCounter, Hcorrection.ColumnCounter);
     115  if (!NoHCorrection) 
     116    HcorrectionFragments.AllocateMatrix(Hcorrection.Header, Hcorrection.MatrixCounter, Hcorrection.RowCounter, Hcorrection.ColumnCounter);
    89117  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;
    90120  if (periode != NULL) { // also look for PAS values
    91121    if (!ShieldingFragments.AllocateMatrix(Shielding.Header, Shielding.MatrixCounter, Shielding.RowCounter, Shielding.ColumnCounter)) return 1;
    92122    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;
    93125  }
    94126 
     
    96128  if(!Energy.SetLastMatrix(0., 0)) return 1;
    97129  if(!Force.SetLastMatrix(0., 2)) return 1;
     130  if (!NoHessian)
     131    if (!Hessian.SetLastMatrix(0., 0)) return 1;
    98132  if (periode != NULL) { // also look for PAS values
    99133    if(!Shielding.SetLastMatrix(0., 2)) return 1;
    100134    if(!ShieldingPAS.SetLastMatrix(0., 2)) return 1;
     135    if(!Chi.SetLastMatrix(0., 2)) return 1;
     136    if(!ChiPAS.SetLastMatrix(0., 2)) return 1;
    101137  }
    102138
     
    108144    cout << "Summing energy of order " << BondOrder+1 << " ..." << endl;
    109145    if (!EnergyFragments.SumSubManyBodyTerms(Energy, KeySet, BondOrder)) return 1;
    110     if (Hcorrected) {
     146    if (!NoHCorrection) {
    111147      HcorrectionFragments.SumSubManyBodyTerms(Hcorrection, KeySet, BondOrder);
    112148      if (!Energy.SumSubEnergy(EnergyFragments, &HcorrectionFragments, KeySet, BondOrder, 1.)) return 1;
    113       if (Hcorrected) Hcorrection.SumSubEnergy(HcorrectionFragments, NULL, KeySet, BondOrder, 1.);
     149      Hcorrection.SumSubEnergy(HcorrectionFragments, NULL, KeySet, BondOrder, 1.);
    114150    } else
    115151      if (!Energy.SumSubEnergy(EnergyFragments, NULL, KeySet, BondOrder, 1.)) return 1;
     
    118154    if (!ForceFragments.SumSubManyBodyTerms(Force, KeySet, BondOrder)) return 1;
    119155    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    }
    120162    if (periode != NULL) { // also look for PAS values
    121       cout << "Summing shieldings of order " << BondOrder+1 << " ..." << endl;
     163      cout << "Summing shieldings and susceptibilities of order " << BondOrder+1 << " ..." << endl;
    122164      if (!ShieldingFragments.SumSubManyBodyTerms(Shielding, KeySet, BondOrder)) return 1;
    123165      if (!Shielding.SumSubForces(ShieldingFragments, KeySet, BondOrder, 1.)) return 1;
    124166      if (!ShieldingPASFragments.SumSubManyBodyTerms(ShieldingPAS, KeySet, BondOrder)) return 1;
    125167      if (!ShieldingPAS.SumSubForces(ShieldingPASFragments, KeySet, BondOrder, 1.)) return 1;
     168      if (!ChiFragments.SumSubManyBodyTerms(Chi, KeySet, BondOrder)) return 1;
     169      if (!Chi.SumSubEnergy(ChiFragments, NULL, KeySet, BondOrder, 1.)) return 1;
     170      if (!ChiPASFragments.SumSubManyBodyTerms(ChiPAS, KeySet, BondOrder)) return 1;
     171      if (!ChiPAS.SumSubEnergy(ChiPASFragments, NULL,KeySet, BondOrder, 1.)) return 1;
    126172    }
    127173
     
    134180    // forces
    135181    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;
    136185    // shieldings
    137186    if (periode != NULL) { // also look for PAS values
    138187      if (!Shielding.WriteLastMatrix(argv[1], (prefix.str()).c_str(), ShieldingSuffix)) return 1;
    139188      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;
    140191    }
    141192  }
     
    144195  prefix << dir << EnergyFragmentSuffix;
    145196  if (!EnergyFragments.WriteTotalFragments(argv[1], (prefix.str()).c_str())) return 1;
    146   if (Hcorrected) {
     197  if (!NoHCorrection) {
    147198    prefix.str(" ");
    148199    prefix << dir << HcorrectionFragmentSuffix;
     
    153204  if (!ForceFragments.WriteTotalFragments(argv[1], (prefix.str()).c_str())) return 1;
    154205  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  }
    155211  if (periode != NULL) { // also look for PAS values
    156212    prefix.str(" ");
     
    160216    prefix << dir << ShieldingPASFragmentSuffix;
    161217    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;
    162224  }
    163225
    164226  // write last matrices as fragments into central dir (not subdir as above), for analyzer to know index bounds
    165227  if (!Energy.WriteLastMatrix(argv[1], dir, EnergyFragmentSuffix)) return 1;
    166   if (Hcorrected) Hcorrection.WriteLastMatrix(argv[1], dir, HcorrectionFragmentSuffix);
     228  if (!NoHCorrection) Hcorrection.WriteLastMatrix(argv[1], dir, HcorrectionFragmentSuffix);
    167229  if (!Force.WriteLastMatrix(argv[1], dir, ForceFragmentSuffix)) return 1;
     230  if (!NoHessian)
     231    if (!Hessian.WriteLastMatrix(argv[1], dir, HessianFragmentSuffix)) return 1;
    168232  if (periode != NULL) { // also look for PAS values
    169233    if (!Shielding.WriteLastMatrix(argv[1], dir, ShieldingFragmentSuffix)) return 1;
    170234    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;
    171237  }
    172238
  • src/moleculelist.cpp

    • Property mode changed from 100644 to 100755
    rfcbfc8 r631dcb  
    395395  int FragmentCounter = 0;
    396396  ofstream output;
     397  string basis("3-21G");
    397398 
    398399  // store the fragments as config and as xyz
     
    455456    // and save as config
    456457    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(&outputFragment, ListOfMolecules[i]->elemente, ListOfMolecules[i])))
     459    if ((intermediateResult = configuration->Save(FragmentName, ListOfMolecules[i]->elemente, ListOfMolecules[i])))
    460460      *out << " done." << endl;
    461461    else
    462462      *out << " failed." << endl;
     463    result = result && intermediateResult;
    463464
    464465    // restore old config
    465466    configuration->SetDefaultPath(PathBackup);
    466467
    467     result = result && intermediateResult;
    468     outputFragment.close();
    469     outputFragment.clear();
    470468
    471469    // and save as mpqc input file
    472470    sprintf(FragmentName, "%s/%s%s.in", configuration->configpath, fragmentprefix, FragmentNumber);
    473     outputFragment.open(FragmentName, ios::out);
    474471    *out << Verbose(2) << "Saving " << fragmentprefix << " No. " << FragmentNumber << "/" << FragmentCounter-1 << " as mpqc input ...";
    475     if ((intermediateResult = configuration->SaveMPQC(&outputFragment, ListOfMolecules[i])))
     472    if ((intermediateResult = configuration->SaveMPQC(FragmentName, ListOfMolecules[i])))
    476473      *out << " done." << endl;
    477474    else
     
    479476       
    480477    result = result && intermediateResult;
    481     outputFragment.close();
    482     outputFragment.clear();
     478    //outputFragment.close();
     479    //outputFragment.clear();
    483480    delete(FragmentNumber);
    484481    //Free((void **)&FragmentNumber, "MoleculeListClass::OutputConfigForListOfFragments: *FragmentNumber");
  • src/molecules.cpp

    • Property mode changed from 100644 to 100755
    rfcbfc8 r631dcb  
    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) << "WARNING: There is no typical bond distance for bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") of degree " << TopBond->BondDegree << "!" << endl;
    223     BondRescale = bondlength;
     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;
    224225  } else {
    225226    if (!IsAngstroem)
     
    272273      if (FirstOtherAtom != NULL) { // then we just have this double bond and the plane does not matter at all
    273274//        *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;
    274        
     275
    275276        // determine the plane of these two with the *origin
    276277        AllWentWell = AllWentWell && Orthovector1.MakeNormalVector(&TopOrigin->x, &FirstOtherAtom->x, &SecondOtherAtom->x);
     
    285286      Orthovector1.Normalize();
    286287      //*out << Verbose(3) << "ReScaleCheck: " << Orthovector1.Norm() << " and " << InBondvector.Norm() << "." << endl;
    287      
     288
    288289      // create the two Hydrogens ...
    289290      FirstOtherAtom = new atom();
     
    299300      bondangle = TopOrigin->type->HBondAngle[1];
    300301      if (bondangle == -1) {
    301         *out << Verbose(3) << "WARNING: There is no typical bond angle for bond (" << TopOrigin->Name << "<->" << TopReplacement->Name << ") of degree " << TopBond->BondDegree << "!" << endl;
     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;
    302304        bondangle = 0;
    303305      }
     
    316318        SecondOtherAtom->x.x[i] = InBondvector.x[i] * cos(bondangle) + Orthovector1.x[i] * (-sin(bondangle));
    317319      }
    318       FirstOtherAtom->x.Scale(&BondRescale);  // rescale by correct BondDistance 
     320      FirstOtherAtom->x.Scale(&BondRescale);  // rescale by correct BondDistance
    319321      SecondOtherAtom->x.Scale(&BondRescale);
    320322      //*out << Verbose(3) << "ReScaleCheck: " << FirstOtherAtom->x.Norm() << " and " << SecondOtherAtom->x.Norm() << "." << endl;
    321323      for(int i=NDIM;i--;) { // and make relative to origin atom
    322         FirstOtherAtom->x.x[i] += TopOrigin->x.x[i]; 
     324        FirstOtherAtom->x.x[i] += TopOrigin->x.x[i];
    323325        SecondOtherAtom->x.x[i] += TopOrigin->x.x[i];
    324326      }
     
    363365//      *out << endl;
    364366      AllWentWell = AllWentWell && Orthovector2.MakeNormalVector(&InBondvector, &Orthovector1);
    365 //      *out << Verbose(3) << "Orthovector2: "; 
     367//      *out << Verbose(3) << "Orthovector2: ";
    366368//      Orthovector2.Output(out);
    367369//      *out << endl;
    368      
     370
    369371      // create correct coordination for the three atoms
    370372      alpha = (TopOrigin->type->HBondAngle[2])/180.*M_PI/2.;  // retrieve triple bond angle from database
     
    378380      factors[0] = d;
    379381      factors[1] = f;
    380       factors[2] = 0.; 
     382      factors[2] = 0.;
    381383      FirstOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
    382384      factors[1] = -0.5*f;
    383       factors[2] = g; 
     385      factors[2] = g;
    384386      SecondOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
    385       factors[2] = -g; 
     387      factors[2] = -g;
    386388      ThirdOtherAtom->x.LinearCombinationOfVectors(&InBondvector, &Orthovector1, &Orthovector2, factors);
    387389
     
    435437 */
    436438bool molecule::AddXYZFile(string filename)
    437 { 
     439{
    438440  istringstream *input = NULL;
    439441  int NumberOfAtoms = 0; // atom number in xyz read
     
    444446  string line;    // currently parsed line
    445447  double x[3];    // atom coordinates
    446  
     448
    447449  xyzfile.open(filename.c_str());
    448450  if (!xyzfile)
     
    452454  input = new istringstream(line);
    453455  *input >> NumberOfAtoms;
    454   cout << Verbose(0) << "Parsing " << NumberOfAtoms << " atoms in file." << endl; 
     456  cout << Verbose(0) << "Parsing " << NumberOfAtoms << " atoms in file." << endl;
    455457  getline(xyzfile,line,'\n'); // Read comment
    456458  cout << Verbose(1) << "Comment: " << line << endl;
    457  
     459
    458460  if (MDSteps == 0) // no atoms yet present
    459461    MDSteps++;
     
    489491  xyzfile.close();
    490492  delete(input);
    491   return true; 
     493  return true;
    492494};
    493495
     
    501503  atom *LeftAtom = NULL, *RightAtom = NULL;
    502504  atom *Walker = NULL;
    503  
     505
    504506  // copy all atoms
    505507  Walker = start;
     
    508510    CurrentAtom = copy->AddCopyAtom(Walker);
    509511  }
    510  
     512
    511513  // copy all bonds
    512514  bond *Binder = first;
     
    532534      copy->NoCyclicBonds++;
    533535    NewBond->Type = Binder->Type;
    534   } 
     536  }
    535537  // correct fathers
    536538  Walker = copy->start;
     
    549551    copy->CreateListOfBondsPerAtom((ofstream *)&cout);
    550552  }
    551  
     553
    552554  return copy;
    553555};
     
    574576
    575577/** Remove bond from bond chain list.
    576  * \todo Function not implemented yet 
     578 * \todo Function not implemented yet
    577579 * \param *pointer bond pointer
    578580 * \return true - bound found and removed, false - bond not found/removed
     
    586588
    587589/** Remove every bond from bond chain list that atom \a *BondPartner is a constituent of.
    588  * \todo Function not implemented yet 
     590 * \todo Function not implemented yet
    589591 * \param *BondPartner atom to be removed
    590592 * \return true - bounds found and removed, false - bonds not found/removed
     
    619621  Vector *min = new Vector;
    620622  Vector *max = new Vector;
    621  
     623
    622624  // gather min and max for each axis
    623625  ptr = start->next;  // start at first in list
     
    665667{
    666668  Vector *min = new Vector;
    667  
     669
    668670//  *out << Verbose(3) << "Begin of CenterEdge." << endl;
    669671  atom *ptr = start->next;  // start at first in list
     
    681683      }
    682684    }
    683 //    *out << Verbose(4) << "Maximum is "; 
     685//    *out << Verbose(4) << "Maximum is ";
    684686//    max->Output(out);
    685687//    *out << ", Minimum is ";
     
    689691    max->AddVector(min);
    690692    Translate(min);
    691   } 
     693  }
    692694  delete(min);
    693695//  *out << Verbose(3) << "End of CenterEdge." << endl;
    694 }; 
     696};
    695697
    696698/** Centers the center of the atoms at (0,0,0).
     
    702704  int Num = 0;
    703705  atom *ptr = start->next;  // start at first in list
    704  
     706
    705707  for(int i=NDIM;i--;) // zero center vector
    706708    center->x[i] = 0.;
    707    
     709
    708710  if (ptr != end) {   //list not empty?
    709711    while (ptr->next != end) {  // continue with second if present
    710712      ptr = ptr->next;
    711713      Num++;
    712       center->AddVector(&ptr->x);       
     714      center->AddVector(&ptr->x);
    713715    }
    714716    center->Scale(-1./Num); // divide through total number (and sign for direction)
    715717    Translate(center);
    716718  }
    717 }; 
     719};
    718720
    719721/** Returns vector pointing to center of gravity.
     
    727729  Vector tmp;
    728730  double Num = 0;
    729  
     731
    730732  a->Zero();
    731733
     
    735737      Num += 1.;
    736738      tmp.CopyVector(&ptr->x);
    737       a->AddVector(&tmp);       
     739      a->AddVector(&tmp);
    738740    }
    739741    a->Scale(-1./Num); // divide through total mass (and sign for direction)
     
    755757        Vector tmp;
    756758  double Num = 0;
    757        
     759
    758760        a->Zero();
    759761
     
    764766      tmp.CopyVector(&ptr->x);
    765767      tmp.Scale(ptr->type->mass);  // scale by mass
    766       a->AddVector(&tmp);       
     768      a->AddVector(&tmp);
    767769    }
    768770    a->Scale(-1./Num); // divide through total mass (and sign for direction)
     
    787789    Translate(center);
    788790  }
    789 }; 
     791};
    790792
    791793/** Scales all atoms by \a *factor.
     
    801803      Trajectories[ptr].R.at(j).Scale(factor);
    802804    ptr->x.Scale(factor);
    803   }     
    804 };
    805 
    806 /** Translate all atoms by given vector. 
     805  }
     806};
     807
     808/** Translate all atoms by given vector.
    807809 * \param trans[] translation vector.
    808810 */
     
    816818      Trajectories[ptr].R.at(j).Translate(trans);
    817819    ptr->x.Translate(trans);
    818   }     
    819 };
    820 
    821 /** Mirrors all atoms against a given plane. 
     820  }
     821};
     822
     823/** Mirrors all atoms against a given plane.
    822824 * \param n[] normal vector of mirror plane.
    823825 */
     
    831833      Trajectories[ptr].R.at(j).Mirror(n);
    832834    ptr->x.Mirror(n);
    833   }     
     835  }
    834836};
    835837
     
    845847  bool flag;
    846848  Vector Testvector, Translationvector;
    847  
     849
    848850  do {
    849851    Center.Zero();
     
    861863          if (Walker->nr < Binder->GetOtherAtom(Walker)->nr) // otherwise we shift one to, the other fro and gain nothing
    862864            for (int j=0;j<NDIM;j++) {
    863               tmp = Walker->x.x[j] - Binder->GetOtherAtom(Walker)->x.x[j]; 
     865              tmp = Walker->x.x[j] - Binder->GetOtherAtom(Walker)->x.x[j];
    864866              if ((fabs(tmp)) > BondDistance) {
    865867                flag = false;
     
    877879        cout << Verbose(1) << "vector is: ";
    878880        Testvector.Output((ofstream *)&cout);
    879         cout << endl;     
     881        cout << endl;
    880882#ifdef ADDHYDROGEN
    881883        // now also change all hydrogens
     
    890892            cout << Verbose(1) << "Hydrogen vector is: ";
    891893            Testvector.Output((ofstream *)&cout);
    892             cout << endl;     
     894            cout << endl;
    893895          }
    894896        }
     
    912914
    913915        CenterGravity(out, CenterOfGravity);
    914        
    915         // reset inertia tensor 
     916
     917        // reset inertia tensor
    916918        for(int i=0;i<NDIM*NDIM;i++)
    917919                InertiaTensor[i] = 0.;
    918        
     920
    919921        // sum up inertia tensor
    920922        while (ptr->next != end) {
     
    941943        }
    942944        *out << endl;
    943        
     945
    944946        // diagonalize to determine principal axis system
    945947        gsl_eigen_symmv_workspace *T = gsl_eigen_symmv_alloc(NDIM);
     
    950952        gsl_eigen_symmv_free(T);
    951953        gsl_eigen_symmv_sort(eval, evec, GSL_EIGEN_SORT_ABS_DESC);
    952        
     954
    953955        for(int i=0;i<NDIM;i++) {
    954956                *out << Verbose(1) << "eigenvalue = " << gsl_vector_get(eval, i);
    955957                *out << ", eigenvector = (" << evec->data[i * evec->tda + 0] << "," << evec->data[i * evec->tda + 1] << "," << evec->data[i * evec->tda + 2] << ")" << endl;
    956958        }
    957        
     959
    958960        // check whether we rotate or not
    959961        if (DoRotate) {
    960           *out << Verbose(1) << "Transforming molecule into PAS ... "; 
     962          *out << Verbose(1) << "Transforming molecule into PAS ... ";
    961963          // the eigenvectors specify the transformation matrix
    962964          ptr = start;
     
    970972
    971973          // summing anew for debugging (resulting matrix has to be diagonal!)
    972           // reset inertia tensor 
     974          // reset inertia tensor
    973975    for(int i=0;i<NDIM*NDIM;i++)
    974976      InertiaTensor[i] = 0.;
    975    
     977
    976978    // sum up inertia tensor
    977979    ptr = start;
     
    10001002    *out << endl;
    10011003        }
    1002        
     1004
    10031005        // free everything
    10041006        delete(CenterOfGravity);
     
    14891491{
    14901492  atom *walker = NULL;
    1491   int AtomNo;
    14921493  ifstream input(file);
    14931494  string token;
    14941495  stringstream item;
    1495   double a, IonMass, Vector[NDIM], ConstrainedPotentialEnergy, ActualTemp;
     1496  double IonMass, Vector[NDIM], ConstrainedPotentialEnergy, ActualTemp;
    14961497  ForceMatrix Force;
    14971498
    14981499  CountElements();  // make sure ElementsInMolecule is up to date
    1499  
     1500
    15001501  // check file
    15011502  if (input == NULL) {
     
    15781579    }
    15791580  }
     1581  // correct velocities (rather momenta) so that center of mass remains motionless
    15801582  for(int d=0;d<NDIM;d++)
    15811583    Vector[d] /= IonMass;
     
    15921594  MDSteps++;
    15931595
    1594  
     1596
    15951597  // exit
    15961598  return true;
    15971599};
    1598 
    15991600
    16001601/** Implementation of various thermostats.
     
    17851786    ptr = ptr->next;
    17861787    tmp = ptr->x.x[0];
    1787     ptr->x.x[0] =  cos(alpha) * tmp + sin(alpha) * ptr->x.x[2]; 
     1788    ptr->x.x[0] =  cos(alpha) * tmp + sin(alpha) * ptr->x.x[2];
    17881789    ptr->x.x[2] = -sin(alpha) * tmp + cos(alpha) * ptr->x.x[2];
    17891790    for (int j=0;j<MDSteps;j++) {
    17901791      tmp = Trajectories[ptr].R.at(j).x[0];
    1791       Trajectories[ptr].R.at(j).x[0] =  cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2]; 
     1792      Trajectories[ptr].R.at(j).x[0] =  cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2];
    17921793      Trajectories[ptr].R.at(j).x[2] = -sin(alpha) * tmp + cos(alpha) * Trajectories[ptr].R.at(j).x[2];
    17931794    }
    1794   }     
     1795  }
    17951796  // rotate n vector
    17961797  tmp = n->x[0];
     
    18001801  n->Output((ofstream *)&cout);
    18011802  cout << endl;
    1802  
     1803
    18031804  // rotate on z-y plane
    18041805  ptr = start;
     
    18081809    ptr = ptr->next;
    18091810    tmp = ptr->x.x[1];
    1810     ptr->x.x[1] =  cos(alpha) * tmp + sin(alpha) * ptr->x.x[2]; 
     1811    ptr->x.x[1] =  cos(alpha) * tmp + sin(alpha) * ptr->x.x[2];
    18111812    ptr->x.x[2] = -sin(alpha) * tmp + cos(alpha) * ptr->x.x[2];
    18121813    for (int j=0;j<MDSteps;j++) {
    18131814      tmp = Trajectories[ptr].R.at(j).x[1];
    1814       Trajectories[ptr].R.at(j).x[1] =  cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2]; 
     1815      Trajectories[ptr].R.at(j).x[1] =  cos(alpha) * tmp + sin(alpha) * Trajectories[ptr].R.at(j).x[2];
    18151816      Trajectories[ptr].R.at(j).x[2] = -sin(alpha) * tmp + cos(alpha) * Trajectories[ptr].R.at(j).x[2];
    18161817    }
    1817   }     
     1818  }
    18181819  // rotate n vector (for consistency check)
    18191820  tmp = n->x[1];
    18201821  n->x[1] =  cos(alpha) * tmp +  sin(alpha) * n->x[2];
    18211822  n->x[2] = -sin(alpha) * tmp +  cos(alpha) * n->x[2];
    1822  
     1823
    18231824  cout << Verbose(1) << "alignment vector after second rotation: ";
    18241825  n->Output((ofstream *)&cout);
     
    18311832 * \return true - succeeded, false - atom not found in list
    18321833 */
    1833 bool molecule::RemoveAtom(atom *pointer) 
    1834 { 
     1834bool molecule::RemoveAtom(atom *pointer)
     1835{
    18351836  if (ElementsInMolecule[pointer->type->Z] != 0)  // this would indicate an error
    18361837    ElementsInMolecule[pointer->type->Z]--;  // decrease number of atom of this element
    18371838  else
    1838     cerr << "ERROR: Atom " << pointer->Name << " is of element " << pointer->type->Z << " but the entry in the table of the molecule is 0!" << endl; 
     1839    cerr << "ERROR: Atom " << pointer->Name << " is of element " << pointer->type->Z << " but the entry in the table of the molecule is 0!" << endl;
    18391840  if (ElementsInMolecule[pointer->type->Z] == 0)  // was last atom of this element?
    18401841    ElementCount--;
     
    18461847 * \return true - succeeded, false - atom not found in list
    18471848 */
    1848 bool molecule::CleanupMolecule() 
    1849 { 
    1850   return (cleanup(start,end) && cleanup(first,last)); 
     1849bool molecule::CleanupMolecule()
     1850{
     1851  return (cleanup(start,end) && cleanup(first,last));
    18511852};
    18521853
     
    18621863  } else {
    18631864    cout << Verbose(0) << "Atom not found in list." << endl;
    1864     return NULL; 
     1865    return NULL;
    18651866  }
    18661867};
     
    19111912  struct lsq_params *par = (struct lsq_params *)params;
    19121913  atom *ptr = par->mol->start;
    1913  
     1914
    19141915  // initialize vectors
    19151916  a.x[0] = gsl_vector_get(x,0);
     
    19411942{
    19421943    int np = 6;
    1943    
     1944
    19441945   const gsl_multimin_fminimizer_type *T =
    19451946     gsl_multimin_fminimizer_nmsimplex;
     
    19471948   gsl_vector *ss;
    19481949   gsl_multimin_function minex_func;
    1949  
     1950
    19501951   size_t iter = 0, i;
    19511952   int status;
    19521953   double size;
    1953  
     1954
    19541955   /* Initial vertex size vector */
    19551956   ss = gsl_vector_alloc (np);
    1956  
     1957
    19571958   /* Set all step sizes to 1 */
    19581959   gsl_vector_set_all (ss, 1.0);
    1959  
     1960
    19601961   /* Starting point */
    19611962   par->x = gsl_vector_alloc (np);
    19621963   par->mol = this;
    1963  
     1964
    19641965   gsl_vector_set (par->x, 0, 0.0);  // offset
    19651966   gsl_vector_set (par->x, 1, 0.0);
     
    19681969   gsl_vector_set (par->x, 4, 0.0);
    19691970   gsl_vector_set (par->x, 5, 1.0);
    1970  
     1971
    19711972   /* Initialize method and iterate */
    19721973   minex_func.f = &LeastSquareDistance;
    19731974   minex_func.n = np;
    19741975   minex_func.params = (void *)par;
    1975  
     1976
    19761977   s = gsl_multimin_fminimizer_alloc (T, np);
    19771978   gsl_multimin_fminimizer_set (s, &minex_func, par->x, ss);
    1978  
     1979
    19791980   do
    19801981     {
    19811982       iter++;
    19821983       status = gsl_multimin_fminimizer_iterate(s);
    1983  
     1984
    19841985       if (status)
    19851986         break;
    1986  
     1987
    19871988       size = gsl_multimin_fminimizer_size (s);
    19881989       status = gsl_multimin_test_size (size, 1e-2);
    1989  
     1990
    19901991       if (status == GSL_SUCCESS)
    19911992         {
    19921993           printf ("converged to minimum at\n");
    19931994         }
    1994  
     1995
    19951996       printf ("%5d ", (int)iter);
    19961997       for (i = 0; i < (size_t)np; i++)
     
    20012002     }
    20022003   while (status == GSL_CONTINUE && iter < 100);
    2003  
     2004
    20042005  for (i=0;i<(size_t)np;i++)
    20052006    gsl_vector_set(par->x, i, gsl_vector_get(s->x, i));
     
    20182019  int ElementNo, AtomNo;
    20192020  CountElements();
    2020  
     2021
    20212022  if (out == NULL) {
    20222023    return false;
     
    20532054  int ElementNo, AtomNo;
    20542055  CountElements();
    2055  
     2056
    20562057  if (out == NULL) {
    20572058    return false;
     
    21002101  atom *Walker = start;
    21012102  while (Walker->next != end) {
    2102     Walker = Walker->next; 
     2103    Walker = Walker->next;
    21032104#ifdef ADDHYDROGEN
    21042105    if (Walker->type->Z != 1) {   // regard only non-hydrogen
     
    21312132  int No = 0;
    21322133  time_t now;
    2133  
     2134
    21342135  now = time((time_t *)NULL);   // Get the system time and put it into 'now' as 'calender time'
    21352136  walker = start;
     
    21582159{
    21592160  atom *walker = NULL;
    2160   int No = 0;
     2161  int AtomNo = 0, ElementNo;
    21612162  time_t now;
    2162  
     2163  element *runner = NULL;
     2164
    21632165  now = time((time_t *)NULL);   // Get the system time and put it into 'now' as 'calender time'
    21642166  walker = start;
    21652167  while (walker->next != end) { // go through every atom and count
    21662168    walker = walker->next;
    2167     No++;
     2169    AtomNo++;
    21682170  }
    21692171  if (out != NULL) {
    2170     *out << No << "\n\tCreated by molecuilder on " << ctime(&now);
    2171     walker = start;
    2172     while (walker->next != end) { // go through every atom of this element
    2173       walker = walker->next;
    2174       walker->OutputXYZLine(out);
     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      }
    21752187    }
    21762188    return true;
     
    22032215              Walker->nr = i;   // update number in molecule (for easier referencing in FragmentMolecule lateron)
    22042216              if (Walker->type->Z != 1) // count non-hydrogen atoms whilst at it
    2205                 NoNonHydrogen++; 
     2217                NoNonHydrogen++;
    22062218              Free((void **)&Walker->Name, "molecule::CountAtoms: *walker->Name");
    22072219              Walker->Name = (char *) Malloc(sizeof(char)*6, "molecule::CountAtoms: *walker->Name");
     
    22112223            }
    22122224    } else
    2213         *out << Verbose(3) << "AtomCount is still " << AtomCount << ", thus counting nothing." << endl; 
     2225        *out << Verbose(3) << "AtomCount is still " << AtomCount << ", thus counting nothing." << endl;
    22142226  }
    22152227};
     
    22232235        ElementsInMolecule[i] = 0;
    22242236        ElementCount = 0;
    2225        
     2237
    22262238  atom *walker = start;
    22272239  while (walker->next != end) {
     
    22592271    Binder = Binder->next;
    22602272    if (Binder->Cyclic)
    2261       No++;   
     2273      No++;
    22622274  }
    22632275  delete(BackEdgeStack);
     
    23172329
    23182330/** Creates an adjacency list of the molecule.
     2331 * We obtain an outside file with the indices of atoms which are bondmembers.
     2332 */
     2333void 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.
    23192379 * Generally, we use the CSD approach to bond recognition, that is the the distance
    23202380 * between two atoms A and B must be within [Rcov(A)+Rcov(B)-t,Rcov(A)+Rcov(B)+t] with
    2321  * a threshold t = 0.4 Angstroem. 
     2381 * a threshold t = 0.4 Angstroem.
    23222382 * To make it O(N log N) the function uses the linked-cell technique as follows:
    23232383 * The procedure is step-wise:
     
    23362396void molecule::CreateAdjacencyList(ofstream *out, double bonddistance, bool IsAngstroem)
    23372397{
     2398
    23382399  atom *Walker = NULL, *OtherWalker = NULL, *Candidate = NULL;
    23392400  int No, NoBonds, CandidateBondNo;
     
    23442405  Vector x;
    23452406  int FalseBondDegree = 0;
    2346  
     2407  
    23472408  BondDistance = bonddistance; // * ((IsAngstroem) ? 1. : 1./AtomicLengthToAngstroem);
    23482409  *out << Verbose(0) << "Begin of CreateAdjacencyList." << endl;
     
    23512412    cleanup(first,last);
    23522413  }
    2353        
     2414
    23542415  // count atoms in molecule = dimension of matrix (also give each unique name and continuous numbering)
    23552416  CountAtoms(out);
     
    23702431    for (int i=NumberCells;i--;)
    23712432      CellList[i] = NULL;
    2372  
     2433
    23732434    // 2b. put all atoms into its corresponding list
    23742435    Walker = start;
     
    23912452      if (CellList[index] == NULL)  // allocate molecule if not done
    23922453        CellList[index] = new molecule(elemente);
    2393       OtherWalker = CellList[index]->AddCopyAtom(Walker); // add a copy of walker to this atom, father will be walker for later reference 
    2394       //*out << Verbose(1) << "Copy Atom is " << *OtherWalker << "." << endl; 
     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;
    23952456    }
    23962457    //for (int i=0;i<NumberCells;i++)
    23972458      //*out << Verbose(1) << "Cell number " << i << ": " << CellList[i] << "." << endl;
    2398      
     2459
     2460
    23992461    // 3a. go through every cell
    24002462    for (N[0]=divisor[0];N[0]--;)
     
    24092471              Walker = Walker->next;
    24102472              //*out << Verbose(0) << "Current Atom is " << *Walker << "." << endl;
    2411               // 3c. check for possible bond between each atom in this and every one in the 27 cells 
     2473              // 3c. check for possible bond between each atom in this and every one in the 27 cells
    24122474              for (n[0]=-1;n[0]<=1;n[0]++)
    24132475                for (n[1]=-1;n[1]<=1;n[1]++)
     
    24412503          }
    24422504        }
     2505
     2506
     2507
    24432508    // 4. free the cell again
    24442509    for (int i=NumberCells;i--;)
     
    24472512      }
    24482513    Free((void **)&CellList, "molecule::CreateAdjacencyList - ** CellList");
    2449    
     2514
    24502515    // create the adjacency list per atom
    24512516    CreateListOfBondsPerAtom(out);
    2452                
     2517
    24532518    // correct Bond degree of each bond by checking both bond partners for a mismatch between valence and current sum of bond degrees,
    24542519    // iteratively increase the one first where the other bond partner has the fewest number of bonds (i.e. in general bonds oxygene
     
    25092574    *out << endl;
    25102575  } else
    2511         *out << Verbose(1) << "AtomCount is " << AtomCount << ", thus no bonds, no connections!." << endl; 
     2576        *out << Verbose(1) << "AtomCount is " << AtomCount << ", thus no bonds, no connections!." << endl;
    25122577  *out << Verbose(0) << "End of CreateAdjacencyList." << endl;
    25132578  Free((void **)&matrix, "molecule::CreateAdjacencyList: *matrix");
    2514 };
     2579
     2580};
     2581
     2582
    25152583
    25162584/** Performs a Depth-First search on this molecule.
     
    25332601  bond *Binder = NULL;
    25342602  bool BackStepping = false;
    2535  
     2603
    25362604  *out << Verbose(0) << "Begin of DepthFirstSearchAnalysis" << endl;
    2537  
     2605
    25382606  ResetAllBondsToUnused();
    25392607  ResetAllAtomNumbers();
     
    25482616    LeafWalker->Leaf = new molecule(elemente);
    25492617    LeafWalker->Leaf->AddCopyAtom(Root);
    2550    
     2618
    25512619    OldGraphNr = CurrentGraphNr;
    25522620    Walker = Root;
     
    25592627          AtomStack->Push(Walker);
    25602628          CurrentGraphNr++;
    2561         }     
     2629        }
    25622630        do { // (3) if Walker has no unused egdes, go to (5)
    25632631          BackStepping = false; // reset backstepping flag for (8)
     
    25932661          Binder = NULL;
    25942662      } while (1);  // (2)
    2595      
     2663
    25962664      // 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!
    25972665      if ((Walker == Root) && (Binder == NULL))
    25982666        break;
    2599        
    2600       // (5) if Ancestor of Walker is ... 
     2667
     2668      // (5) if Ancestor of Walker is ...
    26012669      *out << Verbose(1) << "(5) Number of Walker[" << Walker->Name << "]'s Ancestor[" << Walker->Ancestor->Name << "] is " << Walker->Ancestor->GraphNr << "." << endl;
    26022670      if (Walker->Ancestor->GraphNr != Root->GraphNr) {
     
    26412709        } while (OtherAtom != Walker);
    26422710        ComponentNumber++;
    2643    
     2711
    26442712        // (11) Root is separation vertex,  set Walker to Root and go to (4)
    26452713        Walker = Root;
     
    26542722
    26552723    // From OldGraphNr to CurrentGraphNr ranges an disconnected subgraph
    2656     *out << Verbose(0) << "Disconnected subgraph ranges from " << OldGraphNr << " to " << CurrentGraphNr << "." << endl;   
     2724    *out << Verbose(0) << "Disconnected subgraph ranges from " << OldGraphNr << " to " << CurrentGraphNr << "." << endl;
    26572725    LeafWalker->Leaf->Output(out);
    26582726    *out << endl;
     
    26622730      //*out << Verbose(1) << "Current next subgraph root candidate is " << Root->Name << "." << endl;
    26632731      if (Root->GraphNr != -1) // if already discovered, step on
    2664         Root = Root->next; 
     2732        Root = Root->next;
    26652733    }
    26662734  }
     
    26842752    *out << " with Lowpoint " << Walker->LowpointNr << " and Graph Nr. " << Walker->GraphNr << "." << endl;
    26852753  }
    2686  
     2754
    26872755  *out << Verbose(1) << "Final graph info for each bond is:" << endl;
    26882756  Binder = first;
     
    26952763    *out << ((Binder->rightatom->SeparationVertex) ? "SP," : "") << "L" << Binder->rightatom->LowpointNr << " G" << Binder->rightatom->GraphNr << " Comp.";
    26962764    OutputComponentNumber(out, Binder->rightatom);
    2697     *out << ">." << endl; 
     2765    *out << ">." << endl;
    26982766    if (Binder->Cyclic) // cyclic ??
    26992767      *out << Verbose(3) << "Lowpoint at each side are equal: CYCLIC!" << endl;
     
    27102778 * the other our initial Walker - and do a Breadth First Search for the Root. We mark down each Predecessor and as soon as
    27112779 * we have found the Root via BFS, we may climb back the closed cycle via the Predecessors. Thereby we mark atoms and bonds
    2712  * as cyclic and print out the cycles. 
     2780 * as cyclic and print out the cycles.
    27132781 * \param *out output stream for debugging
    27142782 * \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!
     
    27212789  int *ShortestPathList = (int *) Malloc(sizeof(int)*AtomCount, "molecule::CyclicStructureAnalysis: *ShortestPathList");
    27222790  enum Shading *ColorList = (enum Shading *) Malloc(sizeof(enum Shading)*AtomCount, "molecule::CyclicStructureAnalysis: *ColorList");
    2723   class StackClass<atom *> *BFSStack = new StackClass<atom *> (AtomCount);   // will hold the current ring 
     2791  class StackClass<atom *> *BFSStack = new StackClass<atom *> (AtomCount);   // will hold the current ring
    27242792  class StackClass<atom *> *TouchedStack = new StackClass<atom *> (AtomCount);   // contains all "touched" atoms (that need to be reset after BFS loop)
    27252793  atom *Walker = NULL, *OtherAtom = NULL, *Root = NULL;
     
    27332801    ColorList[i] = white;
    27342802  }
    2735   
     2803 
    27362804  *out << Verbose(1) << "Back edge list - ";
    27372805  BackEdgeStack->Output(out);
    2738  
     2806
    27392807  *out << Verbose(1) << "Analysing cycles ... " << endl;
    27402808  NumCycles = 0;
     
    27422810    BackEdge = BackEdgeStack->PopFirst();
    27432811    // this is the target
    2744     Root = BackEdge->leftatom; 
     2812    Root = BackEdge->leftatom;
    27452813    // this is the source point
    2746     Walker = BackEdge->rightatom; 
     2814    Walker = BackEdge->rightatom;
    27472815    ShortestPathList[Walker->nr] = 0;
    27482816    BFSStack->ClearStack();  // start with empty BFS stack
     
    27582826        if (Binder != BackEdge) { // only walk along DFS spanning tree (otherwise we always find SP of one being backedge Binder)
    27592827          OtherAtom = Binder->GetOtherAtom(Walker);
    2760 #ifdef ADDHYDROGEN         
     2828#ifdef ADDHYDROGEN
    27612829          if (OtherAtom->type->Z != 1) {
    27622830#endif
     
    27672835              PredecessorList[OtherAtom->nr] = Walker;  // Walker is the predecessor
    27682836              ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
    2769               *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; 
     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;
    27702838              //if (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr]) { // Check for maximum distance
    27712839                *out << Verbose(3) << "Putting OtherAtom into queue." << endl;
     
    27772845            if (OtherAtom == Root)
    27782846              break;
    2779 #ifdef ADDHYDROGEN         
     2847#ifdef ADDHYDROGEN
    27802848          } else {
    27812849            *out << Verbose(2) << "Skipping hydrogen atom " << *OtherAtom << "." << endl;
     
    28152883      }
    28162884    } while ((!BFSStack->IsEmpty()) && (OtherAtom != Root) && (OtherAtom != NULL)); // || (ShortestPathList[OtherAtom->nr] < MinimumRingSize[Walker->GetTrueFather()->nr])));
    2817    
     2885
    28182886    if (OtherAtom == Root) {
    28192887      // now climb back the predecessor list and thus find the cycle members
     
    28432911      *out << Verbose(1) << "No ring containing " << *Root << " with length equal to or smaller than " << MinimumRingSize[Walker->GetTrueFather()->nr] << " found." << endl;
    28442912    }
    2845    
     2913
    28462914    // now clean the lists
    28472915    while (!TouchedStack->IsEmpty()){
     
    28532921  }
    28542922  if (MinRingSize != -1) {
    2855     // go over all atoms 
     2923    // go over all atoms
    28562924    Root = start;
    28572925    while(Root->next != end) {
    28582926      Root = Root->next;
    2859      
     2927
    28602928      if (MinimumRingSize[Root->GetTrueFather()->nr] == AtomCount) { // check whether MinimumRingSize is set, if not BFS to next where it is
    28612929        Walker = Root;
     
    28942962          }
    28952963          ColorList[Walker->nr] = black;
    2896           //*out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl; 
     2964          //*out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
    28972965        }
    2898    
     2966
    28992967        // now clean the lists
    29002968        while (!TouchedStack->IsEmpty()){
     
    29453013void molecule::OutputComponentNumber(ofstream *out, atom *vertex)
    29463014{
    2947   for(int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++) 
     3015  for(int i=0;i<NumberOfBondsPerAtom[vertex->nr];i++)
    29483016    *out << vertex->ComponentNr[i] << "  ";
    29493017};
     
    30233091{
    30243092  int c = 0;
    3025   int FragmentCount; 
     3093  int FragmentCount;
    30263094  // get maximum bond degree
    30273095  atom *Walker = start;
     
    30333101  *out << Verbose(1) << "Upper limit for this subgraph is " << FragmentCount << " for " << NoNonHydrogen << " non-H atoms with maximum bond degree of " << c << "." << endl;
    30343102  return FragmentCount;
    3035 }; 
     3103};
    30363104
    30373105/** Scans a single line for number and puts them into \a KeySet.
    30383106 * \param *out output stream for debugging
    30393107 * \param *buffer buffer to scan
    3040  * \param &CurrentSet filled KeySet on return 
     3108 * \param &CurrentSet filled KeySet on return
    30413109 * \return true - at least one valid atom id parsed, false - CurrentSet is empty
    30423110 */
     
    30463114  int AtomNr;
    30473115  int status = 0;
    3048  
     3116
    30493117  line.str(buffer);
    30503118  while (!line.eof()) {
     
    30823150  double TEFactor;
    30833151  char *filename = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::ParseKeySetFile - filename");
    3084  
     3152
    30853153  if (FragmentList == NULL) { // check list pointer
    30863154    FragmentList = new Graph;
    30873155  }
    3088  
     3156
    30893157  // 1st pass: open file and read
    30903158  *out << Verbose(1) << "Parsing the KeySet file ... " << endl;
     
    31153183    status = false;
    31163184  }
    3117  
     3185
    31183186  // 2nd pass: open TEFactors file and read
    31193187  *out << Verbose(1) << "Parsing the TEFactors file ... " << endl;
     
    31273195        InputFile >> TEFactor;
    31283196        (*runner).second.second = TEFactor;
    3129         *out << Verbose(2) << "Setting " << ++NumberOfFragments << " fragment's TEFactor to " << (*runner).second.second << "." << endl; 
     3197        *out << Verbose(2) << "Setting " << ++NumberOfFragments << " fragment's TEFactor to " << (*runner).second.second << "." << endl;
    31303198      } else {
    31313199        status = false;
     
    31683236  if(output != NULL) {
    31693237    for(Graph::iterator runner = KeySetList.begin(); runner != KeySetList.end(); runner++) {
    3170       for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) { 
     3238      for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) {
    31713239        if (sprinter != (*runner).first.begin())
    31723240          output << "\t";
     
    32343302    status = false;
    32353303  }
    3236  
     3304
    32373305  return status;
    32383306};
     
    32433311 * \param **ListOfAtoms allocated (molecule::AtomCount) and filled lookup table for ids (Atom::nr) to *Atom
    32443312 * \return true - structure is equal, false - not equivalence
    3245  */ 
     3313 */
    32463314bool molecule::CheckAdjacencyFileAgainstMolecule(ofstream *out, char *path, atom **ListOfAtoms)
    32473315{
     
    32503318  bool status = true;
    32513319  char *buffer = (char *) Malloc(sizeof(char)*MAXSTRINGSIZE, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer");
    3252  
     3320
    32533321  filename << path << "/" << FRAGMENTPREFIX << ADJACENCYFILE;
    32543322  File.open(filename.str().c_str(), ios::out);
     
    33093377  *out << endl;
    33103378  Free((void **)&buffer, "molecule::CheckAdjacencyFileAgainstMolecule: *buffer");
    3311  
     3379
    33123380  return status;
    33133381};
     
    33313399  for(int i=AtomCount;i--;)
    33323400    AtomMask[i] = false;
    3333  
     3401
    33343402  if (Order < 0) { // adaptive increase of BondOrder per site
    33353403    if (AtomMask[AtomCount] == true)  // break after one step
     
    33713439          line >> ws >> Value; // skip time entry
    33723440          line >> ws >> Value;
    3373           No -= 1;  // indices start at 1 in file, not 0 
     3441          No -= 1;  // indices start at 1 in file, not 0
    33743442          //*out << Verbose(2) << " - yields (" << No << "," << Value << ", " << FragOrder << ")" << endl;
    33753443
     
    33803448            // 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
    33813449            pair <map<int, pair<double,int> >::iterator, bool> InsertedElement = AdaptiveCriteriaList.insert( make_pair(*((*marker).second.begin()), pair<double,int>( fabs(Value), FragOrder) ));
    3382             map<int, pair<double,int> >::iterator PresentItem = InsertedElement.first; 
     3450            map<int, pair<double,int> >::iterator PresentItem = InsertedElement.first;
    33833451            if (!InsertedElement.second) { // this root is already present
    3384               if ((*PresentItem).second.second < FragOrder)  // if order there is lower, update entry with higher-order term 
    3385                 //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) 
     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)
    33863454                {  // if value is smaller, update value and order
    33873455                (*PresentItem).second.first = fabs(Value);
     
    34213489        Walker = FindAtom(No);
    34223490        //if (Walker->AdaptiveOrder < MinimumRingSize[Walker->nr]) {
    3423           *out << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", setting entry " << No << " of Atom mask to true." << endl; 
     3491          *out << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", setting entry " << No << " of Atom mask to true." << endl;
    34243492          AtomMask[No] = true;
    34253493          status = true;
    34263494        //} else
    3427           //*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; 
     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;
    34283496      }
    34293497      // close and done
     
    34593527    if ((Order == 0) && (AtomMask[AtomCount] == false))  // single stepping, just check
    34603528      status = true;
    3461      
     3529
    34623530    if (!status) {
    34633531      if (Order == 0)
     
    34673535    }
    34683536  }
    3469  
     3537
    34703538  // print atom mask for debugging
    34713539  *out << "              ";
     
    34763544    *out << (AtomMask[i] ? "t" : "f");
    34773545  *out << endl;
    3478  
     3546
    34793547  return status;
    34803548};
     
    34903558  int AtomNo = 0;
    34913559  atom *Walker = NULL;
    3492  
     3560
    34933561  if (SortIndex != NULL) {
    34943562    *out << Verbose(1) << "SortIndex is " << SortIndex << " and not NULL as expected." << endl;
     
    35483616  atom **ListOfAtoms = NULL;
    35493617  atom ***ListOfLocalAtoms = NULL;
    3550   bool *AtomMask = NULL; 
    3551  
     3618  bool *AtomMask = NULL;
     3619
    35523620  *out << endl;
    35533621#ifdef ADDHYDROGEN
     
    35583626
    35593627  // ++++++++++++++++++++++++++++ INITIAL STUFF: Bond structure analysis, file parsing, ... ++++++++++++++++++++++++++++++++++++++++++
    3560  
     3628
    35613629  // ===== 1. Check whether bond structure is same as stored in files ====
    3562  
     3630
    35633631  // fill the adjacency list
    35643632  CreateListOfBondsPerAtom(out);
     
    35663634  // create lookup table for Atom::nr
    35673635  FragmentationToDo = FragmentationToDo && CreateFatherLookupTable(out, start, end, ListOfAtoms, AtomCount);
    3568  
     3636
    35693637  // === compare it with adjacency file ===
    3570   FragmentationToDo = FragmentationToDo && CheckAdjacencyFileAgainstMolecule(out, configuration->configpath, ListOfAtoms); 
     3638  FragmentationToDo = FragmentationToDo && CheckAdjacencyFileAgainstMolecule(out, configuration->configpath, ListOfAtoms);
    35713639  Free((void **)&ListOfAtoms, "molecule::FragmentMolecule - **ListOfAtoms");
    35723640
     
    35913659//      else
    35923660//        *out << "\t" << ListOfLocalAtoms[FragmentCounter][i]->Name;
     3661    *out << Verbose(0) << "Gathering local back edges for subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
    35933662    MolecularWalker->Leaf->PickLocalBackEdges(out, ListOfLocalAtoms[FragmentCounter++], BackEdgeStack, LocalBackEdgeStack);
     3663    *out << Verbose(0) << "Analysing the cycles of subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
    35943664    MolecularWalker->Leaf->CyclicStructureAnalysis(out, LocalBackEdgeStack, MinimumRingSize);
     3665    *out << Verbose(0) << "Done with Analysing the cycles of subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
    35953666    delete(LocalBackEdgeStack);
    35963667  }
     
    36143685    FragmentationToDo = FragmentationToDo || CheckOrder;
    36153686    AtomMask[AtomCount] = true;   // last plus one entry is used as marker that we have been through this loop once already in CheckOrderAtSite()
    3616     // ===== 6b. fill RootStack for each subgraph (second adaptivity check) ===== 
     3687    // ===== 6b. fill RootStack for each subgraph (second adaptivity check) =====
    36173688    Subgraphs->next->FillRootStackForSubgraphs(out, RootStack, AtomMask, (FragmentCounter = 0));
    36183689
     
    36233694      MolecularWalker = MolecularWalker->next;
    36243695      *out << Verbose(1) << "Fragmenting subgraph " << MolecularWalker << "." << endl;
    3625       // output ListOfBondsPerAtom for debugging
    3626       MolecularWalker->Leaf->OutputListOfBonds(out);
     3696      //MolecularWalker->Leaf->OutputListOfBonds(out);  // output ListOfBondsPerAtom for debugging
    36273697      if (MolecularWalker->Leaf->first->next != MolecularWalker->Leaf->last) {
    3628      
    36293698        // call BOSSANOVA method
    36303699        *out << Verbose(0) << endl << " ========== BOND ENERGY of subgraph " << FragmentCounter << " ========================= " << endl;
     
    36463715  // ===== 8a. translate list into global numbers (i.e. ones that are valid in "this" molecule, not in MolecularWalker->Leaf)
    36473716  Subgraphs->next->TranslateIndicesToGlobalIDs(out, FragmentList, (FragmentCounter = 0), TotalNumberOfKeySets, TotalGraph);
    3648  
     3717
    36493718  // free subgraph memory again
    36503719  FragmentCounter = 0;
     
    36713740    }
    36723741    *out << k << "/" << BondFragments->NumberOfMolecules << " fragments generated from the keysets." << endl;
    3673    
     3742
    36743743    // ===== 9. Save fragments' configuration and keyset files et al to disk ===
    36753744    if (BondFragments->NumberOfMolecules != 0) {
    36763745      // create the SortIndex from BFS labels to order in the config file
    36773746      CreateMappingLabelsToConfigSequence(out, SortIndex);
    3678      
     3747
    36793748      *out << Verbose(1) << "Writing " << BondFragments->NumberOfMolecules << " possible bond fragmentation configs" << endl;
    36803749      if (BondFragments->OutputConfigForListOfFragments(out, FRAGMENTPREFIX, configuration, SortIndex, true, true))
     
    36823751      else
    36833752        *out << Verbose(1) << "Some config writing failed." << endl;
    3684  
     3753
    36853754      // store force index reference file
    36863755      BondFragments->StoreForcesFile(out, configuration->configpath, SortIndex);
    3687      
    3688       // store keysets file 
     3756
     3757      // store keysets file
    36893758      StoreKeySetFile(out, TotalGraph, configuration->configpath);
    3690  
    3691       // store Adjacency file 
     3759
     3760      // store Adjacency file
    36923761      StoreAdjacencyToFile(out, configuration->configpath);
    3693  
     3762
    36943763      // store Hydrogen saturation correction file
    36953764      BondFragments->AddHydrogenCorrection(out, configuration->configpath);
    3696      
     3765
    36973766      // store adaptive orders into file
    36983767      StoreOrderAtSiteFile(out, configuration->configpath);
    3699      
     3768
    37003769      // restore orbital and Stop values
    37013770      CalculateOrbitals(*configuration);
    3702      
     3771
    37033772      // free memory for bond part
    37043773      *out << Verbose(1) << "Freeing bond memory" << endl;
    37053774      delete(FragmentList); // remove bond molecule from memory
    3706       Free((void **)&SortIndex, "molecule::FragmentMolecule: *SortIndex"); 
     3775      Free((void **)&SortIndex, "molecule::FragmentMolecule: *SortIndex");
    37073776    } else
    37083777      *out << Verbose(1) << "FragmentList is zero on return, splitting failed." << endl;
    3709   //} else 
     3778  //} else
    37103779  //  *out << Verbose(1) << "No fragments to store." << endl;
    37113780  *out << Verbose(0) << "End of bond fragmentation." << endl;
     
    37363805  do {  // go through all bonds and push local ones
    37373806    Walker = ListOfLocalAtoms[Binder->leftatom->nr];  // get one atom in the reference molecule
    3738     if (Walker == NULL) // if this Walker exists in the subgraph ...
    3739       continue;
    3740     for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {    // go through the local list of bonds
    3741       OtherAtom = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
    3742       if (OtherAtom == ListOfLocalAtoms[Binder->rightatom->nr]) { // found the bond
    3743         LocalStack->Push(ListOfBondsPerAtom[Walker->nr][i]);
    3744         break;
    3745       }
    3746     }
     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        }
    37473816    Binder = ReferenceStack->PopFirst();  // loop the stack for next item
     3817    *out << Verbose(3) << "Current candidate edge " << Binder << "." << endl;
    37483818    ReferenceStack->Push(Binder);
    37493819  } while (FirstBond != Binder);
     
    38243894      Walker->AdaptiveOrder = OrderArray[Walker->nr];
    38253895      Walker->MaxOrder = MaxArray[Walker->nr];
    3826       *out << Verbose(2) << *Walker << " gets order " << (int)Walker->AdaptiveOrder << " and is " << (!Walker->MaxOrder ? "not " : " ") << "maxed." << endl; 
     3896      *out << Verbose(2) << *Walker << " gets order " << (int)Walker->AdaptiveOrder << " and is " << (!Walker->MaxOrder ? "not " : " ") << "maxed." << endl;
    38273897    }
    38283898    file.close();
     
    38353905  Free((void **)&OrderArray, "molecule::ParseOrderAtSiteFromFile - *OrderArray");
    38363906  Free((void **)&MaxArray, "molecule::ParseOrderAtSiteFromFile - *MaxArray");
    3837  
     3907
    38383908  *out << Verbose(1) << "End of ParseOrderAtSiteFromFile" << endl;
    38393909  return status;
     
    39013971    }
    39023972    *out << " -- TotalDegree: " << TotalDegree << endl;
    3903   }     
     3973  }
    39043974  *out << Verbose(1) << "End of Creating ListOfBondsPerAtom." << endl << endl;
    39053975};
     
    39073977/** Adds atoms up to \a BondCount distance from \a *Root and notes them down in \a **AddedAtomList.
    39083978 * Gray vertices are always enqueued in an StackClass<atom *> FIFO queue, the rest is usual BFS with adding vertices found was
    3909  * white and putting into queue. 
     3979 * white and putting into queue.
    39103980 * \param *out output stream for debugging
    39113981 * \param *Mol Molecule class to add atoms to
     
    39163986 * \param BondOrder maximum distance for vertices to add
    39173987 * \param IsAngstroem lengths are in angstroem or bohrradii
    3918  */ 
     3988 */
    39193989void molecule::BreadthFirstSearchAdd(ofstream *out, molecule *Mol, atom **&AddedAtomList, bond **&AddedBondList, atom *Root, bond *Bond, int BondOrder, bool IsAngstroem)
    39203990{
     
    39424012  }
    39434013  ShortestPathList[Root->nr] = 0;
    3944  
     4014
    39454015  // and go on ... Queue always contains all lightgray vertices
    39464016  while (!AtomStack->IsEmpty()) {
     
    39504020    // followed by n+1 till top of stack.
    39514021    Walker = AtomStack->PopFirst(); // pop oldest added
    3952     *out << Verbose(1) << "Current Walker is: " << Walker->Name << ", and has " << NumberOfBondsPerAtom[Walker->nr] << " bonds." << endl; 
     4022    *out << Verbose(1) << "Current Walker is: " << Walker->Name << ", and has " << NumberOfBondsPerAtom[Walker->nr] << " bonds." << endl;
    39534023    for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {
    39544024      Binder = ListOfBondsPerAtom[Walker->nr][i];
     
    39574027        *out << Verbose(2) << "Current OtherAtom is: " << OtherAtom->Name << " for bond " << *Binder << "." << endl;
    39584028        if (ColorList[OtherAtom->nr] == white) {
    3959           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) 
     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)
    39604030            ColorList[OtherAtom->nr] = lightgray;
    39614031          PredecessorList[OtherAtom->nr] = Walker;  // Walker is the predecessor
    39624032          ShortestPathList[OtherAtom->nr] = ShortestPathList[Walker->nr]+1;
    3963           *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; 
     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;
    39644034          if ((((ShortestPathList[OtherAtom->nr] < BondOrder) && (Binder != Bond))) ) { // Check for maximum distance
    39654035            *out << Verbose(3);
     
    39994069              } else {
    40004070#ifdef ADDHYDROGEN
    4001                 Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem);
     4071                if (!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem))
     4072                  exit(1);
    40024073#endif
    40034074              }
     
    40084079          // This has to be a cyclic bond, check whether it's present ...
    40094080          if (AddedBondList[Binder->nr] == NULL) {
    4010             if ((Binder != Bond) && (Binder->Cyclic) && (((ShortestPathList[Walker->nr]+1) < BondOrder))) { 
     4081            if ((Binder != Bond) && (Binder->Cyclic) && (((ShortestPathList[Walker->nr]+1) < BondOrder))) {
    40114082              AddedBondList[Binder->nr] = Mol->AddBond(AddedAtomList[Walker->nr], AddedAtomList[OtherAtom->nr], Binder->BondDegree);
    40124083              AddedBondList[Binder->nr]->Cyclic = Binder->Cyclic;
     
    40144085            } else { // if it's root bond it has to broken (otherwise we would not create the fragments)
    40154086#ifdef ADDHYDROGEN
    4016               Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem);
     4087              if(!Mol->AddHydrogenReplacementAtom(out, Binder, AddedAtomList[Walker->nr], Walker, OtherAtom, ListOfBondsPerAtom[Walker->nr], NumberOfBondsPerAtom[Walker->nr], IsAngstroem))
     4088                exit(1);
    40174089#endif
    40184090            }
     
    40224094    }
    40234095    ColorList[Walker->nr] = black;
    4024     *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl; 
     4096    *out << Verbose(1) << "Coloring Walker " << Walker->Name << " black." << endl;
    40254097  }
    40264098  Free((void **)&PredecessorList, "molecule::BreadthFirstSearchAdd: **PredecessorList");
     
    40464118
    40474119  *out << Verbose(2) << "Begin of BuildInducedSubgraph." << endl;
    4048  
     4120
    40494121  // reset parent list
    40504122  *out << Verbose(3) << "Resetting ParentList." << endl;
    40514123  for (int i=Father->AtomCount;i--;)
    40524124    ParentList[i] = NULL;
    4053  
     4125
    40544126  // fill parent list with sons
    40554127  *out << Verbose(3) << "Filling Parent List." << endl;
     
    40924164 * \param *&Leaf KeySet to look through
    40934165 * \param *&ShortestPathList list of the shortest path to decide which atom to suggest as removal candidate in the end
    4094  * \param index of the atom suggested for removal 
     4166 * \param index of the atom suggested for removal
    40954167 */
    40964168int molecule::LookForRemovalCandidate(ofstream *&out, KeySet *&Leaf, int *&ShortestPathList)
     
    40984170  atom *Runner = NULL;
    40994171  int SP, Removal;
    4100  
     4172
    41014173  *out << Verbose(2) << "Looking for removal candidate." << endl;
    41024174  SP = -1; //0;  // not -1, so that Root is never removed
     
    41164188/** Stores a fragment from \a KeySet into \a molecule.
    41174189 * First creates the minimal set of atoms from the KeySet, then creates the bond structure from the complete
    4118  * molecule and adds missing hydrogen where bonds were cut. 
     4190 * molecule and adds missing hydrogen where bonds were cut.
    41194191 * \param *out output stream for debugging messages
    4120  * \param &Leaflet pointer to KeySet structure 
     4192 * \param &Leaflet pointer to KeySet structure
    41214193 * \param IsAngstroem whether we have Ansgtroem or bohrradius
    41224194 * \return pointer to constructed molecule
     
    41294201  bool LonelyFlag = false;
    41304202  int size;
    4131  
     4203
    41324204//  *out << Verbose(1) << "Begin of StoreFragmentFromKeyset." << endl;
    4133  
     4205
    41344206  Leaf->BondDistance = BondDistance;
    41354207  for(int i=NDIM*2;i--;)
    4136     Leaf->cell_size[i] = cell_size[i]; 
     4208    Leaf->cell_size[i] = cell_size[i];
    41374209
    41384210  // initialise SonList (indicates when we need to replace a bond with hydrogen instead)
     
    41474219    size++;
    41484220  }
    4149  
     4221
    41504222  // create the bonds between all: Make it an induced subgraph and add hydrogen
    41514223//  *out << Verbose(2) << "Creating bonds from father graph (i.e. induced subgraph creation)." << endl;
     
    41574229    if (SonList[FatherOfRunner->nr] != NULL)  {  // check if this, our father, is present in list
    41584230      // create all bonds
    4159       for (int i=0;i<NumberOfBondsPerAtom[FatherOfRunner->nr];i++) { // go through every bond of father 
     4231      for (int i=0;i<NumberOfBondsPerAtom[FatherOfRunner->nr];i++) { // go through every bond of father
    41604232        OtherFather = ListOfBondsPerAtom[FatherOfRunner->nr][i]->GetOtherAtom(FatherOfRunner);
    41614233//        *out << Verbose(2) << "Father " << *FatherOfRunner << " of son " << *SonList[FatherOfRunner->nr] << " is bound to " << *OtherFather;
    41624234        if (SonList[OtherFather->nr] != NULL) {
    4163 //          *out << ", whose son is " << *SonList[OtherFather->nr] << "." << endl; 
     4235//          *out << ", whose son is " << *SonList[OtherFather->nr] << "." << endl;
    41644236          if (OtherFather->nr > FatherOfRunner->nr) { // add bond (nr check is for adding only one of both variants: ab, ba)
    41654237//            *out << Verbose(3) << "Adding Bond: ";
    4166 //            *out << 
     4238//            *out <<
    41674239            Leaf->AddBond(Runner, SonList[OtherFather->nr], ListOfBondsPerAtom[FatherOfRunner->nr][i]->BondDegree);
    41684240//            *out << "." << endl;
    41694241            //NumBonds[Runner->nr]++;
    4170           } else { 
     4242          } else {
    41714243//            *out << Verbose(3) << "Not adding bond, labels in wrong order." << endl;
    41724244          }
    41734245          LonelyFlag = false;
    41744246        } else {
    4175 //          *out << ", who has no son in this fragment molecule." << endl; 
     4247//          *out << ", who has no son in this fragment molecule." << endl;
    41764248#ifdef ADDHYDROGEN
    41774249          //*out << Verbose(3) << "Adding Hydrogen to " << Runner->Name << " and a bond in between." << endl;
    4178           Leaf->AddHydrogenReplacementAtom(out, ListOfBondsPerAtom[FatherOfRunner->nr][i], Runner, FatherOfRunner, OtherFather, ListOfBondsPerAtom[FatherOfRunner->nr],NumberOfBondsPerAtom[FatherOfRunner->nr], IsAngstroem);
     4250          if(!Leaf->AddHydrogenReplacementAtom(out, ListOfBondsPerAtom[FatherOfRunner->nr][i], Runner, FatherOfRunner, OtherFather, ListOfBondsPerAtom[FatherOfRunner->nr],NumberOfBondsPerAtom[FatherOfRunner->nr], IsAngstroem))
     4251            exit(1);
    41794252#endif
    41804253          //NumBonds[Runner->nr] += ListOfBondsPerAtom[FatherOfRunner->nr][i]->BondDegree;
     
    41904263    while ((Runner->next != Leaf->end) && (Runner->next->type->Z == 1)) // skip added hydrogen
    41914264      Runner = Runner->next;
    4192 #endif       
     4265#endif
    41934266  }
    41944267  Leaf->CreateListOfBondsPerAtom(out);
     
    42234296  StackClass<atom *> *TouchedStack = new StackClass<atom *>((int)pow(4,Order)+2); // number of atoms reached from one with maximal 4 bonds plus Root itself
    42244297  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!
    4225   MoleculeLeafClass *Leaflet = NULL, *TempLeaf = NULL; 
     4298  MoleculeLeafClass *Leaflet = NULL, *TempLeaf = NULL;
    42264299  MoleculeListClass *FragmentList = NULL;
    42274300  atom *Walker = NULL, *OtherAtom = NULL, *Root = NULL, *Removal = NULL;
     
    42734346                // clear snake stack
    42744347          SnakeStack->ClearStack();
    4275     //SnakeStack->TestImplementation(out, start->next);   
     4348    //SnakeStack->TestImplementation(out, start->next);
    42764349
    42774350    ///// INNER LOOP ////////////
     
    42944367        }
    42954368        if (ShortestPathList[Walker->nr] == -1) {
    4296           ShortestPathList[Walker->nr] = ShortestPathList[PredecessorList[Walker->nr]->nr]+1; 
     4369          ShortestPathList[Walker->nr] = ShortestPathList[PredecessorList[Walker->nr]->nr]+1;
    42974370          TouchedStack->Push(Walker); // mark every atom for lists cleanup later, whose shortest path has been changed
    42984371        }
     
    43324405                                OtherAtom = Binder->GetOtherAtom(Walker);
    43334406            if ((Labels[OtherAtom->nr] != -1) && (Labels[OtherAtom->nr] < Labels[Root->nr])) { // we don't step up to labels bigger than us
    4334               *out << "Label " << Labels[OtherAtom->nr] << " is smaller than Root's " << Labels[Root->nr] << "." << endl; 
     4407              *out << "Label " << Labels[OtherAtom->nr] << " is smaller than Root's " << Labels[Root->nr] << "." << endl;
    43354408              //ColorVertexList[OtherAtom->nr] = lightgray;    // mark as explored
    43364409            } else { // otherwise check its colour and element
    43374410                                if (
    43384411#ifdef ADDHYDROGEN
    4339               (OtherAtom->type->Z != 1) && 
     4412              (OtherAtom->type->Z != 1) &&
    43404413#endif
    43414414                    (ColorEdgeList[Binder->nr] == white)) {  // skip hydrogen, look for unexplored vertices
     
    43474420                //} else {
    43484421                //  *out << Verbose(3) << "Predecessor of " << OtherAtom->Name << " is " << PredecessorList[OtherAtom->nr]->Name << "." << endl;
    4349                 //} 
     4422                //}
    43504423                Walker = OtherAtom;
    43514424                break;
    43524425              } else {
    4353                 if (OtherAtom->type->Z == 1) 
     4426                if (OtherAtom->type->Z == 1)
    43544427                  *out << "Links to a hydrogen atom." << endl;
    4355                 else                 
     4428                else
    43564429                  *out << "Bond has not white but " << GetColor(ColorEdgeList[Binder->nr]) << " color." << endl;
    43574430              }
     
    43634436          *out << Verbose(3) << "We have gone too far, stepping back to " << Walker->Name << "." << endl;
    43644437        }
    4365                         if (Walker != OtherAtom) {      // if no white neighbours anymore, color it black 
     4438                        if (Walker != OtherAtom) {      // if no white neighbours anymore, color it black
    43664439          *out << Verbose(2) << "Coloring " << Walker->Name << " black." << endl;
    43674440                                ColorVertexList[Walker->nr] = black;
     
    43704443      }
    43714444        } while ((Walker != Root) || (ColorVertexList[Root->nr] != black));
    4372     *out << Verbose(2) << "Inner Looping is finished." << endl;   
     4445    *out << Verbose(2) << "Inner Looping is finished." << endl;
    43734446
    43744447    // if we reset all AtomCount atoms, we have again technically O(N^2) ...
     
    43864459    }
    43874460  }
    4388   *out << Verbose(1) << "Outer Looping over all vertices is done." << endl; 
     4461  *out << Verbose(1) << "Outer Looping over all vertices is done." << endl;
    43894462
    43904463  // copy together
    4391   *out << Verbose(1) << "Copying all fragments into MoleculeList structure." << endl; 
     4464  *out << Verbose(1) << "Copying all fragments into MoleculeList structure." << endl;
    43924465  FragmentList = new MoleculeListClass(FragmentCounter, AtomCount);
    43934466  RunningIndex = 0;
     
    44604533
    44614534  NumCombinations = 1 << SetDimension;
    4462  
     4535
    44634536  // Hier muessen von 1 bis NumberOfBondsPerAtom[Walker->nr] alle Kombinationen
    44644537  // von Endstuecken (aus den Bonds) hinzugefᅵᅵgt werden und fᅵᅵr verbleibende ANOVAOrder
    44654538  // rekursiv GraphCrawler in der nᅵᅵchsten Ebene aufgerufen werden
    4466  
     4539
    44674540  *out << Verbose(1+verbosity) << "Begin of SPFragmentGenerator." << endl;
    44684541  *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;
    44694542
    4470   // initialised touched list (stores added atoms on this level) 
     4543  // initialised touched list (stores added atoms on this level)
    44714544  *out << Verbose(1+verbosity) << "Clearing touched list." << endl;
    44724545  for (TouchedIndex=SubOrder+1;TouchedIndex--;)  // empty touched list
    44734546    TouchedList[TouchedIndex] = -1;
    44744547  TouchedIndex = 0;
    4475  
     4548
    44764549  // create every possible combination of the endpieces
    44774550  *out << Verbose(1+verbosity) << "Going through all combinations of the power set." << endl;
     
    44814554    for (int j=SetDimension;j--;)
    44824555      bits += (i & (1 << j)) >> j;
    4483      
     4556
    44844557    *out << Verbose(1+verbosity) << "Current set is " << Binary(i | (1 << SetDimension)) << ", number of bits is " << bits << "." << endl;
    44854558    if (bits <= SubOrder) { // if not greater than additional atoms allowed on stack, continue
     
    44894562        bit = ((i & (1 << j)) != 0);  // mask the bit for the j-th bond
    44904563        if (bit) {  // if bit is set, we add this bond partner
    4491                 OtherWalker = BondsSet[j]->rightatom;   // rightatom is always the one more distant, i.e. the one to add 
     4564                OtherWalker = BondsSet[j]->rightatom;   // rightatom is always the one more distant, i.e. the one to add
    44924565          //*out << Verbose(1+verbosity) << "Current Bond is " << ListOfBondsPerAtom[Walker->nr][i] << ", checking on " << *OtherWalker << "." << endl;
    44934566          *out << Verbose(2+verbosity) << "Adding " << *OtherWalker << " with nr " << OtherWalker->nr << "." << endl;
    4494           TestKeySetInsert = FragmentSearch->FragmentSet->insert(OtherWalker->nr); 
     4567          TestKeySetInsert = FragmentSearch->FragmentSet->insert(OtherWalker->nr);
    44954568          if (TestKeySetInsert.second) {
    44964569            TouchedList[TouchedIndex++] = OtherWalker->nr;  // note as added
     
    45054578        }
    45064579      }
    4507      
    4508       SpaceLeft = SubOrder - Added ;// SubOrder - bits; // due to item's maybe being already present, this does not work anymore 
     4580
     4581      SpaceLeft = SubOrder - Added ;// SubOrder - bits; // due to item's maybe being already present, this does not work anymore
    45094582      if (SpaceLeft > 0) {
    45104583        *out << Verbose(1+verbosity) << "There's still some space left on stack: " << SpaceLeft << "." << endl;
     
    45344607          }
    45354608          *out << Verbose(2+verbosity) << "Calling subset generator " << SP << " away from root " << *FragmentSearch->Root << " with sub set dimension " << SubSetDimension << "." << endl;
    4536           SPFragmentGenerator(out, FragmentSearch, SP, BondsList, SubSetDimension, SubOrder-bits); 
     4609          SPFragmentGenerator(out, FragmentSearch, SP, BondsList, SubSetDimension, SubOrder-bits);
    45374610          Free((void **)&BondsList, "molecule::SPFragmentGenerator: **BondsList");
    45384611        }
     
    45434616        *out << Verbose(2) << "Found a new fragment[" << FragmentSearch->FragmentCounter << "], local nr.s are: ";
    45444617        for(KeySet::iterator runner = FragmentSearch->FragmentSet->begin(); runner != FragmentSearch->FragmentSet->end(); runner++)
    4545           *out << (*runner) << " "; 
     4618          *out << (*runner) << " ";
    45464619        *out << endl;
    45474620        //if (!CheckForConnectedSubgraph(out, FragmentSearch->FragmentSet))
     
    45514624        //Removal = StoreFragmentFromStack(out, FragmentSearch->Root, FragmentSearch->Leaflet, FragmentSearch->FragmentStack, FragmentSearch->ShortestPathList, &FragmentSearch->FragmentCounter, FragmentSearch->configuration);
    45524625      }
    4553      
     4626
    45544627      // --3-- remove all added items in this level from snake stack
    45554628      *out << Verbose(1+verbosity) << "Removing all items that were added on this SP level " << RootDistance << "." << endl;
     
    45624635      *out << Verbose(2) << "Remaining local nr.s on snake stack are: ";
    45634636      for(KeySet::iterator runner = FragmentSearch->FragmentSet->begin(); runner != FragmentSearch->FragmentSet->end(); runner++)
    4564         *out << (*runner) << " "; 
     4637        *out << (*runner) << " ";
    45654638      *out << endl;
    45664639      TouchedIndex = 0; // set Index to 0 for list of atoms added on this level
     
    45694642    }
    45704643  }
    4571   Free((void **)&TouchedList, "molecule::SPFragmentGenerator: *TouchedList"); 
     4644  Free((void **)&TouchedList, "molecule::SPFragmentGenerator: *TouchedList");
    45724645  *out << Verbose(1+verbosity) << "End of SPFragmentGenerator, " << RootDistance << " away from Root " << *FragmentSearch->Root << " and SubOrder is " << SubOrder << "." << endl;
    45734646};
     
    45784651 * \return true - connected, false - disconnected
    45794652 * \note this is O(n^2) for it's just a bug checker not meant for permanent use!
    4580  */ 
     4653 */
    45814654bool molecule::CheckForConnectedSubgraph(ofstream *out, KeySet *Fragment)
    45824655{
     
    45844657  bool BondStatus = false;
    45854658  int size;
    4586  
     4659
    45874660  *out << Verbose(1) << "Begin of CheckForConnectedSubgraph" << endl;
    45884661  *out << Verbose(2) << "Disconnected atom: ";
    4589  
     4662
    45904663  // count number of atoms in graph
    45914664  size = 0;
     
    46334706 * \param *out output stream for debugging
    46344707 * \param Order bond order (limits BFS exploration and "number of digits" in power set generation
    4635  * \param FragmentSearch UniqueFragments structure containing TEFactor, root atom and so on 
     4708 * \param FragmentSearch UniqueFragments structure containing TEFactor, root atom and so on
    46364709 * \param RestrictedKeySet Restricted vertex set to use in context of molecule
    46374710 * \return number of inserted fragments
    46384711 * \note ShortestPathList in FragmentSearch structure is probably due to NumberOfAtomsSPLevel and SP not needed anymore
    46394712 */
    4640 int molecule::PowerSetGenerator(ofstream *out, int Order, struct UniqueFragments &FragmentSearch, KeySet RestrictedKeySet) 
     4713int molecule::PowerSetGenerator(ofstream *out, int Order, struct UniqueFragments &FragmentSearch, KeySet RestrictedKeySet)
    46414714{
    46424715  int SP, AtomKeyNr;
     
    46594732    FragmentSearch.BondsPerSPCount[i] = 0;
    46604733  FragmentSearch.BondsPerSPCount[0] = 1;
    4661   Binder = new bond(FragmentSearch.Root, FragmentSearch.Root); 
     4734  Binder = new bond(FragmentSearch.Root, FragmentSearch.Root);
    46624735  add(Binder, FragmentSearch.BondsPerSPList[1]);
    4663  
     4736
    46644737  // do a BFS search to fill the SP lists and label the found vertices
    46654738  // Actually, we should construct a spanning tree vom the root atom and select all edges therefrom and put them into
    46664739  // according shortest path lists. However, we don't. Rather we fill these lists right away, as they do form a spanning
    46674740  // tree already sorted into various SP levels. That's why we just do loops over the depth (CurrentSP) and breadth
    4668   // (EdgeinSPLevel) of this tree ... 
     4741  // (EdgeinSPLevel) of this tree ...
    46694742  // In another picture, the bonds always contain a direction by rightatom being the one more distant from root and hence
    46704743  // naturally leftatom forming its predecessor, preventing the BFS"seeker" from continuing in the wrong direction.
     
    47194792    }
    47204793  }
    4721  
     4794
    47224795  // outputting all list for debugging
    47234796  *out << Verbose(0) << "Printing all found lists." << endl;
     
    47284801      Binder = Binder->next;
    47294802      *out << Verbose(2) << *Binder << endl;
    4730     } 
    4731   }
    4732  
     4803    }
     4804  }
     4805
    47334806  // creating fragments with the found edge sets  (may be done in reverse order, faster)
    47344807  SP = -1;  // the Root <-> Root edge must be subtracted!
     
    47374810    while (Binder->next != FragmentSearch.BondsPerSPList[2*i+1]) {
    47384811      Binder = Binder->next;
    4739       SP ++; 
     4812      SP ++;
    47404813    }
    47414814  }
     
    47444817    // start with root (push on fragment stack)
    47454818    *out << Verbose(0) << "Starting fragment generation with " << *FragmentSearch.Root << ", local nr is " << FragmentSearch.Root->nr << "." << endl;
    4746     FragmentSearch.FragmentSet->clear(); 
     4819    FragmentSearch.FragmentSet->clear();
    47474820    *out << Verbose(0) << "Preparing subset for this root and calling generator." << endl;
    47484821    // prepare the subset and call the generator
    47494822    BondsList = (bond **) Malloc(sizeof(bond *)*FragmentSearch.BondsPerSPCount[0], "molecule::PowerSetGenerator: **BondsList");
    47504823    BondsList[0] = FragmentSearch.BondsPerSPList[0]->next;  // on SP level 0 there's only the root bond
    4751    
     4824
    47524825    SPFragmentGenerator(out, &FragmentSearch, 0, BondsList, FragmentSearch.BondsPerSPCount[0], Order);
    4753    
     4826
    47544827    Free((void **)&BondsList, "molecule::PowerSetGenerator: **BondsList");
    47554828  } else {
     
    47604833  // remove root from stack
    47614834  *out << Verbose(0) << "Removing root again from stack." << endl;
    4762   FragmentSearch.FragmentSet->erase(FragmentSearch.Root->nr);   
     4835  FragmentSearch.FragmentSet->erase(FragmentSearch.Root->nr);
    47634836
    47644837  // free'ing the bonds lists
     
    47794852  }
    47804853
    4781   // return list 
     4854  // return list
    47824855  *out << Verbose(0) << "End of PowerSetGenerator." << endl;
    47834856  return (FragmentSearch.FragmentCounter - Counter);
     
    48104883    // remove bonds that are beyond bonddistance
    48114884    for(int i=NDIM;i--;)
    4812       Translationvector.x[i] = 0.; 
     4885      Translationvector.x[i] = 0.;
    48134886    // scan all bonds
    48144887    Binder = first;
     
    48574930        }
    48584931      }
    4859       // re-add bond   
     4932      // re-add bond
    48604933      link(Binder, OtherBinder);
    48614934    } else {
     
    49114984        IteratorB++;
    49124985      } // end of while loop
    4913     }// end of check in case of equal sizes 
     4986    }// end of check in case of equal sizes
    49144987  }
    49154988  return false; // if we reach this point, they are equal
     
    49555028 * \param graph1 first (dest) graph
    49565029 * \param graph2 second (source) graph
    4957  * \param *counter keyset counter that gets increased 
     5030 * \param *counter keyset counter that gets increased
    49585031 */
    49595032inline void InsertGraphIntoGraph(ofstream *out, Graph &graph1, Graph &graph2, int *counter)
     
    50005073  int RootKeyNr, RootNr;
    50015074  struct UniqueFragments FragmentSearch;
    5002  
     5075
    50035076  *out << Verbose(0) << "Begin of FragmentBOSSANOVA." << endl;
    50045077
     
    50235096    Walker = Walker->next;
    50245097    CompleteMolecule.insert(Walker->GetTrueFather()->nr);
    5025   } 
     5098  }
    50265099
    50275100  // 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
     
    50375110    //if ((MinimumRingSize[Walker->GetTrueFather()->nr] != -1) && (Walker->GetTrueFather()->AdaptiveOrder+1 > MinimumRingSize[Walker->GetTrueFather()->nr])) {
    50385111    //  *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;
    5039     //} else 
     5112    //} else
    50405113    {
    50415114      // increase adaptive order by one
    50425115      Walker->GetTrueFather()->AdaptiveOrder++;
    50435116      Order = Walker->AdaptiveOrder = Walker->GetTrueFather()->AdaptiveOrder;
    5044  
     5117
    50455118      // initialise Order-dependent entries of UniqueFragments structure
    50465119      FragmentSearch.BondsPerSPList = (bond **) Malloc(sizeof(bond *)*Order*2, "molecule::PowerSetGenerator: ***BondsPerSPList");
     
    50495122        FragmentSearch.BondsPerSPList[2*i] = new bond();    // start node
    50505123        FragmentSearch.BondsPerSPList[2*i+1] = new bond();  // end node
    5051         FragmentSearch.BondsPerSPList[2*i]->next = FragmentSearch.BondsPerSPList[2*i+1];     // intertwine these two 
     5124        FragmentSearch.BondsPerSPList[2*i]->next = FragmentSearch.BondsPerSPList[2*i+1];     // intertwine these two
    50525125        FragmentSearch.BondsPerSPList[2*i+1]->previous = FragmentSearch.BondsPerSPList[2*i];
    50535126        FragmentSearch.BondsPerSPCount[i] = 0;
    5054       } 
    5055  
     5127      }
     5128
    50565129      // allocate memory for all lower level orders in this 1D-array of ptrs
    50575130      NumLevels = 1 << (Order-1); // (int)pow(2,Order);
     
    50595132      for (int i=0;i<NumLevels;i++)
    50605133        FragmentLowerOrdersList[RootNr][i] = NULL;
    5061      
     5134
    50625135      // create top order where nothing is reduced
    50635136      *out << Verbose(0) << "==============================================================================================================" << endl;
    50645137      *out << Verbose(0) << "Creating KeySets of Bond Order " << Order << " for " << *Walker << ", " << (RootStack.size()-RootNr) << " Roots remaining." << endl; // , NumLevels is " << NumLevels << "
    5065  
     5138
    50665139      // Create list of Graphs of current Bond Order (i.e. F_{ij})
    50675140      FragmentLowerOrdersList[RootNr][0] =  new Graph;
     
    50765149        // we don't have to dive into suborders! These keysets are all already created on lower orders!
    50775150        // this was all ancient stuff, when we still depended on the TEFactors (and for those the suborders were needed)
    5078        
     5151
    50795152//        if ((NumLevels >> 1) > 0) {
    50805153//          // create lower order fragments
     
    50835156//          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)
    50845157//            // step down to next order at (virtual) boundary of powers of 2 in array
    5085 //            while (source >= (1 << (Walker->AdaptiveOrder-Order))) // (int)pow(2,Walker->AdaptiveOrder-Order))   
     5158//            while (source >= (1 << (Walker->AdaptiveOrder-Order))) // (int)pow(2,Walker->AdaptiveOrder-Order))
    50865159//              Order--;
    50875160//            *out << Verbose(0) << "Current Order is: " << Order << "." << endl;
     
    50905163//              *out << Verbose(0) << "--------------------------------------------------------------------------------------------------------------" << endl;
    50915164//              *out << Verbose(0) << "Current SubOrder is: " << SubOrder << " with source " << source << " to destination " << dest << "." << endl;
    5092 //       
     5165//
    50935166//              // every molecule is split into a list of again (Order - 1) molecules, while counting all molecules
    50945167//              //*out << Verbose(1) << "Splitting the " << (*FragmentLowerOrdersList[RootNr][source]).size() << " molecules of the " << source << "th cell in the array." << endl;
     
    51215194      RootStack.push_back(RootKeyNr); // put back on stack
    51225195      RootNr++;
    5123  
     5196
    51245197      // free Order-dependent entries of UniqueFragments structure for next loop cycle
    51255198      Free((void **)&FragmentSearch.BondsPerSPCount, "molecule::PowerSetGenerator: *BondsPerSPCount");
     
    51275200        delete(FragmentSearch.BondsPerSPList[2*i]);
    51285201        delete(FragmentSearch.BondsPerSPList[2*i+1]);
    5129       } 
     5202      }
    51305203      Free((void **)&FragmentSearch.BondsPerSPList, "molecule::PowerSetGenerator: ***BondsPerSPList");
    51315204    }
     
    51385211  Free((void **)&FragmentSearch.ShortestPathList, "molecule::PowerSetGenerator: *ShortestPathList");
    51395212  delete(FragmentSearch.FragmentSet);
    5140  
    5141   // now, FragmentLowerOrdersList is complete, it looks - for BondOrder 5 - as this (number is the ANOVA Order of the terms therein) 
     5213
     5214  // now, FragmentLowerOrdersList is complete, it looks - for BondOrder 5 - as this (number is the ANOVA Order of the terms therein)
    51425215  // 5433222211111111
    51435216  // 43221111
     
    51595232    RootKeyNr = RootStack.front();
    51605233    RootStack.pop_front();
    5161     Walker = FindAtom(RootKeyNr); 
     5234    Walker = FindAtom(RootKeyNr);
    51625235    NumLevels = 1 << (Walker->AdaptiveOrder - 1);
    51635236    for(int i=0;i<NumLevels;i++) {
     
    51725245  Free((void **)&FragmentLowerOrdersList, "molecule::FragmentBOSSANOVA: ***FragmentLowerOrdersList");
    51735246  Free((void **)&NumMoleculesOfOrder, "molecule::FragmentBOSSANOVA: *NumMoleculesOfOrder");
    5174  
     5247
    51755248  *out << Verbose(0) << "End of FragmentBOSSANOVA." << endl;
    51765249};
     
    52065279  atom *Walker = NULL;
    52075280  bool result = true; // status of comparison
    5208  
    5209   *out << Verbose(3) << "Begin of IsEqualToWithinThreshold." << endl; 
     5281
     5282  *out << Verbose(3) << "Begin of IsEqualToWithinThreshold." << endl;
    52105283  /// first count both their atoms and elements and update lists thereby ...
    52115284  //*out << Verbose(0) << "Counting atoms, updating list" << endl;
     
    52545327    if (CenterOfGravity.Distance(&OtherCenterOfGravity) > threshold) {
    52555328      *out << Verbose(4) << "Centers of gravity don't match." << endl;
    5256       result = false; 
    5257     }
    5258   }
    5259  
     5329      result = false;
     5330    }
     5331  }
     5332
    52605333  /// ... then make a list with the euclidian distance to this center for each atom of both molecules
    52615334  if (result) {
     
    52735346      OtherDistances[Walker->nr] = OtherCenterOfGravity.Distance(&Walker->x);
    52745347    }
    5275  
     5348
    52765349    /// ... sort each list (using heapsort (o(N log N)) from GSL)
    52775350    *out << Verbose(5) << "Sorting distances" << endl;
     
    52845357    for(int i=AtomCount;i--;)
    52855358      PermutationMap[PermMap[i]] = (int) OtherPermMap[i];
    5286    
     5359
    52875360    /// ... and compare them step by step, whether the difference is individiually(!) below \a threshold for all
    52885361    *out << Verbose(4) << "Comparing distances" << endl;
     
    52955368    Free((void **)&PermMap, "molecule::IsEqualToWithinThreshold: *PermMap");
    52965369    Free((void **)&OtherPermMap, "molecule::IsEqualToWithinThreshold: *OtherPermMap");
    5297      
     5370
    52985371    /// free memory
    52995372    Free((void **)&Distances, "molecule::IsEqualToWithinThreshold: Distances");
     
    53035376      result = false;
    53045377    }
    5305   } 
     5378  }
    53065379  /// return pointer to map if all distances were below \a threshold
    53075380  *out << Verbose(3) << "End of IsEqualToWithinThreshold." << endl;
     
    53125385    *out << Verbose(3) << "Result: Not equal." << endl;
    53135386    return NULL;
    5314   } 
     5387  }
    53155388};
    53165389
     
    53675440 * \param *output output stream of temperature file
    53685441 * \return file written (true), failure on writing file (false)
    5369  */ 
     5442 */
    53705443bool molecule::OutputTemperatureFromTrajectories(ofstream *out, int startstep, int endstep, ofstream *output)
    53715444{
     
    53755448  if (output == NULL)
    53765449    return false;
    5377   else 
     5450  else
    53785451    *output << "# Step Temperature [K] Temperature [a.u.]" << endl;
    53795452  for (int step=startstep;step < endstep; step++) { // loop over all time steps
  • src/molecules.hpp

    • Property mode changed from 100644 to 100755
    rfcbfc8 r631dcb  
    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
     
    5656#define BoundariesTestPair pair< Boundaries::iterator, bool>
    5757
    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 < LinePair::iterator, bool >
    65 
    66 #define TriangleMap map < int, class BoundaryTriangleSet * > 
    67 #define TrianglePair pair < int, class BoundaryTriangleSet * > 
    68 #define TriangleTestPair pair < TrianglePair::iterator, bool > 
     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 >
    6969
    7070#define DistanceMultiMap multimap <double, pair < PointMap::iterator, PointMap::iterator> >
     
    8888//bool operator < (KeySet SubgraphA, KeySet SubgraphB);   //note: this declaration is important, otherwise normal < is used (producing wrong order)
    8989inline 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 
     90inline void InsertGraphIntoGraph(ofstream *out, Graph &graph1, Graph &graph2, int *counter);  // Insert all KeySet's in a Graph into another Graph
    9191int CompareDoubles (const void * a, const void * b);
    9292
     
    142142    unsigned char AdaptiveOrder;  //!< current present bond order at site (0 means "not set")
    143143    bool MaxOrder;  //!< whether this atom as a root in fragmentation still creates more fragments on higher orders or not
    144  
     144
    145145  atom();
    146146  ~atom();
    147  
     147
    148148  bool Output(int ElementNo, int AtomNo, ofstream *out) const;
    149149  bool OutputXYZLine(ofstream *out) const;
    150150  atom *GetTrueFather();
    151151  bool Compare(atom &ptr);
    152  
     152
    153153  private:
    154154};
     
    171171    int nr;           //!< unique number in a molecule, updated by molecule::CreateAdjacencyList()
    172172    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        
     173    enum EdgeType Type;//!< whether this is a tree or back edge
     174
    175175  atom * GetOtherAtom(atom *Atom) const;
    176176  bond * GetFirstBond();
    177177  bond * GetLastBond();
    178  
     178
    179179  bool MarkUsed(enum Shading color);
    180180  enum Shading IsUsed();
     
    182182  bool Contains(const atom *ptr);
    183183  bool Contains(const int nr);
    184  
     184
    185185  bond();
    186186  bond(atom *left, atom *right);
     
    188188  bond(atom *left, atom *right, int degree, int number);
    189189  ~bond();
    190    
    191   private: 
     190
     191  private:
    192192    enum Shading Used;        //!< marker in depth-first search, DepthFirstSearchAnalysis()
    193193};
     
    226226    int NoCyclicBonds;  //!< number of cyclic bonds in molecule, by DepthFirstSearchAnalysis()
    227227    double BondDistance;  //!< typical bond distance used in CreateAdjacencyList() and furtheron
    228  
     228
    229229  molecule(periodentafel *teil);
    230230  ~molecule();
    231  
     231
    232232  /// remove atoms from molecule.
    233233  bool AddAtom(atom *pointer);
     
    238238  atom * AddCopyAtom(atom *pointer);
    239239  bool AddXYZFile(string filename);
    240   bool AddHydrogenReplacementAtom(ofstream *out, bond *Bond, atom *BottomOrigin, atom *TopOrigin, atom *TopReplacement, bond **BondList, int NumBond, bool IsAngstroem); 
     240  bool AddHydrogenReplacementAtom(ofstream *out, bond *Bond, atom *BottomOrigin, atom *TopOrigin, atom *TopReplacement, bond **BondList, int NumBond, bool IsAngstroem);
    241241  bond * AddBond(atom *first, atom *second, int degree);
    242242  bool RemoveBond(bond *pointer);
    243243  bool RemoveBonds(atom *BondPartner);
    244    
     244
    245245  /// Find atoms.
    246   atom * FindAtom(int Nr) const; 
     246  atom * FindAtom(int Nr) const;
    247247  atom * AskAtom(string text);
    248248
     
    252252  void CalculateOrbitals(class config &configuration);
    253253  bool CenterInBox(ofstream *out, Vector *BoxLengths);
    254   void CenterEdge(ofstream *out, Vector *max); 
    255   void CenterOrigin(ofstream *out, Vector *max); 
     254  void CenterEdge(ofstream *out, Vector *max);
     255  void CenterOrigin(ofstream *out, Vector *max);
    256256  void CenterGravity(ofstream *out, Vector *max);
    257257  void Translate(const Vector *x);
     
    268268        double VolumeOfConvexEnvelope(ofstream *out, bool IsAngstroem);
    269269       
    270         bool VerletForceIntegration(ofstream *out, char *file, config &configuration);
     270  bool VerletForceIntegration(ofstream *out, char *file, config &configuration);
    271271  void Thermostats(config &configuration, double ActualTemp, int Thermostat);
    272272
    273273  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);
     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);
    277277       
    278278  bool CheckBounds(const Vector *x) const;
    279279  void GetAlignvector(struct lsq_params * par) const;
    280280
    281   /// Initialising routines in fragmentation 
     281  /// Initialising routines in fragmentation
     282  void CreateAdjacencyList2(ofstream *out, ifstream *output);
    282283  void CreateAdjacencyList(ofstream *out, double bonddistance, bool IsAngstroem);
    283284  void CreateListOfBondsPerAtom(ofstream *out);
    284  
     285
    285286  // Graph analysis
    286287  MoleculeLeafClass * DepthFirstSearchAnalysis(ofstream *out, class StackClass<bond *> *&BackEdgeStack);
     
    298299
    299300  molecule *CopyMolecule();
    300  
     301
    301302  /// Fragment molecule by two different approaches:
    302303  int FragmentMolecule(ofstream *out, int Order, config *configuration);
     
    320321  int LookForRemovalCandidate(ofstream *&out, KeySet *&Leaf, int *&ShortestPathList);
    321322  int GuesstimateFragmentCount(ofstream *out, int order);
    322          
    323   // Recognize doubly appearing molecules in a list of them   
     323
     324  // Recognize doubly appearing molecules in a list of them
    324325  int * IsEqualToWithinThreshold(ofstream *out, molecule *OtherMolecule, double threshold);
    325326  int * GetFatherSonAtomicMap(ofstream *out, molecule *OtherMolecule);
    326        
     327
    327328  // Output routines.
    328329  bool Output(ofstream *out);
     
    345346    int NumberOfMolecules;        //!< Number of entries in \a **FragmentList and of to be returned one.
    346347    int NumberOfTopAtoms;         //!< Number of atoms in the molecule from which all fragments originate
    347    
     348
    348349  MoleculeListClass();
    349350  MoleculeListClass(int Num, int NumAtoms);
     
    355356  bool OutputConfigForListOfFragments(ofstream *out, const char *fragmentprefix, config *configuration, int *SortIndex, bool DoPeriodic, bool DoCentering);
    356357  void Output(ofstream *out);
    357  
     358
    358359  private:
    359360};
     
    365366class MoleculeLeafClass {
    366367  public:
    367     molecule *Leaf;                   //!< molecule of this leaf 
     368    molecule *Leaf;                   //!< molecule of this leaf
    368369    //MoleculeLeafClass *UpLeaf;        //!< Leaf one level up
    369370    //MoleculeLeafClass *DownLeaf;      //!< First leaf one level down
     
    401402    bool FastParsing;
    402403    double Deltat;
     404    string basis;
     405
    403406    int DoConstrainedMD;
    404407    int MaxOuterStep;
     
    416419    char *defaultpath;
    417420    char *pseudopotpath;
    418    
     421
    419422    int DoOutVis;
    420423    int DoOutMes;
     
    431434    int UseAddGramSch;
    432435    int Seed;
    433    
     436
    434437    int OutVisStep;
    435438    int OutSrcStep;
    436439    int MaxPsiStep;
    437440    double EpsWannier;
    438    
     441
    439442    int MaxMinStep;
    440443    double RelEpsTotalEnergy;
     
    445448    double InitRelEpsKineticEnergy;
    446449    int InitMaxMinGapStopStep;
    447    
     450
    448451    //double BoxLength[NDIM*NDIM];
    449    
     452
    450453    double ECut;
    451454    int MaxLevel;
     
    456459    int RTActualUse;
    457460    int AddPsis;
    458    
     461
    459462    double RCut;
    460463    int StructOpt;
     
    463466    int MaxTypes;
    464467
    465  
     468
    466469  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);
    467  
     470
    468471  public:
    469472  config();
     
    474477  void LoadOld(char *filename, periodentafel *periode, molecule *mol);
    475478  void RetrieveConfigPathAndName(string filename);
    476   bool Save(ofstream *file, periodentafel *periode, molecule *mol) const;
    477   bool SaveMPQC(ofstream *file, molecule *mol) const;
     479  bool Save(const char *filename, periodentafel *periode, molecule *mol) const;
     480  bool SaveMPQC(const char *filename, molecule *mol) const;
    478481  void Edit(molecule *mol);
    479482  bool GetIsAngstroem() const;
  • src/orbitals.db

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

    • Property mode changed from 100644 to 100755
    rfcbfc8 r631dcb  
    5656MatrixContainer::MatrixContainer() {
    5757  Indices = NULL;
    58   Header = (char *) Malloc(sizeof(char)*1023, "MatrixContainer::MatrixContainer: *Header");
     58  Header = (char **) Malloc(sizeof(char)*1, "MatrixContainer::MatrixContainer: **Header");
    5959  Matrix = (double ***) Malloc(sizeof(double **)*(1), "MatrixContainer::MatrixContainer: ***Matrix"); // one more each for the total molecule
    6060  RowCounter = (int *) Malloc(sizeof(int)*(1), "MatrixContainer::MatrixContainer: *RowCounter");
     61  ColumnCounter = (int *) Malloc(sizeof(int)*(1), "MatrixContainer::MatrixContainer: *ColumnCounter");
     62  Header[0] = NULL;
    6163  Matrix[0] = NULL;
    6264  RowCounter[0] = -1;
    6365  MatrixCounter = 0;
    64   ColumnCounter = 0;
     66  ColumnCounter[0] = -1;
    6567};
    6668
     
    7072  if (Matrix != NULL) {
    7173    for(int i=MatrixCounter;i--;) {
    72       if (RowCounter != NULL) {
     74      if ((ColumnCounter != NULL) && (RowCounter != NULL)) {
    7375          for(int j=RowCounter[i]+1;j--;)
    7476            Free((void **)&Matrix[i][j], "MatrixContainer::~MatrixContainer: *Matrix[][]");
     
    7678      }
    7779    }
    78     if ((RowCounter != NULL) && (Matrix[MatrixCounter] != NULL))
     80    if ((ColumnCounter != NULL) && (RowCounter != NULL) && (Matrix[MatrixCounter] != NULL))
    7981      for(int j=RowCounter[MatrixCounter]+1;j--;)
    8082        Free((void **)&Matrix[MatrixCounter][j], "MatrixContainer::~MatrixContainer: *Matrix[MatrixCounter][]");
     
    8991  Free((void **)&Indices, "MatrixContainer::~MatrixContainer: **Indices");
    9092 
    91   Free((void **)&Header, "MatrixContainer::~MatrixContainer: *Header");
     93  if (Header != NULL)
     94    for(int i=MatrixCounter+1;i--;)
     95      Free((void **)&Header[i], "MatrixContainer::~MatrixContainer: *Header[]");
     96  Free((void **)&Header, "MatrixContainer::~MatrixContainer: **Header");
    9297  Free((void **)&RowCounter, "MatrixContainer::~MatrixContainer: *RowCounter");
    93 };
    94 
     98  Free((void **)&ColumnCounter, "MatrixContainer::~MatrixContainer: *RowCounter");
     99};
     100
     101/** Either copies index matrix from another MatrixContainer or initialises with trivial mapping if NULL.
     102 * This either copies the index matrix or just maps 1 to 1, 2 to 2 and so on for all fragments.
     103 * \param *Matrix pointer to other MatrixContainer
     104 * \return true - copy/initialisation sucessful, false - dimension false for copying
     105 */
     106bool MatrixContainer::InitialiseIndices(class MatrixContainer *Matrix)
     107{
     108  cout << "Initialising indices";
     109  if (Matrix == NULL) {
     110    cout << " with trivial mapping." << endl;
     111    Indices = (int **) Malloc(sizeof(int *)*(MatrixCounter+1), "MatrixContainer::InitialiseIndices: **Indices");
     112    for(int i=MatrixCounter+1;i--;) {
     113      Indices[i] = (int *) Malloc(sizeof(int)*RowCounter[i], "MatrixContainer::InitialiseIndices: *Indices[]");
     114      for(int j=RowCounter[i];j--;)
     115        Indices[i][j] = j;
     116    }
     117  } else {
     118    cout << " from other MatrixContainer." << endl;
     119    if (MatrixCounter != Matrix->MatrixCounter)
     120      return false;
     121    Indices = (int **) Malloc(sizeof(int *)*(MatrixCounter+1), "MatrixContainer::InitialiseIndices: **Indices");
     122    for(int i=MatrixCounter+1;i--;) {
     123      if (RowCounter[i] != Matrix->RowCounter[i])
     124        return false;
     125      Indices[i] = (int *) Malloc(sizeof(int)*Matrix->RowCounter[i], "MatrixContainer::InitialiseIndices: *Indices[]");
     126      for(int j=Matrix->RowCounter[i];j--;) {
     127        Indices[i][j] = Matrix->Indices[i][j];
     128        //cout << Indices[i][j] << "\t";
     129      }
     130      //cout << endl;
     131    }
     132  }
     133  return true;
     134};
    95135
    96136/** Parsing a number of matrices.
     
    120160    return false;
    121161  }
    122  
    123   // skip some initial lines
     162
     163  // parse header
     164  Header[MatrixNr] = (char *) Malloc(sizeof(char)*1024, "MatrixContainer::ParseMatrix: *Header[]");
    124165  for (int m=skiplines+1;m--;)
    125     input.getline(Header, 1023);
     166    input.getline(Header[MatrixNr], 1023);
    126167 
    127168  // scan header for number of columns
    128   line.str(Header);
     169  line.str(Header[MatrixNr]);
    129170  for(int k=skipcolumns;k--;)
    130     line >> Header;
     171    line >> Header[MatrixNr];
    131172  //cout << line.str() << endl;
    132   ColumnCounter=0;
     173  ColumnCounter[MatrixNr]=0;
    133174  while ( getline(line,token, '\t') ) {
    134175    if (token.length() > 0)
    135       ColumnCounter++;
     176      ColumnCounter[MatrixNr]++;
    136177  }
    137178  //cout << line.str() << endl;
    138   //cout << "ColumnCounter: " << ColumnCounter << "." << endl;
    139   if (ColumnCounter == 0)
    140     cerr << "ColumnCounter: " << ColumnCounter << " from file " << name << ", this is probably an error!" << endl;
     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;
    141182 
    142183  // scan rest for number of rows/lines
     
    155196 
    156197  // allocate matrix if it's not zero dimension in one direction
    157   if ((ColumnCounter > 0) && (RowCounter[MatrixNr] > -1)) {
    158     Matrix[MatrixNr] = (double **) Malloc(sizeof(double *)*(RowCounter[MatrixNr]+1), "MatrixContainer::ParseFragmentMatrix: **Matrix[]");
     198  if ((ColumnCounter[MatrixNr] > 0) && (RowCounter[MatrixNr] > -1)) {
     199    Matrix[MatrixNr] = (double **) Malloc(sizeof(double *)*(RowCounter[MatrixNr]+1), "MatrixContainer::ParseMatrix: **Matrix[]");
    159200 
    160201    // parse in each entry for this matrix
     
    162203    input.seekg(ios::beg);
    163204    for (int m=skiplines+1;m--;)
    164       input.getline(Header, 1023);    // skip header
    165     line.str(Header);
     205      input.getline(Header[MatrixNr], 1023);    // skip header
     206    line.str(Header[MatrixNr]);
    166207    for(int k=skipcolumns;k--;)  // skip columns in header too
    167208      line >> filename;
    168     strncpy(Header, line.str().c_str(), 1023); 
     209    strncpy(Header[MatrixNr], line.str().c_str(), 1023); 
    169210    for(int j=0;j<RowCounter[MatrixNr];j++) {
    170       Matrix[MatrixNr][j] = (double *) Malloc(sizeof(double)*ColumnCounter, "MatrixContainer::ParseFragmentMatrix: *Matrix[][]");
     211      Matrix[MatrixNr][j] = (double *) Malloc(sizeof(double)*ColumnCounter[MatrixNr], "MatrixContainer::ParseMatrix: *Matrix[][]");
    171212      input.getline(filename, 1023);
    172213      stringstream lines(filename);
     
    174215      for(int k=skipcolumns;k--;)
    175216        lines >> filename;
    176       for(int k=0;(k<ColumnCounter) && (!lines.eof());k++) {
     217      for(int k=0;(k<ColumnCounter[MatrixNr]) && (!lines.eof());k++) {
    177218        lines >> Matrix[MatrixNr][j][k];
    178219        //cout << " " << setprecision(2) << Matrix[MatrixNr][j][k];;
    179220      }
    180221      //cout << endl;
    181       Matrix[MatrixNr][ RowCounter[MatrixNr] ] = (double *) Malloc(sizeof(double)*ColumnCounter, "MatrixContainer::ParseFragmentMatrix: *Matrix[RowCounter[MatrixNr]][]");
    182       for(int j=ColumnCounter;j--;)
     222      Matrix[MatrixNr][ RowCounter[MatrixNr] ] = (double *) Malloc(sizeof(double)*ColumnCounter[MatrixNr], "MatrixContainer::ParseMatrix: *Matrix[RowCounter[MatrixNr]][]");
     223      for(int j=ColumnCounter[MatrixNr];j--;)
    183224        Matrix[MatrixNr][ RowCounter[MatrixNr] ][j] = 0.;
    184225    }
    185226  } else {
    186     cerr << "ERROR: Matrix nr. " << MatrixNr << " has column and row count of (" << ColumnCounter << "," << RowCounter[MatrixNr] << "), could not allocate nor parse!" << endl;
     227    cerr << "ERROR: Matrix nr. " << MatrixNr << " has column and row count of (" << ColumnCounter[MatrixNr] << "," << RowCounter[MatrixNr] << "), could not allocate nor parse!" << endl;
    187228  }
    188229  input.close();
     
    233274 
    234275  cout << "Parsing through each fragment and retrieving " << prefix << suffix << "." << endl;
     276  Header = (char **) ReAlloc(Header, sizeof(char *)*(MatrixCounter+1), "MatrixContainer::ParseFragmentMatrix: **Header"); // one more each for the total molecule
    235277  Matrix = (double ***) ReAlloc(Matrix, sizeof(double **)*(MatrixCounter+1), "MatrixContainer::ParseFragmentMatrix: ***Matrix"); // one more each for the total molecule
    236278  RowCounter = (int *) ReAlloc(RowCounter, sizeof(int)*(MatrixCounter+1), "MatrixContainer::ParseFragmentMatrix: *RowCounter");
     279  ColumnCounter = (int *) ReAlloc(ColumnCounter, sizeof(int)*(MatrixCounter+1), "MatrixContainer::ParseFragmentMatrix: *ColumnCounter");
    237280  for(int i=MatrixCounter+1;i--;) {
    238281    Matrix[i] = NULL;
     282    Header[i] = NULL;
    239283    RowCounter[i] = -1;
     284    ColumnCounter[i] = -1;
    240285  }
    241286  for(int i=0; i < MatrixCounter;i++) {
     
    252297
    253298/** Allocates and resets the memory for a number \a MCounter of matrices.
    254  * \param *GivenHeader Header line
     299 * \param **GivenHeader Header line for each matrix
    255300 * \param MCounter number of matrices
    256301 * \param *RCounter number of rows for each matrix
    257  * \param CCounter number of columns for all matrices
     302 * \param *CCounter number of columns for each matrix
    258303 * \return Allocation successful
    259304 */
    260 bool 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 
     305bool MatrixContainer::AllocateMatrix(char **GivenHeader, int MCounter, int *RCounter, int *CCounter)
     306{
    265307  MatrixCounter = MCounter;
    266   ColumnCounter = CCounter;
    267   Matrix = (double ***) Malloc(sizeof(double **)*(MatrixCounter+1), "MatrixContainer::ParseFragmentMatrix: ***Matrix"); // one more each for the total molecule
    268   RowCounter = (int *) Malloc(sizeof(int)*(MatrixCounter+1), "MatrixContainer::ParseFragmentMatrix: *RowCounter");
     308  Header = (char **) Malloc(sizeof(char *)*(MatrixCounter+1), "MatrixContainer::AllocateMatrix: *Header");
     309  Matrix = (double ***) Malloc(sizeof(double **)*(MatrixCounter+1), "MatrixContainer::AllocateMatrix: ***Matrix"); // one more each for the total molecule
     310  RowCounter = (int *) Malloc(sizeof(int)*(MatrixCounter+1), "MatrixContainer::AllocateMatrix: *RowCounter");
     311  ColumnCounter = (int *) Malloc(sizeof(int)*(MatrixCounter+1), "MatrixContainer::AllocateMatrix: *ColumnCounter");
    269312  for(int i=MatrixCounter+1;i--;) {
     313    Header[i] = (char *) Malloc(sizeof(char)*1024, "MatrixContainer::AllocateMatrix: *Header[i]");
     314    strncpy(Header[i], GivenHeader[i], 1023);
    270315    RowCounter[i] = RCounter[i];
    271     Matrix[i] = (double **) Malloc(sizeof(double *)*(RowCounter[i]+1), "MatrixContainer::ParseFragmentMatrix: **Matrix[]"); 
     316    ColumnCounter[i] = CCounter[i];
     317    Matrix[i] = (double **) Malloc(sizeof(double *)*(RowCounter[i]+1), "MatrixContainer::AllocateMatrix: **Matrix[]"); 
    272318    for(int j=RowCounter[i]+1;j--;) {
    273       Matrix[i][j] = (double *) Malloc(sizeof(double)*ColumnCounter, "MatrixContainer::ParseFragmentMatrix: *Matrix[][]");
    274       for(int k=ColumnCounter;k--;)
     319      Matrix[i][j] = (double *) Malloc(sizeof(double)*ColumnCounter[i], "MatrixContainer::AllocateMatrix: *Matrix[][]");
     320      for(int k=ColumnCounter[i];k--;)
    275321        Matrix[i][j][k] = 0.;
    276322    }
     
    286332  for(int i=MatrixCounter+1;i--;)
    287333    for(int j=RowCounter[i]+1;j--;)
    288       for(int k=ColumnCounter;k--;)
     334      for(int k=ColumnCounter[i];k--;)
    289335        Matrix[i][j][k] = 0.;
    290336   return true;
     
    299345  for(int i=MatrixCounter+1;i--;)
    300346    for(int j=RowCounter[i]+1;j--;)
    301       for(int k=ColumnCounter;k--;)
     347      for(int k=ColumnCounter[i];k--;)
    302348        if (fabs(Matrix[i][j][k]) > max)
    303349          max = fabs(Matrix[i][j][k]);
     
    315361  for(int i=MatrixCounter+1;i--;)
    316362    for(int j=RowCounter[i]+1;j--;)
    317       for(int k=ColumnCounter;k--;)
     363      for(int k=ColumnCounter[i];k--;)
    318364        if (fabs(Matrix[i][j][k]) < min)
    319365          min = fabs(Matrix[i][j][k]);
     
    331377{
    332378  for(int j=RowCounter[MatrixCounter]+1;j--;)
    333     for(int k=skipcolumns;k<ColumnCounter;k++)
     379    for(int k=skipcolumns;k<ColumnCounter[MatrixCounter];k++)
    334380      Matrix[MatrixCounter][j][k] = value;
    335381   return true;
     
    344390{
    345391  for(int j=RowCounter[MatrixCounter]+1;j--;)
    346     for(int k=skipcolumns;k<ColumnCounter;k++)
     392    for(int k=skipcolumns;k<ColumnCounter[MatrixCounter];k++)
    347393      Matrix[MatrixCounter][j][k] = values[j][k];
    348394   return true;
    349395};
    350396
    351 /** Sums the energy with each factor and put into last element of \a ***Energies.
     397/** Sums the entries with each factor and put into last element of \a ***Matrix.
    352398 * Sums over "E"-terms to create the "F"-terms
    353  * \param Matrix MatrixContainer with matrices (LevelCounter by ColumnCounter) with all the energies.
     399 * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies.
    354400 * \param KeySet KeySetContainer with bond Order and association mapping of each fragment to an order
    355401 * \param Order bond order
     
    384430              }
    385431              if (Order == SubOrder) { // equal order is always copy from Energies
    386                 for(int l=ColumnCounter;l--;) // then adds/subtract each column
     432                for(int l=ColumnCounter[ KeySet.OrderSet[SubOrder][j] ];l--;) // then adds/subtract each column
    387433                  Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][m][l] += MatrixValues.Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l];
    388434              } else {
    389                 for(int l=ColumnCounter;l--;)
     435                for(int l=ColumnCounter[ KeySet.OrderSet[SubOrder][j] ];l--;)
    390436                  Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][m][l] -= Matrix[ KeySet.OrderSet[SubOrder][j] ][k][l];
    391437              }
    392438            }
    393             //if ((ColumnCounter>1) && (RowCounter[0]-1 >= 1))
     439            //if ((ColumnCounter[ KeySet.OrderSet[SubOrder][j] ]>1) && (RowCounter[0]-1 >= 1))
    394440             //cout << "Fragments[ KeySet.OrderSet[" << Order << "][" << CurrentFragment << "]=" << KeySet.OrderSet[Order][CurrentFragment] << " ][" << RowCounter[0]-1 << "][" << 1 << "] = " <<  Matrix[ KeySet.OrderSet[Order][CurrentFragment] ][RowCounter[0]-1][1] << endl;
    395441          }
     
    426472      return false;
    427473    }
    428     output << Header << endl;
     474    output << Header[i] << endl;
    429475    for(int j=0;j<RowCounter[i];j++) {
    430       for(int k=0;k<ColumnCounter;k++)
     476      for(int k=0;k<ColumnCounter[i];k++)
    431477        output << scientific << Matrix[i][j][k] << "\t";
    432478      output << endl;
     
    455501    return false;
    456502  }
    457   output << Header << endl;
     503  output << Header[MatrixCounter] << endl;
    458504  for(int j=0;j<RowCounter[MatrixCounter];j++) {
    459     for(int k=0;k<ColumnCounter;k++)
     505    for(int k=0;k<ColumnCounter[MatrixCounter];k++)
    460506      output << scientific << Matrix[MatrixCounter][j][k] << "\t";
    461507    output << endl;
     
    467513// ======================================= CLASS EnergyMatrix =============================
    468514
    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  */
    473 bool 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 
    485515/** Sums the energy with each factor and put into last element of \a EnergyMatrix::Matrix.
    486516 * Sums over the "F"-terms in ANOVA decomposition.
    487  * \param Matrix MatrixContainer with matrices (LevelCounter by ColumnCounter) with all the energies.
     517 * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies.
    488518 * \param CorrectionFragments MatrixContainer with hydrogen saturation correction per fragments
    489519 * \param KeySet KeySetContainer with bond Order and association mapping of each fragment to an order
     
    498528    for(int i=KeySet.FragmentsPerOrder[Order];i--;)
    499529      for(int j=RowCounter[ KeySet.OrderSet[Order][i] ];j--;)
    500         for(int k=ColumnCounter;k--;)
     530        for(int k=ColumnCounter[ KeySet.OrderSet[Order][i] ];k--;)
    501531          Matrix[MatrixCounter][j][k] += sign*Fragments.Matrix[ KeySet.OrderSet[Order][i] ][j][k];
    502532  else
    503533    for(int i=KeySet.FragmentsPerOrder[Order];i--;)
    504534      for(int j=RowCounter[ KeySet.OrderSet[Order][i] ];j--;)
    505         for(int k=ColumnCounter;k--;)
     535        for(int k=ColumnCounter[ KeySet.OrderSet[Order][i] ];k--;)
    506536          Matrix[MatrixCounter][j][k] += sign*(Fragments.Matrix[ KeySet.OrderSet[Order][i] ][j][k] + CorrectionFragments->Matrix[ KeySet.OrderSet[Order][i] ][j][k]);
    507537  return true;
     
    524554    // count maximum of columns
    525555    RowCounter[MatrixCounter] = 0;
    526     for(int j=0; j < MatrixCounter;j++) // (energy matrix might be bigger than number of atoms in terms of rows)
     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)
    527558      if (RowCounter[j] > RowCounter[MatrixCounter])
    528559        RowCounter[MatrixCounter] = RowCounter[j];
     560      if (ColumnCounter[j] > ColumnCounter[MatrixCounter])  // take maximum of all for last matrix
     561        ColumnCounter[MatrixCounter] = ColumnCounter[j];
     562    }
    529563    // allocate last plus one matrix
    530     cout << "Allocating last plus one matrix with " << (RowCounter[MatrixCounter]+1) << " rows and " << ColumnCounter << " columns." << endl;
     564    cout << "Allocating last plus one matrix with " << (RowCounter[MatrixCounter]+1) << " rows and " << ColumnCounter[MatrixCounter] << " columns." << endl;
    531565    Matrix[MatrixCounter] = (double **) Malloc(sizeof(double *)*(RowCounter[MatrixCounter]+1), "MatrixContainer::ParseFragmentMatrix: **Matrix[]");
    532566    for(int j=0;j<=RowCounter[MatrixCounter];j++)
    533       Matrix[MatrixCounter][j] = (double *) Malloc(sizeof(double)*ColumnCounter, "MatrixContainer::ParseFragmentMatrix: *Matrix[][]");
     567      Matrix[MatrixCounter][j] = (double *) Malloc(sizeof(double)*ColumnCounter[MatrixCounter], "MatrixContainer::ParseFragmentMatrix: *Matrix[][]");
    534568   
    535569    // try independently to parse global energysuffix file if present
     
    589623
    590624/** Sums the forces and puts into last element of \a ForceMatrix::Matrix.
    591  * \param Matrix MatrixContainer with matrices (LevelCounter by ColumnCounter) with all the energies.
     625 * \param Matrix MatrixContainer with matrices (LevelCounter by *ColumnCounter) with all the energies.
    592626 * \param KeySet KeySetContainer with bond Order and association mapping of each fragment to an order
    593627 * \param Order bond order
     
    609643      if (j != -1) {
    610644        //if (j == 0) cout << "Summing onto ion 0, type 0 from fragment " << FragmentNr << ", ion " << l << "." << endl;
    611         for(int k=2;k<ColumnCounter;k++)
     645        for(int k=2;k<ColumnCounter[MatrixCounter];k++)
    612646          Matrix[MatrixCounter][j][k] += sign*Fragments.Matrix[ FragmentNr ][l][k];
    613647      }
     
    655689    RowCounter[MatrixCounter]++;    // nr start at 0, count starts at 1
    656690    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    }
    657697 
    658698    // allocate last plus one matrix
    659     cout << "Allocating last plus one matrix with " << (RowCounter[MatrixCounter]+1) << " rows and " << ColumnCounter << " columns." << endl;
     699    cout << "Allocating last plus one matrix with " << (RowCounter[MatrixCounter]+1) << " rows and " << ColumnCounter[MatrixCounter] << " columns." << endl;
    660700    Matrix[MatrixCounter] = (double **) Malloc(sizeof(double *)*(RowCounter[MatrixCounter]+1), "MatrixContainer::ParseFragmentMatrix: **Matrix[]");
    661701    for(int j=0;j<=RowCounter[MatrixCounter];j++)
    662       Matrix[MatrixCounter][j] = (double *) Malloc(sizeof(double)*ColumnCounter, "MatrixContainer::ParseFragmentMatrix: *Matrix[][]");
     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 */
     721bool 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 */
     768bool 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 */
     800HessianMatrix::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 */
     812bool 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 */
     888bool 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[][]");
    663927
    664928    // try independently to parse global forcesuffix file if present
  • src/parser.hpp

    • Property mode changed from 100644 to 100755
    rfcbfc8 r631dcb  
    1919
    2020#define EnergySuffix ".energy.all"
     21#define EnergyFragmentSuffix ".energyfragment.all"
     22#define ForcesSuffix ".forces.all"
     23#define ForceFragmentSuffix ".forcefragment.all"
    2124#define HcorrectionSuffix ".Hcorrection.all"
    22 #define ForcesSuffix ".forces.all"
     25#define HcorrectionFragmentSuffix ".Hcorrectionfragment.all"
     26#define HessianSuffix ".hessian_xx.all"
     27#define HessianFragmentSuffix ".hessianfragment_xx.all"
     28#define OrderSuffix ".Order"
    2329#define ShieldingSuffix ".sigma_all.csv"
    2430#define ShieldingPASSuffix ".sigma_all_PAS.csv"
    2531#define ShieldingFragmentSuffix ".sigma_all_fragment.all"
    2632#define ShieldingPASFragmentSuffix ".sigma_all_PAS_fragment.all"
     33#define ChiSuffix ".chi_all.csv"
     34#define ChiPASSuffix ".chi_all_PAS.csv"
     35#define ChiFragmentSuffix ".chi_all_fragment.all"
     36#define ChiPASFragmentSuffix ".chi_all_PAS_fragment.all"
    2737#define TimeSuffix ".speed"
    28 #define EnergyFragmentSuffix ".energyfragment.all"
    29 #define HcorrectionFragmentSuffix ".Hcorrectionfragment.all"
    30 #define ForceFragmentSuffix ".forcefragment.all"
    31 #define OrderSuffix ".Order"
    3238
    3339// ======================================= FUNCTIONS ==========================================
     
    4349    double ***Matrix;
    4450    int **Indices;
    45     char *Header;
     51    char **Header;
    4652    int MatrixCounter;
    4753    int *RowCounter;
    48     int ColumnCounter;
     54    int *ColumnCounter;
    4955 
    5056  MatrixContainer();
    5157  ~MatrixContainer();
    5258 
     59  bool InitialiseIndices(class MatrixContainer *Matrix = NULL);
    5360  bool ParseMatrix(const char *name, int skiplines, int skipcolumns, int MatrixNr);
    5461  virtual bool ParseFragmentMatrix(char *name, char *prefix, string suffix, int skiplines, int skipcolumns);
    55   bool AllocateMatrix(char *GivenHeader, int MCounter, int *RCounter, int CCounter);
     62  bool AllocateMatrix(char **GivenHeader, int MCounter, int *RCounter, int *CCounter);
    5663  bool ResetMatrix();
    5764  double FindMinValue();
     
    7077class EnergyMatrix : public MatrixContainer {
    7178  public:
    72     bool ParseIndices();
    7379    bool SumSubEnergy(class EnergyMatrix &Fragments, class EnergyMatrix *CorrectionFragments, class KeySetsContainer &KeySet, int Order, double sign);
    7480    bool ParseFragmentMatrix(char *name, char *prefix, string suffix, int skiplines, int skipcolumns);
     
    8288    bool SumSubForces(class ForceMatrix &Fragments, class KeySetsContainer &KeySet, int Order, double sign);
    8389    bool ParseFragmentMatrix(char *name, char *prefix, string suffix, int skiplines, int skipcolumns);
     90};
     91
     92// ======================================= CLASS HessianMatrix =============================
     93
     94class 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;
    84104};
    85105
  • src/periodentafel.cpp

    • Property mode changed from 100644 to 100755
    rfcbfc8 r631dcb  
    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 
    120119/** Prints period table to given stream.
    121120 * \param output stream
    122  */ 
     121 */
    123122bool periodentafel::Output(ofstream *output) const
    124123{
     
    131130    }
    132131    return result;
    133   } else 
     132  } else
    134133    return false;
    135134};
     
    138137 * \param *output output stream
    139138 * \param *checkliste elements table for this molecule
    140  */ 
     139 */
    141140bool periodentafel::Checkout(ofstream *output, const int *checkliste) const
    142141{
     
    152151      if ((walker != NULL) && (walker->Z > 0) && (walker->Z < MAX_ELEMENTS) && (checkliste[walker->Z])) {
    153152        walker->No = No;
    154         result = result && walker->Checkout(output, No++, checkliste[walker->Z]);     
     153        result = result && walker->Checkout(output, No++, checkliste[walker->Z]);
    155154      }
    156155    }
    157156    return result;
    158   } else 
     157  } else
    159158    return false;
    160159};
    161 
    162160
    163161/** Loads element list from file.
     
    171169  bool status = true;
    172170  bool otherstatus = true;
    173   char *filename = new char[MAXSTRINGSIZE];
    174  
     171  char filename[255];
     172
    175173  // fill elements DB
    176174  strncpy(filename, path, MAXSTRINGSIZE);
     
    225223  if (infile != NULL) {
    226224    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;
     225      infile >> tmp;
     226      infile >> ws;
     227      infile >> FindElement((int)tmp)->Valence;
     228      infile >> ws;
     229      //cout << Verbose(3) << "Element " << (int)tmp << " has " << FindElement((int)tmp)->Valence << " valence electrons." << endl;
    232230    }
    233231    infile.close();
     
    253251  } else
    254252    otherstatus = false;
    255  
     253
    256254  // fill H-BondDistance DB per element
    257255  strncpy(filename, path, MAXSTRINGSIZE);
     
    261259  if (infile != NULL) {
    262260    while (!infile.eof()) {
    263         infile >> tmp;
     261      infile >> tmp;
    264262      ptr = FindElement((int)tmp);
    265         infile >> ws;
     263      infile >> ws;
    266264      infile >> ptr->HBondDistance[0];
    267265      infile >> ptr->HBondDistance[1];
    268266      infile >> ptr->HBondDistance[2];
    269         infile >> ws;
     267      infile >> ws;
    270268      //cout << Verbose(3) << "Element " << (int)tmp << " has " << FindElement((int)tmp)->HBondDistance[0] << " Angstrom typical distance to hydrogen." << endl;
    271269    }
     
    274272  } else
    275273    otherstatus = false;
    276  
     274
    277275  // fill H-BondAngle DB per element
    278276  strncpy(filename, path, MAXSTRINGSIZE);
     
    294292  } else
    295293    otherstatus = false;
    296  
     294
    297295  if (!otherstatus)
    298     cerr << "ERROR: Something went wrong while parsing the databases!" << endl;
    299  
     296    cerr << "WARNING: Something went wrong while parsing the other databases!" << endl;
     297
    300298  return status;
    301299};
     
    308306  ofstream f;
    309307  char filename[MAXSTRINGSIZE];
    310  
     308
    311309  strncpy(filename, path, MAXSTRINGSIZE);
    312310  strncat(filename, "/", MAXSTRINGSIZE-strlen(filename));
  • src/periodentafel.hpp

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

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

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

    • Property mode changed from 100644 to 100755
    rfcbfc8 r631dcb  
    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 ************************************/
     
    2121 */
    2222Vector::~Vector() {};
     23
     24/** Calculates square of distance between this and another vector.
     25 * \param *y array to second vector
     26 * \return \f$| x - y |^2\f$
     27 */
     28double Vector::DistanceSquared(const Vector *y) const
     29{
     30  double res = 0.;
     31  for (int i=NDIM;i--;)
     32    res += (x[i]-y->x[i])*(x[i]-y->x[i]);
     33  return (res);
     34};
    2335
    2436/** Calculates distance between this and another vector.
    2537 * \param *y array to second vector
    26  * \return \f$| x - y |^2\f$
     38 * \return \f$| x - y |\f$
    2739 */
    2840double Vector::Distance(const Vector *y) const
     
    3143  for (int i=NDIM;i--;)
    3244    res += (x[i]-y->x[i])*(x[i]-y->x[i]);
    33   return (res); 
     45  return (sqrt(res));
    3446};
    3547
     
    6981        if (tmp < res) res = tmp;
    7082      }
    71   return (res); 
     83  return (res);
    7284};
    7385
     
    112124  for (int i=NDIM;i--;)
    113125    res += x[i]*y->x[i];
    114   return (res); 
    115 };
     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 */
     136void 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
    116146
    117147/** projects this vector onto plane defined by \a *y.
    118  * \param *y array to normal vector of plane
     148 * \param *y normal vector of plane
    119149 * \return \f$\langle x, y \rangle\f$
    120150 */
     
    123153  Vector tmp;
    124154  tmp.CopyVector(y);
    125   tmp.Scale(Projection(y));
     155  tmp.Normalize();
     156  tmp.Scale(ScalarProduct(&tmp));
    126157  this->SubtractVector(&tmp);
    127158};
     
    144175  for (int i=NDIM;i--;)
    145176    res += this->x[i]*this->x[i];
    146   return (sqrt(res)); 
     177  return (sqrt(res));
    147178};
    148179
     
    178209 */
    179210void Vector::Init(double x1, double x2, double x3)
    180 { 
     211{
    181212  x[0] = x1;
    182213  x[1] = x2;
     
    188219 * \return \f$\acos\bigl(frac{\langle x, y \rangle}{|x||y|}\bigr)\f$
    189220 */
    190 double Vector::Angle(Vector *y) const
    191 {
    192   return acos(this->ScalarProduct(y)/Norm()/y->Norm()); 
     221double Vector::Angle(const Vector *y) const
     222{
     223  return acos(this->ScalarProduct(y)/Norm()/y->Norm());
    193224};
    194225
     
    238269
    239270/** Sums two vectors \a  and \b component-wise.
    240  * \param a first vector 
     271 * \param a first vector
    241272 * \param b second vector
    242273 * \return a + b
     
    251282
    252283/** Factors given vector \a a times \a m.
    253  * \param a vector 
     284 * \param a vector
    254285 * \param m factor
    255286 * \return a + b
     
    282313};
    283314
    284 ofstream& operator<<(ofstream& ost,Vector& m)
    285 {
    286         m.Output(&ost);
     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 */
     320ostream& 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 << ")";
    287329        return ost;
    288330};
     
    309351};
    310352
    311 /** Translate atom by given vector. 
     353/** Translate atom by given vector.
    312354 * \param trans[] translation vector.
    313355 */
     
    316358  for (int i=NDIM;i--;)
    317359    x[i] += trans->x[i];
    318 }; 
     360};
    319361
    320362/** Do a matrix multiplication.
     
    355397    B[7] = -detAReci*RDET2(A[0],A[1],A[6],A[7]);    // A_32
    356398    B[8] =  detAReci*RDET2(A[0],A[1],A[3],A[4]);    // A_33
    357  
     399
    358400    // do the matrix multiplication
    359401    C.x[0] = B[0]*x[0]+B[3]*x[1]+B[6]*x[2];
     
    379421{
    380422  for(int i=NDIM;i--;)
    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. 
     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.
    385427 * \param n[] normal vector of mirror plane.
    386428 */
     
    398440  Output((ofstream *)&cout);
    399441  cout << endl;
    400 }; 
     442};
    401443
    402444/** Calculates normal vector for three given vectors (being three points in space).
     
    430472  this->x[2] = (x1.x[0]*x2.x[1] - x1.x[1]*x2.x[0]);
    431473  Normalize();
    432  
     474
    433475  return true;
    434476};
     
    488530/** Creates this vector as one of the possible orthonormal ones to the given one.
    489531 * Just scan how many components of given *vector are unequal to zero and
    490  * try to get the skp of both to be zero accordingly. 
     532 * try to get the skp of both to be zero accordingly.
    491533 * \param *vector given vector
    492534 * \return true - success, false - failure (null vector given)
     
    509551      Components[Last++] = j;
    510552  cout << Verbose(4) << Last << " Components != 0: (" << Components[0] << "," << Components[1] << "," << Components[2] << ")" << endl;
    511        
     553
    512554  switch(Last) {
    513555    case 3:  // threecomponent system
     
    522564    case 1: // one component system
    523565      // set sole non-zero component to 0, and one of the other zero component pendants to 1
    524       x[(Components[0]+2)%NDIM] = 0.;   
    525       x[(Components[0]+1)%NDIM] = 1.;   
    526       x[Components[0]] = 0.;   
     566      x[(Components[0]+2)%NDIM] = 0.;
     567      x[(Components[0]+1)%NDIM] = 1.;
     568      x[Components[0]] = 0.;
    527569      return true;
    528570      break;
     
    541583{
    542584//  cout << Verbose(3) << "For comparison: ";
    543 //  cout << "A " << A->Projection(this) << "\t"; 
    544 //  cout << "B " << B->Projection(this) << "\t"; 
    545 //  cout << "C " << C->Projection(this) << "\t"; 
     585//  cout << "A " << A->Projection(this) << "\t";
     586//  cout << "B " << B->Projection(this) << "\t";
     587//  cout << "C " << C->Projection(this) << "\t";
    546588//  cout << endl;
    547589  return A->Projection(this);
     
    553595 * \return true if success, false if failed due to linear dependency
    554596 */
    555 bool Vector::LSQdistance(Vector **vectors, int num) 
     597bool Vector::LSQdistance(Vector **vectors, int num)
    556598{
    557599        int j;
    558                                
     600
    559601        for (j=0;j<num;j++) {
    560602                cout << Verbose(1) << j << "th atom's vector: ";
     
    565607  int np = 3;
    566608        struct LSQ_params par;
    567    
     609
    568610   const gsl_multimin_fminimizer_type *T =
    569611     gsl_multimin_fminimizer_nmsimplex;
     
    571613   gsl_vector *ss, *y;
    572614   gsl_multimin_function minex_func;
    573  
     615
    574616   size_t iter = 0, i;
    575617   int status;
    576618   double size;
    577  
     619
    578620   /* Initial vertex size vector */
    579621   ss = gsl_vector_alloc (np);
    580622   y = gsl_vector_alloc (np);
    581  
     623
    582624   /* Set all step sizes to 1 */
    583625   gsl_vector_set_all (ss, 1.0);
    584  
     626
    585627   /* Starting point */
    586628   par.vectors = vectors;
    587629         par.num = num;
    588        
     630
    589631         for (i=NDIM;i--;)
    590                 gsl_vector_set(y, i, (vectors[0]->x[i] - vectors[1]->x[i])/2.); 
    591          
     632                gsl_vector_set(y, i, (vectors[0]->x[i] - vectors[1]->x[i])/2.);
     633
    592634   /* Initialize method and iterate */
    593635   minex_func.f = &LSQ;
    594636   minex_func.n = np;
    595637   minex_func.params = (void *)&par;
    596  
     638
    597639   s = gsl_multimin_fminimizer_alloc (T, np);
    598640   gsl_multimin_fminimizer_set (s, &minex_func, y, ss);
    599  
     641
    600642   do
    601643     {
    602644       iter++;
    603645       status = gsl_multimin_fminimizer_iterate(s);
    604  
     646
    605647       if (status)
    606648         break;
    607  
     649
    608650       size = gsl_multimin_fminimizer_size (s);
    609651       status = gsl_multimin_test_size (size, 1e-2);
    610  
     652
    611653       if (status == GSL_SUCCESS)
    612654         {
    613655           printf ("converged to minimum at\n");
    614656         }
    615  
     657
    616658       printf ("%5d ", (int)iter);
    617659       for (i = 0; i < (size_t)np; i++)
     
    622664     }
    623665   while (status == GSL_CONTINUE && iter < 100);
    624  
     666
    625667  for (i=(size_t)np;i--;)
    626668    this->x[i] = gsl_vector_get(s->x, i);
     
    688730 * \param alpha first angle
    689731 * \param beta second angle
    690  * \param c norm of final vector 
     732 * \param c norm of final vector
    691733 * \return a vector with \f$\langle x1,x2 \rangle=A\f$, \f$\langle x1,y \rangle = B\f$ and with norm \a c.
    692  * \bug this is not yet working properly 
     734 * \bug this is not yet working properly
    693735 */
    694736bool Vector::SolveSystem(Vector *x1, Vector *x2, Vector *y, double alpha, double beta, double c)
     
    706748  if (fabs(x1->x[0]) < MYEPSILON) { // check for zero components for the later flipping and back-flipping
    707749    if (fabs(x1->x[1]) > MYEPSILON) {
    708       flag = 1;   
     750      flag = 1;
    709751    } else if (fabs(x1->x[2]) > MYEPSILON) {
    710752       flag = 2;
     
    739781  // now comes the case system
    740782  D1 = -y->x[0]/x1->x[0]*x1->x[1]+y->x[1];
    741   D2 = -y->x[0]/x1->x[0]*x1->x[2]+y->x[2]; 
     783  D2 = -y->x[0]/x1->x[0]*x1->x[2]+y->x[2];
    742784  D3 = y->x[0]/x1->x[0]*A-B1;
    743785  cout << Verbose(2) << "D1 " << D1 << "\tD2 " << D2 << "\tD3 " << D3 << "\n";
    744786  if (fabs(D1) < MYEPSILON) {
    745     cout << Verbose(2) << "D1 == 0!\n"; 
     787    cout << Verbose(2) << "D1 == 0!\n";
    746788    if (fabs(D2) > MYEPSILON) {
    747       cout << Verbose(3) << "D2 != 0!\n"; 
     789      cout << Verbose(3) << "D2 != 0!\n";
    748790      x[2] = -D3/D2;
    749791      E1 = A/x1->x[0] + x1->x[2]/x1->x[0]*D3/D2;
     
    755797      cout << Verbose(3) << "F1 " << F1 << "\tF2 " << F2 << "\tF3 " << F3 << "\n";
    756798      if (fabs(F1) < MYEPSILON) {
    757         cout << Verbose(4) << "F1 == 0!\n"; 
     799        cout << Verbose(4) << "F1 == 0!\n";
    758800        cout << Verbose(4) << "Gleichungssystem linear\n";
    759         x[1] = F3/(2.*F2); 
     801        x[1] = F3/(2.*F2);
    760802      } else {
    761803        p = F2/F1;
    762804        q = p*p - F3/F1;
    763         cout << Verbose(4) << "p " << p << "\tq " << q << endl; 
     805        cout << Verbose(4) << "p " << p << "\tq " << q << endl;
    764806        if (q < 0) {
    765807          cout << Verbose(4) << "q < 0" << endl;
     
    782824    cout << Verbose(2) << "F1 " << F1 << "\tF2 " << F2 << "\tF3 " << F3 << "\n";
    783825    if (fabs(F1) < MYEPSILON) {
    784       cout << Verbose(3) << "F1 == 0!\n"; 
     826      cout << Verbose(3) << "F1 == 0!\n";
    785827      cout << Verbose(3) << "Gleichungssystem linear\n";
    786       x[2] = F3/(2.*F2);     
     828      x[2] = F3/(2.*F2);
    787829    } else {
    788830      p = F2/F1;
    789831      q = p*p - F3/F1;
    790       cout << Verbose(3) << "p " << p << "\tq " << q << endl; 
     832      cout << Verbose(3) << "p " << p << "\tq " << q << endl;
    791833      if (q < 0) {
    792834        cout << Verbose(3) << "q < 0" << endl;
     
    832874    }
    833875    cout << Verbose(2) << i << ": sign matrix is " << sign[0] << "\t" << sign[1] << "\t" << sign[2] << "\n";
    834     // apply sign matrix 
     876    // apply sign matrix
    835877    for (j=NDIM;j--;)
    836878      x[j] *= sign[j];
     
    838880    ang = x2->Angle (this);
    839881    cout << Verbose(1) << i << "th angle " << ang << "\tbeta " << cos(beta) << " :\t";
    840     if (fabs(ang - cos(beta)) < MYEPSILON) { 
     882    if (fabs(ang - cos(beta)) < MYEPSILON) {
    841883      break;
    842884    }
  • src/vector.hpp

    • Property mode changed from 100644 to 100755
    rfcbfc8 r631dcb  
    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;
    1819  double PeriodicDistance(const Vector *y, const double *cell_size) const;
    1920  double ScalarProduct(const Vector *y) const;
    2021  double Projection(const Vector *y) const;
    2122  double Norm() const ;
    22   double Angle(Vector *y) const;
     23  double Angle(const Vector *y) const;
    2324
    2425  void AddVector(const Vector *y);
     
    2627  void CopyVector(const Vector *y);
    2728  void RotateVector(const Vector *y, const double alpha);
     29  void VectorProduct(const Vector *y);
    2830  void ProjectOntoPlane(const Vector *y);
    29   void Zero(); 
     31  void Zero();
    3032  void One(double one);
    3133  void Init(double x1, double x2, double x3);
     
    4042  void KeepPeriodic(ofstream *out, double *matrix);
    4143  void LinearCombinationOfVectors(const Vector *x1, const Vector *x2, const Vector *x3, double *factors);
    42  
     44
    4345  double CutsPlaneAt(Vector *A, Vector *B, Vector *C);
    4446  bool GetOneNormalVector(const Vector *x1);
     
    5355};
    5456
    55 ofstream& operator<<(ofstream& ost, Vector& m);
    56 Vector& operator+=(Vector& a, const Vector& b);
    57 Vector& operator*=(Vector& a, const double m);
    58 Vector& operator*(const Vector& a, const double m);
    59 Vector& operator+(const Vector& a, const Vector& b);
     57ostream & 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);
    6062
    6163#endif /*VECTOR_HPP_*/
  • src/verbose.cpp

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

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

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

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

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