elem_refinement.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2014 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"
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  // Create my children if necessary
47  if (!_children)
48  {
49  _children = new Elem*[this->n_children()];
50 
51  unsigned int parent_p_level = this->p_level();
52  for (unsigned int c=0; c<this->n_children(); c++)
53  {
54  _children[c] = Elem::build(this->type(), this).release();
56  _children[c]->set_p_level(parent_p_level);
58  }
59 
60  // Compute new nodal locations
61  // and asssign nodes to children
62  // Make these static. It is unlikely the
63  // sizes will change from call to call, so having these
64  // static should save on reallocations
65  std::vector<std::vector<Point> > p (this->n_children());
66  std::vector<std::vector<Node*> > nodes(this->n_children());
67 
68 
69  // compute new nodal locations
70  for (unsigned int c=0; c<this->n_children(); c++)
71  {
72  Elem *current_child = this->child(c);
73  p[c].resize (current_child->n_nodes());
74  nodes[c].resize(current_child->n_nodes());
75 
76  for (unsigned int nc=0; nc<current_child->n_nodes(); nc++)
77  {
78  // zero entries
79  p[c][nc].zero();
80  nodes[c][nc] = NULL;
81 
82  for (unsigned int n=0; n<this->n_nodes(); n++)
83  {
84  // The value from the embedding matrix
85  const float em_val = this->embedding_matrix(c,nc,n);
86 
87  if (em_val != 0.)
88  {
89  p[c][nc].add_scaled (this->point(n), em_val);
90 
91  // We may have found the node, in which case we
92  // won't need to look it up later.
93  if (em_val == 1.)
94  nodes[c][nc] = this->get_node(n);
95  }
96  }
97  }
98 
99  // assign nodes to children & add them to the mesh
100  const Real pointtol = this->hmin() * TOLERANCE;
101  for (unsigned int nc=0; nc<current_child->n_nodes(); nc++)
102  {
103  if (nodes[c][nc] != NULL)
104  {
105  current_child->set_node(nc) = nodes[c][nc];
106  }
107  else
108  {
109  current_child->set_node(nc) =
110  mesh_refinement.add_point(p[c][nc],
111  current_child->processor_id(),
112  pointtol);
113  current_child->get_node(nc)->set_n_systems
114  (this->n_systems());
115  }
116  }
117 
118  mesh_refinement.add_elem (current_child);
119  current_child->set_n_systems(this->n_systems());
120  }
121  }
122  else
123  {
124  unsigned int parent_p_level = this->p_level();
125  for (unsigned int c=0; c<this->n_children(); c++)
126  {
127  Elem *current_child = this->child(c);
128  libmesh_assert(current_child->subactive());
129  current_child->set_refinement_flag(Elem::JUST_REFINED);
130  current_child->set_p_level(parent_p_level);
131  current_child->set_p_refinement_flag(this->p_refinement_flag());
132  }
133  }
134 
135  // Un-set my refinement flag now
138 
139  for (unsigned int c=0; c<this->n_children(); c++)
140  {
141  libmesh_assert_equal_to (this->child(c)->parent(), this);
142  libmesh_assert(this->child(c)->active());
143  }
144  libmesh_assert (this->ancestor());
145 }
146 
147 
148 
150 {
151  libmesh_assert_equal_to (this->refinement_flag(), Elem::COARSEN_INACTIVE);
152  libmesh_assert (!this->active());
153 
154  // We no longer delete children until MeshRefinement::contract()
155  // delete [] _children;
156  // _children = NULL;
157 
158  unsigned int parent_p_level = 0;
159 
160  // re-compute hanging node nodal locations
161  for (unsigned int c=0; c<this->n_children(); c++)
162  {
163  Elem *mychild = this->child(c);
164  if (mychild == remote_elem)
165  continue;
166  for (unsigned int nc=0; nc<mychild->n_nodes(); nc++)
167  {
168  Point new_pos;
169  bool calculated_new_pos = false;
170 
171  for (unsigned int n=0; n<this->n_nodes(); n++)
172  {
173  // The value from the embedding matrix
174  const float em_val = this->embedding_matrix(c,nc,n);
175 
176  // The node location is somewhere between existing vertices
177  if ((em_val != 0.) && (em_val != 1.))
178  {
179  new_pos.add_scaled (this->point(n), em_val);
180  calculated_new_pos = true;
181  }
182  }
183 
184  if(calculated_new_pos)
185  {
186  //Move the existing node back into it's original location
187  for(unsigned int i=0; i<LIBMESH_DIM; i++)
188  {
189  Point & child_node = *(mychild->get_node(nc));
190  child_node(i)=new_pos(i);
191  }
192  }
193  }
194  }
195 
196  for (unsigned int c=0; c<this->n_children(); c++)
197  {
198  Elem *mychild = this->child(c);
199  if (mychild == remote_elem)
200  continue;
201  libmesh_assert_equal_to (mychild->refinement_flag(), Elem::COARSEN);
203  if (mychild->p_level() > parent_p_level)
204  parent_p_level = mychild->p_level();
205  }
206 
208  this->set_p_level(parent_p_level);
209 
210  libmesh_assert (this->active());
211 }
212 
213 
214 
216 {
217  // Subactive elements get deleted entirely, not contracted
218  libmesh_assert (this->active());
219 
220  // Active contracted elements no longer can have children
221  if (_children)
222  {
223  delete [] _children;
224  _children = NULL;
225  }
226  if (this->refinement_flag() == Elem::JUST_COARSENED)
228 }
229 
230 #endif // #ifdef LIBMESH_ENABLE_AMR
231 
232 
233 } // namespace libMesh

Site Created By: libMesh Developers
Last modified: February 07 2014 16:57:04 UTC

Hosted By:
SourceForge.net Logo