PhotoElectrochemical Cell Simulator A Finite Element Based Simulator For Water Splitting Solar Cells
LDG_System::LDG< dim > Class Template Reference

This class builds two system matrices using the LDG method for the two ChargeCarrierSpace::Carrier objects in each of the ChargeCarrierSpace::CarrierPair objects. More...

#include <LDG.hpp>

## Public Member Functions

LDG ()
A simple constructor which instantiates test functions.

~LDG ()
A simple destructor which clears carrier_dof_handler.

void assemble_flux_terms (DoFHandler< dim > &carrier_dof_handler, ChargeCarrierSpace::CarrierPair< dim > &carrier_pair, FESystem< dim > &Poisson_fe, FESystem< dim > &carrier_fe)
Assembles the local LDG flux matrices for interior faces. More...

void assemble_local_flux_terms (Assembly::AssemblyScratch< dim > &scratch, Assembly::DriftDiffusion::CopyData< dim > &data, const double &penalty)
Assemble the local LDG flux matrices with no local refinement This corresponds to the case for two cells where they are on the same refinement level.

void assemble_local_LDG_cell_and_bc_terms (const typename DoFHandler< dim >::active_cell_iterator &cell, Assembly::AssemblyScratch< dim > &scratch, Assembly::DriftDiffusion::CopyData< dim > &data, const double &scaled_mobility_1, const double &scaled_mobility_2, const double &delta_t, const double &transient_or_steady, const double &penalty)
Assembles the local sytem matrix for this cell. More...

void assemble_local_LDG_mass_matrix (const typename DoFHandler< dim >::active_cell_iterator &cell, Assembly::AssemblyScratch< dim > &scratch, Assembly::DriftDiffusion::CopyData< dim > &data, const double &delta_t)

void assemble_local_test_rhs (const typename DoFHandler< dim >::active_cell_iterator &cell, Assembly::AssemblyScratch< dim > &scratch, Assembly::DriftDiffusion::CopyData< dim > &data, const double &penalty)

void assemble_local_test_transient_rhs (const typename DoFHandler< dim >::active_cell_iterator &cell, Assembly::AssemblyScratch< dim > &scratch, Assembly::DriftDiffusion::CopyData< dim > &data, const Vector< double > &old_solution, const double &time, const double &penalty)

void compute_coupled_errors (const Triangulation< dim > &triangulation, DoFHandler< dim > &carrier_dof_handler, Vector< double > &solution, double &potential_error, double &field_error, const double &time)
Computes the local error of your approximation for the LDG method on the cell and stores the errors in potential_error and field_error.  More...

void compute_errors (const Triangulation< dim > &triangulation, DoFHandler< dim > &carrier_dof_handler, Vector< double > &solution, double &potential_error, double &field_error, const bool &steady_state, const double &time)
Computes the local error of your approximation for the LDG method on the cell and stores the errors in potential_error and field_error.  More...

void compute_interface_errors (const Triangulation< dim > &triangulation, DoFHandler< dim > &carrier_dof_handler, Vector< double > &solution, double &potential_error, double &field_error, const double &time)
Computes the local error of your approximation for the LDG method on the cell and stores the errors in potential_error and field_error.  More...

void distribute_local_fluxes_to_global (ChargeCarrierSpace::CarrierPair< dim > &carrier_pair, Assembly::DriftDiffusion::CopyData< dim > &data)
Function which distributes local fluxes to global matrices.

void output_rescaled_results (DoFHandler< dim > &carrier_dof_handler, ChargeCarrierSpace::CarrierPair< dim > &carrier_pair, const ParameterSpace::Parameters &sim_params, const unsigned int time_step_number) const
Prints the current and density of each carrier in carrier pair with units. More...

void output_unscaled_results (DoFHandler< dim > &carrier_dof_handler, ChargeCarrierSpace::CarrierPair< dim > &carrier_pair, const unsigned int time_step_number) const
Prints the current and density of each carrier in carrier pair without units.

void output_unscaled_results_on_boundary (DoFHandler< dim > &carrier_dof_handler, ChargeCarrierSpace::CarrierPair< dim > &carrier_pair, const unsigned int time_step_number) const
Does the same as LDG_System::LDG::output_unscaled_results but only on the boundary.

## Data Fields

test_DD_Poisson::DD_DirichletBC< dim > test_DD_bc

test_DD_Poisson::DD_RightHandSide< dim > test_DD_rhs

test_DD_Poisson::DD_TrueSolution< dim > test_DD_solution

test_interface_problem::DirichletBC< dim > test_interface_bc

test_interface_problem::InterfaceFunction< dim > test_interface_function

const test_interface_problem::InitialConditions< dim > test_interface_initial

test_interface_problem::RightHandSide< dim > test_interface_rhs

test_interface_problem::TrueSolution< dim > test_interface_solution

test_LDG_IMEX::DirichletBC< dim > test_LDG_bc

test_LDG_IMEX::InterfaceFunction< dim > test_LDG_interface

test_LDG_IMEX::RightHandSide< dim > test_LDG_rhs

test_LDG_IMEX::TrueSolution< dim > test_LDG_solution

## Private Types

enum  { Interface, Dirichlet, Neumann, Schottky }

## Private Attributes

const test_Poisson::DirichletBoundaryValues< dim > test_Poisson_bc

const test_Poisson::RightHandSide< dim > test_Poisson_rhs

const test_Poisson::TrueSolution< dim > test_Poisson_solution

## Detailed Description

### template<int dim> class LDG_System::LDG< dim >

This class builds two system matrices using the LDG method for the two ChargeCarrierSpace::Carrier objects in each of the ChargeCarrierSpace::CarrierPair objects.

This class will build portions of the LDG local cell matrix for the general (non-dimensional) drift diffusion equation:

\begin{align} u_{t} \ - \ \boldsymbol \nabla \ \cdot \ \mu \left( s \boldsymbol \nabla \Phi u \ + \ \boldsymbol \nabla u \ \right) \; &= \; R(u) + G && \text{in} \; \Omega \\ u \; &= \; u_{D} && \text{on} \; \Omega_{D} \\ - \mu \left(s \boldsymbol \nabla \Phi \ u \ + \ \boldsymbol \nabla u \ \right) \ \cdot \ \boldsymbol \eta \; &= \; K (u) && \text{on} \; \partial \Omega_{N} \end{align}

We rewrite this in mixed form:

\begin{align} u_{t} \ + \ \nabla \ \textbf{q} \ &= \ R(u) \ + G && \text{in} \ \Omega \\ \mu^{-1} \ \textbf{q} \ & = \ -s \nabla \Phi \ u \ - \nabla u && \text{in} \ \Omega \\ \mu^{-1} \ \textbf{q} \ \cdot \boldsymbol \eta &= \ K(u) && \text{on} \ \partial \ \Omega_{N} \\ u \ &= \ u_{D} && \text{on} \ \partial \Omega_{D} \end{align}

The weak formulation for IMEX will be:

Find $$(u, \textbf{q}) \in W \times [t^{k-1}, t^{k}] \times \textbf{W}^{d} \times[ t^{k-1}, t^{k}]$$ such that,

\begin{align} \frac{1}{\Delta t} \left( v , u^{k} \right) - \tau \langle [[ \ v \ ]] , [[ u^{k} ]] \rangle_{\mathcal{E}_{h}^{0}} - \left( \boldsymbol \nabla v , \textbf{q}^{k} \right) + \langle [[ \ v \ ]] , \{ \textbf{q}^{k} \} \rangle_{\mathcal{E}_{h}^{0} \cap \partial \Omega_{D}} \ &= \ \left( v , R(u^{k-1}) + G \right) - \langle v, K( u^{k-1}) \rangle_{\Sigma} \nonumber \\ - \left( \boldsymbol \nabla \cdot \textbf{p} , u^{k-1} \right) \ - \ \langle [[ \, \textbf{p} \, ]] , \{ u^{k} \} \rangle_{\mathcal{E}^{0}_{h} \cap \partial \Omega_{N}} \ + \ \left( \textbf{p} , \textbf{q}^{k} \right) \ &= \ + \left( s \textbf{P} \cdot \boldsymbol \nabla \Phi , u^{k-1} \right) - \langle \textbf{p} , u_{D} \rangle_{ \partial \Omega_{N} } \end{align}

For all $$(v,\textbf{p}) \in W \times \textbf{W}^{d})$$.

The corresponding matrix will be of the form,

$\left[ \begin{matrix} \mu^{-1} A & B_{1} + F_{1} \\ B_{2} + F_{2} & \frac{1}{\Delta t} M + C \end{matrix} \right]$

This matrix will assembled once and stored in each carriers ChargeCarrierSpace::Carrier::system_matrix. The corresponding right hand side vector will assembled at every time step and stored in ChargeCarrierSpace::Carrier::system_rhs.

NOTE: We use IMEX time stepping so all non-linear terms and drift terms are time lagged and therefore on the right hand side. While they are are built in parallel, this place takes place outside of this class and in SOLARCELL::SolarCellProblem::assemble_semiconductor_rhs and SOLARCELL::SolarCellProblem::assemble_electrolyte_rhs.

NOTE: The LDG flux matrices $$F_{1}$$ and $$F_{2}$$. are built sequentially and this occurs in a loop outside this class, but calls the function assemble_local_flux_terms or in the case of a locally/adaptively refined mesh calls assemble_local_child_flux_terms.

NOTE: This assembles the ChargeCarrierSpace::Carrier::system_matrix for both ChargeCarrierSpace::CarrierPair::carrier_1 and ChargeCarrierSpace::CarrierPair::carrier_2 at the same time. It therefore deals with two equations of the above form, but proceed to explain it on only one of the equations.

## Member Function Documentation

template<int dim>
 void LDG_System::LDG< dim >::assemble_flux_terms ( DoFHandler< dim > & carrier_dof_handler, ChargeCarrierSpace::CarrierPair< dim > & carrier_pair, FESystem< dim > & Poisson_fe, FESystem< dim > & carrier_fe )

Assembles the local LDG flux matrices for interior faces.

These are the matrices which correspond to

$F_{1}(v,\textbf{q} ) \; = \; \langle [[ \ v \ ]] , \{ \textbf{q} \} \rangle_{\mathcal{E}_{h}^{0} }$

$F_{2}(\textbf{p},u ) \; = \; \langle [[ \, \textbf{p} \, ]] , \{ u \} \rangle_{\mathcal{E}^{0}_{h} }$

It will call LDG_System::LDG::assemble_local_flux_terms and LDG_System::LDG::assemble_local_child_flux_terms.

template<int dim>
 void LDG_System::LDG< dim >::assemble_local_LDG_cell_and_bc_terms ( const typename DoFHandler< dim >::active_cell_iterator & cell, Assembly::AssemblyScratch< dim > & scratch, Assembly::DriftDiffusion::CopyData< dim > & data, const double & scaled_mobility_1, const double & scaled_mobility_2, const double & delta_t, const double & transient_or_steady, const double & penalty )

Assembles the local sytem matrix for this cell.

This function can either be called when looping throug the cells by hand and assemblying the global matrix sequentially or by using the WorkStream to assemble it in parallel. If you use it in squential mode, than you must have the AssemblyScratch and DriftDiffusion::CopyData instantiated before calling this function.

This function loops through the quadrature points of this cell and assembles a local mass matrix for the LDG method applied to the drift-diffusion equation and stores it in DriftDiffusionCopyData.

Parameters
 delta_t is the fixed time step size. scaled_mobility is the scaled mobility constant $$\mu$$.

The matrix will be of the form,

$\left[ \begin{matrix} \mu^{-1} A & B_{1} \\ B_{2} & \frac{1}{\Delta t} M + C \end{matrix} \right]$

where,

$A(\textbf{p},\textbf{q} ) \; = \; \int_{\Omega} \ \textbf{p} \ \cdot \textbf{q} \ dx$

$M(v,u ) \; = \; \int_{\Omega} \ v \ u \ dx$

$B_{1}(v,\textbf{q} ) \; = \; \int_{\Omega} \ \nabla \ v \ \textbf{q} \ dx \ + \ \int_{\partial \Omega_{D}} v \ \textbf{q} \ \cdot \boldsymbol \eta \ ds$

$B_{2}(\textbf{p},u ) \; = \; \int_{\Omega} \ \nabla \ \cdot \ \textbf{p} \ u \ dx \ + \ \int_{\partial \Omega_{N}} \textbf{p} \cdot \boldsymbol \eta \ u \ ds$

template<int dim>
 void LDG_System::LDG< dim >::assemble_local_LDG_mass_matrix ( const typename DoFHandler< dim >::active_cell_iterator & cell, Assembly::AssemblyScratch< dim > & scratch, Assembly::DriftDiffusion::CopyData< dim > & data, const double & delta_t )

This function can either be called when looping throug the cells by hand and assemblying the global matrix sequentially or by using the WorkStream to assemble it in parallel. If you use it in squential mode, than you must have the Assembly::AssemblyScratch and Assembly::DriftDiffusion::CopyData instantiated before calling this function.

This function loops through the quadrature points of this cell and assembles a local mass matrix for the LDG method applied to the drift-diffusion equation and stores it in Assembly::DriftDiffusion::CopyData.

Parameters
 delta_t is the fixed time step size. scaled_mobility is the scaled mobility constant $$\mu$$.

The matrix will be of the form,

$\left[ \begin{matrix} 0 & 0 \\ 0 & \frac{1}{\Delta t} M \end{matrix} \right]$

where,

$M(v,u ) \; = \; \int_{\Omega} \ v \ u \ dx$

template<int dim>
 void LDG_System::LDG< dim >::assemble_local_test_rhs ( const typename DoFHandler< dim >::active_cell_iterator & cell, Assembly::AssemblyScratch< dim > & scratch, Assembly::DriftDiffusion::CopyData< dim > & data, const double & penalty )

Assembles the right hand sides carrier test case locally on each cell. Corresponds to the problem defined in SOLARCELL::SolarCellProblem::test_steady_state

template<int dim>
 void LDG_System::LDG< dim >::assemble_local_test_transient_rhs ( const typename DoFHandler< dim >::active_cell_iterator & cell, Assembly::AssemblyScratch< dim > & scratch, Assembly::DriftDiffusion::CopyData< dim > & data, const Vector< double > & old_solution, const double & time, const double & penalty )

Assembles the right hand side for test case locally on each cell. Corresponds to the problem defined in SOLARCELL::SolarCellProblem::test_transient.

template<int dim>
 void LDG_System::LDG< dim >::compute_coupled_errors ( const Triangulation< dim > & triangulation, DoFHandler< dim > & carrier_dof_handler, Vector< double > & solution, double & potential_error, double & field_error, const double & time )

Computes the local error of your approximation for the LDG method on the cell and stores the errors in potential_error and field_error.

Parameters
 solution is the carrier_solution vector to the LDG on Poisson's equation!  potential_error is $$L^{2}$$ error of the approximation the density.  field_error is $$L^{2}$$ error of the approximation current.

For problem defined in SOLARCELL::SolarCellProblem::test_DD_Poisson.

template<int dim>
 void LDG_System::LDG< dim >::compute_errors ( const Triangulation< dim > & triangulation, DoFHandler< dim > & carrier_dof_handler, Vector< double > & solution, double & potential_error, double & field_error, const bool & steady_state, const double & time )

Computes the local error of your approximation for the LDG method on the cell and stores the errors in potential_error and field_error.

Parameters
 solution is the carrier_solution vector to the LDG on Poisson's equation!  potential_error is $$L^{2}$$ error of the approximation the density.  field_error is $$L^{2}$$ error of the approximation current. For problem defined in SOLARCELL::SolarCellProblem::test_steady_state or defined in SOLARCELL::SolarCellProblem::test_transient.
template<int dim>
 void LDG_System::LDG< dim >::compute_interface_errors ( const Triangulation< dim > & triangulation, DoFHandler< dim > & carrier_dof_handler, Vector< double > & solution, double & potential_error, double & field_error, const double & time )

Computes the local error of your approximation for the LDG method on the cell and stores the errors in potential_error and field_error.

Parameters
 solution is the carrier_solution vector to the LDG on Poisson's equation!  potential_error is $$L^{2}$$ error of the approximation the density.  field_error is $$L^{2}$$ error of the approximation current.

For problem defined in SOLARCELL::SolarCellProblem::test_interface_coupling.

template<int dim>
 void LDG_System::LDG< dim >::output_rescaled_results ( DoFHandler< dim > & carrier_dof_handler, ChargeCarrierSpace::CarrierPair< dim > & carrier_pair, const ParameterSpace::Parameters & sim_params, const unsigned int time_step_number ) const

Prints the current and density of each carrier in carrier pair with units.

Note
The densities will still be without units because Paraview cant handle it otherwise.
I think this will only work when code is compiled in release mode,

The documentation for this class was generated from the following file:
• /Users/Mike/Documents/cpp_codes/PECS_2D/include/LDG.hpp