Chi-Tech
dfem_diffusion_utils.cc
Go to the documentation of this file.
2#include "chi_lua.h"
4
6
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.*/
23 unsigned int f)
24{
25 const auto& sdm = *sdm_ptr_;
26
27 const auto& cell_mapping = sdm.GetCellMapping(cell);
28 double hp;
29
30 const size_t num_faces = cell.faces_.size();
31 const size_t num_vertices = cell.vertex_ids_.size();
32
33 const double volume = cell_mapping.CellVolume();
34 const double face_area = cell_mapping.FaceArea(f);
35
36 /**Lambda to compute surface area.*/
37 auto ComputeSurfaceArea = [&cell_mapping,&num_faces]()
38 {
39 double surface_area = 0.0;
40 for (size_t fr=0; fr<num_faces; ++fr)
41 surface_area += cell_mapping.FaceArea(fr);
42
43 return surface_area;
44 };
45
46 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% SLAB
47 if (cell.Type() == chi_mesh::CellType::SLAB)
48 hp = volume/2.0;
49 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% POLYGON
50 else if (cell.Type() == chi_mesh::CellType::POLYGON)
51 {
52 if (num_faces == 3)
53 hp = 2.0*volume/face_area;
54 else if (num_faces == 4)
55 hp = volume/face_area;
56 else //Nv > 4
57 {
58 const double surface_area = ComputeSurfaceArea();
59
60 if (num_faces % 2 == 0)
61 hp = 4.0*volume/surface_area;
62 else
63 {
64 hp = 2.0*volume/surface_area;
65 hp += sqrt(2.0 * volume /
66 (scdouble(num_faces) * sin(2.0 * M_PI / scdouble(num_faces))));
67 }
68 }
69 }
70 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% POLYHEDRON
71 else if (cell.Type() == chi_mesh::CellType::POLYHEDRON)
72 {
73 const double surface_area = ComputeSurfaceArea();
74
75 if (num_faces == 4) //Tet
76 hp = 3 * volume / surface_area;
77 else if (num_faces == 6 && num_vertices == 8) //Hex
78 hp = volume / surface_area;
79 else //Polyhedron
80 hp = 6 * volume / surface_area;
81 }//Polyhedron
82 else
83 throw std::logic_error(
84 "dfem_diffusion::Solver::HPerpendicular: "
85 "Unsupported cell type in call to HPerpendicular");
86
87 return hp;
88}
89
90//###################################################################
91/**Maps a face, in a discontinuous sense, using the spatial discretization.*/
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& sdm = *sdm_ptr_;
101
102 const auto& cur_cell_mapping = sdm.GetCellMapping(cur_cell);
103 const auto& adj_cell_mapping = sdm.GetCellMapping(adj_cell);
104
105 const int i = cur_cell_mapping.MapFaceNode(ccf, ccfi);
106 const auto& node_i_loc = cc_node_locs[i];
107
108 const size_t adj_face_num_nodes = adj_cell_mapping.NumFaceNodes(acf);
109
110 for (size_t fj=0; fj<adj_face_num_nodes; ++fj)
111 {
112 const int j = adj_cell_mapping.MapFaceNode(acf,fj);
113 if ((node_i_loc - ac_node_locs[j]).NormSquare() < epsilon)
114 return j;
115 }
116
117 throw std::logic_error(
118 "dfem_diffusion::Solver::MapFaceNodeDisc: Mapping failure.");
119}
120
121//###################################################################
122/**Calls a lua function with xyz coordinates.
123 * \param L The lua state.
124 * \param lua_func_name The name used to define this lua function in the lua
125 * state.
126 * \param imat The material ID of the cell
127 * \param xyz The xyz coordinates of the point where the function is called.
128 *
129 * \return The function evaluation.*/
131 lua_State* L,
132 const std::string& lua_func_name,
133 const int imat,
134 const chi_mesh::Vector3& xyz)
135{
136 //============= Load lua function
137 lua_getglobal(L, lua_func_name.c_str());
138
139 //============= Error check lua function
140 if (not lua_isfunction(L, -1))
141 throw std::logic_error("CallLua_iXYZFunction attempted to access lua-function, " +
142 lua_func_name + ", but it seems the function"
143 " could not be retrieved.");
144
145 //============= Push arguments
146 lua_pushinteger(L, imat);
147 lua_pushnumber(L, xyz.x);
148 lua_pushnumber(L, xyz.y);
149 lua_pushnumber(L, xyz.z);
150
151 //============= Call lua function
152 //4 arguments, 1 result (double), 0=original error object
153 double lua_return;
154 if (lua_pcall(L,4,1,0) == 0)
155 {
156 LuaCheckNumberValue("CallLua_iXYZFunction", L, -1);
157 lua_return = lua_tonumber(L,-1);
158 }
159 else
160 throw std::logic_error("dfem_diffusion::CallLua_iXYZFunction attempted to call lua-function, " +
161 lua_func_name + ", but the call failed." +
162 xyz.PrintStr());
163
164 lua_pop(L,1); //pop the double, or error code
165
166 return lua_return;
167}
168
169//###################################################################
170/**Updates the field functions with the latest data.*/
172{
173 auto& ff = *field_functions_.front();
174 ff.UpdateFieldVector(x_);
175}
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)
static double CallLua_iXYZFunction(lua_State *L, const std::string &, int, const chi_mesh::Vector3 &)
double HPerpendicular(const chi_mesh::Cell &cell, unsigned int f)
#define scdouble
std::string PrintStr() const
double x
Element-0.
double y
Element-1.
double z
Element-2.