ViennaSHE 1.3.0
Free open-source semiconductor device simulator using spherical harmonics expansions techniques.
quantity.cpp
Go to the documentation of this file.
1/* ============================================================================
2 Copyright (c) 2011-2022, Institute for Microelectronics,
3 Institute for Analysis and Scientific Computing,
4 TU Wien.
5
6 -----------------
7 ViennaSHE - The Vienna Spherical Harmonics Expansion Boltzmann Solver
8 -----------------
9
10 http://viennashe.sourceforge.net/
11
12 License: MIT (X11), see file LICENSE in the base directory
13=============================================================================== */
14
15// C++ includes
19
20// C includes
22
23#include <cstring>
24
25
26#ifdef __cplusplus
27extern "C"
28{
29#endif
30
32{
33 try
34 {
36 CHECK_ARGUMENT_FOR_NULL(sim,2,"sim");
37
38 // Get simulator
39 viennashe_simulator_impl * int_sim = sim;
40 if (!int_sim->is_valid())
41 {
42 viennashe::log::error() << "ERROR! viennashe_create_quantity_register(): The simulator (sim) must be valid!" << std::endl;
43 return 2;
44 }
45
47 int_reg->int_sim = int_sim; // Make sure to register the quans for a certain simulator!
48
49
50 //
51 // Register Quantities
53 libviennashe::register_quans(*(int_reg->int_sim->sim1d), *int_reg);
55 libviennashe::register_quans(*(int_reg->int_sim->simq2d), *int_reg);
57 libviennashe::register_quans(*(int_reg->int_sim->simt2d), *int_reg);
59 libviennashe::register_quans(*(int_reg->int_sim->simh3d), *int_reg);
61 libviennashe::register_quans(*(int_reg->int_sim->simt3d), *int_reg);
62 else
63 {
64 viennashe::log::error() << "ERROR! viennashe_create_quantity_register(): Malconfigured simulator!" << std::endl;
65 return 2;
66 }
67
68 *reg = reinterpret_cast<viennashe_quan_register>(int_reg);
69 }
70 catch (...)
71 {
72 viennashe::log::error() << "ERROR: viennashe_create_quantity_register(): UNKOWN ERROR!" << std::endl;
73 return -1;
74 }
75 return 0;
76}
77
79{
80 try
81 {
82 if (reg != NULL)
83 {
84 delete reinterpret_cast<libviennashe::quan_register_internal *>(reg);
85 }
86 }
87 catch (...)
88 {
89 viennashe::log::error() << "ERROR: viennashe_free_quantity_register(): UNKOWN ERROR!" << std::endl;
90 return -1;
91 }
92 return 0;
93}
94
95
97{
98 try
99 {
101 CHECK_ARGUMENT_FOR_NULL(num,2,"num");
102
104 *num = static_cast<viennashe_index_type>(int_reg->cell_based.size());
105 }
106 catch (...)
107 {
108 viennashe::log::error() << "ERROR: viennashe_get_num_vertex_based(): UNKOWN ERROR!" << std::endl;
109 return -1;
110 }
111 return 0;
112}
113
114
116{
117 try
118 {
120 CHECK_ARGUMENT_FOR_NULL(names,2,"names");
121
123 std::vector<std::string> vnames = int_reg->cell_based.get_names();
124 for (std::size_t i = 0; i < vnames.size(); ++i)
125 {
126 // No "new" statement here ... since valgrind would complain ...
127 names[i] = (char*) malloc(sizeof(char) * (vnames[i].size()+1));
128 std::strncpy(names[i], vnames[i].c_str(), vnames[i].size()+1);
129 }
130 }
131 catch (...)
132 {
133 viennashe::log::error() << "ERROR: viennashe_get_vertex_based_quantity_list(): UNKOWN ERROR!" << std::endl;
134 return -1;
135 }
136 return 0;
137}
138
140{
141 try
142 {
144 CHECK_ARGUMENT_FOR_NULL(name,2,"name");
145 CHECK_ARGUMENT_FOR_NULL(exists,3,"exists");
146
148
149 // Translate bool to LIBVIENNASHE_BOOL "by hand" just to be sure
150 if(int_reg->cell_based.has_quan(std::string(name)) == true)
151 *exists = libviennashe_true;
152 else
153 *exists = libviennashe_false;
154
155 }
156 catch (...)
157 {
158 viennashe::log::error() << "ERROR: viennashe_get_vertex_based_quantity(): UNKOWN ERROR!" << std::endl;
159 return -1;
160 }
161 return 0;
162}
163
165{
166 try
167 {
169 CHECK_ARGUMENT_FOR_NULL(name,2,"name");
170 CHECK_ARGUMENT_FOR_NULL(values,3,"values");
171 CHECK_ARGUMENT_FOR_NULL(len,4,"len");
172
174
175 if (!int_reg->cell_based.has_quan(std::string(name)))
176 {
177 viennashe::log::error() << "ERROR: viennashe_get_vertex_based_quantity(): The quantity '" << name << "' does not exist." << std::endl;
178 return 2;
179 }
180 // fill value array
181 int_reg->cell_based.get(std::string(name)).fill(values, len);
182
183 }
184 catch (...)
185 {
186 viennashe::log::error() << "ERROR: viennashe_get_vertex_based_quantity(): UNKOWN ERROR!" << std::endl;
187 return -1;
188 }
189 return 0;
190}
191
192
194 double ** energies, double ** values, viennashe_index_type * len)
195{
196 try
197 {
199 CHECK_ARGUMENT_FOR_NULL(len,5,"len");
200 CHECK_ARGUMENT_FOR_NULL(energies,3,"energies");
201 CHECK_ARGUMENT_FOR_NULL(values,4,"values");
202
204 // Get simulator
205 viennashe_simulator_impl * int_sim = int_reg->int_sim;
206 if (!int_sim->is_valid())
207 {
208 viennashe::log::error() << "ERROR! viennashe_get_she_edf(): The simulator (sim) must be valid!" << std::endl;
209 return 1;
210 }
211
213
215 libviennashe::she_fill_edf(*(int_reg->int_sim->sim1d), arg_ctype, energies, values, len);
217 libviennashe::she_fill_edf(*(int_reg->int_sim->simq2d), arg_ctype, energies, values, len);
218 else if (int_sim->stype == libviennashe::meshtype::triangular_2d)
219 libviennashe::she_fill_edf(*(int_reg->int_sim->simt2d), arg_ctype, energies, values, len);
220 else if (int_sim->stype == libviennashe::meshtype::hexahedral_3d)
221 libviennashe::she_fill_edf(*(int_reg->int_sim->simh3d), arg_ctype, energies, values, len);
223 libviennashe::she_fill_edf(*(int_reg->int_sim->simt3d), arg_ctype, energies, values, len);
224 else
225 {
226 viennashe::log::error() << "ERROR! viennashe_get_she_edf(): Malconfigured simulator!" << std::endl;
227 return 2;
228 }
229
230
231 }
232 catch (...)
233 {
234 viennashe::log::error() << "ERROR: viennashe_get_she_edf(): UNKOWN ERROR!" << std::endl;
235 return -1;
236 }
237 return 0;
238}
239
241 double ** energies, double ** values, viennashe_index_type * len)
242{
243 try
244 {
245 if (reg == NULL)
246 {
247 viennashe::log::error() << "ERROR: viennashe_get_she_dos(): The register pointer (reg) must not be NULL." << std::endl;
248 return 1;
249 }
250 if (len == NULL) { return 5; }
251 if (energies == NULL) { return 3; }
252 if (values == NULL) { return 4; }
254 // Get simulator
255 viennashe_simulator_impl * int_sim = int_reg->int_sim;
256 if (!int_sim->is_valid())
257 {
258 viennashe::log::error() << "ERROR! viennashe_get_she_dos(): The simulator (sim) must be valid!" << std::endl;
259 return 1;
260 }
261
263
265 libviennashe::she_fill_dos(*(int_reg->int_sim->sim1d), arg_ctype, energies, values, len);
267 libviennashe::she_fill_dos(*(int_reg->int_sim->simq2d), arg_ctype, energies, values, len);
268 else if (int_sim->stype == libviennashe::meshtype::triangular_2d)
269 libviennashe::she_fill_dos(*(int_reg->int_sim->simt2d), arg_ctype, energies, values, len);
270 else if (int_sim->stype == libviennashe::meshtype::hexahedral_3d)
271 libviennashe::she_fill_dos(*(int_reg->int_sim->simh3d), arg_ctype, energies, values, len);
273 libviennashe::she_fill_dos(*(int_reg->int_sim->simt3d), arg_ctype, energies, values, len);
274 else
275 {
276 viennashe::log::error() << "ERROR! viennashe_get_she_dos(): Malconfigured simulator!" << std::endl;
277 return 2;
278 }
279
280
281 }
282 catch (...)
283 {
284 viennashe::log::error() << "ERROR: viennashe_get_she_dos(): UNKOWN ERROR!" << std::endl;
285 return -1;
286 }
287 return 0;
288}
289
291 double ** energies, double ** values, viennashe_index_type * len)
292{
293 try
294 {
296 CHECK_ARGUMENT_FOR_NULL(len,5,"len");
297 CHECK_ARGUMENT_FOR_NULL(energies,3,"energies");
298 CHECK_ARGUMENT_FOR_NULL(values,4,"values");
299
301 // Get simulator
302 viennashe_simulator_impl * int_sim = int_reg->int_sim;
303 if (!int_sim->is_valid())
304 {
305 viennashe::log::error() << "ERROR! viennashe_get_she_group_velocity(): The simulator (sim) must be valid!" << std::endl;
306 return 1;
307 }
308
310
312 libviennashe::she_fill_group_velocity(*(int_reg->int_sim->sim1d), arg_ctype, energies, values, len);
314 libviennashe::she_fill_group_velocity(*(int_reg->int_sim->simq2d), arg_ctype, energies, values, len);
315 else if (int_sim->stype == libviennashe::meshtype::triangular_2d)
316 libviennashe::she_fill_group_velocity(*(int_reg->int_sim->simt2d), arg_ctype, energies, values, len);
317 else if (int_sim->stype == libviennashe::meshtype::hexahedral_3d)
318 libviennashe::she_fill_group_velocity(*(int_reg->int_sim->simh3d), arg_ctype, energies, values, len);
320 libviennashe::she_fill_group_velocity(*(int_reg->int_sim->simt3d), arg_ctype, energies, values, len);
321 else
322 {
323 viennashe::log::error() << "ERROR! viennashe_get_she_group_velocity(): Malconfigured simulator!" << std::endl;
324 return 2;
325 }
326
327
328 }
329 catch (...)
330 {
331 viennashe::log::error() << "ERROR: viennashe_get_she_group_velocity(): UNKOWN ERROR!" << std::endl;
332 return -1;
333 }
334 return 0;
335}
336
337
339{
340 try
341 {
343
344 viennashe_index_type num_vertices = 0;
345 if (viennashe_get_num_vertices(dev, &num_vertices) != 0 || num_vertices <= 0)
346 {
347 viennashe::log::error() << "ERROR: viennashe_prealloc_vertex_based_quantity(): The mesh is malconfigured." << std::endl;
348 return 1;
349 }
350
351 if ( *uarray == NULL )
352 {
353 // allocate
354 *uarray = new double*[num_vertices];
355 // NULLify
356 for (size_t i = 0; i < num_vertices; ++i)
357 {
358 (*uarray)[i] = NULL;
359 } // for each vertex
360 }
361 else
362 {
363 viennashe::log::error() << "ERROR: viennashe_prealloc_vertex_based_quantity(): The user array (uarray) is already preallocated (uarray != NULL)." << std::endl;
364 return 2;
365 }
366
367 if ( *len == NULL )
368 {
369 // allocate
370 *len = new viennashe_index_type[num_vertices];
371 // NULLify
372 for (size_t i = 0; i < num_vertices; ++i)
373 {
374 (*len)[i] = 0;
375 } // for each vertex
376 }
377 else
378 {
379 viennashe::log::error() << "ERROR: viennashe_prealloc_vertex_based_quantity(): The user array (len) is already preallocated (len != NULL)." << std::endl;
380 return 3;
381 }
382
383
384 }
385 catch (...)
386 {
387 viennashe::log::error() << "ERROR: viennashe_prealloc_vertex_based_quantity(): UNKOWN ERROR!" << std::endl;
388 return -1;
389 }
390 return 0;
391}
392
393
395{
396 try
397 {
399
400 viennashe_index_type num_vertices = 0;
401 if (viennashe_get_num_vertices(dev, &num_vertices) != 0 || num_vertices <= 0)
402 {
403 viennashe::log::error() << "ERROR: viennashe_free_vertex_based_quantity(): The mesh is malconfigured." << std::endl;
404 return 1;
405 }
406
407 if ((*uarray) != NULL)
408 {
409 for (size_t i = 0; i < num_vertices; ++i)
410 {
411 if ((*uarray)[i] != NULL)
412 {
413 delete (*uarray)[i];
414 (*uarray)[i] = NULL;
415 }
416 } // for each vertex
417 delete *uarray;
418 *uarray = NULL;
419 }
420
421 if ((*len) != NULL)
422 {
423 delete *len;
424 *len = NULL;
425 }
426 }
427 catch (...)
428 {
429 viennashe::log::error() << "ERROR: viennashe_free_vertex_based_quantity(): UNKOWN ERROR!" << std::endl;
430 return -1;
431 }
432 return 0;
433}
434
435
436#ifdef __cplusplus
437}
438#endif
439
440
quantity_wrapper const & get(std::string const &name) const
Returns a single const reference to a quantitiy wrapper.
bool has_quan(std::string const &name) const
Returns true if a quantity is registered.
std::size_t size() const
Returns the number of registered quantities.
std::vector< std::string > get_names() const
Returns all names of the registered quantities.
virtual void fill(double **values, viennashe_index_type *len) const =0
Interface. Fills values with all quantity values, where the length of values[i] is to be found in len...
VIENNASHE_EXPORT viennasheErrorCode viennashe_get_num_vertices(viennashe_device dev, viennashe_index_type *num)
int viennasheErrorCode
Definition: error.h:25
void she_fill_dos(SimulatorT const &sim, viennashe::carrier_type_id ctype, double **ekin, double **dos, viennashe_index_type *len)
Fills the given C-arrays ekin and dos with the DOS for every vertex.
void she_fill_group_velocity(SimulatorT const &sim, viennashe::carrier_type_id ctype, double **ekin, double **vg, viennashe_index_type *len)
Fills the given C-arrays ekin and vg with the group velocity for every vertex.
void register_quans(SimulatorT const &sim, quan_register_internal &reg)
Main quantity regsiter function. Add your simulator quantities here.
void she_fill_edf(SimulatorT const &sim, viennashe::carrier_type_id ctype, double **ekin, double **edf, viennashe_index_type *len)
Fills the given C-arrays with the complete EDF.
reg
This is DD, so we do not need to give any inital guess.
Definition: resistor.py:84
logger< true > error()
Used to log errors. The logging level is logERROR.
Definition: log.hpp:301
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
viennashe_quan_register_impl * viennashe_quan_register
Definition: quantity.h:31
VIENNASHE_EXPORT viennasheErrorCode viennashe_free_quantity_register(viennashe_quan_register reg)
VIENNASHE_EXPORT viennasheErrorCode viennashe_get_she_dos(viennashe_quan_register reg, viennashe_carrier_ids ctype, double **energies, double **values, viennashe_index_type *len)
VIENNASHE_EXPORT viennasheErrorCode viennashe_has_cell_based_quantity(viennashe_quan_register reg, char const *name, libviennashe_bool *exists)
VIENNASHE_EXPORT viennasheErrorCode viennashe_create_quantity_register(viennashe_quan_register *reg, viennashe_simulator sim)
VIENNASHE_EXPORT viennasheErrorCode viennashe_get_cell_based_quantity_list(viennashe_quan_register reg, char **names)
VIENNASHE_EXPORT viennasheErrorCode viennashe_get_cell_based_quantity(viennashe_quan_register reg, char const *name, double **values, viennashe_index_type *len)
VIENNASHE_EXPORT viennasheErrorCode viennashe_get_she_group_velocity(viennashe_quan_register reg, viennashe_carrier_ids ctype, double **energies, double **values, viennashe_index_type *len)
VIENNASHE_EXPORT viennasheErrorCode viennashe_prealloc_cell_based_quantity(viennashe_device dev, double ***uarray, viennashe_index_type **len)
viennashe_carrier_ids
Enum of available charge carrier types.
Definition: quantity.h:34
@ viennashe_electron_id
Definition: quantity.h:34
VIENNASHE_EXPORT viennasheErrorCode viennashe_free_cell_based_quantity(viennashe_device dev, double ***uarray, viennashe_index_type **len)
VIENNASHE_EXPORT viennasheErrorCode viennashe_get_num_cell_based(viennashe_quan_register reg, viennashe_index_type *num)
VIENNASHE_EXPORT viennasheErrorCode viennashe_get_she_edf(viennashe_quan_register reg, viennashe_carrier_ids ctype, double **energies, double **values, viennashe_index_type *len)
Common routines for the registry of simulator dependent quantities.
Routines to wrap ViennaSHE quantities (doping, potential, distribution functions, ....
C++ to C wrapper of the quantity registry.
libviennashe::quantity::quantitiy_register cell_based
viennashe_simulator_impl * int_sim
Register for vertex based quantities.
Internal C++ to C wrapper for the device. Has typedefs and destructor.
Internal C++ to C wrapper for the simulator. Has typedefs and destructor.
libviennashe_bool
Definition: sys.h:31
@ libviennashe_false
Definition: sys.h:31
@ libviennashe_true
Definition: sys.h:31
unsigned long viennashe_index_type
Definition: sys.h:42
#define VIENNASHE_EXPORT
Definition: sys.h:19
Contains all viennashe includes and most of the C++/C-wrappers. Contains macros.
#define CHECK_ARGUMENT_FOR_NULL(arg, pos, name)