Esempio n. 1
0
    def get_A_Ga(self, Nbar, primaldual='primal', order=None, P=None):
        """ Returns stiffness matrix for scheme with exact integration."""

        if order is None and 'order' in self.conf:
            order = self.conf['order']

        if order is None:
            shape_funs = self.get_shape_functions(Nbar)
            val = np.zeros(self.conf['vals'][0].shape + shape_funs[0].shape)
            for ii in range(len(self.conf['inclusions'])):
                if primaldual is 'primal':
                    Aincl = self.conf['vals'][ii]
                elif primaldual is 'dual':
                    Aincl = np.linalg.inv(self.conf['vals'][ii])
                val += np.einsum('ij...,k...->ijk...', Aincl, shape_funs[ii])
            return Matrix(name='A_Ga', val=val, Fourier=False)

        else:
            if P is None and 'P' in self.conf:
                P = self.conf['P']
            coord = Grid.get_coordinates(P, self.Y)
            vals = self.evaluate(coord)
            dim = vals.d
            if primaldual is 'dual':
                vals = vals.inv()

            h = self.Y/P
            if order in [0, 'constant']:
                Wraw = get_weights_con(h, Nbar, self.Y)
            elif order in [1, 'bilinear']:
                Wraw = get_weights_lin(h, Nbar, self.Y)

            Aapp = np.zeros(np.hstack([dim, dim, Nbar]))
            for m in np.arange(dim):
                for n in np.arange(dim):
                    hAM0 = DFT.fftnc(vals[m, n], P)
                    if np.allclose(P, Nbar):
                        hAM = hAM0
                    elif np.all(np.greater_equal(P, Nbar)):
                        hAM = decrease(hAM0, Nbar)
                    elif np.all(np.less(P, Nbar)):
                        factor = np.ceil(np.array(Nbar, dtype=np.float64) / P)
                        hAM0per = np.tile(hAM0, 2*factor-1)
                        hAM = decrease(hAM0per, Nbar)
                    else:
                        raise ValueError()

                    pNbar = np.prod(Nbar)
                    """ if DFT is normalized in accordance with articles there
                    should be np.prod(M) instead of np.prod(Nbar)"""
                    Aapp[m, n] = np.real(pNbar*DFT.ifftnc(Wraw*hAM, Nbar))

            name = 'A_Ga_o%d_P%d' % (order, P.max())
            return Matrix(name=name, val=Aapp, Fourier=False)
Esempio n. 2
0
    def get_topologies(self, coord):
        """
        Returns topologies at coordinates (coord). By a topology, it is
        understood a characteristic function (ones and zeros at coord)
        of individual inclusions (square, circle, etc.) usually defined in
        input file.
        """
        inclusions = self.conf['inclusions']
        params = self.conf['params']
        positions = self.conf['positions']

        dim = coord.shape[0]
        topos = []

        # periodically enlarge coordinates
        N = np.array(coord.shape[1:])
        cop = np.empty(np.hstack([dim, 3*N]))
        mapY = np.array([-1, 0, 1])
        for dd in np.arange(dim):
            Nshape = np.ones(dim, dtype=np.int32)
            Nshape[dd] = 3*N[dd]
            Nrep = 3*N
            Nrep[dd] = 1
            vec = np.repeat(mapY*self.Y[dd], N[dd])
            Ymat = np.tile(np.reshape(vec, Nshape), Nrep)
            cop[dd] = np.tile(coord[dd], 3*np.ones(dim)) + Ymat

        mapY = np.array([-1, 0, 1])
        Yiter = mapY[np.newaxis]
        for ii in np.arange(1, dim):
            Yiter = np.vstack([np.repeat(Yiter, 3, axis=1),
                               np.tile(mapY, Yiter.shape[1])])

        for ii, kind in enumerate(inclusions):

            if kind in inclusion_keys['cube']:
                param = np.array(params[ii], dtype=np.float64)
                pos = np.array(positions[ii], dtype=np.float64)
                topos.append(np.zeros(cop.shape[1:]))
                for Ycoef in Yiter.T:
                    Ym = self.Y*Ycoef
                    topo_loc = np.ones(cop.shape[1:])
                    for dd in np.arange(dim):
                        topo_loc *= ((cop[dd]-pos[dd]+Ym[dd]) > -param[dd]/2)
                        topo_loc *= ((cop[dd]-pos[dd]+Ym[dd]) <= param[dd]/2)
                    topos[ii] += topo_loc
                topos[ii] = decrease(topos[ii], N)

            elif kind in inclusion_keys['ball']:
                pos = np.array(positions[ii], dtype=np.float64)
                topos.append(np.zeros(cop.shape[1:]))
                for Ycoef in Yiter.T:
                    Ym = self.Y*Ycoef
                    topo_loc = np.ones(cop.shape[1:])

                    norm2 = 0. # square of norm
                    for dd in np.arange(dim):
                        norm2 += (cop[dd]-pos[dd]-Ym[dd])**2
                    topos[ii] += (norm2**0.5 < params[ii]/2)
                topos[ii] = decrease(topos[ii], N)

            elif kind in inclusion_keys['pyramid']:
                param = np.array(params[ii], dtype=np.float64)
                pos = np.array(positions[ii], dtype=np.float64)
                topos.append(np.zeros(cop.shape[1:]))
                for Ycoef in Yiter.T:
                    Ym = self.Y*Ycoef
                    topo_loc = np.ones(cop.shape[1:])
                    shp = cop[0].shape
                    tri = lambda t, h: np.maximum(1-np.abs(t)/h, np.zeros(shp))
                    for dd in np.arange(dim):
                        topo_loc *= tri(cop[dd]-pos[dd]+2*Ym[dd], param[dd]/2.)
                    topos[ii] += topo_loc
                topos[ii] = decrease(topos[ii], N)

            elif kind == 'otherwise':
                topos.append(np.ones(coord.shape[1:]))
                for jj in np.arange(len(topos)-1):
                    topos[ii] -= topos[jj]
                if not (topos[ii] >= 0).all():
                    raise NotImplementedError("Overlapping inclusions!")

            elif kind == 'all':
                topos.append(np.ones(coord.shape[1:]))

            else:
                msg = "Inclusion (%s) is not implemented." % (kind)
                raise NotImplementedError(msg)

        return topos
Esempio n. 3
0
    def get_A_Ga(self, Nbar, primaldual='primal', order=-1, P=None):
        """
        Returns stiffness matrix for scheme with exact integration.
        """
        if order == -1:
            if 'order' in self.conf:
                order = self.conf['order']
            else:
                raise ValueError('The material order is undefined!')
        elif order not in [None, 'exact', 0, 1]:
            raise ValueError('Wrong material order (%s)!' % str(order))

        if order in [None, 'exact']:
            shape_funs = self.get_shape_functions(Nbar)
            val = np.zeros(self.conf['vals'][0].shape + shape_funs[0].shape)
            for ii in range(len(self.conf['inclusions'])):
                if primaldual is 'primal':
                    Aincl = self.conf['vals'][ii]
                elif primaldual is 'dual':
                    Aincl = np.linalg.inv(self.conf['vals'][ii])
                val += np.einsum('ij...,k...->ijk...', Aincl, shape_funs[ii])
            name = 'A_Ga'

        else:
            if P is None and 'P' in self.conf:
                P = self.conf['P']
            coord = Grid.get_coordinates(P, self.Y)
            vals = self.evaluate(coord)
            dim = vals.d
            if primaldual is 'dual':
                vals = vals.inv()

            h = self.Y / P
            if order in [0, 'constant']:
                Wraw = get_weights_con(h, Nbar, self.Y)
            elif order in [1, 'bilinear']:
                Wraw = get_weights_lin(h, Nbar, self.Y)

            val = np.zeros(np.hstack([dim, dim, Nbar]))
            for m in np.arange(dim):
                for n in np.arange(dim):
                    hAM0 = DFT.fftnc(vals[m, n], P)
                    if np.allclose(P, Nbar):
                        hAM = hAM0
                    elif np.all(np.greater_equal(P, Nbar)):
                        hAM = decrease(hAM0, Nbar)
                    elif np.all(np.less(P, Nbar)):
                        factor = np.ceil(np.array(Nbar, dtype=np.float64) / P)
                        hAM0per = np.tile(hAM0, 2 * factor - 1)
                        hAM = decrease(hAM0per, Nbar)
                    else:
                        raise ValueError()

                    pNbar = np.prod(Nbar)
                    """ if DFT is normalized in accordance with articles there
                    should be np.prod(M) instead of np.prod(Nbar)"""
                    val[m, n] = np.real(pNbar * DFT.ifftnc(Wraw * hAM, Nbar))

            name = 'A_Ga_o%d_P%d' % (order, P.max())

        return Matrix(name=name, val=val, Fourier=False)
Esempio n. 4
0
    def get_topologies(self, coord):
        """
        Returns topologies at coordinates (coord). By a topology, it is
        understood a characteristic function (ones and zeros at coord)
        of individual inclusions (square, circle, etc.) usually defined in
        input file.
        """
        inclusions = self.conf['inclusions']
        params = self.conf['params']
        positions = self.conf['positions']

        dim = coord.shape[0]
        topos = []

        # periodically enlarge coordinates
        N = np.array(coord.shape[1:])
        cop = np.empty(np.hstack([dim, 3 * N]))
        mapY = np.array([-1, 0, 1])
        for dd in np.arange(dim):
            Nshape = np.ones(dim, dtype=np.int32)
            Nshape[dd] = 3 * N[dd]
            Nrep = 3 * N
            Nrep[dd] = 1
            vec = np.repeat(mapY * self.Y[dd], N[dd])
            Ymat = np.tile(np.reshape(vec, Nshape), Nrep)
            cop[dd] = np.tile(coord[dd], 3 * np.ones(dim)) + Ymat

        mapY = np.array([-1, 0, 1])
        Yiter = mapY[np.newaxis]
        for ii in np.arange(1, dim):
            Yiter = np.vstack(
                [np.repeat(Yiter, 3, axis=1),
                 np.tile(mapY, Yiter.shape[1])])

        for ii, kind in enumerate(inclusions):

            if kind in inclusion_keys['cube']:
                param = np.array(params[ii], dtype=np.float64)
                pos = np.array(positions[ii], dtype=np.float64)
                topos.append(np.zeros(cop.shape[1:]))
                for Ycoef in Yiter.T:
                    Ym = self.Y * Ycoef
                    topo_loc = np.ones(cop.shape[1:])
                    for dd in np.arange(dim):
                        topo_loc *= ((cop[dd] - pos[dd] + Ym[dd]) >
                                     -param[dd] / 2)
                        topo_loc *= ((cop[dd] - pos[dd] + Ym[dd]) <=
                                     param[dd] / 2)
                    topos[ii] += topo_loc
                topos[ii] = decrease(topos[ii], N)

            elif kind in inclusion_keys['ball']:
                pos = np.array(positions[ii], dtype=np.float64)
                topos.append(np.zeros(cop.shape[1:]))
                for Ycoef in Yiter.T:
                    Ym = self.Y * Ycoef
                    topo_loc = np.ones(cop.shape[1:])

                    norm2 = 0.  # square of norm
                    for dd in np.arange(dim):
                        norm2 += (cop[dd] - pos[dd] - Ym[dd])**2
                    topos[ii] += (norm2**0.5 < params[ii] / 2)
                topos[ii] = decrease(topos[ii], N)

            elif kind in inclusion_keys['pyramid']:
                param = np.array(params[ii], dtype=np.float64)
                pos = np.array(positions[ii], dtype=np.float64)
                topos.append(np.zeros(cop.shape[1:]))
                for Ycoef in Yiter.T:
                    Ym = self.Y * Ycoef
                    topo_loc = np.ones(cop.shape[1:])
                    shp = cop[0].shape
                    tri = lambda t, h: np.maximum(1 - np.abs(t) / h,
                                                  np.zeros(shp))
                    for dd in np.arange(dim):
                        topo_loc *= tri(cop[dd] - pos[dd] + 2 * Ym[dd],
                                        param[dd] / 2.)
                    topos[ii] += topo_loc
                topos[ii] = decrease(topos[ii], N)

            elif kind == 'otherwise':
                topos.append(np.ones(coord.shape[1:]))
                for jj in np.arange(len(topos) - 1):
                    topos[ii] -= topos[jj]
                if not (topos[ii] >= 0).all():
                    raise NotImplementedError("Overlapping inclusions!")

            elif kind == 'all':
                topos.append(np.ones(coord.shape[1:]))

            else:
                msg = "Inclusion (%s) is not implemented." % (kind)
                raise NotImplementedError(msg)

        return topos