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_data().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_data().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_data() );
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);
228 master_mesh_->offsets_ = std::make_shared<ElementDataCache<unsigned int>>(
230 auto &offsets_vec = *(
master_mesh_->offsets_->get_data().get() );
231 auto &elems_n_nodes_vec = *( elems_n_nodes->get_data().get() );
232 unsigned int offset=0;
234 for (
unsigned int i=0; i<n_elems; ++i) {
235 offset += elems_n_nodes_vec[i];
236 offsets_vec[i+1] = offset;
248 master_mesh_->connectivity_ = serial_connectivity_cache;
260 auto &local_elems_n_nodes_vec = *( local_elems_n_nodes.
get_data().get() );
261 auto &offset_vec = *(
offsets_->get_data().get() );
262 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];
265 std::shared_ptr<ElementDataCache<unsigned int>> global_elems_n_nodes;
268 return global_elems_n_nodes;
296 ASSERT(0).error(
"Not implemented yet.");
301 ASSERT(0).error(
"Not implemented yet.");
308 return std::make_shared<OutputMesh>(*
orig_mesh_);
314 std::shared_ptr<ElementDataCache<double>> serial_nodes_cache;
319 if (
el_ds_->
myp()==0) serial_nodes_cache = std::dynamic_pointer_cast< ElementDataCache<double> >(serial_nodes);
320 return serial_nodes_cache;
326 std::shared_ptr<ElementDataCache<unsigned int>> serial_connectivity_cache;
331 auto &global_conn_vec = *( global_conn.
get_data().get() );
332 for(
unsigned int i=0; i<conn_vec.size(); i++) {
337 auto &local_offset_vec = *(
offsets_->get_data().get() );
339 auto collective_conn = global_fix_size_conn->gather(
el_ds_,
el_4_loc_);
342 auto &offset_vec = *( global_offsets->get_data().get() );
343 serial_connectivity_cache = std::dynamic_pointer_cast< ElementDataCache<unsigned int> >( collective_conn->element_node_cache_optimize_size(offset_vec) );
345 return serial_connectivity_cache;
374 static const unsigned int n_subelements = 1 << dim;
454 refinement.push_back(aux_element);
466 nodes.reserve(n_old_nodes+n_new_nodes);
469 for(
unsigned int e=0; e < n_new_nodes; e++)
473 nodes.push_back( p / 2.0);
477 unsigned int diagonal = 0;
480 double min_diagonal = arma::norm(nodes[4]-nodes[9],2);
481 double d = arma::norm(nodes[5]-nodes[8],2);
482 if(d < min_diagonal){
486 d = arma::norm(nodes[6]-nodes[7],2);
487 if(d < min_diagonal){
493 for(
unsigned int i=0; i < n_subelements; i++)
496 sub_ele.
nodes.resize(n_old_nodes);
500 for(
unsigned int j=0; j < n_old_nodes; j++)
502 unsigned int conn_id = (n_old_nodes)*i + j;
503 sub_ele.
nodes[j] = nodes[conn[dim+diagonal][conn_id]];
505 refine_aux_element<dim>(sub_ele, refinement, ele_acc);
529 for(
auto& v : aux_ele.
nodes ) centre += v;
530 centre = centre/aux_ele.
nodes.size();
552 point_list.
set(0) = centre;
554 for (
auto node : ele.
nodes) point_list.
set(++i) = node;
561 double average_val = 0.0;
562 for(
unsigned int i=1; i<ele.
nodes.size()+1; ++i)
563 average_val += val_list[i];
564 average_val = average_val / ele.
nodes.size();
566 double diff = std::abs((average_val - val_list[0])/val_list[0]);
575 return std::make_shared<OutputMeshDiscontinuous>(*
orig_mesh_);
581 std::shared_ptr<ElementDataCache<double>> serial_nodes_cache;
584 std::shared_ptr< ElementDataCache<double> > discont_node_cache = std::make_shared<ElementDataCache<double>>(
"",
586 auto &discont_node_vec = *( discont_node_cache->get_data().get() );
587 auto &local_nodes_vec = *( this->
nodes_->get_data().get() );
588 auto &local_conn_vec = *( this->
connectivity_->get_data().get() );
589 auto &local_offset_vec = *( this->
offsets_->get_data().get() );
590 unsigned int i_old, i_new;
591 for (
unsigned int i_conn=0; i_conn<this->
connectivity_->n_values(); ++i_conn) {
595 discont_node_vec[i_new+i] = local_nodes_vec[i_old+i];
599 auto fix_size_node_cache = discont_node_cache->element_node_cache_fixed_size(local_offset_vec);
600 auto collect_fix_size_node_cache = fix_size_node_cache->gather(
el_ds_,
el_4_loc_);
603 auto &offset_vec = *( global_offsets->get_data().get() );
604 serial_nodes_cache = std::dynamic_pointer_cast< ElementDataCache<double> >(collect_fix_size_node_cache->element_node_cache_optimize_size(offset_vec));
606 return serial_nodes_cache;
612 std::shared_ptr<ElementDataCache<unsigned int>> serial_connectivity_cache;
615 auto &offset_vec = *( global_offsets->get_data().get() );
616 serial_connectivity_cache = std::make_shared<ElementDataCache<unsigned int>>(
618 auto &conn_vec = *( serial_connectivity_cache->get_data().get() );
619 for (
unsigned int i=0; i<conn_vec.size(); ++i) conn_vec[i] = i;
621 return serial_connectivity_cache;
629 DebugOut() <<
"Create refined discontinuous submesh containing only local elements.";
637 unsigned int last_offset = 0;
639 auto &node_vec = *(
nodes_->get_data().get() );
641 auto &offset_vec = *(
offsets_->get_data().get() );
646 offset_vec.push_back(0);
651 for (
unsigned int loc_el = 0; loc_el < n_local_elements; loc_el++) {
658 aux_ele.
nodes.resize(ele->n_nodes());
662 for (li=0; li<ele->n_nodes(); li++) {
663 aux_ele.
nodes[li] = *ele.node(li);
669 case 1: this->refine_aux_element<1>(aux_ele, refinement, ele);
break;
670 case 2: this->refine_aux_element<2>(aux_ele, refinement, ele);
break;
671 case 3: this->refine_aux_element<3>(aux_ele, refinement, ele);
break;
672 default:
ASSERT(0 < dim && dim < 4);
677 unsigned int node_offset = node_vec.size(),
678 con_offset = conn_vec.size();
679 node_vec.resize(node_vec.size() + (refinement.size() * (dim+1))*
spacedim);
680 conn_vec.resize(conn_vec.size() + refinement.size()*(dim+1));
685 for(
unsigned int i=0; i < refinement.size(); i++)
687 last_offset += dim+1;
688 offset_vec.push_back(last_offset);
689 (*orig_element_indices_).push_back(ele_idx);
690 for(
unsigned int j=0; j < dim+1; j++)
692 unsigned int con = i*(dim+1) + j;
693 conn_vec[con_offset + con] = con_offset + con;
695 for(
unsigned int k=0; k <
spacedim; k++) {
696 node_vec[node_offset + con*
spacedim + k] = refinement[i].nodes[j][k];
702 conn_vec.shrink_to_fit();
703 node_vec.shrink_to_fit();
704 offset_vec.shrink_to_fit();
708 offsets_->set_n_values(offset_vec.size());
716 for (
unsigned int i=0; i<
el_ds_->
lsize(); ++i, ++global_el_idx) {
721 for (
unsigned int i=0; i<
node_ds_->
lsize(); ++i, ++global_node_idx) {
736 master_mesh_->connectivity_ = std::make_shared<ElementDataCache<unsigned int>>(
738 auto &master_conn_vec = *(
master_mesh_->connectivity_->get_data().get() );
739 for (
unsigned int i=0; i<master_conn_vec.size(); ++i) master_conn_vec[i] = i;
741 master_mesh_->nodes_ = std::make_shared<ElementDataCache<double>>(
743 auto &node_vec = *( this->
nodes_->get_data().get() );
744 auto &master_node_vec = *(
master_mesh_->nodes_->get_data().get() );
745 unsigned int i_own, i_master, j;
746 for (
unsigned int i=0; i<conn_vec.size(); ++i) {
750 master_node_vec[i_master+j] = node_vec[i_own+j];