solfun = solution.gridFunction() # We now do a simple 3d visualization. The visualization module provides some # helper routines using the TVTK package. A lot more is possible by directly # accessing the Mayavi visualization pipelines. # (This example still uses the "old" visualization module. It needs to be # updated to the "new" visualization module visualization2.) # In order to evaluate the field we need to create a single-layer potential # operator. Note: A single-layer potential operator is different from a # single-layer boundary operator in the sense that its purpose is evaluation in # free space, while the boundary operator is a weak form that lives on the # boundary. potential = lib.createHelmholtz3dSingleLayerPotentialOperator(context, k) # We will create a three-plane view. For this we need to define the extents of # the planes and the number of grid points in each dimension. limits = (-5, 5) dims = 200 # The total field is evaluated as u = u_{inc} - S u_{n}, where u_{inc} is the # incident field and u_{n} the computed normal derivative stored in solfun. # Hence, to get the total field we need to take the output of val = S u_{n} and # compute u_{inc} - val for each grid point. This is done by the following # 'transformation' function, which is given to the visualization routine. def transformation(point, val): return np.real(np.exp(1j *k * point[:,0]) - val)
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) dlPot = lib.createHelmholtz3dDoubleLayerPotentialOperator(context, k) evalOptions = lib.createEvaluationOptions() endpl = 0.5 radpl = 0.1 hwwing = 0.05 angl = 0.3 wings = 0.3 xe = radpl * np.cos(angl) + wings ye = 0.0 #radpl*Sin(angl); ze = 0.0 # : Middle of wing plane potRes = slPot.evaluateAtPoints(sol, [[xe], [ye], [ze]], evalOptions)
uExtDeriv = solution.gridFunction(1) # Combine them with the incident wave to yield the traces of the scattered field # (uSc) and the field transmitted into the object (uInt) uSc = uExt - uInc uScDeriv = uExtDeriv - uIncDeriv uInt = uExt uIntDeriv = rhoInt / rhoExt * uExtDeriv # PART 6: Evaluate the total field on part of the xy plane ##################### # Create the potential operators entering the Green's representation formula slPotInt = lib.createHelmholtz3dSingleLayerPotentialOperator(context, kInt) dlPotInt = lib.createHelmholtz3dDoubleLayerPotentialOperator(context, kInt) slPotExt = lib.createHelmholtz3dSingleLayerPotentialOperator(context, kExt) dlPotExt = lib.createHelmholtz3dDoubleLayerPotentialOperator(context, kExt) # Create a grid of points nPointsX = 201 nPointsY = 201 x, y, z = np.mgrid[-5:5:nPointsX*1j, -5:5:nPointsY*1j, 0:0:1j] points = np.vstack((x.ravel(), y.ravel(), z.ravel())) # Split the points into those located inside and outside the scatterer inside = lib.areInside(grid, points) outside = np.logical_not(inside)