This file is indexed.

/usr/include/libmesh/mesh_base.h is in libmesh-dev 0.7.1-2ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
// $Id: mesh_base.h 4402 2011-04-22 23:10:19Z roystgnr $

// The libMesh Finite Element Library.
// Copyright (C) 2002-2008 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
  
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
  
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
  
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA



#ifndef __mesh_base_h__
#define __mesh_base_h__



// C++ Includes   -----------------------------------
#include <string>

// Local Includes -----------------------------------
#include "auto_ptr.h"
#include "dof_object.h" // for invalid_processor_id
#include "enum_elem_type.h"
#include "libmesh_common.h"
#include "multi_predicates.h"
#include "partitioner.h" // AutoPtr needs a real declaration
#include "point_locator_base.h"
#include "variant_filter_iterator.h"

namespace libMesh
{

// forward declarations
class Elem;
class Node;
class Point;
class BoundaryInfo;
class MeshData;



/**
 * This is the \p MeshBase class. This class provides all the data necessary
 * to describe a geometric entity.  It allows for the description of a
 * \p dim dimensional object that lives in \p LIBMESH_DIM-dimensional space.
 * \par
 * A mesh is made of nodes and elements, and this class provides data
 * structures to store and access both.  A mesh may be partitioned into a
 * number of subdomains, and this class provides that functionality.
 * Furthermore, this class provides functions for reading and writing a
 * mesh to disk in various formats.
 *
 * \author  Benjamin S. Kirk
 * \date    $Date: 2011-04-22 18:10:19 -0500 (Fri, 22 Apr 2011) $
 * \version $Revision: 4402 $
 */


// ------------------------------------------------------------
// MeshBase class definition
class MeshBase
{
public:

  /**
   * Constructor.  Takes \p dim, the dimension of the mesh.
   * The mesh dimension can be changed (and may automatically be
   * changed by mesh generation/loading) later.
   */
  MeshBase (unsigned int dim=1);
  
  /**
   * Copy-constructor.
   */
  MeshBase (const MeshBase& other_mesh);

  /**
   * Virtual "copy constructor"
   */
  virtual AutoPtr<MeshBase> clone() const = 0;

  /**
   * Destructor.
   */
  virtual ~MeshBase ();

  /**
   * This class holds the boundary information.  It can store nodes, edges,
   * and faces with a corresponding id that facilitates setting boundary
   * conditions.
   */
  AutoPtr<BoundaryInfo> boundary_info;

  /**
   * A partitioner to use at each prepare_for_use()
   */
  virtual AutoPtr<Partitioner> &partitioner() { return _partitioner; }
  
  /**
   * Deletes all the data that are currently stored.
   */
  virtual void clear ();
  
  /**
   * @returns \p true if the mesh has been prepared via a call
   * to \p prepare_for_use, \p false otherwise.
   */
  bool is_prepared () const
  { return _is_prepared; }
  
  /**
   * @returns \p true if all elements and nodes of the mesh
   * exist on the current processor, \p false otherwise
   */
  virtual bool is_serial () const 
  { return true; }
  
  /**
   * Gathers all elements and nodes of the mesh onto
   * every processor
   */
  virtual void allgather () {}
  
  /**
   * When supported, deletes all nonlocal elements of the mesh
   * except for "ghosts" which touch a local element, and deletes
   * all nodes which are not part of a local or ghost element
   */
  virtual void delete_remote_elements () {}
  
  /**
   * @returns the logical dimension of the mesh; i.e. the manifold
   * dimension of the elements in the mesh.  If we ever support
   * multi-dimensional meshes (e.g. hexes and quads in the same mesh)
   * then this will return the largest such dimension.
   */
  unsigned int mesh_dimension () const
  { return static_cast<unsigned int>(_dim); }
  
  /**
   * Resets the logical dimension of the mesh.
   */
  void set_mesh_dimension (unsigned int d)
  { _dim = d; }
  
  /**
   * Returns the spatial dimension of the mesh.  Note that this is
   * defined at compile time in the header \p libmesh_common.h.
   */
  unsigned int spatial_dimension () const
  { return static_cast<unsigned int>(LIBMESH_DIM); }
  
  /**
   * Returns the number of nodes in the mesh. This function and others must
   * be defined in derived classes since the MeshBase class has no specific
   * storage for nodes or elements.
   */
  virtual unsigned int n_nodes () const = 0; 

  /**
   * Returns the number of nodes on processor \p proc.
   */
  unsigned int n_nodes_on_proc (const unsigned int proc) const;

  /**
   * Returns the number of nodes on the local processor.
   */
  unsigned int n_local_nodes () const
  { return this->n_nodes_on_proc (libMesh::processor_id()); }

  /**
   * Returns the number of nodes owned by no processor.
   */
  unsigned int n_unpartitioned_nodes () const
  { return this->n_nodes_on_proc (DofObject::invalid_processor_id); }

  /**
   * Returns a number greater than or equal to the maximum node id in the
   * mesh.
   */
  virtual unsigned int max_node_id () const = 0;

  /**
   * Reserves space for a known number of nodes.
   * Note that this method may or may not do anything, depending
   * on the actual \p Mesh implementation.  If you know the number
   * of nodes you will add and call this method before repeatedly
   * calling \p add_point() the implementation will be more efficient.
   */
  virtual void reserve_nodes (const unsigned int nn) = 0; 
  
  /**
   * Returns the number of elements in the mesh.
   */
  virtual unsigned int n_elem () const = 0; 

  /**
   * Returns a number greater than or equal to the maximum element id in the
   * mesh.
   */
  virtual unsigned int max_elem_id () const = 0;

  /**
   * Reserves space for a known number of elements.
   * Note that this method may or may not do anything, depending
   * on the actual \p Mesh implementation.  If you know the number
   * of elements you will add and call this method before repeatedly
   * calling \p add_point() the implementation will be more efficient.
   */
  virtual void reserve_elem (const unsigned int ne) = 0; 

  /**
   * Updates parallel caches so that methods like n_elem() 
   * accurately reflect changes on other processors
   */
  virtual void update_parallel_id_counts () = 0;

  /**
   * Returns the number of active elements in the mesh.  Implemented
   * in terms of active_element_iterators.
   */
  virtual unsigned int n_active_elem () const = 0;

  /**
   * Returns the number of elements on processor \p proc.
   */
  unsigned int n_elem_on_proc (const unsigned int proc) const;

  /**
   * Returns the number of elements on the local processor.
   */
  unsigned int n_local_elem () const
  { return this->n_elem_on_proc (libMesh::processor_id()); }

  /**
   * Returns the number of elements owned by no processor.
   */
  unsigned int n_unpartitioned_elem () const
  { return this->n_elem_on_proc (DofObject::invalid_processor_id); }

  /**
   * Returns the number of active elements on processor \p proc.
   */
  unsigned int n_active_elem_on_proc (const unsigned int proc) const;

  /**
   * Returns the number of active elements on the local processor.
   */
  unsigned int n_active_local_elem () const
  { return this->n_active_elem_on_proc (libMesh::processor_id()); }
  
  /**
   * This function returns the number of elements that will be written
   * out in the Tecplot format.  For example, a 9-noded quadrilateral will
   * be broken into 4 linear sub-elements for plotting purposes.  Thus, for
   * a mesh of 2 \p QUAD9 elements  \p n_tecplot_elem() will return 8.
   * Implemented in terms of element_iterators.
   */
  unsigned int n_sub_elem () const;

  /**
   * Same, but only counts active elements.
   */
  unsigned int n_active_sub_elem () const;
  
  /**
   * Return a constant reference (for reading only) to the
   * \f$ i^{th} \f$ point.
   */  
  virtual const Point& point (const unsigned int i) const = 0;

  /**
   * Return a constant reference (for reading only) to the
   * \f$ i^{th} \f$ node.
   */  
  virtual const Node& node (const unsigned int i) const = 0;
  
  /**
   * Return a reference to the \f$ i^{th} \f$ node.
   */  
  virtual Node& node (const unsigned int i) = 0;
  
  /**
   * Return a pointer to the \f$ i^{th} \f$ node.
   */  
  virtual const Node* node_ptr (const unsigned int i) const = 0;

  /**
   * Return a pointer to the \f$ i^{th} \f$ node.
   */  
  virtual Node* & node_ptr (const unsigned int i) = 0;

  /**
   * Return a pointer to the \f$ i^{th} \f$ element.
   */
  virtual Elem* elem (const unsigned int i) const = 0;

  /**
   * Add a new \p Node at \p Point \p p to the end of the vertex array,
   * with processor_id \p procid.
   * Use DofObject::invalid_processor_id (default) to add a node to all
   * processors, or libMesh::processor_id() to add a node to the local
   * processor only.
   * If adding a node locally, passing an \p id other than
   * DofObject::invalid_id will set that specific node id.  Only
   * do this in parallel if you are manually keeping ids consistent.
   */
  virtual Node* add_point (const Point& p,
			   const unsigned int id = DofObject::invalid_id,
			   const unsigned int proc_id =
			     DofObject::invalid_processor_id) = 0;

  /**
   * Add \p Node \p n to the end of the vertex array.
   */
  virtual Node* add_node (Node* n) = 0;

  /**
   * Removes the Node n from the mesh.
   */
  virtual void delete_node (Node* n) = 0;
  
  /**
   * Changes the id of node \p old_id, both by changing node(old_id)->id() and
   * by moving node(old_id) in the mesh's internal container.  No element with
   * the id \p new_id should already exist.
   */
  virtual void renumber_node (unsigned int old_id, unsigned int new_id) = 0;
		      
  /**
   * Add elem \p e to the end of the element array.
   * To add an element locally, set e->processor_id() before adding it.
   * To ensure a specific element id, call e->set_id() before adding it;
   * only do this in parallel if you are manually keeping ids consistent.
   */
  virtual Elem* add_elem (Elem* e) = 0;

  /**
   * Insert elem \p e to the element array, preserving its id
   * and replacing/deleting any existing element with the same id.
   */
  virtual Elem* insert_elem (Elem* e) = 0;

  /**
   * Removes element \p e from the mesh. Note that calling this
   * method may produce isolated nodes, i.e. nodes not connected
   * to any element.  This method must be implemented in derived classes
   * in such a way that it does not invalidate element iterators.
   */
  virtual void delete_elem (Elem* e) = 0;

  /**
   * Changes the id of element \p old_id, both by changing elem(old_id)->id()
   * and by moving elem(old_id) in the mesh's internal container.  No element
   * with the id \p new_id should already exist.
   */
  virtual void renumber_elem (unsigned int old_id, unsigned int new_id) = 0;

  /**
   * Locate element face (edge in 2D) neighbors.  This is done with the help
   * of a \p std::map that functions like a hash table.  
   * After this routine is called all the elements with a \p NULL neighbor
   * pointer are guaranteed to be on the boundary.  Thus this routine is
   * useful for automatically determining the boundaries of the domain.
   * If reset_remote_elements is left to false, remote neighbor links are not
   * reset and searched for in the local mesh.  If reset_current_list is
   * left as true, then any existing links will be reset before initiating
   * the algorithm, while honoring the value of the reset_remote_elements
   * flag.
   */
  virtual void find_neighbors (const bool reset_remote_elements = false,
			       const bool reset_current_list    = true) = 0;
  
  /**
   * After partitoning a mesh it is useful to renumber the nodes and elements
   * so that they lie in contiguous blocks on the processors.  This method
   * does just that.
   */
  virtual void renumber_nodes_and_elements () = 0;    

    /**
     * There is no reason for a user to ever call this function.
     *
     * This function restores a previously broken element/node numbering such that
     * \p mesh.node(n)->id() == n. 
     */
  virtual void fix_broken_node_and_element_numbering () = 0;
  

#ifdef LIBMESH_ENABLE_AMR
  /**
   * Delete subactive (i.e. children of coarsened) elements.
   * This removes all elements descended from currently active
   * elements in the mesh.
   */
  virtual bool contract () = 0;
#endif

  /**
   * Prepare a newly created (or read) mesh for use.
   * This involves 3 steps:
   *  1.) call \p find_neighbors()
   *  2.) call \p partition()
   *  3.) call \p renumber_nodes_and_elements() 
   *
   * The read_xda_file boolean flag is true when prepare_for_use
   * is called from Mesh::read after reading an xda file.  It prevents
   * the renumbering of nodes and elements.  In general, leave this at
   * the default value of false.
   *
   * skip_renumber is currently set to TRUE to work around an I/O bug
   */
  void prepare_for_use (const bool skip_renumber_nodes_and_elements=true);
  
  /**
   * Call the default partitioner (currently \p metis_partition()).
   */
  virtual void partition (const unsigned int n_parts=libMesh::n_processors());

  /**
   * If true is passed in then this mesh will no longer be (re)partitioned.
   * It would probably be a bad idea to call this on a Serial Mesh _before_
   * the first partitioning has happened... because no elements would get assigned
   * to your processor pool.
   *
   * Note that turning on skip_partitioning() can have adverse effects on your
   * performance when using AMR... ie you could get large load imbalances.
   *
   * However you might still want to use this if the communication and computation
   * of the rebalance and repartition is too high for your application.
   */
  void skip_partitioning(bool skip) { _skip_partitioning = skip; }
  bool skip_partitioning() { return _skip_partitioning; }
  
  /**
   * Returns the number of subdomains in the global mesh. Subdomains correspond
   * to separate subsets of the mesh which could correspond e.g. to different 
   * materials in a solid mechanics application, or regions where different
   * physical processes are important.  The subdomain mapping is independent
   * from the parallel decomposition.
   */
  unsigned int n_subdomains () const;

  /**
   * Returns the number of partitions which have been defined via
   * a call to either mesh.partition() or by building a Partitioner
   * object and calling partition.  Note that the partitioner objects
   * are responsible for setting this value.
   */
  unsigned int n_partitions () const
  { return _n_parts; }
  
  /**
   * @returns the number of processors used in the
   * current simulation.
   */
  unsigned int n_processors () const
  { return libMesh::n_processors(); }

  /**
   * @returns the subdomain id for this processor.
   */
  unsigned int processor_id () const
  { return libMesh::processor_id(); }

  /**
   * @returns a string containing relevant information
   * about the mesh.
   */
  std::string get_info () const;

  /**
   * Prints relevant information about the mesh.
   */
  void print_info (std::ostream& os=libMesh::out) const;

  /**
   * Equivalent to calling print_info() above, but now you can write:
   * Mesh mesh;
   * libMesh::out << mesh << std::endl;
   */
  friend std::ostream& operator << (std::ostream& os, const MeshBase& m);

  /**
   * Interfaces for reading/writing a mesh to/from a file.  Must be
   * implemented in derived classes.
   */
  virtual void read  (const std::string& name, MeshData* mesh_data=NULL,
		      bool skip_renumber_nodes_and_elements=false) = 0;
  virtual void write (const std::string& name, MeshData* mesh_data=NULL) = 0;

  /**
   * Converts a mesh with higher-order
   * elements into a mesh with linear elements.  For 
   * example, a mesh consisting of \p Tet10 will be converted
   * to a mesh with \p Tet4 etc.
   */
  virtual void all_first_order () = 0;

  /**
   * Converts a (conforming, non-refined) mesh with linear 
   * elements into a mesh with second-order elements.  For 
   * example, a mesh consisting of \p Tet4 will be converted
   * to a mesh with \p Tet10 etc.  Note that for some elements
   * like \p Hex8 there exist @e two higher order equivalents,
   * \p Hex20 and \p Hex27.  When \p full_ordered is \p true
   * (default), then \p Hex27 is built.  Otherwise, \p Hex20
   * is built.  The same holds obviously for \p Quad4, \p Prism6
   * ...
   */
  virtual void all_second_order (const bool full_ordered=true) = 0;

  /**
   * We need an empty, generic class to act as a predicate for this
   * and derived mesh classes.
   */
  typedef Predicates::multi_predicate Predicate;

  /**
   * structs for the element_iterator's.
   * Note that these iterators were designed so that derived mesh classes could use the
   * _same_ base class iterators interchangeably.  Their definition comes later in the
   * header file.
   */
  struct element_iterator;
  struct const_element_iterator;

  /**
   * structs for the node_iterator's.
   * Note that these iterators were designed so that derived mesh classes could use the
   * _same_ base class iterators interchangeably.  Their definition comes later in the
   * header file.
   */
  struct node_iterator;
  struct const_node_iterator;

  /**
   * In a few (very rare) cases, the user may have manually tagged the
   * elements with specific processor IDs by hand, without using a
   * partitioner.  In this case, the Mesh will not know that the total
   * number of partitions, _n_parts, has changed, unless you call this
   * function.  This is an O(N active elements) calculation.  The return
   * value is the number of partitions, and _n_parts is also set by
   * this function.  
   */
  unsigned int recalculate_n_partitions();

  /**
   * \p returns a pointer to a \p PointLocatorBase object for this
   * mesh, constructing a master PointLocator first if necessary.
   * This should never be used in threaded or non-parallel_only code,
   * and so is deprecated.
   */
  const PointLocatorBase& point_locator () const;

  /**
   * \p returns a pointer to a subordinate \p PointLocatorBase object
   * for this mesh, constructing a master PointLocator first if
   * necessary.  This should not be used in threaded or
   * non-parallel_only code unless the master has already been
   * constructed.
   */
  AutoPtr<PointLocatorBase> sub_point_locator () const;

  /**
   * Releases the current \p PointLocator object.
   */
  void clear_point_locator ();

  /**
   * Verify id and processor_id consistency of our elements and
   * nodes containers.
   * Calls libmesh_assert() on each possible failure.
   * Currently only implemented on ParallelMesh; a serial data
   * structure is much harder to get out of sync.
   */
  virtual void libmesh_assert_valid_parallel_ids() const {}

public:


  
  /**
   * Elem iterator accessor functions.  These must be defined in
   * Concrete base classes.
   */
  virtual element_iterator elements_begin                   () = 0;
  virtual element_iterator elements_end                     () = 0;
  virtual element_iterator active_elements_begin            () = 0;
  virtual element_iterator active_elements_end              () = 0;
  virtual element_iterator ancestor_elements_begin          () = 0;
  virtual element_iterator ancestor_elements_end            () = 0;
  virtual element_iterator subactive_elements_begin         () = 0;
  virtual element_iterator subactive_elements_end           () = 0;
  virtual element_iterator not_active_elements_begin        () = 0;
  virtual element_iterator not_active_elements_end          () = 0;
  virtual element_iterator not_ancestor_elements_begin      () = 0;
  virtual element_iterator not_ancestor_elements_end        () = 0;
  virtual element_iterator not_subactive_elements_begin     () = 0;
  virtual element_iterator not_subactive_elements_end       () = 0;
  virtual element_iterator local_elements_begin             () = 0;
  virtual element_iterator local_elements_end               () = 0;
  virtual element_iterator not_local_elements_begin         () = 0;
  virtual element_iterator not_local_elements_end           () = 0;
  virtual element_iterator active_local_elements_begin      () = 0;
  virtual element_iterator active_local_elements_end        () = 0;
  virtual element_iterator active_not_local_elements_begin  () = 0;
  virtual element_iterator active_not_local_elements_end    () = 0;
  virtual element_iterator level_elements_begin             (const unsigned int level  ) = 0;
  virtual element_iterator level_elements_end               (const unsigned int level  ) = 0;
  virtual element_iterator not_level_elements_begin         (const unsigned int level  ) = 0;
  virtual element_iterator not_level_elements_end           (const unsigned int level  ) = 0;
  virtual element_iterator local_level_elements_begin       (const unsigned int level  ) = 0;
  virtual element_iterator local_level_elements_end         (const unsigned int level  ) = 0;
  virtual element_iterator local_not_level_elements_begin   (const unsigned int level  ) = 0;
  virtual element_iterator local_not_level_elements_end     (const unsigned int level  ) = 0;
  virtual element_iterator pid_elements_begin               (const unsigned int proc_id) = 0;
  virtual element_iterator pid_elements_end                 (const unsigned int proc_id) = 0;
  virtual element_iterator type_elements_begin              (const ElemType type       ) = 0;
  virtual element_iterator type_elements_end                (const ElemType type       ) = 0;
  virtual element_iterator active_type_elements_begin       (const ElemType type       ) = 0;
  virtual element_iterator active_type_elements_end         (const ElemType type       ) = 0;
  virtual element_iterator active_pid_elements_begin        (const unsigned int proc_id) = 0;
  virtual element_iterator active_pid_elements_end          (const unsigned int proc_id) = 0;
  virtual element_iterator unpartitioned_elements_begin     () = 0;
  virtual element_iterator unpartitioned_elements_end       () = 0;
  virtual element_iterator active_local_subdomain_elements_begin         (const unsigned int subdomain_id) = 0;
  virtual element_iterator active_local_subdomain_elements_end           (const unsigned int subdomain_id) = 0;
  

  
  
  /**
   * const Elem iterator accessor functions.
   */
  virtual const_element_iterator elements_begin                   () const = 0;
  virtual const_element_iterator elements_end                     () const = 0;
  virtual const_element_iterator active_elements_begin            () const = 0;
  virtual const_element_iterator active_elements_end              () const = 0;
  virtual const_element_iterator ancestor_elements_begin          () const = 0;
  virtual const_element_iterator ancestor_elements_end            () const = 0;
  virtual const_element_iterator subactive_elements_begin         () const = 0;
  virtual const_element_iterator subactive_elements_end           () const = 0;
  virtual const_element_iterator not_active_elements_begin        () const = 0;
  virtual const_element_iterator not_active_elements_end          () const = 0;
  virtual const_element_iterator not_ancestor_elements_begin      () const = 0;
  virtual const_element_iterator not_ancestor_elements_end        () const = 0;
  virtual const_element_iterator not_subactive_elements_begin     () const = 0;
  virtual const_element_iterator not_subactive_elements_end       () const = 0;
  virtual const_element_iterator local_elements_begin             () const = 0;
  virtual const_element_iterator local_elements_end               () const = 0;
  virtual const_element_iterator not_local_elements_begin         () const = 0;
  virtual const_element_iterator not_local_elements_end           () const = 0;
  virtual const_element_iterator active_local_elements_begin      () const = 0;
  virtual const_element_iterator active_local_elements_end        () const = 0;
  virtual const_element_iterator active_not_local_elements_begin  () const = 0;
  virtual const_element_iterator active_not_local_elements_end    () const = 0;
  virtual const_element_iterator level_elements_begin             (const unsigned int level)   const = 0;
  virtual const_element_iterator level_elements_end               (const unsigned int level)   const = 0;
  virtual const_element_iterator not_level_elements_begin         (const unsigned int level)   const = 0;
  virtual const_element_iterator not_level_elements_end           (const unsigned int level)   const = 0;
  virtual const_element_iterator local_level_elements_begin       (const unsigned int level)   const = 0;
  virtual const_element_iterator local_level_elements_end         (const unsigned int level)   const = 0;
  virtual const_element_iterator local_not_level_elements_begin   (const unsigned int level)   const = 0;
  virtual const_element_iterator local_not_level_elements_end     (const unsigned int level)   const = 0;
  virtual const_element_iterator pid_elements_begin               (const unsigned int proc_id) const = 0;
  virtual const_element_iterator pid_elements_end                 (const unsigned int proc_id) const = 0;
  virtual const_element_iterator type_elements_begin              (const ElemType type)        const = 0;
  virtual const_element_iterator type_elements_end                (const ElemType type)        const = 0;
  virtual const_element_iterator active_type_elements_begin       (const ElemType type)        const = 0;
  virtual const_element_iterator active_type_elements_end         (const ElemType type)        const = 0;
  virtual const_element_iterator active_pid_elements_begin        (const unsigned int proc_id) const = 0;
  virtual const_element_iterator active_pid_elements_end          (const unsigned int proc_id) const = 0;
  virtual const_element_iterator unpartitioned_elements_begin     () const = 0;
  virtual const_element_iterator unpartitioned_elements_end       () const = 0;
  virtual const_element_iterator active_local_subdomain_elements_begin (const unsigned int subdomain_id) const = 0;
  virtual const_element_iterator active_local_subdomain_elements_end   (const unsigned int subdomain_id) const = 0;

  
  /**
   * non-const Node iterator accessor functions.
   */
  virtual node_iterator nodes_begin        () = 0;
  virtual node_iterator nodes_end          () = 0;
  virtual node_iterator active_nodes_begin () = 0;
  virtual node_iterator active_nodes_end   () = 0;
  virtual node_iterator local_nodes_begin  () = 0;
  virtual node_iterator local_nodes_end    () = 0;
  virtual node_iterator pid_nodes_begin    (const unsigned int proc_id) = 0;
  virtual node_iterator pid_nodes_end      (const unsigned int proc_id) = 0;


  /**
   * const Node iterator accessor functions.
   */
  virtual const_node_iterator nodes_begin        () const = 0;
  virtual const_node_iterator nodes_end          () const = 0;
  virtual const_node_iterator active_nodes_begin () const = 0;
  virtual const_node_iterator active_nodes_end   () const = 0;
  virtual const_node_iterator local_nodes_begin  () const = 0;
  virtual const_node_iterator local_nodes_end    () const = 0;
  virtual const_node_iterator pid_nodes_begin    (const unsigned int proc_id) const = 0;
  virtual const_node_iterator pid_nodes_end      (const unsigned int proc_id) const = 0;


  
protected:



  
  

  /**
   * Returns a writeable reference to the number of partitions.
   */
  unsigned int& set_n_partitions ()
  { return _n_parts; }
  
  /**
   * The number of partitions the mesh has.  This is set by
   * the partitioners, and may not be changed directly by
   * the user.
   * **NOTE** The number of partitions *need not* equal
   * libMesh::n_processors(), consider for example the case
   * where you simply want to partition a mesh on one
   * processor and view the result in GMV.
   */
  unsigned int _n_parts;
  
  /**
   * The logical dimension of the mesh.
   */     
  unsigned int _dim;

  /**
   * Flag indicating if the mesh has been prepared for use.
   */
  bool _is_prepared;
  
  /**
   * A \p PointLocator class for this mesh. 
   * This will not actually be built unless needed. Further, since we want 
   * our \p point_locator() method to be \p const (yet do the dynamic allocating)
   * this needs to be mutable.  Since the PointLocatorBase::build() member is used, 
   * and it operates on a constant reference to the mesh, this is OK.
   */
  mutable AutoPtr<PointLocatorBase> _point_locator;

  /**
   * A partitioner to use at each prepare_for_use().
   *
   * This will be built in the constructor of each derived class, but
   * can be replaced by the user through the partitioner() accessor.
   */
  AutoPtr<Partitioner> _partitioner;

  /**
   * If this is true then no partitioning should be done.
   */
  bool _skip_partitioning;
  
  /**
   * The partitioner class is a friend so that it can set
   * the number of partitions.
   */
  friend class Partitioner;

  /**
   * Make the \p BoundaryInfo class a friend so that
   * it can create and interact with \p BoundaryMesh.
   */
  friend class BoundaryInfo;

};











/**
 * The definition of the element_iterator struct.
 */
struct
MeshBase::element_iterator :
variant_filter_iterator<MeshBase::Predicate,
			Elem*>
{
  // Templated forwarding ctor -- forwards to appropriate variant_filter_iterator ctor
  template <typename PredType, typename IterType>
  element_iterator (const IterType& d,
		    const IterType& e,
		    const PredType& p ) :
    variant_filter_iterator<MeshBase::Predicate,
			    Elem*>(d,e,p) {}
};




/**
 * The definition of the const_element_iterator struct.  It is similar to the regular
 * iterator above, but also provides an additional conversion-to-const ctor.
 */
struct
MeshBase::const_element_iterator :
variant_filter_iterator<MeshBase::Predicate,
			Elem* const,
			Elem* const&,
			Elem* const*>
{
  // Templated forwarding ctor -- forwards to appropriate variant_filter_iterator ctor
  template <typename PredType, typename IterType>
  const_element_iterator (const IterType& d,
			  const IterType& e,
			  const PredType& p ) :
    variant_filter_iterator<MeshBase::Predicate,
			    Elem* const,
			    Elem* const&,
			    Elem* const*>(d,e,p)  {}


  // The conversion-to-const ctor.  Takes a regular iterator and calls the appropriate
  // variant_filter_iterator copy constructor.  Note that this one is *not* templated!
  const_element_iterator (const MeshBase::element_iterator& rhs) :
    variant_filter_iterator<Predicate,
			    Elem* const,
			    Elem* const&,
			    Elem* const*>(rhs)
  {
    // libMesh::out << "Called element_iterator conversion-to-const ctor." << std::endl;
  }
};







/**
 * The definition of the node_iterator struct.
 */
struct
MeshBase::node_iterator :
variant_filter_iterator<MeshBase::Predicate,
			Node*>
{
  // Templated forwarding ctor -- forwards to appropriate variant_filter_iterator ctor
  template <typename PredType, typename IterType>
  node_iterator (const IterType& d,
		 const IterType& e,
		 const PredType& p ) :
    variant_filter_iterator<MeshBase::Predicate,
			    Node*>(d,e,p) {}
};




/**
 * The definition of the const_node_iterator struct.  It is similar to the regular
 * iterator above, but also provides an additional conversion-to-const ctor.
 */
struct
MeshBase::const_node_iterator :
variant_filter_iterator<MeshBase::Predicate,
			Node* const,
			Node* const &,
			Node* const *>
{
  // Templated forwarding ctor -- forwards to appropriate variant_filter_iterator ctor
  template <typename PredType, typename IterType>
  const_node_iterator (const IterType& d,
		       const IterType& e,
		       const PredType& p ) :
    variant_filter_iterator<MeshBase::Predicate,
			    Node* const,
			    Node* const &,
			    Node* const *>(d,e,p)  {}


  // The conversion-to-const ctor.  Takes a regular iterator and calls the appropriate
  // variant_filter_iterator copy constructor.  Note that this one is *not* templated!
  const_node_iterator (const MeshBase::node_iterator& rhs) :
    variant_filter_iterator<Predicate,
			    Node* const,
			    Node* const &,
			    Node* const *>(rhs)
  {
    // libMesh::out << "Called node_iterator conversion-to-const ctor." << std::endl;
  }
};


} // namespace libMesh

#endif