Chi-Tech
pi_keigen_scdsa_03b_nodal_avg_pwld.cc
Go to the documentation of this file.
1#include "pi_keigen_scdsa.h"
2
5
6#include "chi_log.h"
7
8namespace lbs
9{
10
11/**This method takes an input vector that is the local version of
12* a PWLD discrete space and then makes it continuous by applying nodal
13* averages.*/
15 const std::vector<double>& input,
16 const chi_math::SpatialDiscretization& pwld_sdm,
17 const chi_math::SpatialDiscretization& pwlc_sdm,
18 const chi_math::UnknownManager& uk_man,
20{
21 const auto& vgc = ghost_info.vector_ghost_communicator;
22 const auto& dfem_dof_global2local_map =
24
25 auto input_with_ghosts = vgc->MakeGhostedVector(input);
26 vgc->CommunicateGhostEntries(input_with_ghosts);
27
28 typedef const int64_t cint64_t;
29
30 const auto& grid = pwld_sdm.Grid();
31
32 const size_t num_unknowns = uk_man.unknowns_.size();
33
34 const size_t num_cfem_local_dofs = pwlc_sdm.GetNumLocalAndGhostDOFs(uk_man);
35
36 std::vector<double> cont_input(num_cfem_local_dofs, 0.0);
37 std::vector<double> cont_input_ctr(num_cfem_local_dofs, 0.0);
38
39 std::map<int64_t, int64_t> cfem_dof_global2local_map;
40
41 //================================================== Local cells first
42 std::set<uint64_t> partition_bndry_vertex_id_set;
43 for (const auto& cell : grid.local_cells)
44 {
45 const auto& cell_mapping = pwld_sdm.GetCellMapping(cell);
46 const size_t num_nodes = cell_mapping.NumNodes();
47
48 for (size_t i = 0; i < num_nodes; ++i)
49 {
50 for (size_t u = 0; u < num_unknowns; ++u)
51 {
52 const size_t num_components = uk_man.unknowns_[u].num_components_;
53 for (size_t c = 0; c < num_components; ++c)
54 {
55 cint64_t dof_dfem_map = pwld_sdm.MapDOFLocal(cell, i, uk_man, u, c);
56 cint64_t dof_cfem_map = pwlc_sdm.MapDOFLocal(cell, i, uk_man, u, c);
57 cint64_t dof_cfem_map_globl = pwlc_sdm.MapDOF(cell, i, uk_man, u, c);
58
59 cfem_dof_global2local_map[dof_cfem_map_globl] = dof_cfem_map;
60
61 const double phi_value = input[dof_dfem_map];
62
63 cont_input[dof_cfem_map] += phi_value;
64 cont_input_ctr[dof_cfem_map] += 1.0;
65 } // for component c
66 } // for unknown u
67 } // for node i
68
69 for (const auto& face : cell.faces_)
70 if (face.has_neighbor_)
71 if (not grid.IsCellLocal(face.neighbor_id_))
72 for (const uint64_t vid : face.vertex_ids_)
73 partition_bndry_vertex_id_set.insert(vid);
74 } // for local cell
75
76 //================================================== Ghost cells
77 const auto ghost_cell_ids = grid.cells.GetGhostGlobalIDs();
78 const auto& vid_set = partition_bndry_vertex_id_set;
79 for (const auto global_id : ghost_cell_ids)
80 {
81 const auto& cell = grid.cells[global_id];
82 const auto& cell_mapping = pwld_sdm.GetCellMapping(cell);
83 const size_t num_nodes = cell_mapping.NumNodes();
84
85 for (size_t i = 0; i < num_nodes; ++i)
86 {
87 if (vid_set.find(cell.vertex_ids_[i]) == vid_set.end()) continue;
88
89 for (size_t u = 0; u < num_unknowns; ++u)
90 {
91 const size_t num_components = uk_man.unknowns_[u].num_components_;
92 for (size_t c = 0; c < num_components; ++c)
93 {
94 cint64_t dof_dfem_map_globl = pwld_sdm.MapDOF(cell, i, uk_man, u, c);
95 cint64_t dof_cfem_map_globl = pwlc_sdm.MapDOF(cell, i, uk_man, u, c);
96 if (cfem_dof_global2local_map.count(dof_cfem_map_globl) > 0)
97 {
98 cint64_t dof_dfem_map =
99 dfem_dof_global2local_map.at(dof_dfem_map_globl);
100 cint64_t dof_cfem_map =
101 cfem_dof_global2local_map[dof_cfem_map_globl];
102
103 const double phi_value = input_with_ghosts[dof_dfem_map];
104
105 cont_input[dof_cfem_map] += phi_value;
106 cont_input_ctr[dof_cfem_map] += 1.0;
107 }
108 } // for component
109 } // for unknown
110 } // for node i
111 } // for ghost cell
112
113 //================================================== Compute nodal averages
114 {
115 const size_t num_vals = cont_input.size();
116 for (size_t k = 0; k < num_vals; ++k)
117 cont_input[k] /= cont_input_ctr[k];
118 }
119
120 //================================================== Project back to dfem
121 auto output = input;
122 for (const auto& cell : grid.local_cells)
123 {
124 const auto& cell_mapping = pwld_sdm.GetCellMapping(cell);
125 const size_t num_nodes = cell_mapping.NumNodes();
126
127 for (size_t i = 0; i < num_nodes; ++i)
128 {
129 for (size_t u = 0; u < num_unknowns; ++u)
130 {
131 const size_t num_components = uk_man.unknowns_[u].num_components_;
132 for (size_t c = 0; c < num_components; ++c)
133 {
134 cint64_t dof_dfem_map = pwld_sdm.MapDOFLocal(cell, i, uk_man, u, c);
135 cint64_t dof_cfem_map = pwlc_sdm.MapDOFLocal(cell, i, uk_man, u, c);
136
137 const double phi_value = cont_input[dof_cfem_map];
138
139 output[dof_dfem_map] = phi_value;
140 } // for component c
141 } // for unknown u
142 } // for node i
143 } // for local cell
144
145 return output;
146}
147
148} // namespace lbs
size_t NumNodes() const
Definition: CellMapping.cc:34
size_t GetNumLocalAndGhostDOFs(const UnknownManager &unknown_manager) const
const CellMapping & GetCellMapping(const chi_mesh::Cell &cell) const
const chi_mesh::MeshContinuum & Grid() const
virtual int64_t MapDOF(const chi_mesh::Cell &cell, unsigned int node, const UnknownManager &unknown_manager, unsigned int unknown_id, unsigned int component) const =0
virtual int64_t MapDOFLocal(const chi_mesh::Cell &cell, unsigned int node, const UnknownManager &unknown_manager, unsigned int unknown_id, unsigned int component) const =0
std::vector< Unknown > unknowns_
static std::vector< double > NodallyAveragedPWLDVector(const std::vector< double > &input, const chi_math::SpatialDiscretization &pwld_sdm, const chi_math::SpatialDiscretization &pwlc_sdm, const chi_math::UnknownManager &uk_man, const XXPowerIterationKEigenSCDSA::GhostInfo &ghost_info)
std::map< int64_t, int64_t > ghost_global_id_2_local_map