local_operator_cfg.hh 3.54 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
#ifndef DUNE_DORIE_RICHARDS_LOP_CFG_HH
#define DUNE_DORIE_RICHARDS_LOP_CFG_HH

#include <tuple>
#include <string>

#include <dune/common/exceptions.hh>
#include <dune/common/parametertree.hh>

#include <dune/dorie/common/logging.hh>

namespace Dune {
namespace Dorie {
namespace Operator {

/**
 *  \addtogroup RichardsModel
 *  \{
 */

//! Interior penalty type
enum class RichardsDGMethod
{
    NIPG, //!< Non-symmetric interior penalty
    SIPG, //!< Symmetric interior penalty (default)
    OBB,  //!< Oden, Babuska, Baumann (no penalty term)
    IIP   //!< Incomplete interior penalty (no symmetry term)
};

//! Gradient weighting
enum class RichardsDGWeights
{
    weightsOn, //!< harmonic weighting of flux contributions
    weightsOff //!< no weighting of flux contributions
};

//! Upwinding type
enum class RichardsUpwinding
{
    fullUpwind, //!< Upwind conductivity
    semiUpwind, //!< Upwind conductivity factor
    none //!< No upwinding
};


/// Read operator settings from a parameter file
/* \return Tuple of RichardsUpwinding, RichardsDGMethod, and
 *    RichardsDGWeights to be inserted into the local operator constructor.
 */
inline auto read_operator_settings(
    const Dune::ParameterTree& inifile)
        -> std::tuple<Operator::RichardsUpwinding,
                      Operator::RichardsDGMethod,
                      Operator::RichardsDGWeights>
{
    const auto log = Dorie::get_logger(log_richards);
    log->debug("Reading local operator settings:");

    RichardsUpwinding upwinding;
    RichardsDGMethod method = RichardsDGMethod::SIPG;
    RichardsDGWeights weights = RichardsDGWeights::weightsOn;

    // Upwinding
    const auto upwinding_str
        = inifile.get<std::string>("numerics.upwinding");
    log->debug("  Upwinding scheme: {}", upwinding_str);
    if (upwinding_str == "none")
        upwinding = RichardsUpwinding::none;
    else if (upwinding_str == "semiUpwind")
        upwinding = RichardsUpwinding::semiUpwind;
    else if (upwinding_str == "fullUpwind")
        upwinding = RichardsUpwinding::fullUpwind;
    else {
        log->error("Unknown upwinding scheme: {}", upwinding_str);
        DUNE_THROW(Dune::IOError, "Unknown upwinding scheme");
    }

    // Return here if the local operator is FV only
    if (inifile.get<int>("numerics.FEorder") == 0)
    {
        log->debug("  Ignoring settings 'numerics.DGMethod' and  "
                   "'numerics.DGWeights' for finite volume solver.");
        return std::make_tuple(upwinding, method, weights);
    }

    // DG Method
    const auto method_str = inifile.get<std::string>("numerics.DGMethod");
    log->debug("  DG method: {}", method_str);
    if (method_str == "SIPG")
        method = RichardsDGMethod::SIPG;
    else if (method_str == "NIPG")
        method = RichardsDGMethod::NIPG;
    else if (method_str == "OBB")
        method = RichardsDGMethod::OBB;
    else if (method_str == "IIP")
        method = RichardsDGMethod::IIP;
    else {
        log->error("Unknown DG method: {}", method_str);
        DUNE_THROW(Dune::IOError, "Unknown DG method");
    }

    // Harmonic weighting of fluxes
    const auto weights_str = inifile.get<bool>("numerics.DGWeights");
    log->debug("  Harmonic weights for interface fluxes (DG): {}", 
               weights_str);
    if (weights_str)
        weights = RichardsDGWeights::weightsOn;
    else
        weights = RichardsDGWeights::weightsOff;

    return std::make_tuple(upwinding, method, weights);
}

/**
 *  \}
 *  // group RichardsModel
 */

} // namespace Operator
} // namespace Dorie
} // namespace Dune

#endif // DUNE_DORIE_RICHARDS_LOP_CFG_HH