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() + 1;
136 for (
unsigned int j = 0; j <
it->n_nodes(); ++j) {
138 else node_idx[0] = node_list[j] + 1;
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++) {
197 ASSERT(local_nodes_map[ elm.
node(li).idx() ] !=
undef_idx)(elm.
node(li).idx()).error(
"Undefined global to local node index!");
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;
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;
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];
#define ASSERT_PERMANENT(expr)
Allow use shorter versions of macro names if these names is not used with external library.
#define ASSERT_EQ(a, b)
Definition of comparative assert macro (EQual) only for debug mode.
#define ASSERT_PTR(ptr)
Definition of assert macro checking non-null pointer (PTR) only for debug mode.
ArrayMatSet set(uint index)
unsigned int myp() const
get my processor
unsigned int begin(int proc) const
get starting local index
unsigned int end(int proc) const
get last local index +1
unsigned int lsize(int proc) const
get local size
unsigned int size() const
get global size
unsigned int np() const
get num of processors
NodeAccessor< 3 > node(unsigned int ni) const
unsigned int n_values() const
std::shared_ptr< ElementDataCacheBase > gather(Distribution *distr, LongIdx *local_to_global) override
Implements ElementDataCacheBase::gather.
std::shared_ptr< ElementDataCacheBase > element_node_cache_fixed_size(std::vector< unsigned int > &offset_vec) override
Implements ElementDataCacheBase::element_node_cache_fixed_size.
CacheData get_data()
Return underlying vector of element data.
unsigned int n_nodes() const
General iterator template. Provides iterator over objects of type Object in some container.
LongIdx * get_el_4_loc() const
unsigned int n_nodes() const
int find_node_id(unsigned int pos) const
Return node id (in GMSH file) of node of given position in node vector.
NodeAccessor< 3 > node(unsigned int idx) const
Create and return NodeAccessor to node of given idx.
int find_elem_id(unsigned int pos) const
Return element id (in GMSH file) of element of given position in element vector.
Distribution * get_el_ds() const
unsigned int n_elements() const
ElementAccessor< 3 > element_accessor(unsigned int idx) const
Create and return ElementAccessor to element of given idx.
LongIdx * get_node_4_loc() const
unsigned int n_local_nodes() const
Distribution * get_node_ds() const
Base class for Output mesh.
double refinement_error_tolerance_
Tolerance for error criterion refinement.
virtual std::shared_ptr< ElementDataCache< double > > make_serial_nodes_cache(std::shared_ptr< ElementDataCache< unsigned int >> global_offsets)=0
friend class OutputElement
Friend provides access to vectors for element accessor class.
OutputMeshBase(Mesh &mesh)
Constructor. Takes computational mesh as a parameter.
LongIdx * node_4_loc_
Index set assigning to local node index its global index.
std::shared_ptr< ElementDataCache< unsigned int > > connectivity_
Vector maps the nodes to their coordinates in vector nodes_.
void make_serial_master_mesh()
Synchronize parallel data and create serial COLECTIVE output mesh on zero process.
std::function< void(const Armor::array &, const ElementAccessor< spacedim > &, std::vector< double > &)> ErrorControlFieldFunc
virtual std::shared_ptr< OutputMeshBase > construct_mesh()=0
static const Input::Type::Record & get_input_type()
The specification of output mesh.
std::shared_ptr< ElementDataCache< unsigned int > > get_elems_n_nodes()
Compute and return number of nodes for each elements (compute from offsets)
unsigned int n_elements()
Returns number of element.
friend class OutputMeshDiscontinuous
std::shared_ptr< OutputMeshBase > master_mesh_
bool is_created()
Check if nodes_, connectivity_ and offsets_ data caches are created.
LongIdx * el_4_loc_
Index set assigning to local element index its global index.
virtual std::shared_ptr< ElementDataCache< unsigned int > > make_serial_connectivity_cache(std::shared_ptr< ElementDataCache< unsigned int >> global_offsets)=0
Distribution * el_ds_
Parallel distribution of elements.
std::shared_ptr< ElementDataCache< unsigned int > > node_ids_
Vector gets ids of nodes. Data is used in GMSH output.
bool refine_by_error_
True, if output mesh is to be refined by error criterion.
ErrorControlFieldFunc error_control_field_func_
Refinement error control field function (hold value_list function of field).
OutputElementIterator begin()
Gives iterator to the FIRST element of the output mesh.
std::shared_ptr< std::vector< unsigned int > > orig_element_indices_
Vector of element indices in the computational mesh. (Important when refining.)
const unsigned int max_level_
Maximal level of refinement.
OutputElementIterator end()
Gives iterator to the LAST element of the output mesh.
std::shared_ptr< ElementDataCache< unsigned int > > elem_ids_
Vector gets ids of elements. Data is used in GMSH output.
std::shared_ptr< ElementDataCache< int > > partitions_
Vector gets partitions of elements. Data is used in GMSH output.
std::shared_ptr< ElementDataCache< double > > nodes_
Vector of node coordinates. [spacedim x n_nodes].
static const unsigned int spacedim
Shortcut instead of spacedim template. We suppose only spacedim=3 at the moment.
MeshType mesh_type_
Type of OutputMesh.
std::shared_ptr< ElementDataCache< unsigned int > > offsets_
Vector of offsets of node indices of elements. Maps elements to their nodes in connectivity_.
unsigned int n_nodes()
Returns number of nodes.
unsigned int n_local_nodes_
Hold number of local nodes (own + ghost), value is equal with size of node_4_loc array.
Mesh * orig_mesh_
Pointer to the computational mesh.
void set_error_control_field(ErrorControlFieldFunc error_control_field_func)
Selects the error control field computing function of output field set according to input record.
LongIdx * loc_4_el_
Index set assigning to global index its local element index.
virtual ~OutputMeshBase()
Distribution * node_ds_
Parallel distribution of nodes. Depends on elements distribution.
std::shared_ptr< ElementDataCache< unsigned int > > region_ids_
Vector gets ids of regions. Data is used in GMSH output.
void create_id_caches()
Create nodes and elements data caches.
bool refinement_criterion_error(const AuxElement &ele, const Space< spacedim >::Point ¢re, const ElementAccessor< spacedim > &ele_acc)
Refinement flag - measures discretisation error according to error control field.
void make_parallel_master_mesh() override
Overrides OutputMeshBase::make_parallel_master_mesh.
void create_refined_sub_mesh() override
Implements OutputMeshBase::create_refined_sub_mesh.
bool refinement_criterion_uniform(const AuxElement &ele)
Refinement flag - checks only maximal level of refinement.
bool refinement_criterion(const AuxElement &ele, const ElementAccessor< spacedim > &ele_acc)
Collects different refinement criteria results.
void refine_aux_element(const AuxElement &aux_element, std::vector< AuxElement > &refinement, const ElementAccessor< spacedim > &ele_acc)
Performs the actual refinement of AuxElement. Recurrent.
std::shared_ptr< ElementDataCache< unsigned int > > make_serial_connectivity_cache(std::shared_ptr< ElementDataCache< unsigned int >> global_offsets) override
Implements OutputMeshBase::make_serial_connectivity_cache.
std::shared_ptr< ElementDataCache< double > > make_serial_nodes_cache(std::shared_ptr< ElementDataCache< unsigned int >> global_offsets) override
Implements OutputMeshBase::make_serial_nodes_cache.
std::shared_ptr< OutputMeshBase > construct_mesh() override
Implements OutputMeshBase::construct_mesh.
~OutputMeshDiscontinuous()
std::shared_ptr< ElementDataCache< unsigned int > > make_serial_connectivity_cache(std::shared_ptr< ElementDataCache< unsigned int >> global_offsets) override
Implements OutputMeshBase::make_serial_connectivity_cache.
std::shared_ptr< ElementDataCache< double > > make_serial_nodes_cache(std::shared_ptr< ElementDataCache< unsigned int >> global_offsets) override
Implements OutputMeshBase::make_serial_nodes_cache.
std::shared_ptr< OutputMeshBase > construct_mesh() override
Implements OutputMeshBase::construct_mesh.
bool refinement_criterion()
void create_refined_sub_mesh() override
Implements OutputMeshBase::create_refined_sub_mesh.
static const IdxVector<(InDim >OutDim ? InDim+1 :dim-InDim) > interact(TInteraction< OutDim, InDim > interaction, bool inv=false)
Armor::ArmaVec< double, spacedim > Point
Support classes for parallel programing.
const unsigned int undef_idx
int LongIdx
Define type that represents indices of large arrays (elements, nodes, dofs etc.)
#define DebugOut()
Macro defining 'debug' record of log.
Class OutputElement and its iterator OutputElementIterator on the output mesh.
Classes for auxiliary output mesh.
Iter< OutputElement > OutputElementIterator
Implementation of range helper class.
Class RefElement defines numbering of vertices, sides, calculation of normal vectors etc.
Auxiliary structure defining element of refined output mesh.
std::vector< Space< spacedim >::Point > nodes