ViennaSHE 1.3.0
Free open-source semiconductor device simulator using spherical harmonics expansions techniques.
simulator_setup.hpp
Go to the documentation of this file.
1#ifndef VIENNASHE_SIMULATOR_SETUP_HPP
2#define VIENNASHE_SIMULATOR_SETUP_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 <iostream>
19#include <sstream>
20#include <string>
21#include <stdexcept>
22#include <limits>
23
24// viennashe
25#include "viennashe/forwards.h"
27#include "viennashe/setters.hpp"
28#include "viennashe/device.hpp"
35#include "viennashe/log/log.hpp"
36
37#include "viennagrid/algorithm/norm.hpp"
38#include "viennagrid/algorithm/quantity_transfer.hpp"
39#include "viennagrid/algorithm/closest_points.hpp"
40#include "viennagrid/algorithm/distance.hpp"
41
42#include "viennagrid/mesh/segmentation.hpp"
43#include "viennagrid/mesh/mesh_operations.hpp"
44
45
46
51namespace viennashe
52{
53 namespace detail
54 {
55
64 template <typename ElementTagT, typename DeviceType, typename AccessorType, typename FilterType, typename CheckerType>
65 bool check_quantity_on_ncell(DeviceType const & device,
66 AccessorType const & accessor,
67 FilterType const & filter,
68 CheckerType const & checker)
69 {
70 typedef typename DeviceType::mesh_type MeshType;
71 typedef typename viennagrid::result_of::const_element_range<MeshType, ElementTagT>::type NCellContainer;
72 typedef typename viennagrid::result_of::iterator<NCellContainer>::type NCellIterator;
73
74 NCellContainer cells(device.mesh());
75
76 bool quantity_okay = true;
77
78 // Check whether quantities are okay:
79 for (NCellIterator nit = cells.begin();
80 nit != cells.end();
81 ++nit)
82 {
83 if (!filter(*nit))
84 continue;
85
86 if (!checker(accessor(*nit)))
87 {
88 quantity_okay = false;
89 break;
90 }
91 }
92
93 return quantity_okay;
94 }
95
96
112 template <typename TagT, typename FallbackTagT, typename DeviceType,
113 typename AccessorType, typename FilterType, typename CheckerType,
114 typename FallbackAccessorType, typename FallbackSetterType, typename FallbackAveragerType, typename FallbackFilterType, typename FallbackCheckerType>
116 AccessorType const & accessor,
117 FilterType const & filter,
118 CheckerType const & checker,
119 FallbackAccessorType const & fallback_accessor,
120 FallbackSetterType & fallback_setter,
121 FallbackAveragerType const & fallback_averager,
122 FallbackFilterType const & fallback_filter,
123 FallbackCheckerType const & fallback_checker
124 )
125 {
126 bool quantity_okay = check_quantity_on_ncell<TagT>(device, accessor, filter, checker);
127
128 // if quantity is not yet okay, use fallback
129 if (!quantity_okay)
130 {
131 // transfer quantity
132 viennagrid::quantity_transfer<FallbackTagT, TagT>(device.mesh(),
133 fallback_accessor, fallback_setter, // Accessor (in) and Setter (out)
134 fallback_averager, // Averaging
135 fallback_filter, filter); // Filters (in, out)
136
137 //check again:
138 check_quantity_on_ncell<TagT>(device, accessor, filter, fallback_checker);
139 return true;
140 }
141
142 return false;
143 }
144
147 {
148 if (ctype == viennashe::ELECTRON_TYPE_ID)
149 return invalid_doping_in_device_exception("Check failed: Invalid donator doping in device!");
150 else if (ctype == viennashe::HOLE_TYPE_ID)
151 return invalid_doping_in_device_exception("Check failed: Invalid acceptor doping in device!");
152 else
153 return invalid_doping_in_device_exception("Check failed: Invalid UNKOWN doping in device!");
154 }
155
156 } // namespace detail
157
158
159 //
160 // Doping
161 //
162
168 template <typename DeviceType>
170 {
171 typedef typename viennagrid::result_of::cell_tag<typename DeviceType::mesh_type>::type CellTag;
172
173 // fallback functors:
174 doping_setter<DeviceType> fallback_setter(device, ctype);
175 util::geometric_averaging fallback_averager;
177
178 // standard check functors:
180 util::vicinity_filter<DeviceType,
181 CellTag,
182 util::semiconductor_filter<DeviceType> > filter(device, fallback_filter);
183 util::range_checker<double> checker(1.0, 1e32);
184
185 bool fallback_used = detail::setup_and_check_quantity_on_ncell_with_fallback<viennagrid::vertex_tag, CellTag>(
186 device, doping_accessor, filter, checker,
187 doping_accessor, fallback_setter, fallback_averager, fallback_filter,
189 );
190 if (fallback_used)
191 {
192 log::info() << "* setup_doping_on_vertices(): Doping defined on cells successfully transferred to vertices. " << std::endl;
193 }
194 else
195 {
196 log::info() << "* setup_doping_on_vertices(): Doping defined on vertices passes consistency check." << std::endl;
197 }
198
199 }
200
205 template <typename DeviceType>
207 {
210 }
211
212
221 /*
222 template <typename DeviceType>
223 void setup_insulator_distances(DeviceType & device)
224 {
225 typedef typename DeviceType::mesh_type MeshType;
226 typedef typename viennagrid::result_of::segmentation<MeshType>::type SegmentationType;
227 typedef typename viennagrid::result_of::segment_handle<SegmentationType>::type SegmentType;
228 typedef typename viennagrid::result_of::point<MeshType>::type PointType;
229
230 typedef typename viennagrid::result_of::const_cell_range<SegmentType>::type CellOnSegmentContainer;
231 typedef typename viennagrid::result_of::const_vertex_range<SegmentType> ::type VertexOnSegmentContainer;
232 typedef typename viennagrid::result_of::iterator<VertexOnSegmentContainer>::type VertexIterator;
233
234 log::info() << "* setup_insulator_distances(): Calculating interface distances ..." << std::endl;
235
236 // for every semiconductor segment ...
237 for ( typename SegmentationType::const_iterator seg_it = device.segmentation().begin();
238 seg_it != device.segmentation().end();
239 ++seg_it)
240 {
241 const SegmentType & segment = *seg_it;
242 CellOnSegmentContainer cells(segment);
243
244 if(cells.size() > 0 && viennashe::materials::is_semiconductor(device.get_material(cells[0]))) // exclude non semiconductors
245 {
246 // ... loop over every vertex in that segment ...
247 VertexOnSegmentContainer vertices(segment);
248 for (VertexIterator vit = vertices.begin(); vit != vertices.end(); vit++)
249 {
250 double mindist = std::numeric_limits<double>::max();
251 // ... loop over all insulator segments ...
252 for ( typename SegmentationType::const_iterator seg_it2 = device.segmentation().begin();
253 seg_it2 != device.segmentation().end();
254 ++seg_it2)
255 {
256 const SegmentType & insulator_segment = *seg_it2;
257 CellOnSegmentContainer insulator_cells(insulator_segment);
258
259 if(insulator_cells.size() == 0 || &segment == &insulator_segment) continue; // skip empty segments
260 if(!viennashe::materials::is_insulator(device.get_material(insulator_cells[0]))) continue; // skip non-insulator segments
261
262 // ... find the shortest distance from the vertex to the insulator segment and cache it ...
263 throw "Fix me!";
264 const PointType pt; // FIX = viennagrid::closest_points(*vit, insulator_segment).second - viennagrid::point(*vit);
265 const double dist = viennagrid::norm_2(viennagrid::point(*vit) - pt);
266 // ... if it is smaller than the previous distance
267 if(dist < mindist)
268 {
269 //viennashe::log::debug() << "DISTANCE vector from " << sid_semi << " to "<< sid << " for vertex " << vit->id() << " => (" << pt << ") " << std::endl;
270 device.set_vector_to_next_insulator(*vit, pt); // TODO: What about corners ? (think of an L-shaped insulator and a semiconductor in its corner)
271 mindist = dist;
272 }
273 } // for insulator segments
274 } // for vertices of semiconductor segment
275 } // if current segment is semiconductor
276 } // for segments
277
278 } */
279
280} //namespace viennashe
281
282#endif
Contains the definition of per-device accessors (read-only!) for various quantities.
Defines a set of checker functors for micro-tests within ViennaSHE.
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
Accessor for returning the doping (donator/acceptor doping is defined in the CTOR)
Definition: accessors.hpp:141
Convenience functor for setting the doping across the device.
Definition: setters.hpp:45
Exception for the case that an invalid doping is encountered.
Definition: exception.hpp:39
Checker for values inside a half-open interval [a, b), where 'a' is included, while 'b' is not.
Definition: checks.hpp:57
A filter accepting semiconductor cells only.
Definition: filter.hpp:56
A filter returning true if any of the neighboring ncells of dimension 'dim' evaluate to true.
Definition: filter.hpp:144
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.
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.
A logging facility providing fine-grained control over logging in ViennaSHE.
A very simple material database. Needs to be replaced by something more versatile soon.
Miscellaneous utilities.
invalid_doping_in_device_exception get_invalid_doping_exception(viennashe::carrier_type_id ctype)
Helper routine for creating the exception thrown if the donator doping is found to be invalid on the ...
bool setup_and_check_quantity_on_ncell_with_fallback(DeviceType &device, AccessorType const &accessor, FilterType const &filter, CheckerType const &checker, FallbackAccessorType const &fallback_accessor, FallbackSetterType &fallback_setter, FallbackAveragerType const &fallback_averager, FallbackFilterType const &fallback_filter, FallbackCheckerType const &fallback_checker)
Ensures that a quantity is available on n-cells of a certain dimension. If this is not the case,...
bool check_quantity_on_ncell(DeviceType const &device, AccessorType const &accessor, FilterType const &filter, CheckerType const &checker)
Ensures that a quantity is available on n-cells of a certain dimension. If this is not the case,...
logger< true > info()
Used to log infos. The logging level is logINFO.
Definition: log.hpp:307
checker_with_exception< CheckerType, ExceptionType > make_checker_with_exception(CheckerType const &checker, ExceptionType const &ex)
Convenience creator routine for creating a checker with exception from checker returning a bool only.
Definition: checks.hpp:161
The main ViennaSHE namespace. All functionality resides inside this namespace.
Definition: accessors.hpp:40
void setup_doping_on_vertices(DeviceType &device, viennashe::carrier_type_id ctype)
Sets up donator or acceptor doping on vertices. If doping is provided on cells, it is interpolated ac...
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
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)....
A functor which computes the geometric average of all entries in a container.
Definition: misc.hpp:101