32 return IT::Record(
"OutputMesh",
"Parameters of the refined output mesh. [Not impemented]")
34 "Maximal level of refinement of the output mesh.")
36 "Set true for using ``error_control_field``. Set false for global uniform refinement to max_level.")
38 "Name of an output field, according to which the output mesh will be refined. The field must be a SCALAR one.")
40 "Tolerance for element refinement by error. If tolerance is reached, refinement is stopped."
41 "Relative difference between error control field and its linear approximation on element is computed"
42 "and compared with tolerance.")
50 refine_by_error_(false),
51 refinement_error_tolerance_(0.0),
60 input_record_(in_rec),
62 max_level_(input_record_.val<int>(
"max_level")),
63 refine_by_error_(input_record_.val<bool>(
"refine_by_error")),
64 refinement_error_tolerance_(input_record_.val<double>(
"refinement_error_tolerance")),
110 return nodes_->n_values();
115 unsigned int elm_idx[1];
116 unsigned int node_idx[1];
117 unsigned int region_idx[1];
119 elem_ids_ = std::make_shared< ElementDataCache<unsigned int> >(
"elements_ids", (
unsigned int)1, this->
n_elements());
120 node_ids_ = std::make_shared< ElementDataCache<unsigned int> >(
"node_ids", (
unsigned int)1, this->
n_nodes());
121 region_ids_ = std::make_shared< ElementDataCache<unsigned int> >(
"region_ids", (
unsigned int)1, this->
n_elements());
122 partitions_ = std::make_shared< ElementDataCache<int> >(
"partitions", (
unsigned int)1, this->
n_elements());
124 for (
unsigned int i = 0; i < this->
n_elements(); ++i, ++
it) {
126 else elm_idx[0] =
it->idx();
136 for (
unsigned int j = 0; j <
it->n_nodes(); ++j) {
138 else node_idx[0] = node_list[j];
139 node_ids_->store_value( node_list[j], node_idx );
155 DebugOut() <<
"Create output submesh containing only local elements.";
157 unsigned int ele_id = 0,
169 const unsigned int n_local_elements =
el_ds_->
lsize();
176 auto &offset_vec = *(
offsets_->get_component_data(0).get() );
181 for (
unsigned int loc_el = 0; loc_el < n_local_elements; loc_el++) {
185 offset += elm->
dim() + 1;
186 offset_vec[ele_id+1] = offset;
187 (*orig_element_indices_)[ele_id] =
el_4_loc_[loc_el];
192 offset_vec[offset_vec.size()-1]);
193 auto &connectivity_vec = *(
connectivity_->get_component_data(0).get() );
194 for (
unsigned int loc_el = 0; loc_el < n_local_elements; loc_el++) {
196 for (
unsigned int li=0; li<elm->
n_nodes(); li++) {
198 connectivity_vec[conn_id++] = local_nodes_map[ elm.
node(li).idx() ];
204 auto &node_vec = *(
nodes_->get_component_data(0) );
205 for(
unsigned int i_node=0; i_node<local_nodes_map.size(); ++i_node) {
206 if (local_nodes_map[i_node]==
undef_idx)
continue;
208 coord_id = 3*local_nodes_map[i_node];
209 node_vec[coord_id++] = node[0];
210 node_vec[coord_id++] = node[1];
211 node_vec[coord_id] = node[2];
219 std::shared_ptr<ElementDataCache<unsigned int>> global_offsets;
227 master_mesh_->orig_element_indices_ = std::make_shared<std::vector<unsigned int>>(n_elems);
229 auto &offsets_vec = *(
master_mesh_->offsets_->get_component_data(0).get() );
230 auto &elems_n_nodes_vec = *( elems_n_nodes->get_component_data(0).get() );
231 unsigned int offset=0;
233 for (
unsigned int i=0; i<n_elems; ++i) {
234 offset += elems_n_nodes_vec[i];
235 offsets_vec[i+1] = offset;
247 master_mesh_->connectivity_ = serial_connectivity_cache;
260 auto &offset_vec = *(
offsets_->get_component_data(0).get() );
261 for (
unsigned int i=0; i<local_elems_n_nodes.
n_values(); ++i) local_elems_n_nodes_vec[i] = offset_vec[i+1] - offset_vec[i];
264 std::shared_ptr<ElementDataCache<unsigned int>> global_elems_n_nodes;
267 return global_elems_n_nodes;
295 ASSERT(0).error(
"Not implemented yet.");
300 ASSERT(0).error(
"Not implemented yet.");
307 return std::make_shared<OutputMesh>(*
orig_mesh_);
313 std::shared_ptr<ElementDataCache<double>> serial_nodes_cache;
318 if (
el_ds_->
myp()==0) serial_nodes_cache = std::dynamic_pointer_cast< ElementDataCache<double> >(serial_nodes);
319 return serial_nodes_cache;
325 std::shared_ptr<ElementDataCache<unsigned int>> serial_connectivity_cache;
328 auto &conn_vec = *(
connectivity_->get_component_data(0).get() );
331 for(
unsigned int i=0; i<conn_vec.size(); i++) {
336 auto &local_offset_vec = *(
offsets_->get_component_data(0).get() );
338 auto collective_conn = global_fix_size_conn->gather(
el_ds_,
el_4_loc_);
341 auto &offset_vec = *( global_offsets->get_component_data(0).get() );
342 serial_connectivity_cache = std::dynamic_pointer_cast< ElementDataCache<unsigned int> >( collective_conn->element_node_cache_optimize_size(offset_vec) );
344 return serial_connectivity_cache;
373 static const unsigned int n_subelements = 1 << dim;
453 refinement.push_back(aux_element);
465 nodes.reserve(n_old_nodes+n_new_nodes);
468 for(
unsigned int e=0; e < n_new_nodes; e++)
472 nodes.push_back( p / 2.0);
476 unsigned int diagonal = 0;
479 double min_diagonal = arma::norm(nodes[4]-nodes[9],2);
480 double d = arma::norm(nodes[5]-nodes[8],2);
481 if(d < min_diagonal){
485 d = arma::norm(nodes[6]-nodes[7],2);
486 if(d < min_diagonal){
492 for(
unsigned int i=0; i < n_subelements; i++)
495 sub_ele.
nodes.resize(n_old_nodes);
499 for(
unsigned int j=0; j < n_old_nodes; j++)
501 unsigned int conn_id = (n_old_nodes)*i + j;
502 sub_ele.
nodes[j] = nodes[conn[dim+diagonal][conn_id]];
504 refine_aux_element<dim>(sub_ele, refinement, ele_acc);
528 for(
auto& v : aux_ele.
nodes ) centre += v;
529 centre = centre/aux_ele.
nodes.size();
551 point_list.
set(0) = centre;
553 for (
auto node : ele.
nodes) point_list.
set(++i) = node;
560 double average_val = 0.0;
561 for(
unsigned int i=1; i<ele.
nodes.size()+1; ++i)
562 average_val += val_list[i];
563 average_val = average_val / ele.
nodes.size();
565 double diff = std::abs((average_val - val_list[0])/val_list[0]);
574 return std::make_shared<OutputMeshDiscontinuous>(*
orig_mesh_);
580 std::shared_ptr<ElementDataCache<double>> serial_nodes_cache;
583 std::shared_ptr< ElementDataCache<double> > discont_node_cache = std::make_shared<ElementDataCache<double>>(
"",
585 auto &discont_node_vec = *( discont_node_cache->get_component_data(0).get() );
586 auto &local_nodes_vec = *( this->
nodes_->get_component_data(0).get() );
587 auto &local_conn_vec = *( this->
connectivity_->get_component_data(0).get() );
588 auto &local_offset_vec = *( this->
offsets_->get_component_data(0).get() );
589 unsigned int i_old, i_new;
590 for (
unsigned int i_conn=0; i_conn<this->
connectivity_->n_values(); ++i_conn) {
594 discont_node_vec[i_new+i] = local_nodes_vec[i_old+i];
598 auto fix_size_node_cache = discont_node_cache->element_node_cache_fixed_size(local_offset_vec);
599 auto collect_fix_size_node_cache = fix_size_node_cache->gather(
el_ds_,
el_4_loc_);
602 auto &offset_vec = *( global_offsets->get_component_data(0).get() );
603 serial_nodes_cache = std::dynamic_pointer_cast< ElementDataCache<double> >(collect_fix_size_node_cache->element_node_cache_optimize_size(offset_vec));
605 return serial_nodes_cache;
611 std::shared_ptr<ElementDataCache<unsigned int>> serial_connectivity_cache;
614 auto &offset_vec = *( global_offsets->get_component_data(0).get() );
616 offset_vec[offset_vec.size()-1]);
617 auto &conn_vec = *( serial_connectivity_cache->get_component_data(0).get() );
618 for (
unsigned int i=0; i<conn_vec.size(); ++i) conn_vec[i] = i;
620 return serial_connectivity_cache;
628 DebugOut() <<
"Create refined discontinuous submesh containing only local elements.";
636 unsigned int last_offset = 0;
638 auto &node_vec = *(
nodes_->get_component_data(0).get() );
639 auto &conn_vec = *(
connectivity_->get_component_data(0).get() );
640 auto &offset_vec = *(
offsets_->get_component_data(0).get() );
645 offset_vec.push_back(0);
650 for (
unsigned int loc_el = 0; loc_el < n_local_elements; loc_el++) {
657 aux_ele.
nodes.resize(ele->n_nodes());
661 for (li=0; li<ele->n_nodes(); li++) {
662 aux_ele.
nodes[li] = *ele.node(li);
668 case 1: this->refine_aux_element<1>(aux_ele, refinement, ele);
break;
669 case 2: this->refine_aux_element<2>(aux_ele, refinement, ele);
break;
670 case 3: this->refine_aux_element<3>(aux_ele, refinement, ele);
break;
671 default:
ASSERT(0 < dim && dim < 4);
676 unsigned int node_offset = node_vec.size(),
677 con_offset = conn_vec.size();
678 node_vec.resize(node_vec.size() + (refinement.size() * (dim+1))*
spacedim);
679 conn_vec.resize(conn_vec.size() + refinement.size()*(dim+1));
684 for(
unsigned int i=0; i < refinement.size(); i++)
686 last_offset += dim+1;
687 offset_vec.push_back(last_offset);
688 (*orig_element_indices_).push_back(ele_idx);
689 for(
unsigned int j=0; j < dim+1; j++)
691 unsigned int con = i*(dim+1) + j;
692 conn_vec[con_offset + con] = con_offset + con;
694 for(
unsigned int k=0; k <
spacedim; k++) {
695 node_vec[node_offset + con*
spacedim + k] = refinement[i].nodes[j][k];
701 conn_vec.shrink_to_fit();
702 node_vec.shrink_to_fit();
703 offset_vec.shrink_to_fit();
707 offsets_->set_n_values(offset_vec.size());
715 for (
unsigned int i=0; i<
el_ds_->
lsize(); ++i, ++global_el_idx) {
720 for (
unsigned int i=0; i<
node_ds_->
lsize(); ++i, ++global_node_idx) {
734 auto &conn_vec = *( this->
connectivity_->get_component_data(0).get() );
737 auto &master_conn_vec = *(
master_mesh_->connectivity_->get_component_data(0).get() );
738 for (
unsigned int i=0; i<master_conn_vec.size(); ++i) master_conn_vec[i] = i;
741 auto &node_vec = *( this->
nodes_->get_component_data(0).get() );
742 auto &master_node_vec = *(
master_mesh_->nodes_->get_component_data(0).get() );
743 unsigned int i_own, i_master, j;
744 for (
unsigned int i=0; i<conn_vec.size(); ++i) {
748 master_node_vec[i_master+j] = node_vec[i_own+j];