ComputationalGeometry
ComputationalGeometry is the class that implements geometries in chombo-discharge.
In principle, geometries consist of electrodes and dielectrics but there are many problems where the actual nature of the EB is irrelevant (such as fluid flow).
For other problems, such as ones involving electric fields, the classification into electrodes and dielectric are obviously important.
Tip
Here is the ComputationalGeometry C++ API.
ComputationalGeometry is not an abstract class.
The default implementation is an empty geometry, i.e., a geometry without any solid objects.
Several pre-defined geometries are included in $DISCHARGE_HOME/Geometries.
Making a non-empty ComputationalGeometry class requires that you inherit from ComputationalGeometry and instantiate the class members specified in Listing 2.
ComputationalGeometry base class. Highlighted members must be instantiated by the user in order to create a new geometry./*!
@brief Background permittivity
*/
Real m_eps0;
/*!
@brief True if we use the chombo-discharge geometry generation utility.
*/
bool m_useScanShop;
/*!
@brief Grid level where we begin using ScanShop
*/
ProblemDomain m_scanDomain;
/*!
@brief Maximum number of ghost cells that we will ever need
*/
int m_maxGhostEB;
/*!
@brief List of dielectrics
*/
Vector<Dielectric> m_dielectrics;
/*!
@brief List of electrodes
*/
Vector<Electrode> m_electrodes;
/*!
@brief The gas-phase implicit function (i.e. outside electrodes and dielectrics).
*/
RefCountedPtr<BaseIF> m_implicitFunctionGas;
/*!
@brief The solid-phase implicit function (i.e. the inside of the dielectrics).
*/
RefCountedPtr<BaseIF> m_implicitFunctionSolid;
Here, m_eps0 is the relative gas permittivity (which is virtually always 1), m_electrodes are the electrodes for the geometry and m_dielectrics are the dielectrics for the geometry.
These are described in detail below.
Implicit functions and compound geometries
ComputationalGeometry always uses implicit functions for describing the geometry, see Geometry representation.
These functions are analytic functions that describe the inside and outside regions of a solid object, and usually appear in the form \(f: \mathbb{R}^3\rightarrow \mathbb{R}\).
We point out that there is support in chombo-discharge for turning surface meshes into such functions, and arbitrary complex geometries can therefore be generated.
In chombo-discharge we always use signed distance functions wherever we can.
When geometries are created, the ComputationalGeometry class will first create the (approximations to the) compound signed distance functions that describe two possible material phases (gas and solid).
Here, the solid phase is the part of the computational domain inside the dielectrics, while the gas phase is the part of the computational domain that is outside both the electrodes and the dielectrics.
Because of this, there is a corresponding logic that underpins the partition into the three relevant domains. Let \(A\cup B\) be the union of two objects \(A\) and \(B\), and \(A \cap B\) be the intersection of the same objects. Furthermore, let \(f_1, f_2, \ldots\) denote the implicit functions for the electrodes. The electrode region is then given by
For the dielectric region, the canonical definition in chombo-discharge is that this region is composed of all regions that are inside a dielectric but outside of a provided electrode (note that the user can override this behavior in his/her implementation of ComputationalGeometry).
Specifically, if \(g_1, g_2, \ldots\) are the dielectric implicit functions, the dielectric region is given by
The region occupied by the gas is then given by \(\left(f \cup g\right)^\complement\).
Electrode
The Electrode class is responsible for describing an electrode and also its boundary electrostatic boundary condition.
Internally, this class is lightweight and consists only of a tuple that holds an implicit function and an associated boolean value that tells whether or not the level-set function is at a live voltage or not.
The constructor for the electrode class is given in Listing 3.
Electrode(const RefCountedPtr<BaseIF>& a_baseIF, const bool a_live, const Real a_voltageFraction = 1.0);
In the code block above, a_baseIF argument is the implicit function for the electrode object, and the a_live argument is used by some solvers in order to determine if the electrode is at a live voltage or not.
For example, if a_live is set to false, FieldSolver will fetch this value and determine that the electrode is at ground.
Otherwise, if a_live is set to true then FieldSolver will determine that the electrode is at live voltage, and the a_fraction argument is an optional argument that allows the user to set the potential to a specified fraction of the live voltage.
This is also used throughout other physics modules in chombo-discharge.
The user can also set a specified fraction of the live voltage but setting the a_voltageFraction parameter to a relative fraction of the applied voltage.
Tip
Here is the Electrode C++ API
Dielectric
The Dielectric class describes a dielectric similar to how Electrode describes an electrode object.
This class is lightweight and consists of a tuple that holds a level-set function and the relative associated permittivity (just like Electrode holds an implicit function and a relative voltage).
The constructors for this class are
/*!
@brief Full constructor which uses constant permittivity.
@param[in] a_baseIF Implicit function
@param[in] a_permittivity Constant permittivity
@note Calls the define function for constant permittivity.
*/
Dielectric(const RefCountedPtr<BaseIF>& a_baseIF, const Real a_permittivity);
/*!
@brief Full constructor which uses variable permittivity.
@param[in] a_baseIF Implicit function
@param[in] a_permittivity Variable permittivity
@note Calls the define function for variable permittivity.
*/
Dielectric(const RefCountedPtr<BaseIF>& a_baseIF, const std::function<Real(const RealVect a_pos)>& a_permittivity);
where the a_baseIF argument is the level-set function and the second argument sets a the permittivity.
In the constructor, the relative permittivity can be set to a constant (first constructor) or to a spatially varying value (second constructor).
Several solvers will then use the permittivities were specified by the user.
Tip
Here is the Dielectric C++ API
Retrieving parts
It is possible to retrieve the implicit functions for the electrodes and dielectrics through the following member functions:
/*!
@brief Get dielectrics
@return Dielectrics (m_dielectrics)
*/
const Vector<Dielectric>&
getDielectrics() const;
/*!
@brief Get electrodes
@return Electrodes (m_electrodes)
*/
const Vector<Electrode>&
getElectrodes() const;
Obtaining the implicit functions for each part can be useful when determining which object is closest to some physical location \(\mathbf{x}\). This is frequently used when, e.g., colliding particles with the embedded boundaries and we want to determine which electrode or dielectric the particle collided with.
Retrieving compound implicit functions
When generating the geometry we compute the implicit functions for each phase, the gas-phase, the dielectric-phase, and the electrodes. We outlined this process in Eq. 1 and Eq. 2.
To retrive the implicit function corresponding to a particular phase, use
const RefCountedPtr<BaseIF>& getImplicitFunction(const phase::which_phase a_phase) const;
where a_phase will be phase::gas or phase::solid.
This function will return the implicit function corresponding to all boundaries that contain the gas phase (phase::gas) or dielectric phase (phase::solid).
There is no corresponding function for the interior of the electrodes as the solutions are uninteresting in these regions.