| [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)
 | 
|---|
 | 52 | {
 | 
|---|
 | 53 |   // check stream
 | 
|---|
 | 54 |   if (ost.bad())
 | 
|---|
 | 55 |     throw SerializablePotentialException();
 | 
|---|
 | 56 | 
 | 
|---|
 | 57 |   /// print parameter key
 | 
|---|
 | 58 |   ost << potential.getToken() << ":";
 | 
|---|
 | 59 |   /// print associated particles
 | 
|---|
 | 60 |   const SerializablePotential::ParticleTypes_t &types = potential.getParticleTypes();
 | 
|---|
 | 61 |   for (size_t index=0; index < types.size(); ++index) {
 | 
|---|
 | 62 |     ost << "\tparticle_type" << index+1 << "=" << types[index];
 | 
|---|
 | 63 |     ost << (index != (types.size()-1) ? std::string(",") : std::string(""));
 | 
|---|
 | 64 |   }
 | 
|---|
 | 65 |   /// print coefficients
 | 
|---|
 | 66 |   const SerializablePotential::ParameterNames_t ¶mNames = potential.getParameterNames();
 | 
|---|
 | 67 |   const SerializablePotential::parameters_t ¶ms = potential.getParameters();
 | 
|---|
 | 68 |   SerializablePotential::ParameterNames_t::const_iterator nameiter = paramNames.begin();
 | 
|---|
 | 69 |   SerializablePotential::parameters_t::const_iterator valueiter = params.begin();
 | 
|---|
 | 70 |   for (; valueiter != params.end(); ++valueiter, ++nameiter) {
 | 
|---|
 | 71 |     ASSERT( nameiter != paramNames.end(),
 | 
|---|
 | 72 |         "ManyBodyPotential_Tersoff::operator<<() - there are less names than parameters.");
 | 
|---|
 | 73 |     if (*nameiter != std::string(""))
 | 
|---|
 | 74 |       ost << ",\t" << *nameiter << "=" << *valueiter;
 | 
|---|
 | 75 |   }
 | 
|---|
 | 76 |   /// print terminating semi-colon
 | 
|---|
 | 77 |   ost << ";";
 | 
|---|
 | 78 |   return ost;
 | 
|---|
 | 79 | }
 | 
|---|
 | 80 | 
 | 
|---|
 | 81 | std::istream& operator>>(std::istream &ist, SerializablePotential &potential)
 | 
|---|
 | 82 | {
 | 
|---|
 | 83 |   // check stream
 | 
|---|
 | 84 |   if (ist.bad())
 | 
|---|
 | 85 |     throw SerializablePotentialException();
 | 
|---|
 | 86 | 
 | 
|---|
 | 87 |   // create copy of current parameters, hence line may contain not all required
 | 
|---|
 | 88 |   SerializablePotential::parameters_t params(potential.getParameters());
 | 
|---|
 | 89 | 
 | 
|---|
 | 90 |   // read in full line
 | 
|---|
 | 91 |   std::string linestring;
 | 
|---|
 | 92 |   getline(ist, linestring);
 | 
|---|
 | 93 |   const std::string whitespace(" \t");
 | 
|---|
 | 94 |   const size_t strBegin = linestring.find_first_not_of(whitespace);
 | 
|---|
 | 95 |   const size_t colonpos = linestring.find(":");
 | 
|---|
 | 96 |   if ((strBegin == std::string::npos) || (colonpos == std::string::npos) ||
 | 
|---|
 | 97 |       (linestring.substr(strBegin, colonpos-1) != potential.getToken()))
 | 
|---|
 | 98 |     throw SerializablePotentialMissingValueException()
 | 
|---|
 | 99 |         << SerializablePotentialKey(potential.getName());
 | 
|---|
 | 100 | 
 | 
|---|
 | 101 |   // tokenize by ","
 | 
|---|
 | 102 |   typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
 | 
|---|
 | 103 |   boost::char_separator<char> pairsep(",\t ;");
 | 
|---|
 | 104 |   boost::char_separator<char> keyvaluesep("=");
 | 
|---|
 | 105 |   std::string remainderstring(linestring.substr(colonpos+1));
 | 
|---|
 | 106 | //  {
 | 
|---|
 | 107 | //    std::stringstream remainderstream
 | 
|---|
 | 108 | //    remainderstream >> std::ws >> remainderstring;
 | 
|---|
 | 109 | //  }
 | 
|---|
 | 110 |   tokenizer tokens(remainderstring, pairsep); //skip colon
 | 
|---|
 | 111 | 
 | 
|---|
 | 112 |   // step through each token
 | 
|---|
 | 113 |   ConvertTo<size_t> ConvertToIndex;
 | 
|---|
 | 114 |   ConvertTo<SerializablePotential::parameter_t> ConvertToValue;
 | 
|---|
 | 115 |   ConvertTo<SerializablePotential::ParticleType_t> ConvertToParticleType;
 | 
|---|
 | 116 |   for (tokenizer::iterator tok_iter = tokens.begin();
 | 
|---|
 | 117 |     tok_iter != tokens.end(); ++tok_iter) {
 | 
|---|
 | 118 |     const std::string &keyvalue = *tok_iter;
 | 
|---|
 | 119 |     tokenizer keyvaluetoken(keyvalue, keyvaluesep);
 | 
|---|
 | 120 |     tokenizer::iterator keyvalue_iter = keyvaluetoken.begin();
 | 
|---|
 | 121 |     const std::string &key = *keyvalue_iter;
 | 
|---|
 | 122 | 
 | 
|---|
 | 123 |     /// parse the particle_types
 | 
|---|
 | 124 |     const size_t pos = key.find("particle_type");
 | 
|---|
 | 125 |     if (pos != std::string::npos) {
 | 
|---|
 | 126 |       // split of type and convert rest to index
 | 
|---|
 | 127 |       const size_t index = ConvertToIndex(key.substr(pos, std::string::npos));
 | 
|---|
 | 128 |       // and set the type
 | 
|---|
 | 129 |       if (++keyvalue_iter == keyvaluetoken.end())
 | 
|---|
 | 130 |         throw SerializablePotentialMissingValueException() << SerializablePotentialKey(key);
 | 
|---|
 | 131 |       const std::string &value = *keyvalue_iter;
 | 
|---|
 | 132 |       potential.setParticleType(index, ConvertToParticleType(value));
 | 
|---|
 | 133 |     } else {
 | 
|---|
 | 134 |       const size_t index = potential.getParameterIndex(key);
 | 
|---|
 | 135 |       // parse the coefficients
 | 
|---|
 | 136 |       if (index != (size_t)-1) {
 | 
|---|
 | 137 |         if (++keyvalue_iter == keyvaluetoken.end())
 | 
|---|
 | 138 |           throw SerializablePotentialMissingValueException() << SerializablePotentialKey(key);
 | 
|---|
 | 139 |         const std::string &value = *keyvalue_iter;
 | 
|---|
 | 140 |         params[index] = ConvertToValue(value);
 | 
|---|
 | 141 |       } else {
 | 
|---|
 | 142 |         throw SerializablePotentialIllegalKeyException() << SerializablePotentialKey(key);
 | 
|---|
 | 143 |       }
 | 
|---|
 | 144 |     }
 | 
|---|
 | 145 |   }
 | 
|---|
 | 146 | 
 | 
|---|
 | 147 |   /// set the new paremeters
 | 
|---|
 | 148 |   potential.setParameters(params);
 | 
|---|
 | 149 |   return ist;
 | 
|---|
 | 150 | }
 | 
|---|
 | 151 | 
 | 
|---|
 | 152 | const size_t SerializablePotential::getParameterIndex(const std::string &_name) const
 | 
|---|
 | 153 | {
 | 
|---|
 | 154 |   const ParameterNames_t& ParameterNames = getParameterNames();
 | 
|---|
 | 155 |   ParameterNames_t::const_iterator iter =
 | 
|---|
 | 156 |       std::find(ParameterNames.begin(), ParameterNames.end(), _name);
 | 
|---|
 | 157 |   if (iter == ParameterNames.end())
 | 
|---|
 | 158 |     return (size_t)-1;
 | 
|---|
 | 159 |   else
 | 
|---|
 | 160 |     return std::distance(ParameterNames.begin(), iter);
 | 
|---|
 | 161 | }
 | 
|---|
 | 162 | 
 | 
|---|
 | 163 | const std::string SerializablePotential::getName() const
 | 
|---|
 | 164 | {
 | 
|---|
 | 165 |   std::string returnstring = getToken() + std::string("_");
 | 
|---|
 | 166 |   BOOST_FOREACH(const ParticleType_t &type, getParticleTypes()) {
 | 
|---|
 | 167 |     returnstring += toString(type);
 | 
|---|
 | 168 |   }
 | 
|---|
 | 169 |   return returnstring;
 | 
|---|
 | 170 | }
 | 
|---|