libMesh
Classes | Public Types | Public Member Functions | Public Attributes | Private Attributes | List of all members
libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction > Class Template Reference

The GenericProjector class implements the core of other projection operations, using two input functors to read values to be projected and an output functor to set degrees of freedom in the result. More...

#include <generic_projector.h>

Classes

struct  ProjectEdges
 
struct  ProjectInteriors
 
struct  ProjectSides
 
struct  ProjectVertices
 
struct  SortAndCopy
 
struct  SubFunctor
 
struct  SubProjector
 

Public Types

typedef std::set< unsigned intvar_set
 
typedef std::pair< const Node *, std::tuple< const Elem *, unsigned short, var_set > > node_projection
 
typedef StoredRange< std::vector< node_projection >::const_iterator, node_projectionnode_range
 
typedef StoredRange< std::vector< const Elem * >::const_iterator, const Elem * > interior_range
 

Public Member Functions

 GenericProjector (const System &system_in, FFunctor &f_in, GFunctor *g_in, ProjectionAction &act_in, const std::vector< unsigned int > &variables_in, std::unordered_map< dof_id_type, std::vector< dof_id_type >> *nodes_to_elem_in=nullptr)
 
 GenericProjector (const GenericProjector &in)
 
 ~GenericProjector ()
 
void project (const ConstElemRange &range)
 Function definitions. More...
 
template<typename Value >
void send_and_insert_dof_values (std::unordered_map< dof_id_type, std::pair< Value, processor_id_type >> &ids_to_push, ProjectionAction &action) const
 

Public Attributes

std::unordered_map< dof_id_type, typename FFunctor::ValuePushType > ids_to_save
 

Private Attributes

const Systemsystem
 
FFunctor & master_f
 
GFunctor * master_g
 
bool g_was_copied
 
bool map_was_created
 
ProjectionAction & master_action
 
const std::vector< unsigned int > & variables
 
std::unordered_map< dof_id_type, std::vector< dof_id_type > > * nodes_to_elem
 
bool done_saving_ids
 

Detailed Description

template<typename FFunctor, typename GFunctor, typename FValue, typename ProjectionAction>
class libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >

The GenericProjector class implements the core of other projection operations, using two input functors to read values to be projected and an output functor to set degrees of freedom in the result.

This may be executed in parallel on multiple threads.

Author
Roy H. Stogner
Date
2016

Definition at line 83 of file generic_projector.h.

Member Typedef Documentation

◆ interior_range

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
typedef StoredRange<std::vector<const Elem *>::const_iterator, const Elem *> libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::interior_range

Definition at line 354 of file generic_projector.h.

◆ node_projection

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
typedef std::pair<const Node *, std::tuple<const Elem *, unsigned short, var_set> > libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::node_projection

Definition at line 234 of file generic_projector.h.

◆ node_range

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
typedef StoredRange<std::vector<node_projection>::const_iterator, node_projection> libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::node_range

Definition at line 237 of file generic_projector.h.

◆ var_set

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
typedef std::set<unsigned int> libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::var_set

Definition at line 152 of file generic_projector.h.

Constructor & Destructor Documentation

◆ GenericProjector() [1/2]

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::GenericProjector ( const System system_in,
FFunctor &  f_in,
GFunctor *  g_in,
ProjectionAction &  act_in,
const std::vector< unsigned int > &  variables_in,
std::unordered_map< dof_id_type, std::vector< dof_id_type >> *  nodes_to_elem_in = nullptr 
)
inline

Definition at line 99 of file generic_projector.h.

References libMesh::MeshTools::build_nodes_to_elem_map(), libMesh::System::get_mesh(), libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::map_was_created, libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::nodes_to_elem, and libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::system.

105  :
106  system(system_in),
107  master_f(f_in),
108  master_g(g_in),
109  g_was_copied(false),
110  map_was_created(!nodes_to_elem_in),
111  master_action(act_in),
112  variables(variables_in),
113  nodes_to_elem(nodes_to_elem_in)
114  {
115  if (map_was_created) // past tense misnomer here
116  {
117  nodes_to_elem = new
118  std::unordered_map<dof_id_type, std::vector<dof_id_type>>;
120  }
121  }
ProjectionAction & master_action
void build_nodes_to_elem_map(const MeshBase &mesh, std::vector< std::vector< dof_id_type >> &nodes_to_elem_map)
After calling this function the input vector nodes_to_elem_map will contain the node to element conne...
Definition: mesh_tools.C:448
const MeshBase & get_mesh() const
Definition: system.h:2277
const std::vector< unsigned int > & variables
std::unordered_map< dof_id_type, std::vector< dof_id_type > > * nodes_to_elem

◆ GenericProjector() [2/2]

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::GenericProjector ( const GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction > &  in)
inline

Definition at line 123 of file generic_projector.h.

123  :
124  system(in.system),
125  master_f(in.master_f),
126  master_g(in.master_g ? new GFunctor(*in.master_g) : nullptr),
127  g_was_copied(in.master_g),
128  master_action(in.master_action),
129  variables(in.variables),
130  nodes_to_elem(in.nodes_to_elem)
131  {}
ProjectionAction & master_action
const std::vector< unsigned int > & variables
std::unordered_map< dof_id_type, std::vector< dof_id_type > > * nodes_to_elem

◆ ~GenericProjector()

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::~GenericProjector ( )
inline

Member Function Documentation

◆ project()

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
void libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::project ( const ConstElemRange range)

Function definitions.

Definition at line 1201 of file generic_projector.h.

References libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SortAndCopy::edges, libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SortAndCopy::interiors, libMesh::libmesh_merge_move(), libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::new_ids_to_push, libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::new_ids_to_save, libMesh::Threads::parallel_reduce(), libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SortAndCopy::sides, and libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SortAndCopy::vertices.

1202 {
1203  LOG_SCOPE ("project", "GenericProjector");
1204 
1205  // Unless we split sort and copy into two passes we can't know for
1206  // sure ahead of time whether we need to save the copied ids
1207  done_saving_ids = false;
1208 
1209  SortAndCopy sort_work(*this);
1210  Threads::parallel_reduce (range, sort_work);
1211  ProjectionAction action(master_action);
1212 
1213  // Keep track of dof ids and values to send to other ranks
1214  std::unordered_map<dof_id_type, std::pair<typename FFunctor::ValuePushType, processor_id_type>>
1215  ids_to_push;
1216 
1217  ids_to_push.insert(sort_work.new_ids_to_push.begin(),
1218  sort_work.new_ids_to_push.end());
1219  ids_to_save.insert(sort_work.new_ids_to_save.begin(),
1220  sort_work.new_ids_to_save.end());
1221 
1222  std::vector<node_projection> vertices(sort_work.vertices.begin(),
1223  sort_work.vertices.end());
1224 
1225  done_saving_ids = sort_work.edges.empty() &&
1226  sort_work.sides.empty() && sort_work.interiors.empty();
1227 
1228  {
1229  ProjectVertices project_vertices(*this);
1230  Threads::parallel_reduce (node_range(&vertices), project_vertices);
1231  libmesh_merge_move(ids_to_push, project_vertices.new_ids_to_push);
1232  libmesh_merge_move(ids_to_save, project_vertices.new_ids_to_save);
1233  }
1234 
1235  done_saving_ids = sort_work.sides.empty() && sort_work.interiors.empty();
1236 
1237  this->send_and_insert_dof_values(ids_to_push, action);
1238 
1239  {
1240  std::vector<node_projection> edges(sort_work.edges.begin(), sort_work.edges.end());
1241  ProjectEdges project_edges(*this);
1242  Threads::parallel_reduce (node_range(&edges), project_edges);
1243  libmesh_merge_move(ids_to_push, project_edges.new_ids_to_push);
1244  libmesh_merge_move(ids_to_save, project_edges.new_ids_to_save);
1245  }
1246 
1247  done_saving_ids = sort_work.interiors.empty();
1248 
1249  this->send_and_insert_dof_values(ids_to_push, action);
1250 
1251  {
1252  std::vector<node_projection> sides(sort_work.sides.begin(), sort_work.sides.end());
1253  ProjectSides project_sides(*this);
1254  Threads::parallel_reduce (node_range(&sides), project_sides);
1255  libmesh_merge_move(ids_to_push, project_sides.new_ids_to_push);
1256  libmesh_merge_move(ids_to_save, project_sides.new_ids_to_save);
1257  }
1258 
1259  done_saving_ids = true;
1260  this->send_and_insert_dof_values(ids_to_push, action);
1261 
1262  // No ids to save or push this time, but we still use a reduce since
1263  // nominally ProjectInteriors still has non-const operator()
1264  ProjectInteriors project_interiors(*this);
1265  Threads::parallel_reduce (interior_range(&sort_work.interiors),
1266  project_interiors);
1267 }
void send_and_insert_dof_values(std::unordered_map< dof_id_type, std::pair< Value, processor_id_type >> &ids_to_push, ProjectionAction &action) const
void libmesh_merge_move(T &target, T &source)
ProjectionAction & master_action
std::unordered_map< dof_id_type, typename FFunctor::ValuePushType > ids_to_save
StoredRange< std::vector< node_projection >::const_iterator, node_projection > node_range
void parallel_reduce(const Range &range, Body &body)
Execute the provided reduction operation in parallel on the specified range.
Definition: threads_none.h:101
StoredRange< std::vector< const Elem * >::const_iterator, const Elem * > interior_range

◆ send_and_insert_dof_values()

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
template<typename Value >
void libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::send_and_insert_dof_values ( std::unordered_map< dof_id_type, std::pair< Value, processor_id_type >> &  ids_to_push,
ProjectionAction &  action 
) const

Definition at line 2890 of file generic_projector.h.

References libMesh::ParallelObject::comm(), libMesh::convert_from_receive(), libMesh::convert_to_send(), libMesh::DofObject::invalid_processor_id, libMesh::libmesh_assert(), and libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::system.

2892 {
2893  LOG_SCOPE ("send_and_insert_dof_values", "GenericProjector");
2894 
2895  // See if we calculated any ids that need to be pushed; get them
2896  // ready to push.
2897  std::unordered_map<processor_id_type, std::vector<dof_id_type>>
2898  pushed_dof_ids, received_dof_ids;
2899  std::unordered_map<processor_id_type, std::vector<typename TypeToSend<Value>::type>>
2900  pushed_dof_values, received_dof_values;
2901  for (auto & id_val_pid : ids_to_push)
2902  {
2903  processor_id_type pid = id_val_pid.second.second;
2905  {
2906  pushed_dof_ids[pid].push_back(id_val_pid.first);
2907  pushed_dof_values[pid].push_back(convert_to_send(id_val_pid.second.first));
2908  }
2909  }
2910 
2911  // If and when we get ids pushed to us, act on them if we have
2912  // corresponding values or save them if not
2913  auto ids_action_functor =
2914  [&action, &received_dof_ids, &received_dof_values]
2915  (processor_id_type pid,
2916  const std::vector<dof_id_type> & data)
2917  {
2918  auto iter = received_dof_values.find(pid);
2919  if (iter == received_dof_values.end())
2920  {
2921  libmesh_assert(received_dof_ids.find(pid) ==
2922  received_dof_ids.end());
2923  received_dof_ids[pid] = data;
2924  }
2925  else
2926  {
2927  auto & vals = iter->second;
2928  std::size_t vals_size = vals.size();
2929  libmesh_assert_equal_to(vals_size, data.size());
2930  for (std::size_t i=0; i != vals_size; ++i)
2931  {
2932  Value val;
2933  convert_from_receive(vals[i], val);
2934  action.insert(data[i], val);
2935  }
2936  received_dof_values.erase(iter);
2937  }
2938  };
2939 
2940  // If and when we get values pushed to us, act on them if we have
2941  // corresponding ids or save them if not
2942  auto values_action_functor =
2943  [&action, &received_dof_ids, &received_dof_values]
2944  (processor_id_type pid,
2945  const std::vector<typename TypeToSend<Value>::type> & data)
2946  {
2947  auto iter = received_dof_ids.find(pid);
2948  if (iter == received_dof_ids.end())
2949  {
2950  // We get no more than 1 values vector from anywhere
2951  libmesh_assert(received_dof_values.find(pid) ==
2952  received_dof_values.end());
2953  received_dof_values[pid] = data;
2954  }
2955  else
2956  {
2957  auto & ids = iter->second;
2958  std::size_t ids_size = ids.size();
2959  libmesh_assert_equal_to(ids_size, data.size());
2960  for (std::size_t i=0; i != ids_size; ++i)
2961  {
2962  Value val;
2963  convert_from_receive(data[i], val);
2964  action.insert(ids[i], val);
2965  }
2966  received_dof_ids.erase(iter);
2967  }
2968  };
2969 
2970  Parallel::push_parallel_vector_data
2971  (system.comm(), pushed_dof_ids, ids_action_functor);
2972 
2973  Parallel::push_parallel_vector_data
2974  (system.comm(), pushed_dof_values, values_action_functor);
2975 
2976  // At this point we shouldn't have any unprocessed data left
2977  libmesh_assert(received_dof_ids.empty());
2978  libmesh_assert(received_dof_values.empty());
2979 
2980 }
const Parallel::Communicator & comm() const
uint8_t processor_id_type
static const processor_id_type invalid_processor_id
An invalid processor_id to distinguish DoFs that have not been assigned to a processor.
Definition: dof_object.h:488
libmesh_assert(ctx)
void convert_from_receive(SendT &received, T &converted)
const TypeToSend< T >::type convert_to_send(const T &in)

Member Data Documentation

◆ done_saving_ids

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
bool libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::done_saving_ids
private

Definition at line 96 of file generic_projector.h.

◆ g_was_copied

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
bool libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::g_was_copied
private

◆ ids_to_save

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
std::unordered_map<dof_id_type, typename FFunctor::ValuePushType> libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::ids_to_save

◆ map_was_created

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
bool libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::map_was_created
private

◆ master_action

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
ProjectionAction& libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::master_action
private

Definition at line 93 of file generic_projector.h.

◆ master_f

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
FFunctor& libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::master_f
private

Definition at line 90 of file generic_projector.h.

◆ master_g

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
GFunctor* libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::master_g
private

◆ nodes_to_elem

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
std::unordered_map<dof_id_type, std::vector<dof_id_type> >* libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::nodes_to_elem
private

◆ system

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
const System& libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::system
private

◆ variables

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
const std::vector<unsigned int>& libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::variables
private

Definition at line 94 of file generic_projector.h.


The documentation for this class was generated from the following file: