31 #ifndef OOMPH_GMSH_TET_MESH_TEMPLATE_CC 32 #define OOMPH_GMSH_TET_MESH_TEMPLATE_CC 44 template <
class ELEMENT>
57 double max_edge_ratio=this->compute_volume_target(elem_error,
60 unsigned n=target_size.size();
62 double min_size=DBL_MAX;
63 for (
unsigned e=0;
e<n;
e++)
65 if (target_size[
e]>max_size) max_size=target_size[
e];
66 if (target_size[
e]<min_size) min_size=target_size[
e];
69 oomph_info <<
"Maximum target size: " << max_size << std::endl;
70 oomph_info <<
"Minimum target size: " << min_size << std::endl;
71 oomph_info <<
"Number of elements to be refined " 72 << this->Nrefined << std::endl;
73 oomph_info <<
"Number of elements to be unrefined " 74 << this->Nunrefined << std::endl;
75 oomph_info <<
"Max edge ratio "<< max_edge_ratio << std::endl;
77 double orig_max_size, orig_min_size;
78 this->max_and_min_element_size(orig_max_size, orig_min_size);
79 oomph_info <<
"Max/min element size in original mesh: " 80 << orig_max_size <<
" " 81 << orig_min_size << std::endl;
84 oomph_info <<
"adapt: Time for getting volume targets : " 86 <<
" sec " << std::endl;
90 if ( (Nrefined > 0) || (Nunrefined > this->max_keep_unrefined())
91 || (max_edge_ratio > this->max_permitted_edge_ratio()) )
94 if (! ( (Nrefined > 0) || (Nunrefined > max_keep_unrefined()) ) )
97 <<
"Mesh regeneration triggered by edge ratio criterion\n";
107 bool use_eulerian_coords=
false;
108 if (solid_mesh_pt!=0)
110 use_eulerian_coords=
true;
115 #ifdef OOMPH_HAS_CGAL 119 if (use_eulerian_coords)
127 std::ostringstream error_message;
128 error_message <<
"Non-CGAL-based target size transfer not implemented.\n";
130 OOMPH_CURRENT_FUNCTION,
131 OOMPH_EXCEPTION_LOCATION);
139 std::map<GeneralisedElement*,unsigned> element_number;
140 unsigned nelem=this->nelement();
141 for (
unsigned e=0;
e<nelem;
e++)
143 element_number[this->element_pt(
e)]=
e;
149 min_and_max_coordinates();
152 double dx=(min_and_max_coordinates[0].second-
153 min_and_max_coordinates[0].first);
154 double dy=(min_and_max_coordinates[1].second-
155 min_and_max_coordinates[1].first);
156 double dz=(min_and_max_coordinates[2].second-
157 min_and_max_coordinates[2].first);
159 double dx_target=this->Gmsh_parameters_pt->dx_for_target_size_transfer();
160 unsigned nx=unsigned(dx/dx_target);
161 unsigned ny=unsigned(dy/dx_target);
162 unsigned nz=unsigned(dz/dx_target);
171 this->Gmsh_parameters_pt->target_size_file_name();
173 std::ofstream target_size_file;
174 target_size_file.open(target_size_file_name.c_str());
175 target_size_file << min_and_max_coordinates[0].first <<
" " 176 << min_and_max_coordinates[1].first <<
" " 177 << min_and_max_coordinates[2].first <<
" " 179 target_size_file << dx <<
" " << dy <<
" " << dz << std::endl;
180 target_size_file << nx+1 <<
" " << ny+1 <<
" " << nz+1 << std::endl;
184 int counter=this->Gmsh_parameters_pt->
185 counter_for_filename_gmsh_size_transfer();
187 stem_for_filename_gmsh_size_transfer();
188 std::ofstream latest_sizes_file;
189 bool doc_target_areas=
false;
190 if ((stem!=
"")&&(counter>=0))
192 doc_target_areas=
true;
195 latest_sizes_file.open(filename.c_str());
196 latest_sizes_file <<
"ZONE I=" << nx+1
200 this->Gmsh_parameters_pt->
201 counter_for_filename_gmsh_size_transfer()++;
206 for (
unsigned i=0;
i<=nx;
i++)
208 x[0]=min_and_max_coordinates[0].first+double(
i)*dx;
209 for (
unsigned j=0;j<=ny;j++)
211 x[1]=min_and_max_coordinates[1].first+double(j)*dy;
212 for (
unsigned k=0;k<=nz;k++)
214 x[2]=min_and_max_coordinates[2].first+double(k)*dz;
220 unsigned max_sample_points=this->Gmsh_parameters_pt->
221 max_sample_points_for_limited_locate_zeta_during_target_size_transfer();
223 #ifdef OOMPH_HAS_CGAL 226 sample_point_container_pt())->
227 limited_locate_zeta(x,max_sample_points,
232 std::ostringstream error_message;
233 error_message <<
"Non-CGAL-based target size transfer not implemented.\n";
235 OOMPH_CURRENT_FUNCTION,
236 OOMPH_EXCEPTION_LOCATION);
246 std::stringstream error_message;
248 <<
"Limited locate zeta failed for zeta = [ " 249 << x[0] <<
" " << x[1] <<
" " << x[2] <<
" ]. Makes no sense!\n";
251 OOMPH_CURRENT_FUNCTION,
252 OOMPH_EXCEPTION_LOCATION);
263 std::stringstream error_message;
265 <<
"Cast to FE for GeomObject returned by limited " 266 <<
"locate zeta failed for zeta = [ " 267 << x[0] <<
" " << x[1] <<
" " << x[2] <<
" ]. Makes no sense!\n";
269 OOMPH_CURRENT_FUNCTION,
270 OOMPH_EXCEPTION_LOCATION);
277 double tg_size=pow(target_size[element_number[fe_pt]],1.0/3.0);
278 target_size_file << tg_size <<
" ";
281 if (doc_target_areas)
283 latest_sizes_file << x[0] <<
" " 286 << tg_size << std::endl;
294 target_size_file << std::endl;
297 target_size_file.close();
299 if (doc_target_areas)
301 latest_sizes_file.close();
305 bool use_mesh_grading_from_file=
true;
308 use_mesh_grading_from_file,
309 this->Time_stepper_pt);
325 if (!this->Gmsh_parameters_pt->projection_is_disabled())
330 project_problem_pt->
mesh_pt()=new_mesh_pt;
331 project_problem_pt->
project(
this);
334 <<
"adapt: Time for project soln onto new mesh : " 336 <<
" sec " << std::endl;
343 unsigned nnod=nnode();
344 for(
unsigned j=nnod;j>0;j--)
349 unsigned nel=nelement();
350 for(
unsigned e=nel;
e>0;
e--)
352 delete Element_pt[
e-1];
358 nnod=new_mesh_pt->
nnode();
359 Node_pt.resize(nnod);
361 Element_pt.resize(nel);
362 for(
unsigned j=0;j<nnod;j++)
364 Node_pt[j] = new_mesh_pt->
node_pt(j);
366 for(
unsigned e=0;
e<nel;
e++)
372 unsigned nbound=new_mesh_pt->
nboundary();
373 Boundary_element_pt.resize(nbound);
374 Face_index_at_boundary.resize(nbound);
375 Boundary_node_pt.resize(nbound);
376 for (
unsigned b=0;b<nbound;b++)
379 Boundary_element_pt[b].resize(nel);
380 Face_index_at_boundary[b].resize(nel);
381 for (
unsigned e=0;
e<nel;
e++)
387 Boundary_node_pt[b].resize(nnod);
388 for (
unsigned j=0;j<nnod;j++)
395 unsigned n_region = new_mesh_pt->
nregion();
401 this->Region_element_pt.resize(n_region);
402 this->Region_attribute.resize(n_region);
403 for(
unsigned i=0;
i<n_region;
i++)
409 unsigned r=this->Region_attribute[
i];
411 this->Region_element_pt[
i].resize(n_region_element);
412 for(
unsigned e=0;
e<n_region_element;
e++)
419 this->Boundary_region_element_pt.resize(nbound);
420 this->Face_index_region_at_boundary.resize(nbound);
423 for(
unsigned b=0;b<nbound;++b)
426 for(
unsigned i=0;
i<n_region;++
i)
428 unsigned r=this->Region_attribute[
i];
430 unsigned n_boundary_el_in_region =
432 if(n_boundary_el_in_region > 0)
435 this->Boundary_region_element_pt[b][r].
436 resize(n_boundary_el_in_region);
437 this->Face_index_region_at_boundary[b][r].
438 resize(n_boundary_el_in_region);
441 for(
unsigned e=0;
e<n_boundary_el_in_region;++
e)
443 this->Boundary_region_element_pt[b][r][
e]
445 this->Face_index_region_at_boundary[b][r][
e]
460 delete project_problem_pt;
463 oomph_info <<
"adapt: Time for moving nodes etc. to actual mesh : " 465 <<
" sec " << std::endl;
470 if (solid_mesh_pt!=0)
473 std::stringstream error_message;
475 <<
"Lagrangian coordinates are currently not projected but are\n" 476 <<
"are re-set during adaptation. This is not appropriate for\n" 477 <<
"real solid mechanics problems!\n";
479 OOMPH_CURRENT_FUNCTION,
480 OOMPH_EXCEPTION_LOCATION);
483 dynamic_cast<SolidMesh*
>(
this)->set_lagrangian_nodal_coordinates();
488 this->max_and_min_element_size(max_area, min_area);
489 oomph_info <<
"Max/min element size in adapted mesh: " 491 << min_area << std::endl;
495 oomph_info <<
"Not enough benefit in adaptation.\n";
unsigned nboundary_element(const unsigned &b) const
Return number of finite elements that are adjacent to boundary b.
Node *& boundary_node_pt(const unsigned &b, const unsigned &n)
Return pointer to node n on boundary b.
SamplePointContainer * sample_point_container_pt() const
Pointer to the sample point container.
unsigned nregion()
Return the number of regions specified by attributes.
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.
Helper object for dealing with the parameters used for the CGALSamplePointContainer objects...
A general Finite Element class.
FiniteElement * boundary_element_pt(const unsigned &b, const unsigned &e) const
Return pointer to e-th finite element on boundary b.
CGAL-based SamplePointContainer.
unsigned long nboundary_node(const unsigned &ibound) const
Return number of nodes on a particular boundary.
void project(Mesh *base_mesh_pt, const bool &dont_project_positions=false)
Project from base into the problem's own mesh.
Mesh *& mesh_pt()
Return a pointer to the global mesh.
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 long nelement() const
Return number of elements in the mesh.
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.
void adapt(const Vector< double > &elem_error)
Adapt mesh, based on elemental error provided.
GeneralisedElement *& element_pt(const unsigned long &e)
Return pointer to element e.
unsigned nboundary() const
Return number of boundaries.
double timer()
returns the time in seconds after some point in past
Node *& node_pt(const unsigned long &n)
Return pointer to global node n.
unsigned long nnode() const
Return number of nodes in the mesh.
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
void enable_use_eulerian_coordinates_during_setup()
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_element(const unsigned &r)
Return the number of elements in region r.
void flush_element_and_node_storage()
Flush storage for elements and nodes by emptying the vectors that store the pointers to them...
FiniteElement * region_element_pt(const unsigned &r, const unsigned &e)
Return the e-th element in the r-th region.
unsigned nboundary_element_in_region(const unsigned &b, const unsigned &r) const
Return the number of elements adjacent to boundary b in region r.
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)...