Commit 5b42dbd2 authored by Simon Spannagel's avatar Simon Spannagel
Browse files

Mobility: tune range of TabulatedPow, extend documentation

parent 84cb69e5
Loading
Loading
Loading
Loading
+14 −7
Original line number Diff line number Diff line
@@ -117,15 +117,22 @@ namespace allpix {
    public:
        explicit CanaliFast(SensorMaterial material, double temperature)
            : JacoboniCanali(material, temperature), Canali(material, temperature) {
            LOG(WARNING) << "This mobility model uses a tabulated pow implementation and might be less accurate";
            LOG(INFO) << "This mobility model uses a tabulated pow implementation and might be less accurate";

            pow_e_beta = std::make_unique<TabulatedPow>(0., 1.0e6 / electron_Ec_, electron_Beta_, 1000);
            // The following boundary values and binning are chosen according to the expected range of the base.
            // Values are tabulated up to field values of 1000kV/cm

            // The lower boundary is 0 since we are looking at electric field magnitudes which are >= 0
            // The upper boundary is set to the pow function argument: maximum field divided by critical field
            pow_e_beta = std::make_unique<TabulatedPow>(0., Units::get(1000., "kV/cm") / electron_Ec_, electron_Beta_, 1000);
            pow_h_beta = std::make_unique<TabulatedPow>(0., Units::get(1000., "kV/cm") / hole_Ec_, hole_Beta_, 1000);

            // The lower boundary is 1 due to the offset present in the Canali formula
            // The upper boundary is set to the pow function argument: one plus pow from maximum / critical field
            pow_e_inv_beta = std::make_unique<TabulatedPow>(
                0., 10 * std::pow(100000. / electron_Ec_, electron_Beta_), 1.0 / electron_Beta_, 1000);
            pow_h_beta = std::make_unique<TabulatedPow>(0., 1000000. / hole_Ec_, hole_Beta_, 1000);
            pow_h_inv_beta =
                std::make_unique<TabulatedPow>(0., 10 * std::pow(100000. / hole_Ec_, hole_Beta_), 1.0 / hole_Beta_, 1000);
            LOG(DEBUG) << "Successfully generated pre-calculated pow tables";
                1., 1. + std::pow(Units::get(1000., "kV/cm") / electron_Ec_, electron_Beta_), 1.0 / electron_Beta_, 1000);
            pow_h_inv_beta = std::make_unique<TabulatedPow>(
                1., 1 + std::pow(Units::get(1000., "kV/cm") / hole_Ec_, hole_Beta_), 1.0 / hole_Beta_, 1000);
        }

        double operator()(const CarrierType& type, double efield_mag, double) const override {
+6 −1
Original line number Diff line number Diff line
@@ -27,6 +27,9 @@ namespace allpix {
     * the range of x, value of y and the binning has to be provided. The exact value of pow(x, y) is calculated for each
     * of the bin boundaries. After construction, the result of x^y can be obtained for every value of x within the defined
     * range using linear interpolation between neighboring bins.
     *
     * By not clamping the input value x to the pre-calculated range, but only the derived table bins, values at positions
     * outside the defined range are extrapolated linearly from the first and last bin.
     */
    class TabulatedPow {
    private:
@@ -61,7 +64,9 @@ namespace allpix {
         * @param  x     Value of the base to calculate x^y for.
         * @return Interpolated value of x^y
         *
         * @note The provided x has to be within the defined range provided to the constructor.
         * @note For precise approximation of pow, the provided x has to be within the defined range provided to the
         * constructor. For values outside the specified range, the return value will be a linear extrapolation from the
         * closest tabulated bin.
         */
        double get(double x) const {
            // Calculate position on pre-calculate table