ViennaSHE 1.3.0
Free open-source semiconductor device simulator using spherical harmonics expansions techniques.
quantity_transfer.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#if defined(_MSC_VER)
16 // Disable name truncation warning obtained in Visual Studio
17 #pragma warning(disable:4503)
18#endif
19
20#include <iostream>
21#include <cstdlib>
22#include <vector>
23
24// ViennaSHE includes:
25#include "viennashe/core.hpp"
26
27// ViennaGrid default configurations:
28#include "viennagrid/config/default_configs.hpp"
29
30
32template <typename ValueType>
33struct field_container
34{
35 typedef ValueType value_type;
36
37 field_container(std::size_t size, value_type default_value = value_type()) : data_(size, default_value) {}
38
39 template <typename ElementType>
40 value_type operator()(ElementType const & elem) const
41 {
42 return data_.at(std::size_t(elem.id().get()));
43 }
44
45 template <typename ElementType>
46 void operator()(ElementType const & elem, value_type val)
47 {
48 data_.at(std::size_t(elem.id().get())) = val;
49 }
50
51 std::vector<value_type> const & container() const { return data_; }
52
53 std::vector<value_type> data_;
54};
55
59template <typename DeviceType>
60int test(DeviceType const & device, std::string output_filename)
61{
62 typedef typename DeviceType::mesh_type MeshType;
63
64 typedef typename viennagrid::result_of::point<MeshType>::type PointType;
65 typedef typename viennagrid::result_of::facet<MeshType>::type FacetType;
66 typedef typename viennagrid::result_of::cell<MeshType>::type CellType;
67
68 typedef typename viennagrid::result_of::const_facet_range<MeshType>::type FacetContainer;
69 typedef typename viennagrid::result_of::iterator<FacetContainer>::type FacetIterator;
70 typedef typename viennagrid::result_of::const_cell_range<MeshType>::type CellContainer;
71 typedef typename viennagrid::result_of::iterator<CellContainer>::type CellIterator;
72
73 typedef typename viennagrid::result_of::const_facet_range<CellType>::type FacetOnCellContainer;
74
75 std::vector<double> reference_field(3);
76 reference_field[0] = 1.0;
77 reference_field[1] = 2.0;
78 reference_field[2] = 3.0;
79
80 MeshType const & mesh = device.mesh();
81
82 //
83 // Write normal components of field (1, 1, 0) to each edge:
84 //
85 std::cout << "Writing normal projections on box interfaces to facets..." << std::endl;
86 FacetContainer facets(mesh);
87 field_container<double> field_component_on_edge_container(facets.size());
88
89 for (FacetIterator fit = facets.begin();
90 fit != facets.end();
91 ++fit)
92 {
93 typedef typename viennagrid::result_of::const_coboundary_range<MeshType, FacetType, CellType>::type CellOnFacetContainer;
94 //typedef typename viennagrid::result_of::iterator<CellOnFacetContainer>::type CellOnFacetIterator;
95
96 CellOnFacetContainer cells_on_facet(mesh, viennagrid::handle(mesh, *fit));
97
98 // Reference orientation of facet is from first coboundary cell to second coboundary cell:
99
100 PointType n = viennashe::util::outer_cell_normal_at_facet(cells_on_facet[0], *fit);
101 n /= viennagrid::norm_2(n); // n should be normalized already, but let's ensure this is indeed the case
102
103 double field_in_n = reference_field[0] * n[0];
104 if (PointType::dim >= 2)
105 field_in_n += reference_field[1] * n[1];
106 if (PointType::dim >= 3)
107 field_in_n += reference_field[2] * n[2];
108 field_component_on_edge_container(*fit, field_in_n);
109 }
110
111
112 //
113 // Now transfer from normal projection on edges to vertices:
114 //
115 std::cout << "Transferring from edges to vertices..." << std::endl;
116 CellContainer cells(mesh);
117 field_container<std::vector<double> > my_cell_field_container(cells.size(), std::vector<double>(PointType::dim));
118
119 for (CellIterator cit = cells.begin();
120 cit != cells.end();
121 ++cit)
122 {
123 FacetOnCellContainer facets_on_cell(*cit);
124
126 *cit, facets_on_cell,
127 my_cell_field_container, field_component_on_edge_container);
128
129 std::vector<double> e_field(3);
130 e_field[0] = my_cell_field_container(*cit)[0];
131 if (PointType::dim >= 2)
132 e_field[1] = my_cell_field_container(*cit)[1];
133 if (PointType::dim >= 3)
134 e_field[2] = my_cell_field_container(*cit)[2];
135
136 //
137 // Run checks:
138 //
139 double diff = (e_field[0] - reference_field[0]) * (e_field[0] - reference_field[0]);
140 if (PointType::dim >= 2)
141 diff += (e_field[1] - reference_field[1]) * (e_field[1] - reference_field[1]);
142 if (PointType::dim >= 3)
143 diff += (e_field[2] - reference_field[2]) * (e_field[2] - reference_field[2]);
144 if (std::abs(diff) > 1e-10)
145 {
146 std::cerr << "Test failed at cell " << *cit << std::endl;
147 std::cerr << "Diff: " << diff << ", computed vector: (" << e_field[0] << ", " << e_field[1] << ", " << e_field[2] << ")" << std::endl;
148 return EXIT_FAILURE;
149 }
150 }
151
152
153 //
154 // Write to VTK
155 //
156
157 std::cout << "Writing to VTK..." << std::endl;
158 viennagrid::io::vtk_writer<MeshType> my_vtk_writer;
159 my_vtk_writer.add_vector_data_on_cells(viennagrid::make_accessor<CellType>(my_cell_field_container.container()), "flux");
160 my_vtk_writer(mesh, output_filename);
161
162 //
163 // Test result:
164 //
165
166 return EXIT_SUCCESS;
167}
168
169
170
171int main()
172{
173 typedef viennagrid::line_1d_mesh MeshType1d;
174 typedef viennashe::device<MeshType1d> DeviceType1d;
175
176 typedef viennagrid::triangular_2d_mesh MeshType2d;
177 typedef viennashe::device<MeshType2d> DeviceType2d;
178
179 typedef viennagrid::tetrahedral_3d_mesh MeshType3d;
180 typedef viennashe::device<MeshType3d> DeviceType3d;
181
182 std::cout << "* main(): Testing mesh in 1d..." << std::endl;
183 DeviceType1d device1d;
185 generator_params.add_segment(0.0, 1e-6, 30); //start at x=0, length 1e-6, 30 points
186 device1d.generate_mesh(generator_params);
187
188 if (test(device1d, "quantity_transfer_1d") != EXIT_SUCCESS)
189 return EXIT_FAILURE;
190
191
192
193 std::cout << "* main(): Testing mesh in 2d..." << std::endl;
194 DeviceType2d device2d;
195 device2d.load_mesh("../../examples/data/nin2d.mesh");
196
197 if (test(device2d, "quantity_transfer_2d") != EXIT_SUCCESS)
198 return EXIT_FAILURE;
199
200
201 std::cout << "* main(): Testing mesh in 3d..." << std::endl;
202 DeviceType3d device3d;
203 device3d.load_mesh("../../examples/data/half-trigate57656.mesh");
204
205 if (test(device3d, "quantity_transfer_3d") != EXIT_SUCCESS)
206 return EXIT_FAILURE;
207
208}
209
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)
Convenience header, which includes all core functionality available in ViennaSHE.
VectorType::value_type norm_2(VectorType const &v)
Definition: linalg_util.hpp:37
void dual_box_flux_to_cell(DeviceT const &device, CellT const &cell, FacetContainerT const &facets, CellSetterT &cell_setter, FacetAccessorT const &facet_access)
Interpolates normal components of the flux defined on each facet to cells. Mostly used for visualizat...
viennagrid::result_of::point< viennagrid::element< CellTagT, WrappedConfigT > >::type outer_cell_normal_at_facet(viennagrid::element< CellTagT, WrappedConfigT > const &cell, viennagrid::element< FacetTagT, WrappedConfigT > const &facet)
Returns the unit outer normal of a facet with respect to the provided cell.
int main()
Definition: resistor1d-c.c:108