libMesh
dof_object.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2017 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 
20 #ifndef LIBMESH_DOF_OBJECT_H
21 #define LIBMESH_DOF_OBJECT_H
22 
23 // Local includes
24 #include "libmesh/id_types.h"
25 #include "libmesh/libmesh_config.h"
26 #include "libmesh/libmesh_common.h"
27 #include "libmesh/libmesh.h" // libMesh::invalid_uint
28 #include "libmesh/reference_counted_object.h"
29 
30 // C++ includes
31 #include <cstddef>
32 #include <vector>
33 
34 namespace libMesh
35 {
36 
37 // Forward declarations
38 class DofObject;
39 
40 
51 class DofObject : public ReferenceCountedObject<DofObject>
52 {
53 #ifdef LIBMESH_IS_UNIT_TESTING
54 public:
55 #else
56 protected:
57 #endif
58 
63  DofObject ();
64 
69  ~DofObject ();
70 
71 public:
72 
73 #ifdef LIBMESH_ENABLE_AMR
74 
80 
84  void clear_old_dof_object ();
85 
89  void set_old_dof_object ();
90 
91 #endif
92 
97  void clear_dofs ();
98 
102  void invalidate_dofs (const unsigned int sys_num = libMesh::invalid_uint);
103 
107  void invalidate_id ();
108 
112  void invalidate_processor_id ();
113 
117  void invalidate ();
118 
124  unsigned int n_dofs (const unsigned int s,
125  const unsigned int var =
126  libMesh::invalid_uint) const;
127 
131  dof_id_type id () const;
132 
136  dof_id_type & set_id ();
137 
141  unique_id_type unique_id () const;
142 
147 
151  void set_id (const dof_id_type dofid)
152  { this->set_id() = dofid; }
153 
158  bool valid_id () const;
159 
164  bool valid_unique_id () const;
165 
174 
180 
184  void processor_id (const processor_id_type pid);
185 
190  bool valid_processor_id () const;
191 
196  unsigned int n_systems() const;
197 
201  void set_n_systems (const unsigned int s);
202 
206  void add_system ();
207 
212  unsigned int n_var_groups(const unsigned int s) const;
213 
218  unsigned int n_vars(const unsigned int s,
219  const unsigned int vg) const;
220 
225  unsigned int n_vars(const unsigned int s) const;
226 
234  void set_n_vars_per_group(const unsigned int s,
235  const std::vector<unsigned int> & nvpg);
236 
246  unsigned int n_comp(const unsigned int s,
247  const unsigned int var) const;
248 
258  unsigned int n_comp_group(const unsigned int s,
259  const unsigned int vg) const;
260 
265  void set_n_comp(const unsigned int s,
266  const unsigned int var,
267  const unsigned int ncomp);
268 
273  void set_n_comp_group(const unsigned int s,
274  const unsigned int vg,
275  const unsigned int ncomp);
276 
285  dof_id_type dof_number(const unsigned int s,
286  const unsigned int var,
287  const unsigned int comp) const;
288 
293  void set_dof_number(const unsigned int s,
294  const unsigned int var,
295  const unsigned int comp,
296  const dof_id_type dn);
297 
302  bool has_dofs(const unsigned int s=libMesh::invalid_uint) const;
303 
309  void set_vg_dof_base(const unsigned int s,
310  const unsigned int vg,
311  const dof_id_type db);
312 
318  dof_id_type vg_dof_base(const unsigned int s,
319  const unsigned int vg) const;
320 
324  static const dof_id_type invalid_id = static_cast<dof_id_type>(-1);
325 
329  static const unique_id_type invalid_unique_id = static_cast<unique_id_type>(-1);
330 
336 
341  unsigned int packed_indexing_size() const;
342 
347  static unsigned int unpackable_indexing_size
348  (std::vector<largest_id_type>::const_iterator begin);
349 
355  void unpack_indexing(std::vector<largest_id_type>::const_iterator begin);
356 
362  void pack_indexing(std::back_insert_iterator<std::vector<largest_id_type>> target) const;
363 
367  void debug_buffer () const;
368 
372  void print_dof_info() const;
373 
374  // Deep copy (or almost-copy) of DofObjects is now deprecated in
375  // derived classes; we keep these methods around solely for a couple
376  // tricky internal uses.
377 #ifndef LIBMESH_ENABLE_DEPRECATED
378 private:
379 #endif
380 
385  DofObject (const DofObject &);
386 
390  DofObject & operator= (const DofObject & dof_obj);
391 
392 private:
393 
398  unsigned int var_to_vg (const unsigned int s,
399  const unsigned int var) const;
400 
405  unsigned int system_var_to_vg_var (const unsigned int s,
406  const unsigned int vg,
407  const unsigned int var) const;
408 
412 #ifdef LIBMESH_ENABLE_UNIQUE_ID
414 #endif
415 
420 
431 
484  typedef std::vector<index_t> index_buffer_t;
485  index_buffer_t _idx_buf;
486 
496  static const index_t ncv_magic = 256; // = 2^8, in case we want to manually bitshift
497  static const index_t ncv_magic_exp = 8; // Let's manually bitshift
498 
502  unsigned int start_idx(const unsigned int s) const;
503 
507  unsigned int end_idx(const unsigned int s) const;
508 
509  // methods only available for unit testing
510 #ifdef LIBMESH_IS_UNIT_TESTING
511 public:
512  void set_buffer (const std::vector<dof_id_type> & buf)
513  { _idx_buf = buf; }
514 #endif
515 };
516 
517 
518 
519 //------------------------------------------------------
520 // Inline functions
521 inline
523 #ifdef LIBMESH_ENABLE_AMR
525 #endif
526 #ifdef LIBMESH_ENABLE_UNIQUE_ID
528 #endif
529  _id (invalid_id),
531 {
532  this->invalidate();
533 }
534 
535 
536 
537 
538 
539 inline
541 {
542  // Free all memory.
543 #ifdef LIBMESH_ENABLE_AMR
544  this->clear_old_dof_object ();
545 #endif
546  this->clear_dofs ();
547 }
548 
549 
550 
551 inline
552 void DofObject::invalidate_dofs (const unsigned int sys_num)
553 {
554  // If the user does not specify the system number...
555  if (sys_num >= this->n_systems())
556  {
557  for (unsigned int s=0; s<this->n_systems(); s++)
558  for (unsigned int vg=0; vg<this->n_var_groups(s); vg++)
559  if (this->n_comp_group(s,vg))
560  this->set_vg_dof_base(s,vg,invalid_id);
561  }
562  // ...otherwise invalidate the dofs for all systems
563  else
564  for (unsigned int vg=0; vg<this->n_var_groups(sys_num); vg++)
565  if (this->n_comp_group(sys_num,vg))
566  this->set_vg_dof_base(sys_num,vg,invalid_id);
567 }
568 
569 
570 
571 inline
573 {
574  this->set_id (invalid_id);
575 }
576 
577 
578 
579 inline
581 {
583 }
584 
585 
586 
587 inline
589 {
590  this->invalidate_dofs ();
591  this->invalidate_id ();
592  this->invalidate_processor_id ();
593 }
594 
595 
596 
597 inline
599 {
600  // vector swap trick to force deallocation
601  index_buffer_t().swap(_idx_buf);
602 
603  libmesh_assert_equal_to (this->n_systems(), 0);
604  libmesh_assert (_idx_buf.empty());
605 }
606 
607 
608 
609 inline
610 unsigned int DofObject::n_dofs (const unsigned int s,
611  const unsigned int var) const
612 {
613  libmesh_assert_less (s, this->n_systems());
614 
615  unsigned int num = 0;
616 
617  // Count all variables
618  if (var == libMesh::invalid_uint)
619  for (unsigned int v=0; v<this->n_vars(s); v++)
620  num += this->n_comp(s,v);
621 
622  // Only count specified variable
623  else
624  num = this->n_comp(s,var);
625 
626  return num;
627 }
628 
629 
630 
631 inline
633 {
634  libmesh_assert (this->valid_id());
635  return _id;
636 }
637 
638 
639 
640 inline
642 {
643  return _id;
644 }
645 
646 
647 
648 inline
650 {
651 #ifdef LIBMESH_ENABLE_UNIQUE_ID
653  return _unique_id;
654 #else
655  return invalid_unique_id;
656 #endif
657 }
658 
659 
660 
661 inline
663 {
664 #ifdef LIBMESH_ENABLE_UNIQUE_ID
665  return _unique_id;
666 #else
667  libmesh_not_implemented();
668 #endif
669 }
670 
671 
672 
673 inline
674 bool DofObject::valid_id () const
675 {
676  return (DofObject::invalid_id != _id);
677 }
678 
679 
680 
681 inline
683 {
684 #ifdef LIBMESH_ENABLE_UNIQUE_ID
686 #else
687  return false;
688 #endif
689 }
690 
691 
692 
693 inline
695 {
696  return _processor_id;
697 }
698 
699 
700 
701 inline
703 {
704  return _processor_id;
705 }
706 
707 
708 
709 inline
711 {
712  this->processor_id() = pid;
713 }
714 
715 
716 
717 inline
719 {
721 }
722 
723 
724 
725 inline
726 unsigned int DofObject::n_systems () const
727 {
728  return _idx_buf.empty() ?
729  0 : cast_int<unsigned int>(_idx_buf[0]);
730 }
731 
732 
733 
734 inline
735 unsigned int DofObject::n_var_groups(const unsigned int s) const
736 {
737  libmesh_assert_less (s, this->n_systems());
738 
739  return (this->end_idx(s) - this->start_idx(s)) / 2;
740 }
741 
742 
743 
744 inline
745 unsigned int DofObject::n_vars(const unsigned int s,
746  const unsigned int vg) const
747 {
748  libmesh_assert_less (s, this->n_systems());
749  libmesh_assert_less (vg, this->n_var_groups(s));
750 
751  const unsigned int start_idx_sys = this->start_idx(s);
752 
753  libmesh_assert_less ((start_idx_sys + 2*vg), _idx_buf.size());
754 
755  return (cast_int<unsigned int>
756  (_idx_buf[start_idx_sys + 2*vg]) >> ncv_magic_exp);
757 }
758 
759 
760 
761 inline
762 unsigned int DofObject::n_vars(const unsigned int s) const
763 {
764  libmesh_assert_less (s, this->n_systems());
765 
766  const unsigned int nvg = this->n_var_groups(s);
767 
768  unsigned int val=0;
769 
770  for (unsigned int vg=0; vg<nvg; vg++)
771  val += this->n_vars(s,vg);
772 
773  return val;
774 }
775 
776 
777 
778 
779 inline
780 unsigned int DofObject::n_comp(const unsigned int s,
781  const unsigned int var) const
782 {
783  libmesh_assert_less (s, this->n_systems());
784  libmesh_assert_less (var, this->n_vars(s));
785 
786  return this->n_comp_group(s,this->var_to_vg(s,var));
787 }
788 
789 
790 
791 
792 inline
793 unsigned int DofObject::n_comp_group(const unsigned int s,
794  const unsigned int vg) const
795 {
796  libmesh_assert_less (s, this->n_systems());
797  libmesh_assert_less (vg, this->n_var_groups(s));
798 
799  const unsigned int
800  start_idx_sys = this->start_idx(s);
801 
802  libmesh_assert_less ((start_idx_sys + 2*vg), _idx_buf.size());
803 
804  return (_idx_buf[start_idx_sys + 2*vg] % ncv_magic);
805 }
806 
807 
808 
809 inline
810 dof_id_type DofObject::dof_number(const unsigned int s,
811  const unsigned int var,
812  const unsigned int comp) const
813 {
814  libmesh_assert_less (s, this->n_systems());
815  libmesh_assert_less (var, this->n_vars(s));
816  libmesh_assert_less (comp, this->n_comp(s,var));
817 
818  const unsigned int
819  vg = this->var_to_vg(s,var),
820  start_idx_sys = this->start_idx(s);
821 
822  libmesh_assert_less ((start_idx_sys + 2*vg + 1), _idx_buf.size());
823 
824  const dof_id_type
825  base_idx = _idx_buf[start_idx_sys + 2*vg + 1];
826 
827  // if the first component is invalid, they
828  // are all invalid
829  if (base_idx == invalid_id)
830  return invalid_id;
831 
832  // otherwise the index is the first component
833  // index augmented by the component number
834  else
835  {
836  const unsigned int
837  ncg = this->n_comp_group(s,vg),
838  vig = this->system_var_to_vg_var(s,vg,var);
839 
840  // std::cout << "base_idx, var, vg, vig, ncg, comp="
841  // << base_idx << " "
842  // << var << " "
843  // << vg << " "
844  // << vig << " "
845  // << ncg << " "
846  // << comp << '\n';
847 
848  return cast_int<dof_id_type>(base_idx + vig*ncg + comp);
849  }
850 }
851 
852 
853 
854 inline
855 bool DofObject::has_dofs (const unsigned int sys) const
856 {
857  if (sys == libMesh::invalid_uint)
858  {
859  for (unsigned int s=0; s<this->n_systems(); s++)
860  if (this->n_vars(s))
861  return true;
862  }
863 
864  else
865  {
866  libmesh_assert_less (sys, this->n_systems());
867 
868  if (this->n_vars(sys))
869  return true;
870  }
871 
872  return false;
873 }
874 
875 
876 
877 inline
878 unsigned int DofObject::start_idx (const unsigned int s) const
879 {
880  libmesh_assert_less (s, this->n_systems());
881  libmesh_assert_less (s, _idx_buf.size());
882 
883  return cast_int<unsigned int>(_idx_buf[s]);
884 }
885 
886 
887 
888 inline
889 unsigned int DofObject::end_idx (const unsigned int s) const
890 {
891  libmesh_assert_less (s, this->n_systems());
892  libmesh_assert_less (s, _idx_buf.size());
893 
894  return ((s+1) == this->n_systems()) ?
895  cast_int<unsigned int>(_idx_buf.size()) :
896  cast_int<unsigned int>(_idx_buf[s+1]);
897 }
898 
899 
900 
901 inline
902 void DofObject::set_vg_dof_base(const unsigned int s,
903  const unsigned int vg,
904  const dof_id_type db)
905 {
906  libmesh_assert_less (s, this->n_systems());
907  libmesh_assert_less (vg, this->n_var_groups(s));
908 
909  const unsigned int
910  start_idx_sys = this->start_idx(s);
911 
912  libmesh_assert_less ((start_idx_sys + 2*vg + 1), _idx_buf.size());
913 
914  _idx_buf[start_idx_sys + 2*vg + 1] = db;
915 
916  libmesh_assert_equal_to (this->vg_dof_base(s,vg), db);
917 }
918 
919 
920 
921 inline
922 dof_id_type DofObject::vg_dof_base(const unsigned int s,
923  const unsigned int vg) const
924 {
925  libmesh_assert_less (s, this->n_systems());
926  libmesh_assert_less (vg, this->n_var_groups(s));
927 
928  const unsigned int
929  start_idx_sys = this->start_idx(s);
930 
931  libmesh_assert_less ((start_idx_sys + 2*vg + 1), _idx_buf.size());
932 
933  // #ifdef DEBUG
934  // std::cout << " [ ";
935  // for (std:size_t i=0; i<_idx_buf.size(); i++)
936  // std::cout << _idx_buf[i] << " ";
937  // std::cout << "]\n";
938  // #endif
939 
940  return _idx_buf[start_idx_sys + 2*vg + 1];
941 }
942 
943 
944 
945 inline
946 unsigned int DofObject::var_to_vg (const unsigned int s,
947  const unsigned int var) const
948 {
949  const unsigned int
950  nvg = this->n_var_groups(s);
951 
952  for (unsigned int vg=0, vg_end=0; vg<nvg; vg++)
953  {
954  vg_end += this->n_vars(s,vg);
955  if (var < vg_end) return vg;
956  }
957 
958  libmesh_error_msg("We'll never get here!");
959  return 0;
960 }
961 
962 
963 
964 inline
965 unsigned int DofObject::system_var_to_vg_var (const unsigned int s,
966  const unsigned int vg,
967  const unsigned int var) const
968 {
969  unsigned int accumulated_sum=0;
970 
971  for (unsigned int vgc=0; vgc<vg; vgc++)
972  accumulated_sum += this->n_vars(s,vgc);
973 
974  libmesh_assert_less_equal (accumulated_sum, var);
975 
976  return (var - accumulated_sum);
977 }
978 
979 
980 } // namespace libMesh
981 
982 
983 #endif // #ifndef LIBMESH_DOF_OBJECT_H
unsigned int n_comp_group(const unsigned int s, const unsigned int vg) const
Definition: dof_object.h:793
bool has_dofs(const unsigned int s=libMesh::invalid_uint) const
Definition: dof_object.h:855
void set_n_comp(const unsigned int s, const unsigned int var, const unsigned int ncomp)
Sets the number of components for Variable var of system s associated with this DofObject.
Definition: dof_object.C:345
unique_id_type & set_unique_id()
Definition: dof_object.h:662
bool valid_id() const
Definition: dof_object.h:674
void set_old_dof_object()
Sets the old_dof_object to a copy of this.
Definition: dof_object.C:150
void clear_dofs()
Clear the DofMap data structures and return to a pristine state.
Definition: dof_object.h:598
static unsigned int unpackable_indexing_size(std::vector< largest_id_type >::const_iterator begin)
If we have indices packed into an buffer for communications, how much of that buffer applies to this ...
Definition: dof_object.C:473
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value.
Definition: libmesh.h:184
unsigned int n_vars(const unsigned int s, const unsigned int vg) const
Definition: dof_object.h:745
ImplicitSystem & sys
void set_id(const dof_id_type dofid)
Sets the id for this DofObject.
Definition: dof_object.h:151
uint8_t processor_id_type
Definition: id_types.h:99
unsigned int n_dofs(const unsigned int s, const unsigned int var=libMesh::invalid_uint) const
Definition: dof_object.h:610
const class libmesh_nullptr_t libmesh_nullptr
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
Definition: dof_object.h:810
dof_id_type _id
The id of the DofObject.
Definition: dof_object.h:419
void invalidate()
Invalidates all the indices for this DofObject.
Definition: dof_object.h:588
~DofObject()
Destructor.
Definition: dof_object.h:540
unsigned int system_var_to_vg_var(const unsigned int s, const unsigned int vg, const unsigned int var) const
Utility function - for variable var in system s, figure out what variable group it lives in...
Definition: dof_object.h:965
void print_dof_info() const
Print out info for debugging.
Definition: dof_object.C:560
void set_vg_dof_base(const unsigned int s, const unsigned int vg, const dof_id_type db)
VariableGroup DoF indices are indexed as id = base + var_in_vg*ncomp + comp This method allows for di...
Definition: dof_object.h:902
The libMesh namespace provides an interface to certain functionality in the library.
dof_id_type & set_id()
Definition: dof_object.h:641
bool valid_unique_id() const
Definition: dof_object.h:682
libmesh_assert(j)
unsigned int end_idx(const unsigned int s) const
The ending index for system s.
Definition: dof_object.h:889
DofObject()
Constructor.
Definition: dof_object.h:522
dof_id_type index_t
DoF index information.
Definition: dof_object.h:483
unique_id_type _unique_id
A globally unique id, guaranteed not to change as the mesh is repartitioned or adapted.
Definition: dof_object.h:413
void add_system()
Adds an additional system to the DofObject.
Definition: dof_object.C:195
void pack_indexing(std::back_insert_iterator< std::vector< largest_id_type >> target) const
A method for creating packed data from our index buffer - basically a copy with prepended size with o...
Definition: dof_object.C:532
dof_id_type vg_dof_base(const unsigned int s, const unsigned int vg) const
VariableGroup DoF indices are indexed as id = base + var_in_vg*ncomp + comp This method allows for di...
Definition: dof_object.h:922
bool valid_processor_id() const
Definition: dof_object.h:718
void set_buffer(const std::vector< dof_id_type > &buf)
Definition: dof_object.h:512
DofObject & operator=(const DofObject &dof_obj)
Deep-copying assignment operator.
Definition: dof_object.C:90
static const unique_id_type invalid_unique_id
An invalid unique_id to distinguish an uninitialized DofObject.
Definition: dof_object.h:329
static const processor_id_type invalid_processor_id
An invalid processor_id to distinguish DoFs that have not been assigned to a processor.
Definition: dof_object.h:335
void set_dof_number(const unsigned int s, const unsigned int var, const unsigned int comp, const dof_id_type dn)
Sets the global degree of freedom number for variable var, component comp for system s associated wit...
Definition: dof_object.C:414
unsigned int n_var_groups(const unsigned int s) const
Definition: dof_object.h:735
void clear_old_dof_object()
Sets the old_dof_object to libmesh_nullptr.
Definition: dof_object.C:142
void invalidate_id()
Sets the id to invalid_id.
Definition: dof_object.h:572
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:324
unsigned int start_idx(const unsigned int s) const
The starting index for system s.
Definition: dof_object.h:878
This class implements reference counting.
void invalidate_processor_id()
Sets the processor id to invalid_processor_id.
Definition: dof_object.h:580
std::vector< index_t > index_buffer_t
Definition: dof_object.h:484
void set_n_comp_group(const unsigned int s, const unsigned int vg, const unsigned int ncomp)
Sets the number of components for VariableGroup vg of system s associated with this DofObject...
Definition: dof_object.C:357
unsigned int packed_indexing_size() const
If we pack our indices into an buffer for communications, how many ints do we need?
Definition: dof_object.C:457
void set_n_systems(const unsigned int s)
Sets the number of systems for this DofObject.
Definition: dof_object.C:165
unsigned int var_to_vg(const unsigned int s, const unsigned int var) const
Utility function - for variable var in system s, figure out what variable group it lives in...
Definition: dof_object.h:946
void set_n_vars_per_group(const unsigned int s, const std::vector< unsigned int > &nvpg)
Sets number of variables in each group associated with system s for this DofObject.
Definition: dof_object.C:227
DofObject * old_dof_object
This object on the last mesh.
Definition: dof_object.h:79
void invalidate_dofs(const unsigned int sys_num=libMesh::invalid_uint)
Sets all degree of freedom numbers to invalid_id.
Definition: dof_object.h:552
void unpack_indexing(std::vector< largest_id_type >::const_iterator begin)
A method for creating our index buffer from packed data - basically with our current implementation w...
Definition: dof_object.C:494
The DofObject defines an abstract base class for objects that have degrees of freedom associated with...
Definition: dof_object.h:51
index_buffer_t _idx_buf
Definition: dof_object.h:485
unsigned int n_comp(const unsigned int s, const unsigned int var) const
Definition: dof_object.h:780
dof_id_type id() const
Definition: dof_object.h:632
unsigned int n_systems() const
Definition: dof_object.h:726
void debug_buffer() const
Print our buffer for debugging.
Definition: dof_object.C:550
unique_id_type unique_id() const
Definition: dof_object.h:649
uint8_t unique_id_type
Definition: id_types.h:79
processor_id_type _processor_id
The processor_id of the DofObject.
Definition: dof_object.h:430
static const index_t ncv_magic_exp
Definition: dof_object.h:497
uint8_t dof_id_type
Definition: id_types.h:64
processor_id_type processor_id() const
Definition: dof_object.h:694
static const index_t ncv_magic
Above we introduced the chimera ncv, which is a hybrid of the form ncv = ncv_magic*nv + nc where nv a...
Definition: dof_object.h:496