コード例 #1
0
def _gmres_single_op_imp(
    A,
    b,
    tol=1e-5,
    restart=None,
    maxiter=None,
    use_strong_form=False,
    return_residuals=False,
    return_iteration_count=False,
):
    """Implementation for single operators."""
    from bempp.api.assembly.grid_function import GridFunction

    import scipy.sparse.linalg

    import bempp.api
    import time

    if not isinstance(b, GridFunction):
        raise ValueError("b must be of type GridFunction")

    # Assemble weak form before the logging messages

    if use_strong_form:
        if not A.range.is_compatible(b.space):
            raise ValueError(
                "The range of A and the domain of A must have" +
                "the same number of unknowns if the strong form is used.")
        A_op = A.strong_form()
        b_vec = b.coefficients
    else:
        A_op = A.weak_form()
        b_vec = b.projections(A.dual_to_range)

    callback = IterationCounter(return_residuals)

    bempp.api.log("Starting GMRES iteration")
    start_time = time.time()
    x, info = scipy.sparse.linalg.gmres(A_op,
                                        b_vec,
                                        tol=tol,
                                        restart=restart,
                                        maxiter=maxiter,
                                        callback=callback)
    end_time = time.time()
    bempp.api.log("GMRES finished in %i iterations and took %.2E sec." %
                  (callback.count, end_time - start_time))

    res_fun = GridFunction(A.domain, coefficients=x.ravel())

    if return_residuals and return_iteration_count:
        return res_fun, info, callback.residuals, callback.count

    if return_residuals:
        return res_fun, info, callback.residuals

    if return_iteration_count:
        return res_fun, info, callback.count

    return res_fun, info
コード例 #2
0
ファイル: blocked_operator.py プロジェクト: pescap/bempp-cl
def grid_function_list_from_projections(projections, spaces, dual_spaces=None):
    """
    Create a list of grid functions from a long vector of projections.

    Parameters
    ----------
    coefficients : np.ndarray
        One-dimensional array of coefficients
    spaces : list of Space objects
        The sum of the global dofs of the spaces must be equal to the
        length of the coefficients vector.
    dual_spaces : list of Space objects
        The associated dual spaces. If None use the spaces as dual spaces.
    """
    from bempp.api import GridFunction

    pos = 0
    res_list = []
    if dual_spaces is None:
        dual_spaces = spaces
    if len(spaces) != len(dual_spaces):
        raise ValueError("spaces must have the same length as dual_spaces")
    for space, dual in zip(spaces, dual_spaces):
        dof_count = space.global_dof_count
        res_list.append(
            GridFunction(space,
                         projections=projections[pos:pos + dof_count],
                         dual_space=dual))
        pos += dof_count
    return res_list
コード例 #3
0
def load(self, simulation_data, bem_data):
    # from bempp.api import function_space
    # from bempp.applications.room_acoustic import Simulation
    from bempp.api.grid import Grid
    from bempp.api.assembly.grid_function import GridFunction

    # Loading BEM object data
    for attr, value in vars(self).items():
        if attr in bem_data.keys():
            try:
                setattr(self, attr, bem_data[attr])
            except TypeError:
                print('Cant load ' + str(attr) + ' field.')

    # Loading simulation data
    grid = Grid(simulation_data['grid']['vertices'],
                simulation_data['grid']['elements'],
                simulation_data['grid']['domain_indices'])
    # self.simulation = Simulation(simulation_data['frequencies'], self.admittance, grid)
    #     self.set_SR()
    self.r0 = simulation_data['positions']
    # self.pts = simulation_data['receivers']
    self.q = simulation_data['amplitudes']
    # self.set_status = True

    self.boundData = []
    # self.simulation._incident_traces = []
    # self.simulation._incident_fields = []
    for sol in range(len(simulation_data['u'])):
        u = GridFunction(simulation_data['space'],
                         coefficients=simulation_data['u'][sol])
        un = GridFunction(simulation_data['space'],
                          coefficients=simulation_data['un'][sol])
        # incident_traces = GridFunction(self.simulation._space, coefficients=simulation_data['incident_traces'][sol])
        self.boundData.append((u, un))
        # self.simulation._incident_traces.append(incident_traces)
    # for frequency, mu in zip(self.simulation._frequencies, self.simulation._admittance_factors):
    #     wavenumber = 2 * np.pi * frequency / 343
    #     _, uinc = self.simulation._compute_incident_trace_and_field(wavenumber, mu, grid=False, incident=True)
    #     self.simulation._incident_fields.append(uinc)

    print('\tBEM loaded successfully.')
コード例 #4
0
    def __mul__(self, other):
        """Multiply two blocked operators."""
        import collections

        if _np.isscalar(other):
            # Multiplication with scalar
            return ScaledBlockedOperator(self, other)
        elif isinstance(other, BlockedOperatorBase):
            # Multiplication with another blocked operator.
            return ProductBlockedOperator(self, other)
        elif isinstance(other, collections.Iterable):
            # Multiplication with a list of grid functions.
            from bempp.api.assembly.grid_function import GridFunction
            list_input = list(other)
            if len(list_input) != self.ndims[1]:
                raise ValueError(
                    "Length of input list is {0}.".format(len(list_input)) +
                    ". But domain dimension of blocked operator" +
                    "is {0}".format(self.ndims[1]))
            for item in list_input:
                if not isinstance(item, GridFunction):
                    raise ValueError(
                        "All items in the input list must be grid functions.")
            weak_op = self.weak_form()
            input_type = list_input[0].coefficients.dtype
            for item in list_input:
                input_type = _np.promote_types(input_type,
                                               item.coefficients.dtype)
            x_in = _np.zeros(weak_op.shape[1], dtype=input_type)
            col_pos = _np.hstack([[0], _np.cumsum(weak_op.column_dimensions)])
            row_pos = _np.hstack([[0], _np.cumsum(weak_op.row_dimensions)])
            for index in range(weak_op.ndims[1]):
                x_in[col_pos[index]:col_pos[index+1]] = \
                    list_input[index].coefficients
            res = weak_op * x_in

            # Now assemble the output grid functions back together.
            output_list = []

            for index in range(weak_op.ndims[0]):
                output_list.append(
                    GridFunction(self.range_spaces[index],
                                 dual_space=self.dual_to_range_spaces[index],
                                 projections=res[row_pos[index]:row_pos[index +
                                                                        1]]))
            return output_list

        else:
            return NotImplementedError
コード例 #5
0
ファイル: blocked_operator.py プロジェクト: pescap/bempp-cl
def grid_function_list_from_coefficients(coefficients, spaces):
    """
    Create a list of grid functions from a long vector of coefficients.

    Parameters
    ----------
    coefficients : np.ndarray
        One-dimensional array of coefficients
    spaces : list of Space objects
        The sum of the global dofs of the spaces must be equal to the
        length of the coefficients vector.
    """
    from bempp.api import GridFunction

    pos = 0
    res_list = []
    for space in spaces:
        dof_count = space.global_dof_count
        res_list.append(
            GridFunction(space,
                         coefficients=coefficients[pos:pos + dof_count]))
        pos += dof_count
    return res_list
コード例 #6
0
ファイル: make_Toeplitz.py プロジェクト: AndrewGibbs/Dweezil
def gmres(A_full, dual_to_range_sub, domain_sub, rhs_fun, Z,
            tol=1e-5,restart=None,maxiter=None):
    
    A_toe = get_weak_toe_form(A_full,Z)
    
    if isinstance(A_full, bempp.api.assembly.blocked_operator.BlockedOperatorBase):
        blocked = True
        b_vec = projections_from_grid_functions_list(rhs_fun, dual_to_range_sub)
    else:
        blocked = False
        b_vec = rhs_fun.projections(dual_to_range_sub)
    
    # use scipy's gmres to get the coefficients
    x, info = sp_gmres(
    A_toe, b_vec, tol=tol, restart=restart, maxiter=maxiter
    )
    
    if blocked:
        res_fun = grid_function_list_from_coefficients(x.ravel(), domain_sub)
    else:
        res_fun = GridFunction(domain_sub, coefficients=x.ravel())

    return res_fun, info
コード例 #7
0
def cg(
    A,
    b,
    tol=1e-5,
    maxiter=None,
    use_strong_form=False,
    return_residuals=False,
    return_iteration_count=False,
):
    """Interface to the scipy.sparse.linalg.cg function.

    This function behaves like the scipy.sparse.linalg.cg function. But
    instead of a linear operator and a vector b it takes a boundary operator
    and a grid function. The result is returned as a grid function in the
    correct space.

    """
    from bempp.api.assembly.boundary_operator import BoundaryOperator
    from bempp.api.assembly.grid_function import GridFunction

    import scipy.sparse.linalg

    import bempp.api
    import time

    if not isinstance(A, BoundaryOperator):
        raise ValueError("A must be of type BoundaryOperator")

    if not isinstance(b, GridFunction):
        raise ValueError("b must be of type GridFunction")

    if use_strong_form:
        if not A.range.is_compatible(b.space):
            raise ValueError(
                "The range of A and the domain of A must " +
                "have the same number of unknowns if the strong form is used.")
        A_op = A.strong_form()
        b_vec = b.coefficients
    else:
        A_op = A.weak_form()
        b_vec = b.projections(A.dual_to_range)

    callback = IterationCounter(return_residuals, True, A_op, b_vec)
    bempp.api.log("Starting CG iteration")
    start_time = time.time()
    x, info = scipy.sparse.linalg.cg(A_op,
                                     b_vec,
                                     tol=tol,
                                     maxiter=maxiter,
                                     callback=callback)
    end_time = time.time()
    bempp.api.log("CG finished in %i iterations and took %.2E sec." %
                  (callback.count, end_time - start_time))

    res_fun = GridFunction(A.domain, coefficients=x.ravel())

    if return_residuals and return_iteration_count:
        return res_fun, info, callback.residuals, callback.count

    if return_residuals:
        return res_fun, info, callback.residuals

    if return_iteration_count:
        return res_fun, info, callback.count

    return res_fun, info