31 #ifndef OOMPH_GMSH_TET_MESH_TEMPLATE_CC 32 #define OOMPH_GMSH_TET_MESH_TEMPLATE_CC 44 template <
class ELEMENT>
52 t_start=TimingHelpers::timer();
56 Vector<double> target_size(elem_error.size());
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 : " 85 << TimingHelpers::timer()-t_start
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";
102 SolidMesh* solid_mesh_pt=
dynamic_cast<SolidMesh*
>(
this);
107 bool use_eulerian_coords=
false;
108 if (solid_mesh_pt!=0)
110 use_eulerian_coords=
true;
113 MeshAsGeomObject* mesh_geom_obj_pt=0;
115 #ifdef OOMPH_HAS_CGAL 118 CGALSamplePointContainerParameters cgal_params(
this);
119 if (use_eulerian_coords)
121 cgal_params.enable_use_eulerian_coordinates_during_setup();
123 mesh_geom_obj_pt=
new MeshAsGeomObject(&cgal_params);
127 std::ostringstream error_message;
128 error_message <<
"Non-CGAL-based target size transfer not implemented.\n";
129 throw OomphLibError(error_message.str(),
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;
147 Vector<std::pair<double, double> > min_and_max_coordinates=
148 mesh_geom_obj_pt->sample_point_container_pt()->
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);
170 std::string target_size_file_name=
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();
186 std::string stem=this->Gmsh_parameters_pt->
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;
193 std::string filename=stem+
194 oomph::StringConversion::to_string(counter)+
".dat";
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;
219 GeomObject* geom_obj_pt=0;
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 225 dynamic_cast<CGALSamplePointContainer*
>(mesh_geom_obj_pt->
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";
234 throw OomphLibError(error_message.str(),
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";
250 throw OomphLibError(error_message.str(),
251 OOMPH_CURRENT_FUNCTION,
252 OOMPH_EXCEPTION_LOCATION);
258 FiniteElement* fe_pt=
dynamic_cast<FiniteElement*
>(geom_obj_pt);
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";
268 throw OomphLibError(error_message.str(),
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);
319 t_start=TimingHelpers::timer();
322 ProjectionProblem<ELEMENT>* project_problem_pt=0;
325 if (!this->Gmsh_parameters_pt->projection_is_disabled())
329 project_problem_pt=
new ProjectionProblem<ELEMENT>;
330 project_problem_pt->mesh_pt()=new_mesh_pt;
331 project_problem_pt->project(
this);
334 <<
"adapt: Time for project soln onto new mesh : " 335 << TimingHelpers::timer()-t_start
336 <<
" sec " << std::endl;
339 t_start=TimingHelpers::timer();
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);
360 nel=new_mesh_pt->nelement();
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++)
368 Element_pt[e] = new_mesh_pt->element_pt(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++)
378 unsigned nel=new_mesh_pt->nboundary_element(b);
379 Boundary_element_pt[b].resize(nel);
380 Face_index_at_boundary[b].resize(nel);
381 for (
unsigned e=0;e<nel;e++)
383 Boundary_element_pt[b][e]=new_mesh_pt->boundary_element_pt(b,e);
384 Face_index_at_boundary[b][e]=new_mesh_pt->face_index_at_boundary(b,e);
386 unsigned nnod=new_mesh_pt->nboundary_node(b);
387 Boundary_node_pt[b].resize(nnod);
388 for (
unsigned j=0;j<nnod;j++)
390 Boundary_node_pt[b][j]=new_mesh_pt->boundary_node_pt(b,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++)
406 this->Region_attribute[i] = new_mesh_pt->region_attribute(i);
409 unsigned r=this->Region_attribute[i];
410 unsigned n_region_element = new_mesh_pt->nregion_element(r);
411 this->Region_element_pt[i].resize(n_region_element);
412 for(
unsigned e=0;e<n_region_element;e++)
414 this->Region_element_pt[i][e] = new_mesh_pt->region_element_pt(r,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 =
431 new_mesh_pt->nboundary_element_in_region(b,r);
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]
444 = new_mesh_pt->boundary_element_in_region_pt(b,r,e);
445 this->Face_index_region_at_boundary[b][r][e]
446 = new_mesh_pt->face_index_at_boundary_in_region(b,r,e);
456 new_mesh_pt->flush_element_and_node_storage();
460 delete project_problem_pt;
463 oomph_info <<
"adapt: Time for moving nodes etc. to actual mesh : " 464 << TimingHelpers::timer()-t_start
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";
478 OomphLibWarning(error_message.str(),
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";
void adapt(const Vector< double > &elem_error)
Adapt mesh, based on elemental error provided.