| [6efcae] | 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)
 | 
|---|
| [3d2559] | 52 | {
 | 
|---|
 | 53 |   potential.stream_to(ost);
 | 
|---|
 | 54 |   return ost;
 | 
|---|
 | 55 | }
 | 
|---|
 | 56 | 
 | 
|---|
 | 57 | void SerializablePotential::stream_to(std::ostream &ost) const
 | 
|---|
| [6efcae] | 58 | {
 | 
|---|
 | 59 |   // check stream
 | 
|---|
 | 60 |   if (ost.bad())
 | 
|---|
 | 61 |     throw SerializablePotentialException();
 | 
|---|
 | 62 | 
 | 
|---|
 | 63 |   /// print parameter key
 | 
|---|
| [3d2559] | 64 |   ost << getToken() << ":";
 | 
|---|
| [6efcae] | 65 |   /// print associated particles
 | 
|---|
| [3d2559] | 66 |   const SerializablePotential::ParticleTypes_t &types = getParticleTypes();
 | 
|---|
| [6efcae] | 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
 | 
|---|
| [3d2559] | 72 |   const SerializablePotential::ParameterNames_t ¶mNames = getParameterNames();
 | 
|---|
 | 73 |   const SerializablePotential::parameters_t ¶ms = getParameters();
 | 
|---|
| [6efcae] | 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)
 | 
|---|
| [3d2559] | 87 | {
 | 
|---|
 | 88 |   potential.stream_from(ist);
 | 
|---|
 | 89 |   return ist;
 | 
|---|
 | 90 | }
 | 
|---|
 | 91 | 
 | 
|---|
 | 92 | void SerializablePotential::stream_from(std::istream &ist)
 | 
|---|
| [6efcae] | 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
 | 
|---|
| [3d2559] | 99 |   SerializablePotential::parameters_t params(getParameters());
 | 
|---|
| [6efcae] | 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) ||
 | 
|---|
| [3d2559] | 108 |       (linestring.substr(strBegin, colonpos-1) != getToken()))
 | 
|---|
| [6efcae] | 109 |     throw SerializablePotentialMissingValueException()
 | 
|---|
| [3d2559] | 110 |         << SerializablePotentialKey(getName());
 | 
|---|
| [6efcae] | 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;
 | 
|---|
| [3d2559] | 143 |       setParticleType(index, ConvertToParticleType(value));
 | 
|---|
| [6efcae] | 144 |     } else {
 | 
|---|
| [3d2559] | 145 |       const size_t index = getParameterIndex(key);
 | 
|---|
| [6efcae] | 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
 | 
|---|
| [3d2559] | 159 |   setParameters(params);
 | 
|---|
| [6efcae] | 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 | }
 | 
|---|