Chi-Tech
raytracer.cc
Go to the documentation of this file.
1#include "raytracing.h"
2
4
5#include "chi_log.h"
6
8{
9 return reference_grid_;
10}
11
12//###################################################################
14 TraceRay(const Cell &cell,
15 Vector3 &pos_i,
16 Vector3 &omega_i,
17 int function_depth/*=0*/)
18{
19 if (not cell_sizes_.empty())
20 SetTolerancesFromCellSize(cell_sizes_[cell.local_id_]);
21
23
24 bool intersection_found = false;
25 bool backward_tolerance_hit = false;
26
27 if (cell.Type() == chi_mesh::CellType::SLAB)
28 TraceSlab(cell, pos_i, omega_i,
29 intersection_found /*byRef*/,
30 backward_tolerance_hit/*byRef*/,
31 oi /*byRef*/);
32 else if (cell.Type() == chi_mesh::CellType::POLYGON)
33 TracePolygon(cell, pos_i, omega_i,
34 intersection_found /*byRef*/,
35 backward_tolerance_hit/*byRef*/,
36 oi /*byRef*/);
37 else if (cell.Type() == chi_mesh::CellType::POLYHEDRON)
38 TracePolyhedron(cell, pos_i, omega_i,
39 intersection_found /*byRef*/,
40 backward_tolerance_hit/*byRef*/,
41 oi /*byRef*/);
42 else
43 throw std::logic_error("Unsupported cell type encountered in call to "
44 "chi_mesh::RayTrace.");
45
46 if (!intersection_found)
47 {
48 if (function_depth < 5)
49 {
50 // Nudge particle towards centroid
51 chi_mesh::Vector3 v_p_i_cc = (cell.centroid_ - pos_i);
52 chi_mesh::Vector3 pos_i_nudged = pos_i + v_p_i_cc * epsilon_nudge_;
53
54 oi = TraceRay(cell,pos_i_nudged,omega_i,function_depth+1);
55
56 return oi;
57 }
58
59 if (function_depth < 7)
60 {
61 // Nudge particle away from line between location and cell center
62 chi_mesh::Vector3 v_p_i_cc = (cell.centroid_ - pos_i).Cross(omega_i);
63 chi_mesh::Vector3 pos_i_nudged = pos_i + v_p_i_cc * epsilon_nudge_;
64
65 oi = TraceRay(cell,pos_i_nudged,omega_i,function_depth+1);
66
67 return oi;
68 }
69
70
71 std::stringstream outstr;
72
73 outstr
74 << "Intersection not found at function level " << function_depth << "."
75 << ((backward_tolerance_hit)? " Backward tolerance hit. " : "")
76 << "For particle xyz="
77 << pos_i.PrintS() << " uvw="
78 << omega_i.PrintS() << " " << (pos_i + extension_distance_ * omega_i).PrintS()
79 << " " << extension_distance_
80 << " in cell " << cell.global_id_
81 << " with vertices: \n";
82
83 const auto& grid = Grid();
84
85 for (auto vi : cell.vertex_ids_)
86 outstr << grid.vertices[vi].PrintS() << "\n";
87
88 for (auto& face : cell.faces_)
89 {
90 outstr << "Face with centroid: " << face.centroid_.PrintS() << " ";
91 outstr << "n=" << face.normal_.PrintS() << "\n";
92 for (auto vi : face.vertex_ids_)
93 outstr << grid.vertices[vi].PrintS() << "\n";
94 }
95
96 outstr << "o Cell\n";
97 for (auto& vid : cell.vertex_ids_)
98 {
99 auto& v = grid.vertices[vid];
100 outstr << "v " << v.x << " " << v.y << " " << v.z << "\n";
101 }
102
103 for (auto& face : cell.faces_)
104 {
105 auto& v = face.centroid_;
106 outstr << "v " << v.x << " " << v.y << " " << v.z << "\n";
107 }
108
109 for (size_t f=0; f < cell.faces_.size(); ++f)
110 {
111 auto& face = cell.faces_[f];
112 outstr << "f ";
113 for (auto vid : face.vertex_ids_)
114 {
115 size_t ref_cell_id=0;
116 for (size_t cid=0; cid < cell.vertex_ids_.size(); ++cid)
117 if (cell.vertex_ids_[cid] == vid)
118 ref_cell_id = cid + 1;
119
120 outstr << ref_cell_id << "// ";
121 }
122 outstr << "\n";
123 }
124
125 oi.particle_lost = true;
126 oi.lost_particle_info = outstr.str();
127 }
128
129 return oi;
130}
131
132
133//###################################################################
135TraceIncidentRay(const Cell& cell,
136 const Vector3& pos_i,
137 const Vector3& omega_i)
138{
139 const auto cell_type = cell.Type();
140 const double cell_char_length = cell_sizes_[cell.local_id_];
141 const auto& grid = reference_grid_;
142
143 bool intersects_cell = false;
145
146 size_t f = 0;
147 for (const auto& face : cell.faces_)
148 {
149 if (face.normal_.Dot(omega_i) > 0.0) { ++f; continue/*the loop*/; }
150
151 const auto& p0 = grid.vertices[face.vertex_ids_[0]];
152 const auto& n = face.normal_;
153
154 const auto ppos_i = p0 - pos_i;
155 const double d = ppos_i.Dot(omega_i);
156
157 const auto pos_ext = pos_i + (d + cell_char_length)*omega_i;
158
159 using namespace chi_mesh;
160 {
161 if (cell_type == CellType::SLAB)
162 {
163 intersects_cell = CheckPlaneLineIntersect(n, p0, pos_i, pos_ext, I);
164 }//SLAB
165 else if (cell_type == CellType::POLYGON)
166 {
167 const auto& p1 = grid.vertices[face.vertex_ids_[1]];
168 intersects_cell = CheckLineIntersectStrip(p0, p1, n, pos_i, pos_ext, I);
169 }//POLYGON
170 else if (cell_type == CellType::POLYHEDRON)
171 {
172 const auto& vids = face.vertex_ids_;
173 const size_t num_sides = face.vertex_ids_.size();
174 for (size_t s=0; s<num_sides; ++s)
175 {
176 uint64_t v0i = vids[s];
177 uint64_t v1i = (s < (num_sides-1))? vids[s+1] : vids[0];
178
179 const auto& v0 = grid.vertices[v0i];
180 const auto& v1 = grid.vertices[v1i];
181 const auto& v2 = face.centroid_;
182
183
184 const auto v01 = v1 - v0;
185 const auto v02 = v2 - v0;
186 const auto n_est = v01.Cross(v02);
187
188 if (n_est.Dot(omega_i) > 0.0) continue;
189
190 intersects_cell = CheckLineIntersectTriangle2(v0, v1, v2,
191 pos_i, omega_i, I);
192 if (intersects_cell) break;
193 }//for side
194 }//POLYHEDRON
195 }
196 if (intersects_cell) break;
197 ++f;
198 }//for face
199
201 if (intersects_cell)
202 {
203 oi.distance_to_surface = (I - pos_i).Norm();
204 oi.pos_f = I;
207 oi.particle_lost = false;
208 }
209 else
210 oi.particle_lost = true;
211
212 return oi;
213}
std::vector< CellFace > faces_
Definition: cell.h:82
CellType Type() const
Definition: cell.h:98
uint64_t local_id_
Definition: cell.h:76
uint64_t global_id_
Definition: cell.h:75
Vertex centroid_
Definition: cell.h:78
std::vector< uint64_t > vertex_ids_
Definition: cell.h:81
const chi_mesh::MeshContinuum & reference_grid_
Definition: raytracing.h:24
RayTracerOutputInformation TraceRay(const Cell &cell, Vector3 &pos_i, Vector3 &omega_i, int function_depth=0)
Definition: raytracer.cc:14
RayTracerOutputInformation TraceIncidentRay(const Cell &cell, const Vector3 &pos_i, const Vector3 &omega_i)
Definition: raytracer.cc:135
const chi_mesh::MeshContinuum & Grid() const
Definition: raytracer.cc:7
bool CheckLineIntersectTriangle2(const chi_mesh::Vector3 &tri_point0, const chi_mesh::Vector3 &tri_point1, const chi_mesh::Vector3 &tri_point2, const chi_mesh::Vector3 &ray_posi, const chi_mesh::Vector3 &ray_dir, chi_mesh::Vector3 &intersection_point, double *distance_to_intersection=nullptr)
bool CheckPlaneLineIntersect(const chi_mesh::Normal &plane_normal, const chi_mesh::Vector3 &plane_point, const chi_mesh::Vector3 &line_point_0, const chi_mesh::Vector3 &line_point_1, chi_mesh::Vector3 &intersection_point, std::pair< double, double > *weights=nullptr)
bool CheckLineIntersectStrip(const chi_mesh::Vector3 &strip_point0, const chi_mesh::Vector3 &strip_point1, const chi_mesh::Vector3 &strip_normal, const chi_mesh::Vector3 &line_point0, const chi_mesh::Vector3 &line_point1, chi_mesh::Vector3 &intersection_point, double *distance_to_intersection=nullptr)
std::string PrintS() const
Vector3 Dot(const chi_mesh::TensorRank2Dim3 &that) const