Line data Source code
1 : // The libMesh Finite Element Library. 2 : // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 3 : 4 : // This library is free software; you can redistribute it and/or 5 : // modify it under the terms of the GNU Lesser General Public 6 : // License as published by the Free Software Foundation; either 7 : // version 2.1 of the License, or (at your option) any later version. 8 : 9 : // This library is distributed in the hope that it will be useful, 10 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 : // Lesser General Public License for more details. 13 : 14 : // You should have received a copy of the GNU Lesser General Public 15 : // License along with this library; if not, write to the Free Software 16 : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 : 18 : 19 : #ifndef LIBMESH_PARALLEL_HILBERT_H 20 : #define LIBMESH_PARALLEL_HILBERT_H 21 : 22 : // This class contains all the functionality for bin sorting 23 : // Templated on the type of keys you will be sorting and the 24 : // type of iterator you will be using. 25 : 26 : #include "libmesh/libmesh_config.h" 27 : 28 : #if defined(LIBMESH_HAVE_LIBHILBERT) 29 : 30 : // TIMPI includes 31 : #include "timpi/standard_type.h" 32 : 33 : // C/C++ includes 34 : 35 : // So many implicit-fallthrough warnings in crazy libHilbert macros... 36 : #include "libmesh/ignore_warnings.h" 37 : #include "hilbert.h" 38 : #include "libmesh/restore_warnings.h" 39 : 40 : #include <cstddef> 41 : 42 : namespace TIMPI { 43 : 44 : #ifdef LIBMESH_HAVE_MPI 45 : // A StandardType<> specialization to return a derived MPI datatype 46 : // to handle communication of HilbertIndices. We use a singleton 47 : // pattern here because a global variable would have tried to call 48 : // MPI functions before MPI got initialized. 49 : template <> 50 : class StandardType<Hilbert::HilbertIndices> : public DataType 51 : { 52 : public: 53 : explicit 54 13442 : StandardType(const Hilbert::HilbertIndices * =nullptr) 55 13442 : { 56 13442 : _datatype = DataType(StandardType<Hilbert::inttype>(), 3); 57 13442 : } 58 : 59 : StandardType(const StandardType<Hilbert::HilbertIndices> & t) 60 : : DataType() 61 : { 62 : timpi_call_mpi (MPI_Type_dup (t._datatype, &_datatype)); 63 : } 64 : 65 13442 : ~StandardType() { this->free(); } 66 : 67 : static const bool is_fixed_type = true; 68 : }; 69 : 70 : #endif // LIBMESH_HAVE_MPI 71 : 72 : } // namespace TIMPI 73 : 74 : 75 : namespace libMesh { 76 : 77 : namespace Parallel { 78 : 79 : #ifdef LIBMESH_ENABLE_UNIQUE_ID 80 : typedef std::pair<Hilbert::HilbertIndices, unique_id_type> DofObjectKey; 81 : #else 82 : typedef Hilbert::HilbertIndices DofObjectKey; 83 : #endif 84 : 85 : } // namespace Parallel 86 : 87 : } // namespace libMesh 88 : 89 : 90 : namespace Hilbert { 91 : 92 : // This has to be in the Hilbert namespace for Koenig lookup to work? 93 : // g++ doesn't find it if it's in the global namespace. 94 : // XCode didn't find it in the libMesh namespace. 95 : #ifdef LIBMESH_ENABLE_UNIQUE_ID 96 : inline 97 0 : std::ostream & operator << (std::ostream & os, 98 : const libMesh::Parallel::DofObjectKey & hilbert_pair) 99 : { 100 0 : os << '(' << hilbert_pair.first << ',' << hilbert_pair.second << ')' << std::endl; 101 0 : return os; 102 : } 103 : #endif 104 : 105 : } 106 : 107 : 108 : // Appropriate operator< definitions for std::pair let the same code handle 109 : // both DofObjectKey types 110 : 111 : inline 112 1433020 : void dofobjectkey_max_op (libMesh::Parallel::DofObjectKey * in, 113 : libMesh::Parallel::DofObjectKey * inout, 114 : int * len, void *) 115 : { 116 : // When (*in <= *inout), then inout already contains max(*in,*inout) 117 : // Otherwise we need to copy from in. 118 2866040 : for (int i=0; i<*len; i++, in++, inout++) 119 1433020 : if (*inout < *in) 120 3549 : *inout = *in; 121 1433020 : } 122 : 123 : inline 124 1433020 : void dofobjectkey_min_op (libMesh::Parallel::DofObjectKey * in, 125 : libMesh::Parallel::DofObjectKey * inout, 126 : int * len, void *) 127 : { 128 : // When (*in >= *inout), then inout already contains min(*in,*inout) 129 : // Otherwise we need to copy from in. 130 2866040 : for (int i=0; i<*len; i++, in++, inout++) 131 1433020 : if (*in < *inout) 132 787 : *inout = *in; 133 1433020 : } 134 : 135 : #endif // LIBMESH_HAVE_LIBHILBERT 136 : 137 : #endif // LIBMESH_PARALLEL_HILBERT_H