# Path: gusto/configuration.py
# def set_log_handler(comm):
#     def __init__(self, **kwargs):
#     def __setattr__(self, name, value):
#     def name(self):
# class Configuration(object):
# class TimesteppingParameters(Configuration):
# class OutputParameters(Configuration):
# class CompressibleParameters(Configuration):
# class ShallowWaterParameters(Configuration):
# class EadyParameters(Configuration):
# class CompressibleEadyParameters(CompressibleParameters, EadyParameters):
# class AdvectionOptions(Configuration, metaclass=ABCMeta):
# class EmbeddedDGOptions(AdvectionOptions):
# class RecoveredOptions(AdvectionOptions):
# class SUPGOptions(AdvectionOptions):
#     N = 0.01  # Brunt-Vaisala frequency (1/s)
#     T_0 = 273.15  # ref. temperature
#     H = None  # mean depth
#     H = None
#     L = None
#     N = sqrt(EadyParameters.Nsq)


from abc import ABCMeta, abstractmethod
from firedrake import (Function, split, TrialFunction, TestFunction,
                       FacetNormal, inner, dx, cross, div, jump, avg, dS_v,
                       LinearVariationalProblem, LinearVariationalSolver,
                       dot, dS, Constant, as_vector, SpatialCoordinate)
from gusto.configuration import logger, DEBUG
from gusto import thermodynamics


__all__ = ["CompressibleForcing", "IncompressibleForcing", "EadyForcing", "CompressibleEadyForcing", "ShallowWaterForcing"]


class Forcing(object, metaclass=ABCMeta):
    """
    Base class for forcing terms for Gusto.

    :arg state: x :class:`.State` object.
    :arg euler_poincare: if True then the momentum equation is in Euler
    Poincare form and we need to add 0.5*grad(u^2) to the forcing term.
    If False then this term is not added.
    :arg linear: if True then we are solving a linear equation so nonlinear
    terms (namely the Euler Poincare term) should not be added.
    :arg extra_terms: extra terms to add to the u component of the forcing
    term - these will be multiplied by the appropriate test function.
    """

    def __init__(self, state, euler_poincare=False, linear=False, extra_terms=None, moisture=None):
        self.state = state
        if linear:
            self.euler_poincare = False

# Path: gusto/configuration.py
# def set_log_handler(comm):
#     def __init__(self, **kwargs):
#     def __setattr__(self, name, value):
#     def name(self):
# class Configuration(object):
# class TimesteppingParameters(Configuration):
# class OutputParameters(Configuration):
# class CompressibleParameters(Configuration):
# class ShallowWaterParameters(Configuration):
# class EadyParameters(Configuration):
# class CompressibleEadyParameters(CompressibleParameters, EadyParameters):
# class AdvectionOptions(Configuration, metaclass=ABCMeta):
# class EmbeddedDGOptions(AdvectionOptions):
# class RecoveredOptions(AdvectionOptions):
# class SUPGOptions(AdvectionOptions):
#     N = 0.01  # Brunt-Vaisala frequency (1/s)
#     T_0 = 273.15  # ref. temperature
#     H = None  # mean depth
#     H = None
#     L = None
#     N = sqrt(EadyParameters.Nsq)


# Path: gusto/forcing.py
from abc import ABCMeta, abstractmethod
from firedrake import (Function, split, TrialFunction, TestFunction,
                       FacetNormal, inner, dx, cross, div, jump, avg, dS_v,
                       LinearVariationalProblem, LinearVariationalSolver,
                       dot, dS, Constant, as_vector, SpatialCoordinate)
from gusto.configuration import logger, DEBUG
from gusto import thermodynamics



__all__ = ["CompressibleForcing", "IncompressibleForcing", "EadyForcing", "CompressibleEadyForcing", "ShallowWaterForcing"]


class Forcing(object, metaclass=ABCMeta):
    """
    Base class for forcing terms for Gusto.

    :arg state: x :class:`.State` object.
    :arg euler_poincare: if True then the momentum equation is in Euler
    Poincare form and we need to add 0.5*grad(u^2) to the forcing term.
    If False then this term is not added.
    :arg linear: if True then we are solving a linear equation so nonlinear
    terms (namely the Euler Poincare term) should not be added.
    :arg extra_terms: extra terms to add to the u component of the forcing
    term - these will be multiplied by the appropriate test function.
    """

    def __init__(self, state, euler_poincare=False, linear=False, extra_terms=None, moisture=None):
        self.state = state
        if linear:
            self.euler_poincare = False

            logger.warning('Setting euler_poincare to False because you have set linear=True')