27 #ifndef OOMPH_GMSH_TET_MESH_TEMPLATE_CC
28 #define OOMPH_GMSH_TET_MESH_TEMPLATE_CC
39 template<
class ELEMENT>
50 double max_edge_ratio =
51 this->compute_volume_target(elem_error, target_size);
53 unsigned n = target_size.size();
54 double max_size = 0.0;
55 double min_size = DBL_MAX;
56 for (
unsigned e = 0;
e < n;
e++)
58 if (target_size[
e] > max_size) max_size = target_size[
e];
59 if (target_size[
e] < min_size) min_size = target_size[
e];
62 oomph_info <<
"Maximum target size: " << max_size << std::endl;
63 oomph_info <<
"Minimum target size: " << min_size << std::endl;
64 oomph_info <<
"Number of elements to be refined " << this->Nrefined
66 oomph_info <<
"Number of elements to be unrefined " << this->Nunrefined
68 oomph_info <<
"Max edge ratio " << max_edge_ratio << std::endl;
70 double orig_max_size, orig_min_size;
71 this->max_and_min_element_size(orig_max_size, orig_min_size);
72 oomph_info <<
"Max/min element size in original mesh: " << orig_max_size
73 <<
" " << orig_min_size << std::endl;
77 <<
"adapt: Time for getting volume targets : "
82 if ((Nrefined > 0) || (Nunrefined > this->max_keep_unrefined()) ||
83 (max_edge_ratio > this->max_permitted_edge_ratio()))
85 if (!((Nrefined > 0) || (Nunrefined > max_keep_unrefined())))
87 oomph_info <<
"Mesh regeneration triggered by edge ratio criterion\n";
97 bool use_eulerian_coords =
false;
98 if (solid_mesh_pt != 0)
100 use_eulerian_coords =
true;
105 #ifdef OOMPH_HAS_CGAL
109 if (use_eulerian_coords)
117 std::ostringstream error_message;
118 error_message <<
"Non-CGAL-based target size transfer not implemented.\n";
120 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
128 std::map<GeneralisedElement*, unsigned> element_number;
129 unsigned nelem = this->nelement();
130 for (
unsigned e = 0;
e < nelem;
e++)
132 element_number[this->element_pt(
e)] =
e;
142 (min_and_max_coordinates[0].second - min_and_max_coordinates[0].first);
144 (min_and_max_coordinates[1].second - min_and_max_coordinates[1].first);
146 (min_and_max_coordinates[2].second - min_and_max_coordinates[2].first);
149 this->Gmsh_parameters_pt->dx_for_target_size_transfer();
150 unsigned nx = unsigned(dx / dx_target);
151 unsigned ny = unsigned(dy / dx_target);
152 unsigned nz = unsigned(dz / dx_target);
161 this->Gmsh_parameters_pt->target_size_file_name();
163 std::ofstream target_size_file;
164 target_size_file.open(target_size_file_name.c_str());
165 target_size_file << min_and_max_coordinates[0].first <<
" "
166 << min_and_max_coordinates[1].first <<
" "
167 << min_and_max_coordinates[2].first <<
" " << std::endl;
168 target_size_file << dx <<
" " << dy <<
" " << dz << std::endl;
169 target_size_file << nx + 1 <<
" " << ny + 1 <<
" " << nz + 1 << std::endl;
174 this->Gmsh_parameters_pt->counter_for_filename_gmsh_size_transfer();
176 this->Gmsh_parameters_pt->stem_for_filename_gmsh_size_transfer();
177 std::ofstream latest_sizes_file;
178 bool doc_target_areas =
false;
179 if ((stem !=
"") && (counter >= 0))
181 doc_target_areas =
true;
184 latest_sizes_file.open(filename.c_str());
185 latest_sizes_file <<
"ZONE I=" << nx + 1 <<
", J=" << ny + 1
186 <<
", K=" << nz + 1 << std::endl;
187 this->Gmsh_parameters_pt->counter_for_filename_gmsh_size_transfer()++;
192 for (
unsigned i = 0;
i <= nx;
i++)
194 x[0] = min_and_max_coordinates[0].first + double(
i) * dx;
195 for (
unsigned j = 0; j <= ny; j++)
197 x[1] = min_and_max_coordinates[1].first + double(j) * dy;
198 for (
unsigned k = 0; k <= nz; k++)
200 x[2] = min_and_max_coordinates[2].first + double(k) * dz;
206 unsigned max_sample_points =
207 this->Gmsh_parameters_pt
208 ->max_sample_points_for_limited_locate_zeta_during_target_size_transfer();
210 #ifdef OOMPH_HAS_CGAL
214 ->limited_locate_zeta(x, max_sample_points, geom_obj_pt,
s);
218 std::ostringstream error_message;
220 <<
"Non-CGAL-based target size transfer not implemented.\n";
222 OOMPH_CURRENT_FUNCTION,
223 OOMPH_EXCEPTION_LOCATION);
231 if (geom_obj_pt == 0)
233 std::stringstream error_message;
234 error_message <<
"Limited locate zeta failed for zeta = [ "
235 << x[0] <<
" " << x[1] <<
" " << x[2]
236 <<
" ]. Makes no sense!\n";
238 OOMPH_CURRENT_FUNCTION,
239 OOMPH_EXCEPTION_LOCATION);
250 std::stringstream error_message;
252 <<
"Cast to FE for GeomObject returned by limited "
253 <<
"locate zeta failed for zeta = [ " << x[0] <<
" " << x[1]
254 <<
" " << x[2] <<
" ]. Makes no sense!\n";
256 OOMPH_CURRENT_FUNCTION,
257 OOMPH_EXCEPTION_LOCATION);
266 pow(target_size[element_number[fe_pt]], 1.0 / 3.0);
267 target_size_file << tg_size <<
" ";
270 if (doc_target_areas)
272 latest_sizes_file << x[0] <<
" " << x[1] <<
" " << x[2] <<
" "
273 << tg_size << std::endl;
281 target_size_file << std::endl;
284 target_size_file.close();
286 if (doc_target_areas)
288 latest_sizes_file.close();
292 bool use_mesh_grading_from_file =
true;
295 use_mesh_grading_from_file,
296 this->Time_stepper_pt);
312 if (!this->Gmsh_parameters_pt->projection_is_disabled())
317 project_problem_pt->
mesh_pt() = new_mesh_pt;
318 project_problem_pt->
project(
this);
321 <<
"adapt: Time for project soln onto new mesh : "
329 unsigned nnod = nnode();
330 for (
unsigned j = nnod; j > 0; j--)
332 delete Node_pt[j - 1];
335 unsigned nel = nelement();
336 for (
unsigned e = nel;
e > 0;
e--)
338 delete Element_pt[
e - 1];
339 Element_pt[
e - 1] = 0;
344 nnod = new_mesh_pt->
nnode();
345 Node_pt.resize(nnod);
347 Element_pt.resize(nel);
348 for (
unsigned j = 0; j < nnod; j++)
350 Node_pt[j] = new_mesh_pt->
node_pt(j);
352 for (
unsigned e = 0;
e < nel;
e++)
358 unsigned nbound = new_mesh_pt->
nboundary();
359 Boundary_element_pt.resize(nbound);
360 Face_index_at_boundary.resize(nbound);
361 Boundary_node_pt.resize(nbound);
362 for (
unsigned b = 0; b < nbound; b++)
365 Boundary_element_pt[b].resize(nel);
366 Face_index_at_boundary[b].resize(nel);
367 for (
unsigned e = 0;
e < nel;
e++)
370 Face_index_at_boundary[b][
e] =
374 Boundary_node_pt[b].resize(nnod);
375 for (
unsigned j = 0; j < nnod; j++)
382 unsigned n_region = new_mesh_pt->
nregion();
388 this->Region_element_pt.resize(n_region);
389 this->Region_attribute.resize(n_region);
390 for (
unsigned i = 0;
i < n_region;
i++)
396 unsigned r = this->Region_attribute[
i];
398 this->Region_element_pt[
i].resize(n_region_element);
399 for (
unsigned e = 0;
e < n_region_element;
e++)
401 this->Region_element_pt[
i][
e] =
407 this->Boundary_region_element_pt.resize(nbound);
408 this->Face_index_region_at_boundary.resize(nbound);
411 for (
unsigned b = 0; b < nbound; ++b)
414 for (
unsigned i = 0;
i < n_region; ++
i)
416 unsigned r = this->Region_attribute[
i];
418 unsigned n_boundary_el_in_region =
420 if (n_boundary_el_in_region > 0)
423 this->Boundary_region_element_pt[b][r].resize(
424 n_boundary_el_in_region);
425 this->Face_index_region_at_boundary[b][r].resize(
426 n_boundary_el_in_region);
429 for (
unsigned e = 0;
e < n_boundary_el_in_region; ++
e)
431 this->Boundary_region_element_pt[b][r][
e] =
433 this->Face_index_region_at_boundary[b][r][
e] =
448 delete project_problem_pt;
452 <<
"adapt: Time for moving nodes etc. to actual mesh : "
458 if (solid_mesh_pt != 0)
461 std::stringstream error_message;
463 <<
"Lagrangian coordinates are currently not projected but are\n"
464 <<
"are re-set during adaptation. This is not appropriate for\n"
465 <<
"real solid mechanics problems!\n";
467 OOMPH_CURRENT_FUNCTION,
468 OOMPH_EXCEPTION_LOCATION);
471 dynamic_cast<SolidMesh*
>(
this)->set_lagrangian_nodal_coordinates();
476 this->max_and_min_element_size(max_area, min_area);
477 oomph_info <<
"Max/min element size in adapted mesh: " << max_area <<
" "
478 << min_area << std::endl;
482 oomph_info <<
"Not enough benefit in adaptation.\n";
///////////////////////////////////////////////////////////////////// ///////////////////////////////...
const std::pair< double, double > & min_and_max_coordinates(const unsigned &i) const
Pair of doubles for min and maximum coordinates in i-th direction: min (first) and max....
/////////////////////////////////////////////////////////////////////////// /////////////////////////...
A general Finite Element class.
/////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////// ///////////////////////////////...
SamplePointContainer * sample_point_container_pt() const
Pointer to the sample point container.
unsigned long nboundary_node(const unsigned &ibound) const
Return number of nodes on a particular boundary.
void flush_element_and_node_storage()
Flush storage for elements and nodes by emptying the vectors that store the pointers to them....
int face_index_at_boundary(const unsigned &b, const unsigned &e) const
For the e-th finite element on boundary b, return int to indicate the face_index of the face adjacent...
unsigned nboundary_element(const unsigned &b) const
Return number of finite elements that are adjacent to boundary b.
unsigned nboundary() const
Return number of boundaries.
FiniteElement * boundary_element_pt(const unsigned &b, const unsigned &e) const
Return pointer to e-th finite element on boundary b.
GeneralisedElement *& element_pt(const unsigned long &e)
Return pointer to element e.
unsigned long nnode() const
Return number of nodes in the mesh.
Node *& node_pt(const unsigned long &n)
Return pointer to global node n.
Node *& boundary_node_pt(const unsigned &b, const unsigned &n)
Return pointer to node n on boundary b.
unsigned long nelement() const
Return number of elements in the mesh.
An OomphLibError object which should be thrown when an run-time error is encountered....
An OomphLibWarning object which should be created as a temporary object to issue a warning....
Mesh *& mesh_pt()
Return a pointer to the global mesh.
Projection problem. This is created during the adaptation of unstructured meshes and it is assumed th...
void project(Mesh *base_mesh_pt, const bool &dont_project_positions=false)
Project from base into the problem's own mesh.
/////////////////////////////////////////////////////////////////////// /////////////////////////////...
void adapt(const Vector< double > &elem_error)
Adapt mesh, based on elemental error provided.
void enable_use_eulerian_coordinates_during_setup()
Enable use of eulerian coordinates (via interpolated_x) during setup (otherwise use interpolated_zeta...
int face_index_at_boundary_in_region(const unsigned &b, const unsigned &r, const unsigned &e) const
Return face index of the e-th element adjacent to boundary b in region r.
double region_attribute(const unsigned &i)
Return the i-th region attribute (here only used as the (assumed to be unsigned) region id.
unsigned nregion()
Return the number of regions specified by attributes.
unsigned nboundary_element_in_region(const unsigned &b, const unsigned &r) const
Return the number of elements adjacent to boundary b in region r.
FiniteElement * boundary_element_in_region_pt(const unsigned &b, const unsigned &r, const unsigned &e) const
Return pointer to the e-th element adjacent to boundary b in region r.
FiniteElement * region_element_pt(const unsigned &r, const unsigned &e)
Return the e-th element in the r-th region.
unsigned nregion_element(const unsigned &r)
Return the number of elements in region r.
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
std::string to_string(T object, unsigned float_precision=8)
Conversion function that should work for anything with operator<< defined (at least all basic types).
double timer()
returns the time in seconds after some point in past
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
OomphInfo oomph_info
Single (global) instantiation of the OomphInfo object – this is used throughout the library as a "rep...