ViennaSHE 1.3.0
Free open-source semiconductor device simulator using spherical harmonics expansions techniques.
assemble_traps.hpp
Go to the documentation of this file.
1#ifndef VIENNASHE_SHE_ASSEMBLE_TRAPS_HPP
2#define VIENNASHE_SHE_ASSEMBLE_TRAPS_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
18
19// viennagrid
20#include "viennagrid/mesh/mesh.hpp"
21#include "viennagrid/algorithm/voronoi.hpp"
22
23// viennashe
24#include "viennashe/forwards.h"
25#include "viennashe/setters.hpp"
30
34
38
42
43#include "viennashe/log/log.hpp"
45
46
48
49
54namespace viennashe
55{
56 namespace she
57 {
58
59 namespace detail
60 {
61
63 template <typename DeviceType,
64 typename TimeStepQuantitiesT,
65 typename SHEQuantity,
66 typename MatrixType,
67 typename VectorType,
68 typename CouplingMatrixType>
69 void assemble_traps_coupling_on_cell(DeviceType const & device,
70 TimeStepQuantitiesT const & quantities,
71 SHEQuantity const & quan,
72 viennashe::config const & conf,
73 typename DeviceType::cell_type const & el,
74 std::size_t index_H,
75 MatrixType & matrix, VectorType & rhs,
76 CouplingMatrixType const & diagonal_coupling_matrix,
77 CouplingMatrixType const & coupling_matrix_00
78 )
79 {
80 typedef typename DeviceType::trap_level_container_type TrapContainerType;
81 typedef typename TrapContainerType::const_iterator TrapIterator;
82
83 const long row_index = quan.get_unknown_index(el, index_H);
84
85 if (row_index < 0)
86 return;
87
88 TrapContainerType const & traps = device.get_trap_levels(el);
89
90 const std::size_t num_trap_unknowns = quantities.num_trap_unknown_indices(el);
91
92 if (num_trap_unknowns <= 0)
93 return;
94
95 if (num_trap_unknowns != traps.size())
96 throw viennashe::invalid_value_exception("The number of traps configured in the device does not match the number of unknowns for traps!", static_cast<double>(num_trap_unknowns));
97
98 const double Z = averaged_density_of_states(quan, conf.dispersion_relation(quan.get_carrier_type_id()), el, index_H);
99 const long expansion_order = static_cast<long>(quan.get_expansion_order(el, index_H));
100 const double energy_height = box_height(quan, el, index_H);
101
103
104 double volume_contribution = viennagrid::volume(el);
105
106 std::size_t inner_index = 0;
107 for ( TrapIterator trap_it = traps.begin();
108 trap_it != traps.end();
109 ++trap_it, ++inner_index)
110 {
111 log::debug<log_traps>() << el << " => " << *trap_it << std::endl;
112
113 const double occupancy = quantities.trap_occupancy(el, inner_index);
114
115 //
116 // Term + Gamma_rec N_T f (electrons)
117 // Gamma_rec N_T f (holes)
118 //
119 // Note: Gamma_rec should already include the trap occupancies !!!
120 //
121
122 const double trap_density = trap_it->density();
123 // Note: Gamma_rec should already include the trap occupancies !!!
125 quantities, quan.get_carrier_type_id(),
126 occupancy, index_H);
127
129 std::size_t(row_index), std::size_t(row_index),
130 gamma_recombination * trap_density * Z * volume_contribution * energy_height,
131 diagonal_coupling_matrix,
132 viennashe::math::spherical_harmonics_iterator(expansion_order, harmonics_it_id),
133 viennashe::math::spherical_harmonics_iterator(expansion_order, harmonics_it_id)
134 );
135
136 //
137 // Term - (1 - f) Gamma_gen N_T (electrons)
138 // - (1 - f) Gamma_gen N_T (holes)
139 //
140 // Neglecting Pauli principle, thus only - Gamma_gen N_T f_T is assembled
141 //
142 // Note: Gamma_gen should already include the trap occupancies !!!
143 //
144
145 // Note: Gamma_gen should already include the trap occupancies !!!
146 const double gamma_generation = viennashe::models::srh::gamma_generation(*trap_it, device, el, conf,
147 quantities, quan.get_carrier_type_id(),
148 occupancy, index_H);
149 write_boundary(rhs, std::size_t(row_index),
150 - gamma_generation * trap_density * Z * volume_contribution * energy_height,
151 coupling_matrix_00,
152 viennashe::math::spherical_harmonics_iterator(expansion_order, harmonics_it_id)
153 );
154 } // for traps
155
156 } //assemble_traps_coupling_on_cell
157
158
160 template <typename DeviceType,
161 typename TimeStepQuantitiesT,
162 typename SHEQuantity,
163 typename MatrixType,
164 typename VectorType,
165 typename CouplingMatrixType>
167 TimeStepQuantitiesT const & quantities,
168 SHEQuantity const & quan,
169 viennashe::config const & conf,
170 typename DeviceType::facet_type const & el,
171 std::size_t index_H,
172 MatrixType & matrix, VectorType & rhs,
173 CouplingMatrixType const & diagonal_coupling_matrix,
174 CouplingMatrixType const & coupling_matrix_00
175 )
176 {
177 typedef typename DeviceType::mesh_type MeshType;
178 typedef typename DeviceType::cell_type CellType;
179 typedef typename DeviceType::trap_level_container_type TrapContainerType;
180 typedef typename TrapContainerType::const_iterator TrapIterator;
181 typedef typename viennagrid::result_of::point<MeshType>::type PointType;
182 typedef typename viennagrid::result_of::const_coboundary_range<MeshType, typename DeviceType::facet_type, CellType>::type CellOnFacetContainer;
183
184 (void)rhs; (void)coupling_matrix_00;
185 const long row_index = quan.get_unknown_index(el, index_H);
186
187 if (row_index < 0)
188 return;
189
190 const double Z = averaged_density_of_states(quan, conf.dispersion_relation(quan.get_carrier_type_id()), el, index_H);
191 const long expansion_order = static_cast<long>(quan.get_expansion_order(el, index_H));
192 const double energy_height = box_height(quan, el, index_H);
193
195
196 double volume_contribution = viennagrid::volume(el);
197 volume_contribution *= detail::cell_connection_length(device.mesh(), el, viennagrid::cells(device.mesh())[0]) / static_cast<double>(PointType::dim);
198
199 CellOnFacetContainer cells_on_facet(device.mesh(), viennagrid::handle(device.mesh(), el));
200
201 for (std::size_t cell_index = 0; cell_index < cells_on_facet.size(); ++cell_index)
202 {
203 CellType const & cell = cells_on_facet[cell_index];
204
205 TrapContainerType const & traps = device.get_trap_levels(cell);
206 const std::size_t num_trap_unknowns = quantities.num_trap_unknown_indices(cell);
207
208 if (num_trap_unknowns <= 0)
209 return;
210
211 if (num_trap_unknowns != traps.size())
212 throw viennashe::invalid_value_exception("The number of traps configured in the device does not match the number of unknowns for traps!", static_cast<double>(num_trap_unknowns));
213
214 std::size_t inner_index = 0;
215 for ( TrapIterator trap_it = traps.begin();
216 trap_it != traps.end();
217 ++trap_it, ++inner_index)
218 {
219 log::debug<log_traps>() << el << " => " << *trap_it << std::endl;
220
221 const double occupancy = quantities.trap_occupancy(cell, inner_index);
222
223 //
224 // Term + Gamma_rec N_T f (electrons)
225 // Gamma_rec N_T f (holes)
226 //
227 // Note: Gamma_rec should already include the trap occupancies !!!
228 //
229
230 const double trap_density = trap_it->density();
231 // Note: Gamma_rec should already include the trap occupancies !!!
233 quantities, quan.get_carrier_type_id(), occupancy, index_H);
234
236 std::size_t(row_index), std::size_t(row_index),
237 gamma_recombination * trap_density * Z * volume_contribution * energy_height,
238 diagonal_coupling_matrix,
239 viennashe::math::spherical_harmonics_iterator(expansion_order, harmonics_it_id),
240 viennashe::math::spherical_harmonics_iterator(expansion_order, harmonics_it_id)
241 );
242 } // for traps
243 }
244
245 } // assemble_traps_coupling_on_facet
246
247 } // namespace detail
248
258 template <typename DeviceType,
259 typename TimeStepQuantitiesT,
260 typename SHEQuantity,
261 typename MatrixType,
262 typename VectorType>
263 void assemble_traps_coupling(DeviceType const & device,
264 TimeStepQuantitiesT const & quantities,
265 viennashe::config const & conf,
266 SHEQuantity const & quan,
267 MatrixType & matrix,
268 VectorType & rhs)
269 {
270 typedef typename DeviceType::mesh_type MeshType;
271
272 typedef typename viennagrid::result_of::const_cell_range<MeshType>::type CellContainer;
273 typedef typename viennagrid::result_of::iterator<CellContainer>::type CellIterator;
274
275 typedef typename viennagrid::result_of::const_facet_range<MeshType>::type FacetContainer;
276 typedef typename viennagrid::result_of::iterator<FacetContainer>::type FacetIterator;
277
278 typedef viennashe::math::sparse_matrix<double> CouplingMatrixType;
279
280 MeshType const & mesh = device.mesh();
281
282 //
283 // Set up scatter matrices:
284 //
285 std::size_t L_max = static_cast<std::size_t>(conf.max_expansion_order());
286 std::size_t num_harmonics = static_cast<std::size_t>(L_max+1) * static_cast<std::size_t>(L_max+1);
287 CouplingMatrixType diagonal_coupling_matrix(num_harmonics, num_harmonics);
288 CouplingMatrixType coupling_matrix_00(num_harmonics, num_harmonics);
290
291 for (std::size_t i=0; i< (L_max+1) * (L_max+1); ++i)
292 diagonal_coupling_matrix(i,i) += 1.0;
293 coupling_matrix_00(0,0) = 1.0 / Y_00(0,0);
294
295 //
296 // Step 1: assemble on even nodes:
297 //
298 CellContainer cells(mesh);
299 for (CellIterator cit = cells.begin();
300 cit != cells.end();
301 ++cit)
302 {
303 for (std::size_t index_H = 0; index_H < quan.get_value_H_size(); ++index_H)
304 detail::assemble_traps_coupling_on_cell(device, quantities, quan, conf, *cit, index_H, matrix, rhs, diagonal_coupling_matrix, coupling_matrix_00);
305 }
306
307
308 //
309 // Step 3: assemble on odd nodes
310 //
311 FacetContainer facets(mesh);
312 for (FacetIterator fit = facets.begin();
313 fit != facets.end();
314 ++fit)
315 {
316 for (std::size_t index_H = 0; index_H < quan.get_value_H_size(); ++index_H)
317 detail::assemble_traps_coupling_on_facet(device, quantities, quan, conf, *fit, index_H, matrix, rhs, diagonal_coupling_matrix, coupling_matrix_00);
318 }
319
320 } //assemble_traps_coupling
321
322
323
324
325 template <typename DeviceType,
326 typename TimeStepQuantitiesT,
327 typename SHEQuantity,
328 typename MatrixType,
329 typename VectorType>
330 void assemble_traps_solver(DeviceType const & device,
331 TimeStepQuantitiesT & quantities,
332 viennashe::config const & conf,
333 SHEQuantity const & quan,
334 MatrixType & matrix,
335 VectorType & rhs
336 )
337 {
338 typedef typename DeviceType::mesh_type MeshType;
339
340 typedef typename viennagrid::result_of::const_cell_range<MeshType>::type CellContainer;
341 typedef typename viennagrid::result_of::iterator<CellContainer>::type CellIterator;
342
343 typedef typename DeviceType::trap_level_container_type TrapContainerType;
344 typedef typename TrapContainerType::const_iterator TrapIterator;
345
346 (void)quan; (void)matrix; (void)rhs; //eliminate unused parameter warnings
347
348 MeshType const & mesh = device.mesh();
349
350 CellContainer cells(mesh);
351 for (CellIterator cit = cells.begin();
352 cit != cells.end();
353 ++cit)
354 {
355 const std::size_t num_trap_unknowns = quantities.num_trap_unknown_indices(*cit);
356 TrapContainerType const & traps = device.get_trap_levels(*cit);
357 if (num_trap_unknowns > 0)
358 {
359
360 if (num_trap_unknowns != traps.size())
361 throw viennashe::invalid_value_exception("The number of traps configured in the device does not match the number of unknowns for traps!", static_cast<double>(num_trap_unknowns));
362
363 std::size_t inner_index = 0;
364
365 for (TrapIterator trap_it = traps.begin();
366 trap_it != traps.end();
367 ++trap_it, ++inner_index)
368 {
369 // No need to assemble a matrix ...
370 double new_ft = viennashe::models::srh::evaluate(*trap_it, device, *cit, conf, quantities);
371
372 //std::cout << *cit << " => " << new_ft << std::endl;
373
374 quantities.trap_occupancy(*cit, inner_index, new_ft);
375
376 /* TODO: NEWTON
377 matrix(unknown_index, unknown_index) = 1.0;
378 if (simulation_cnt > 0)
379 {
380 rhs[unknown_index] = (electron_rec_rate + hole_gen_rate) / (electron_rec_rate + electron_gen_rate + hole_rec_rate + hole_gen_rate); // aka. rate_in / (rate_in + rate_out)
381 if (with_full_newton)
382 rhs[unknown_index] -= current_guess[unknown_index];
383 }
384 else
385 rhs[unknown_index] = trap_it->occupancy();
386
387 ++unknown_index;
388 */
389
390 } //for trap_level
391 } // if
392 } //for cells
393 }
394
395
396 template <typename DeviceType,
397 typename TimeStepQuantitiesT,
398 typename SHEQuantity,
399 typename MatrixType,
400 typename VectorType>
401 void assemble_traps(DeviceType const & device,
402 TimeStepQuantitiesT & quantities,
403 viennashe::config const & conf,
404 SHEQuantity const & quan,
405 MatrixType & matrix,
406 VectorType & rhs
407 )
408 {
409
410 if (conf.with_trap_selfconsistency())
411 viennashe::she::assemble_traps_coupling(device, quantities, conf, quan, matrix, rhs);
412
413 viennashe::she::assemble_traps_solver(device, quantities, conf, quan, matrix, rhs);
414 }
415
416 } //namespace she
417} //namespace viennashe
418
419#endif
Contains the definition of per-device accessors (read-only!) for various quantities.
Common routines for the assembly of SHE equations.
Writes a possibly scaled block matrix to the system matrix. Includes similar functionality for comput...
The main SHE configuration class. To be adjusted by the user for his/her needs.
Definition: config.hpp:124
viennashe::physics::dispersion_proxy dispersion_relation(viennashe::carrier_type_id ctype) const
Returns the dispersion relation for electrons.
Definition: config.hpp:266
long max_expansion_order() const
Returns the current maximum expansion order.
Definition: config.hpp:369
bool with_trap_selfconsistency() const
Returns true if traps are considered self-consistently in the simulation.
Definition: config.hpp:247
MeshT const & mesh() const
Returns the underlying mesh.
Definition: device.hpp:145
trap_level_container_type const & get_trap_levels(cell_type const &cell) const
Returns all the trap levels defined for the provided cell.
Definition: device.hpp:615
Defines the physical properties of a device, e.g. doping. This is the implementation for 2d and highe...
Definition: device.hpp:818
Exception for the case that an invalid value (depends on the method called) is encountered.
Definition: exception.hpp:76
Iteration over all spherical harmonics indices up to order L, with increasing indices l and m.
Contains the dispersion relations for different materials and different polarities.
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.
Provides the SHE coupling matrices and computes higher-order coupling matrices if required....
Implementation of numerical integration routines.
Implementation of various utilities related to linear algebra.
A logging facility providing fine-grained control over logging in ViennaSHE.
Provides a number of fundamental math constants.
harmonics_iteration_type
An enumeration of spherical harmonics types (all, even, odd) ViennaSHE supports.
Definition: forwards.h:159
@ EVEN_HARMONICS_ITERATION_ID
Definition: forwards.h:161
@ ODD_HARMONICS_ITERATION_ID
Definition: forwards.h:162
double gamma_generation(viennashe::trap_level const &trap, DeviceType const &device, ElementType const &el, viennashe::config const &conf, TimeStepQuantitiesT const &quantities, viennashe::carrier_type_id ctype, double occupancy, std::size_t index_H=0)
Returns the carrier generation, where the occupancies have been considered!
double evaluate(viennashe::trap_level const &trap, DeviceType const &device, ElementType const &el, viennashe::config const &conf, TimeStepQuantitiesT const &quantities)
Returns the trap occupancy based on a bipolar SHE or DD solution.
double gamma_recombination(viennashe::trap_level const &trap, DeviceType const &device, ElementType const &el, viennashe::config const &conf, TimeStepQuantitiesT const &quantities, viennashe::carrier_type_id ctype, double occupancy, std::size_t index_H=0)
Returns the carrier recombination, where the occupancies have been considered!
void assemble_traps_coupling_on_cell(DeviceType const &device, TimeStepQuantitiesT const &quantities, SHEQuantity const &quan, viennashe::config const &conf, typename DeviceType::cell_type const &el, std::size_t index_H, MatrixType &matrix, VectorType &rhs, CouplingMatrixType const &diagonal_coupling_matrix, CouplingMatrixType const &coupling_matrix_00)
Assembles the coupling of the distribution function with the trap occupancy for a cell (even-order f_...
double cell_connection_length(MeshT const &, CellT const &, CellT const &)
Static dispatcher for computing the connection between two cells adjacent to a facet....
void assemble_traps_coupling_on_facet(DeviceType const &device, TimeStepQuantitiesT const &quantities, SHEQuantity const &quan, viennashe::config const &conf, typename DeviceType::facet_type const &el, std::size_t index_H, MatrixType &matrix, VectorType &rhs, CouplingMatrixType const &diagonal_coupling_matrix, CouplingMatrixType const &coupling_matrix_00)
Assembles the coupling of the distribution function with the trap occupancy for either a facet (odd-o...
void assemble_traps(DeviceType const &device, TimeStepQuantitiesT &quantities, viennashe::config const &conf, SHEQuantity const &quan, MatrixType &matrix, VectorType &rhs)
void assemble_traps_solver(DeviceType const &device, TimeStepQuantitiesT &quantities, viennashe::config const &conf, SHEQuantity const &quan, MatrixType &matrix, VectorType &rhs)
double averaged_density_of_states(SHEQuantity const &quan, viennashe::config::dispersion_relation_type const &dispersion, CellFacetType const &cell_facet, std::size_t index_H)
Returns the density of states around a vertex or an edge at total energy specified by index_H....
double box_height(SHEQuantity const &quan, ElementType const &elem, std::size_t index_H)
Returns the height of the control box with respect to energy at the provided element (vertex or edge)...
void assemble_traps_coupling(DeviceType const &device, TimeStepQuantitiesT const &quantities, viennashe::config const &conf, SHEQuantity const &quan, MatrixType &matrix, VectorType &rhs)
Interface function for the assembly of traps.
void write_boundary(VectorType &rhs, std::size_t row_start, double prefactor, MatrixType const &coupling_matrix, IteratorType row_iter)
Write Dirichlet boundary conditions to right hand side.
void add_block_matrix(SystemMatrixType &system_matrix, std::size_t row_index, std::size_t col_index, double prefactor, BlockMatrixType const &coupling_matrix, RowIndexIterator row_iter, ColumnIndexIterator const &col_iter_init, bool elastic_scattering_roundoff_error_prevention=false)
Writes a sub-matrix of a block matrix 'coupling_matrix' into the global system matrix,...
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.
Returns a few helper routines for computing physical quantities. To be replaced in the future.
Contains the definition of convenience functors for accessing device quantities (see class device)....
Implementation of spherical harmonics plus helper functions.
A container of all quantities defined for a certain timestep t.
Defines the log keys used within the viennashe::she namespace.