Exemple #1
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
Exemple #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'),
                   0,
                   info='Value to which the %s is set for 1D solvers' % y.name)

    pde.lock()

    return pde
    def __init__(self,settings):        
        super(FiniteDifferencesPropagator2D,self).__init__(settings)
        from _pypropagate import finite_difference_acF,finite_difference_a0F

        pde = settings.partial_differential_equation
        sb = settings.simulation_box

        self._2step = settings.get_numeric( pc.equal(pde.C, 0)  ) != pc.S(True)
        sf = 0.5 if self._2step else 1

        if self._2step:
            ra = settings.get_as(pde.ra*sf,complex)
            rc = settings.get_as(pde.rc*sf,complex)
        else:
            ra = pc.numpyfy(settings.get_unitless(pde.ra))(**{self._y.name + '_i':range(self._ny)})

        z,dz = sb.coordinates[2].symbol,sb.coordinates[2].step

        evaluators = self._get_evaluators([ (pde.rf*sf),
                                            (pde.rf*sf).subs(z,z-dz*sf),
                                            pde.u_boundary,
                                            pde.u_boundary.subs(z,z-dz*sf) ],
                                          settings,return_type=pc.Types.Complex,compile_to_c = True,parallel=True)

        self.__rf = evaluators[:2]
        self.__u_boundary = evaluators[2:]

        self._solver = finite_difference_acF() if self._2step else finite_difference_a0F()
        self._solver.resize(self._nx,self._ny)

        if self._2step:
            self._solver.ra = ra
            self._solver.rc = rc
        else:
            self._solver.ra.as_numpy()[:] = ra
        
        d,u,l,r = [(self._get_x_coordinates(),np.zeros(self._nx,dtype = np.uint)),
                   (self._get_x_coordinates(),np.ones(self._nx,dtype = np.uint)*(self._ny-1)),
                   (np.zeros(self._ny,dtype = np.uint),
                    self._get_y_coordinates()),
                   (np.ones(self._ny,dtype = np.uint)*(self._nx-1),self._get_y_coordinates())]

        self.__boundary_values = [np.concatenate([v[0] for v in d,u,l,r]),
                                  np.concatenate([v[1] for v in d,u,l,r]),
                                  np.zeros(2*self._nx+2*self._ny,dtype=np.uint)]

        self._set_initial_field(settings)
        self._reset()
for i in range(len(ordered_types)):
    evaluator.add_rule(pc.DominantType(pc.Types.Imaginary,ordered_types[i]),pc.Types.Complex)
    evaluator.add_rule(pc.Type(ordered_types[i]),pc.Types.Type)
    for j in range(i):
      evaluator.add_rule(pc.DominantType(ordered_types[j],ordered_types[i]),ordered_types[i])

def eval_type_equality(m):
    tx = m[s.x]
    ty = m[s.y]
    if tx in ordered_types and ty in ordered_types:
        m[s.z] = tx == ty
        return True
    return False

evaluator.add_rule(pc.equal(s.x,s.y),False,eval_type_equality)

evaluator.add_rule(pc.Type(pc.Types.Imaginary*pc.Types.Complex),pc.Types.Complex)
evaluator.add_rule(pc.DominantType(s.x,s.x),s.x)

evaluator.add_rule(pc.Type(pc.Types.Imaginary),pc.Types.Type)
evaluator.add_rule(pc.Type(pc.Type(s.x)),pc.Types.Type)

evaluator.add_rule(pc.Type(True),pc.Types.Boolean)
evaluator.add_rule(pc.Type(False),pc.Types.Boolean)
evaluator.add_rule(pc.Type(s.x),pc.Types.Natural,condition=is_explicit_natural(s.x))
evaluator.add_rule(pc.Type(1/s.x),pc.DominantType(pc.Types.Rational,pc.Type(s.x)))

evaluator.add_rule(pc.Type(s.x**s.y),pc.OperationType(pc.Type(s.x)**pc.Type(s.y)))
evaluator.add_rule(pc.Type(s.x*s.y),pc.OperationType(pc.Type(s.x)*pc.Type(s.y)))
def is_even(x):
    return pc.equal(pc.mod(x, 2), 0)
    binary_rule(lambda x, y: x**y if exp_length(x, y) < 100 else None),
    condition=are_explicit_numbers(s.x, s.y))

evaluator.add_rule(pc.mod(s.x, s.y),
                   s.z,
                   binary_rule(lambda x, y: x % y),
                   condition=are_explicit_numbers(s.x, s.y))
evaluator.add_rule(pc.mod(s.x, -s.y),
                   s.z,
                   binary_rule(lambda x, y: x % (-y)),
                   condition=are_explicit_numbers(s.x, s.y))
evaluator.add_rule(pc.mod(-s.x, s.y),
                   s.z,
                   binary_rule(lambda x, y: (-x) % (-y)),
                   condition=are_explicit_numbers(s.x, s.y))
evaluator.add_rule(pc.equal(s.x, s.y),
                   s.z,
                   binary_rule(lambda x, y: x == y),
                   condition=are_explicit_numbers(s.x, s.y))
evaluator.add_rule(pc.equal(s.x, -s.y),
                   False,
                   condition=are_explicit_numbers(s.x, s.y))

evaluator.add_rule(s.x < s.y,
                   s.z,
                   binary_rule(lambda x, y: x < y),
                   condition=are_explicit_numbers(s.x, s.y))
evaluator.add_rule(s.x < -s.y,
                   s.z,
                   binary_rule(lambda x, y: x < -y),
                   condition=are_explicit_numbers(s.x, s.y))
logic_evaluator.add_rule(pc.Not(True), False)
logic_evaluator.add_rule(pc.Not(False), True)

logic_evaluator.add_rule(pc.And(s.x, True), s.x)
logic_evaluator.add_rule(pc.And(s.x, False), False)
logic_evaluator.add_rule(pc.Or(s.x, True), True)
logic_evaluator.add_rule(pc.Or(s.x, False), s.x)

logic_evaluator.add_rule(pc.Not(pc.Not(s.x)), s.x)
logic_evaluator.add_rule(pc.And(s.x, pc.Not(s.x)), False)
logic_evaluator.add_rule(pc.Or(s.x, pc.Not(s.x)), True)

logic_evaluator.add_rule(pc.And(s.x, s.x), s.x)
logic_evaluator.add_rule(pc.Or(s.x, s.x), s.x)

logic_evaluator.add_rule(pc.equal(s.x, s.x), True)

logic_evaluator.add_rule(-s.x < -s.y, s.y < s.x)
'''
logic_evaluator.add_rule(s.x<s.x,False);
logic_evaluator.add_rule(-s.x<-s.y,s.y<s.x);
logic_evaluator.add_rule(s.x<-s.x,False);
logic_evaluator.add_rule(-s.x<s.x,False);
logic_evaluator.add_rule(s.x<=s.x,True);

logic_evaluator.add_rule(s.x>s.y,s.y<s.x);
logic_evaluator.add_rule(s.x>=s.y,s.y<=s.x);
logic_evaluator.add_rule(s.x<=s.y,pc.Or(s.x<s.y,equal(s.x,s.y)));

logic_evaluator.add_rule(And(x<y,y<x),False);
logic_evaluator.add_rule(pc.Not(True),False);
logic_evaluator.add_rule(pc.Not(False),True);

logic_evaluator.add_rule(pc.And(s.x,True),s.x);
logic_evaluator.add_rule(pc.And(s.x,False),False);
logic_evaluator.add_rule(pc.Or(s.x,True),True);
logic_evaluator.add_rule(pc.Or(s.x,False),s.x);

logic_evaluator.add_rule(pc.Not(pc.Not(s.x)),s.x);
logic_evaluator.add_rule(pc.And(s.x,pc.Not(s.x)),False);
logic_evaluator.add_rule(pc.Or(s.x,pc.Not(s.x)),True);

logic_evaluator.add_rule(pc.And(s.x,s.x),s.x);
logic_evaluator.add_rule(pc.Or(s.x,s.x),s.x);

logic_evaluator.add_rule(pc.equal(s.x,s.x),True);


logic_evaluator.add_rule(-s.x<-s.y,s.x<s.y)

'''
logic_evaluator.add_rule(s.x<s.x,False);
logic_evaluator.add_rule(-s.x<-s.y,s.y<s.x);
logic_evaluator.add_rule(s.x<-s.x,False);
logic_evaluator.add_rule(-s.x<s.x,False);
logic_evaluator.add_rule(s.x<=s.x,True);

logic_evaluator.add_rule(s.x>s.y,s.y<s.x);
logic_evaluator.add_rule(s.x>=s.y,s.y<=s.x);
logic_evaluator.add_rule(s.x<=s.y,pc.Or(s.x<s.y,equal(s.x,s.y)));
        ]

    m[s.z] = pc.multiplication(*exponents)


canonical_form.add_rule(pc.multiplication(s.x), s.x)
canonical_form.add_rule(pc.addition(s.x), s.x)
canonical_form.add_rule(pc.exponentiation(s.x), s.x)

canonical_form.add_rule(1 / s.x, s.x**-1)
canonical_form.add_rule(pc.exp(s.x), pc.e**s.x)
canonical_form.add_rule(s.x**s.y,
                        s.z,
                        normalize_exponentiation,
                        condition=pc.equal(
                            pc.DominantType(pc.Type(s.y), pc.Types.Real),
                            pc.Types.Real))

canonical_form.add_rule(pc.exp(s.x), pc.e**s.x)
canonical_form.add_rule(pc.sqrt(s.x), s.x**(1 / pc.S(2)))

canonical_form.add_rule(s.x > s.y, s.y < s.x)
canonical_form.add_rule(s.x >= s.y, s.y <= s.x)
canonical_form.add_rule(s.x <= s.y, pc.Or(s.x < s.y, pc.equal(s.x, s.y)))
canonical_form.add_rule(pc.unequal(s.x, s.y), pc.Not(pc.equal(s.x, s.y)))

canonical_form.add_rule(abs(s.x),
                        pc.Max(s.x, -s.x),
                        condition=pc.equal(
                            pc.DominantType(pc.Type(s.x), pc.Types.Real),
                            pc.Types.Real))
Exemple #10
0
evaluator.add_rule(s.x * 1, s.x)
evaluator.add_rule(s.x * 0, 0)

evaluator.add_rule(s.x**1, s.x)
evaluator.add_rule(s.x**0, 1)
evaluator.add_rule(1**s.x, 1)
evaluator.add_rule(0**s.x, 0, condition=s.x > 0)

factor_evaluator.add_rule(s.x * s.x, s.x**2)
evaluator.add_rule(s.x * s.x**-1, 1)

evaluator.add_rule(
    (s.x**s.a)**s.b,
    s.x**(s.a * s.b),
    condition=pc.equal(pc.DominantType(pc.Type(s.b), pc.Types.Integer),
                       pc.Types.Integer))

from .numeric_evaluator import is_even, is_uneven
from .type_evaluator import issubtype

evaluator.add_rule((s.x**s.a)**(s.a**-1),
                   abs(s.x),
                   condition=pc.And(issubtype(s.x, pc.Types.Real),
                                    is_even(s.a)))
evaluator.add_rule((s.x**s.a)**(s.a**-1),
                   s.x,
                   condition=pc.And(issubtype(s.x, pc.Types.Real),
                                    is_uneven(s.a)))

evaluator.add_rule((-s.x)**(s.a), s.x**s.a, condition=is_even(s.a))
evaluator.add_rule((-s.x)**(s.a), -(s.x)**s.a, condition=is_uneven(s.a))
Exemple #11
0
def issubtype(x, t):
    return pc.equal(pc.DominantType(pc.Type(x), t), t)
Exemple #12
0
    evaluator.add_rule(pc.Type(ordered_types[i]), pc.Types.Type)
    for j in range(i):
        evaluator.add_rule(pc.DominantType(ordered_types[j], ordered_types[i]),
                           ordered_types[i])


def eval_type_equality(m):
    tx = m[s.x]
    ty = m[s.y]
    if tx in ordered_types and ty in ordered_types:
        m[s.z] = tx == ty
        return True
    return False


evaluator.add_rule(pc.equal(s.x, s.y), False, eval_type_equality)

evaluator.add_rule(pc.Type(pc.Types.Imaginary * pc.Types.Complex),
                   pc.Types.Complex)
evaluator.add_rule(pc.DominantType(s.x, s.x), s.x)

evaluator.add_rule(pc.Type(pc.Types.Imaginary), pc.Types.Type)
evaluator.add_rule(pc.Type(pc.Type(s.x)), pc.Types.Type)

evaluator.add_rule(pc.Type(True), pc.Types.Boolean)
evaluator.add_rule(pc.Type(False), pc.Types.Boolean)
evaluator.add_rule(pc.Type(s.x),
                   pc.Types.Natural,
                   condition=is_explicit_natural(s.x))
evaluator.add_rule(pc.Type(1 / s.x),
                   pc.DominantType(pc.Types.Rational, pc.Type(s.x)))
def is_even(x):
    return pc.equal(pc.mod(x,2),0)
evaluator.add_rule(-s.x-s.y, -s.z, binary_rule(lambda x, y: x + y), condition=are_explicit_numbers(s.x, s.y))
evaluator.add_rule(s.x - s.y, s.z, binary_rule(lambda x, y: x - y), condition=are_explicit_numbers(s.x, s.y))
evaluator.add_rule(s.x * s.y, s.z, binary_rule(lambda x, y: x * y), condition=are_explicit_numbers(s.x, s.y))
evaluator.add_rule(s.x ** s.a * s.y ** s.a, s.z ** s.a, binary_rule(lambda x, y: x * y), condition=are_explicit_numbers(s.x, s.y))

def exp_length(a,b):
    import math as m
    return m.log10(a)*b

evaluator.add_rule(s.x ** s.y, s.z, binary_rule(lambda x, y: x ** y if exp_length(x,y)<100 else None), condition=are_explicit_numbers(s.x, s.y))
evaluator.add_rule(s.x ** -s.y, s.z ** -1, binary_rule(lambda x, y: x ** y if exp_length(x,y)<100 else None), condition=are_explicit_numbers(s.x, s.y))

evaluator.add_rule(pc.mod(s.x,s.y), s.z, binary_rule(lambda x, y: x % y), condition=are_explicit_numbers(s.x, s.y))
evaluator.add_rule(pc.mod(s.x,-s.y), s.z, binary_rule(lambda x, y: x % (-y)), condition=are_explicit_numbers(s.x, s.y))
evaluator.add_rule(pc.mod(-s.x,s.y), s.z, binary_rule(lambda x, y: (-x) % (-y)), condition=are_explicit_numbers(s.x, s.y))
evaluator.add_rule(pc.equal(s.x,s.y), s.z, binary_rule(lambda x, y: x == y), condition=are_explicit_numbers(s.x, s.y))
evaluator.add_rule(pc.equal(s.x,-s.y), False, condition=are_explicit_numbers(s.x, s.y))

evaluator.add_rule(s.x < s.y, s.z, binary_rule(lambda x, y: x < y), condition=are_explicit_numbers(s.x, s.y))
evaluator.add_rule(s.x < -s.y, s.z, binary_rule(lambda x, y: x < -y), condition=are_explicit_numbers(s.x, s.y))
evaluator.add_rule(-s.x < s.y, s.z, binary_rule(lambda x, y: -x < y), condition=are_explicit_numbers(s.x, s.y))


#evaluator.add_rule(s.a**s.x*s.b**-s.x, (s.a*s.b**-1)**(s.x),condition=are_explicit_numbers(s.a, s.b))

def is_even(x):
    return pc.equal(pc.mod(x,2),0)

from type_evaluator import issubtype

def is_uneven(x):
def issubtype(x,t):
    return pc.equal(pc.DominantType(pc.Type(x),t),t)
    e = m[s.y]
    exponents = [(arg.args[0]**arg.args[1])**e for arg in f.args if arg.function == pc.exponentiation]
    exponents += [arg ** e for arg in f.args if isinstance(arg.value, pc.Number) or arg == pc.I]

    if len(candidates) != len(f.args):
        exponents += [pc.multiplication(*[arg for arg in f.args if arg not in candidates])**e]

    m[s.z] = pc.multiplication(*exponents)

canonical_form.add_rule(pc.multiplication(s.x),s.x)
canonical_form.add_rule(pc.addition(s.x),s.x)
canonical_form.add_rule(pc.exponentiation(s.x),s.x)

canonical_form.add_rule(1/s.x, s.x**-1)
canonical_form.add_rule(pc.exp(s.x), pc.e**s.x)
canonical_form.add_rule(s.x**s.y, s.z, normalize_exponentiation,condition=pc.equal(pc.DominantType(pc.Type(s.y),pc.Types.Real),pc.Types.Real))

canonical_form.add_rule(pc.exp(s.x),pc.e**s.x)
canonical_form.add_rule(pc.sqrt(s.x),s.x**(1/pc.S(2)))


canonical_form.add_rule(s.x>s.y,s.y<s.x)
canonical_form.add_rule(s.x>=s.y,s.y<=s.x)
canonical_form.add_rule(s.x<=s.y,pc.Or(s.x<s.y,pc.equal(s.x,s.y)))
canonical_form.add_rule(pc.unequal(s.x,s.y),pc.Not(pc.equal(s.x,s.y)));


canonical_form.add_rule(abs(s.x),pc.Max(s.x,-s.x),condition=pc.equal(pc.DominantType(pc.Type(s.x),pc.Types.Real),pc.Types.Real))

canonical_form.add_rule(pc.Max(s.a,s.b),-pc.Min(-s.a,-s.b))
evaluator.add_rule(s.x+0, s.x)
evaluator.add_rule(s.x-s.x, 0)
evaluator.add_rule(s.x+s.x, 2*s.x)

evaluator.add_rule(s.x*1, s.x)
evaluator.add_rule(s.x*0, 0)

evaluator.add_rule(s.x**1, s.x)
evaluator.add_rule(s.x**0, 1)
evaluator.add_rule(1**s.x, 1)
evaluator.add_rule(0**s.x, 0,condition=s.x>0)

factor_evaluator.add_rule(s.x*s.x, s.x**2)
evaluator.add_rule(s.x*s.x**-1, 1)

evaluator.add_rule((s.x**s.a)**s.b, s.x**(s.a*s.b),condition=pc.equal(pc.DominantType(pc.Type(s.b),pc.Types.Integer),pc.Types.Integer))

from .numeric_evaluator import is_even,is_uneven
from .type_evaluator import issubtype

evaluator.add_rule((s.x**s.a)**(s.a**-1), abs(s.x),condition=pc.And( issubtype(s.x,pc.Types.Real),is_even(s.a) ) )
evaluator.add_rule((s.x**s.a)**(s.a**-1), s.x,condition=pc.And( issubtype(s.x,pc.Types.Real),is_uneven(s.a)))


evaluator.add_rule((-s.x)**(s.a), s.x**s.a ,condition=is_even(s.a))
evaluator.add_rule((-s.x)**(s.a), -(s.x)**s.a ,condition=is_uneven(s.a))



factor_evaluator.add_rule(s.x**s.n*s.y**-s.n,(s.x*s.y**-1)**s.n,condition=pc.Or(s.y>0,issubtype(s.n,pc.Types.Integer)))