ViennaSHE 1.3.0
Free open-source semiconductor device simulator using spherical harmonics expansions techniques.
device.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
23
24
25namespace libviennashe
26{
27
28 template < typename DeviceT >
29 void get_vertices_on_cell(DeviceT const & device,
31 viennashe_index_type * vertex_ids
32 )
33 {
34 typedef typename DeviceT::mesh_type MeshType;
35 typedef typename viennagrid::result_of::cell<MeshType>::type CellType;
36 typedef typename viennagrid::result_of::const_cell_range<MeshType>::type CellContainer;
37 typedef typename viennagrid::result_of::const_vertex_range<CellType>::type VertexOnCellContainer;
38 typedef typename viennagrid::result_of::iterator<VertexOnCellContainer>::type VertexOnCellIterator;
39
40 CellContainer cells(device.mesh());
41
42 if (vertex_ids == 0) throw std::invalid_argument("vertices = NULL !");
43 if (/*cell_id < 0 ||*/ cell_id >= cells.size()) throw std::invalid_argument("cell_id invalid !");
44
45
46 VertexOnCellContainer vertices_on_cell(cells[cell_id]);
47 std::size_t j = 0;
48 for (VertexOnCellIterator vit = vertices_on_cell.begin(); vit != vertices_on_cell.end(); ++vit, ++j)
49 {
50 vertex_ids[j] = static_cast<viennashe_index_type>(vit->id().get());
51 }
52
53 } // dump_mesh
54
55
63 template < typename DeviceT >
64 void initalize_device(DeviceT & device, long * material_ids, double * doping_n, double * doping_p)
65 {
66 typedef typename DeviceT::mesh_type MeshType;
67
68 typedef typename viennagrid::result_of::const_cell_range<MeshType>::type CellContainer;
69
70 CellContainer cells = viennagrid::cells(device.mesh());
71
72 for (std::size_t i = 0; i < cells.size(); ++i)
73 {
74 device.set_material(material_ids[i], cells[i]);
75
76 if (doping_n[i] < 0)
77 {
78 viennashe::log::warn() << "initalize_device(): Warning! The donor doping must be greater zero. doping_n[" << i << "] = " << doping_n[i] << std::endl;
79 }
80 else if (doping_p[i] < 0)
81 {
82 viennashe::log::warn() << "initalize_device(): Warning! The acceptor doping must be greater zero. doping_p[" << i << "] = " << doping_p[i] << std::endl;
83 }
84 else
85 {
86 // Zero doping means do not set !
87 if (doping_n[i]) device.set_doping_n(doping_n[i], cells[i]);
88 if (doping_p[i]) device.set_doping_p(doping_p[i], cells[i]);
89 }
90 }
91
92 } // initalize_device
93
101 template < typename DeviceT >
102 void set_contact_potential(DeviceT & device, viennashe_index_type * cell_ids, double * values, viennashe_index_type len)
103 {
104 typedef typename DeviceT::mesh_type MeshType;
105
106 typedef typename viennagrid::result_of::const_cell_range<MeshType>::type CellContainer;
107
108 CellContainer cells(device.mesh());
109
110 for (std::size_t i = 0; i < len; ++i)
111 {
112 const viennashe_index_type id = cell_ids[i];
113 if (id < cells.size())
114 device.set_contact_potential(values[i], cells[id] );
115 else
116 viennashe::log::warn() << "WARNING! set_contact_potential(): Invalid cell id '" << id << "' ... skipping!" << std::endl;
117 }
118
119 } // initalize_device
120
127 template < typename DeviceT >
128 void set_contact_potential(DeviceT & device, viennashe_index_type segment_id, double value)
129 {
130 if (segment_id < device.segmentation().size())
131 device.set_contact_potential(value, device.segment(static_cast<int>(segment_id)));
132 else
133 viennashe::log::warn() << "WARNING! set_contact_potential(): Invalid segment id '" << segment_id << "' ... skipping!" << std::endl;
134
135 } // initalize_device
136
137} // namespace libviennashe
138
139#ifdef __cplusplus
140extern "C" {
141#endif
142
143
145{
146 try
147 {
149
150 //
151 // CHECKS
152 CHECK_ARGUMENT_FOR_NULL(dev, 1, "dev");
153 if (len_x <= 0.0)
154 {
155 viennashe::log::error() << "ERROR! viennashe_create_1d_device(): len_x must be greater zero. len_x = " << len_x << std::endl;
156 return 2;
157 }
158 if (points_x == 0)
159 {
160 viennashe::log::error() << "ERROR! viennashe_create_1d_device(): points_x must be greater zero. points_x = " << points_x << std::endl;
161 return 3;
162 }
163
164 //
165 // Generate device
168
170 generator_params.add_segment(0.0, len_x, static_cast<unsigned long>(points_x));
171 int_dev->device_1d->generate_mesh(generator_params);
172
173 *dev = int_dev;
174 }
175 catch(...)
176 {
177 viennashe::log::error() << "ERROR! viennashe_create_1d_device(): UNKOWN ERROR!" << std::endl;
178 return -1;
179 }
180 return 0;
181}
182
183
185{
186 try
187 {
188 if (dev != NULL)
189 {
190 delete (dev);
191 }
192 }
193 catch(...)
194 {
195 viennashe::log::error() << "ERROR! free_device(): UNKOWN ERROR!" << std::endl;
196 return -1;
197 }
198 return 0;
199}
200
201viennasheErrorCode viennashe_initalize_device(viennashe_device dev, viennashe_material_id * material_ids, double * doping_n, double * doping_p)
202{
203 try
204 {
205 //
206 // Checks
208 if (doping_n == 0 || doping_p == 0 || material_ids == 0)
209 {
210 viennashe::log::error() << "ERROR! initalize_device(): The arrays material_ids, doping_n and doping_p must be arrays " << std::endl;
211 return 2;
212 }
213
214 viennashe_device_impl * int_dev = (dev);
215
216 if (int_dev->device_1d == NULL)
217 {
218 viennashe::log::error() << "ERROR! initalize_device(): The device must exist!" << std::endl;
219 return 1;
220 }
221
222 switch (int_dev->stype)
223 {
224 case libviennashe::meshtype::line_1d: libviennashe::initalize_device(*int_dev->device_1d, material_ids, doping_n, doping_p); break;
225 case libviennashe::meshtype::quadrilateral_2d: libviennashe::initalize_device(*int_dev->device_quad_2d, material_ids, doping_n, doping_p); break;
226 case libviennashe::meshtype::triangular_2d: libviennashe::initalize_device(*int_dev->device_tri_2d, material_ids, doping_n, doping_p); break;
227 case libviennashe::meshtype::hexahedral_3d: libviennashe::initalize_device(*int_dev->device_hex_3d, material_ids, doping_n, doping_p); break;
228 case libviennashe::meshtype::tetrahedral_3d: libviennashe::initalize_device(*int_dev->device_tet_3d, material_ids, doping_n, doping_p); break;
229 default:
230 viennashe::log::error() << "ERROR! initalize_device(): UNKOWN DEVICE TYPE!" << std::endl;
231 return -1;
232 }
233 }
234 catch(...)
235 {
236 viennashe::log::error() << "ERROR! initalize_device(): UNKOWN ERROR!" << std::endl;
237 return -1;
238 }
239 return 0;
240}
241
243{
244 try
245 {
246 //
247 // Checks
249 if (material_id < 0)
250 {
251 viennashe::log::error() << "ERROR! viennashe_set_material_on_segment(): The material_id needs to be greater zero. material_id = " << material_id << std::endl;
252 return 2;
253 }
254
255 viennashe_device_impl * int_dev = (dev);
256
257 if (int_dev->device_1d == NULL)
258 {
259 viennashe::log::error() << "ERROR! viennashe_set_material_on_segment(): The device must exist!" << std::endl;
260 return 1;
261 }
262
263 switch (int_dev->stype)
264 {
265 case libviennashe::meshtype::line_1d: int_dev->device_1d->set_material(material_id, static_cast<int>(segment_id)); break;
266 case libviennashe::meshtype::quadrilateral_2d: int_dev->device_quad_2d->set_material(material_id, static_cast<int>(segment_id)); break;
267 case libviennashe::meshtype::triangular_2d: int_dev->device_tri_2d->set_material(material_id, static_cast<int>(segment_id)); break;
268 case libviennashe::meshtype::hexahedral_3d: int_dev->device_hex_3d->set_material(material_id, static_cast<int>(segment_id)); break;
269 case libviennashe::meshtype::tetrahedral_3d: int_dev->device_tet_3d->set_material(material_id, static_cast<int>(segment_id)); break;
270 default:
271 viennashe::log::error() << "ERROR! initalize_device(): UNKOWN DEVICE TYPE!" << std::endl;
272 return -1;
273 }
274 }
275 catch(...)
276 {
277 viennashe::log::error() << "ERROR! viennashe_set_material_on_segment(): UNKOWN ERROR!" << std::endl;
278 return -1;
279 }
280 return 0;
281}
282
284{
285 try
286 {
287 //
288 // Checks
290 if (doping_n < 0)
291 {
292 viennashe::log::error() << "ERROR! viennashe_set_doping_n_on_segment(): The doping_n needs to be greater zero. doping_n = " << doping_n << std::endl;
293 return 2;
294 }
295
296 viennashe_device_impl * int_dev = (dev);
297
298 if (int_dev->device_1d == NULL)
299 {
300 viennashe::log::error() << "ERROR! viennashe_set_doping_n_on_segment(): The device must exist!" << std::endl;
301 return 1;
302 }
303
304 switch (int_dev->stype)
305 {
306 case libviennashe::meshtype::line_1d: int_dev->device_1d->set_doping_n(doping_n, static_cast<int>(segment_id)); break;
307 case libviennashe::meshtype::quadrilateral_2d: int_dev->device_quad_2d->set_doping_n(doping_n, static_cast<int>(segment_id)); break;
308 case libviennashe::meshtype::triangular_2d: int_dev->device_tri_2d->set_doping_n(doping_n, static_cast<int>(segment_id)); break;
309 case libviennashe::meshtype::hexahedral_3d: int_dev->device_hex_3d->set_doping_n(doping_n, static_cast<int>(segment_id)); break;
310 case libviennashe::meshtype::tetrahedral_3d: int_dev->device_tet_3d->set_doping_n(doping_n, static_cast<int>(segment_id)); break;
311 default:
312 viennashe::log::error() << "ERROR! viennashe_set_doping_n_on_segment(): UNKOWN DEVICE TYPE!" << std::endl;
313 return -1;
314 }
315
316 }
317 catch(...)
318 {
319 viennashe::log::error() << "ERROR! viennashe_set_doping_n_on_segment(): UNKOWN ERROR!" << std::endl;
320 return -1;
321 }
322 return 0;
323}
324
326{
327 try
328 {
329 //
330 // Checks
332 if (doping_p < 0)
333 {
334 viennashe::log::error() << "ERROR! viennashe_set_doping_p_on_segment(): The doping_p needs to be greater zero. doping_p = " << doping_p << std::endl;
335 return 2;
336 }
337
338 viennashe_device_impl * int_dev = (dev);
339
340 if (int_dev->device_1d == NULL)
341 {
342 viennashe::log::error() << "ERROR! viennashe_set_doping_p_on_segment(): The device must exist!" << std::endl;
343 return 1;
344 }
345
346 switch (int_dev->stype)
347 {
348 case libviennashe::meshtype::line_1d: int_dev->device_1d->set_doping_p(doping_p, static_cast<int>(segment_id)); break;
349 case libviennashe::meshtype::quadrilateral_2d: int_dev->device_quad_2d->set_doping_p(doping_p, static_cast<int>(segment_id)); break;
350 case libviennashe::meshtype::triangular_2d: int_dev->device_tri_2d->set_doping_p(doping_p, static_cast<int>(segment_id)); break;
351 case libviennashe::meshtype::hexahedral_3d: int_dev->device_hex_3d->set_doping_p(doping_p, static_cast<int>(segment_id)); break;
352 case libviennashe::meshtype::tetrahedral_3d: int_dev->device_tet_3d->set_doping_p(doping_p, static_cast<int>(segment_id)); break;
353 default:
354 viennashe::log::error() << "ERROR! viennashe_set_doping_p_on_segment(): UNKOWN DEVICE TYPE!" << std::endl;
355 return -1;
356 }
357
358 }
359 catch(...)
360 {
361 viennashe::log::error() << "ERROR! viennashe_set_doping_p_on_segment(): UNKOWN ERROR!" << std::endl;
362 return -1;
363 }
364 return 0;
365}
366
368{
369 try
370 {
371 //
372 // Checks
374 CHECK_ARGUMENT_FOR_NULL(cell_ids,2,"cell_ids");
375 CHECK_ARGUMENT_FOR_NULL(values,3,"values");
376
377 viennashe_device_impl * int_dev = (dev);
378
379 if (int_dev->device_1d == NULL)
380 {
381 viennashe::log::error() << "ERROR! set_contact_potential(): The device must exist!" << std::endl;
382 return 1;
383 }
384
385 switch (int_dev->stype)
386 {
387 case libviennashe::meshtype::line_1d: libviennashe::set_contact_potential(*int_dev->device_1d, cell_ids, values, len); break;
388 case libviennashe::meshtype::quadrilateral_2d: libviennashe::set_contact_potential(*int_dev->device_quad_2d, cell_ids, values, len); break;
389 case libviennashe::meshtype::triangular_2d: libviennashe::set_contact_potential(*int_dev->device_tri_2d, cell_ids, values, len); break;
390 case libviennashe::meshtype::hexahedral_3d: libviennashe::set_contact_potential(*int_dev->device_hex_3d, cell_ids, values, len); break;
391 case libviennashe::meshtype::tetrahedral_3d: libviennashe::set_contact_potential(*int_dev->device_tet_3d, cell_ids, values, len); break;
392 default:
393 viennashe::log::error() << "ERROR! initalize_device(): UNKOWN DEVICE TYPE!" << std::endl;
394 return -1;
395 }
396 }
397 catch(...)
398 {
399 viennashe::log::error() << "ERROR! viennashe_set_contact_potential_cells(): UNKOWN ERROR!" << std::endl;
400 return 1;
401 }
402 return 0;
403}
404
406{
407 try
408 {
409 //
410 // Checks
412
413 viennashe_device_impl * int_dev = (dev);
414
415 if (int_dev->device_1d == NULL)
416 {
417 viennashe::log::error() << "ERROR! set_contact_potential(): The device must exist!" << std::endl;
418 return 1;
419 }
420
421 switch (int_dev->stype)
422 {
423 case libviennashe::meshtype::line_1d: libviennashe::set_contact_potential(*int_dev->device_1d, segment_id, value); break;
424 case libviennashe::meshtype::quadrilateral_2d: libviennashe::set_contact_potential(*int_dev->device_quad_2d, segment_id, value); break;
425 case libviennashe::meshtype::triangular_2d: libviennashe::set_contact_potential(*int_dev->device_tri_2d, segment_id, value); break;
426 case libviennashe::meshtype::hexahedral_3d: libviennashe::set_contact_potential(*int_dev->device_hex_3d, segment_id, value); break;
427 case libviennashe::meshtype::tetrahedral_3d: libviennashe::set_contact_potential(*int_dev->device_tet_3d, segment_id, value); break;
428 default:
429 viennashe::log::error() << "ERROR! initalize_device(): UNKOWN DEVICE TYPE!" << std::endl;
430 return -1;
431 }
432 }
433 catch(...)
434 {
435 viennashe::log::error() << "ERROR! set_contact_potential(): UNKOWN ERROR!" << std::endl;
436 return 1;
437 }
438 return 0;
439}
440
442{
443 try
444 {
445 //
446 // CHECKS
448 CHECK_ARGUMENT_FOR_NULL(num,2,"num");
449
450 viennashe_device_impl * int_dev = (dev);
451
453 *num = static_cast<viennashe_index_type>(viennagrid::vertices(int_dev->device_1d->mesh()).size());
455 *num = static_cast<viennashe_index_type>(viennagrid::vertices(int_dev->device_quad_2d->mesh()).size());
457 *num = static_cast<viennashe_index_type>(viennagrid::vertices(int_dev->device_tri_2d->mesh()).size());
459 *num = static_cast<viennashe_index_type>(viennagrid::vertices(int_dev->device_hex_3d->mesh()).size());
461 *num = static_cast<viennashe_index_type>(viennagrid::vertices(int_dev->device_tet_3d->mesh()).size());
462
463 }
464 catch(...)
465 {
466 viennashe::log::error() << "ERROR! get_num_vertices(): UNKOWN ERROR!" << std::endl;
467 return -1;
468 }
469 return 0;
470}
471
473{
474 try
475 {
476 //
477 // CHECKS
479 CHECK_ARGUMENT_FOR_NULL(num,2,"num");
480
481 viennashe_device_impl * int_dev = (dev);
482
484 *num = static_cast<viennashe_index_type>(viennagrid::cells(int_dev->device_1d->mesh()).size());
486 *num = static_cast<viennashe_index_type>(viennagrid::cells(int_dev->device_quad_2d->mesh()).size());
488 *num = static_cast<viennashe_index_type>(viennagrid::cells(int_dev->device_tri_2d->mesh()).size());
490 *num = static_cast<viennashe_index_type>(viennagrid::cells(int_dev->device_hex_3d->mesh()).size());
492 *num = static_cast<viennashe_index_type>(viennagrid::cells(int_dev->device_tet_3d->mesh()).size());
493 }
494 catch(...)
495 {
496 viennashe::log::error() << "ERROR! get_num_cells(): UNKOWN ERROR!" << std::endl;
497 return -1;
498 }
499 return 0;
500}
501
503{
504 try
505 {
506 //
507 // CHECKS
509 CHECK_ARGUMENT_FOR_NULL(num,2,"num");
510
511 viennashe_device_impl * int_dev = (dev);
512
514 *num = static_cast<viennashe_index_type>(int_dev->device_1d->segmentation().size());
516 *num = static_cast<viennashe_index_type>(int_dev->device_quad_2d->segmentation().size());
518 *num = static_cast<viennashe_index_type>(int_dev->device_tri_2d->segmentation().size());
520 *num = static_cast<viennashe_index_type>(int_dev->device_hex_3d->segmentation().size());
522 *num = static_cast<viennashe_index_type>(int_dev->device_tet_3d->segmentation().size());
523 }
524 catch(...)
525 {
526 viennashe::log::error() << "ERROR! get_num_segments(): UNKOWN ERROR!" << std::endl;
527 return -1;
528 }
529 return 0;
530}
531
533{
534 try
535 {
536 //
537 // CHECKS
539 CHECK_ARGUMENT_FOR_NULL(num,3,"num");
540
541
542 viennashe_index_type num_seg = 0;
544 //
545 viennashe_device_impl * int_dev = (dev);
546
548 *num = static_cast<viennashe_index_type>(viennagrid::vertices(int_dev->device_1d->segmentation()[static_cast<int>(segment_id)]).size());
550 *num = static_cast<viennashe_index_type>(viennagrid::vertices(int_dev->device_quad_2d->segmentation()[static_cast<int>(segment_id)]).size());
552 *num = static_cast<viennashe_index_type>(viennagrid::vertices(int_dev->device_tri_2d->segmentation()[static_cast<int>(segment_id)]).size());
554 *num = static_cast<viennashe_index_type>(viennagrid::vertices(int_dev->device_hex_3d->segmentation()[static_cast<int>(segment_id)]).size());
556 *num = static_cast<viennashe_index_type>(viennagrid::vertices(int_dev->device_tet_3d->segmentation()[static_cast<int>(segment_id)]).size());
557 }
558 catch(...)
559 {
560 viennashe::log::error() << "ERROR! get_num_vertices_on_segment(): UNKOWN ERROR!" << std::endl;
561 return -1;
562 }
563 return 0;
564}
565
567{
568 try
569 {
570 //
571 // CHECKS
573 CHECK_ARGUMENT_FOR_NULL(num,3,"num");
574
575 viennashe_index_type num_seg = 0;
577 //
578 viennashe_device_impl * int_dev = (dev);
579
581 *num = static_cast<viennashe_index_type>(viennagrid::cells(int_dev->device_1d->segmentation()[static_cast<int>(segment_id)]).size());
583 *num = static_cast<viennashe_index_type>(viennagrid::cells(int_dev->device_quad_2d->segmentation()[static_cast<int>(segment_id)]).size());
585 *num = static_cast<viennashe_index_type>(viennagrid::cells(int_dev->device_tri_2d->segmentation()[static_cast<int>(segment_id)]).size());
587 *num = static_cast<viennashe_index_type>(viennagrid::cells(int_dev->device_hex_3d->segmentation()[static_cast<int>(segment_id)]).size());
589 *num = static_cast<viennashe_index_type>(viennagrid::cells(int_dev->device_tet_3d->segmentation()[static_cast<int>(segment_id)]).size());
590 }
591 catch(...)
592 {
593 viennashe::log::error() << "ERROR! get_num_cells_on_segment(): UNKOWN ERROR!" << std::endl;
594 return -1;
595 }
596 return 0;
597}
598
600{
601 try
602 {
603 //
604 // CHECKS
606 CHECK_ARGUMENT_FOR_NULL(dim,2,"dim");
607
608 viennashe_device_impl * int_dev = (dev);
609
610 if (int_dev->stype == libviennashe::meshtype::line_1d) *dim = 1;
611 if (int_dev->stype == libviennashe::meshtype::quadrilateral_2d) *dim = 2;
612 if (int_dev->stype == libviennashe::meshtype::triangular_2d) *dim = 2;
613 if (int_dev->stype == libviennashe::meshtype::hexahedral_3d) *dim = 3;
614 if (int_dev->stype == libviennashe::meshtype::tetrahedral_3d) *dim = 3;
615 }
616 catch(...)
617 {
618 viennashe::log::error() << "ERROR! viennashe_get_dimension(): UNKOWN ERROR!" << std::endl;
619 return -1;
620 }
621 return 0;
622}
623
625{
626 try
627 {
628 //
629 // CHECKS
631 CHECK_ARGUMENT_FOR_NULL(num,2,"num");
632
633 viennashe_device_impl * int_dev = (dev);
634
635 if (int_dev->stype == libviennashe::meshtype::line_1d) *num = 2;
636 if (int_dev->stype == libviennashe::meshtype::quadrilateral_2d) *num = 4;
637 if (int_dev->stype == libviennashe::meshtype::triangular_2d) *num = 3;
638 if (int_dev->stype == libviennashe::meshtype::hexahedral_3d) *num = 6;
639 if (int_dev->stype == libviennashe::meshtype::tetrahedral_3d) *num = 4;
640 }
641 catch(...)
642 {
643 viennashe::log::error() << "ERROR! viennashe_get_num_vertices_per_cell(): UNKOWN ERROR!" << std::endl;
644 return -1;
645 }
646 return 0;
647}
648
649
651 double ** vertices, viennashe_index_type num_vertices,
653 viennashe_index_type * segmentation)
654{
655 try
656 {
657 //
658 // CHECKS
660 CHECK_ARGUMENT_FOR_NULL(vertices,3,"vertices");
661 CHECK_ARGUMENT_FOR_NULL(cells,5,"cells");
662
664
665 viennashe::util::device_from_array_generator<viennashe_index_type> gen(vertices, cells, segmentation, num_vertices, num_cells);
666
667 if (topology_id == viennashe_line_1d)
668 {
671 int_dev->device_1d->generate_mesh(gen);
672 }
673 else if (topology_id == viennashe_quadrilateral_2d)
674 {
677 int_dev->device_quad_2d->generate_mesh(gen);
678 }
679 else if (topology_id == viennashe_triangular_2d)
680 {
683 int_dev->device_tri_2d->generate_mesh(gen);
684 }
685 else if (topology_id == viennashe_hexahedral_3d)
686 {
689 int_dev->device_hex_3d->generate_mesh(gen);
690 }
691 else if (topology_id == viennashe_tetrahedral_3d)
692 {
695 int_dev->device_tet_3d->generate_mesh(gen);
696 }
697 else
698 {
699 viennashe::log::error() << "ERROR! viennashe_create_device(): Invalid topolgy id !" << std::endl;
700 return 2;
701 }
702
703 // RETURN
704 *dev = int_dev;
705
706 }
707 catch(...)
708 {
709 viennashe::log::error() << "ERROR! viennashe_create_device(): UNKOWN ERROR!" << std::endl;
710 return -1;
711 }
712 return 0;
713}
714
715
716
718 double * vertices, viennashe_index_type num_vertices,
720 viennashe_index_type * segmentation)
721{
722 try
723 {
724 //
725 // CHECKS
727 CHECK_ARGUMENT_FOR_NULL(vertices,3,"vertices");
728 CHECK_ARGUMENT_FOR_NULL(cells,5,"cells");
729
731
732 viennashe::util::device_from_flat_array_generator<viennashe_index_type> gen(vertices, cells, segmentation, num_vertices, num_cells);
733
734 if (topology_id == viennashe_line_1d)
735 {
738 int_dev->device_1d->generate_mesh(gen);
739 }
740 else if (topology_id == viennashe_quadrilateral_2d)
741 {
744 int_dev->device_quad_2d->generate_mesh(gen);
745 }
746 else if (topology_id == viennashe_triangular_2d)
747 {
750 int_dev->device_tri_2d->generate_mesh(gen);
751 }
752 else if (topology_id == viennashe_hexahedral_3d)
753 {
756 int_dev->device_hex_3d->generate_mesh(gen);
757 }
758 else if (topology_id == viennashe_tetrahedral_3d)
759 {
762 int_dev->device_tet_3d->generate_mesh(gen);
763 }
764 else
765 {
766 viennashe::log::error() << "ERROR! viennashe_create_device_flat(): Invalid topolgy id !" << std::endl;
767 return 2;
768 }
769
770 // RETURN
771 *dev = int_dev;
772
773 }
774 catch(...)
775 {
776 viennashe::log::error() << "ERROR! viennashe_create_device_flat(): UNKOWN ERROR!" << std::endl;
777 return -1;
778 }
779 return 0;
780}
781
782
784{
785 try
786 {
787 //
788 // CHECKS
790 CHECK_ARGUMENT_FOR_NULL(filename,2,"filename");
791
793
794 if (topology_id == viennashe_line_1d)
795 {
798 int_dev->device_1d->load_mesh(std::string(filename));
799 }
800 else if (topology_id == viennashe_quadrilateral_2d)
801 {
804 int_dev->device_quad_2d->load_mesh(std::string(filename));
805 }
806 else if (topology_id == viennashe_triangular_2d)
807 {
810 int_dev->device_tri_2d->load_mesh(std::string(filename));
811 }
812 else if (topology_id == viennashe_hexahedral_3d)
813 {
816 int_dev->device_hex_3d->load_mesh(std::string(filename));
817 }
818 else if (topology_id == viennashe_tetrahedral_3d)
819 {
822 int_dev->device_tet_3d->load_mesh(std::string(filename));
823 }
824 else
825 {
826 viennashe::log::error() << "ERROR! viennashe_create_device_from_file(): Invalid topolgy id !" << std::endl;
827 return 2;
828 }
829
830 // RETURN
831 *dev = int_dev;
832
833 }
834 catch(std::exception const & ex)
835 {
836 viennashe::log::error() << "ERROR! viennashe_create_device_from_file(): " << ex.what() << std::endl;
837 return -1;
838 }
839 catch(...)
840 {
841 viennashe::log::error() << "ERROR! viennashe_create_device_from_file(): UNKOWN ERROR!" << std::endl;
842 return -1;
843 }
844 return 0;
845}
846
849{
850 try
851 {
852 //
853 // CHECKS
854 if (dev == NULL)
855 {
856 viennashe::log::error() << "ERROR! viennashe_get_grid(): Mesh must exist (dev != NULL) "<< std::endl;
857 return 1;
858 }
859 if (num_vertices == NULL || vertices == NULL)
860 {
861 viennashe::log::error() << "ERROR! viennashe_get_grid(): num_vertices must be valid. num_vertices = "
862 << num_vertices << " and vertices = " << vertices << std::endl;
863 return 2;
864 }
865 if (num_cells == NULL || cells == NULL)
866 {
867 viennashe::log::error() << "ERROR! viennashe_get_grid(): num_cells must be valid. num_cells = "
868 << num_cells << " and cells = " << cells << std::endl;
869 return 4;
870 }
871
872 // Check topology and set parameters and generate mesh
874 {
875 viennashe::util::dump_mesh(*(dev->device_1d), vertices, *num_vertices, cells, *num_cells);
876 }
878 {
879 viennashe::util::dump_mesh(*(dev->device_quad_2d), vertices, *num_vertices, cells, *num_cells);
880 }
882 {
883 viennashe::util::dump_mesh(*(dev->device_tri_2d), vertices, *num_vertices, cells, *num_cells);
884 }
886 {
887 viennashe::util::dump_mesh(*(dev->device_hex_3d), vertices, *num_vertices, cells, *num_cells);
888 }
890 {
891 viennashe::util::dump_mesh(*(dev->device_tet_3d), vertices, *num_vertices, cells, *num_cells);
892 }
893 else
894 {
895 viennashe::log::error() << "ERROR! viennashe_get_grid(): Unkown topology type or malconfigured device (dev)!" << std::endl;
896 return 1;
897 }
898
899 }
900 catch(...)
901 {
902 viennashe::log::error() << "ERROR! viennashe_get_grid(): UNKOWN ERROR!" << std::endl;
903 return -1;
904 }
905 return 0;
906} // viennashe_get_grid
907
908
909
911{
912 try
913 {
918
919 viennashe_index_type num_vertices = 0;
920 viennashe_get_num_vertices(dev, &num_vertices);
921
922 if ( static_cast<long>(vid) < 0 || vid >= num_vertices) // static_cast to silence tautology warnings (vid < 0 always fulfilled for unsigned integers)
923 {
924 viennashe::log::error() << "ERROR! viennashe_get_nth_vertex(): The given index id (vid) must not be smaller 0 or greater " << num_vertices << std::endl;
925 return 2;
926 }
927
928 *x = 0; *y = 0; *z = 0;
929
930 // Check topology and set parameters and generate mesh
932 {
934 typedef viennagrid::result_of::const_vertex_range<MeshType>::type VertexContainer;
935
936 VertexContainer vertices((dev->device_1d)->mesh());
937 *x = viennagrid::point(vertices[vid])[0];
938 }
940 {
942 typedef viennagrid::result_of::const_vertex_range<MeshType>::type VertexContainer;
943
944 VertexContainer vertices((dev->device_quad_2d)->mesh());
945 *x = viennagrid::point(vertices[vid])[0];
946 *y = viennagrid::point(vertices[vid])[1];
947 }
949 {
951 typedef viennagrid::result_of::const_vertex_range<MeshType>::type VertexContainer;
952
953 VertexContainer vertices((dev->device_tri_2d)->mesh());
954 *x = viennagrid::point(vertices[vid])[0];
955 *y = viennagrid::point(vertices[vid])[1];
956 }
958 {
960 typedef viennagrid::result_of::const_vertex_range<MeshType>::type VertexContainer;
961
962 VertexContainer vertices((dev->device_hex_3d)->mesh());
963 *x = viennagrid::point(vertices[vid])[0];
964 *y = viennagrid::point(vertices[vid])[1];
965 *z = viennagrid::point(vertices[vid])[2];
966 }
968 {
970 typedef viennagrid::result_of::const_vertex_range<MeshType>::type VertexContainer;
971
972 VertexContainer vertices((dev->device_tet_3d)->mesh());
973 *x = viennagrid::point(vertices[vid])[0];
974 *y = viennagrid::point(vertices[vid])[1];
975 *z = viennagrid::point(vertices[vid])[2];
976 }
977 else
978 {
979 viennashe::log::error() << "ERROR! viennashe_get_nth_vertex(): Unkown topology type or malconfigured device (dev)!" << std::endl;
980 return 1;
981 }
982
983 }
984 catch(...)
985 {
986 viennashe::log::error() << "ERROR! viennashe_get_nth_vertex(): UNKOWN ERROR!" << std::endl;
987 return -1;
988 }
989 return 0;
990}
991
993{
994 try
995 {
997 CHECK_ARGUMENT_FOR_NULL(vertex_id_list,3,"vertex_id_list");
998
1001
1002 if (static_cast<long>(cid) < 0 || cid >= num_cells) // static_cast to silence tautology warnings (vid < 0 always fulfilled for unsigned integers)
1003 {
1004 viennashe::log::error() << "ERROR! viennashe_get_nth_vertex(): The given index id (cid) must not be smaller 0 or greater " << num_cells << std::endl;
1005 return 2;
1006 }
1007
1008 // Check topology and set parameters and generate mesh
1010 {
1011 libviennashe::get_vertices_on_cell(*(dev->device_1d), cid, vertex_id_list);
1012 }
1014 {
1015 libviennashe::get_vertices_on_cell(*(dev->device_quad_2d), cid, vertex_id_list);
1016 }
1017 else if (dev->stype == libviennashe::meshtype::triangular_2d)
1018 {
1019 libviennashe::get_vertices_on_cell(*(dev->device_tri_2d), cid, vertex_id_list);
1020 }
1021 else if (dev->stype == libviennashe::meshtype::hexahedral_3d)
1022 {
1023 libviennashe::get_vertices_on_cell(*(dev->device_hex_3d), cid, vertex_id_list);
1024 }
1026 {
1027 libviennashe::get_vertices_on_cell(*(dev->device_tet_3d), cid, vertex_id_list);
1028 }
1029 else
1030 {
1031 viennashe::log::error() << "ERROR! viennashe_get_nth_vertex(): Unkown topology type or malconfigured device (dev)!" << std::endl;
1032 return 1;
1033 }
1034
1035 }
1036 catch(...)
1037 {
1038 viennashe::log::error() << "ERROR! viennashe_get_nth_vertex(): UNKOWN ERROR!" << std::endl;
1039 return -1;
1040 }
1041 return 0;
1042}
1043
1044
1045#ifdef __cplusplus
1046}
1047#endif
void generate_mesh(viennashe::util::device_generation_config const &generator_params)
Definition: device.hpp:128
void set_material(long material_id, cell_type const &elem)
Sets the material ID on a cell.
Definition: device.hpp:448
void load_mesh(std::string filename)
Definition: device.hpp:96
segmentation_type const & segmentation() const
Definition: device.hpp:156
void set_doping_p(double value, cell_type const &c)
Sets the acceptor doping (in m^-3) in the specified cell.
Definition: device.hpp:365
MeshT const & mesh() const
Returns the underlying mesh.
Definition: device.hpp:145
void set_doping_n(double value, cell_type const &c)
Sets the donator doping (in m^-3) in the specified cell.
Definition: device.hpp:292
Defines the physical properties of a device, e.g. doping. This is the implementation for 2d and highe...
Definition: device.hpp:818
Configuration class for the simple mesh generator.
void add_segment(double start_x, double start_y, double len_x, double len_y, unsigned long points_x, unsigned long points_y)
VIENNASHE_EXPORT viennasheErrorCode viennashe_get_num_vertices(viennashe_device dev, viennashe_index_type *num)
VIENNASHE_EXPORT viennasheErrorCode viennashe_get_num_segments(viennashe_device dev, viennashe_index_type *num)
VIENNASHE_EXPORT viennasheErrorCode viennashe_create_device_flat(viennashe_device *dev, viennashe_topology_type_id topology_id, double *vertices, viennashe_index_type num_vertices, viennashe_index_type *cells, viennashe_index_type num_cells, viennashe_index_type *segmentation)
VIENNASHE_EXPORT viennasheErrorCode viennashe_free_device(viennashe_device dev)
VIENNASHE_EXPORT viennasheErrorCode viennashe_set_contact_potential_cells(viennashe_device dev, viennashe_index_type *cell_ids, double *values, viennashe_index_type len)
VIENNASHE_EXPORT viennasheErrorCode viennashe_create_1d_device(viennashe_device *dev, double len_x, size_t points_x)
VIENNASHE_EXPORT viennasheErrorCode viennashe_get_nth_cell(viennashe_device dev, viennashe_index_type cid, viennashe_index_type *vertex_id_list)
VIENNASHE_EXPORT viennasheErrorCode viennashe_get_grid(viennashe_device dev, double **vertices, viennashe_index_type *num_vertices, viennashe_index_type **cells, viennashe_index_type *num_cells)
viennashe_topology_type_id
Enum of available toplogical mesh configurations.
Definition: device.h:31
@ viennashe_quadrilateral_2d
Definition: device.h:32
@ viennashe_line_1d
Definition: device.h:31
@ viennashe_hexahedral_3d
Definition: device.h:33
@ viennashe_tetrahedral_3d
Definition: device.h:33
@ viennashe_triangular_2d
Definition: device.h:32
VIENNASHE_EXPORT viennasheErrorCode viennashe_set_contact_potential_segment(viennashe_device dev, double value, viennashe_index_type segment_id)
VIENNASHE_EXPORT viennasheErrorCode viennashe_get_num_cells(viennashe_device dev, viennashe_index_type *num)
VIENNASHE_EXPORT viennasheErrorCode viennashe_set_doping_p_on_segment(viennashe_device dev, double doping_p, viennashe_index_type segment_id)
VIENNASHE_EXPORT viennasheErrorCode viennashe_get_num_vertices_on_segment(viennashe_device dev, viennashe_index_type segment_id, viennashe_index_type *num)
VIENNASHE_EXPORT viennasheErrorCode viennashe_set_doping_n_on_segment(viennashe_device dev, double doping_n, viennashe_index_type segment_id)
VIENNASHE_EXPORT viennasheErrorCode viennashe_get_dimension(viennashe_device dev, viennashe_index_type *dim)
VIENNASHE_EXPORT viennasheErrorCode viennashe_initalize_device(viennashe_device dev, viennashe_material_id *material_ids, double *doping_n, double *doping_p)
VIENNASHE_EXPORT viennasheErrorCode viennashe_get_num_vertices_per_cell(viennashe_device dev, viennashe_index_type *num)
VIENNASHE_EXPORT viennasheErrorCode viennashe_get_nth_vertex(viennashe_device dev, viennashe_index_type vid, double *x, double *y, double *z)
VIENNASHE_EXPORT viennasheErrorCode viennashe_create_device(viennashe_device *dev, viennashe_topology_type_id topology_id, double **vertices, viennashe_index_type num_vertices, viennashe_index_type **cells, viennashe_index_type num_cells, viennashe_index_type *segmentation)
VIENNASHE_EXPORT viennasheErrorCode viennashe_set_material_on_segment(viennashe_device dev, viennashe_material_id material_id, viennashe_index_type segment_id)
VIENNASHE_EXPORT viennasheErrorCode viennashe_create_device_from_file(viennashe_device *dev, viennashe_topology_type_id topology_id, char const *filename)
VIENNASHE_EXPORT viennasheErrorCode viennashe_get_num_cells_on_segment(viennashe_device dev, viennashe_index_type segment_id, viennashe_index_type *num)
int viennasheErrorCode
Definition: error.h:25
Contains a very simple mesh generator (ortho-grids) for one and two spatial dimensions.
long viennashe_material_id
Definition: material.h:26
The internal C++ namespace of the library.
int points_x
Definition: resistor.py:39
int len_x
Definition: resistor.py:38
logger< true > error()
Used to log errors. The logging level is logERROR.
Definition: log.hpp:301
logger< true > warn()
Used to log warnings. The logging level is logWARNING.
Definition: log.hpp:303
void dump_mesh(DeviceT const &device, double **vertices, IndexT &num_vertices, IndexT **cells, IndexT &num_cells)
A device generator to generate a device from C-Arrays (DOES NOT TAKE OWNERSHIP)
A device generator to generate a device from flat C-Arrays (DOES NOT TAKE OWNERSHIP)
Internal C++ to C wrapper for the device. Has typedefs and destructor.
devq2d_type * device_quad_2d
devt2d_type * device_tri_2d
devh3d_type * device_hex_3d
devt3d_type * device_tet_3d
struct viennashe_device_impl viennashe_device_impl
Device implementation type.
Definition: sys.h:34
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)