示例#1
0
def periodic_envelope_propagation(field,omega0,s=1,z=None,omega=None,t=None):

    import numpy as np
    import expresso.pycas as pc
    from .. import units

    if z is None:
        z = pc.Symbol('z')
    if t is None:
        t = pc.Symbol('t')
    if omega is None:
        omega = pc.Symbol('omega')
        
    zindex = field.get_axis_index(z)
    omegaindex = field.get_axis_index(omega)

    omegamin,omegamax = field.bounds[omegaindex]
    zmin, zmax = field.bounds[zindex]
    sz = zmax - zmin

    ukmin = float(field.evaluate( (omegamin-omega0)/units.c*sz ))
    ukmax = float(field.evaluate( (omegamax-omega0)/units.c*sz ))
    uzmin = 0
    uzmax = 1

    nz,ik = np.meshgrid(np.linspace(uzmin,uzmax,field.shape[zindex]),np.linspace(1j*ukmin,1j*ukmax,field.shape[omegaindex]))
    factor = np.exp(-ik*nz/float(s))
    del nz,ik
    transform = field * factor
    del factor
    tdfield = fourier_transform(transform, omega, t, inverse=True)
    del transform
    tdfield.bounds[omegaindex] = [(b - tdfield.bounds[omegaindex][0]).evaluate() for b in tdfield.bounds[omegaindex]]

    return tdfield
示例#2
0
    def __init__(self, settings, thread_count=1):
        import expresso.pycas as pc

        super(Fresnel2D, self).__init__(settings)
        self._thread_count = thread_count

        self._set_initial_field(settings)

        pe = settings.partial_differential_equation
        x, y, z = settings.partial_differential_equation.coordinates

        R, = self._get_evaluators([pc.exp(pe.F * z.step)],
                                  settings,
                                  return_type=pc.Types.Complex)

        D = pc.numpyfy(
            self._evaluate(pc.exp(-pe.A * z.step * (pc.Symbol('kx')**2)),
                           settings))

        if self._F_is_constant_in_z:
            self.__R_step = R(*self._get_indices())
        else:
            self.__R = R

        import numpy as np
        fx = 2 * np.pi / (self._nx * self._get_as(x.step, float, settings))
        kx = fx * (self._nx / 2. - np.abs(np.arange(self._nx) - self._nx / 2.))
        self.__D_step = D(kx=kx, **self._get_indices_dict())
示例#3
0
 def __init__(self, sb, name):
     self.name = name
     self.symbol = getattr(sb, name)
     self.min = getattr(sb, name + 'min')
     self.max = getattr(sb, name + 'max')
     self.step = getattr(sb, 'd' + name)
     self.steps = getattr(sb, 'N' + name)
     self.size = getattr(sb, 's' + name)
     self.index = pc.Symbol('%s_i' % name, type=pc.Types.Natural)
示例#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
def plot(arg, *args, **kwargs):
    """
    Simple plot function for 1D and 2D coordinate arrays. If the data is complex, the absolute square value of the data will be plottted.

    Parameters
    -----------
    arg: coordinate array
          the input data

    **kwargs: additional parameters to be passed to the plot functions

    Returns
    --------
    plot: output of ax.plot for 1D and ax.imshow for 2D arrays

    """
    import expresso.pycas
    import numpy as np
    from coordinate_ndarray import CoordinateNDArray

    if isinstance(arg, expresso.pycas.Expression):
        from .settings import Settings

        if len(args) > 0 and isinstance(args[0], Settings):
            settings = args[0]
            args = list(args)
            del args[0]
        else:
            settings = kwargs.get('settings')
            if not settings:
                raise ValueError(
                    'cannot plot expression: no settings provided')
            del kwargs['settings']

        arg = expression_to_array(arg, settings)

        if isinstance(arg, (float, complex)):
            print arg
            return

    elif not isinstance(arg, CoordinateNDArray):
        if isinstance(arg, np.ndarray):
            pc = expresso.pycas
            arg = CoordinateNDArray(
                arg, [(pc.S(0), pc.S(n)) for n in arg.shape],
                [pc.Symbol('x_%i' % i) for i in range(len(arg.shape))])
        else:
            raise ValueError(
                'cannot plot non CoordinateNDArray object. For plotting regular arrays please use the matplotlib.pyplot module.'
            )

    if not np.can_cast(arg.data.dtype, np.float128):
        if np.all(arg.data.imag == 0): arg = arg.real
        else: arg = abs(arg)**2
    if len(arg.axis) == 1: return line_plot(arg, *args, **kwargs)
    elif len(arg.axis) == 2: return image_plot(arg, *args, **kwargs)
    else: raise ValueError("input array must be one or two dimensional")
示例#6
0
def create_unit(name):
    u = pc.Symbol("SI base unit " + name,
                  type=pc.Types.Real,
                  positive=True,
                  latex=r'\mathrm{%s}' % name,
                  repr=name)
    globals()[name] = u
    base_units.add(u)
    add_metric_prefixes(name)
示例#7
0
    def __init__(self, settings, thread_count=None):

        super(Fresnel3D, self).__init__(settings)
        if thread_count == None:
            import multiprocessing
            thread_count = multiprocessing.cpu_count()
        self._thread_count = thread_count
        pe = settings.partial_differential_equation
        x, y, z = settings.partial_differential_equation.coordinates

        import expresso.pycas as pc
        R, = self._get_evaluators([pc.exp(pe.F * z.step)],
                                  settings,
                                  return_type=pc.Types.Complex,
                                  parallel=not self._F_is_constant_in_z)
        if self._F_is_constant_in_z:
            self.__R_step = R(*self._get_indices())
        else:
            self.__R = R

        D = pc.numpyfy(
            self._evaluate(
                pc.exp(
                    -z.step *
                    (pe.A * pc.Symbol('kx')**2 + pe.C * pc.Symbol('ky')**2)),
                settings))

        import numpy as np

        fx = 2 * np.pi / (self._nx * self._get_as(x.step, float, settings))
        fy = 2 * np.pi / (self._ny * self._get_as(y.step, float, settings))

        ky, kx = np.meshgrid(
            fy * (self._ny / 2. - np.abs(np.arange(self._ny) - self._ny / 2.)),
            fx * (self._nx / 2. - np.abs(np.arange(self._nx) - self._nx / 2.)))

        self.__C_is_zero = settings.get_numeric(pe.C) == pc.S(0)

        self.__D_step = D(kx=kx, ky=ky, **self._get_indices_dict())

        self._set_initial_field(settings)
示例#8
0
    def __init__(self, settings, thread_count=1):
        import expresso.pycas as pc
        import numpy as np

        pe = settings.partial_differential_equation
        x, y, z = settings.partial_differential_equation.coordinates

        xi = getattr(settings.simulation_box, x.name + 'i')
        self.__ximin = float(settings.get_unitless(xi.subs(x.symbol, 0)))
        self.__ximax = float(settings.get_unitless(xi.subs(x.symbol, x.max)))
        self.__sx = self.__ximax - self.__ximin

        super(FresnelCS, self).__init__(settings)
        self._thread_count = thread_count

        self._set_initial_field(settings)

        R, = self._get_evaluators([pc.exp(pe.F * z.step)],
                                  settings,
                                  return_type=pc.Types.Complex)

        D = pc.numpyfy(
            self._evaluate(pc.exp(-pe.A * z.step * (pc.Symbol('kx')**2)),
                           settings))

        if self._F_is_constant_in_z:
            self.__R_step = R(*self._get_indices())
        else:
            self.__R = R

        kx = hankel_freq(self._nx) * ((self._nx - 1) * 1. / self.__sx)
        self.__D_step = D(kx=kx, **self._get_indices_dict())

        self.__hankel_resample_matrix = hankel_resample_matrix(
            self._nx,
            (np.arange(self._nx) - self.__ximin) * (self._nx * 1. / self.__sx),
            cache_key=(self._nx, self.__ximin, self.__sx),
            xmax=self._nx)
示例#9
0
def add_coordinate(settings, category, name):

    import expresso.pycas as pc

    x = category.create_key(name,
                            pc.Symbol(name, type=pc.Types.Real),
                            info='coordinate')
    xmin = category.create_key('%smin' % name,
                               pc.Symbol('%s_min' % name),
                               info='minimum value')
    xmax = category.create_key('%smax' % name,
                               pc.Symbol('%s_max' % name),
                               info='maximum value')
    xi = pc.Symbol('%s_i' % name, type=pc.Types.Natural)
    xif = category.create_key('%si' % name,
                              pc.Function('%s_i' % name)(x),
                              info='numerical index')
    Nx = category.create_key('N%s' % name,
                             pc.Symbol('N_%s' % name, type=pc.Types.Natural),
                             info='numerical steps')
    sx = category.create_key('s%s' % name,
                             pc.Symbol('s_%s' % name),
                             info='total size')
    dx = category.create_key('d%s' % name,
                             pc.Symbol('Delta %s' % name),
                             info='step size')

    setattr(category, name, xmin + xi * dx)
    setattr(category, '%si' % name, (x - xmin) / dx)

    setattr(category, 's%s' % name, xmax - xmin)
    setattr(category, 'd%s' % name, sx / (Nx - 1))

    category.lock(name, 'defined by %si' % name)
    category.lock('s%s' % name, 'defined by %smin and %smax' % (name, name))
    category.lock('d%s' % name, 'defined by s%s and N%s' % (name, name))

    settings.unitless.add_key('%s_coordinate' % name, x)
示例#10
0
def create_2D_frequency_settings_from(settings):
    import expresso.pycas as pc
    from .. import units
    from ..plot import expression_to_array
    from ..coordinate_ndarray import CoordinateNDArray
    import numpy as np

    settings.initialize()
    settings = settings.copy()

    sb = settings.simulation_box
    we = settings.wave_equation
    omega0 = settings.get_numeric(we.omega)
    we.unlock('omega')
    we.omega = None

    freq_settings = create_paraxial_settings()
    pde = freq_settings.partial_differential_equation

    freq_settings.simulation_box.unlock()
    freq_settings.simulation_box.remove_name('y')
    omega = freq_settings.simulation_box.create_key('y', pc.Symbol('omega'))

    fsb = freq_settings.simulation_box
    freq_settings.simulation_box.y = fsb.ymin + fsb.yi * fsb.dy

    n = settings.get_numeric(we.n.subs(sb.y, 0)).subs(omega,
                                                      abs(omega - omega0))

    p = freq_settings.create_category('paramters', short_name="p")
    p.create_function('n', (sb.x, sb.y, sb.z, omega), n)
    p.create_symbol('k', (omega - omega0) / units.c)
    p.create_symbol('k_0', omega0 / units.c)

    pde.A = 1j / (2 * p.k_0)
    pde.C = 0
    pde.F = 1j / (2 * p.k_0) * (p.n**2 * p.k**2 - p.k_0**2)

    xmin = settings.get_numeric(sb.xmin)
    xmax = settings.get_numeric(sb.xmax)

    freq_settings.simulation_box.xmin = xmin
    freq_settings.simulation_box.xmax = xmax
    freq_settings.simulation_box.Nx = settings.get_as(sb.Nx, int)

    omegamin = settings.get_numeric(-2 * pc.pi * sb.Nt / sb.st)
    omegamax = settings.get_numeric(2 * pc.pi * sb.Nt / sb.st)

    freq_settings.simulation_box.ymin = omegamin
    freq_settings.simulation_box.ymax = omegamax
    freq_settings.simulation_box.Ny = settings.get_as(sb.Nt, int)

    freq_settings.simulation_box.zmin = settings.get_numeric(sb.zmin)
    freq_settings.simulation_box.zmax = settings.get_numeric(sb.zmax)
    freq_settings.simulation_box.Nz = settings.get_as(sb.Nz, int)

    freq_settings.unitless.create_key(
        's', units.s,
        settings.get_as(2 / (omegamax - omegamin) / units.s, float))

    u0 = expression_to_array(settings.wave_equation.u0.subs([(sb.y, 0),
                                                             (sb.z, sb.zmin)]),
                             settings,
                             axes=(sb.x, sb.t))

    u0hat = CoordinateNDArray(
        np.fft.fftshift(np.fft.fft(u0.data, axis=1), axes=(1, )),
        [(xmin, xmax), (omegamin, omegamax)], [sb.x, omega])

    set_initial(freq_settings, u0hat)
    freq_settings.partial_differential_equation.u_boundary = 0

    return freq_settings
示例#11
0
 def create_symbol(name, value=None, info=None, **kwargs):
     prefix = '_'.join(cat_path)
     return cat.create_key(
         name, pc.Symbol("%s_%s" % (name, prefix), **kwargs), value,
         info)