Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://mooseframework.inl.gov 3 : //* 4 : //* All rights reserved, see COPYRIGHT for full restrictions 5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT 6 : //* 7 : //* Licensed under LGPL 2.1, please see LICENSE for details 8 : //* https://www.gnu.org/licenses/lgpl-2.1.html 9 : 10 : #pragma once 11 : 12 : #include "MooseTypes.h" 13 : 14 : #include "libmesh/point.h" 15 : 16 : /** 17 : * This namespace provides efficient algorithms for quickly hashing different types for checking 18 : * identity with a very low collision probability. 19 : */ 20 : namespace hashing 21 : { 22 : typedef std::size_t HashValue; 23 : 24 : /** 25 : * Final iteration of the variadic template with no additional arguments 26 : */ 27 : inline void 28 : hashCombine(HashValue & /* seed */) 29 : { 30 : } 31 : 32 : /** 33 : * Variadic template to hashing a combination with finite size 34 : * see: https://stackoverflow.com/a/38140932 35 : */ 36 : template <class T, class... Rest> 37 : inline void 38 6837583 : hashCombine(HashValue & seed, const T & value, Rest... rest) 39 : { 40 : std::hash<T> hasher; 41 : 42 6837620 : seed ^= hasher(value) + 0x9e3779b9 + (seed << 6) + (seed >> 2); 43 5128161 : hashCombine(seed, rest...); 44 6837583 : } 45 : 46 : /** 47 : * Hash function for sampling 10 points from a large container and hashing 48 : * see: https://stackoverflow.com/a/37007715 49 : */ 50 : template <class Container> 51 : HashValue 52 9 : hashLargeContainer(Container const & container) 53 : { 54 : std::size_t size = container.size(); 55 9 : std::size_t stride = 1 + size / 10; 56 5 : HashValue seed = size; 57 : 58 92 : for (std::size_t i = 0; i < size; i += stride) 59 : { 60 83 : hashCombine(seed, container.data()[i]); 61 : } 62 : 63 9 : return seed; 64 : } 65 : 66 : /** 67 : * Hashing for Point 68 : */ 69 : inline HashValue 70 4 : hashCombine(const libMesh::Point & point) 71 : { 72 : // 'Magic seed' seed that provides entropy against the other hashCombine() seed 73 4 : HashValue seed = 3; 74 : 75 4 : hashCombine(seed, point(0), point(1), point(2)); 76 : 77 4 : return seed; 78 : } 79 : 80 : /** 81 : * Hashing for Point and time, useful for Functions 82 : */ 83 : inline HashValue 84 1709368 : hashCombine(Real time, const libMesh::Point & point) 85 : { 86 : // 'Magic seed' seed that provides entropy against the other hashCombine() seed 87 1709368 : HashValue seed = 42; 88 : 89 1709368 : hashCombine(seed, time, point(0), point(1), point(2)); 90 : 91 1709368 : return seed; 92 : } 93 : }