tree.template.cc
Go to the documentation of this file.
1// LIC// ====================================================================
2// LIC// This file forms part of oomph-lib, the object-oriented,
3// LIC// multi-physics finite-element library, available
4// LIC// at http://www.oomph-lib.org.
5// LIC//
6// LIC// Copyright (C) 2006-2025 Matthias Heil and Andrew Hazel
7// LIC//
8// LIC// This library is free software; you can redistribute it and/or
9// LIC// modify it under the terms of the GNU Lesser General Public
10// LIC// License as published by the Free Software Foundation; either
11// LIC// version 2.1 of the License, or (at your option) any later version.
12// LIC//
13// LIC// This library is distributed in the hope that it will be useful,
14// LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16// LIC// Lesser General Public License for more details.
17// LIC//
18// LIC// You should have received a copy of the GNU Lesser General Public
19// LIC// License along with this library; if not, write to the Free Software
20// LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21// LIC// 02110-1301 USA.
22// LIC//
23// LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
24// LIC//
25// LIC//====================================================================
26#ifndef OOMPH_TREE_TEMPLATE_HEADER
27#define OOMPH_TREE_TEMPLATE_HEADER
28
29// Config header generated by autoconfig
30#ifdef HAVE_CONFIG_H
31#include <oomph-lib-config.h>
32#endif
33
34// oomph-lib headers
35#include "tree.h"
36
37#include <stdio.h>
38
39namespace oomph
40{
41 //================================================================
42 /// If required, split the leaf element and create its sons
43 ///
44 /// Split is performed if
45 ///
46 /// object_pt()->to_be_refined()
47 ///
48 /// returns true.
49 ///
50 /// If this is the case, then we execute
51 ///
52 /// object_pt()->split(new_elements_pt)
53 ///
54 /// to create the sons. Pointers to the son objects are then inserted
55 /// into the son pointers of the present element. This turns the
56 /// present element into a "grey" (=non-leaf) node.
57 ///
58 //=================================================================
59 template<class ELEMENT>
61 {
62#ifdef PARANOID
63 if (Son_pt.size() != 0)
64 {
65 std::string error_message =
66 "Can't split non-leaf elements (or at least I can't see\n";
67 error_message +=
68 "why you would want me to... If you're sure, then hack me... \n";
69
70 throw OomphLibError(
72 }
73
74 if (Object_pt == 0)
75 {
76 std::stringstream error_message;
77 error_message
78 << "No object defined in split_if_required. Father nodes:\n";
79
81 unsigned nnod = el_pt->nnode();
82 for (unsigned j = 0; j < nnod; j++)
83 {
85 unsigned n = nod_pt->ndim();
86 for (unsigned i = 0; i < n; i++)
87 {
88 error_message << nod_pt->x(i) << " ";
89 }
90 error_message << "\n";
91 }
92 throw OomphLibError(
94 }
95
96#endif
97
98 // Check if refinement is required
100 {
101 // Perform the split for the element in question and return Vector
102 // of pointers to the newly created elements
105
106 // Find the number of sons constructed by the element
107 unsigned n_sons = new_elements_pt.size();
108
109 // Turn the new elements into QuadTrees and assign
110 // the pointers to the present element's sons
111 Son_pt.resize(n_sons);
112 Tree* father_pt = this;
113 for (unsigned i_son = 0; i_son < n_sons; i_son++)
114 {
116 // Now that the son knows its position in the tree, we can set it
117 // up as a proper element (e.g. p-refineable stuff)
118 Son_pt[i_son]->object_pt()->initial_setup();
119 }
120 }
121 }
122
123
124 //================================================================
125 /// If required, p-refine/unrefine the leaf element
126 ///
127 /// p-refinement is performed if
128 ///
129 /// object_pt()->to_be_p_refined()
130 ///
131 /// returns true. p-unrefinement is performed if
132 ///
133 /// object_pt()->to_be_p_unrefined()
134 ///
135 /// returns true.
136 ///
137 /// If this is the case, then we execute
138 ///
139 /// object_pt()->p_refine(+/-1,mesh_pt,clone_pt)
140 ///
141 /// to p-refine the element, where mesh_pt is a pointer to the
142 /// mesh that the element lives in, and clone_pt is a pointer to
143 /// a GeneralisedElement that has all the information that would
144 /// be needed from the father element during h-refinement.
145 ///
146 //=================================================================
147 template<class ELEMENT>
149 {
150#ifdef PARANOID
151 if (Son_pt.size() != 0)
152 {
153 std::string error_message =
154 "Can't p-refine non-leaf elements (or at least I can't see\n";
155 error_message +=
156 "why you would want me to... If you're sure, then hack me... \n";
157
158 throw OomphLibError(
160 }
161
162 if (Object_pt == 0)
163 {
164 std::stringstream error_message;
165 error_message
166 << "No object defined in p_refine_if_required. Father nodes:\n";
167
169 unsigned nnod = el_pt->nnode();
170 for (unsigned j = 0; j < nnod; j++)
171 {
173 unsigned n = nod_pt->ndim();
174 for (unsigned i = 0; i < n; i++)
175 {
176 error_message << nod_pt->x(i) << " ";
177 }
178 error_message << "\n";
179 }
180 throw OomphLibError(
182 }
183
184#endif
185
186 // Cast to p-refineable element
188 dynamic_cast<PRefineableElement*>(Object_pt);
189
190 // Check if we can p-refine the element
191 if (p_ref_obj_pt == 0)
192 {
193 throw OomphLibError("Element cannot be p-refined",
196 }
197
198
199 // Create a temporary clone of the element to be refined.
200 // This is required so that the element can read data from "itself"
201 // while it rebuilds itself with a new p-order. Only the information
202 // required for the p-refinement is copied across.
203
204 // Make new element (using ELEMENT's standard constructor)
205 ELEMENT* clone_pt = new ELEMENT();
206
207 // Do initial setup with myself as the clone's adopted father
208 clone_pt->initial_setup(this);
209
210 // All that is left to do is to "build" the clone. It has the same
211 // nodes as me, so we can just copy across their pointers
212 for (unsigned j = 0; j < clone_pt->nnode(); j++)
213 {
215 }
216
217
218 // Check if refinement is required
219 if (p_ref_obj_pt->to_be_p_refined())
220 {
221 // Perform the split for the element in question and return Vector
222 // of pointers to the newly created elements
223 p_ref_obj_pt->p_refine(1, mesh_pt, clone_pt);
224 }
225 // Check if unrefinement is required
226 else if (p_ref_obj_pt->to_be_p_unrefined())
227 {
228 // Perform the split for the element in question and return Vector
229 // of pointers to the newly created elements
230 p_ref_obj_pt->p_refine(-1, mesh_pt, clone_pt);
231 }
232
233
234 // Delete the temporary copy of the element
235 delete clone_pt;
236 }
237
238
239} // namespace oomph
240
241#endif
cstr elem_len * i
Definition cfortran.h:603
double size() const
Calculate the size of the element (length, area, volume,...) in Eulerian computational coordinates....
Definition elements.cc:4320
unsigned nnode() const
Return the number of nodes.
Definition elements.h:2214
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition elements.h:2179
unsigned ndim() const
Access function to # of Eulerian coordinates.
A general mesh class.
Definition mesh.h:67
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
Definition nodes.h:906
An OomphLibError object which should be thrown when an run-time error is encountered....
p-refineable version of RefineableElement
RefineableElements are FiniteElements that may be subdivided into children to provide a better local ...
void split(Vector< ELEMENT * > &son_pt) const
Split the element into the number of sons to be constructed and return a vector of pointers to the so...
bool to_be_refined()
Has the element been selected for refinement?
TAdvectionDiffusionReactionElement<NREAGENT,DIM,NNODE_1D> elements are isoparametric triangular DIM-d...
A generalised tree base class that abstracts the common functionality between the quad- and octrees u...
Definition tree.h:74
Tree * Father_pt
Pointer to the Father of the Tree.
Definition tree.h:296
RefineableElement * Object_pt
Pointer to the object represented by the tree.
Definition tree.h:308
void p_refine_if_required(Mesh *&mesh_pt)
If required, p-refine the leaf – criterion: bool object_pt()-> to_be_p_refined() = true or bool objec...
RefineableElement * object_pt() const
Return the pointer to the object (RefineableElement) represented by the tree.
Definition tree.h:88
void split_if_required()
If required, split the leaf and create its sons – criterion: bool object_pt()-> to_be_refined() = tru...
Tree * father_pt() const
Return pointer to father: NULL if it's a root node.
Definition tree.h:235
Vector< Tree * > Son_pt
Vector of pointers to the sons of the Tree.
Definition tree.h:299
virtual Tree * construct_son(RefineableElement *const &object_pt, Tree *const &father_pt, const int &son_type)=0
A function that constructs a specific type of tree. This MUST be overloaded for each specific tree ty...
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).