Exemple #1
0
def interpolate_scattered_field(es, new_NM, new_NS):
    """Interpolate the scattered field.

    Parameters
    ----------
        es : :class:`numpy.ndarray`
            Scattered field matrix.

        new_NM : int
            New number of measurement angles.

        new_NS : int
            New number of incidence angles.
    """
    NM, NS = es.shape
    theta = cfg.get_angles(NM)
    phi = cfg.get_angles(NS)
    freal = interp2d(phi, theta, np.real(es), kind='cubic')
    fimag = interp2d(phi, theta, np.imag(es), kind='cubic')
    new_theta = cfg.get_angles(new_NM)
    new_phi = cfg.get_angles(new_NS)
    esi = freal(new_phi, new_theta) + 1j * fimag(new_phi, new_theta)
    return esi
Exemple #2
0
    def incident_field(self, resolution):
        """Compute the incident field matrix.

        Given the configuration information stored in the object, it
        computes the incident field matrix considering plane waves in
        different from different angles.

        Parameters
        ----------
            resolution : 2-tuple
                The image size of D-domain in pixels (y and x).

        Returns
        -------
            ei : :class:`numpy.ndarray`
                Incident field matrix. The rows correspond to the points
                in the image following `C`-order and the columns
                corresponds to the sources.
        """
        NY, NX = resolution
        phi = cfg.get_angles(self.configuration.NS)
        x, y = cfg.get_coordinates_ddomain(configuration=self.configuration,
                                           resolution=resolution)
        kb = self.configuration.kb
        E0 = self.configuration.E0
        if isinstance(kb, float) or isinstance(kb, complex):
            ei = E0*np.exp(-1j*kb*(x.reshape((-1, 1))
                                   @ np.cos(phi.reshape((1, -1)))
                                   + y.reshape((-1, 1))
                                   @ np.sin(phi.reshape((1, -1)))))
        else:
            ei = np.zeros((NX*NY, self.configuration.NS, kb.size),
                          dtype=complex)
            for f in range(kb.size):
                ei[:, :, f] = E0*np.exp(-1j*kb[f]*(x.reshape((-1, 1))
                                                   @ np.cos(phi.reshape((1,
                                                                         -1)))
                                                   + y.reshape((-1, 1))
                                                   @ np.sin(phi.reshape((1,
                                                                         -1))))
                                        )
        return ei
Exemple #3
0
    def conductor_cylinder(self,
                           scenario,
                           radius_proportion=0.5,
                           SAVE_INTERN_FIELD=True,
                           SAVE_MAP=False):
        """Solve the forward problem.

        Parameters
        ----------
            scenario : :class:`inputdata:InputData`
                An object describing the dielectric property map.

            PRINT_INFO : boolean, default: False
                Print iteration information.

            COMPUTE_INTERN_FIELD : boolean, default: True
                Compute the total field in D-domain.

        Return
        ------
            es, et, ei : :class:`numpy:ndarray`
                Matrices with the scattered, total and incident field
                information.

        Examples
        --------
        >>> solver = MoM_CG_FFT(configuration)
        >>> es, et, ei = solver.solve(scenario)
        >>> es, ei = solver.solve(scenario, COMPUTE_INTERN_FIELD=False)
        """
        # Main constants
        omega = 2 * pi * self.configuration.f  # Angular frequency [rad/s]
        kb = self.configuration.kb  # Wavenumber of background [rad/m]
        a = radius_proportion * self.configuration.lambda_b  # Sphere's radius
        thetal = cfg.get_angles(self.configuration.NS)
        thetam = cfg.get_angles(self.configuration.NM)

        # Summing coefficients
        n = np.arange(-self.NT, self.NT + 1)
        an = -jv(n, kb * a) / hankel2(n, kb * a)
        cn = np.zeros(n.size)

        # Mesh parameters
        x, y = cfg.get_coordinates_ddomain(configuration=self.configuration,
                                           resolution=scenario.resolution)

        # Incident field
        ei = self.incident_field(scenario.resolution)

        # Total field array
        et = compute_total_field(x, y, a, an, cn, self.NT, kb, 1.,
                                 self.configuration.E0, thetal)

        # Map of parameters
        sigma = np.zeros(x.shape)
        sigma[x**2 + y**2 <= a**2] = 1e10

        # Scatered field
        rho = self.configuration.Ro
        xm, ym = rho * np.cos(thetam), rho * np.sin(thetam)
        es = compute_scattered_field(xm, ym, an, kb, thetal,
                                     self.configuration.E0)

        if scenario.noise > 0:
            es = fwr.add_noise(es, scenario.noise)

        scenario.es = np.copy(es)
        scenario.ei = np.copy(ei)
        if SAVE_INTERN_FIELD:
            scenario.et = np.copy(et)
        if SAVE_MAP:
            scenario.sigma = np.copy(sigma)
        self.et = et
        self.ei = ei
        self.es = es
        self.epsilon_r = None
        self.sigma = sigma
        self.radius_proportion = radius_proportion
        self.problem = PERFECT_DIELECTRIC_PROBLEM
Exemple #4
0
    def _set_meshes(self, inputdata):
        """Set elements meshgrid data.

        Parameters
        ----------
            inputdata : :class:`inputdata.InputData`
                An instance of problem with resolution information.
        """
        # Number of measurements and sources
        NM, NS = self.configuration.NM, self.configuration.NS

        # Discretization in S-domain
        NW, NZ = self.discretization[0], self.discretization[1]

        # Discretization in D-domain
        NP, NQ = self.discretization[3], self.discretization[2]

        # Image resolution
        NY, NX = inputdata.resolution
        dx, dy = self.configuration.Lx / NX, self.configuration.Ly / NY

        x, y = cfg.get_coordinates_ddomain(configuration=self.configuration,
                                           resolution=inputdata.resolution)
        self._u, self._v = x.reshape(-1), y.reshape(-1)
        self._du, self._dv = dx, dy

        # Interpolation condition: if S-space discretization is greater
        # than the number of measurements and sources.
        # If the discretization is smaller, than S-space is integrated
        # in the points of the original data.
        # Otherwise, the original data is interpolated in order to have
        # more integration points than elements.
        self._FLAG_INTERPOLATION = NW > NM or NZ > NS

        # If the original data have more information than discretization
        if not self._FLAG_INTERPOLATION:
            xm, ym = cfg.get_coordinates_sdomain(self.configuration.Ro,
                                                 self.configuration.NM)
            self._xms = np.reshape(np.tile(xm.reshape((-1, 1)), (1, NS)), (-1))
            self._yms = np.reshape(np.tile(ym.reshape((-1, 1)), (1, NS)), (-1))
            self._phi_ms, self._theta_ms = np.meshgrid(cfg.get_angles(NS),
                                                       cfg.get_angles(NM))

        # If the original data have less information than discretization
        else:
            new_NM = self.constant_interpolation * NW
            new_NS = self.constant_interpolation * NZ
            xm, ym = cfg.get_coordinates_sdomain(self.configuration.Ro, new_NM)
            self._xms = np.reshape(np.tile(xm.reshape((-1, 1)), (1, new_NS)),
                                   (-1))
            self._yms = np.reshape(np.tile(ym.reshape((-1, 1)), (1, new_NS)),
                                   (-1))
            self._phi_ms, self._theta_ms = np.meshgrid(cfg.get_angles(new_NS),
                                                       cfg.get_angles(new_NM))

        self._phi_wz, self._theta_wz = np.meshgrid(cfg.get_angles(NZ),
                                                   cfg.get_angles(NW))
        self._dtheta = self._theta_ms[1, 0] - self._theta_ms[0, 0]
        self._dphi = self._phi_ms[0, 1] - self._phi_ms[0, 0]
        self._R = np.zeros((self._theta_ms.size, self._u.size))
        for i in range(self._R.shape[0]):
            self._R[i, :] = np.sqrt((self._xms[i] - self._u)**2 +
                                    (self._yms[i] - self._v)**2)

        # Coordinates of D-domain elements
        self._xpq, self._ypq = clc.get_elements_mesh(NX, NY, dx, dy, NP, NQ)

        if self.basis_function == BASIS_BILINEAR:
            self._fij = clc.bilinear(self._u.reshape((NY, NX)),
                                     self._v.reshape((NY, NX)),
                                     self._xpq.reshape((NQ, NP)),
                                     self._ypq.reshape((NQ, NP)))
            self._gij = clc.bilinear(self._phi_ms, self._theta_ms,
                                     self._phi_wz, self._theta_wz)

        elif self.basis_function == BASIS_LEGENDRE:
            xmin, xmax = cfg.get_bounds(self.configuration.Lx)
            ymin, ymax = cfg.get_bounds(self.configuration.Ly)
            self._fij = legendre(self._u.reshape((NY, NX)),
                                 self._v.reshape((NY, NX)), NQ, NP, xmin, xmax,
                                 ymin, ymax)
            self._gij = legendre(self._phi_ms, self._theta_ms, NW, NZ, 0,
                                 2 * np.pi, 0, 2 * np.pi)
Exemple #5
0
    def dielectric_cylinder(self,
                            scenario,
                            radius_proportion=0.5,
                            contrast=2.,
                            SAVE_INTERN_FIELD=True,
                            SAVE_MAP=False):
        """Solve the forward problem.

        Parameters
        ----------
            scenario : :class:`inputdata:InputData`
                An object describing the dielectric property map.

            PRINT_INFO : boolean, default: False
                Print iteration information.

            COMPUTE_INTERN_FIELD : boolean, default: True
                Compute the total field in D-domain.

        Return
        ------
            es, et, ei : :class:`numpy:ndarray`
                Matrices with the scattered, total and incident field
                information.

        Examples
        --------
        >>> solver = MoM_CG_FFT(configuration)
        >>> es, et, ei = solver.solve(scenario)
        >>> es, ei = solver.solve(scenario, COMPUTE_INTERN_FIELD=False)
        """
        # Main constants
        omega = 2 * pi * self.configuration.f  # Angular frequency [rad/s]
        epsilon_rd = cfg.get_relative_permittivity(
            contrast, self.configuration.epsilon_rb)
        epsd = epsilon_rd * epsilon_0  # Cylinder's permittivity [F/m]
        epsb = self.configuration.epsilon_rb * epsilon_0
        mud = mu_0  # Cylinder's permeability [H/m]
        kb = self.configuration.kb  # Wavenumber of background [rad/m]
        kd = omega * np.sqrt(mud * epsd)  # Wavenumber of cylinder [rad/m]
        lambdab = 2 * pi / kb  # Wavelength of background [m]
        a = radius_proportion * lambdab  # Sphere's radius [m]
        thetal = cfg.get_angles(self.configuration.NS)
        thetam = cfg.get_angles(self.configuration.NM)

        # Summing coefficients
        an, cn = get_coefficients(self.NT, kb, kd, a, epsd, epsb)

        # Mesh parameters
        x, y = cfg.get_coordinates_ddomain(configuration=self.configuration,
                                           resolution=scenario.resolution)

        # Incident field
        ei = self.incident_field(scenario.resolution)

        # Total field array
        et = compute_total_field(x, y, a, an, cn, self.NT, kb, kd,
                                 self.configuration.E0, thetal)

        # Map of parameters
        epsilon_r, _ = get_map(x, y, a, self.configuration.epsilon_rb,
                               epsilon_rd)

        # Scatered field
        rho = self.configuration.Ro
        xm, ym = rho * np.cos(thetam), rho * np.sin(thetam)
        es = compute_scattered_field(xm, ym, an, kb, thetal,
                                     self.configuration.E0)

        if scenario.noise > 0:
            es = fwr.add_noise(es, scenario.noise)

        scenario.es = np.copy(es)
        scenario.ei = np.copy(ei)
        if SAVE_INTERN_FIELD:
            scenario.et = np.copy(et)
        if SAVE_MAP:
            scenario.epsilon_r = np.copy(epsilon_r)
        self.et = et
        self.ei = ei
        self.es = es
        self.epsilon_r = epsilon_r
        self.sigma = None
        self.radius_proportion = radius_proportion
        self.contrast = contrast
        self.problem = PERFECT_DIELECTRIC_PROBLEM