コード例 #1
0
    def __init__(self, fine_level, coarse_level, base_transfer_params, space_transfer_class, space_transfer_params):
        """
        Initialization routine

        Args:
            fine_level (pySDC.Level.level): fine level connected with the base_transfer operations
            coarse_level (pySDC.Level.level): coarse level connected with the base_transfer operations
            base_transfer_params (dict): parameters for the base_transfer operations
            space_transfer_class: class to perform spatial transfer
            space_transfer_params (dict): parameters for the space_transfer operations
        """

        self.params = _Pars(base_transfer_params)

        # set up logger
        self.logger = logging.getLogger('transfer')

        # just copy by object
        self.fine = fine_level
        self.coarse = coarse_level

        fine_grid = self.fine.sweep.coll.nodes
        coarse_grid = self.coarse.sweep.coll.nodes

        if len(fine_grid) == len(coarse_grid):
            self.Pcoll = sp.eye(len(fine_grid)).toarray()
            self.Rcoll = sp.eye(len(fine_grid)).toarray()
        else:
            self.Pcoll = th.interpolation_matrix_1d(fine_grid, coarse_grid, k=self.params.coll_iorder, pad=0,
                                                    equidist_nested=False).toarray()
            self.Rcoll = th.restriction_matrix_1d(fine_grid, coarse_grid, k=self.params.coll_rorder, pad=0).toarray()

        # set up spatial transfer
        self.space_transfer = space_transfer_class(fine_prob=self.fine.prob, coarse_prob=self.coarse.prob,
                                                   params=space_transfer_params)
コード例 #2
0
def check_Q_transfer(collclass):
    """
    A simple test program to check the order of the Q interpolation/restriction
    """

    for M in range(3, 9):

        Mfine = M
        Mcoarse = int((Mfine + 1) / 2.0)

        coll_fine = collclass(Mfine, 0, 1)
        coll_coarse = collclass(Mcoarse, 0, 1)

        assert coll_fine.left_is_node == coll_coarse.left_is_node, 'ERROR: should be using the same class for coarse and fine Q'

        if not coll_fine.left_is_node:
            fine_grid = np.concatenate(([0], coll_fine.nodes))
            coarse_grid = np.concatenate(([0], coll_coarse.nodes))
        else:
            fine_grid = coll_fine.nodes
            coarse_grid = coll_coarse.nodes

        for order in range(2, coll_coarse.num_nodes + 1):

            Pcoll = th.interpolation_matrix_1d(fine_grid,
                                               coarse_grid,
                                               k=order,
                                               pad=0)
            Rcoll = th.restriction_matrix_1d(fine_grid,
                                             coarse_grid,
                                             k=order,
                                             pad=0)

            for polyorder in range(1, order + 2):
                coeff = np.random.rand(polyorder)
                ufine = polyval(fine_grid, coeff)
                ucoarse = polyval(coarse_grid, coeff)

                uinter = Pcoll.dot(ucoarse)
                urestr = Rcoll.dot(ufine)

                err_inter = np.linalg.norm(uinter - ufine, np.inf)
                err_restr = np.linalg.norm(urestr - ucoarse, np.inf)

                if polyorder <= order:
                    assert err_inter < 2E-15, "ERROR: Q-interpolation order is not reached, got %s" % err_inter
                    assert err_restr < 2E-15, "ERROR: Q-restriction order is not reached, got %s" % err_restr
                else:
                    assert err_inter > 2E-15, "ERROR: Q-interpolation order is higher than expected, got %s" % polyorder
コード例 #3
0
    def __init__(self, fine_level, coarse_level, params):
        """
        Initialization routine
        Args:
            fine_level: fine level connected with the transfer operations (passed to parent)
            coarse_level: coarse level connected with the transfer operations (passed to parent)
            params: parameters for the transfer operators
        """

        # invoke super initialization
        super(mesh_to_mesh_1d_periodic, self).__init__(fine_level,
                                                       coarse_level, params)

        fine_grid = np.array(
            [i * fine_level.prob.dx for i in range(fine_level.prob.nvars)])
        coarse_grid = np.array(
            [i * coarse_level.prob.dx for i in range(coarse_level.prob.nvars)])

        # if number of variables is the same on both levels, Rspace and Pspace are identity
        if self.init_c == self.init_f:
            self.Rspace = np.eye(self.init_c)
        # assemble restriction as transpose of interpolation
        else:

            if params['rorder'] == 1:

                self.Rspace = th.restriction_matrix_1d(fine_grid,
                                                       coarse_grid,
                                                       k=1,
                                                       periodic=True)

            else:

                self.Rspace = 0.5 * th.interpolation_matrix_1d(
                    fine_grid, coarse_grid, k=params['rorder'],
                    periodic=True).T

        # if number of variables is the same on both levels, Rspace and Pspace are identity
        if self.init_f == self.init_c:
            self.Pspace = np.eye(self.init_f)
        else:
            self.Pspace = th.interpolation_matrix_1d(fine_grid,
                                                     coarse_grid,
                                                     k=params['iorder'],
                                                     periodic=True)
        # print(self.Rspace.todense())
        # print(self.Pspace.todense())
        # exit()
        pass
コード例 #4
0
def check_Q_transfer_minimal(collclass):
    """
    A simple test program to check the order of the Q interpolation/restriction for only 2 coarse nodes
    """

    Mcoarse = 2
    coll_coarse = collclass(Mcoarse, 0, 1)

    for M in range(3, 9):

        Mfine = M

        coll_fine = collclass(Mfine, 0, 1)

        assert coll_fine.left_is_node == coll_coarse.left_is_node, 'ERROR: should be using the same class for coarse and fine Q'

        fine_grid = coll_fine.nodes
        coarse_grid = coll_coarse.nodes

        Pcoll = th.interpolation_matrix_1d(fine_grid, coarse_grid, k=2, pad=0, equidist_nested=False)
        Rcoll = th.restriction_matrix_1d(fine_grid, coarse_grid, k=2, pad=0)

        for polyorder in range(1,3):
            coeff = np.random.rand(polyorder)
            ufine = polyval(fine_grid,coeff)
            ucoarse = polyval(coarse_grid,coeff)

            uinter = Pcoll.dot(ucoarse)
            urestr = Rcoll.dot(ufine)

            err_inter = np.linalg.norm(uinter-ufine, np.inf)
            err_restr = np.linalg.norm(urestr-ucoarse, np.inf)

            if polyorder <= 2:
                assert err_inter < 2E-15, "ERROR: Q-interpolation order is not reached, got %s" %err_inter
                assert err_restr < 2E-15, "ERROR: Q-restriction order is not reached, got %s" % err_restr
            else:
                assert err_inter > 2E-15, "ERROR: Q-interpolation order is higher than expected, got %s" % polyorder
コード例 #5
0
    def __init__(self, fine_prob, coarse_prob, params):
        """
        Initialization routine

        Args:
            fine_prob: fine problem
            coarse_prob: coarse problem
            params: parameters for the transfer operators
        """

        if 'iorder' not in params:
            raise TransferError('Need iorder parameter for spatial transfer')
        if 'rorder' not in params:
            raise TransferError('Need rorder parameter for spatial transfer')

        # invoke super initialization
        super(mesh_to_mesh, self).__init__(fine_prob, coarse_prob, params)

        if type(self.fine_prob.params.nvars) is tuple:
            if type(self.coarse_prob.params.nvars) is not tuple:
                raise TransferError(
                    'nvars parameter of coarse problem needs to be a tuple')
            if not len(self.fine_prob.params.nvars) == len(
                    self.coarse_prob.params.nvars):
                raise TransferError(
                    'nvars parameter of fine and coarse level needs to have the same length'
                )
        elif type(self.fine_prob.params.nvars) is int:
            if type(self.coarse_prob.params.nvars) is not int:
                raise TransferError(
                    'nvars parameter of coarse problem needs to be an int')
        else:
            raise TransferError("unknow type of nvars for transfer, got %s" %
                                self.fine_prob.params.nvars)

        # we have a 1d problem
        if type(self.fine_prob.params.nvars) is int:

            # if number of variables is the same on both levels, Rspace and Pspace are identity
            if self.coarse_prob.params.nvars == self.fine_prob.params.nvars:
                self.Rspace = sp.eye(self.coarse_prob.params.nvars)
                self.Pspace = sp.eye(self.fine_prob.params.nvars)
            # assemble restriction as transpose of interpolation
            else:

                if not self.params.periodic:
                    fine_grid = np.array([
                        (i + 1) * self.fine_prob.dx
                        for i in range(self.fine_prob.params.nvars)
                    ])
                    coarse_grid = np.array([
                        (i + 1) * self.coarse_prob.dx
                        for i in range(self.coarse_prob.params.nvars)
                    ])
                else:
                    fine_grid = np.array([
                        i * self.fine_prob.dx
                        for i in range(self.fine_prob.params.nvars)
                    ])
                    coarse_grid = np.array([
                        i * self.coarse_prob.dx
                        for i in range(self.coarse_prob.params.nvars)
                    ])

                if self.params.rorder <= 1:
                    self.Rspace = th.restriction_matrix_1d(
                        fine_grid,
                        coarse_grid,
                        k=self.params.rorder,
                        periodic=self.params.periodic)
                else:
                    self.Rspace = 0.5 * th.interpolation_matrix_1d(
                        fine_grid,
                        coarse_grid,
                        k=self.params.rorder,
                        periodic=self.params.periodic).T

                self.Pspace = th.interpolation_matrix_1d(
                    fine_grid,
                    coarse_grid,
                    k=self.params.iorder,
                    periodic=self.params.periodic)

        # we have an n-d problem
        else:

            Rspace = []
            Pspace = []
            for i in range(len(self.fine_prob.params.nvars)):

                # if number of variables is the same on both levels, Rspace and Pspace are identity
                if self.coarse_prob.params.nvars == self.fine_prob.params.nvars:
                    Rspace.append(sp.eye(self.coarse_prob.params.nvars[i]))
                    Pspace.append(sp.eye(self.fine_prob.params.nvars[i]))
                # assemble restriction as transpose of interpolation
                else:

                    if not self.params.periodic:
                        fine_grid = np.array([
                            (j + 1) * self.fine_prob.dx
                            for j in range(self.fine_prob.params.nvars[i])
                        ])
                        coarse_grid = np.array([
                            (j + 1) * self.coarse_prob.dx
                            for j in range(self.coarse_prob.params.nvars[i])
                        ])
                    else:
                        fine_grid = np.array([
                            j * self.fine_prob.dx
                            for j in range(self.fine_prob.params.nvars[i])
                        ])
                        coarse_grid = np.array([
                            j * self.coarse_prob.dx
                            for j in range(self.coarse_prob.params.nvars[i])
                        ])

                    if self.params.iorder <= 1:
                        Rspace.append(
                            th.restriction_matrix_1d(
                                fine_grid,
                                coarse_grid,
                                k=self.params.iorder,
                                periodic=self.params.periodic).T)
                    else:
                        Rspace.append(0.5 * th.interpolation_matrix_1d(
                            fine_grid,
                            coarse_grid,
                            k=self.params.iorder,
                            periodic=self.params.periodic).T)
                    Pspace.append(
                        th.interpolation_matrix_1d(
                            fine_grid,
                            coarse_grid,
                            k=self.params.iorder,
                            periodic=self.params.periodic))

            # kronecker 1-d operators for n-d
            self.Pspace = Pspace[0]
            for i in range(1, len(Pspace)):
                self.Pspace = sp.kron(self.Pspace, Pspace[i], format='csc')

            self.Rspace = Rspace[0]
            for i in range(1, len(Rspace)):
                self.Rspace = sp.kron(self.Rspace, Rspace[i], format='csc')
コード例 #6
0
    def __init__(self, fine_level, coarse_level, base_transfer_params,
                 space_transfer_class, space_transfer_params):
        """
        Initialization routine

        Args:
            fine_level (pySDC.Level.level): fine level connected with the base_transfer operations
            coarse_level (pySDC.Level.level): coarse level connected with the base_transfer operations
            base_transfer_params (dict): parameters for the base_transfer operations
            space_transfer_class: class to perform spatial transfer
            space_transfer_params (dict): parameters for the space_transfer operations
        """

        # short helper class to add params as attributes
        class __Pars(FrozenClass):
            def __init__(self, pars):
                self.finter = False
                self.coll_iorder = 2
                self.coll_rorder = 1
                for k, v in pars.items():
                    setattr(self, k, v)

                self._freeze()

        self.params = __Pars(base_transfer_params)

        # set up logger
        self.logger = logging.getLogger('transfer')

        # just copy by object
        self.fine = fine_level
        self.coarse = coarse_level

        # for Q-based transfer, check if we need to add 0 to the list of nodes
        if not self.fine.sweep.coll.left_is_node:
            fine_grid = np.concatenate(([0], self.fine.sweep.coll.nodes))
            coarse_grid = np.concatenate(([0], self.coarse.sweep.coll.nodes))
        else:
            fine_grid = self.fine.sweep.coll.nodes
            coarse_grid = self.coarse.sweep.coll.nodes

        if self.params.coll_iorder > len(coarse_grid):
            self.logger.warning(
                'requested order of Q-interpolation is not valid, resetting to %s'
                % len(coarse_grid))
            self.params.coll_iorder = len(coarse_grid)
        if self.params.coll_rorder != 1:
            self.logger.warning(
                'requested order of Q-restriction is != 1, can lead to weird behavior!'
            )

        # set up preliminary transfer matrices for Q-based coarsening
        Pcoll = th.interpolation_matrix_1d(fine_grid,
                                           coarse_grid,
                                           k=self.params.coll_iorder,
                                           pad=0).toarray()
        Rcoll = th.restriction_matrix_1d(fine_grid,
                                         coarse_grid,
                                         k=self.params.coll_rorder,
                                         pad=0).toarray()

        # pad transfer matrices if necessary
        if self.fine.sweep.coll.left_is_node:
            self.Pcoll = np.zeros((self.fine.sweep.coll.num_nodes + 1,
                                   self.coarse.sweep.coll.num_nodes + 1))
            self.Rcoll = np.zeros((self.coarse.sweep.coll.num_nodes + 1,
                                   self.fine.sweep.coll.num_nodes + 1))
            self.Pcoll[1:, 1:] = Pcoll
            self.Rcoll[1:, 1:] = Rcoll
        else:
            self.Pcoll = Pcoll
            self.Rcoll = Rcoll

        # set up spatial transfer
        self.space_transfer = space_transfer_class(
            fine_prob=self.fine.prob,
            coarse_prob=self.coarse.prob,
            params=space_transfer_params)