def save_output(context, layers, x, fname):
    """Create vtk files from the result"""

    ndofc = sum([layers[i]['spaces']['ndof'] for i in range(len(layers))])
    tmp = x.ExtractView().T
    xc = tmp[:ndofc, :] + 1j * tmp[ndofc:, :]

    if Epetra.PyComm().MyPID() == 0:
        n = 0
        for i in range(len(layers)):
            plc = layers[i]['spaces']['l']
            pwc = layers[i]['spaces']['c']
            nplc = plc.globalDofCount()
            npwc = pwc.globalDofCount()
            ndof = nplc + npwc

            coeff_dirichlet = xc[n:n + nplc, 0]
            coeff_neumann = xc[n + nplc:n + nplc + npwc, 0]
            n = n + ndof

            ufun = lib.createGridFunction(context,
                                          plc,
                                          pwc,
                                          coefficients=coeff_dirichlet)
            vfun = lib.createGridFunction(context,
                                          pwc,
                                          plc,
                                          coefficients=coeff_neumann)

            ufun.exportToVtk("vertex_data", "dirichlet_data",
                             fname + "_u" + str(i))
            vfun.exportToVtk("cell_data", "neumann_data",
                             fname + "_v" + str(i))
def save_output(context,layers,x,fname):
    """Create vtk files from the result"""

    ndofc = sum([layers[i]['spaces']['ndof'] for i in range(len(layers))])
    tmp = x.ExtractView().T
    xc = tmp[:ndofc,:]+1j*tmp[ndofc:,:]

    if Epetra.PyComm().MyPID()==0:
        n = 0
        for i in range(len(layers)):
            plc = layers[i]['spaces']['l']
            pwc = layers[i]['spaces']['c']
            nplc = plc.globalDofCount()
            npwc = pwc.globalDofCount()
            ndof = nplc+npwc

            coeff_dirichlet = xc[n:n+nplc,0]
            coeff_neumann = xc[n+nplc:n+nplc+npwc,0]
            n = n+ndof

            ufun = lib.createGridFunction(context,plc,pwc,coefficients=coeff_dirichlet)
            vfun = lib.createGridFunction(context,pwc,plc,coefficients=coeff_neumann)

            ufun.exportToVtk("vertex_data","dirichlet_data",fname+"_u"+str(i))
            vfun.exportToVtk("cell_data","neumann_data",fname+"_v"+str(i))
Exemplo n.º 3
0
 def project_incident_field(self,fun,time,space_index=0):
     
     if space_index==0:
         f = lambda x,normal:fun.dirichlet_trace(x,time,normal)
         gridFun = _bempplib.createGridFunction(self._context,self._space,self._space,f,surfaceNormalDependent=True)
         return gridFun.coefficients()
     else:
         f = lambda x,normal: fun.neumann_trace(x,time,normal)
         gridFun = _bempplib.createGridFunction(self._context,self._space,self._space,f,surfaceNormalDependent=True)
         return gridFun.coefficients()
Exemplo n.º 4
0
    def evaluate_potential(self,wave_number,density):
        
        
        if self._evaluation_options is None:
            raise Exception("Error. 'evaluation_options' must be defined")
        
        if self._evaluation_quadrature_strategy is None:
            raise Exception("Error. 'evaluation_quadrature_options' must be defined")
        
        
        op_found_in_cache = False
        if self._operator_cache:
            try:
                potential = self._potential_operator_cache.get(wave_number)
                op_found_in_cache = True
            except:
                pass
        
        if not op_found_in_cache:
 
        
            potential = _bempplib.createMaxwell3dSingleLayerPotentialOperator(self._context,1.0j*wave_number).assemble(self._space,
                                                                                                                       self._evaluation_points,
                                                                                                                       self._evaluation_quadrature_strategy,
                                                                                                                       self._evaluation_options)
            if self._operator_cache: self._potential_operator_cache.insert(wave_number,potential)
            
        n = len(density[0])
        
        gridFun = _bempplib.createGridFunction(self._context,self._space,coefficients=density[0])
        return potential.apply(gridFun)
def initialize_rhs(context, layers, evalFun, process_maps):
    """Generate the rhs vector"""

    pwc = layers[0]['spaces']['c']
    plc = layers[0]['spaces']['l']
    ndof = plc.globalDofCount()
    total_dofs = sum([layers[i]['spaces']['ndof'] for i in range(len(layers))])

    rhs_data = Epetra.MultiVector(process_maps.single_proc_map, 1)

    if Epetra.PyComm().MyPID() == 0:

        pwc = layers[0]['spaces']['c']
        plc = layers[0]['spaces']['l']

        fun = lib.createGridFunction(context, pwc, plc, evalFun)
        data = fun.projections()
        rhs_data[0, :ndof] = np.real(data)
        rhs_data[0, total_dofs:total_dofs + ndof] = np.imag(data)

    return rhs_data
def initialize_rhs(context,layers,evalFun,process_maps):
    """Generate the rhs vector"""

    pwc = layers[0]['spaces']['c']
    plc = layers[0]['spaces']['l']
    ndof = plc.globalDofCount()
    total_dofs = sum([layers[i]['spaces']['ndof'] for i in range(len(layers))])

    rhs_data = Epetra.MultiVector(process_maps.single_proc_map,1)

    if Epetra.PyComm().MyPID()==0:
        
        pwc = layers[0]['spaces']['c']
        plc = layers[0]['spaces']['l']

        fun = lib.createGridFunction(context,pwc,plc,evalFun)
        data = fun.projections()
        rhs_data[0,:ndof] = np.real(data)
        rhs_data[0,total_dofs:total_dofs+ndof]=np.imag(data)

    return rhs_data
Exemplo n.º 7
0
adlpOp = lib.createHelmholtz3dAdjointDoubleLayerBoundaryOperator(
    context, pwiseConstants, pwiseConstants, pwiseConstants, k)
idOp = lib.createIdentityOperator(
    context, pwiseConstants, pwiseConstants, pwiseConstants)

# Standard arithmetic operators can be used to create linear combinations of
# boundary operators.

lhsOp = idOp + 2 * adlpOp - 2j * k * slpOp

# Use the rhsData() Python function defined earlier to initialize the grid
# function that represents the right-hand side. The spaces are the domain space
# and the test space (in this case they are identical). rhsData() takes the
# surface normal as a parameter, so we set surfaceNormalDependent to True.

fun = lib.createGridFunction(
    context, pwiseConstants, pwiseConstants, rhsData, surfaceNormalDependent=True)


# We will now use GMRES to solve the problem.

# The default iterative solver supports several Krylov space methods.

solver = lib.createDefaultIterativeSolver(lhsOp)

# Create an initialization list for GMRES with tolerance 1e-5.
# A CG parameter list is also available for symmetric problems.

params = lib.defaultGmresParameterList(1e-5)
solver.initializeSolver(params)

# Solve...
Exemplo n.º 8
0
 def _save_slice(self,data,fname):
     
     gridFun = _bempplib.createGridFunction(self._context,self._spaces[0],self._spaces[0],coefficients=data)
     gridFun.exportToVtk("cell_data","solution_data",fname)
Exemplo n.º 9
0
structure.setBlock(2, 1, lhs_k32)
structure.setBlock(2, 2, lhs_k33)
structure.setBlock(2, 3, lhs_k34)
structure.setBlock(2, 4, lhs_k35)
structure.setBlock(3, 1, lhs_k42)
structure.setBlock(3, 2, lhs_k43)
structure.setBlock(3, 3, lhs_k44)
structure.setBlock(3, 4, lhs_k45)
structure.setBlock(4, 3, lhs_k54)
structure.setBlock(4, 4, lhs_k55)
blockedOp = blib.createBlockedBoundaryOperator(context, structure)

rhs1 = scale * slp11
rhs2 = scale * slp21

boundaryData1 = rhs1 * blib.createGridFunction(context, sphere1_plc,
                                               sphere1_plc, evalBoundaryData)
boundaryData2 = rhs2 * blib.createGridFunction(context, sphere1_plc,
                                               sphere1_plc, evalBoundaryData)
boundaryData3 = blib.createGridFunction(context, sphere2_plc, sphere2_plc,
                                        evalNullData)
boundaryData4 = blib.createGridFunction(context, sphere3_plc, sphere3_plc,
                                        evalNullData)
boundaryData5 = blib.createGridFunction(context, sphere3_plc, sphere3_plc,
                                        evalNullData)

rhs = [
    boundaryData1, boundaryData2, boundaryData3, boundaryData4, boundaryData5
]

solver = blib.createDefaultIterativeSolver(blockedOp)
params = blib.defaultGmresParameterList(1e-10)
Exemplo n.º 10
0
	x, y, z = point
	res = 0.0*x + 0.0j*y + 0*z
	for pt in range(0,x.size):
		res[pt] = np.exp(1j*k*x[pt]) 
	return res

def evalInc(point):
    x, y, z = point
    if x.size == 1:
	return uIncData(point)
    res = 0.0*x + 0.0j*y + 0.0*z
    for pt in range(0,x.size):
	res[pt] = uIncData([x[pt], y[pt], z[pt] ]) 
    return res

uInc = lib.createGridFunction(context, pconsts, pconsts, evalInc)
rhs = -uInc

# PART 4: Discretize and solve the equations ###################################
solver = lib.createDefaultIterativeSolver(lhsOp)
params = lib.defaultGmresParameterList(1e-8)
solver.initializeSolver(params)
# Solve the equation
solution = solver.solve(rhs)
print solution.solverMessage()

# PART 5: Extract the solution #################################################
sol = solution.gridFunction()
print "************** k = ", k, " **********************"

Exemplo n.º 11
0
lhsOp10 =  0.5 * idOp + dlpOpInt
lhsOp11 = -rhoInt / rhoExt * slpOpInt

# ... and combine them into a blocked operator

lhsOp = lib.createBlockedBoundaryOperator(
    context, [[lhsOp00, lhsOp01], [lhsOp10, lhsOp11]])

# Create a grid function representing the Dirichlet trace of the incident wave

def uIncData(point):
    x, y, z = point
    r = np.sqrt(x**2 + y**2 + z**2)
    return np.exp(1j * kExt * x)

uInc = lib.createGridFunction(context, pconsts, pconsts, uIncData)

# Create a grid function representing the Neumann trace of the incident wave

def uIncDerivData(point, normal):
    x, y, z = point
    nx, ny, nz = normal
    r = np.sqrt(x**2 + y**2 + z**2)
    return 1j * kExt * np.exp(1j * kExt * x) * nx

uIncDeriv = lib.createGridFunction(context, pconsts, pconsts, uIncDerivData,
                                   surfaceNormalDependent=True)

# Create elements of the right hand side of the equation

rhs = [uInc, None]
Exemplo n.º 12
0
    def evaluate_potential(self,wave_number,density):
        
        
        if self._evaluation_options is None:
            raise Exception("Error. 'evaluation_options' must be defined")
        
        if self._evaluation_quadrature_strategy is None:
            raise Exception("Error. 'evaluation_quadrature_options' must be defined")
        
        
        op_found_in_cache = False
        if self._operator_cache:
            try:
                pot_ext_single,pot_ext_double,pot_int_single,pot_int_double = self._potential_operator_cache.get(wave_number)
                op_found_in_cache = True
            except:
                pass
        
        if not op_found_in_cache:
 

            k_ext = 1.0j*wave_number * _np.sqrt(self._eps_ext * self._mu_ext)
            k_int = 1.0j*wave_number * _np.sqrt(self._eps_int * self._mu_int)
            rho = (k_int * self._mu_ext) / (k_ext * self._mu_int)
            


        
            pot_ext_single = _bempplib.createMaxwell3dSingleLayerPotentialOperator(self._context,k_ext).assemble(self._space,
                                                                                                                 self._evaluation_points[:,self._outside],
                                                                                                                 self._evaluation_quadrature_strategy,
                                                                                                                 self._evaluation_options)
            
            pot_ext_double = _bempplib.createMaxwell3dDoubleLayerPotentialOperator(self._context,k_ext).assemble(self._space,
                                                                                                                 self._evaluation_points[:,self._outside],
                                                                                                                 self._evaluation_quadrature_strategy,
                                                                                                                 self._evaluation_options)
            

            pot_int_single = _bempplib.createMaxwell3dSingleLayerPotentialOperator(self._context,k_int).assemble(self._space,
                                                                                                                 self._evaluation_points[:,self._inside],
                                                                                                                 self._evaluation_quadrature_strategy,
                                                                                                                 self._evaluation_options)
            
            pot_int_double = _bempplib.createMaxwell3dDoubleLayerPotentialOperator(self._context,k_int).assemble(self._space,
                                                                                                                 self._evaluation_points[:,self._inside],
                                                                                                                 self._evaluation_quadrature_strategy,
                                                                                                                 self._evaluation_options)
            
            
            
            
            if self._operator_cache: self._potential_operator_cache.insert(wave_number,pot_int_single,pot_int_double,
                                                                           pot_ext_single,pot_ext_double)
            


        dirichlet_ext = density[0]
        dirichlet_int = dirichlet_ext
        neumann_ext = density[1]
        neumann_int = density[1]/rho
            
        dirichlet_ext_fun = _bempplib.createGridFunction(self._context,self._space,self._space,coefficients=dirichlet_ext)
        dirichlet_int_fun = _bempplib.createGridFunction(self._context,self._space,self._space,coefficients=dirichlet_int)
        neumann_ext_fun = _bempplib.createGridFunction(self._context,self._space,self._space,coefficients=neumann_ext)
        neumann_int_fun = _bempplib.createGridFunction(self._context,self._space,self._space,coefficients=neumann_int)
        
        scatt_dirichlet_ext_fun = dirichlet_ext_fun - self._inc_dirichlet_traces[wave_number]
        print "Eval Dirichlet Error "+str(scatt_dirichlet_ext_fun.L2Norm()/dirichlet_ext_fun.L2Norm())
        scatt_neumann_ext_fun = neumann_ext_fun - self._inc_neumann_traces[wave_number]
        print "Eval Neumann Error "+str(scatt_neumann_ext_fun.L2Norm()/dirichlet_ext_fun.L2Norm())                
        
        valsExt = pot_ext_single.apply(scatt_neumann_ext_fun) + pot_ext_double.apply(scatt_dirichlet_ext_fun)
        valsInt = pot_int_single.apply(neumann_int_fun) + pot_int_double.apply(dirichlet_int_fun)
        
        vals = _np.zeros((3,self._evaluation_points.shape[1]), dtype='complex128')
        vals[:,self._inside] = valsInt
        vals[:,self._outside] = valsExt

        return vals
Exemplo n.º 13
0
    def solve_bvp(self,wave_number,rhs):
                        
        self._residuals[wave_number] = []
        
        def evaluate_residual(res):
            self._residuals[wave_number].append(res)
        
        
        k_ext = 1.0j*wave_number * _np.sqrt(self._eps_ext * self._mu_ext)
        k_int = 1.0j*wave_number * _np.sqrt(self._eps_int * self._mu_int)
        rho = (k_int * self._mu_ext) / (k_ext * self._mu_int)
                    
        
        op_found_in_cache = False
        if self._operator_cache:
            try:
                op,prec = self._boundary_operator_cache(wave_number)
                op_found_in_cache = True
            except:
                pass
        if not op_found_in_cache:   
            
            context = self._context
            space = self._space

            slpOpExt = _bempplib.createMaxwell3dSingleLayerBoundaryOperator(
                context, space, space, space, k_ext, "SLP_ext")
            dlpOpExt = _bempplib.createMaxwell3dDoubleLayerBoundaryOperator(
                context, space, space, space, k_ext, "DLP_ext")
            slpOpInt = _bempplib.createMaxwell3dSingleLayerBoundaryOperator(
                context, space, space, space, k_int, "SLP_int")
            dlpOpInt = _bempplib.createMaxwell3dDoubleLayerBoundaryOperator(
                context, space, space, space, k_int, "DLP_int")
            idOp = _bempplib.createMaxwell3dIdentityOperator(
                context, space, space, space, "Id")
            
            # Form the left- and right-hand-side operators
            
            lhsOp00 = -(slpOpExt + rho * slpOpInt)
            lhsOp01 = lhsOp10 = dlpOpExt + dlpOpInt
            lhsOp11 = slpOpExt + (1. / rho) * slpOpInt
            
            lhsOp = _bempplib.createBlockedBoundaryOperator(
                context, [[lhsOp00, lhsOp01], [lhsOp10, lhsOp11]])
            

            precTol = self._aca_lu_delta
            invLhsOp00 = _bempplib.acaOperatorApproximateLuInverse(
                lhsOp00.weakForm().asDiscreteAcaBoundaryOperator(), precTol)
            invLhsOp11 = _bempplib.acaOperatorApproximateLuInverse(
                lhsOp11.weakForm().asDiscreteAcaBoundaryOperator(), precTol)
            prec = _bempplib.discreteBlockDiagonalPreconditioner([invLhsOp00, invLhsOp11])
            
            op = lhsOp


            # Construct the grid functions representing the traces of the incident field
            
        incDirichletTrace = _bempplib.createGridFunction(
            context, space, space, coefficients=rhs[0])
        incNeumannTrace = 1./(1j*k_ext)*_bempplib.createGridFunction(
            context, space, space, coefficients=rhs[1])
        
        self._inc_dirichlet_traces[wave_number] = incDirichletTrace
        self._inc_neumann_traces[wave_number] = incNeumannTrace
            
            # Construct the right-hand-side grid function
            
        rhs = [idOp * incNeumannTrace, idOp * incDirichletTrace]
            
            
        
            
        solver = _bempplib.createDefaultIterativeSolver(op)
        solver.initializeSolver(_bempplib.defaultGmresParameterList(self._gmres_tol), prec)
        
            # Solve the equation
            
        solution = solver.solve(rhs)
        print solution.solverMessage()
        
        # Extract the solution components in the form of grid functions
        
        extDirichletTrace = solution.gridFunction(0)
        extNeumannTrace = solution.gridFunction(1)
        

        if self._operator_cache: self._boundary_operator_cache.insert(wave_number,(op,prec))
        
        scatt_dirichlet_ext_fun = extDirichletTrace - self._inc_dirichlet_traces[wave_number]
        print "Dirichlet Error "+str(scatt_dirichlet_ext_fun.L2Norm()/extDirichletTrace.L2Norm())
        scatt_neumann_ext_fun = extNeumannTrace - self._inc_neumann_traces[wave_number]
        print "Neumann Error "+str(scatt_neumann_ext_fun.L2Norm()/extNeumannTrace.L2Norm())                
        


        return [extDirichletTrace.coefficients(),extNeumannTrace.coefficients()]
Exemplo n.º 14
0
structure.setBlock(2, 1, lhs_k32);
structure.setBlock(2, 2, lhs_k33);
structure.setBlock(2, 3, lhs_k34);
structure.setBlock(2, 4, lhs_k35);
structure.setBlock(3, 1, lhs_k42);
structure.setBlock(3, 2, lhs_k43);
structure.setBlock(3, 3, lhs_k44);
structure.setBlock(3, 4, lhs_k45);
structure.setBlock(4, 3, lhs_k54);
structure.setBlock(4, 4, lhs_k55);
blockedOp = blib.createBlockedBoundaryOperator(context,structure)

rhs1 = scale*slp11
rhs2 = scale*slp21

boundaryData1 = rhs1 * blib.createGridFunction(
    context, sphere1_plc, sphere1_plc, evalBoundaryData)
boundaryData2 = rhs2 * blib.createGridFunction(
    context, sphere1_plc, sphere1_plc, evalBoundaryData)
boundaryData3 = blib.createGridFunction(
    context, sphere2_plc, sphere2_plc, evalNullData)
boundaryData4 = blib.createGridFunction(
    context, sphere3_plc, sphere3_plc, evalNullData)
boundaryData5 = blib.createGridFunction(
    context, sphere3_plc, sphere3_plc, evalNullData)

rhs = [boundaryData1, boundaryData2, boundaryData3, boundaryData4, boundaryData5]

solver = blib.createDefaultIterativeSolver(blockedOp)
params = blib.defaultGmresParameterList(1e-10)
solver.initializeSolver(params)
solution = solver.solve(rhs)
Exemplo n.º 15
0
    for pt in range(0, x.size):
        res[pt] = np.exp(1j * k * x[pt])
    return res


def evalInc(point):
    x, y, z = point
    if x.size == 1:
        return uIncData(point)
    res = 0.0 * x + 0.0j * y + 0.0 * z
    for pt in range(0, x.size):
        res[pt] = uIncData([x[pt], y[pt], z[pt]])
    return res


uInc = lib.createGridFunction(context, pconsts, pconsts, evalInc)
rhs = -uInc

# PART 4: Discretize and solve the equations ###################################
solver = lib.createDefaultIterativeSolver(lhsOp)
params = lib.defaultGmresParameterList(1e-8)
solver.initializeSolver(params)
# Solve the equation
solution = solver.solve(rhs)
print solution.solverMessage()

# PART 5: Extract the solution #################################################
sol = solution.gridFunction()
print "************** k = ", k, " **********************"

slPot = lib.createHelmholtz3dSingleLayerPotentialOperator(context, k)
Exemplo n.º 16
0
adlpOp = lib.createHelmholtz3dAdjointDoubleLayerBoundaryOperator(
    context, pwiseConstants, pwiseConstants, pwiseConstants, k)
idOp = lib.createIdentityOperator(
    context, pwiseConstants, pwiseConstants, pwiseConstants)

# Standard arithmetic operators can be used to create linear combinations of
# boundary operators.

lhsOp = idOp + 2 * adlpOp - 2j * k * slpOp

# Use the rhsData() Python function defined earlier to initialize the grid
# function that represents the right-hand side. The spaces are the domain space
# and the test space (in this case they are identical). rhsData() takes the
# surface normal as a parameter, so we set surfaceNormalDependent to True.

fun = lib.createGridFunction(
    context, pwiseConstants, pwiseConstants, rhsData, surfaceNormalDependent=True)


# We will now use GMRES to solve the problem.

# The default iterative solver supports several Krylov space methods.

solver = lib.createDefaultIterativeSolver(lhsOp)

# Create an initialization list for GMRES with tolerance 1e-5.
# A CG parameter list is also available for symmetric problems.

params = lib.defaultGmresParameterList(1e-5)
solver.initializeSolver(params)

# Solve...
Exemplo n.º 17
0
lhsOp10 =  0.5 * idOp + dlpOpInt
lhsOp11 = -rhoInt / rhoExt * slpOpInt

# ... and combine them into a blocked operator

lhsOp = lib.createBlockedBoundaryOperator(
    context, [[lhsOp00, lhsOp01], [lhsOp10, lhsOp11]])

# Create a grid function representing the Dirichlet trace of the incident wave

def uIncData(point):
    x, y, z = point
    r = np.sqrt(x**2 + y**2 + z**2)
    return np.exp(1j * kExt * x)

uInc = lib.createGridFunction(context, pconsts, pconsts, uIncData)

# Create a grid function representing the Neumann trace of the incident wave

def uIncDerivData(point, normal):
    x, y, z = point
    nx, ny, nz = normal
    r = np.sqrt(x**2 + y**2 + z**2)
    return 1j * kExt * np.exp(1j * kExt * x) * nx

uIncDeriv = lib.createGridFunction(context, pconsts, pconsts, uIncDerivData,
                                   surfaceNormalDependent=True)

# Create elements of the right hand side of the equation

rhs = [uInc, None]
Exemplo n.º 18
0
 def project_incident_field(self,fun,time,space_index=0):
     f = lambda x:fun.dirichlet_trace(x,time)
     gridFun = _bempplib.createGridFunction(self._context,self._spaces[0],self._spaces[0],f)
     return gridFun.coefficients()