oomph::BrickMeshBase Class Reference

Base class for brick meshes (meshes made of 3D brick elements). More...

#include <brick_mesh.h>

+ Inheritance diagram for oomph::BrickMeshBase:

Public Member Functions

 BrickMeshBase ()
 Constructor (empty) More...
 
 BrickMeshBase (const BrickMeshBase &)=delete
 Broken copy constructor. More...
 
virtual ~BrickMeshBase ()
 Broken assignment operator. More...
 
void setup_boundary_element_info ()
 
void setup_boundary_element_info (std::ostream &outfile)
 
- Public Member Functions inherited from oomph::Mesh
 Mesh ()
 Default constructor. More...
 
 Mesh (const Vector< Mesh * > &sub_mesh_pt)
 
void merge_meshes (const Vector< Mesh * > &sub_mesh_pt)
 
virtual void reset_boundary_element_info (Vector< unsigned > &ntmp_boundary_elements, Vector< Vector< unsigned >> &ntmp_boundary_elements_in_region, Vector< FiniteElement * > &deleted_elements)
 Virtual function to perform the reset boundary elements info rutines. More...
 
template<class BULK_ELEMENT >
void doc_boundary_coordinates (const unsigned &b, std::ofstream &the_file)
 
virtual void scale_mesh (const double &factor)
 
 Mesh (const Mesh &dummy)=delete
 Broken copy constructor. More...
 
void operator= (const Mesh &)=delete
 Broken assignment operator. More...
 
virtual ~Mesh ()
 Virtual Destructor to clean up all memory. More...
 
void flush_element_and_node_storage ()
 
void flush_element_storage ()
 
void flush_node_storage ()
 
Node *& node_pt (const unsigned long &n)
 Return pointer to global node n. More...
 
Nodenode_pt (const unsigned long &n) const
 Return pointer to global node n (const version) More...
 
GeneralisedElement *& element_pt (const unsigned long &e)
 Return pointer to element e. More...
 
GeneralisedElementelement_pt (const unsigned long &e) const
 Return pointer to element e (const version) More...
 
const Vector< GeneralisedElement * > & element_pt () const
 Return reference to the Vector of elements. More...
 
Vector< GeneralisedElement * > & element_pt ()
 Return reference to the Vector of elements. More...
 
FiniteElementfinite_element_pt (const unsigned &e) const
 
Node *& boundary_node_pt (const unsigned &b, const unsigned &n)
 Return pointer to node n on boundary b. More...
 
Nodeboundary_node_pt (const unsigned &b, const unsigned &n) const
 Return pointer to node n on boundary b. More...
 
void set_nboundary (const unsigned &nbound)
 Set the number of boundaries in the mesh. More...
 
void remove_boundary_nodes ()
 Clear all pointers to boundary nodes. More...
 
void remove_boundary_nodes (const unsigned &b)
 
void remove_boundary_node (const unsigned &b, Node *const &node_pt)
 Remove a node from the boundary b. More...
 
void add_boundary_node (const unsigned &b, Node *const &node_pt)
 Add a (pointer to) a node to the b-th boundary. More...
 
void copy_boundary_node_data_from_nodes ()
 
bool boundary_coordinate_exists (const unsigned &i) const
 Indicate whether the i-th boundary has an intrinsic coordinate. More...
 
unsigned long nelement () const
 Return number of elements in the mesh. More...
 
unsigned long nnode () const
 Return number of nodes in the mesh. More...
 
unsigned ndof_types () const
 Return number of dof types in mesh. More...
 
unsigned elemental_dimension () const
 Return number of elemental dimension in mesh. More...
 
unsigned nodal_dimension () const
 Return number of nodal dimension in mesh. More...
 
void add_node_pt (Node *const &node_pt)
 Add a (pointer to a) node to the mesh. More...
 
void add_element_pt (GeneralisedElement *const &element_pt)
 Add a (pointer to) an element to the mesh. More...
 
virtual void node_update (const bool &update_all_solid_nodes=false)
 
virtual void reorder_nodes (const bool &use_old_ordering=true)
 
virtual void get_node_reordering (Vector< Node * > &reordering, const bool &use_old_ordering=true) const
 
template<class BULK_ELEMENT , template< class > class FACE_ELEMENT>
void build_face_mesh (const unsigned &b, Mesh *const &face_mesh_pt)
 
unsigned self_test ()
 Self-test: Check elements and nodes. Return 0 for OK. More...
 
void max_and_min_element_size (double &max_size, double &min_size)
 
double total_size ()
 
void check_inverted_elements (bool &mesh_has_inverted_elements, std::ofstream &inverted_element_file)
 
void check_inverted_elements (bool &mesh_has_inverted_elements)
 
unsigned check_for_repeated_nodes (const double &epsilon=1.0e-12)
 
Vector< Node * > prune_dead_nodes ()
 
unsigned nboundary () const
 Return number of boundaries. More...
 
unsigned long nboundary_node (const unsigned &ibound) const
 Return number of nodes on a particular boundary. More...
 
FiniteElementboundary_element_pt (const unsigned &b, const unsigned &e) const
 Return pointer to e-th finite element on boundary b. More...
 
Nodeget_some_non_boundary_node () const
 
unsigned nboundary_element (const unsigned &b) const
 Return number of finite elements that are adjacent to boundary b. More...
 
int face_index_at_boundary (const unsigned &b, const unsigned &e) const
 
virtual void dump (std::ofstream &dump_file, const bool &use_old_ordering=true) const
 Dump the data in the mesh into a file for restart. More...
 
void dump (const std::string &dump_file_name, const bool &use_old_ordering=true) const
 Dump the data in the mesh into a file for restart. More...
 
virtual void read (std::ifstream &restart_file)
 Read solution from restart file. More...
 
void output_paraview (std::ofstream &file_out, const unsigned &nplot) const
 
void output_fct_paraview (std::ofstream &file_out, const unsigned &nplot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt) const
 
void output_fct_paraview (std::ofstream &file_out, const unsigned &nplot, const double &time, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt) const
 
void output (std::ostream &outfile)
 Output for all elements. More...
 
void output (std::ostream &outfile, const unsigned &n_plot)
 Output at f(n_plot) points in each element. More...
 
void output (FILE *file_pt)
 Output for all elements (C-style output) More...
 
void output (FILE *file_pt, const unsigned &nplot)
 Output at f(n_plot) points in each element (C-style output) More...
 
void output (const std::string &output_filename)
 Output for all elements. More...
 
void output (const std::string &output_filename, const unsigned &n_plot)
 Output at f(n_plot) points in each element. More...
 
void output_fct (std::ostream &outfile, const unsigned &n_plot, FiniteElement::SteadyExactSolutionFctPt)
 Output a given Vector function at f(n_plot) points in each element. More...
 
void output_fct (std::ostream &outfile, const unsigned &n_plot, const double &time, FiniteElement::UnsteadyExactSolutionFctPt)
 
void output_boundaries (std::ostream &outfile)
 Output the nodes on the boundaries (into separate tecplot zones) More...
 
void output_boundaries (const std::string &output_filename)
 
void assign_initial_values_impulsive ()
 Assign initial values for an impulsive start. More...
 
void shift_time_values ()
 
void calculate_predictions ()
 
void set_nodal_and_elemental_time_stepper (TimeStepper *const &time_stepper_pt, const bool &preserve_existing_data)
 
virtual void set_mesh_level_time_stepper (TimeStepper *const &time_stepper_pt, const bool &preserve_existing_data)
 
void set_consistent_pinned_values_for_continuation (ContinuationStorageScheme *const &continuation_stepper_pt)
 Set consistent values for pinned data in continuation. More...
 
bool does_pointer_correspond_to_mesh_data (double *const &parameter_pt)
 Does the double pointer correspond to any mesh data. More...
 
void set_nodal_time_stepper (TimeStepper *const &time_stepper_pt, const bool &preserve_existing_data)
 Set the timestepper associated with the nodal data in the mesh. More...
 
void set_elemental_internal_time_stepper (TimeStepper *const &time_stepper_pt, const bool &preserve_existing_data)
 
virtual void compute_norm (double &norm)
 
virtual void compute_norm (Vector< double > &norm)
 
virtual void compute_error (std::ostream &outfile, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt, const double &time, double &error, double &norm)
 
virtual void compute_error (std::ostream &outfile, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, double &error, double &norm)
 
virtual void compute_error (FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, double &error, double &norm)
 
virtual void compute_error (FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, Vector< double > &error, Vector< double > &norm)
 
virtual void compute_error (std::ostream &outfile, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt, const double &time, Vector< double > &error, Vector< double > &norm)
 
virtual void compute_error (std::ostream &outfile, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, Vector< double > &error, Vector< double > &norm)
 
virtual void compute_error (FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt, const double &time, double &error, double &norm)
 Returns the norm of the error and that of the exact solution. More...
 
virtual void compute_error (FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt, const double &time, Vector< double > &error, Vector< double > &norm)
 
bool is_mesh_distributed () const
 Boolean to indicate if Mesh has been distributed. More...
 
OomphCommunicatorcommunicator_pt () const
 
void delete_all_external_storage ()
 Wipe the storage for all externally-based elements. More...
 

Additional Inherited Members

- Public Types inherited from oomph::Mesh
typedef void(FiniteElement::* SteadyExactSolutionFctPt) (const Vector< double > &x, Vector< double > &soln)
 
typedef void(FiniteElement::* UnsteadyExactSolutionFctPt) (const double &time, const Vector< double > &x, Vector< double > &soln)
 
- Static Public Attributes inherited from oomph::Mesh
static Steady< 0 > Default_TimeStepper
 The Steady Timestepper. More...
 
static bool Suppress_warning_about_empty_mesh_level_time_stepper_function
 Static boolean flag to control warning about mesh level timesteppers. More...
 
- Protected Member Functions inherited from oomph::Mesh
unsigned long assign_global_eqn_numbers (Vector< double * > &Dof_pt)
 Assign (global) equation numbers to the nodes. More...
 
void describe_dofs (std::ostream &out, const std::string &current_string) const
 
void describe_local_dofs (std::ostream &out, const std::string &current_string) const
 
void assign_local_eqn_numbers (const bool &store_local_dof_pt)
 Assign local equation numbers in all elements. More...
 
void convert_to_boundary_node (Node *&node_pt, const Vector< FiniteElement * > &finite_element_pt)
 
void convert_to_boundary_node (Node *&node_pt)
 
- Protected Attributes inherited from oomph::Mesh
Vector< Vector< Node * > > Boundary_node_pt
 
bool Lookup_for_elements_next_boundary_is_setup
 
Vector< Vector< FiniteElement * > > Boundary_element_pt
 
Vector< Vector< int > > Face_index_at_boundary
 
Vector< Node * > Node_pt
 Vector of pointers to nodes. More...
 
Vector< GeneralisedElement * > Element_pt
 Vector of pointers to generalised elements. More...
 
std::vector< boolBoundary_coordinate_exists
 

Detailed Description

Base class for brick meshes (meshes made of 3D brick elements).

//////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////

Constructor & Destructor Documentation

◆ BrickMeshBase() [1/2]

oomph::BrickMeshBase::BrickMeshBase ( )
inline

Constructor (empty)

181 {}

◆ BrickMeshBase() [2/2]

oomph::BrickMeshBase::BrickMeshBase ( const BrickMeshBase )
delete

Broken copy constructor.

◆ ~BrickMeshBase()

virtual oomph::BrickMeshBase::~BrickMeshBase ( )
inlinevirtual

Broken assignment operator.

Destructor (empty)

191 {}

Member Function Documentation

◆ setup_boundary_element_info() [1/2]

void oomph::BrickMeshBase::setup_boundary_element_info ( )
inlinevirtual

Setup lookup schemes which establish whic elements are located next to mesh's boundaries (wrapper to suppress doc).

Reimplemented from oomph::Mesh.

196  {
197  std::ofstream outfile;
199  }
void setup_boundary_element_info()
Definition: brick_mesh.h:195

Referenced by oomph::EighthSphereMesh< ELEMENT >::EighthSphereMesh(), oomph::QuarterTubeMesh< ELEMENT >::QuarterTubeMesh(), oomph::RefineableSolidCubicMesh< ELEMENT >::setup_boundary_element_info(), and oomph::TubeMesh< ELEMENT >::TubeMesh().

◆ setup_boundary_element_info() [2/2]

void oomph::BrickMeshBase::setup_boundary_element_info ( std::ostream &  outfile)
virtual

Setup lookup schemes which establish whic elements are located next to mesh's boundaries. Doc in outfile (if it's open).

//////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// Setup lookup schemes which establish which elements are located next to which boundaries (Doc to outfile if it's open).

Reimplemented from oomph::Mesh.

52  {
53  // Martina's fixed and commented version of the code.
54 
55  // Define variable doc and set the initial value to False.
56  bool doc = false;
57 
58  // If file declared in outfile exists,set doc=true to enable writing to
59  // stream
60  if (outfile) doc = true;
61 
62  // Number of boundaries. Gives the value assigned by the function
63  // nboundary()
64  unsigned nbound = nboundary();
65 
66  if (doc)
67  {
68  outfile << "The number of boundaries is " << nbound << "\n";
69  }
70 
71  // Wipe/allocate storage for arrays
72  // Command clear will reomve all elements of vectors
73  // Command resize will adapt pointer to correct boundary size. Internal data
74  Boundary_element_pt.clear();
75  Face_index_at_boundary.clear();
76  Boundary_element_pt.resize(nbound);
77  Face_index_at_boundary.resize(nbound);
78 
79 
80  // Temporary vector of vectors of pointers to elements on the boundaries:
81  // vector_of_boundary_element_pt[i] is the vector of pointers to all
82  // elements that have nodes on boundary i.
83  // This is not a set to ensure UNIQUE ordering on every processor
84  // There are a number of elements with nodes on each boundary.
85  // For each boundary we store the appropriate elements in a vector.
86  // There is therefore a vector for each boundary, which we store in
87  // another vector, i.e. a matrix (vector of vectors).
88  // Then vector_of_boundary_element_pt[0] is a vector of pointers to elements
89  // with nodes on boundary 0 and vector_of_boundary_element_pt[0][0] is the
90  // first element with nodes on boundary 0.
91  Vector<Vector<FiniteElement*>> vector_of_boundary_element_pt;
92  vector_of_boundary_element_pt.resize(nbound);
93 
94  // Matrix map for working out the fixed local coord for elements on boundary
95  // Calling pointer to FiniteElement and pointer to Vector<int> defining
96  // the matrix to identify each element on boundary
97  MapMatrixMixed<unsigned, FiniteElement*, Vector<int>*> boundary_identifier;
98 
99 
100  // Temporary container to store pointers to temporary vectors
101  // so they can be deleted. Creating storage to store these
102  // temporary vectors of vectors of pointers previously defined
103  Vector<Vector<int>*> tmp_vect_pt;
104 
105  // Loop over elements
106  //-------------------
107  unsigned nel = nelement();
108  for (unsigned e = 0; e < nel; e++)
109  {
110  // Get pointer to element
111  // and put it in local storage fe_pt.
112  FiniteElement* fe_pt = finite_element_pt(e);
113 
114  // print out values of all elements to doc
115  if (doc) outfile << "Element: " << e << " " << fe_pt << std::endl;
116 
117  // Loop over the element's nodes and find out which boundaries they're on
118  // ----------------------------------------------------------------------
119  // Return number of nodes along one edge of the current element defined by
120  // fe_pt hence, loop over nodes of each element in 3D-dimension
121  unsigned nnode_1d = fe_pt->nnode_1d();
122 
123  // Loop over nodes in order
124  for (unsigned i0 = 0; i0 < nnode_1d; i0++)
125  {
126  for (unsigned i1 = 0; i1 < nnode_1d; i1++)
127  {
128  for (unsigned i2 = 0; i2 < nnode_1d; i2++)
129  {
130  // Local node number, which is an assumed ordering defined in our
131  // underlying finite element scheme.
132  unsigned j = i0 + i1 * nnode_1d + i2 * nnode_1d * nnode_1d;
133 
134  // Get pointer to the set of boundaries that this node lives on
135  // for each node reset boundaries_pt to 0,
136  // create pointer to each node in each element
137  // and give boundaries_pt a value
138  std::set<unsigned>* boundaries_pt = 0;
139  fe_pt->node_pt(j)->get_boundaries_pt(boundaries_pt);
140 
141  // If the node lives on some boundaries....
142  // If not equal to 0, node is on boundary
143  // Loop through values of the current node stored in boundaries_pt
144  if (boundaries_pt != 0)
145  {
146  // Loop over the entries in the set "it" (name we use to refer to
147  // the iterator)
148  for (std::set<unsigned>::iterator it = boundaries_pt->begin();
149  it != boundaries_pt->end();
150  ++it)
151  {
152  // What's the boundary?
153  // Define boundary_id to have the value pointed to by
154  // boundaries_pt
155  unsigned boundary_id = *it;
156 
157  // Add pointer to finite element to vector for the appropriate
158  // boundary
159 
160  // Does the pointer already exist in the vector
161  Vector<FiniteElement*>::iterator b_el_it =
162  std::find(vector_of_boundary_element_pt[*it].begin(),
163  vector_of_boundary_element_pt[*it].end(),
164  fe_pt);
165 
166  // Only insert if we have not found it (i.e. got to the end)
167  if (b_el_it == vector_of_boundary_element_pt[*it].end())
168  {
169  vector_of_boundary_element_pt[*it].push_back(fe_pt);
170  }
171 
172  // For the current element/boundary combination, create
173  // a vector that stores an indicator which element boundaries
174  // the node is located (boundary_identifier=-/+1 for nodes
175  // on the left/right boundary; boundary_identifier=-/+2 for
176  // nodes on the lower/upper boundary. We determine these indices
177  // for all corner nodes of the element and add them to a vector
178  // to a vector. This allows us to decide which faces of the
179  // element coincide with the boundary since each face of the
180  // element must have all four corner nodes on the boundary.
181  if (boundary_identifier(boundary_id, fe_pt) == 0)
182  {
183  // Here we make our vector of integers and keep track of the
184  // pointer to it The vector stores information about local
185  // node position for each boundary element
186  Vector<int>* tmp_pt = new Vector<int>;
187 
188  // Add to the local scheme that will allow us to delete it
189  // later at the very end of the function
190  tmp_vect_pt.push_back(tmp_pt);
191 
192  // Add the pointer to the storage scheme defined by
193  // boundary_id and pointer to finite element
194  boundary_identifier(boundary_id, fe_pt) = tmp_pt;
195  }
196 
197  // Are we at a corner node? (local for each boundary element)
198  // i0,i1,i2 represent the current 3D coordinates- which local
199  // corner node.
200  if (((i0 == 0) || (i0 == nnode_1d - 1)) &&
201  ((i1 == 0) || (i1 == nnode_1d - 1)) &&
202  ((i2 == 0) || (i2 == nnode_1d - 1)))
203  {
204  // Create index to represent position relative to s_0
205  // s_0,s_1,s_2 are local 3D directions
206  (*boundary_identifier(boundary_id, fe_pt))
207  .push_back(1 * (2 * i0 / (nnode_1d - 1) - 1));
208 
209  // Create index to represent position relative to s_1
210  (*boundary_identifier(boundary_id, fe_pt))
211  .push_back(2 * (2 * i1 / (nnode_1d - 1) - 1));
212 
213  // Create index to represent position relative to s_2
214  (*boundary_identifier(boundary_id, fe_pt))
215  .push_back(3 * (2 * i2 / (nnode_1d - 1) - 1));
216  }
217  }
218  }
219  }
220  }
221  }
222  }
223 
224 
225  // Now copy everything across into permanent arrays
226  //-------------------------------------------------
227 
228  // Loop over boundaries
229  //---------------------
230  for (unsigned i = 0; i < nbound; i++)
231  {
232  // Loop over elements on given boundary
233  typedef Vector<FiniteElement*>::iterator IT;
234  for (IT it = vector_of_boundary_element_pt[i].begin();
235  it != vector_of_boundary_element_pt[i].end();
236  it++)
237  {
238  // Recover pointer to element for each element
239  FiniteElement* fe_pt = (*it);
240 
241  // Initialise count for boundary identities (-3,-2,-1,1,2,3)
242  std::map<int, unsigned> count;
243 
244  // Loop over coordinates in 3D dimension
245  for (int ii = 0; ii < 3; ii++)
246  {
247  // Loop over upper/lower end of coordinates
248  // count -/+ for each direction separately
249  for (int sign = -1; sign < 3; sign += 2)
250  {
251  count[(ii + 1) * sign] = 0;
252 
253  // Initialise map of counts to 0 before loop
254  // count boundary indicator for each element
255  // and its nodes
256  }
257  }
258 
259  // Loop over boundary indicators for this element/boundary
260  // count nodes for any one fixed boundary determined by
261  // boundary indicator
262  unsigned n_indicators = (*boundary_identifier(i, fe_pt)).size();
263  for (unsigned j = 0; j < n_indicators; j++)
264  {
265  count[(*boundary_identifier(i, fe_pt))[j]]++;
266  }
267 
268  // Determine the correct boundary indicator by checking that it
269  // occurs four times (since four corner nodes of the element's boundary
270  // need to be located on the boundary domain)
271  int indicator = -10;
272 
273 
274  // Loop over coordinates
275  for (int ii = 0; ii < 3; ii++)
276  {
277  // Loop over upper/lower end of coordinates
278  for (int sign = -1; sign < 3; sign += 2)
279  {
280  // If an index occurs four times then a face is on the boundary
281  // But we can have multiple faces on the same boundary, so add all
282  // the ones that we find!
283  if (count[(ii + 1) * sign] == 4)
284  {
285  indicator = (ii + 1) * sign;
286 
287  // Copy into the member data structures
288  Boundary_element_pt[i].push_back(*it);
289  Face_index_at_boundary[i].push_back(indicator);
290  }
291  }
292  }
293  }
294  }
295 
296  // Doc?
297  //-----
298  if (doc)
299  {
300  // Loop over boundaries
301  for (unsigned i = 0; i < nbound; i++)
302  {
303  unsigned nel = Boundary_element_pt[i].size();
304  outfile << "Boundary: " << i << " is adjacent to " << nel << " elements"
305  << std::endl;
306 
307  // Loop over elements on given boundary
308  for (unsigned e = 0; e < nel; e++)
309  {
310  FiniteElement* fe_pt = Boundary_element_pt[i][e];
311  outfile << "Boundary element:" << fe_pt
312  << " Face index along boundary is "
313  << Face_index_at_boundary[i][e] << std::endl;
314  }
315  }
316  }
317 
318 
319  // Lookup scheme has now been setup yet
321 
322 
323  // Cleanup temporary vectors
324  unsigned n = tmp_vect_pt.size();
325  for (unsigned i = 0; i < n; i++)
326  {
327  delete tmp_vect_pt[i];
328  }
329 
330  return;
331 
332 
333  // Doc?
334  /*bool doc=false;
335  if (outfile) doc=true;
336 
337  // Number of boundaries
338  unsigned nbound=nboundary();
339 
340  // Wipe/allocate storage for arrays
341  Boundary_element_pt.clear();
342  Face_index_at_boundary.clear();
343  Boundary_element_pt.resize(nbound);
344  Face_index_at_boundary.resize(nbound);
345 
346 
347  // Temporary vector of vectors of pointers to elements on the boundaries:
348  // vector_of_boundary_element_pt[i] is the vector of pointers to all
349  // elements that have nodes on boundary i.
350  // This is not a set to ensure UNIQUE ordering on every processor
351  Vector<Vector<FiniteElement*> > vector_of_boundary_element_pt;
352  vector_of_boundary_element_pt.resize(nbound);
353 
354  // Matrix map for working out the fixed local coord for elements on boundary
355  MapMatrixMixed<unsigned,FiniteElement*,Vector<int>* >
356  boundary_identifier;
357 
358  // Tmp container to store pointers to tmp vectors so they can be deleted
359  Vector<Vector<int>*> tmp_vect_pt;
360 
361  // Loop over elements
362  //-------------------
363  unsigned nel=nelement();
364  for (unsigned e=0;e<nel;e++)
365  {
366  // Get pointer to element
367  FiniteElement* fe_pt=finite_element_pt(e);
368 
369  if (doc) outfile << "Element: " << e << " " << fe_pt << std::endl;
370 
371  // Loop over the element's nodes and find out which boundaries they're on
372  // ----------------------------------------------------------------------
373  unsigned nnode_1d=fe_pt->nnode_1d();
374 
375  // Loop over nodes in order
376  for (unsigned i0=0;i0<nnode_1d;i0++)
377  {
378  for (unsigned i1=0;i1<nnode_1d;i1++)
379  {
380  for (unsigned i2=0;i2<nnode_1d;i2++)
381  {
382  // Local node number
383  unsigned j=i0+i1*nnode_1d+i2*nnode_1d*nnode_1d;
384 
385  // Get pointer to set of boundaries that this
386  // node lives on
387  std::set<unsigned>* boundaries_pt=0;
388  fe_pt->node_pt(j)->get_boundaries_pt(boundaries_pt);
389 
390  // If the node lives on some boundaries....
391  if (boundaries_pt!=0)
392  {
393  for (std::set<unsigned>::iterator it=boundaries_pt->begin();
394  it!=boundaries_pt->end();++it)
395  {
396 
397  // What's the boundary?
398  unsigned boundary_id=*it;
399 
400  // Add pointer to finite element to vector for the appropriate
401  // boundary
402 
403  // Does the pointer already exits in the vector
404  Vector<FiniteElement*>::iterator b_el_it =
405  std::find(vector_of_boundary_element_pt[*it].begin(),
406  vector_of_boundary_element_pt[*it].end(),
407  fe_pt);
408 
409  //Only insert if we have not found it (i.e. got to the end)
410  if(b_el_it == vector_of_boundary_element_pt[*it].end())
411  {
412  vector_of_boundary_element_pt[*it].push_back(fe_pt);
413  }
414 
415  // For the current element/boundary combination, create
416  // a vector that stores an indicator which element boundaries
417  // the node is located (boundary_identifier=-/+1 for nodes
418  // on the left/right boundary; boundary_identifier=-/+2 for
419  nodes
420  // on the lower/upper boundary. We determine these indices
421  // for all corner nodes of the element and add them to a vector
422  // to a vector. This allows us to decide which face of the
423  element
424  // coincides with the boundary since the (brick!) element must
425  // have exactly four corner nodes on the boundary.
426  if (boundary_identifier(boundary_id,fe_pt)==0)
427  {
428  Vector<int>* tmp_pt=new Vector<int>;
429  tmp_vect_pt.push_back(tmp_pt);
430  boundary_identifier(boundary_id,fe_pt)=tmp_pt;
431  }
432 
433  // Are we at a corner node?
434  if (((i0==0)||(i0==nnode_1d-1))&&((i1==0)||(i1==nnode_1d-1))
435  &&((i2==0)||(i2==nnode_1d-1)))
436  {
437  // Create index to represent position relative to s_0
438  (*boundary_identifier(boundary_id,fe_pt)).
439  push_back(1*(2*i0/(nnode_1d-1)-1));
440 
441  // Create index to represent position relative to s_1
442  (*boundary_identifier(boundary_id,fe_pt)).
443  push_back(2*(2*i1/(nnode_1d-1)-1));
444 
445  // Create index to represent position relative to s_2
446  (*boundary_identifier(boundary_id,fe_pt)).
447  push_back(3*(2*i2/(nnode_1d-1)-1));
448  }
449  }
450  }
451  }
452  }
453  }
454  }
455 
456 
457  // Now copy everything across into permanent arrays
458  //-------------------------------------------------
459 
460  // Loop over boundaries
461  //---------------------
462  for (unsigned i=0;i<nbound;i++)
463  {
464  // Loop over elements on given boundary
465  typedef Vector<FiniteElement*>::iterator IT;
466  for (IT it=vector_of_boundary_element_pt[i].begin();
467  it!=vector_of_boundary_element_pt[i].end();
468  it++)
469  {
470  // Recover pointer to element
471  FiniteElement* fe_pt=(*it);
472 
473  // Initialise count for boundary identiers (-3,-2,-1,1,2,3)
474  std::map<int,unsigned> count;
475 
476  // Loop over coordinates
477  for (int ii=0;ii<3;ii++)
478  {
479  // Loop over upper/lower end of coordinates
480  for (int sign=-1;sign<3;sign+=2)
481  {
482  count[(ii+1)*sign]=0;
483  }
484  }
485 
486  // Loop over boundary indicators for this element/boundary
487  unsigned n_indicators=(*boundary_identifier(i,fe_pt)).size();
488  for (unsigned j=0;j<n_indicators;j++)
489  {
490  count[(*boundary_identifier(i,fe_pt))[j] ]++;
491  }
492 
493  // Determine the correct boundary indicator by checking that it
494  // occurs four times (since four corner nodes of the element's boundary
495  // need to be located on the domain boundary
496  int indicator=-10;
497 
498  //Check that we're finding exactly one boundary indicator
499  bool found=false;
500 
501  // Loop over coordinates
502  for (int ii=0;ii<3;ii++)
503  {
504  // Loop over upper/lower end of coordinates
505  for (int sign=-1;sign<3;sign+=2)
506  {
507  if (count[(ii+1)*sign]==4)
508  {
509  // Check that we haven't found multiple boundaries
510  if (found)
511  {
512  throw OomphLibError(
513  "Trouble: Multiple boundary identifiers!\n",
514  OOMPH_CURRENT_FUNCTION,
515  OOMPH_EXCEPTION_LOCATION);
516  }
517  found=true;
518  indicator=(ii+1)*sign;
519  }
520  }
521  }
522 
523  // Check if we've found one boundary
524  if (found)
525  {
526 
527  // Store element
528  Boundary_element_pt[i].push_back(*it);
529 
530  // Now convert boundary indicator into information required
531  // for FaceElements
532  switch (indicator)
533  {
534  case -3:
535 
536  // s_2 is fixed at -1.0:
537  Face_index_at_boundary[i].push_back(-3);
538  break;
539 
540  case -2:
541 
542  // s_1 is fixed at -1.0:
543  Face_index_at_boundary[i].push_back(-2);
544  break;
545 
546  case -1:
547 
548  // s_0 is fixed at -1.0:
549  Face_index_at_boundary[i].push_back(-1);
550  break;
551 
552 
553  case 1:
554 
555  // s_0 is fixed at 1.0:
556  Face_index_at_boundary[i].push_back(1);
557  break;
558 
559  case 2:
560 
561  // s_1 is fixed at 1.0:
562  Face_index_at_boundary[i].push_back(2);
563  break;
564 
565  case 3:
566 
567  // s_2 is fixed at 1.0:
568  Face_index_at_boundary[i].push_back(3);
569  break;
570 
571 
572  default:
573 
574  throw OomphLibError("Never get here",
575  OOMPH_CURRENT_FUNCTION,
576  OOMPH_EXCEPTION_LOCATION);
577  }
578 
579  }
580  }
581  }
582 
583  // Doc?
584  //-----
585  if (doc)
586  {
587  // Loop over boundaries
588  for (unsigned i=0;i<nbound;i++)
589  {
590  unsigned nel=Boundary_element_pt[i].size();
591  outfile << "Boundary: " << i
592  << " is adjacent to " << nel
593  << " elements" << std::endl;
594 
595  // Loop over elements on given boundary
596  for (unsigned e=0;e<nel;e++)
597  {
598  FiniteElement* fe_pt=Boundary_element_pt[i][e];
599  outfile << "Boundary element:" << fe_pt
600  << " Face index along boundary is "
601  << Face_index_at_boundary[i][e] << std::endl;
602  }
603  }
604  }
605 
606 
607  // Lookup scheme has now been setup yet
608  Lookup_for_elements_next_boundary_is_setup=true;
609 
610 
611  // Cleanup temporary vectors
612  unsigned n=tmp_vect_pt.size();
613  for (unsigned i=0;i<n;i++)
614  {
615  delete tmp_vect_pt[i];
616  }*/
617  }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
Array< double, 1, 3 > e(1./3., 0.5, 2.)
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
Vector< Vector< FiniteElement * > > Boundary_element_pt
Definition: mesh.h:91
bool Lookup_for_elements_next_boundary_is_setup
Definition: mesh.h:87
FiniteElement * finite_element_pt(const unsigned &e) const
Definition: mesh.h:473
Vector< Vector< int > > Face_index_at_boundary
Definition: mesh.h:95
unsigned nboundary() const
Return number of boundaries.
Definition: mesh.h:827
unsigned long nelement() const
Return number of elements in the mesh.
Definition: mesh.h:590
static constexpr lastp1_t end
Definition: IndexedViewHelper.h:79
T sign(T x)
Definition: cxx11_tensor_builtins_sycl.cpp:172
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2

References oomph::Mesh::Boundary_element_pt, e(), Eigen::placeholders::end, oomph::Mesh::Face_index_at_boundary, oomph::Mesh::finite_element_pt(), oomph::Node::get_boundaries_pt(), i, j, oomph::Mesh::Lookup_for_elements_next_boundary_is_setup, n, oomph::Mesh::nboundary(), oomph::Mesh::nelement(), oomph::FiniteElement::nnode_1d(), oomph::FiniteElement::node_pt(), SYCL::sign(), and size.


The documentation for this class was generated from the following files: