ViennaSHE 1.3.0
Free open-source semiconductor device simulator using spherical harmonics expansions techniques.
accessors.hpp
Go to the documentation of this file.
1#ifndef VIENNASHE_ACCESSORS_HPP
2#define VIENNASHE_ACCESSORS_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// viennagrid
19#include "viennagrid/forwards.hpp"
20#include "viennagrid/mesh/mesh.hpp"
21#include "viennagrid/algorithm/voronoi.hpp"
22#include "viennagrid/mesh/neighbor_iteration.hpp"
23
24// viennashe
25#include "viennashe/forwards.h"
30#include "viennashe/device.hpp"
31
33
39namespace viennashe
40{
41 namespace detail
42 {
50 template < typename DeviceType, typename CellType >
51 void get_dopings_from_neighboring_semiconductor_cells(DeviceType const & device, CellType const & cell,
52 double * doping_n_ret, double * doping_p_ret)
53 {
54 typedef typename viennagrid::result_of::const_facet_range<CellType>::type FacetOnCellContainer;
55 typedef typename viennagrid::result_of::iterator<FacetOnCellContainer>::type FacetOnCellIterator;
56
57 // Ensure unity doping by default
58 double doping_n = 1;
59 double doping_p = 1;
60
61 long N = 0;
62 FacetOnCellContainer facets(cell);
63 for (FacetOnCellIterator focit = facets.begin(); focit != facets.end(); ++focit)
64 {
65 CellType const *other_cell_ptr = viennashe::util::get_other_cell_of_facet(device.mesh(), *focit, cell);
66 if (other_cell_ptr == 0) continue;
67
69 {
70 doping_n *= device.get_doping_n(*other_cell_ptr);
71 doping_p *= device.get_doping_p(*other_cell_ptr);
72 N += 1;
73 }
74 }
75 if(N > 1) doping_n = std::pow(doping_n, 1.0/N);
76 if(N > 1) doping_p = std::pow(doping_p, 1.0/N);
77
78 // RETURN
79 if(doping_n_ret) *doping_n_ret = doping_n;
80 if(doping_p_ret) *doping_p_ret = doping_p;
81 }
82
83 } // namespace detail
84
85 //
86 // Accessors
87 //
89 template <typename ConstantType>
91 {
92 public:
93 typedef ConstantType value_type;
94
95 constant_accessor(ConstantType const & c) : constant_(c) {}
96
97 template <typename T>
98 value_type operator()(T const &) const { return constant_; }
99
100 private:
101 ConstantType constant_;
102 };
103
105 template <typename DeviceType>
107 {
108 typedef typename DeviceType::mesh_type MeshType;
109 public:
110 typedef typename viennagrid::result_of::cell<MeshType>::type cell_type;
111 typedef double value_type;
112
113 lattice_temperature_accessor(DeviceType const & d) : device_(d) {}
114
115 value_type operator()(cell_type const & c) const { return device_.get_lattice_temperature(c); }
116
117 private:
118 DeviceType const & device_;
119 };
120
122 template <typename DeviceType>
124 {
125 typedef typename DeviceType::mesh_type MeshType;
126 public:
127 typedef typename viennagrid::result_of::cell<MeshType>::type cell_type;
128 typedef double value_type;
129
130 thermal_potential_accessor(DeviceType const & d) : device_(d) {}
131
132 value_type operator()(cell_type const & c) const { return viennashe::physics::get_thermal_potential(device_.get_lattice_temperature(c)); }
133
134 private:
135 DeviceType const & device_;
136 };
137
139 template <typename DeviceType>
141 {
142 typedef typename DeviceType::mesh_type MeshType;
143 public:
144 typedef typename viennagrid::result_of::cell<MeshType>::type cell_type;
145 typedef double value_type;
146
148 doping_accessor(DeviceType const & d, viennashe::carrier_type_id ctype) : device_(d), is_doping_n_(ctype == viennashe::ELECTRON_TYPE_ID) {}
149
150 value_type operator()(cell_type const & c) const { return is_doping_n_ ? device_.get_doping_n(c) : device_.get_doping_p(c); }
151
152 private:
153 DeviceType const & device_;
154 bool is_doping_n_;
155 };
156
157
159 template <typename DeviceType>
161 {
162 typedef typename DeviceType::mesh_type MeshType;
163
164 public:
165 typedef typename viennagrid::result_of::cell<MeshType>::type cell_type;
166 typedef typename viennagrid::result_of::facet<MeshType>::type facet_type;
167 typedef double value_type;
168
169 built_in_potential_accessor(DeviceType const & d) : device_(d) {}
170
172 {
173 if (viennashe::materials::is_semiconductor(device_.get_material(c)))
174 return viennashe::physics::built_in_potential(device_.get_lattice_temperature(c),
175 device_.get_doping_n(c),
176 device_.get_doping_p(c));
177
178 if (viennashe::materials::is_conductor(device_.get_material(c))) // important for boundary conditions
179 {
180 typedef typename viennagrid::result_of::const_neighbor_range<MeshType, cell_type, facet_type>::type NeighborRange;
181 typedef typename viennagrid::result_of::iterator<NeighborRange>::type NeighborIterator;
182
183 // for a cell attached to a semiconductor, return the contact potential corrected by the built-in potential:
184 NeighborRange neighbors(device_.mesh(), viennagrid::handle(device_.mesh(), c));
185 for (NeighborIterator nit = neighbors.begin(); nit != neighbors.end(); ++nit)
186 {
187 if (viennashe::materials::is_semiconductor(device_.get_material(*nit)))
188 return viennashe::physics::built_in_potential(device_.get_lattice_temperature(*nit),
189 device_.get_doping_n(*nit),
190 device_.get_doping_p(*nit));
191 }
192 }
193
194 // cell not attached to semiconductor, so we can safely assume no built-in potential
195 return 0.0;
196 }
197
198 private:
199 DeviceType const & device_;
200 };
201
202
204 template <typename DeviceT>
206 {
207 typedef typename DeviceT::mesh_type MeshType;
208
209 public:
210 typedef typename viennagrid::result_of::cell<MeshType>::type cell_type;
211 typedef double value_type;
212
213 boundary_potential_accessor(DeviceT const & d) : device_(d), built_in_pot_(d) {}
214
216 {
217 if (viennashe::materials::is_semiconductor(device_.get_material(c))
218 || viennashe::materials::is_conductor(device_.get_material(c)))
219 return device_.get_contact_potential(c) + built_in_pot_(c);
220
221 throw std::runtime_error("Logic error: Accessing boundary potential for insulators!");
222 }
223
224 private:
225 DeviceT const & device_;
227 };
228
230 template <typename DeviceType>
232 {
233 typedef typename DeviceType::mesh_type MeshType;
234
235 public:
236 typedef typename viennagrid::result_of::cell<MeshType>::type cell_type;
237 typedef double value_type;
238
239 contact_potential_accessor(DeviceType const & d) : device_(d) {}
240
242 {
243 return device_.get_contact_potential(c);
244 }
245
246 private:
247 DeviceType const & device_;
248 };
249
250
252 template <typename DeviceType>
254 {
255 typedef typename DeviceType::mesh_type MeshType;
256
257 public:
258 typedef typename viennagrid::result_of::cell<MeshType>::type cell_type;
259 typedef double value_type;
260
261 permittivity_accessor(DeviceType const & d) : device_(d) {}
262
263 value_type operator()(cell_type const & cell) const { return viennashe::materials::permittivity(device_.get_material(cell)); }
264
265 private:
266 DeviceType const & device_;
267 };
268
269
271 template <typename DeviceType>
273 {
274 typedef typename DeviceType::mesh_type MeshType;
275
276 public:
277 typedef typename viennagrid::result_of::cell<MeshType>::type cell_type;
278 typedef double value_type;
279
280 fixed_charge_accessor(DeviceType const & d) : device_(d) { }
281
284 {
285 return device_.get_fixed_charge(c);
286 }
287
288 private:
289 DeviceType const & device_;
290 };
291
293 template <typename DeviceType>
295 {
296 typedef typename DeviceType::mesh_type MeshType;
297
298 public:
299 typedef typename viennagrid::result_of::cell<MeshType>::type cell_type;
300 typedef double value_type;
301
302 diffusivity_accessor(DeviceType const & d) : device_(d) {}
303
304 value_type operator()(cell_type const & cell, double T) const
305 {
306 (void)T; // unused at the moment
307 return viennashe::materials::diffusivity(device_.get_material(cell));
308 }
309
310 private:
311 DeviceType const & device_;
312 };
313
315 template <typename DeviceType>
317 {
318 typedef double value_type;
319
320 contact_carrier_density_accessor(DeviceType const & d, viennashe::carrier_type_id ctype, bool doping_bnd = false)
321 : device_(d), carrier_type_id_(ctype), doping_bnd_(doping_bnd) { }
322
323 template < typename ElementType >
324 value_type operator()(ElementType const & el) const
325 {
326 const double temperature = device_.get_lattice_temperature(el);
327 return (this->operator ()(el, temperature));
328 }
329
330 template < typename ElementType >
331 value_type operator()(ElementType const & el, double T) const
332 {
333 if (T <= 0.0) throw viennashe::invalid_value_exception("contact_carrier_density_accessor: T <= 0!");
334
335 const long matid = device_.get_material(el);
336
338 return 0;
339
340 double doping_n = device_.get_doping_n(el);
341 double doping_p = device_.get_doping_p(el);
343 {
344 // ATTENTION: return by reference!
346 }
347
348 if (doping_bnd_ == true)
349 {
350 if(carrier_type_id_ == viennashe::ELECTRON_TYPE_ID)
351 return doping_n;
352 else if(carrier_type_id_ == viennashe::HOLE_TYPE_ID)
353 return doping_p;
354 else
355 throw viennashe::carrier_type_not_supported_exception("contact_carrier_density_accessor: ctype");
356 }
357 else
358 {
359 return viennashe::physics::contact_carrier_ohm(T, doping_n, doping_p, carrier_type_id_);
360 }
361 }
362
363 private:
364 DeviceType const & device_;
365 viennashe::carrier_type_id carrier_type_id_;
366 bool doping_bnd_;
367 };
368
369
370} // namespace viennashe
371
372#endif
373
Accessor for obtaining the Dirichlet boundary condition for the Poisson equation in the device (conta...
Definition: accessors.hpp:206
value_type operator()(cell_type const &c) const
Definition: accessors.hpp:215
viennagrid::result_of::cell< MeshType >::type cell_type
Definition: accessors.hpp:210
boundary_potential_accessor(DeviceT const &d)
Definition: accessors.hpp:213
Accessor for retrieving the built-in potential in the device.
Definition: accessors.hpp:161
viennagrid::result_of::cell< MeshType >::type cell_type
Definition: accessors.hpp:165
value_type operator()(cell_type const &c) const
Definition: accessors.hpp:171
built_in_potential_accessor(DeviceType const &d)
Definition: accessors.hpp:169
viennagrid::result_of::facet< MeshType >::type facet_type
Definition: accessors.hpp:166
Exception thrown in the case that any code does not support the given carrier type.
Definition: exception.hpp:154
An accessor which returns a constant value independent of the object passed.
Definition: accessors.hpp:91
value_type operator()(T const &) const
Definition: accessors.hpp:98
constant_accessor(ConstantType const &c)
Definition: accessors.hpp:95
Accessor for obtaining the contact potential in the device.
Definition: accessors.hpp:232
contact_potential_accessor(DeviceType const &d)
Definition: accessors.hpp:239
viennagrid::result_of::cell< MeshType >::type cell_type
Definition: accessors.hpp:236
value_type operator()(cell_type const &c) const
Definition: accessors.hpp:241
double get_doping_p(cell_type const &c) const
Returns the donator doping (in m^-3) in the specified cell.
Definition: device.hpp:393
long get_material(cell_type const &elem) const
Returns the material id of the provided cell.
Definition: device.hpp:502
MeshT const & mesh() const
Returns the underlying mesh.
Definition: device.hpp:145
double get_doping_n(cell_type const &c) const
Returns the donator doping (in m^-3) in the specified cell.
Definition: device.hpp:320
Defines the physical properties of a device, e.g. doping. This is the implementation for 2d and highe...
Definition: device.hpp:818
Accessor to get the diffusivity. Used in the assembly of the heat diffusion equation.
Definition: accessors.hpp:295
viennagrid::result_of::cell< MeshType >::type cell_type
Definition: accessors.hpp:299
diffusivity_accessor(DeviceType const &d)
Definition: accessors.hpp:302
value_type operator()(cell_type const &cell, double T) const
Definition: accessors.hpp:304
Accessor for returning the doping (donator/acceptor doping is defined in the CTOR)
Definition: accessors.hpp:141
viennagrid::result_of::cell< MeshType >::type cell_type
Definition: accessors.hpp:144
doping_accessor(DeviceType const &d, viennashe::carrier_type_id ctype)
This CTOR specifies donator doping.
Definition: accessors.hpp:148
value_type operator()(cell_type const &c) const
Definition: accessors.hpp:150
Accessor for fixed charges.
Definition: accessors.hpp:273
viennagrid::result_of::cell< MeshType >::type cell_type
Definition: accessors.hpp:277
fixed_charge_accessor(DeviceType const &d)
Definition: accessors.hpp:280
value_type operator()(cell_type const &c) const
Returns the fixed charge in As.
Definition: accessors.hpp:283
Exception for the case that an invalid value (depends on the method called) is encountered.
Definition: exception.hpp:76
Returns the lattice temperature on the device.
Definition: accessors.hpp:107
value_type operator()(cell_type const &c) const
Definition: accessors.hpp:115
lattice_temperature_accessor(DeviceType const &d)
Definition: accessors.hpp:113
viennagrid::result_of::cell< MeshType >::type cell_type
Definition: accessors.hpp:110
Accessor for obtaining the permittivity in the device.
Definition: accessors.hpp:254
value_type operator()(cell_type const &cell) const
Definition: accessors.hpp:263
permittivity_accessor(DeviceType const &d)
Definition: accessors.hpp:261
viennagrid::result_of::cell< MeshType >::type cell_type
Definition: accessors.hpp:258
Returns the thermal potential in the device.
Definition: accessors.hpp:124
value_type operator()(cell_type const &c) const
Definition: accessors.hpp:132
viennagrid::result_of::cell< MeshType >::type cell_type
Definition: accessors.hpp:127
thermal_potential_accessor(DeviceType const &d)
Definition: accessors.hpp:130
Contains the definition of a device class independent of the actual macroscopic model to be solved.
Provides the exceptions used in the main viennashe namespace.
Contains forward declarations and definition of small classes that must be defined at an early stage.
A very simple material database. Needs to be replaced by something more versatile soon.
Miscellaneous utilities.
void get_dopings_from_neighboring_semiconductor_cells(DeviceType const &device, CellType const &cell, double *doping_n_ret, double *doping_p_ret)
Retrieves the averaged dopings from neighboring semiconductor cells.
Definition: accessors.hpp:51
bool is_semiconductor(long material_id)
Convenience function for checking whether the supplied material ID refers to a semiconductor.
Definition: all.hpp:156
double permittivity(long material_id)
Convenience function for returning the permittivity of the material identified by the ID provided.
Definition: all.hpp:214
bool is_insulator(long material_id)
Convenience function for checking whether the supplied material ID refers to an oxide.
Definition: all.hpp:165
double diffusivity(long material_id)
Definition: all.hpp:235
bool is_conductor(long material_id)
Convenience function for checking whether the supplied material ID refers to a metal.
Definition: all.hpp:147
double get_thermal_potential(double T)
Returns the thermal potential for the provided temperature.
Definition: physics.hpp:61
double contact_carrier_ohm(double temperature, double doping_n, double doping_p, viennashe::carrier_type_id ctype)
Consistently calculates the contact carrier concentrations for thermal bath contacts.
Definition: physics.hpp:173
double built_in_potential(double temperature, double doping_n, double doping_p)
Computes the built-in potential for a given temperature and given doping.
Definition: physics.hpp:141
CellT const * get_other_cell_of_facet(MeshT const &mesh, FacetT const &facet, CellT const &cell)
Helper function returning a const-pointer to the 'second cell' of a facet, or NULL if there is no sec...
Definition: misc.hpp:196
The main ViennaSHE namespace. All functionality resides inside this namespace.
Definition: accessors.hpp:40
carrier_type_id
Enumeration type for selecting the carrier type.
Definition: forwards.h:185
@ HOLE_TYPE_ID
Definition: forwards.h:188
@ ELECTRON_TYPE_ID
Definition: forwards.h:187
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.
Returns the carrier density at contacts modelled as thermal baths (used by DD and SHE)
Definition: accessors.hpp:317
value_type operator()(ElementType const &el, double T) const
Definition: accessors.hpp:331
contact_carrier_density_accessor(DeviceType const &d, viennashe::carrier_type_id ctype, bool doping_bnd=false)
Definition: accessors.hpp:320
value_type operator()(ElementType const &el) const
Definition: accessors.hpp:324