def __init__(self, grid, wave_number, parameters): from bempp.api.assembly import InverseSparseDiscreteBoundaryOperator from bempp.api.space import project_operator bc_space = bempp.api.function_space(grid, "BC", 0) rbc_space = bempp.api.function_space(grid, "RBC", 0) rwg_space = bempp.api.function_space(grid, "B-RWG", 0) snc_space = bempp.api.function_space(grid, "B-SNC", 0) rwg_bary_space = bempp.api.function_space(grid.barycentric_grid(), "RWG", 0) snc_bary_space = bempp.api.function_space(grid.barycentric_grid(), "SNC", 0) super(EfieSquared, self).__init__(rwg_space, rwg_space, rbc_space, label="EFIE_SQUARED") self._efie_fine = electric_field(rwg_bary_space, rwg_bary_space, snc_bary_space, wave_number, parameters=parameters) self._efie = project_operator(self._efie_fine, domain=rwg_space, range_=rwg_space, dual_to_range=snc_space) self._efie2 = project_operator(self._efie_fine, domain=bc_space, range_=rwg_space, dual_to_range=rbc_space) self._ident = bempp.api.operators.boundary.sparse.identity( bc_space, rwg_space, snc_space) self._inv_ident = InverseSparseDiscreteBoundaryOperator( self._ident.weak_form())
def multitrace_operator_impl_dual(grid, slp_operator, dlp_operator, hyp_operator, parameters, laplace): """Multitrace operator for dual linear/constant spaces.""" import bempp.api from bempp.api.assembly import BlockedOperator from bempp.api.space import project_operator if parameters is None: parameters = bempp.api.global_parameters blocked_operator = BlockedOperator(2, 2) const_space = bempp.api.function_space(grid, "DUAL", 0) lin_space_bary = bempp.api.function_space(grid, "B-P", 1) lin_space_disc = bempp.api.function_space(grid.barycentric_grid(), "DP", 1) if laplace: const_space_bary = bempp.api.function_space(grid.barycentric_grid(), "DP", 0) slp = slp_operator(const_space_bary, const_space_bary, const_space_bary, parameters=parameters) else: slp = slp_operator(lin_space_disc, lin_space_disc, lin_space_disc, parameters=parameters) dlp_disc = dlp_operator(lin_space_disc, lin_space_disc, lin_space_disc, parameters=parameters) dlp = project_operator(dlp_disc, domain=lin_space_bary, range_=lin_space_bary, dual_to_range=const_space) adlp = project_operator(dlp_disc.transpose(const_space), domain=const_space, range_=const_space, dual_to_range=lin_space_bary) blocked_operator[0, 1] = project_operator(slp, domain=const_space, range_=lin_space_bary, dual_to_range=const_space) blocked_operator[1, 0] = hyp_operator(lin_space_bary, const_space, lin_space_bary, use_slp=slp, parameters=parameters) blocked_operator[0, 0] = -dlp blocked_operator[1, 1] = adlp return blocked_operator
def slp_and_hyp_impl(grid, slp_operator, hyp_operator, parameters, spaces='linear', base_slp=None, return_base_slp=False, laplace='False'): import bempp.api from bempp.api.space import project_operator if parameters is None: parameters = bempp.api.global_parameters if spaces=='linear': lin_space = bempp.api.function_space(grid, "P", 1) lin_space_disc = bempp.api.function_space(grid, "DP", 1) if base_slp: slp_disc = base_slp else: slp_disc = slp_operator(lin_space_disc, lin_space_disc, lin_space_disc, parameters=parameters) slp = project_operator(slp_disc, domain=lin_space, range_=lin_space, dual_to_range=lin_space) hyp = hyp_operator(lin_space, lin_space, lin_space, use_slp=slp_disc, parameters=parameters) if return_base_slp: return (slp, hyp, slp_disc) else: return (slp, hyp) elif spaces=='dual': const_space = bempp.api.function_space(grid, "DUAL", 0) lin_space = bempp.api.function_space(grid, "P", 1) lin_space_bary = bempp.api.function_space(grid, "B-P", 1) lin_space_disc_bary = bempp.api.function_space(grid, "B-DP", 1) lin_space_disc = bempp.api.function_space(grid.barycentric_grid(), "DP", 1) if base_slp: slp = base_slp else: if laplace: const_space_bary = bempp.api.function_space(grid.barycentric_grid(), "DP", 0) slp = slp_operator(const_space_bary, const_space_bary, const_space_bary, parameters=parameters) else: slp = slp_operator(lin_space_disc, lin_space_disc, lin_space_disc, parameters=parameters) slp_projected = project_operator(slp, domain=const_space, range_=lin_space_bary, dual_to_range=const_space) hyp_projected = (hyp_operator( \ lin_space_bary, const_space, lin_space_bary, use_slp=slp, parameters=parameters)) if return_base_slp: return (slp_projected, hyp_projected, slp) else: return (slp_projected, hyp_projected)
def get_wave_operator_with_space_preprocessing( op_fun, domain, range_, dual_to_range, wave_number, label, symmetry, parameters, use_projection_spaces=True, assemble_only_singular_part=False): """Preprocess a wave operator.""" import bempp.api from bempp.api.space import rewrite_operator_spaces from bempp.api.space import project_operator if parameters is None: parameters = bempp.api.global_parameters if check_for_non_barycentric_spaces(domain, dual_to_range): return rewrite_operator_spaces( get_wave_operator_with_space_preprocessing( op_fun, domain.non_barycentric_space, range_, dual_to_range.non_barycentric_space, wave_number, label, symmetry, parameters, use_projection_spaces, assemble_only_singular_part), domain, range_, dual_to_range) if not use_projection_spaces: return op_fun( domain, range_, dual_to_range, wave_number, label, symmetry, parameters, assemble_only_singular_part) else: op = op_fun( domain.super_space, range_, dual_to_range.super_space, wave_number, label, symmetry, parameters, assemble_only_singular_part) return project_operator( op, domain=domain, range_=range_, dual_to_range=dual_to_range)
def multitrace_operator_impl_lin( grid, slp_operator, dlp_operator, hyp_operator, parameters): """Implementation of the multitrace operators for linear spaces.""" import bempp.api from bempp.api.assembly import BlockedOperator from bempp.api.space import project_operator if parameters is None: parameters = bempp.api.global_parameters blocked_operator = BlockedOperator(2, 2) lin_space = bempp.api.function_space(grid, "P", 1) lin_space_disc = bempp.api.function_space(grid, "DP", 1) slp_disc = slp_operator(lin_space_disc, lin_space_disc, lin_space_disc, parameters=parameters) slp = project_operator(slp_disc, domain=lin_space, range_=lin_space, dual_to_range=lin_space) dlp = dlp_operator(lin_space, lin_space, lin_space, parameters=parameters) adlp = dlp.transpose(lin_space) hyp = hyp_operator(lin_space, lin_space, lin_space, use_slp=slp_disc, parameters=parameters) blocked_operator[0, 0] = -dlp blocked_operator[0, 1] = slp blocked_operator[1, 0] = hyp blocked_operator[1, 1] = adlp return blocked_operator
def multitrace_operator_impl_lin(grid, slp_operator, dlp_operator, hyp_operator, parameters): """Implementation of the multitrace operators for linear spaces.""" import bempp.api from bempp.api.assembly import BlockedOperator from bempp.api.space import project_operator if parameters is None: parameters = bempp.api.global_parameters blocked_operator = BlockedOperator(2, 2) lin_space = bempp.api.function_space(grid, "P", 1) lin_space_disc = bempp.api.function_space(grid, "DP", 1) slp_disc = slp_operator(lin_space_disc, lin_space_disc, lin_space_disc, parameters=parameters) slp = project_operator(slp_disc, domain=lin_space, range_=lin_space, dual_to_range=lin_space) dlp = dlp_operator(lin_space, lin_space, lin_space, parameters=parameters) adlp = dlp.transpose(lin_space) hyp = hyp_operator(lin_space, lin_space, lin_space, use_slp=slp_disc, parameters=parameters) blocked_operator[0, 0] = -dlp blocked_operator[0, 1] = slp blocked_operator[1, 0] = hyp blocked_operator[1, 1] = adlp return blocked_operator
def multitrace_operator_impl_dual(grid, slp_operator, dlp_operator, hyp_operator, parameters, laplace): """Implementation of the multitrace operator for dual linear/constant spaces.""" import bempp.api from bempp.api.assembly import BlockedOperator from bempp.api.space import project_operator if parameters is None: parameters = bempp.api.global_parameters blocked_operator = BlockedOperator(2, 2) const_space = bempp.api.function_space(grid, "DUAL", 0) lin_space = bempp.api.function_space(grid, "P", 1) lin_space_bary = bempp.api.function_space(grid, "B-P", 1) lin_space_disc_bary = bempp.api.function_space(grid, "B-DP", 1) lin_space_disc = bempp.api.function_space(grid.barycentric_grid(), "DP", 1) if laplace: const_space_bary = bempp.api.function_space(grid.barycentric_grid(), "DP", 0) slp = slp_operator(const_space_bary, const_space_bary, const_space_bary, parameters=parameters) else: slp = slp_operator(lin_space_disc, lin_space_disc, lin_space_disc, parameters=parameters) dlp_disc = dlp_operator(lin_space_disc, lin_space_disc, lin_space_disc, parameters=parameters) dlp = project_operator(dlp_disc, domain=lin_space_bary, range_=lin_space_bary, dual_to_range=const_space) adlp = project_operator(dlp_disc.transpose(const_space), domain=const_space, range_=const_space, dual_to_range=lin_space_bary) blocked_operator[0, 1] = project_operator(slp, domain=const_space, range_=lin_space_bary, dual_to_range=const_space) blocked_operator[1, 0] = (hyp_operator( \ lin_space_bary, const_space, lin_space_bary, use_slp=slp, parameters=parameters)) blocked_operator[0, 0] = -dlp blocked_operator[1, 1] = adlp return blocked_operator
def multitrace_operator_impl(grid, slp_operator, dlp_operator, hyp_operator, parameters): """Implementation of the multitrace operator.""" import bempp.api from bempp.api.assembly import BlockedOperator from bempp.api.space import project_operator if parameters is None: parameters = bempp.api.global_parameters blocked_operator = BlockedOperator(2, 2) const_space = bempp.api.function_space(grid, "DUAL", 0) lin_space = bempp.api.function_space(grid, "P", 1) lin_space_bary = bempp.api.function_space(grid, "B-P", 1) lin_space_disc_bary = bempp.api.function_space(grid, "B-DP", 1) lin_space_disc = bempp.api.function_space(grid.barycentric_grid(), "DP", 1) slp = slp_operator(lin_space_disc, lin_space_disc, lin_space_disc, parameters=parameters) ident1 = bempp.api.operators.boundary.sparse.identity(lin_space_bary, lin_space_bary, const_space) ident2 = bempp.api.operators.boundary.sparse.identity(const_space, const_space, lin_space_bary) dlp_disc = dlp_operator(lin_space_disc, lin_space_disc, lin_space_disc, parameters=parameters) dlp = project_operator(dlp_disc, domain=lin_space_bary, range_=lin_space_bary, dual_to_range=const_space) adlp = project_operator( dlp_disc.transpose(const_space), domain=const_space, range_=const_space, dual_to_range=lin_space_bary ) blocked_operator[0, 1] = project_operator(slp, domain=const_space, range_=lin_space_bary, dual_to_range=const_space) blocked_operator[1, 0] = hyp_operator( lin_space_bary, const_space, lin_space_bary, use_slp=project_operator(slp, domain=lin_space_disc_bary, dual_to_range=lin_space_disc_bary), parameters=parameters, ) blocked_operator[0, 0] = -dlp blocked_operator[1, 1] = adlp return blocked_operator
def get_operator_with_space_preprocessing(op_fun, domain, range_, dual_to_range, label, symmetry, parameters, use_projection_spaces=True, assemble_only_singular_part=False): """Assemble operator after preprocessing of spaces.""" import bempp.api from bempp.api.space import rewrite_operator_spaces from bempp.api.space import project_operator if parameters is None: parameters = bempp.api.global_parameters if parameters.assembly.boundary_operator_assembly_type == 'dense': from bempp.api import log use_projection_spaces = False log("Projection space mode disabled for dense assembly.") if check_for_non_barycentric_spaces(domain, dual_to_range): return rewrite_operator_spaces( get_operator_with_space_preprocessing( op_fun, domain.non_barycentric_space, range_, dual_to_range.non_barycentric_space, label, symmetry, parameters, use_projection_spaces, assemble_only_singular_part), domain, range_, dual_to_range) if not use_projection_spaces: return op_fun(domain, range_, dual_to_range, label, symmetry, parameters, assemble_only_singular_part) else: operator = op_fun(domain.super_space, range_, dual_to_range.super_space, label, symmetry, parameters, assemble_only_singular_part) return project_operator(operator, domain=domain, range_=range_, dual_to_range=dual_to_range)
def slp_and_hyp_impl(grid, slp_operator, hyp_operator, parameters, spaces='linear', base_slp=None, return_base_slp=False, laplace='False'): """Assemble slp and hyp operator.""" import bempp.api from bempp.api.space import project_operator if parameters is None: parameters = bempp.api.global_parameters if spaces == 'linear': lin_space = bempp.api.function_space(grid, "P", 1) lin_space_disc = bempp.api.function_space(grid, "DP", 1) if base_slp: slp_disc = base_slp else: slp_disc = slp_operator(lin_space_disc, lin_space_disc, lin_space_disc, parameters=parameters) slp = project_operator(slp_disc, domain=lin_space, range_=lin_space, dual_to_range=lin_space) hyp = hyp_operator(lin_space, lin_space, lin_space, use_slp=slp_disc, parameters=parameters) if return_base_slp: return (slp, hyp, slp_disc) else: return (slp, hyp) elif spaces == 'dual': const_space = bempp.api.function_space(grid, "DUAL", 0) lin_space = bempp.api.function_space(grid, "P", 1) lin_space_bary = bempp.api.function_space(grid, "B-P", 1) lin_space_disc = bempp.api.function_space(grid.barycentric_grid(), "DP", 1) if base_slp: slp = base_slp else: if laplace: const_space_bary = bempp.api.function_space( grid.barycentric_grid(), "DP", 0) slp = slp_operator(const_space_bary, const_space_bary, const_space_bary, parameters=parameters) else: slp = slp_operator(lin_space_disc, lin_space_disc, lin_space_disc, parameters=parameters) slp_projected = project_operator(slp, domain=const_space, range_=lin_space_bary, dual_to_range=const_space) hyp_projected = (hyp_operator(lin_space_bary, const_space, lin_space_bary, use_slp=slp, parameters=parameters)) if return_base_slp: return (slp_projected, hyp_projected, slp) else: return (slp_projected, hyp_projected)
def multitrace_operator(grid, wave_number, parameters=None, target=None): """Assemble the multitrace operator for Maxwell.""" from bempp.api.assembly import BlockedOperator from bempp.api.space import project_operator import bempp.api blocked_operator = BlockedOperator(2, 2) rwg_space_fine = bempp.api.function_space(grid.barycentric_grid(), "RWG", 0) rwg_space = bempp.api.function_space(grid, "B-RWG", 0) bc_space = bempp.api.function_space(grid, "BC", 0) rbc_space = bempp.api.function_space(grid, "RBC", 0) snc_space = bempp.api.function_space(grid, "B-SNC", 0) snc_space_fine = bempp.api.function_space(grid.barycentric_grid(), "SNC", 0) if target is None: efie_fine = electric_field(rwg_space_fine, rwg_space_fine, snc_space_fine, wave_number, parameters=parameters) mfie_fine = magnetic_field(rwg_space_fine, rwg_space_fine, snc_space_fine, wave_number, parameters=parameters) blocked_operator[0, 0] = project_operator(mfie_fine, rwg_space, rwg_space, rbc_space) blocked_operator[0, 1] = project_operator(efie_fine, bc_space, rwg_space, rbc_space) blocked_operator[1, 0] = -1 * project_operator(efie_fine, rwg_space, bc_space, snc_space) blocked_operator[1, 1] = project_operator(mfie_fine, bc_space, bc_space, snc_space) else: rwg_space_fine_target = bempp.api.function_space( target.barycentric_grid(), "RWG", 0) rwg_space_target = bempp.api.function_space(target, "B-RWG", 0) bc_space_target = bempp.api.function_space(target, "BC", 0) rbc_space_target = bempp.api.function_space(target, "RBC", 0) snc_space_target = bempp.api.function_space(target, "B-SNC", 0) snc_space_fine_target = bempp.api.function_space( target.barycentric_grid(), "SNC", 0) efie_fine = electric_field(rwg_space_fine, rwg_space_fine_target, snc_space_fine_target, wave_number, parameters=parameters) mfie_fine = magnetic_field(rwg_space_fine, rwg_space_fine_target, snc_space_fine_target, wave_number, parameters=parameters) blocked_operator[0, 0] = project_operator(mfie_fine, rwg_space, rwg_space_target, rbc_space_target) blocked_operator[0, 1] = project_operator(efie_fine, bc_space, rwg_space_target, rbc_space_target) blocked_operator[1, 0] = -1 * project_operator( efie_fine, rwg_space, bc_space_target, snc_space_target) blocked_operator[1, 1] = project_operator(mfie_fine, bc_space, bc_space_target, snc_space_target) return blocked_operator