Пример #1
0
    def __init__(self, settings):
        super(Propagator, self).__init__(settings)

        coordinates = settings.partial_differential_equation.coordinates

        self._x, self._t = coordinates[0].symbol, coordinates[2].symbol
        if self.ndim > 1: self._y = coordinates[1].symbol

        self._nx, self._nt = self._get_as((coordinates[0].steps, coordinates[2].steps), int, settings)
        if self.ndim > 1: self._ny = self._get_as(coordinates[1].steps, int, settings)

        self._xmin, self._xmax, self._tmin, self._tmax = settings.get_numeric(
            (coordinates[0].min, coordinates[0].max, coordinates[2].min, coordinates[2].max))
        if self.ndim > 1: self._ymin, self._ymax = settings.get_numeric((coordinates[1].min, coordinates[1].max))

        import expresso.pycas as pc
        pe = settings.partial_differential_equation

        self._F_is_zero = settings.get_unitless(pe.F) == pc.Zero
        self._F_is_constant_in_z = settings.get_numeric(pc.derivative(pe.F, self._t)) == pc.Zero
        self._F_is_constant = self._F_is_constant_in_z and settings.get_numeric(pc.derivative(pe.F, self._x)) == pc.Zero
        if self.ndim > 1:
            self._F_is_constant &= settings.get_numeric(pc.derivative(pe.F, self._y)) == pc.Zero

        if self.ndim > 1:
            self.__coordinate_names = [c.index.name for c in coordinates]
        else:
            self.__coordinate_names = [c.index.name for c in (coordinates[0], coordinates[2])]
Пример #2
0
def add_partial_differential_equation_category(settings,coordinates = None):
    import expresso.pycas as pc
    sb = settings.simulation_box
    pde = settings.create_category('partial_differential_equation',short_name='PDE',info="parameters of the partial differential equation")

    arg_attrs = [sb.coordinate_dict[x] for x in coordinates] if coordinates is not None else sb.coordinates
    pde.add_attribute('coordinates', arg_attrs)

    x,y,z = [a.symbol for a in arg_attrs]

    dx,dy,dz = [s.step for s in arg_attrs]
    args = (x,y,z)

    pde.create_function('A',args )
    pde.create_function('C',args ,pde.A)
    pde.create_function('F',args )

    pde.create_function('ra',args ,pde.A*dz/dx**2,info="finite difference paramter")
    pde.create_function('rc',args ,pde.C*dz/dy**2,info="finite difference paramter")
    pde.create_function('rf',args ,pde.F*dz/2,info="finite difference paramter")

    pde.create_function('u',args ,info='solution to the PDE')
    pde.lock('u')

    pde.add_attribute('equation', pc.equal(pc.derivative(pde.u, z), pde.A * pc.derivative(pc.derivative(pde.u, x), x) + pde.C * pc.derivative(pc.derivative(pde.u, y), y) + pde.F * pde.u))

    pde.create_key('u0',pc.Function('u_0_PDE')(*args ),info="field initial condition")
    pde.create_function('u_boundary',args ,info="field boundary condition");

    pde.create_key(arg_attrs[1].name+'0',pc.Symbol(y.name+'_0_PDE'),(arg_attrs[1].min+arg_attrs[1].max)/2,info='Value to which the %s is set for 1D solvers' % y.name)

    pde.lock()

    return pde
Пример #3
0
    def __init__(self,settings):
        super(Propagator,self).__init__(settings)

        coordinates = settings.partial_differential_equation.coordinates

        self._x,self._t = coordinates[0].symbol,coordinates[2].symbol
        if self.ndim > 1: self._y = coordinates[1].symbol

        self._nx,self._nt = self._get_as((coordinates[0].steps,coordinates[2].steps),int,settings)
        if self.ndim > 1: self._ny = self._get_as(coordinates[1].steps,int,settings)

        self._xmin,self._xmax,self._tmin,self._tmax = settings.get_numeric((coordinates[0].min,coordinates[0].max,coordinates[2].min,coordinates[2].max))
        if self.ndim > 1: self._ymin,self._ymax = settings.get_numeric((coordinates[1].min,coordinates[1].max))

        import expresso.pycas as pc
        pe = settings.partial_differential_equation

        self._F_is_zero = settings.get_unitless( pe.F ) == pc.Zero
        self._F_is_constant_in_z = settings.get_numeric(pc.derivative(pe.F, self._t )) == pc.Zero
        self._F_is_constant = self._F_is_constant_in_z and settings.get_numeric(pc.derivative(pe.F, self._x)) == pc.Zero
        if self.ndim > 1: self._F_is_constant &= settings.get_numeric(pc.derivative(pe.F, self._y )) == pc.Zero

        if self.ndim > 1:
            self.__coordinate_names = [c.index.name for c in coordinates]
        else:
            self.__coordinate_names = [c.index.name for c in (coordinates[0],coordinates[2])]
Пример #4
0
def add_partial_differential_equation_category(settings, coordinates=None):
    import expresso.pycas as pc
    sb = settings.simulation_box
    pde = settings.create_category(
        'partial_differential_equation',
        short_name='PDE',
        info="parameters of the partial differential equation")

    arg_attrs = [sb.coordinate_dict[x] for x in coordinates
                 ] if coordinates is not None else sb.coordinates
    pde.add_attribute('coordinates', arg_attrs)

    x, y, z = [a.symbol for a in arg_attrs]

    dx, dy, dz = [s.step for s in arg_attrs]
    args = (x, y, z)

    pde.create_function('A', args)
    pde.create_function('C', args, pde.A)
    pde.create_function('F', args)

    pde.create_function('ra',
                        args,
                        pde.A * dz / dx**2,
                        info="finite difference paramter")
    pde.create_function('rc',
                        args,
                        pde.C * dz / dy**2,
                        info="finite difference paramter")
    pde.create_function('rf',
                        args,
                        pde.F * dz / 2,
                        info="finite difference paramter")

    pde.create_function('u', args, info='solution to the PDE')
    pde.lock('u')

    pde.add_attribute(
        'equation',
        pc.equal(
            pc.derivative(pde.u, z),
            pde.A * pc.derivative(pc.derivative(pde.u, x), x) +
            pde.C * pc.derivative(pc.derivative(pde.u, y), y) + pde.F * pde.u))

    pde.create_key('u0',
                   pc.Function('u_0_PDE')(*args),
                   info="field initial condition")
    pde.create_function('u_boundary', args, info="field boundary condition")

    pde.create_key(arg_attrs[1].name + '0',
                   pc.Symbol(y.name + '_0_PDE'),
                   0,
                   info='Value to which the %s is set for 1D solvers' % y.name)

    pde.lock()

    return pde
Пример #5
0
evaluator.add_rule(pc.OperationType(pc.Abs(pc.Types.Rational)),pc.Types.Rational)
evaluator.add_rule(pc.OperationType(pc.Abs(pc.Types.Integer)),pc.Types.Natural)
evaluator.add_rule(pc.OperationType(pc.Abs(pc.Types.Natural)),pc.Types.Natural)


evaluator.add_rule(pc.Type(pc.real(s.x)),pc.Types.Real)
evaluator.add_rule(pc.Type(pc.imag(s.x)),pc.Types.Real)
evaluator.add_rule(pc.Type(pc.conjugate(s.x)),pc.Types.Complex)

evaluator.add_rule(pc.Type(pc.Indicator(s.x)),pc.Types.Natural)
evaluator.add_rule(pc.Type(pc.OuterPiecewise(s.x)),pc.Type(s.x))
evaluator.add_rule(pc.Type(pc.InnerPiecewise((s.a,s.b),s.x)),pc.DominantType(pc.Type(s.a),pc.Type(pc.InnerPiecewise(s.x))))
evaluator.add_rule(pc.Type(pc.InnerPiecewise((s.a,s.b))),pc.Type(s.a))


evaluator.add_rule(pc.Type(pc.derivative(s.x,s.y)),pc.Type(s.x))
evaluator.add_rule(pc.Type(pc.evaluated_at(s.x,s.y,s.z)),pc.DominantType(pc.Type(s.x),pc.Type(s.z)))

evaluator.add_rule(pc.Type(pc.tmp(s.x)),pc.Type(s.x))
evaluator.add_rule(pc.Type(pc.sqrt(s.x)),pc.Type(s.x**(1/pc.S(2))))

evaluator.add_rule(pc.Type(pc.atan2(s.x,s.y)),pc.DominantType(pc.Type(s.x),pc.Type(s.x),pc.Types.Rational))

for f in [pc.exp,pc.log,pc.sin,pc.cos,pc.asin ,pc.acos,pc.tan,pc.atan,pc.cot,pc.acot,pc.sinh,pc.cosh,pc.asinh,pc.acosh,pc.tanh,pc.atanh,pc.coth,pc.acoth]:
    evaluator.add_rule(pc.Type(f(s.x)),pc.DominantType(pc.Type(s.x),pc.Types.Rational))

def issubtype(x,t):
    return pc.equal(pc.DominantType(pc.Type(x),t),t)

from .logic_evaluator import is_mpmath
from mpmath import mp
Пример #6
0
evaluator.add_rule(pc.InnerPiecewise((s.a,s.x),(s.b,s.x)),(s.a,s.x))
evaluator.add_rule(pc.InnerPiecewise((s.x,s.a),(s.x,s.b)),(s.x,pc.Or(s.a,s.b)))
evaluator.add_rule(pc.InnerPiecewise(pc.InnerPiecewise(s.x)),pc.InnerPiecewise(s.x))

evaluator.add_rule(pc.OuterPiecewise((s.a,s.b)),s.a*pc.Indicator(s.b))


from .logic_evaluator import contains_atomic


excluded_derivatives = {pc.InnerPiecewise,pc.Tuple}

def check_if_excluded_derivative(m):
    return not m[s.y].function in excluded_derivatives

evaluator.add_rule(pc.derivative(s.x,s.x),1)
evaluator.add_rule(pc.derivative(s.y,s.x),0,check_if_excluded_derivative,condition=pc.Not(contains_atomic(s.y,s.x)));

evaluator.add_rule(pc.derivative(s.a+s.b,s.x),pc.derivative(s.a,s.x)+pc.derivative(s.b,s.x))
evaluator.add_rule(pc.derivative(s.a*s.b,s.x),pc.derivative(s.a,s.x)*s.b+pc.derivative(s.b,s.x)*s.a)
evaluator.add_rule(pc.derivative(-s.x,s.x),-1)
evaluator.add_rule(pc.derivative(1/s.x,s.x),-s.x**-2)
evaluator.add_rule(pc.derivative(pc.log(s.x),s.x),1/s.x)


evaluator.add_rule(pc.derivative(pc.sin(s.x),s.x),pc.cos(s.x))
evaluator.add_rule(pc.derivative(pc.cos(s.x),s.x),-pc.sin(s.x))

# TODO: Add assumptions to expressions: the following is only valid if x != -1,1 or x != -i,i
evaluator.add_rule(pc.derivative(pc.asin(s.x),s.x),1/pc.sqrt(1-s.x**2))
evaluator.add_rule(pc.derivative(pc.acos(s.x),s.x),-1/pc.sqrt(1-s.x**2))
Пример #7
0
                   (s.x, pc.Or(s.a, s.b)))
evaluator.add_rule(pc.InnerPiecewise(pc.InnerPiecewise(s.x)),
                   pc.InnerPiecewise(s.x))

evaluator.add_rule(pc.OuterPiecewise((s.a, s.b)), s.a * pc.Indicator(s.b))

from .logic_evaluator import contains_atomic

excluded_derivatives = {pc.InnerPiecewise, pc.Tuple}


def check_if_excluded_derivative(m):
    return not m[s.y].function in excluded_derivatives


evaluator.add_rule(pc.derivative(s.x, s.x), 1)
evaluator.add_rule(pc.derivative(s.y, s.x),
                   0,
                   check_if_excluded_derivative,
                   condition=pc.Not(contains_atomic(s.y, s.x)))

evaluator.add_rule(pc.derivative(s.a + s.b, s.x),
                   pc.derivative(s.a, s.x) + pc.derivative(s.b, s.x))
evaluator.add_rule(
    pc.derivative(s.a * s.b, s.x),
    pc.derivative(s.a, s.x) * s.b + pc.derivative(s.b, s.x) * s.a)
evaluator.add_rule(pc.derivative(-s.x, s.x), -1)
evaluator.add_rule(pc.derivative(1 / s.x, s.x), -s.x**-2)
evaluator.add_rule(pc.derivative(pc.log(s.x), s.x), 1 / s.x)

evaluator.add_rule(pc.derivative(pc.sin(s.x), s.x), pc.cos(s.x))
Пример #8
0
evaluator.add_rule(pc.OperationType(pc.Abs(pc.Types.Natural)),
                   pc.Types.Natural)

evaluator.add_rule(pc.Type(pc.real(s.x)), pc.Types.Real)
evaluator.add_rule(pc.Type(pc.imag(s.x)), pc.Types.Real)
evaluator.add_rule(pc.OperationType(abs(s.x)), pc.Types.Real)
#evaluator.add_rule(pc.Type(pc.conjugate(s.x)),pc.Type(s.x))

evaluator.add_rule(pc.Type(pc.Indicator(s.x)), pc.Types.Natural)
evaluator.add_rule(pc.Type(pc.OuterPiecewise(s.x)), pc.Type(s.x))
evaluator.add_rule(
    pc.Type(pc.InnerPiecewise((s.a, s.b), s.x)),
    pc.DominantType(pc.Type(s.a), pc.Type(pc.InnerPiecewise(s.x))))
evaluator.add_rule(pc.Type(pc.InnerPiecewise((s.a, s.b))), pc.Type(s.a))

evaluator.add_rule(pc.Type(pc.derivative(s.x, s.y)), pc.Type(s.x))
evaluator.add_rule(pc.Type(pc.evaluated_at(s.x, s.y, s.z)),
                   pc.DominantType(pc.Type(s.x), pc.Type(s.z)))

evaluator.add_rule(pc.Type(pc.tmp(s.x)), pc.Type(s.x))
evaluator.add_rule(pc.Type(pc.sqrt(s.x)), pc.Type(s.x**(1 / pc.S(2))))

evaluator.add_rule(
    pc.Type(pc.atan2(s.x, s.y)),
    pc.DominantType(pc.Type(s.x), pc.Type(s.x), pc.Types.Rational))

for f in [
        pc.exp, pc.log, pc.sin, pc.cos, pc.asin, pc.acos, pc.tan, pc.atan,
        pc.cot, pc.acot, pc.sinh, pc.cosh, pc.asinh, pc.acosh, pc.tanh,
        pc.atanh, pc.coth, pc.acoth
]: