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() );
179 for (
unsigned int loc_el = 0; loc_el < n_local_elements; loc_el++) {
182 offset += elm->
dim() + 1;
183 offset_vec[ele_id+1] = 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(li).idx() ];
201 auto &node_vec = *(
nodes_->get_component_data(0) );
202 for(
unsigned int i_node=0; i_node<local_nodes_map.size(); ++i_node) {
205 coord_id = 3*local_nodes_map[i_node];
206 node_vec[coord_id++] = node[0];
207 node_vec[coord_id++] = node[1];
208 node_vec[coord_id] = node[2];
216 std::shared_ptr<ElementDataCache<unsigned int>> global_offsets;
224 master_mesh_->orig_element_indices_ = std::make_shared<std::vector<unsigned int>>(n_elems);
226 auto &offsets_vec = *(
master_mesh_->offsets_->get_component_data(0).get() );
227 auto &elems_n_nodes_vec = *( elems_n_nodes->get_component_data(0).get() );
228 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+1] = offset;
244 master_mesh_->connectivity_ = serial_connectivity_cache;
257 auto &offset_vec = *(
offsets_->get_component_data(0).get() );
258 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];
261 std::shared_ptr<ElementDataCache<unsigned int>> global_elems_n_nodes;
264 return global_elems_n_nodes;
292 ASSERT(0).error(
"Not implemented yet.");
297 ASSERT(0).error(
"Not implemented yet.");
304 return std::make_shared<OutputMesh>(*
orig_mesh_);
310 std::shared_ptr<ElementDataCache<double>> serial_nodes_cache;
315 if (
el_ds_->
myp()==0) serial_nodes_cache = std::dynamic_pointer_cast< ElementDataCache<double> >(serial_nodes);
316 return serial_nodes_cache;
322 std::shared_ptr<ElementDataCache<unsigned int>> serial_connectivity_cache;
325 auto &conn_vec = *(
connectivity_->get_component_data(0).get() );
328 for(
unsigned int i=0; i<conn_vec.size(); i++) {
333 auto &local_offset_vec = *(
offsets_->get_component_data(0).get() );
335 auto collective_conn = global_fix_size_conn->gather(
el_ds_,
el_4_loc_);
338 auto &offset_vec = *( global_offsets->get_component_data(0).get() );
339 serial_connectivity_cache = std::dynamic_pointer_cast< ElementDataCache<unsigned int> >( collective_conn->element_node_cache_optimize_size(offset_vec) );
341 return serial_connectivity_cache;
370 static const unsigned int n_subelements = 1 << dim;
450 refinement.push_back(aux_element);
462 nodes.reserve(n_old_nodes+n_new_nodes);
465 for(
unsigned int e=0; e < n_new_nodes; e++)
469 nodes.push_back( p / 2.0);
473 unsigned int diagonal = 0;
476 double min_diagonal = arma::norm(nodes[4]-nodes[9],2);
477 double d = arma::norm(nodes[5]-nodes[8],2);
478 if(d < min_diagonal){
482 d = arma::norm(nodes[6]-nodes[7],2);
483 if(d < min_diagonal){
489 for(
unsigned int i=0; i < n_subelements; i++)
492 sub_ele.
nodes.resize(n_old_nodes);
496 for(
unsigned int j=0; j < n_old_nodes; j++)
498 unsigned int conn_id = (n_old_nodes)*i + j;
499 sub_ele.
nodes[j] = nodes[conn[dim+diagonal][conn_id]];
501 refine_aux_element<dim>(sub_ele, refinement, ele_acc);
525 for(
auto& v : aux_ele.
nodes ) centre += v;
526 centre = centre/aux_ele.
nodes.size();
548 point_list.
set(0) = centre;
550 for (
auto node : ele.
nodes) point_list.
set(++i) = node;
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() );
642 offset_vec.push_back(0);
647 for (
unsigned int loc_el = 0; loc_el < n_local_elements; loc_el++) {
654 aux_ele.
nodes.resize(ele->n_nodes());
658 for (li=0; li<ele->n_nodes(); li++) {
659 aux_ele.
nodes[li] = *ele.node(li);
665 case 1: this->refine_aux_element<1>(aux_ele, refinement, ele);
break;
666 case 2: this->refine_aux_element<2>(aux_ele, refinement, ele);
break;
667 case 3: this->refine_aux_element<3>(aux_ele, refinement, ele);
break;
668 default:
ASSERT(0 < dim && dim < 4);
673 unsigned int node_offset = node_vec.size(),
674 con_offset = conn_vec.size();
675 node_vec.resize(node_vec.size() + (refinement.size() * (dim+1))*
spacedim);
676 conn_vec.resize(conn_vec.size() + refinement.size()*(dim+1));
681 for(
unsigned int i=0; i < refinement.size(); i++)
683 last_offset += dim+1;
684 offset_vec.push_back(last_offset);
685 (*orig_element_indices_).push_back(ele_idx);
686 for(
unsigned int j=0; j < dim+1; j++)
688 unsigned int con = i*(dim+1) + j;
689 conn_vec[con_offset + con] = con_offset + con;
691 for(
unsigned int k=0; k <
spacedim; k++) {
692 node_vec[node_offset + con*
spacedim + k] = refinement[i].nodes[j][k];
698 conn_vec.shrink_to_fit();
699 node_vec.shrink_to_fit();
700 offset_vec.shrink_to_fit();
704 offsets_->set_n_values(offset_vec.size());
712 for (
unsigned int i=0; i<
el_ds_->
lsize(); ++i, ++global_el_idx) {
717 for (
unsigned int i=0; i<
node_ds_->
lsize(); ++i, ++global_node_idx) {
731 auto &conn_vec = *( this->
connectivity_->get_component_data(0).get() );
734 auto &master_conn_vec = *(
master_mesh_->connectivity_->get_component_data(0).get() );
735 for (
unsigned int i=0; i<master_conn_vec.size(); ++i) master_conn_vec[i] = i;
738 auto &node_vec = *( this->
nodes_->get_component_data(0).get() );
739 auto &master_node_vec = *(
master_mesh_->nodes_->get_component_data(0).get() );
740 unsigned int i_own, i_master, j;
741 for (
unsigned int i=0; i<conn_vec.size(); ++i) {
745 master_node_vec[i_master+j] = node_vec[i_own+j];