Chi-Tech
chi_ffinter_point.cc
Go to the documentation of this file.
1#include "chi_ffinter_point.h"
2
6
7#include "chi_runtime.h"
8#include "chi_mpi.h"
9
10//###################################################################
11/**Initializes the point interpolator.*/
13{
14 const std::string fname = "FieldFunctionInterpolationPoint::Initialize";
15 const auto& grid =
16 field_functions_.front()->GetSpatialDiscretization().Grid();
17
18 std::vector<uint64_t> cells_potentially_owning_point;
19 for (const auto& cell : grid.local_cells)
20 {
21 const auto& vcc = cell.centroid_;
22 const auto& poi = point_of_interest_;
23 const auto nudged_point = poi + 1.0e-6*(vcc-poi);
24 if (grid.CheckPointInsideCell(cell, nudged_point))
25 cells_potentially_owning_point.push_back(cell.global_id_);
26 }
27
28 const int local_count = static_cast<int>(cells_potentially_owning_point.size());
29 std::vector<int> locI_count(Chi::mpi.process_count,0);
30 MPI_Allgather(&local_count, //sendbuf
31 1, MPI_INT, //sendcount + sendtype
32 locI_count.data(), //recvbuf + recvtype
33 1, MPI_INT, //recvcount + recvtype
34 Chi::mpi.comm); //communicator
35
36 std::vector<int> recvdispls(Chi::mpi.process_count,0);
37
38 int running_count = 0;
39 for (int locI=0; locI< Chi::mpi.process_count; ++locI)
40 {
41 recvdispls[locI] = running_count;
42 running_count += locI_count[locI];
43 }
44
45 const auto& sendbuf = cells_potentially_owning_point;
46 std::vector<uint64_t> recvbuf(running_count, 0);
47 MPI_Allgatherv(sendbuf.data(), //sendbuf
48 local_count, MPI_UINT64_T, //sendcount + sendtype
49 recvbuf.data(), //recvbuf
50 locI_count.data(), //recvcount
51 recvdispls.data(), //recvdispl
52 MPI_UINT64_T, //recvtype
53 Chi::mpi.comm); //communicator
54
55 if (recvbuf.empty())
56 throw std::logic_error(fname + ": No cell identified containing the point.");
57
58 uint64_t owning_cell_gid = recvbuf.front();
59 for (const uint64_t gid : recvbuf)
60 owning_cell_gid = std::min(owning_cell_gid, gid);
61
62 locally_owned_ = false;
63 for (const uint64_t gid : cells_potentially_owning_point)
64 if (gid == owning_cell_gid)
65 {
66 locally_owned_ = true;
67 owning_cell_gid_ = owning_cell_gid;
68 break;
69 }
70}
71
72//###################################################################
73/**Executes the point interpolator.*/
75{
76 if (not locally_owned_) return;
77
78 const auto& ref_ff = *field_functions_.front();
79 const auto& sdm = ref_ff.GetSpatialDiscretization();
80 const auto& grid = sdm.Grid();
81
82 const auto& uk_man = ref_ff.GetUnknownManager();
83 const auto uid = 0;
84 const auto cid = ref_component_;
85
86 using namespace chi_mesh::ff_interpolation;
87 const auto field_data = ref_ff.GetGhostedFieldVector();
88
89 const auto& cell = grid.cells[owning_cell_gid_];
90 const auto& cell_mapping = sdm.GetCellMapping(cell);
91 const size_t num_nodes = cell_mapping.NumNodes();
92
93 std::vector<double> node_dof_values(num_nodes, 0.0);
94 for (size_t i=0; i<num_nodes; ++i)
95 {
96 const int64_t imap = sdm.MapDOFLocal(cell,i,uk_man,uid,cid);
97 node_dof_values[i] = field_data[imap];
98 }//for i
99
100 std::vector<double> shape_values(num_nodes, 0.0);
101 cell_mapping.ShapeValues(point_of_interest_, shape_values);
102
103 point_value_ = 0.0;
104 for (size_t i=0; i<num_nodes; ++i)
105 point_value_ += node_dof_values[i] * shape_values[i];
106}
107
108//###################################################################
109/**Gets the value of the field function evaluation at the point.*/
111{
112 double global_point_value;
113 MPI_Allreduce(&point_value_, //sendbuf
114 &global_point_value, //recvbuf
115 1, MPI_DOUBLE, //count + datatype
116 MPI_SUM, //operation
117 Chi::mpi.comm); //communicator
118
119 return global_point_value;
120}
static chi::MPI_Info & mpi
Definition: chi_runtime.h:78
const MPI_Comm & comm
MPI communicator.
Definition: mpi_info.h:28
const int & process_count
Total number of processes.
Definition: mpi_info.h:27
std::vector< chi_physics::FieldFunctionGridBasedPtr > field_functions_