ViennaSHE 1.3.0
Free open-source semiconductor device simulator using spherical harmonics expansions techniques.
transfer_to_new_h_space.hpp
Go to the documentation of this file.
1#ifndef VIENNASHE_SHE_TRANSFER_TO_NEW_H_SPACE_HPP
2#define VIENNASHE_SHE_TRANSFER_TO_NEW_H_SPACE_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#include <cmath>
19
20// viennagrid
21#include "viennagrid/mesh/mesh.hpp"
22#include "viennagrid/algorithm/voronoi.hpp"
23
24// viennashe
28
32
37
41
42#include "viennashe/log/log.hpp"
45
50namespace viennashe
51{
52 namespace she
53 {
54
55 namespace detail
56 {
57
58 template <typename ElementType,
59 typename VertexT, typename EdgeT>
60 void transfer_to_new_H_space_on_element(ElementType const & el,
61 std::size_t index_H,
64 {
65 if (new_quan.get_unknown_index(el, index_H) < 0) //nothing to do
66 return;
67
68 double new_kin_energy = new_quan.get_kinetic_energy(el, index_H);
69
70 long old_index_H = energy_index_H(old_quan, el, static_cast<long>(std::min<std::size_t>(index_H, old_quan.get_value_H_size()-1)), new_kin_energy);
71
72 if (old_index_H >= 0) //old quantity does not have this kinetic energy, so set values to zero on new quantity
73 {
74 if (old_quan.get_expansion_order(el, std::size_t(old_index_H)) == 0) //interpolate towards band-edge
75 {
76 while (old_quan.get_expansion_order(el, std::size_t(old_index_H)) == 0 && old_index_H < static_cast<long>(old_quan.get_value_H_size()) - 1) //box might be just below the band edge
77 ++old_index_H;
78 }
79
80 if (old_quan.get_expansion_order(el, std::size_t(old_index_H)) > 0) //there are values defined
81 {
82 std::size_t max_unknown_num = std::max<std::size_t>(new_quan.get_unknown_num(el, index_H ),
83 old_quan.get_unknown_num(el, std::size_t(old_index_H)));
84 std::vector<double> values(max_unknown_num);
85 for (std::size_t i=0; i<old_quan.get_unknown_num(el, std::size_t(old_index_H)); ++i)
86 values[i] = old_quan.get_values(el, std::size_t(old_index_H))[i];
87 new_quan.set_values(el, index_H, &(values[0]));
88 }
89 }
90
91 }
92
93 template <typename ElementType,
94 typename VertexT, typename EdgeT>
95 void normalize_on_new_H_space(ElementType const & el,
97 double scaling_factor)
98 {
99 for (std::size_t index_H=0; index_H < quan.get_value_H_size(); ++index_H)
100 {
101 if (quan.get_unknown_index(el, index_H) >= 0)
102 {
103 std::vector<double> values(quan.get_unknown_num(el, index_H));
104 for (std::size_t i=0; i<values.size(); ++i)
105 values[i] = quan.get_values(el, index_H)[i] * scaling_factor;
106 quan.set_values(el, index_H, &(values[0]));
107 }
108 }
109 }
110
111 } // namespace detail
112
113
121 template <typename DeviceType>
122 void transfer_to_new_h_space(DeviceType const & device,
125 viennashe::config const & conf)
126 {
127 typedef typename DeviceType::mesh_type MeshType;
128
129 typedef typename viennagrid::result_of::cell<MeshType>::type CellType;
130 typedef typename viennagrid::result_of::facet<MeshType>::type FacetType;
131
132 typedef typename viennagrid::result_of::const_facet_range<MeshType>::type FacetContainer;
133 typedef typename viennagrid::result_of::iterator<FacetContainer>::type FacetIterator;
134
135 typedef typename viennagrid::result_of::const_cell_range<MeshType>::type CellContainer;
136 typedef typename viennagrid::result_of::iterator<CellContainer>::type CellIterator;
137
139
140 MeshType const & mesh = device.mesh();
141
142 for (std::size_t i=0; i<new_quantities.unknown_she_quantities().size(); ++i)
143 {
144 SHEQuantity const & old_quan = old_quantities.unknown_she_quantities()[i];
145 SHEQuantity & new_quan = new_quantities.unknown_she_quantities()[i];
146
147 if (new_quan.get_value_H_size() == 0) //don't do anything if quantity is not enabled
148 return;
149
150 viennashe::she::carrier_density_wrapper<SHEQuantity> old_density_wrapper(conf, old_quan);
151 viennashe::she::carrier_density_wrapper<SHEQuantity> new_density_wrapper(conf, new_quan);
152
154 old_edge_evaluator(device, conf, old_quan);
156 new_edge_evaluator(device, conf, new_quan);
157
158 //
159 // Step 1: transfer solution on vertices
160 //
161 CellContainer cells(mesh);
162 for (CellIterator cit = cells.begin();
163 cit != cells.end();
164 ++cit)
165 {
166 for (std::size_t index_H = 1; index_H < new_quan.get_value_H_size() - 1; ++index_H)
167 detail::transfer_to_new_H_space_on_element(*cit, index_H, old_quan, new_quan);
168
169 // scale with respect to density:
170 double density_old = old_density_wrapper(*cit);
171 double density_new = new_density_wrapper(*cit);
172
173 if (density_new > 0 && density_old > 0)
174 detail::normalize_on_new_H_space(*cit, new_quan, density_old / density_new);
175 } //for vertices
176
177
178 //
179 // Step 2: transfer solution on edges
180 //
181 FacetContainer facets(mesh);
182 for (FacetIterator fit = facets.begin();
183 fit != facets.end();
184 ++fit)
185 {
186 for (std::size_t index_H = 1; index_H < new_quan.get_value_H_size()-1; ++index_H)
187 detail::transfer_to_new_H_space_on_element(*fit, index_H, old_quan, new_quan);
188
189 // scale with respect to current:
190 double current_old = old_edge_evaluator(*fit);
191 double current_new = new_edge_evaluator(*fit);
192
193 if (current_new && current_old)
194 detail::normalize_on_new_H_space(*fit, new_quan, current_old / current_new);
195 }
196 }
197
198
199 } //transfer_to_new_H_space
200
201 } //namespace she
202} //namespace viennashe
203
204#endif
205
Common routines for the assembly of SHE equations.
Writes a possibly scaled block matrix to the system matrix. Includes similar functionality for comput...
Provides an accessor for the carrier density.
Defines a set of checker functors for micro-tests within ViennaSHE.
The main SHE configuration class. To be adjusted by the user for his/her needs.
Definition: config.hpp:124
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
An accessor for the carrier density in the device.
The main SHE simulator controller class. Acts as an accessor for all SHE quantities needed for the si...
UnknownSHEQuantityListType & unknown_she_quantities()
General representation of any solver quantity defined on two different element types (e....
std::size_t get_unknown_num(AssociatedT1 const &elem, std::size_t index_H) const
long get_unknown_index(AssociatedT1 const &elem, std::size_t index_H) const
std::size_t get_expansion_order(AssociatedT1 const &elem, std::size_t index_H) const
ValueT get_kinetic_energy(AssociatedT1 const &elem, std::size_t index_H) const
ValueT const * get_values(AssociatedT1 const &elem, std::size_t index_H) const
void set_values(AssociatedT1 const &elem, std::size_t index_H, ValueT const *values)
Contains the dispersion relations for different materials and different polarities.
Provides the SHE coupling matrices and computes higher-order coupling matrices if required....
Implementation of numerical integration routines.
A logging facility providing fine-grained control over logging in ViennaSHE.
Provides a number of fundamental math constants.
Miscellaneous utilities.
void transfer_to_new_H_space_on_element(ElementType const &el, std::size_t index_H, she::unknown_she_quantity< VertexT, EdgeT > const &old_quan, she::unknown_she_quantity< VertexT, EdgeT > &new_quan)
void normalize_on_new_H_space(ElementType const &el, she::unknown_she_quantity< VertexT, EdgeT > &quan, double scaling_factor)
void transfer_to_new_h_space(DeviceType const &device, viennashe::she::timestep_quantities< DeviceType > const &old_quantities, viennashe::she::timestep_quantities< DeviceType > &new_quantities, viennashe::config const &conf)
Interface transferring a solution given by 'old_solution' on some other (old) grid to the new grid.
long energy_index_H(SHEQuantity const &quan, ElementType const &elem, long index_H_hint, double kinetic_energy)
Finds the closest H-index for the provided kinetic energy.
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.
Provides an accessor for the current density.
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.