$extrastylesheet
sparsity_pattern.h
Go to the documentation of this file.
00001 // The libMesh Finite Element Library.
00002 // Copyright (C) 2002-2014 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 #include "libmesh/parallel_object.h"
00026 
00027 // C++ includes
00028 #include <vector>
00029 
00030 namespace libMesh
00031 {
00032 
00033 // Forward declaractions
00034 class MeshBase;
00035 class DofMap;
00036 class CouplingMatrix;
00037 
00038 // ------------------------------------------------------------
00039 // Sparsity Pattern
00040 
00047 namespace SparsityPattern // use a namespace so member classes can be forward-declared.
00048 {
00049 typedef std::vector<dof_id_type, Threads::scalable_allocator<dof_id_type> > Row;
00050 class Graph : public std::vector<Row> {};
00051 
00052 class NonlocalGraph : public std::map<dof_id_type, Row> {};
00053 
00063 template<typename BidirectionalIterator>
00064 static void sort_row (const BidirectionalIterator begin,
00065                       BidirectionalIterator       middle,
00066                       const BidirectionalIterator end);
00067 
00079 class Build : public ParallelObject
00080 {
00081 private:
00082   const MeshBase &mesh;
00083   const DofMap &dof_map;
00084   const CouplingMatrix *dof_coupling;
00085   const bool implicit_neighbor_dofs;
00086   const bool need_full_sparsity_pattern;
00087 
00088 public:
00089 
00090   SparsityPattern::Graph sparsity_pattern;
00091   SparsityPattern::NonlocalGraph nonlocal_pattern;
00092 
00093   std::vector<dof_id_type> n_nz;
00094   std::vector<dof_id_type> n_oz;
00095 
00096   Build (const MeshBase &mesh_in,
00097          const DofMap &dof_map_in,
00098          const CouplingMatrix *dof_coupling_in,
00099          const bool implicit_neighbor_dofs_in,
00100          const bool need_full_sparsity_pattern_in);
00101 
00102   Build (Build &other, Threads::split);
00103 
00104   void operator()(const ConstElemRange &range);
00105 
00106   void join (const Build &other);
00107 
00108   void parallel_sync ();
00109 };
00110 
00111 #if defined(__GNUC__) && (__GNUC__ < 4) && !defined(__INTEL_COMPILER)
00112 
00117 void _dummy_function(void);
00118 #endif
00119 
00120 }
00121 
00122 
00123 
00124 // ------------------------------------------------------------
00125 // SparsityPattern inline member functions
00126 template<typename BidirectionalIterator>
00127 inline
00128 void SparsityPattern::sort_row (const BidirectionalIterator begin,
00129                                 BidirectionalIterator       middle,
00130                                 const BidirectionalIterator end)
00131 {
00132   if ((begin == middle) || (middle == end)) return;
00133 
00134   libmesh_assert_greater (std::distance (begin,  middle), 0);
00135   libmesh_assert_greater (std::distance (middle, end), 0);
00136   libmesh_assert (std::unique (begin,  middle) == middle);
00137   libmesh_assert (std::unique (middle, end) == end);
00138 
00139   while (middle != end)
00140     {
00141       BidirectionalIterator
00142         b = middle,
00143         a = b-1;
00144 
00145       // Bubble-sort the middle value downward
00146       while (!(*a < *b)) // *a & *b are less-than comparable, so use <
00147         {
00148           std::swap (*a, *b);
00149 
00150 #if defined(__GNUC__) && (__GNUC__ < 4) && !defined(__INTEL_COMPILER)
00151           /* Prohibit optimization at this point since gcc 3.3.5 seems
00152              to have a bug.  */
00153           SparsityPattern::_dummy_function();
00154 #endif
00155 
00156           if (a == begin) break;
00157 
00158           b=a;
00159           --a;
00160         }
00161 
00162       ++middle;
00163     }
00164 
00165   // Assure the algorithm worked if we are in DEBUG mode
00166 #ifdef DEBUG
00167   {
00168     // SGI STL extension!
00169     // libmesh_assert (std::is_sorted(begin,end));
00170 
00171     BidirectionalIterator
00172       prev  = begin,
00173       first = begin;
00174 
00175     for (++first; first != end; prev=first, ++first)
00176       if (*first < *prev)
00177         libmesh_assert(false);
00178   }
00179 #endif
00180 
00181   // Make sure the two ranges did not contain any common elements
00182   libmesh_assert (std::unique (begin, end) == end);
00183 }
00184 
00185 } // namespace libMesh
00186 
00187 #endif // LIBMESH_SPARSITY_PATTERN_H