ViennaSHE 1.3.0
Free open-source semiconductor device simulator using spherical harmonics expansions techniques.
assemble_timederivative.hpp
Go to the documentation of this file.
1#ifndef VIENNASHE_SHE_ASSEMBLE_TIMEDERIVATIVE_HPP
2#define VIENNASHE_SHE_ASSEMBLE_TIMEDERIVATIVE_HPP
3
4
5/* ============================================================================
6 Copyright (c) 2011-2022, Institute for Microelectronics,
7 Institute for Analysis and Scientific Computing,
8 TU Wien.
9
10 -----------------
11 ViennaSHE - The Vienna Spherical Harmonics Expansion Boltzmann Solver
12 -----------------
13
14 http://viennashe.sourceforge.net/
15
16 License: MIT (X11), see file LICENSE in the base directory
17=============================================================================== */
18
19#include "viennashe/forwards.h"
24
25namespace viennashe
26{
27 namespace she
28 {
29 namespace detail
30 {
32 template <typename ElementType, typename QuantityPotential, typename QuantityPotentialOld>
33 double potential_difference_to_old_timestep(ElementType const & elem,
34 QuantityPotential const & new_potential,
35 QuantityPotentialOld const & old_potential)
36 {
37 return 0.5*(new_potential.get_value(viennagrid::vertices(elem)[0]) + new_potential.get_value(viennagrid::vertices(elem)[1]))
38 - 0.5*(old_potential.get_value(viennagrid::vertices(elem)[0]) + old_potential.get_value(viennagrid::vertices(elem)[1]));
39 }
40
42 template <typename ConfigType, typename QuantityPotential, typename QuantityPotentialOld>
43 double potential_difference_to_old_timestep(viennagrid::element<viennagrid::vertex_tag, ConfigType> const & elem,
44 QuantityPotential const & new_potential,
45 QuantityPotentialOld const & old_potential)
46 {
47 return new_potential.get_value(elem) - old_potential.get_value(elem);
48 }
49 }
50
51
52 template <typename DeviceType,
53 typename SHEQuantity,
54 typename MatrixType,
55 typename VectorType,
56 typename ElementType,
57 typename CouplingMatrixType,
58 typename QuantityPotential,
59 typename QuantityPotentialOld
60 >
61 void assemble_timederivative( DeviceType const & device,
62 viennashe::config const & conf,
63 SHEQuantity const & quan,
64 SHEQuantity const & quan_old,
65 MatrixType & A,
66 VectorType & b,
67 ElementType const & elem, std::size_t index_H,
68 CouplingMatrixType const & identity_matrix,
69 QuantityPotential const & quan_pot,
70 QuantityPotentialOld const & quan_pot_old)
71 {
72 (void)quan_pot; (void)quan_pot_old; //avoid unused parameter warnings
73
74 typedef typename viennagrid::result_of::point<typename DeviceType::mesh_type>::type PointType;
75
76 const double rtime = (conf.time_step_size() > 0.0) ? 1.0 / conf.time_step_size() : 0.0;
78
79
80 if (rtime == 0.0)
81 return; //stationary
82
83 const long row_index = quan.get_unknown_index(elem, index_H);
84 if (row_index < 0)
85 return; //no unknown here
86
87 bool odd_assembly = detail::is_odd_assembly(elem, viennagrid::cells(device.mesh())[0]);
88
89 //if (odd_assembly)
90 // return;
91
93
94 if (! with_full_newton )
95 {
96 const long expansion_order = static_cast<long>(quan.get_expansion_order(elem, index_H));
97 double box_volume = viennagrid::volume(elem);
98 if (odd_assembly)
99 box_volume *= detail::cell_connection_length(device.mesh(), elem, viennagrid::cells(device.mesh())[0]) / PointType::dim;
100
101 //const double Z = averaged_density_of_states(quan, conf.dispersion_relation(quan.get_carrier_type_id()), elem, index_H);
102
103 //
104 // Assemble the df/dH term: \pm q * dphi/dt * f(H_{n \pm 1}, t_{k+1})
105 //
106 /*
107 const double dphi = detail::potential_difference_to_old_timestep(elem, quan_pot, quan_pot_old); // new - old
108 const double q = viennashe::physics::constants::q;
109
110 const viennashe::carrier_type_id carrier_id = quan.get_carrier_type_id();
111 const double polarity = (carrier_id == ELECTRON_TYPE_ID) ? -1.0 : 1.0;
112
113 const long col_index_minus = quan.get_unknown_index(elem, index_H - 1);
114 if (col_index_minus >= 0 )
115 {
116 double Z_lower = averaged_density_of_states(quan, conf.dispersion_relation(quan.get_carrier_type_id()), elem, index_H - 1);
117
118 // from box integration
119 const double coeff = polarity * Z_lower * box_volume;
120
121 viennashe::util::add_block_matrix(A,
122 row_index, col_index_minus,
123 - 0.5 * q * coeff * dphi * rtime ,
124 identity_matrix,
125 viennashe::math::spherical_harmonics_iterator(expansion_order, harmonics_it_id),
126 viennashe::math::spherical_harmonics_iterator(expansion_order, harmonics_it_id)
127 );
128 }
129
130 const long col_index_plus = quan.get_unknown_index(elem, index_H + 1);
131 if (col_index_plus >= 0 )
132 {
133 double Z_upper = averaged_density_of_states(quan, conf.dispersion_relation(quan.get_carrier_type_id()), elem, index_H + 1);
134
135 const double coeff = polarity * Z_upper * box_volume;
136
137 viennashe::util::add_block_matrix(A,
138 row_index, col_index_plus,
139 + 0.5 * q * coeff * dphi * rtime ,
140 identity_matrix,
141 viennashe::math::spherical_harmonics_iterator(expansion_order, harmonics_it_id),
142 viennashe::math::spherical_harmonics_iterator(expansion_order, harmonics_it_id)
143 );
144 }
145 */
146
147 //
148 // df/dt term
149 //
150 const double height = box_height(quan, elem, index_H);
151 const double coeff = height * box_volume;
152
154 std::size_t(row_index), std::size_t(row_index),
155 coeff * rtime,
156 identity_matrix,
157 viennashe::math::spherical_harmonics_iterator(expansion_order, harmonics_it_id),
158 viennashe::math::spherical_harmonics_iterator(expansion_order, harmonics_it_id)
159 );
160
162 std::size_t(row_index),
163 -coeff * rtime,
164 identity_matrix,
165 viennashe::math::spherical_harmonics_iterator(expansion_order, harmonics_it_id),
166 viennashe::math::spherical_harmonics_iterator(expansion_order, harmonics_it_id),
167 quan_old.get_values(elem,index_H));
168 }
169 else if (with_full_newton)
170 {
171 log::warning() << "* simulator(): !! WARNING !! Time dependence is not available for Newton iterations! Skipping df/dt " << std::endl;
172 }
173
174 }
175
176
177
178 } // she
179} // viennashe
180
181#endif /* ASSEMBLE_TIMEDERIVATIVE_HPP */
182
Common routines for the assembly of SHE equations.
Writes a possibly scaled block matrix to the system matrix. Includes similar functionality for comput...
The main SHE configuration class. To be adjusted by the user for his/her needs.
Definition: config.hpp:124
double time_step_size() const
Definition: config.hpp:536
nonlinear_solver_config_type & nonlinear_solver()
Returns the configuration object for the nonlinear solver.
Definition: config.hpp:495
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
Iteration over all spherical harmonics indices up to order L, with increasing indices l and m.
long id() const
Returns the current linear solver ID.
Definition: config.hpp:262
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.
logger< true > warning()
Used to log warnings. The logging level is logWARNING.
Definition: log.hpp:305
harmonics_iteration_type
An enumeration of spherical harmonics types (all, even, odd) ViennaSHE supports.
Definition: forwards.h:159
@ EVEN_HARMONICS_ITERATION_ID
Definition: forwards.h:161
@ ODD_HARMONICS_ITERATION_ID
Definition: forwards.h:162
bool is_odd_assembly(T const &, T const &)
double cell_connection_length(MeshT const &, CellT const &, CellT const &)
Static dispatcher for computing the connection between two cells adjacent to a facet....
double potential_difference_to_old_timestep(ElementType const &elem, QuantityPotential const &new_potential, QuantityPotentialOld const &old_potential)
Obtain the potential difference from an edge.
double box_height(SHEQuantity const &quan, ElementType const &elem, std::size_t index_H)
Returns the height of the control box with respect to energy at the provided element (vertex or edge)...
void assemble_timederivative(DeviceType const &device, viennashe::config const &conf, SHEQuantity const &quan, SHEQuantity const &quan_old, MatrixType &A, VectorType &b, ElementType const &elem, std::size_t index_H, CouplingMatrixType const &identity_matrix, QuantityPotential const &quan_pot, QuantityPotentialOld const &quan_pot_old)
void add_block_matrix(SystemMatrixType &system_matrix, std::size_t row_index, std::size_t col_index, double prefactor, BlockMatrixType const &coupling_matrix, RowIndexIterator row_iter, ColumnIndexIterator const &col_iter_init, bool elastic_scattering_roundoff_error_prevention=false)
Writes a sub-matrix of a block matrix 'coupling_matrix' into the global system matrix,...
void subtract_folded_block_vector(VectorType &residual, std::size_t row_index, double prefactor, BlockMatrixType const &coupling_matrix, RowIndexIterator row_iter, ColumnIndexIterator const &col_iter_init, double const *fold_vector)
Writes a sub-matrix of a block matrix 'coupling_matrix' to the residual vector. The columns are 'fold...
The main ViennaSHE namespace. All functionality resides inside this namespace.
Definition: accessors.hpp:40
Implementation of spherical harmonics plus helper functions.
@ newton_nonlinear_solver
Gummel iteration.
Definition: config.hpp:244