ViennaSHE 1.3.0
Free open-source semiconductor device simulator using spherical harmonics expansions techniques.
dual_box_flux.hpp
Go to the documentation of this file.
1#ifndef VIENNASHE_UTIL_TRANSLATE_QUANTITY_HPP
2#define VIENNASHE_UTIL_TRANSLATE_QUANTITY_HPP
3
4/* ============================================================================
5 Copyright (c) 2011-2022, Institute for Microelectronics,
6 Institute for Analysis and Scientific Computing,
7 TU Wien.
8
9 -----------------
10 ViennaSHE - The Vienna Spherical Harmonics Expansion Boltzmann Solver
11 -----------------
12
13 http://viennashe.sourceforge.net/
14
15 License: MIT (X11), see file LICENSE in the base directory
16=============================================================================== */
17
22// viennagrid
23#include "viennagrid/forwards.hpp"
24#include "viennagrid/mesh/mesh.hpp"
25#include "viennagrid/algorithm/volume.hpp"
26#include "viennagrid/algorithm/inner_prod.hpp"
27#include "viennagrid/algorithm/centroid.hpp"
28
29// viennashe
30#include "viennashe/forwards.h"
34
35#include "viennashe/log/log.hpp"
36
38
40
41namespace viennashe
42{
43 namespace util
44 {
45 namespace detail
46 {
47 // 1d case:
48 template <typename WrappedConfigT>
49 typename viennagrid::result_of::point< viennagrid::element<viennagrid::line_tag,WrappedConfigT> >::type
50 outer_cell_normal_at_facet(viennagrid::element<viennagrid::line_tag, WrappedConfigT> const & cell,
51 viennagrid::element<viennagrid::vertex_tag, WrappedConfigT> const & facet)
52 {
53 typedef typename viennagrid::result_of::point< viennagrid::element<viennagrid::line_tag,WrappedConfigT> >::type PointType;
54
55 PointType centroid_cell = viennagrid::centroid(cell);
56 PointType centroid_facet = viennagrid::centroid(facet);
57
58 if (centroid_cell[0] < centroid_facet[0])
59 return PointType(1.0);
60 return PointType(-1.0);
61 }
62
63 // 2d, triangles and quadrilaterals:
64 template <typename CellTagT, typename WrappedConfigT>
65 typename viennagrid::result_of::point< viennagrid::element<CellTagT, WrappedConfigT> >::type
66 outer_cell_normal_at_facet(viennagrid::element<CellTagT, WrappedConfigT> const & cell,
67 viennagrid::element<viennagrid::line_tag, WrappedConfigT> const & facet)
68 {
69 typedef viennagrid::element<viennagrid::line_tag, WrappedConfigT> FacetType;
70 typedef typename viennagrid::result_of::point<FacetType>::type PointType;
71 typedef typename viennagrid::result_of::const_vertex_range<FacetType>::type VertexRange;
72
73 VertexRange facet_vertices(facet);
74 PointType facet_vec = viennagrid::point(facet_vertices[1]) - viennagrid::point(facet_vertices[0]);
75 PointType facet_centroid_vec = viennagrid::centroid(cell) - viennagrid::point(facet_vertices[0]);
76
77 PointType edge_normal(facet_vec[1], -facet_vec[0]); // create one normal to line
78
79 if (viennagrid::inner_prod(facet_centroid_vec, edge_normal) > 0) // normal vector is pointing into cell, hence flip
80 edge_normal *= -1;
81
82 return edge_normal / viennagrid::norm(edge_normal);
83 }
84
85 // 3d, implementation for both tetrahedra and hexahedra:
86 template <typename CellTagT, typename FacetTagT, typename WrappedConfigT>
87 typename viennagrid::result_of::point< viennagrid::element<CellTagT, WrappedConfigT> >::type
88 outer_cell_normal_at_facet_3d(viennagrid::element<CellTagT, WrappedConfigT> const & cell,
89 viennagrid::element<FacetTagT, WrappedConfigT> const & facet)
90 {
91 typedef viennagrid::element<FacetTagT, WrappedConfigT> FacetType;
92 typedef typename viennagrid::result_of::point<FacetType>::type PointType;
93 typedef typename viennagrid::result_of::const_vertex_range<FacetType>::type VertexRange;
94
95 VertexRange facet_vertices(facet);
96 PointType facet_vec1 = viennagrid::point(facet_vertices[1]) - viennagrid::point(facet_vertices[0]);
97 PointType facet_vec2 = viennagrid::point(facet_vertices[2]) - viennagrid::point(facet_vertices[0]);
98 PointType facet_centroid_vec = viennagrid::centroid(cell) - viennagrid::point(facet_vertices[0]);
99
100 PointType edge_normal = viennagrid::cross_prod(facet_vec1, facet_vec2); // create one normal to line
101
102 if (viennagrid::inner_prod(facet_centroid_vec, edge_normal) > 0) // normal vector is pointing into cell, hence flip
103 edge_normal *= -1;
104
105 return edge_normal / viennagrid::norm(edge_normal);
106 }
107
108 // 3d, overload for tetrahedra
109 template <typename CellTagT, typename WrappedConfigT>
110 typename viennagrid::result_of::point< viennagrid::element<CellTagT, WrappedConfigT> >::type
111 outer_cell_normal_at_facet(viennagrid::element<CellTagT, WrappedConfigT> const & cell,
112 viennagrid::element<viennagrid::triangle_tag, WrappedConfigT> const & facet)
113 {
114 return outer_cell_normal_at_facet_3d(cell, facet);
115 }
116
117 // 3d, overload for hexahedra
118 template <typename CellTagT, typename WrappedConfigT>
119 typename viennagrid::result_of::point< viennagrid::element<CellTagT, WrappedConfigT> >::type
120 outer_cell_normal_at_facet(viennagrid::element<CellTagT, WrappedConfigT> const & cell,
121 viennagrid::element<viennagrid::quadrilateral_tag, WrappedConfigT> const & facet)
122 {
123 return outer_cell_normal_at_facet_3d(cell, facet);
124 }
125
126
127 }
128
130 template <typename CellTagT, typename FacetTagT, typename WrappedConfigT>
131 typename viennagrid::result_of::point< viennagrid::element<CellTagT,WrappedConfigT> >::type
132 outer_cell_normal_at_facet(viennagrid::element<CellTagT, WrappedConfigT> const & cell,
133 viennagrid::element<FacetTagT, WrappedConfigT> const & facet)
134 {
135 return detail::outer_cell_normal_at_facet(cell, facet);
136 }
137
138
139
149 template <typename DeviceT, typename CellT, typename FacetContainerT, typename CellSetterT, typename FacetAccessorT>
150 void dual_box_flux_to_cell(DeviceT const & device,
151 CellT const & cell, FacetContainerT const & facets,
152 CellSetterT & cell_setter, FacetAccessorT const & facet_access)
153 {
154 typedef typename viennagrid::result_of::iterator<FacetContainerT>::type FacetOnCellIterator;
155 typedef typename DeviceT::mesh_type MeshType;
156 typedef typename FacetOnCellIterator::value_type FacetType;
157 typedef typename viennagrid::result_of::point<CellT>::type PointType;
158
159 typedef typename viennagrid::result_of::const_coboundary_range<MeshType, FacetType, CellT>::type CellOnFacetContainer;
160 int N = PointType::dim;
162 std::vector<double> b(N);
163
164 std::vector<PointType> normals(facets.size());
165 std::vector<double> flux_contributions(facets.size());
166
167 // for all edges connected with the current vertex
168 std::size_t facet_ctr = 0;
169 for (FacetOnCellIterator focit = facets.begin();
170 focit != facets.end();
171 ++focit, ++facet_ctr )
172 {
173 flux_contributions[facet_ctr] = facet_access(*focit);
174 normals[facet_ctr] = outer_cell_normal_at_facet(cell, *focit); // vector along the edge pointing away from Vertex 'to'
175
176 // flip orientation of flux contribution if global orientation is different:
177 CellOnFacetContainer cells_on_facet(device.mesh(), viennagrid::handle(device.mesh(), *focit));
178 if (&cells_on_facet[0] != &cell)
179 flux_contributions[facet_ctr] *= -1.0;
180 }
181
182 // assemble mass matrix and rhs: M_i * V_i = rhs_i
183 for ( std::size_t i = 0; i < static_cast<std::size_t>(PointType::dim); ++i )
184 {
185 for ( std::size_t j = 0; j < static_cast<std::size_t>(PointType::dim); ++j )
186 {
187 for ( std::size_t k = 0; k < normals.size(); ++k )
188 M(i, j) += normals[k][i] * normals[k][j];
189 }
190 for ( std::size_t k = 0; k < normals.size(); ++k )
191 b[i] += normals[k][i] * flux_contributions[k];
192 }
193
194 std::vector<double> to_value(PointType::dim); // default: zero vector
195
196 std::vector<double> result = viennashe::solvers::solve(M, b);
197 for (std::size_t i=0; i<result.size(); ++i)
198 to_value[i] = result[i];
199
200 cell_setter(cell, to_value);
201
202 } // dual_box_flux_to_cell
203
204
211 template <typename DeviceType, typename CellSetter, typename FacetAccessor>
212 void dual_box_flux_to_cell(DeviceType const & device, CellSetter & cell_setter, FacetAccessor const & facet_accessor)
213 {
214 typedef typename DeviceType::mesh_type MeshType;
215 typedef typename viennagrid::result_of::cell<MeshType>::type CellType;
216
217 typedef typename viennagrid::result_of::const_cell_range<MeshType>::type CellContainer;
218 typedef typename viennagrid::result_of::iterator<CellContainer>::type CellIterator;
219
220 typedef typename viennagrid::result_of::const_facet_range<CellType>::type FacetOnCellContainer;
221
222 CellContainer cells(device.mesh());
223 for (CellIterator cit = cells.begin();
224 cit != cells.end();
225 ++cit)
226 {
227 FacetOnCellContainer facets(*cit);
228 dual_box_flux_to_cell(*cit, facets, cell_setter, facet_accessor);
229 }
230 }
231
232 } // util
233} // viennashe
234
235
236#endif /* VIENNASHE_UTIL_TRANSLATE_QUANTITY_HPP */
237
MeshT const & mesh() const
Returns the underlying mesh.
Definition: device.hpp:145
Defines the physical properties of a device, e.g. doping. This is the implementation for 2d and highe...
Definition: device.hpp:818
Defines several filter functors for the device. A filter functor returns true if the supplied argumen...
Contains forward declarations and definition of small classes that must be defined at an early stage.
Implementation of various utilities related to linear algebra.
A logging facility providing fine-grained control over logging in ViennaSHE.
Miscellaneous utilities.
std::vector< double > solve(viennashe::math::sparse_matrix< double > &A, std::vector< double > const &b, linear_solver_config const &config)
Public interface for solving a system of linear equations represented using a sparse matrix.
viennagrid::result_of::point< viennagrid::element< CellTagT, WrappedConfigT > >::type outer_cell_normal_at_facet_3d(viennagrid::element< CellTagT, WrappedConfigT > const &cell, viennagrid::element< FacetTagT, WrappedConfigT > const &facet)
viennagrid::result_of::point< viennagrid::element< viennagrid::line_tag, WrappedConfigT > >::type outer_cell_normal_at_facet(viennagrid::element< viennagrid::line_tag, WrappedConfigT > const &cell, viennagrid::element< viennagrid::vertex_tag, WrappedConfigT > const &facet)
void dual_box_flux_to_cell(DeviceT const &device, CellT const &cell, FacetContainerT const &facets, CellSetterT &cell_setter, FacetAccessorT const &facet_access)
Interpolates normal components of the flux defined on each facet to cells. Mostly used for visualizat...
viennagrid::result_of::point< viennagrid::element< CellTagT, WrappedConfigT > >::type outer_cell_normal_at_facet(viennagrid::element< CellTagT, WrappedConfigT > const &cell, viennagrid::element< FacetTagT, WrappedConfigT > const &facet)
Returns the unit outer normal of a facet with respect to the provided cell.
The main ViennaSHE namespace. All functionality resides inside this namespace.
Definition: accessors.hpp:40
Provides a number of fundamental constants. All constants in SI units.
Forward declarations for a generic solver layer, providing bindings to a native Gauss solver,...