1#ifndef VIENNASHE_DD_POSTPROC_CURRENT_HPP
2#define VIENNASHE_DD_POSTPROC_CURRENT_HPP
25#include "viennagrid/mesh/mesh.hpp"
26#include "viennagrid/algorithm/volume.hpp"
27#include "viennagrid/algorithm/interface.hpp"
56 template <
typename DeviceType,
57 typename PotentialAccessorType,
58 typename AccessorTypeCarrier,
59 typename MobilityModel>
62 typedef typename DeviceType::mesh_type
MeshType;
64 typedef typename viennagrid::result_of::point<MeshType>::type
PointType;
65 typedef typename viennagrid::result_of::vertex<MeshType>::type
VertexType;
66 typedef typename viennagrid::result_of::facet<MeshType>::type
FacetType;
67 typedef typename viennagrid::result_of::cell<MeshType>::type
CellType;
74 AccessorTypeCarrier
const & carrier,
75 MobilityModel
const & mobility_model)
76 : device_(
device), carrier_type_id_(ctype), potential_(
potential), carrier_(carrier), mobility_(mobility_model) { }
80 typedef typename viennagrid::result_of::const_coboundary_range<MeshType, FacetType, CellType>::type CellOnFacetContainer;
81 typedef typename viennagrid::result_of::iterator<CellOnFacetContainer>::type CellOnFacetIterator;
87 CellOnFacetContainer cells_on_facet(device_.mesh(), viennagrid::handle(device_.mesh(), facet));
89 if (cells_on_facet.size() < 2)
92 CellOnFacetIterator cofit = cells_on_facet.begin();
104 const double potential_center = potential_(c1);
106 ? bnd_carrier_density(c2, device_.get_lattice_temperature(c2))
107 : carrier_.get_value(c1);
108 const double T = device_.get_lattice_temperature(c1);
110 const double mobility = mobility_(c1, c2, potential_);
112 const double connection_len =
viennagrid::norm_2(viennagrid::centroid(c2) - viennagrid::centroid(c1));
113 const double potential_outer = potential_(c2);
115 ? bnd_carrier_density(c1, device_.get_lattice_temperature(c1))
116 : carrier_.get_value(c2);
118 if ( carrier_outer <= 0 || carrier_center <= 0 )
return 0;
121 const double charge_flux = flux_approximator(carrier_center, carrier_outer, potential_center, potential_outer, connection_len, mobility, T);
122 const double Jmag = polarity * mobility * charge_flux;
128 DeviceType
const & device_;
130 PotentialAccessorType
const & potential_;
131 AccessorTypeCarrier
const & carrier_;
132 MobilityModel
const & mobility_;
136 template <
typename DeviceType,
typename SimulatorQuantity>
139 typedef typename DeviceType::mesh_type MeshType;
142 typedef typename viennagrid::result_of::cell<MeshType>::type
cell_type;
150 SimulatorQuantity
const & quantity_;
159 template <
typename DeviceType,
160 typename PotentialQuantityType,
161 typename CarrierQuantityType,
162 typename MobilityModel>
168 typedef typename viennagrid::result_of::point<MeshType>::type
PointType;
169 typedef typename viennagrid::result_of::vertex<MeshType>::type
VertexType;
170 typedef typename viennagrid::result_of::facet<MeshType>::type
FacetType;
171 typedef typename viennagrid::result_of::cell<MeshType>::type
CellType;
179 CarrierQuantityType
const & carrier,
180 MobilityModel
const & mobility_model)
181 : device_(
device), carrier_type_id_(ctype), potential_(
potential), carrier_(carrier), mobility_(mobility_model) { }
186 current_density_evaluator edge_evaluator(device_, carrier_type_id_, potential_, carrier_, mobility_);
187 return edge_evaluator(facet);
192 typedef typename viennagrid::result_of::const_facet_range<CellType>::type FacetOnCellContainer;
197 std::vector<double> J(3);
199 if (!carrier_contribution_filter(cell))
return J;
203 current_density_evaluator facet_evaluator(device_, carrier_type_id_, potential_, carrier_, mobility_);
205 FacetOnCellContainer facets_on_cell(cell);
207 cell, facets_on_cell,
208 result, facet_evaluator);
214 DeviceType
const & device_;
216 PotentialQuantityType
const & potential_;
217 CarrierQuantityType
const & carrier_;
218 MobilityModel
const & mobility_;
231 template <
typename DeviceType,
232 typename PotentialQuantityType,
233 typename CarrierQuantityType,
234 typename MobilityModel,
235 typename ContainerType>
238 CarrierQuantityType
const & carrier,
240 MobilityModel
const & mobility_model,
241 ContainerType & container)
254 template <
typename DeviceT,
typename CurrentDensityT>
256 CurrentDensityT
const & current_on_facet)
258 typedef typename DeviceT::mesh_type MeshType;
260 typedef typename viennagrid::result_of::point<MeshType>::type PointType;
261 typedef typename viennagrid::result_of::facet<MeshType>::type FacetType;
262 typedef typename viennagrid::result_of::cell<MeshType>::type CellType;
264 typedef typename viennagrid::result_of::const_cell_range<MeshType>::type CellContainer;
265 typedef typename viennagrid::result_of::iterator<CellContainer>::type CellIterator;
267 typedef typename viennagrid::result_of::const_facet_range<CellType>::type FacetOnCellContainer;
268 typedef typename viennagrid::result_of::iterator<FacetOnCellContainer>::type FacetOnCellIterator;
270 typedef typename viennagrid::result_of::const_coboundary_range<MeshType, FacetType, CellType>::type CellOnFacetContainer;
273 for (CellIterator cit = cells.begin();
277 double net_box_flux = 0;
278 double partial_flux_max = 0;
280 PointType centroid_cell = viennagrid::centroid(*cit);
282 FacetOnCellContainer facets_on_cell(*cit);
283 for (FacetOnCellIterator focit = facets_on_cell.begin();
284 focit != facets_on_cell.end();
289 if (!other_cell_ptr)
continue;
291 PointType centroid_other_cell = viennagrid::centroid(*other_cell_ptr);
292 PointType cell_connection = centroid_other_cell - centroid_cell;
293 PointType cell_connection_normalized = cell_connection / viennagrid::norm(cell_connection);
295 const double weighted_interface_area = viennagrid::volume(*focit) * viennagrid::inner_prod(facet_unit_normal, cell_connection_normalized);
296 double contribution_from_facet = current_on_facet(*focit) * weighted_interface_area;
297 if (std::fabs(contribution_from_facet) > partial_flux_max)
298 partial_flux_max = std::fabs(contribution_from_facet);
300 CellOnFacetContainer cells_on_facet(
device.
mesh(), focit.handle());
301 if ( &(*cit) == &(cells_on_facet[0]) )
302 net_box_flux -= contribution_from_facet;
304 net_box_flux += contribution_from_facet;
307 if (partial_flux_max > 0)
309 if ( std::fabs(net_box_flux / partial_flux_max) > 1e-10)
311 log::info() <<
"-- Box " << *cit <<
" --" << std::endl;
312 log::info() <<
"Net box flux (should be zero, unless at contact): " << net_box_flux <<
" with maximum " << partial_flux_max << std::endl;
319 template <
typename DeviceType,
320 typename PotentialQuantityType,
321 typename CarrierQuantityType,
322 typename MobilityModel>
326 CarrierQuantityType
const & carrier,
327 MobilityModel
const & mobility_model)
Contains the definition of per-device accessors (read-only!) for various quantities.
Defines a set of checker functors for micro-tests within ViennaSHE.
An accessor to the current density on vertices and edges (drift diffusion only!)
viennagrid::result_of::point< MeshType >::type PointType
value_type operator()(CellType const &cell) const
viennagrid::result_of::cell< MeshType >::type CellType
DeviceType::mesh_type MeshType
std::vector< double > value_type
viennagrid::result_of::vertex< MeshType >::type VertexType
viennagrid::result_of::facet< MeshType >::type FacetType
current_density_wrapper(DeviceType const &device, viennashe::carrier_type_id ctype, PotentialQuantityType const &potential, CarrierQuantityType const &carrier, MobilityModel const &mobility_model)
double operator()(FacetType const &facet) const
MeshT const & mesh() const
Returns the underlying mesh.
viennagrid::result_of::cell< MeshType >::type cell_type
value_type operator()(cell_type const &c) const
macroscopic_carrier_mask_filter(SimulatorQuantity const &quan)
Defines the physical properties of a device, e.g. doping. This is the implementation for 2d and highe...
Dispatcher for Scharfetter-Gummel discretization of electron and hold fluxes.
A functor which holds a single value. Used in most of the postprocessing routines.
Helper routines for projecting normal components of a vector-valued quantity defined on edges to vert...
Contains forward declarations and definition of small classes that must be defined at an early stage.
A logging facility providing fine-grained control over logging in ViennaSHE.
Writer for arbitrary macroscopic quantities.
A very simple material database. Needs to be replaced by something more versatile soon.
logger< true > info()
Used to log infos. The logging level is logINFO.
bool is_semiconductor(long material_id)
Convenience function for checking whether the supplied material ID refers to a semiconductor.
bool is_insulator(long material_id)
Convenience function for checking whether the supplied material ID refers to an oxide.
bool is_conductor(long material_id)
Convenience function for checking whether the supplied material ID refers to a metal.
VectorType::value_type norm_2(VectorType const &v)
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.
CellT const * get_other_cell_of_facet(MeshT const &mesh, FacetT const &facet, CellT const &cell)
Helper function returning a const-pointer to the 'second cell' of a facet, or NULL if there is no sec...
The main ViennaSHE namespace. All functionality resides inside this namespace.
void write_current_density_to_container(DeviceType const &device, PotentialQuantityType const &potential, CarrierQuantityType const &carrier, viennashe::carrier_type_id ctype, MobilityModel const &mobility_model, ContainerType &container)
Convenience function for writing the electric field to a container.
carrier_type_id
Enumeration type for selecting the carrier type.
void check_current_conservation(DeviceT const &device, CurrentDensityT const ¤t_on_facet)
Checks current conservation for SHE. Writes information using log::info().
void write_macroscopic_quantity_to_container(DeviceType const &device, MacroscopicQuantityAccessor const &quantity, ContainerType &quantity_container)
Writes the provided macroscopic quantity to the container provided.
Provides a number of fundamental constants. All constants in SI units.
Returns a few helper routines for computing physical quantities. To be replaced in the future.
Scharfetter-Gummel stabilization of the continuity equations.
An accessor to the current density (drift diffusion only!) on edges.
value_type operator()(FacetType const &facet) const
current_density_on_facet(DeviceType const &device, viennashe::carrier_type_id ctype, PotentialAccessorType const &potential, AccessorTypeCarrier const &carrier, MobilityModel const &mobility_model)
viennagrid::result_of::facet< MeshType >::type FacetType
viennagrid::result_of::cell< MeshType >::type CellType
viennagrid::result_of::point< MeshType >::type PointType
DeviceType::mesh_type MeshType
viennagrid::result_of::vertex< MeshType >::type VertexType