COOLFluiD  Release kernel
COOLFluiD is a Collaborative Simulation Environment (CSE) focused on complex MultiPhysics simulations.
Functions.cpp
Go to the documentation of this file.
1 // Copyright (C) 2010-2013 von Karman Institute for Fluid Dynamics, Belgium
2 //
3 // This software is distributed under the terms of the
4 // GNU Lesser General Public License version 3 (LGPLv3).
5 // See doc/lgpl.txt and doc/gpl.txt for the license text.
6 
8 #include "common/List.hpp"
9 
10 #include "mesh/Connectivity.hpp"
11 #include "mesh/Dictionary.hpp"
12 #include "mesh/Space.hpp"
13 #include "mesh/Entities.hpp"
14 
15 namespace cf3 {
16 namespace mesh {
17 
19 
20 using namespace common;
21 
23 
24 boost::shared_ptr< List< Uint > > build_used_nodes_list( const std::vector< Handle<Entities const> >& entities_vector, const Dictionary& dictionary, const bool include_ghost_elems, const bool follow_periodic_links)
25 {
26  boost::shared_ptr< List< Uint > > used_nodes = allocate_component< List< Uint > >(mesh::Tags::nodes_used());
27 
28  if(entities_vector.empty())
29  return used_nodes;
30 
31  const Uint all_nb_nodes = dictionary.size();
32 
33  std::vector<bool> node_is_used(all_nb_nodes, false);
34  const List<Uint>* periodic_links_nodes = dynamic_cast< const List<Uint>* >(dictionary.get_child("periodic_links_nodes").get());
35  const List<bool>* periodic_links_active = dynamic_cast< const List<bool>* >(dictionary.get_child("periodic_links_active").get());
36 
37  // First count the number of unique nodes
38  boost_foreach( const Handle<Space>& space, dictionary.spaces() )
39  {
40  boost_foreach( const Handle<Entities const>& entities, entities_vector )
41  {
42  if( &space->support() == entities.get() )
43  {
44  const Uint nb_elems = space->size();
45 
46  for (Uint idx=0; idx<nb_elems; ++idx)
47  {
48  // Don't include ghost-elements if not requested
49  if(include_ghost_elems || entities->is_ghost(idx) == false)
50  {
51  boost_foreach(const Uint node, space->connectivity()[idx])
52  {
53  cf3_assert(node<node_is_used.size());
54  if(!node_is_used[node])
55  {
56  node_is_used[node] = true;
57  }
58  }
59  }
60  }
61  }
62  }
63  }
64 
65  if(follow_periodic_links && periodic_links_active)
66  {
67  const List<Uint>& per_links = *periodic_links_nodes;
68  const List<bool>& per_active = *periodic_links_active;
69  // Any node connected periodically to a used node is also used
70  for(Uint i = 0; i != all_nb_nodes; ++i)
71  {
72  if(per_active[i] && (node_is_used[per_links[i]] || node_is_used[i]))
73  {
74  node_is_used[i] = true;
75  node_is_used[per_links[i]] = true;
76  }
77  }
78  }
79 
80  // reserve space for all unique nodes
81  const Uint nb_used_nodes = std::count(node_is_used.begin(), node_is_used.end(), true);
82  used_nodes->resize(nb_used_nodes);
83  common::List<Uint>::ListT& nodes_array = used_nodes->array();
84 
85 
86  // Add the unique node indices
87  Uint back = 0;
88  for(Uint i = 0; i != all_nb_nodes; ++i)
89  {
90  if(node_is_used[i])
91  {
92  cf3_assert(back < nb_used_nodes);
93  nodes_array[back++] = i;
94  }
95  }
96 
97  std::sort(used_nodes->array().begin(), used_nodes->array().end());
98  return used_nodes;
99 }
100 
102 
103 boost::shared_ptr< common::List< Uint > > build_used_nodes_list( const Component& node_user, const Dictionary& dictionary, const bool include_ghost_elems, const bool follow_periodic_links)
104 {
105  std::vector< Handle<Entities const> > entities_vector;
106  if (Handle<Entities const> entities_h = node_user.handle<Entities>())
107  entities_vector.push_back(entities_h);
108  else
109  entities_vector = range_to_const_vector( find_components_recursively<Entities>(node_user) );
110 
111  return build_used_nodes_list(entities_vector,dictionary,include_ghost_elems, follow_periodic_links);
112 }
113 
115 
116 void nearest_node_mapping(const RealMatrix& support_local_coords, const RealMatrix& source_local_coords, std::vector<Uint>& node_mapping, std::vector<bool>& is_interior)
117 {
118  const Real eps = 1e-8;
119  const Real min = support_local_coords.minCoeff();
120  const Real max = support_local_coords.maxCoeff();
121  const Real max_sum = min == -1. ? -2. : 1.-eps;
122 
123  const Eigen::Array<bool, Eigen::Dynamic, 1> is_interior_arr = ((source_local_coords.array() > min).rowwise().all() && (source_local_coords.array() < max).rowwise().all() && source_local_coords.array().rowwise().sum() < max_sum);
124 
125  const Uint nb_target_nodes = source_local_coords.rows();
126 
127  node_mapping.resize(nb_target_nodes);
128  is_interior.resize(nb_target_nodes);
129 
130  Eigen::Array<int, Eigen::Dynamic, 1> counts(support_local_coords.rows());
131  counts.setZero();
132 
133  for(Uint row_idx = 0; row_idx != nb_target_nodes; ++row_idx)
134  {
135  is_interior[row_idx] = is_interior_arr[row_idx];
136 
137  // Compute the distances between the target node and the support nodes
138  const Eigen::Array<Real, Eigen::Dynamic, 1> distances = (support_local_coords.rowwise() - source_local_coords.row(row_idx)).rowwise().squaredNorm();
139 
140  // Minimal distance
141  const Real min_dist = distances.minCoeff();
142 
143  // Index of the nearest node that has been selected the fewest times
144  int min_idx;
145  (distances.array() == min_dist).select(counts, nb_target_nodes).minCoeff(&min_idx);
146 
147  node_mapping[row_idx] = min_idx;
148  ++counts[min_idx];
149  }
150 }
151 
153 
154 } // mesh
155 } // cf3
boost::multi_array< ValueT, 1 > ListT
the type of the internal structure of the list
Definition: List.hpp:48
void nearest_node_mapping(const RealMatrix &support_local_coords, const RealMatrix &source_local_coords, std::vector< Uint > &node_mapping, std::vector< bool > &is_interior)
Definition: Functions.cpp:116
std::vector< Uint > used_nodes(const mesh::Region &region, const mesh::Dictionary &dict)
#define cf3_assert(a)
Definition: Assertions.hpp:93
#define boost_foreach
lowercase version of BOOST_FOREACH
Definition: Foreach.hpp:16
Real max(const Real a, const Real b)
Maximum between two scalars.
Definition: Terminals.hpp:228
Real e()
Definition of the Unit charge [C].
Definition: Consts.hpp:30
const std::vector< Handle< Space > > & spaces() const
Definition: Dictionary.cpp:360
Eigen::Matrix< Real, Eigen::Dynamic, Eigen::Dynamic > RealMatrix
Dynamic sized matrix of Real scalars.
Definition: MatrixTypes.hpp:22
Real min(const Real a, const Real b)
Minimum between two scalars.
Definition: Terminals.hpp:234
Handle< Component > get_child(const std::string &name)
Definition: Component.cpp:441
Top-level namespace for coolfluid.
Definition: Action.cpp:18
std::vector< Handle< const T > > range_to_const_vector(boost::iterator_range< ComponentIterator< T > > range)
unsigned int Uint
typedef for unsigned int
Definition: CF.hpp:90
boost::shared_ptr< List< Uint > > build_used_nodes_list(const std::vector< Handle< Entities const > > &entities_vector, const Dictionary &dictionary, const bool include_ghost_elems, const bool follow_periodic_links)
Create a List containing unique entries of all the nodes used by a vector of entities...
Definition: Functions.cpp:24
Handle< Component > handle()
Get a handle to the component.
Definition: Component.hpp:179
Base class for defining CF components.
Definition: Component.hpp:82
Uint size() const
Number of rows of contained fields.
Definition: Dictionary.cpp:99
Uint count(const RangeT &range)
Count the elements in a range.
T * get() const
Raw pointer to the stored value, or null if there is none.
Definition: Handle.hpp:65
Send comments to:
COOLFluiD Web Admin