| 1 | /*
 | 
|---|
| 2 |  * Project: MoleCuilder
 | 
|---|
| 3 |  * Description: creates and alters molecular systems
 | 
|---|
| 4 |  * Copyright (C)  2012 University of Bonn. All rights reserved.
 | 
|---|
| 5 |  * Please see the COPYING file or "Copyright notice" in builder.cpp for details.
 | 
|---|
| 6 |  * 
 | 
|---|
| 7 |  *
 | 
|---|
| 8 |  *   This file is part of MoleCuilder.
 | 
|---|
| 9 |  *
 | 
|---|
| 10 |  *    MoleCuilder is free software: you can redistribute it and/or modify
 | 
|---|
| 11 |  *    it under the terms of the GNU General Public License as published by
 | 
|---|
| 12 |  *    the Free Software Foundation, either version 2 of the License, or
 | 
|---|
| 13 |  *    (at your option) any later version.
 | 
|---|
| 14 |  *
 | 
|---|
| 15 |  *    MoleCuilder is distributed in the hope that it will be useful,
 | 
|---|
| 16 |  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
|---|
| 17 |  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
|---|
| 18 |  *    GNU General Public License for more details.
 | 
|---|
| 19 |  *
 | 
|---|
| 20 |  *    You should have received a copy of the GNU General Public License
 | 
|---|
| 21 |  *    along with MoleCuilder.  If not, see <http://www.gnu.org/licenses/>. 
 | 
|---|
| 22 |  */
 | 
|---|
| 23 | 
 | 
|---|
| 24 | /*
 | 
|---|
| 25 |  * SerializablePotential.cpp
 | 
|---|
| 26 |  *
 | 
|---|
| 27 |  *  Created on: 23.11.2012
 | 
|---|
| 28 |  *      Author: heber
 | 
|---|
| 29 |  */
 | 
|---|
| 30 | 
 | 
|---|
| 31 | // include config.h
 | 
|---|
| 32 | #ifdef HAVE_CONFIG_H
 | 
|---|
| 33 | #include <config.h>
 | 
|---|
| 34 | #endif
 | 
|---|
| 35 | 
 | 
|---|
| 36 | #include "CodePatterns/MemDebug.hpp"
 | 
|---|
| 37 | 
 | 
|---|
| 38 | #include "SerializablePotential.hpp"
 | 
|---|
| 39 | 
 | 
|---|
| 40 | #include <algorithm>
 | 
|---|
| 41 | #include <boost/foreach.hpp>
 | 
|---|
| 42 | #include <boost/tokenizer.hpp>
 | 
|---|
| 43 | #include <iostream>
 | 
|---|
| 44 | #include <string>
 | 
|---|
| 45 | 
 | 
|---|
| 46 | #include "CodePatterns/Assert.hpp"
 | 
|---|
| 47 | #include "CodePatterns/toString.hpp"
 | 
|---|
| 48 | 
 | 
|---|
| 49 | #include "Potentials/Exceptions.hpp"
 | 
|---|
| 50 | 
 | 
|---|
| 51 | std::ostream& operator<<(std::ostream &ost, const SerializablePotential &potential)
 | 
|---|
| 52 | {
 | 
|---|
| 53 |   potential.stream_to(ost);
 | 
|---|
| 54 |   return ost;
 | 
|---|
| 55 | }
 | 
|---|
| 56 | 
 | 
|---|
| 57 | void SerializablePotential::stream_to(std::ostream &ost) const
 | 
|---|
| 58 | {
 | 
|---|
| 59 |   // check stream
 | 
|---|
| 60 |   if (ost.bad())
 | 
|---|
| 61 |     throw SerializablePotentialException();
 | 
|---|
| 62 | 
 | 
|---|
| 63 |   /// print parameter key
 | 
|---|
| 64 |   ost << getToken() << ":";
 | 
|---|
| 65 |   /// print associated particles
 | 
|---|
| 66 |   const SerializablePotential::ParticleTypes_t &types = getParticleTypes();
 | 
|---|
| 67 |   for (size_t index=0; index < types.size(); ++index) {
 | 
|---|
| 68 |     ost << "\tparticle_type" << index+1 << "=" << types[index];
 | 
|---|
| 69 |     ost << (index != (types.size()-1) ? std::string(",") : std::string(""));
 | 
|---|
| 70 |   }
 | 
|---|
| 71 |   /// print coefficients
 | 
|---|
| 72 |   const SerializablePotential::ParameterNames_t ¶mNames = getParameterNames();
 | 
|---|
| 73 |   const SerializablePotential::parameters_t ¶ms = getParameters();
 | 
|---|
| 74 |   SerializablePotential::ParameterNames_t::const_iterator nameiter = paramNames.begin();
 | 
|---|
| 75 |   SerializablePotential::parameters_t::const_iterator valueiter = params.begin();
 | 
|---|
| 76 |   for (; valueiter != params.end(); ++valueiter, ++nameiter) {
 | 
|---|
| 77 |     ASSERT( nameiter != paramNames.end(),
 | 
|---|
| 78 |         "ManyBodyPotential_Tersoff::operator<<() - there are less names than parameters.");
 | 
|---|
| 79 |     if (*nameiter != std::string(""))
 | 
|---|
| 80 |       ost << ",\t" << *nameiter << "=" << *valueiter;
 | 
|---|
| 81 |   }
 | 
|---|
| 82 |   /// print terminating semi-colon
 | 
|---|
| 83 |   ost << ";";
 | 
|---|
| 84 | }
 | 
|---|
| 85 | 
 | 
|---|
| 86 | std::istream& operator>>(std::istream &ist, SerializablePotential &potential)
 | 
|---|
| 87 | {
 | 
|---|
| 88 |   potential.stream_from(ist);
 | 
|---|
| 89 |   return ist;
 | 
|---|
| 90 | }
 | 
|---|
| 91 | 
 | 
|---|
| 92 | void SerializablePotential::stream_from(std::istream &ist)
 | 
|---|
| 93 | {
 | 
|---|
| 94 |   // check stream
 | 
|---|
| 95 |   if (ist.bad())
 | 
|---|
| 96 |     throw SerializablePotentialException();
 | 
|---|
| 97 | 
 | 
|---|
| 98 |   // create copy of current parameters, hence line may contain not all required
 | 
|---|
| 99 |   SerializablePotential::parameters_t params(getParameters());
 | 
|---|
| 100 | 
 | 
|---|
| 101 |   // read in full line
 | 
|---|
| 102 |   std::string linestring;
 | 
|---|
| 103 |   getline(ist, linestring);
 | 
|---|
| 104 |   const std::string whitespace(" \t");
 | 
|---|
| 105 |   const size_t strBegin = linestring.find_first_not_of(whitespace);
 | 
|---|
| 106 |   const size_t colonpos = linestring.find(":");
 | 
|---|
| 107 |   if ((strBegin == std::string::npos) || (colonpos == std::string::npos) ||
 | 
|---|
| 108 |       (linestring.substr(strBegin, colonpos-1) != getToken()))
 | 
|---|
| 109 |     throw SerializablePotentialMissingValueException()
 | 
|---|
| 110 |         << SerializablePotentialKey(getName());
 | 
|---|
| 111 | 
 | 
|---|
| 112 |   // tokenize by ","
 | 
|---|
| 113 |   typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
 | 
|---|
| 114 |   boost::char_separator<char> pairsep(",\t ;");
 | 
|---|
| 115 |   boost::char_separator<char> keyvaluesep("=");
 | 
|---|
| 116 |   std::string remainderstring(linestring.substr(colonpos+1));
 | 
|---|
| 117 | //  {
 | 
|---|
| 118 | //    std::stringstream remainderstream
 | 
|---|
| 119 | //    remainderstream >> std::ws >> remainderstring;
 | 
|---|
| 120 | //  }
 | 
|---|
| 121 |   tokenizer tokens(remainderstring, pairsep); //skip colon
 | 
|---|
| 122 | 
 | 
|---|
| 123 |   // step through each token
 | 
|---|
| 124 |   ConvertTo<size_t> ConvertToIndex;
 | 
|---|
| 125 |   ConvertTo<SerializablePotential::parameter_t> ConvertToValue;
 | 
|---|
| 126 |   ConvertTo<SerializablePotential::ParticleType_t> ConvertToParticleType;
 | 
|---|
| 127 |   for (tokenizer::iterator tok_iter = tokens.begin();
 | 
|---|
| 128 |     tok_iter != tokens.end(); ++tok_iter) {
 | 
|---|
| 129 |     const std::string &keyvalue = *tok_iter;
 | 
|---|
| 130 |     tokenizer keyvaluetoken(keyvalue, keyvaluesep);
 | 
|---|
| 131 |     tokenizer::iterator keyvalue_iter = keyvaluetoken.begin();
 | 
|---|
| 132 |     const std::string &key = *keyvalue_iter;
 | 
|---|
| 133 | 
 | 
|---|
| 134 |     /// parse the particle_types
 | 
|---|
| 135 |     const size_t pos = key.find("particle_type");
 | 
|---|
| 136 |     if (pos != std::string::npos) {
 | 
|---|
| 137 |       // split of type and convert rest to index
 | 
|---|
| 138 |       const size_t index = ConvertToIndex(key.substr(pos, std::string::npos));
 | 
|---|
| 139 |       // and set the type
 | 
|---|
| 140 |       if (++keyvalue_iter == keyvaluetoken.end())
 | 
|---|
| 141 |         throw SerializablePotentialMissingValueException() << SerializablePotentialKey(key);
 | 
|---|
| 142 |       const std::string &value = *keyvalue_iter;
 | 
|---|
| 143 |       setParticleType(index, ConvertToParticleType(value));
 | 
|---|
| 144 |     } else {
 | 
|---|
| 145 |       const size_t index = getParameterIndex(key);
 | 
|---|
| 146 |       // parse the coefficients
 | 
|---|
| 147 |       if (index != (size_t)-1) {
 | 
|---|
| 148 |         if (++keyvalue_iter == keyvaluetoken.end())
 | 
|---|
| 149 |           throw SerializablePotentialMissingValueException() << SerializablePotentialKey(key);
 | 
|---|
| 150 |         const std::string &value = *keyvalue_iter;
 | 
|---|
| 151 |         params[index] = ConvertToValue(value);
 | 
|---|
| 152 |       } else {
 | 
|---|
| 153 |         throw SerializablePotentialIllegalKeyException() << SerializablePotentialKey(key);
 | 
|---|
| 154 |       }
 | 
|---|
| 155 |     }
 | 
|---|
| 156 |   }
 | 
|---|
| 157 | 
 | 
|---|
| 158 |   /// set the new paremeters
 | 
|---|
| 159 |   setParameters(params);
 | 
|---|
| 160 | }
 | 
|---|
| 161 | 
 | 
|---|
| 162 | const size_t SerializablePotential::getParameterIndex(const std::string &_name) const
 | 
|---|
| 163 | {
 | 
|---|
| 164 |   const ParameterNames_t& ParameterNames = getParameterNames();
 | 
|---|
| 165 |   ParameterNames_t::const_iterator iter =
 | 
|---|
| 166 |       std::find(ParameterNames.begin(), ParameterNames.end(), _name);
 | 
|---|
| 167 |   if (iter == ParameterNames.end())
 | 
|---|
| 168 |     return (size_t)-1;
 | 
|---|
| 169 |   else
 | 
|---|
| 170 |     return std::distance(ParameterNames.begin(), iter);
 | 
|---|
| 171 | }
 | 
|---|
| 172 | 
 | 
|---|
| 173 | const std::string SerializablePotential::getName() const
 | 
|---|
| 174 | {
 | 
|---|
| 175 |   std::string returnstring = getToken() + std::string("_");
 | 
|---|
| 176 |   BOOST_FOREACH(const ParticleType_t &type, getParticleTypes()) {
 | 
|---|
| 177 |     returnstring += toString(type);
 | 
|---|
| 178 |   }
 | 
|---|
| 179 |   return returnstring;
 | 
|---|
| 180 | }
 | 
|---|