libMesh
elem_refinement.C
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 // C++ includes
21 
22 // Local includes
23 #include "libmesh/elem.h"
24 #include "libmesh/mesh_refinement.h"
25 #include "libmesh/remote_elem.h"
26 
27 namespace libMesh
28 {
29 
30 
31 //--------------------------------------------------------------------
32 // Elem methods
33 
39 #ifdef LIBMESH_ENABLE_AMR
40 
41 void Elem::refine (MeshRefinement & mesh_refinement)
42 {
43  libmesh_assert_equal_to (this->refinement_flag(), Elem::REFINE);
44  libmesh_assert (this->active());
45 
46  const unsigned int nc = this->n_children();
47 
48  // Create my children if necessary
49  if (!_children)
50  {
51  _children = new Elem *[nc];
52 
53  unsigned int parent_p_level = this->p_level();
54  for (unsigned int c = 0; c != nc; c++)
55  {
56  _children[c] = Elem::build(this->type(), this).release();
57  Elem * current_child = this->child_ptr(c);
58 
60  current_child->set_p_level(parent_p_level);
61  current_child->set_p_refinement_flag(this->p_refinement_flag());
62 
63  for (unsigned int nc=0; nc<current_child->n_nodes(); nc++)
64  {
65  Node * node =
66  mesh_refinement.add_node(*this, c, nc,
67  current_child->processor_id());
68  node->set_n_systems (this->n_systems());
69  current_child->set_node(nc) = node;
70  }
71 
72  mesh_refinement.add_elem (current_child);
73  current_child->set_n_systems(this->n_systems());
74  }
75  }
76  else
77  {
78  unsigned int parent_p_level = this->p_level();
79  for (unsigned int c = 0; c != nc; c++)
80  {
81  Elem * current_child = this->child_ptr(c);
82  libmesh_assert(current_child->subactive());
84  current_child->set_p_level(parent_p_level);
85  current_child->set_p_refinement_flag(this->p_refinement_flag());
86  }
87  }
88 
89  // Un-set my refinement flag now
91 
92  // Leave the p refinement flag set - we will need that later to get
93  // projection operations correct
94  // this->set_p_refinement_flag(Elem::INACTIVE);
95 
96  for (unsigned int c = 0; c != nc; c++)
97  {
98  libmesh_assert_equal_to (this->child_ptr(c)->parent(), this);
99  libmesh_assert(this->child_ptr(c)->active());
100  }
101  libmesh_assert (this->ancestor());
102 }
103 
104 
105 
107 {
108  libmesh_assert_equal_to (this->refinement_flag(), Elem::COARSEN_INACTIVE);
109  libmesh_assert (!this->active());
110 
111  // We no longer delete children until MeshRefinement::contract()
112  // delete [] _children;
113  // _children = libmesh_nullptr;
114 
115  unsigned int parent_p_level = 0;
116 
117  // re-compute hanging node nodal locations
118  for (unsigned int c = 0, nc = this->n_children(); c != nc; ++c)
119  {
120  Elem * mychild = this->child_ptr(c);
121  if (mychild == remote_elem)
122  continue;
123  for (unsigned int nc=0; nc != mychild->n_nodes(); nc++)
124  {
125  Point new_pos;
126  bool calculated_new_pos = false;
127 
128  for (unsigned int n=0; n<this->n_nodes(); n++)
129  {
130  // The value from the embedding matrix
131  const float em_val = this->embedding_matrix(c,nc,n);
132 
133  // The node location is somewhere between existing vertices
134  if ((em_val != 0.) && (em_val != 1.))
135  {
136  new_pos.add_scaled (this->point(n), em_val);
137  calculated_new_pos = true;
138  }
139  }
140 
141  if (calculated_new_pos)
142  {
143  //Move the existing node back into it's original location
144  for (unsigned int i=0; i<LIBMESH_DIM; i++)
145  {
146  Point & child_node = mychild->point(nc);
147  child_node(i)=new_pos(i);
148  }
149  }
150  }
151  }
152 
153  for (auto & mychild : this->child_ref_range())
154  {
155  if (&mychild == remote_elem)
156  continue;
157  libmesh_assert_equal_to (mychild.refinement_flag(), Elem::COARSEN);
158  mychild.set_refinement_flag(Elem::INACTIVE);
159  if (mychild.p_level() > parent_p_level)
160  parent_p_level = mychild.p_level();
161  }
162 
164  this->set_p_level(parent_p_level);
165 
166  libmesh_assert (this->active());
167 }
168 
169 
170 
172 {
173  // Subactive elements get deleted entirely, not contracted
174  libmesh_assert (this->active());
175 
176  // Active contracted elements no longer can have children
177  delete [] _children;
179 
180  if (this->refinement_flag() == Elem::JUST_COARSENED)
182 }
183 
184 #endif // #ifdef LIBMESH_ENABLE_AMR
185 
186 
187 } // namespace libMesh
bool ancestor() const
Definition: elem.C:1574
void set_p_level(const unsigned int p)
Sets the value of the p-refinement level for the element.
Definition: elem.h:2559
virtual Node *& set_node(const unsigned int i)
Definition: elem.h:1941
A Node is like a Point, but with more information.
Definition: node.h:52
bool subactive() const
Definition: elem.h:2275
bool active() const
Definition: elem.h:2257
static UniquePtr< Elem > build(const ElemType type, Elem *p=libmesh_nullptr)
Definition: elem.C:238
virtual ElemType type() const =0
unsigned int p_level() const
Definition: elem.h:2422
void contract()
Contract an active element, i.e.
void add_scaled(const TypeVector< T2 > &, const T)
Add a scaled value to this vector without creating a temporary.
Definition: type_vector.h:624
const Elem * parent() const
Definition: elem.h:2346
This is the base class from which all geometric element types are derived.
Definition: elem.h:89
const class libmesh_nullptr_t libmesh_nullptr
void set_refinement_flag(const RefinementState rflag)
Sets the value of the refinement flag for the element.
Definition: elem.h:2513
The libMesh namespace provides an interface to certain functionality in the library.
SimpleRange< ChildRefIter > child_ref_range()
Returns a range with all children of a parent element, usable in range-based for loops.
Definition: elem.h:1699
libmesh_assert(j)
virtual unsigned int n_nodes() const =0
virtual void refine(MeshRefinement &mesh_refinement)
Refine the element.
This is the MeshRefinement class.
Elem ** _children
Pointers to this element&#39;s children.
Definition: elem.h:1627
const Elem * child_ptr(unsigned int i) const
Definition: elem.h:2445
RefinementState p_refinement_flag() const
Definition: elem.h:2521
dof_id_type node(const unsigned int i) const
Definition: elem.h:1844
virtual unsigned int n_children() const =0
void set_n_systems(const unsigned int s)
Sets the number of systems for this DofObject.
Definition: dof_object.C:165
Node * add_node(Elem &parent, unsigned int child, unsigned int node, processor_id_type proc_id)
Add a node to the mesh.
const Point & point(const unsigned int i) const
Definition: elem.h:1809
Elem * add_elem(Elem *elem)
Adds the element elem to the mesh.
void coarsen()
Coarsen the element.
RefinementState refinement_flag() const
Definition: elem.h:2505
void set_p_refinement_flag(const RefinementState pflag)
Sets the value of the p-refinement flag for the element.
Definition: elem.h:2529
unsigned int n_systems() const
Definition: dof_object.h:726
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:38
processor_id_type processor_id() const
Definition: dof_object.h:694
virtual float embedding_matrix(const unsigned int child_num, const unsigned int child_node_num, const unsigned int parent_node_num) const =0
const RemoteElem * remote_elem
Definition: remote_elem.C:57