1#ifndef VIENNASHE_SHE_DF_WRAPPERS_HPP
2#define VIENNASHE_SHE_DF_WRAPPERS_HPP
24#include "viennagrid/forwards.hpp"
25#include "viennagrid/mesh/mesh.hpp"
45 template <
typename UnknownSHEType,
typename ElementType>
46 std::size_t
find_best_H(UnknownSHEType
const & she_quantity, ElementType
const & el,
double kin_energy, std::size_t index_H_guess)
50 std::size_t index_H = std::min<std::size_t>(index_H_guess, she_quantity.get_value_H_size() - 2);
53 while ( (she_quantity.get_kinetic_energy(el, index_H) < kin_energy)
54 && ( (carrier_sign == 1) ? (index_H > 0) : (index_H < she_quantity.get_value_H_size() - 1) )
57 index_H -=
static_cast<std::size_t
>(carrier_sign);
60 while ( (she_quantity.get_kinetic_energy(el, index_H) > kin_energy)
61 && ( (carrier_sign == -1) ? (index_H > 0) : (index_H < she_quantity.get_value_H_size() - 1) )
64 index_H +=
static_cast<std::size_t
>(carrier_sign);
68 double error_down = she_quantity.get_kinetic_energy(el, index_H) - kin_energy;
72 double error_up = error_down;
73 if (
static_cast<long>(index_H) >=
static_cast<long>(carrier_sign)
74 &&
static_cast<long>(index_H) <
static_cast<long>(she_quantity.get_value_H_size()) +
static_cast<long>(carrier_sign))
76 error_up = she_quantity.get_kinetic_energy(el,
static_cast<std::size_t
>(
static_cast<long>(index_H) - carrier_sign)) - kin_energy;
77 if (she_quantity.get_unknown_index(el,
static_cast<std::size_t
>(
static_cast<long>(index_H) - carrier_sign)) < 0)
78 error_up = 2.0 * error_down;
81 if (std::abs(error_up) < std::abs(error_down))
82 index_H -=
static_cast<std::size_t
>(carrier_sign);
106 template <
typename DeviceType,
typename SHEQuantityT>
112 typedef typename DeviceType::mesh_type MeshType;
114 typedef typename viennagrid::result_of::vertex<MeshType>::type VertexType;
115 typedef typename viennagrid::result_of::facet<MeshType>::type FacetType;
116 typedef typename viennagrid::result_of::cell<MeshType>::type CellType;
130 SHEQuantityT
const &
quan)
144 double kinetic_energy,
147 std::size_t index_H_guess = 0)
const
149 if ( (l % 2 != 0) || (std::abs(
static_cast<double>(m)) >
static_cast<double>(l)) )
152 return evaluate(cell,
167 double kinetic_energy,
170 std::size_t index_H_guess = 0)
const
172 if ( (l % 2 != 1) || (std::abs(
static_cast<double>(m)) >
static_cast<double>(l)) )
175 return evaluate(facet,
182 template <
typename FoldVectorType>
183 void fill(CellType
const & cell,
185 std::size_t index_H_guess,
186 FoldVectorType & vec)
const
188 typedef typename FoldVectorType::value_type value_type;
192 value_type
const * pValues = she_unknown_.get_values(cell, index_H);
194 std::size_t num_values = she_unknown_.get_unknown_num(cell, index_H);
195 for (std::size_t i=0; i < num_values; ++i)
201 template <
typename FoldVectorType>
202 void fill(FacetType
const & facet,
204 std::size_t index_H_guess,
205 FoldVectorType & vec)
const
207 typedef typename FoldVectorType::value_type value_type;
211 value_type
const * pValues = she_unknown_.get_values(facet, index_H);
213 std::size_t num_values = she_unknown_.get_unknown_num(facet, index_H);
214 for (std::size_t i=0; i < num_values; ++i)
219 SHEQuantityT
const &
quan()
const {
return this->she_unknown_; }
233 template <
typename ElementType>
234 double evaluate(ElementType
const & el,
239 std::size_t vec_index = 0;
240 const std::size_t unknown_num = she_unknown_.get_unknown_num(el, index_H);
242 for (std::size_t i = parity_for_element(el); i < l; i += 2)
243 vec_index += 2 * i + 1;
245 if (unknown_num > 0 && unknown_num >= vec_index)
250 return she_unknown_.get_values(el, index_H)[vec_index + std::size_t(
long(l) + m)];
252 return she_unknown_.get_values(el, index_H)[vec_index + std::size_t(
long(l) + m)] /
averaged_density_of_states(she_unknown_, dispersion_, el, index_H);
253 default:
throw std::runtime_error(
"she_df_wrapper::evaluate(): Unknown SHE discretization type!");
260 std::size_t parity_for_element(CellType
const &)
const {
return 0; }
261 std::size_t parity_for_element(FacetType
const &)
const {
return 1; }
264 SHEQuantityT she_unknown_;
278 template <
typename DeviceType,
typename SHEQuantityT>
282 typedef typename DeviceType::mesh_type MeshType;
284 typedef typename viennagrid::result_of::facet<MeshType>::type FacetType;
285 typedef typename viennagrid::result_of::cell<MeshType>::type CellType;
296 SHEQuantityT
const &
quan)
298 she_df_(conf,
quan) {}
309 double kinetic_energy,
312 std::size_t index_H_guess = 0)
const
315 return she_df_(cell, kinetic_energy, l, m, index_H_guess);
317 return interpolated_odd_coefficient(cell, kinetic_energy, l, m, index_H_guess);
321 SHEQuantityT
const &
quan()
const {
return this->she_df_.quan(); }
327 double interpolated_odd_coefficient(CellType
const & cell,
328 double kinetic_energy,
331 std::size_t index_H_guess)
const
333 typedef typename viennagrid::result_of::const_facet_range<CellType>::type FacetOnCellContainer;
334 typedef typename viennagrid::result_of::iterator<FacetOnCellContainer>::type FacetOnCellIterator;
338 double summed_volume = 0;
340 FacetOnCellContainer facets(cell);
341 for (FacetOnCellIterator focit = facets.begin();
342 focit != facets.end();
347 double facet_volume = viennagrid::volume(*focit);
348 summed_volume += facet_volume;
349 result += she_df_(*focit, kinetic_energy, l, m, index_H_guess) * facet_volume;
355 if (summed_volume > 0)
356 result /= summed_volume;
361 DeviceType
const & device_;
362 she_df_wrapper<DeviceType, SHEQuantityT> she_df_;
374 template <
typename DeviceType,
typename SHEQuantityT>
380 typedef typename DeviceType::mesh_type MeshType;
382 typedef typename viennagrid::result_of::facet<MeshType>::type FacetType;
383 typedef typename viennagrid::result_of::cell<MeshType>::type CellType;
394 SHEQuantityT
const &
quan)
395 : she_unknown_(
quan),
407 double kinetic_energy,
410 std::size_t index_H_guess = 0)
const
412 return evaluate(cell, kinetic_energy, theta, phi, index_H_guess);
415 SHEQuantityT
const &
quan()
const {
return this->interpolated_she_df_.quan(); }
421 double evaluate(CellType
const & cell,
422 double kinetic_energy,
425 std::size_t index_H_guess)
const
427 std::size_t index_H =
detail::find_best_H(she_unknown_, cell, kinetic_energy, index_H_guess);
431 for (std::size_t l=0; l <= L; ++l)
433 for (
int m = -
static_cast<int>(l); m <= static_cast<int>(l); ++m)
436 result += interpolated_she_df_(cell, kinetic_energy, l, m, index_H) * Y_lm(theta, phi);
443 UnknownSHEType she_unknown_;
444 interpolated_she_df_wrapper<DeviceType, SHEQuantityT> interpolated_she_df_;
455 template <
typename DeviceType,
typename SHEQuantityT>
461 typedef typename DeviceType::mesh_type MeshType;
463 typedef typename viennagrid::result_of::facet<MeshType>::type FacetType;
464 typedef typename viennagrid::result_of::cell<MeshType>::type CellType;
484 double kinetic_energy,
487 std::size_t index_H_guess = 0)
const
489 return df_(cell, kinetic_energy, theta, phi, index_H_guess) * dispersion_.
density_of_states(kinetic_energy, theta, phi);
492 SHEQuantityT
const &
quan()
const {
return this->df_.quan(); }
516 template <
typename DeviceType,
typename SHEQuantityT>
522 typedef typename DeviceType::mesh_type MeshType;
524 typedef typename viennagrid::result_of::cell<MeshType>::type CellType;
538 SHEQuantityT
const &
quan) : she_df_(conf,
quan), Y_00_(0, 0) {}
548 double kinetic_energy,
549 std::size_t index_H_guess = 0)
const
551 return she_df_(cell, kinetic_energy, 0, 0, index_H_guess) * Y_00_(0, 0);
554 SHEQuantityT
const &
quan()
const {
return this->she_df_.quan(); }
570 template <
typename DeviceType,
typename SHEQuantityT>
576 typedef typename DeviceType::mesh_type MeshType;
578 typedef typename viennagrid::result_of::cell<MeshType>::type CellType;
591 SHEQuantityT
const &
quan)
602 double kinetic_energy,
603 std::size_t index_H_guess = 0)
const
605 return edf_(cell, kinetic_energy, index_H_guess) * dispersion_.
density_of_states(kinetic_energy);
608 SHEQuantityT
const &
quan()
const {
return this->edf_.quan(); }
The main SHE configuration class. To be adjusted by the user for his/her needs.
she_discretization_type_id she_discretization_type() const
Defines the physical properties of a device, e.g. doping. This is the implementation for 2d and highe...
A proxy object for a dispersion relation. Does NOT take ownership of the provided pointer!
double density_of_states(double ekin, double theta=0, double phi=0) const
Returns the density of states as a function of kinetic energy (and angles, eventually)
A convenience wrapper for evaluating the full distribution function. Note: Evaluations are quite cost...
double operator()(CellType const &cell, double kinetic_energy, double theta, double phi, std::size_t index_H_guess=0) const
Returns the energy distribution function for electrons in one valley on a vertex:
dispersion_relation_type const & dispersion_relation() const
viennashe::config::dispersion_relation_type dispersion_relation_type
SHEQuantityT she_quantity_type
SHEQuantityT const & quan() const
df_wrapper(DeviceType const &device, viennashe::config const &conf, SHEQuantityT const &quan)
A convenience wrapper for accessing the energy distribution function on each vertex of the device.
SHEQuantityT const & quan() const
viennashe::config::dispersion_relation_type dispersion_relation_type
edf_wrapper(viennashe::config const &conf, SHEQuantityT const &quan)
Constructs the wrapper.
SHEQuantityT she_quantity_type
double operator()(CellType const &cell, double kinetic_energy, std::size_t index_H_guess=0) const
Returns the energy distribution function for the respective carrier in one valley on a vertex:
dispersion_relation_type const & dispersion_relation() const
A convenience wrapper for evaluating the generalized distribution function (i.e. f * Z,...
SHEQuantityT const & quan() const
SHEQuantityT she_quantity_type
viennashe::config::dispersion_relation_type dispersion_relation_type
generalized_df_wrapper(DeviceType const &device, viennashe::config const &conf, SHEQuantityT const &quan)
double operator()(CellType const &cell, double kinetic_energy, double theta, double phi, std::size_t index_H_guess=0) const
Returns the energy distribution function for the respective carrier in one valley on a vertex:
dispersion_relation_type const & dispersion_relation() const
A convenience wrapper for accessing the generalized energy distribution function (f * Z,...
double operator()(CellType const &cell, double kinetic_energy, std::size_t index_H_guess=0) const
Returns the energy distribution function for electrons in one valley on a vertex:
SHEQuantityT const & quan() const
generalized_edf_wrapper(viennashe::config const &conf, SHEQuantityT const &quan)
Constructs the wrapper.
dispersion_relation_type const & dispersion_relation() const
SHEQuantityT she_quantity_type
viennashe::config::dispersion_relation_type dispersion_relation_type
A convenience wrapper for accessing the distribution function coefficients over the device on each ve...
interpolated_she_df_wrapper self_type
dispersion_relation_type const & dispersion_relation() const
viennashe::config::dispersion_relation_type dispersion_relation_type
interpolated_she_df_wrapper(DeviceType const &device, viennashe::config const &conf, SHEQuantityT const &quan)
SHEQuantityT she_quantity_type
double operator()(CellType const &cell, double kinetic_energy, std::size_t l, long m, std::size_t index_H_guess=0) const
Returns the energy distribution function for the respective carrier type in one valley on a vertex:
SHEQuantityT const & quan() const
Exception for the case that invalid expansion order is accessed.
A convenience wrapper for accessing the distribution function coefficients over the device....
SHEQuantityT she_quantity_type
void fill(CellType const &cell, double kin_energy, std::size_t index_H_guess, FoldVectorType &vec) const
Batch-evaluation: Returns the expansion coefficents computed at the particular vertex for the particu...
SHEQuantityT const & quan() const
viennashe::config::dispersion_relation_type dispersion_relation_type
double operator()(CellType const &cell, double kinetic_energy, std::size_t l, long m, std::size_t index_H_guess=0) const
Returns an even-order SHE coefficient for the respective carrier on a vertex:
dispersion_relation_type const & dispersion_relation() const
viennashe::config const & config() const
void fill(FacetType const &facet, double kin_energy, std::size_t index_H_guess, FoldVectorType &vec) const
Batch-evaluation: Returns the expansion coefficents computed at the particular edge for the particula...
she_df_wrapper(viennashe::config const &conf, SHEQuantityT const &quan)
Constructs the wrapper.
double operator()(FacetType const &facet, double kinetic_energy, std::size_t l, long m, std::size_t index_H_guess=0) const
Returns an even-order SHE coefficient for the respective carrier on an edge:
std::size_t get_expansion_order(AssociatedT1 const &elem, std::size_t index_H) const
The SHE configuration class is defined here.
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.
std::size_t find_best_H(UnknownSHEType const &she_quantity, ElementType const &el, double kin_energy, std::size_t index_H_guess)
Returns the best total energy in order to match the supplied kinetic energy.
double averaged_density_of_states(SHEQuantity const &quan, viennashe::config::dispersion_relation_type const &dispersion, CellFacetType const &cell_facet, std::size_t index_H)
Returns the density of states around a vertex or an edge at total energy specified by index_H....
The main ViennaSHE namespace. All functionality resides inside this namespace.
@ SHE_DISCRETIZATION_EVEN_ODD_ORDER_GENERALIZED_DF
@ SHE_DISCRETIZATION_EVEN_ODD_ORDER_DF
Provides a number of fundamental constants. All constants in SI units.
Provides the exceptions used inside the viennashe::she namespace.
Defines a SHE quantity in (x, H)-space for use within the solvers of ViennaSHE.
Defines a generic simulator quantity for use within the solvers of ViennaSHE.
Implementation of spherical harmonics plus helper functions.