sparsity_pattern.h
Go to the documentation of this file.00001 // The libMesh Finite Element Library. 00002 // Copyright (C) 2002-2012 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 00003 00004 // This library is free software; you can redistribute it and/or 00005 // modify it under the terms of the GNU Lesser General Public 00006 // License as published by the Free Software Foundation; either 00007 // version 2.1 of the License, or (at your option) any later version. 00008 00009 // This library is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // Lesser General Public License for more details. 00013 00014 // You should have received a copy of the GNU Lesser General Public 00015 // License along with this library; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 00018 00019 #ifndef LIBMESH_SPARSITY_PATTERN_H 00020 #define LIBMESH_SPARSITY_PATTERN_H 00021 00022 // Local Includes 00023 #include "libmesh/elem_range.h" 00024 #include "libmesh/threads_allocators.h" 00025 00026 // C++ includes 00027 #include <vector> 00028 00029 namespace libMesh 00030 { 00031 00032 // Forward declaractions 00033 class MeshBase; 00034 class DofMap; 00035 class CouplingMatrix; 00036 00037 // ------------------------------------------------------------ 00038 // Sparsity Pattern 00039 00046 namespace SparsityPattern // use a namespace so member classes can be forward-declared. 00047 { 00048 typedef std::vector<dof_id_type, Threads::scalable_allocator<dof_id_type> > Row; 00049 class Graph : public std::vector<Row> {}; 00050 00051 class NonlocalGraph : public std::map<dof_id_type, Row> {}; 00052 00062 template<typename BidirectionalIterator> 00063 static void sort_row (const BidirectionalIterator begin, 00064 BidirectionalIterator middle, 00065 const BidirectionalIterator end); 00066 00078 class Build 00079 { 00080 private: 00081 const MeshBase &mesh; 00082 const DofMap &dof_map; 00083 const CouplingMatrix *dof_coupling; 00084 const bool implicit_neighbor_dofs; 00085 const bool need_full_sparsity_pattern; 00086 00087 public: 00088 00089 SparsityPattern::Graph sparsity_pattern; 00090 SparsityPattern::NonlocalGraph nonlocal_pattern; 00091 00092 std::vector<dof_id_type> n_nz; 00093 std::vector<dof_id_type> n_oz; 00094 00095 Build (const MeshBase &mesh_in, 00096 const DofMap &dof_map_in, 00097 const CouplingMatrix *dof_coupling_in, 00098 const bool implicit_neighbor_dofs_in, 00099 const bool need_full_sparsity_pattern_in) : 00100 mesh(mesh_in), 00101 dof_map(dof_map_in), 00102 dof_coupling(dof_coupling_in), 00103 implicit_neighbor_dofs(implicit_neighbor_dofs_in), 00104 need_full_sparsity_pattern(need_full_sparsity_pattern_in), 00105 sparsity_pattern(), 00106 nonlocal_pattern(), 00107 n_nz(), 00108 n_oz() 00109 {} 00110 00111 Build (Build &other, Threads::split) : 00112 mesh(other.mesh), 00113 dof_map(other.dof_map), 00114 dof_coupling(other.dof_coupling), 00115 implicit_neighbor_dofs(other.implicit_neighbor_dofs), 00116 need_full_sparsity_pattern(other.need_full_sparsity_pattern), 00117 sparsity_pattern(), 00118 nonlocal_pattern(), 00119 n_nz(), 00120 n_oz() 00121 {} 00122 00123 void operator()(const ConstElemRange &range); 00124 00125 void join (const Build &other); 00126 00127 void parallel_sync (); 00128 }; 00129 00130 #if defined(__GNUC__) && (__GNUC__ < 4) && !defined(__INTEL_COMPILER) 00131 00136 void _dummy_function(void); 00137 #endif 00138 00139 } 00140 00141 00142 00143 // ------------------------------------------------------------ 00144 // SparsityPattern inline member functions 00145 template<typename BidirectionalIterator> 00146 inline 00147 void SparsityPattern::sort_row (const BidirectionalIterator begin, 00148 BidirectionalIterator middle, 00149 const BidirectionalIterator end) 00150 { 00151 if ((begin == middle) || (middle == end)) return; 00152 00153 libmesh_assert_greater (std::distance (begin, middle), 0); 00154 libmesh_assert_greater (std::distance (middle, end), 0); 00155 libmesh_assert (std::unique (begin, middle) == middle); 00156 libmesh_assert (std::unique (middle, end) == end); 00157 00158 while (middle != end) 00159 { 00160 BidirectionalIterator 00161 b = middle, 00162 a = b-1; 00163 00164 // Bubble-sort the middle value downward 00165 while (!(*a < *b)) // *a & *b are less-than comparable, so use < 00166 { 00167 std::swap (*a, *b); 00168 00169 #if defined(__GNUC__) && (__GNUC__ < 4) && !defined(__INTEL_COMPILER) 00170 /* Prohibit optimization at this point since gcc 3.3.5 seems 00171 to have a bug. */ 00172 SparsityPattern::_dummy_function(); 00173 #endif 00174 00175 if (a == begin) break; 00176 00177 b=a; 00178 --a; 00179 } 00180 00181 ++middle; 00182 } 00183 00184 // Assure the algorithm worked if we are in DEBUG mode 00185 #ifdef DEBUG 00186 { 00187 // SGI STL extension! 00188 // libmesh_assert (std::is_sorted(begin,end)); 00189 00190 BidirectionalIterator 00191 prev = begin, 00192 first = begin; 00193 00194 for (++first; first != end; prev=first, ++first) 00195 if (*first < *prev) 00196 libmesh_assert(false); 00197 } 00198 #endif 00199 00200 // Make sure the two ranges did not contain any common elements 00201 libmesh_assert (std::unique (begin, end) == end); 00202 } 00203 00204 } // namespace libMesh 00205 00206 #endif // LIBMESH_SPARSITY_PATTERN_H
Site Created By: libMesh Developers
Last modified: February 05 2013 19:54:48 UTC
Hosted By: