root/src/grid_GridAndTime_impl.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. update_vertices
  2. dgf_find_vertex
  3. dgf_close_list

   1 /*! \file grid_GridAndTime_impl.h
   2     \brief Hash maps for evolving grids
   3 
   4      Revision history
   5      --------------------------------------------------
   6 
   7           Revised by Christian Power June 2016
   8           Originally written by Christian Power
   9                (power22c@gmail.com) 25. Februar 2016
  10 
  11     \author Christian Power
  12     \date 7. June 2016
  13     \copyright Copyright (c) 2016 Christian Power.  All rights reserved.
  14  */
  15 
  16 #ifndef GRID_GRIDANDTIME_IMPL_H
  17 #define GRID_GRIDANDTIME_IMPL_H 
  18 
  19 #include <vector>
  20 #include <array>
  21 #include <string>
  22 #include <unordered_map>
  23 #include <algorithm>
  24 #include <boost/functional/hash.hpp>
  25 #include "grid.h"
  26 
  27 //! Template specializations
  28 namespace std{
  29   //! Hash map for Domain points
  30   /*! \remark Unfortunately does dune change the last precision digits. */
  31   template<> struct std::hash<Esfem::Grid::Deformation::Domain>{
  32     //! Produce hash value via boost helper
  33     /*! \pre Dimension is 3. */
  34     std::size_t operator()(const Esfem::Grid::Deformation::Domain& n) const{
  35       using std::hash;
  36       // return hash<double>{}(n[0])
  37       //        ^ (hash<double>{}(n[1])<<1)>>1
  38       //        ^ (hash<double>{}(n[2])<<1)>>1;
  39       using boost::hash_value;
  40       using boost::hash_combine;
  41       size_t seed {0};
  42       hash_combine(seed, hash_value(n[0]));
  43       hash_combine(seed, hash_value(n[1]));
  44       hash_combine(seed, hash_value(n[2]));
  45       return seed;
  46     }
  47   };
  48   //! Hash map for an array of integers 
  49   template<> struct std::hash<array<int, Esfem::Grid::world_dim()> >{
  50     //! Convenience
  51     using Base = array<int, Esfem::Grid::world_dim()>;
  52     //! Produce hash value via boost helper
  53     /*! \pre Dimension is 3. */
  54     std::size_t operator()(const Base& ai) const{
  55       // using std::hash;
  56       // return hash<double>{}(n[0])
  57       //        ^ (hash<double>{}(n[1])<<1)>>1
  58       //        ^ (hash<double>{}(n[2])<<1)>>1;
  59       using boost::hash_value;
  60       using boost::hash_combine;
  61       size_t seed {0};
  62       for(int i = 0; i < Esfem::Grid::world_dim(); ++i)
  63         hash_combine(seed, hash_value(ai[i]));
  64       return seed;
  65     }
  66   };
  67   //! operator==() for Domain points
  68   template<> struct std::equal_to<Esfem::Grid::Deformation::Domain>{
  69     //! Component-wise comparison
  70     /*! \pre Dimension is 3. */
  71     bool operator()(const Esfem::Grid::Deformation::Domain& lhs,
  72                     const Esfem::Grid::Deformation::Domain& rhs) const{
  73       bool rv = true;
  74       for(int i = 0; i < Esfem::Grid::Deformation::Domain::dimension; ++i)
  75         rv = rv && lhs[i] == rhs[i];
  76       return rv;
  77     }
  78   };
  79   //! operator==() for Domain points
  80   template<> struct std::equal_to<array<int, Esfem::Grid::world_dim()> >{
  81     //! Short alias
  82     using Base = array<int, Esfem::Grid::world_dim()>;
  83     //! Component-wise comparison
  84     /*! \pre Dimension is 3. */
  85     bool operator()(const Base& lhs, const Base& rhs) const{
  86       bool rv = true;
  87       for(int i = 0; i < Esfem::Grid::world_dim(); ++i)
  88         rv = rv && lhs[i] == rhs[i];
  89       return rv;
  90     }
  91   };  
  92 }
  93 
  94 namespace Esfem{
  95   namespace Impl{    
  96     //! Evolution via a hash map
  97     /*! I use std::string as key. */
  98     class Evolving_grid{
  99     public:
 100       //! What is a node for us
 101       using Node = Grid::Deformation::Domain;
 102       //! Empty map
 103       Evolving_grid() = default;
 104       //! Construct grid from dgf
 105       explicit Evolving_grid(const std::string& filename);
 106 
 107       //! Access node
 108       const Node& operator[](const Node&) const;
 109       //! Get new nodes
 110       Evolving_grid& operator=(const Grid::Vec_FEfun& new_nodes);
 111 
 112       //! List of keys for hash map
 113       using Nodes_key = std::vector<std::string>;
 114       //! The actual map
 115       using Map = std::unordered_map<std::string, Node>;
 116     private:
 117       //! The list
 118       const Nodes_key original_vertices;
 119       //! Precision of the strings
 120       std::size_t digit_precision {8};
 121       //! Hash map
 122       Map vertices_map;
 123 
 124       //! Helper for operator=()
 125       /*! \pre distance(first, last) == dim * vertices_map.size().*/
 126       template<typename It, typename Ot>
 127       void update_vertices(It first, It last, Ot out, const int dim);
 128     };
 129 
 130     //! hash grid plus helper functions
 131     namespace hash{
 132       //! Basic dune entity
 133       using range = Grid::Deformation::Domain;
 134       //! Int because of rounding errors
 135       using key = std::array<int, range::dimension>;
 136       
 137       //! Evolution via a hash map
 138       /*! I use boost functions to combine hash values of doubles. */
 139       class grid{
 140         //! Short alias for dimension
 141         static constexpr auto dim = range::dimension;
 142         //! Hash map type
 143         using map = std::unordered_map<key, range>;
 144         //! Sequence
 145         using seq = std::vector<key>;
 146         //! Map 
 147         map m;
 148         //! Original list
 149         seq ol;
 150       public:
 151         //! Reports errors
 152         struct bad : std::runtime_error{
 153           //! Forward error message
 154           explicit bad(const std::string& msg) :std::runtime_error {msg} {}
 155         };
 156         //! Empty map
 157         grid() = default;
 158         //! Read first list from file name
 159         explicit grid(const std::string& fname);
 160         //! Get first list
 161         /*! \remark Use Lagrange interpolation of the identity. */
 162         explicit grid(const Grid::Vec_FEfun& init_keys);
 163         //! Get new list
 164         grid& operator=(const Grid::Vec_FEfun& value_list);
 165         //! Checked access
 166         /*! \throws bad as a nested object if the point does not exists*/
 167         const range& operator[](const range&) const;
 168       };
 169       //! Make a string out of a range
 170       std::string to_string(const range&);
 171       //! Multiply each entry with 1e5 and then truncate
 172       key to_key(const range&);
 173     }
 174     
 175     // ----------------------------------------------------------------------
 176     // Evolving grid constructor helper functions
 177 
 178     Evolving_grid::Nodes_key get_vertexList(const std::string& filename);
 179     // Extract from a dgf all vertices.  The resulting vector is then compatible
 180     // with a Dune discrete finite element function.
 181     std::size_t get_relevant_precision(const Evolving_grid::Nodes_key& vertex_list);
 182     // Calculate minimum precision needed for all Nodes_key
 183     Evolving_grid::Map
 184     identity_map(const Evolving_grid::Nodes_key&, const std::size_t precision);
 185     
 186     std::size_t get_relevant_precision(const std::string& number);
 187     // Assuming scientific format, e.g., 0.9298e-10.
 188     // For this example the function would return 4.
 189     std::vector<std::size_t>
 190     create_precision_vec(const std::vector<std::string>& vertex_list);
 191     // Applies the function above to a whole vector, where each line contains
 192     // three numbers.
 193     
 194     std::size_t max(const std::vector<std::size_t>&);
 195     
 196     std::string node_to_string(const Evolving_grid::Node&, const int precision);
 197     Evolving_grid::Node string_to_node(const std::string&);
 198     std::string normalize_node(const std::string&, const int precision);
 199     
 200     std::string clean_whitespace(const std::string&);
 201     
 202     std::vector<std::string> dgfFile_to_vec(const std::string& filename);
 203     
 204     template<typename It>
 205     It dgf_find_vertex(It first, It last, const std::string& filename);
 206     template<typename It>
 207     It dgf_close_list(It first, It last, const std::string& filename);
 208     
 209     // ----------------------------------------------------------------------
 210     // template implementation
 211     
 212     template<typename It, typename Ot>
 213     void Evolving_grid::update_vertices(It first, It last, Ot out, const int dim){
 214       while(first != last){
 215         Node new_vertex {};
 216         for(int i = 0; i < dim; ++i){
 217           new_vertex[i] = *first;
 218           ++first;
 219         }
 220         try{
 221           vertices_map.at(*out) = new_vertex;
 222         }
 223         catch(...){
 224           const auto err_msg = "Bad node: " + *out;
 225           throw std::logic_error {err_msg};
 226         }
 227         ++out;
 228       }
 229     }
 230 
 231     template<typename It>
 232     It dgf_find_vertex(It first, It last, const std::string& filename){
 233       std::string starting_point {"VERTEX"};
 234       It rv = std::find(first, last, "VERTEX");
 235       if(rv == last)
 236         throw std::runtime_error
 237         {"Missing keyword \"" + starting_point
 238             + "\" in file " + filename + "."};
 239       ++rv; // "VERTEX" is not part of the list
 240       return rv;
 241     }
 242     template<typename It>
 243     It dgf_close_list(It first, It last, const std::string& filename){
 244       std::string ending_point {"#"};
 245       It rv = std::find(first, last, ending_point);
 246       if(rv == last)
 247         throw std::runtime_error
 248         {"Missing ending symbol \"" + ending_point
 249             + "\" in file " + filename + "."};
 250       return rv;
 251     }
 252   }
 253 }
 254 
 255 #endif // GRID_GRIDANDTIME_IMPL_H
 256 
 257 /*! Log:
 258  */

/* [<][>][^][v][top][bottom][index][help] */