Chi-Tech
diffusion_mip_05_utils.cc
Go to the documentation of this file.
1#include "diffusion_mip.h"
2
4
6
7#include "mesh/chi_mesh.h"
8
9#define scdouble static_cast<double>
10
11//###################################################################
12/**Still searching for a reference for this.
13 *
14 * For Polygons:
15 * Defined from paper \n
16 * Turcksin B, Ragusa J, "Discontinuous diffusion synthetic acceleration
17 * for S_n transport on 2D arbitrary polygonal meshes", Journal of
18 * Computational Physics 274, pg 356-369, 2014.\n
19 * \n
20 * Nv = Number of vertices. If Nv <= 4 then the perimeter parameter
21 * should be replaced by edge length.*/
24 unsigned int f)
25{
26 const auto& cell_mapping = sdm_.GetCellMapping(cell);
27 double hp;
28
29 const size_t num_faces = cell.faces_.size();
30 const size_t num_vertices = cell.vertex_ids_.size();
31
32 const double volume = cell_mapping.CellVolume();
33 const double face_area = cell_mapping.FaceArea(f);
34
35 /**Lambda to compute surface area.*/
36 auto ComputeSurfaceArea = [&cell_mapping,&num_faces]()
37 {
38 double surface_area = 0.0;
39 for (size_t fr=0; fr<num_faces; ++fr)
40 surface_area += cell_mapping.FaceArea(fr);
41
42 return surface_area;
43 };
44
45 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% SLAB
46 if (cell.Type() == chi_mesh::CellType::SLAB)
47 hp = volume/2.0;
48 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% POLYGON
49 else if (cell.Type() == chi_mesh::CellType::POLYGON)
50 {
51 if (num_faces == 3)
52 hp = 2.0*volume/face_area;
53 else if (num_faces == 4)
54 hp = volume/face_area;
55 else //Nv > 4
56 {
57 const double surface_area = ComputeSurfaceArea();
58
59 if (num_faces % 2 == 0)
60 hp = 4.0*volume/surface_area;
61 else
62 {
63 hp = 2.0*volume/surface_area;
64 hp += sqrt(2.0 * volume /
65 (scdouble(num_faces) * sin(2.0 * M_PI / scdouble(num_faces))));
66 }
67 }
68 }
69 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% POLYHEDRON
70 else if (cell.Type() == chi_mesh::CellType::POLYHEDRON)
71 {
72 const double surface_area = ComputeSurfaceArea();
73
74 if (num_faces == 4) //Tet
75 hp = 3 * volume / surface_area;
76 else if (num_faces == 6 && num_vertices == 8) //Hex
77 hp = volume / surface_area;
78 else //Polyhedron
79 hp = 6 * volume / surface_area;
80 }//Polyhedron
81 else
82 throw std::logic_error(
83 "lbs::acceleration::DiffusionMIPSolver::HPerpendicular: "
84 "Unsupported cell type in call to HPerpendicular");
85
86 return hp;
87}
88
89//###################################################################
90/**Maps a face, in a discontinuous sense, using the spatial discretization.*/
92 MapFaceNodeDisc(const chi_mesh::Cell& cur_cell,
93 const chi_mesh::Cell& adj_cell,
94 const std::vector<chi_mesh::Vector3>& cc_node_locs,
95 const std::vector<chi_mesh::Vector3>& ac_node_locs,
96 size_t ccf, size_t acf,
97 size_t ccfi,
98 double epsilon/*=1.0e-12*/)
99{
100 const auto& cur_cell_mapping = sdm_.GetCellMapping(cur_cell);
101 const auto& adj_cell_mapping = sdm_.GetCellMapping(adj_cell);
102
103 const int i = cur_cell_mapping.MapFaceNode(ccf, ccfi);
104 const auto& node_i_loc = cc_node_locs[i];
105
106 const size_t adj_face_num_nodes = adj_cell_mapping.NumFaceNodes(acf);
107
108 for (size_t fj=0; fj<adj_face_num_nodes; ++fj)
109 {
110 const int j = adj_cell_mapping.MapFaceNode(acf,fj);
111 if ((node_i_loc - ac_node_locs[j]).NormSquare() < epsilon)
112 return j;
113 }
114
115 throw std::logic_error(
116 "lbs::acceleration::DiffusionMIPSolver::MapFaceNodeDisc: Mapping failure.");
117}
118
119//###################################################################
120/**Calls a lua function with xyz coordinates.
121 * \param L The lua state.
122 * \param lua_func_name The name used to define this lua function in the lua
123 * state.
124 * \param xyz The xyz coordinates of the point where the function is called.
125 *
126 * \return The function evaluation.*/
128 CallLuaXYZFunction(lua_State* L, const std::string& lua_func_name,
129 const chi_mesh::Vector3& xyz)
130{
131 const std::string fname = "lbs::acceleration::DiffusionMIPSolver::"
132 "CallLuaXYZFunction";
133 //============= Load lua function
134 lua_getglobal(L, lua_func_name.c_str());
135
136 //============= Error check lua function
137 if (not lua_isfunction(L, -1))
138 throw std::logic_error(fname + " attempted to access lua-function, " +
139 lua_func_name + ", but it seems the function"
140 " could not be retrieved.");
141
142 //============= Push arguments
143 lua_pushnumber(L, xyz.x);
144 lua_pushnumber(L, xyz.y);
145 lua_pushnumber(L, xyz.z);
146
147 //============= Call lua function
148 //3 arguments, 1 result (double), 0=original error object
149 double lua_return;
150 if (lua_pcall(L,3,1,0) == 0)
151 {
152 LuaCheckNumberValue(fname, L, -1);
153 lua_return = lua_tonumber(L,-1);
154 }
155 else
156 throw std::logic_error(fname + " attempted to call lua-function, " +
157 lua_func_name + ", but the call failed." +
158 xyz.PrintStr());
159
160 lua_pop(L,1); //pop the double, or error code
161
162 return lua_return;
163}
const CellMapping & GetCellMapping(const chi_mesh::Cell &cell) const
std::vector< CellFace > faces_
Definition: cell.h:82
CellType Type() const
Definition: cell.h:98
std::vector< uint64_t > vertex_ids_
Definition: cell.h:81
int MapFaceNodeDisc(const chi_mesh::Cell &cur_cell, const chi_mesh::Cell &adj_cell, const std::vector< chi_mesh::Vector3 > &cc_node_locs, const std::vector< chi_mesh::Vector3 > &ac_node_locs, size_t ccf, size_t acf, size_t ccfi, double epsilon=1.0e-12)
double HPerpendicular(const chi_mesh::Cell &cell, unsigned int f)
static double CallLuaXYZFunction(lua_State *L, const std::string &lua_func_name, const chi_mesh::Vector3 &xyz)
const chi_math::SpatialDiscretization & sdm_
Definition: diffusion.h:39
#define scdouble
std::string PrintStr() const
double x
Element-0.
double y
Element-1.
double z
Element-2.