33 return IT::Record(
"OutputMesh",
"Parameters of the refined output mesh. [Not impemented]")
35 "Maximal level of refinement of the output mesh.")
37 "Set true for using ``error_control_field``. Set false for global uniform refinement to max_level.")
39 "Name of an output field, according to which the output mesh will be refined. The field must be a SCALAR one.")
41 "Tolerance for element refinement by error. If tolerance is reached, refinement is stopped."
42 "Relative difference between error control field and its linear approximation on element is computed"
43 "and compared with tolerance.")
51 refine_by_error_(false),
52 refinement_error_tolerance_(0.0),
61 input_record_(in_rec),
63 max_level_(input_record_.val<int>(
"max_level")),
64 refine_by_error_(input_record_.val<bool>(
"refine_by_error")),
65 refinement_error_tolerance_(input_record_.val<double>(
"refinement_error_tolerance")),
111 return nodes_->n_values();
116 unsigned int elm_idx[1];
117 unsigned int node_idx[1];
118 unsigned int region_idx[1];
120 elem_ids_ = std::make_shared< ElementDataCache<unsigned int> >(
"elements_ids", (
unsigned int)1, this->
n_elements());
121 node_ids_ = std::make_shared< ElementDataCache<unsigned int> >(
"node_ids", (
unsigned int)1, this->
n_nodes());
122 region_ids_ = std::make_shared< ElementDataCache<unsigned int> >(
"region_ids", (
unsigned int)1, this->
n_elements());
123 partitions_ = std::make_shared< ElementDataCache<int> >(
"partitions", (
unsigned int)1, this->
n_elements());
125 for (
unsigned int i = 0; i < this->
n_elements(); ++i, ++
it) {
127 else elm_idx[0] =
it->idx();
137 for (
unsigned int j = 0; j <
it->n_nodes(); ++j) {
139 else node_idx[0] = node_list[j];
140 node_ids_->store_value( node_list[j], node_idx );
156 DebugOut() <<
"Create output submesh containing only local elements.";
158 unsigned int ele_id = 0,
170 const unsigned int n_local_elements =
el_ds_->
lsize();
177 auto &offset_vec = *(
offsets_->get_component_data(0).get() );
179 for (
unsigned int loc_el = 0; loc_el < n_local_elements; loc_el++) {
182 offset += elm->
dim() + 1;
183 offset_vec[ele_id] = offset;
184 (*orig_element_indices_)[ele_id] =
el_4_loc_[loc_el];
189 offset_vec[offset_vec.size()-1]);
190 auto &connectivity_vec = *(
connectivity_->get_component_data(0).get() );
191 for (
unsigned int loc_el = 0; loc_el < n_local_elements; loc_el++) {
193 for (
unsigned int li=0; li<elm->
n_nodes(); li++) {
195 connectivity_vec[conn_id++] = local_nodes_map[ elm.
node_accessor(li).idx() ];
201 auto &node_vec = *(
nodes_->get_component_data(0).get() );
203 for(
unsigned int i_node=0; i_node<local_nodes_map.size(); ++i_node) {
206 coord_id = 3*local_nodes_map[i_node];
207 node_vec[coord_id++] = node->
getX();
208 node_vec[coord_id++] = node->
getY();
209 node_vec[coord_id] = node->
getZ();
217 std::shared_ptr<ElementDataCache<unsigned int>> global_offsets;
225 master_mesh_->orig_element_indices_ = std::make_shared<std::vector<unsigned int>>(n_elems);
227 auto &offsets_vec = *(
master_mesh_->offsets_->get_component_data(0).get() );
228 auto &elems_n_nodes_vec = *( elems_n_nodes->get_component_data(0).get() );
229 unsigned int offset=0;
230 for (
unsigned int i=0; i<n_elems; ++i) {
231 offset += elems_n_nodes_vec[i];
232 offsets_vec[i] = offset;
244 master_mesh_->connectivity_ = serial_connectivity_cache;
257 auto &offset_vec = *(
offsets_->get_component_data(0).get() );
258 for (
unsigned int i=offset_vec.size()-1; i>0; --i) local_elems_n_nodes_vec[i] = offset_vec[i] - offset_vec[i-1];
259 local_elems_n_nodes_vec[0] = offset_vec[0];
262 std::shared_ptr<ElementDataCache<unsigned int>> global_elems_n_nodes;
265 return global_elems_n_nodes;
293 ASSERT(0).error(
"Not implemented yet.");
298 ASSERT(0).error(
"Not implemented yet.");
305 return std::make_shared<OutputMesh>(*
orig_mesh_);
311 std::shared_ptr<ElementDataCache<double>> serial_nodes_cache;
316 if (
el_ds_->
myp()==0) serial_nodes_cache = std::dynamic_pointer_cast< ElementDataCache<double> >(serial_nodes);
317 return serial_nodes_cache;
323 std::shared_ptr<ElementDataCache<unsigned int>> serial_connectivity_cache;
326 auto &conn_vec = *(
connectivity_->get_component_data(0).get() );
329 for(
unsigned int i=0; i<conn_vec.size(); i++) {
334 auto &local_offset_vec = *(
offsets_->get_component_data(0).get() );
336 auto collective_conn = global_fix_size_conn->gather(
el_ds_,
el_4_loc_);
339 auto &offset_vec = *( global_offsets->get_component_data(0).get() );
340 serial_connectivity_cache = std::dynamic_pointer_cast< ElementDataCache<unsigned int> >( collective_conn->element_node_cache_optimize_size(offset_vec) );
342 return serial_connectivity_cache;
371 static const unsigned int n_subelements = 1 << dim;
451 refinement.push_back(aux_element);
463 nodes.reserve(n_old_nodes+n_new_nodes);
466 for(
unsigned int e=0; e < n_new_nodes; e++)
470 nodes.push_back( p / 2.0);
474 unsigned int diagonal = 0;
477 double min_diagonal = arma::norm(nodes[4]-nodes[9],2);
478 double d = arma::norm(nodes[5]-nodes[8],2);
479 if(d < min_diagonal){
483 d = arma::norm(nodes[6]-nodes[7],2);
484 if(d < min_diagonal){
490 for(
unsigned int i=0; i < n_subelements; i++)
493 sub_ele.
nodes.resize(n_old_nodes);
497 for(
unsigned int j=0; j < n_old_nodes; j++)
499 unsigned int conn_id = (n_old_nodes)*i + j;
500 sub_ele.
nodes[j] = nodes[conn[dim+diagonal][conn_id]];
502 refine_aux_element<dim>(sub_ele, refinement, ele_acc);
526 for(
auto& v : aux_ele.
nodes ) centre += v;
527 centre = centre/aux_ele.
nodes.size();
549 point_list.push_back(centre);
550 point_list.insert(point_list.end(), ele.
nodes.begin(), ele.
nodes.end());
557 double average_val = 0.0;
558 for(
unsigned int i=1; i<ele.
nodes.size()+1; ++i)
559 average_val += val_list[i];
560 average_val = average_val / ele.
nodes.size();
562 double diff = std::abs((average_val - val_list[0])/val_list[0]);
571 return std::make_shared<OutputMeshDiscontinuous>(*
orig_mesh_);
577 std::shared_ptr<ElementDataCache<double>> serial_nodes_cache;
580 std::shared_ptr< ElementDataCache<double> > discont_node_cache = std::make_shared<ElementDataCache<double>>(
"",
582 auto &discont_node_vec = *( discont_node_cache->get_component_data(0).get() );
583 auto &local_nodes_vec = *( this->
nodes_->get_component_data(0).get() );
584 auto &local_conn_vec = *( this->
connectivity_->get_component_data(0).get() );
585 auto &local_offset_vec = *( this->
offsets_->get_component_data(0).get() );
586 unsigned int i_old, i_new;
587 for (
unsigned int i_conn=0; i_conn<this->
connectivity_->n_values(); ++i_conn) {
591 discont_node_vec[i_new+i] = local_nodes_vec[i_old+i];
595 auto fix_size_node_cache = discont_node_cache->element_node_cache_fixed_size(local_offset_vec);
596 auto collect_fix_size_node_cache = fix_size_node_cache->gather(
el_ds_,
el_4_loc_);
599 auto &offset_vec = *( global_offsets->get_component_data(0).get() );
600 serial_nodes_cache = std::dynamic_pointer_cast< ElementDataCache<double> >(collect_fix_size_node_cache->element_node_cache_optimize_size(offset_vec));
602 return serial_nodes_cache;
608 std::shared_ptr<ElementDataCache<unsigned int>> serial_connectivity_cache;
611 auto &offset_vec = *( global_offsets->get_component_data(0).get() );
613 offset_vec[offset_vec.size()-1]);
614 auto &conn_vec = *( serial_connectivity_cache->get_component_data(0).get() );
615 for (
unsigned int i=0; i<conn_vec.size(); ++i) conn_vec[i] = i;
617 return serial_connectivity_cache;
625 DebugOut() <<
"Create refined discontinuous submesh containing only local elements.";
633 unsigned int last_offset = 0;
635 auto &node_vec = *(
nodes_->get_component_data(0).get() );
636 auto &conn_vec = *(
connectivity_->get_component_data(0).get() );
637 auto &offset_vec = *(
offsets_->get_component_data(0).get() );
646 for (
unsigned int loc_el = 0; loc_el < n_local_elements; loc_el++) {
653 aux_ele.
nodes.resize(ele->n_nodes());
657 for (li=0; li<ele->n_nodes(); li++) {
658 aux_ele.
nodes[li] = ele.node_accessor(li)->point();
664 case 1: this->refine_aux_element<1>(aux_ele, refinement, ele);
break;
665 case 2: this->refine_aux_element<2>(aux_ele, refinement, ele);
break;
666 case 3: this->refine_aux_element<3>(aux_ele, refinement, ele);
break;
667 default:
ASSERT(0 < dim && dim < 4);
672 unsigned int node_offset = node_vec.size(),
673 con_offset = conn_vec.size();
674 node_vec.resize(node_vec.size() + (refinement.size() * (dim+1))*
spacedim);
675 conn_vec.resize(conn_vec.size() + refinement.size()*(dim+1));
680 for(
unsigned int i=0; i < refinement.size(); i++)
682 last_offset += dim+1;
683 offset_vec.push_back(last_offset);
684 (*orig_element_indices_).push_back(ele_idx);
685 for(
unsigned int j=0; j < dim+1; j++)
687 unsigned int con = i*(dim+1) + j;
688 conn_vec[con_offset + con] = con_offset + con;
690 for(
unsigned int k=0; k <
spacedim; k++) {
691 node_vec[node_offset + con*
spacedim + k] = refinement[i].nodes[j][k];
697 conn_vec.shrink_to_fit();
698 node_vec.shrink_to_fit();
699 offset_vec.shrink_to_fit();
703 offsets_->set_n_values(offset_vec.size());
711 for (
unsigned int i=0; i<
el_ds_->
lsize(); ++i, ++global_el_idx) {
716 for (
unsigned int i=0; i<
node_ds_->
lsize(); ++i, ++global_node_idx) {
730 auto &conn_vec = *( this->
connectivity_->get_component_data(0).get() );
733 auto &master_conn_vec = *(
master_mesh_->connectivity_->get_component_data(0).get() );
734 for (
unsigned int i=0; i<master_conn_vec.size(); ++i) master_conn_vec[i] = i;
737 auto &node_vec = *( this->
nodes_->get_component_data(0).get() );
738 auto &master_node_vec = *(
master_mesh_->nodes_->get_component_data(0).get() );
739 unsigned int i_own, i_master, j;
740 for (
unsigned int i=0; i<conn_vec.size(); ++i) {
744 master_node_vec[i_master+j] = node_vec[i_own+j];