An important result in PIC-MC plasma simulations of sputter cathodes is the ion current absorption profile on the target, because this information can be subsequently used for determining the sputter erosion profile. With planar targets the extraction of the absorption data in a cut plane on the target surface is rather simple. However things become more complicated in case of curved substrates as e.g. in case of cylindrical sputter targets:
The absorption plot comprises the absorbed particle flux per second and per unit area and is stored as 3D volume plot within the cartesian volume grid structure. It can have only non-zero values in cells which intersect with meshed walls. For area normalization, the intersecting cell surfaces are used. These are always computed together with the effective cut-size cell volumina during initialization of a simulation run and stored in the file simulationcase/cell_surfaces.pos
.
The right graph in the figure above shows an enlarged section of the absorption profile close to the target surface thereby illustrating the main issue in obtaining accumulated absorption profiles on curved substrates: The cartesian volume grid structure does not fit well to the cylindrical shape of the surface. Therefore, the cells intersecting with the cylinder form a step-like structure, and partially multiple intersecting cells are aligned on top of each other.
The solution is to consider the product S A between cell surface S and normalized absorption A and to take the following average along vertical direction through all cells intersecting with the cylindrical surface:
This way, the total absorption cumulated over all intersecting cells in vertical direction is divided by the total intersecting cell surface, which is the proper way of averaging the absorption profile on curved surfaces. With the RIG VM postprocessing tools this can be accomplished within following script.
compiletime load "module_ppp.so"; case = BATCH.file; PPP obj = { # Create forward reference for the maximal # absorption at left and right side from center line: float AMAX : 0.5*(A_left_max + A_right_max + abs(A_left_max - A_right_max)); }; T0 = 15; # Start time for time averaging T1 = 20; # End time for time averaging DT = 2.5; # Plot interval radius = 75; # Target radius tilt = 10; # Magnet tilt angle # Compute resulting center coordinate of absorption profile pi = 4*atan(1); Y_center = 92.5 - radius*sin(tilt*pi/180); # Make center coordinate also visible in obj obj.Y_center = Y_center; # Read averaged absorption and cell surfaces for(time=T0; time<=T1+1e-6; time=time+2.5) { obj.read("$case/absorption/absorption_Arplus_$(time%,2f)us.pos", "A"); } obj.read("$case/cell_surfaces.pos", "S_All"); # Consider only surfaces, where Arplus absorption is non-zero obj.create_scalar("S", S_All*A>0 ? S_All ! 0); # Create product A*S obj.create_scalar("AS_product", S*A); # Make horizontal cutplane at Target T2 averaging across upper half surface obj.plane(-298, 0, 205, 298, 0, 205, -298, 170, 205, 40, 0, 0, "average"); obj.reduce(); # Create averaged absorption sum A*S / sum S (if sum S > 0) obj.create_scalar("A_avg", S>0 ? AS_product/S ! 0); # Save plane view with projected absorption for illustration obj.write_pos_scalar_binary("extract/$case-Arplus2D-T2.pos", "Averaged Arplus absorption %", A_avg/A_avg_max*100); # Make cumulated line profiles # Create scalars for distinguishing absorption on left and right side from center obj.create_scalar("A_left", y<Y_center ? A_avg ! 0); obj.create_scalar("A_right", y>Y_center ? A_avg ! 0); # Convert plane profile into accumulated linescan obj.xz_plane(Y_center, radius, "sum"); # Write relative line profiles into TXT file obj.write_txt("extract/$case-T2-lineprofiles.txt", ["x", "A_left_%", "A_right_%"], [x, 100*A_left/AMAX, 100*A_right/AMAX]);
The pictures below show the accumulated Ar+ flux distribution projected onto the 2D cutplane (left graph) as well as the cumulated line profiles of the racetracks on both sides (right graph).
For a cylindrical surface and a given magnetic field, it is often interesting to plot the horizontal and vertical magnetic field component. This can be obtained via the cylindric cutplane function embedded in the RIG-VM postprocessing toolkit. In the following example, a cylindrical target has the following dimensions:
A postprocessing script for extracting the magnetic field on the cylindrical target surface is given as follows.
compiletime load "module_ppp.so"; case = BATCH.file; X0 = 115; X1 = 635; # Cylinder elongation in X direction Y0 = 167.5; Z0 = 247; # Center Coordinates R0 = 70; # Cylinder radius Delta = 5; # Search radius NL = 60; # Point resolution in longitudinal direction NPHI = 75; # Point resolution in angular direction PPP obj = { }; obj.read("$case/field/B_0.00us.pos", "B"); obj.cylinder(X0, Y0, Z0, X1, Y0, Z0, R0, Delta, NL, NPHI, "interpolate"); obj.write_pos_scalar_binary("extract/$case-B-radial.pos", "B radial [mT]", B_r*1000); obj.write_pos_scalar_binary("extract/$case-B-parallel.pos", "B parallel [mT]", sqrt(B_x^2 + B_phi^2)*1000);
The resulting POS file can be visualized in GMSH as follows:
The point resolutions NL, NPHI
in longitudinal and angular direction shall be in the same order as the resolution of the simulation output data. There may be some trials with different settings required for getting a proper visualization.
While some quantities such as the magnetic field exist continuously in the 3D space, other quantities such as the “absorption” exists only at the boundary between open volume and walls. For the absorption data stored in cell resolution this means, that only cells which intersect with a meshed wall can have an absorption > 0.
Therefore, taking a simple average of the absorption across several cells in the vicinity of the surface is not useful, because some of the cells will contribute zero absorption.
A workaround is to additionally load the cell surfaces S and take an average of the absorption A weighted by the cell surface
This can be applied in a postprocessing script as shown below.
compiletime load "module_ppp.so"; case = BATCH.file; X0 = 115; X1 = 635; # Cylinder elongation in X direction Y0 = 167.5; Z0 = 247; # Center Coordinates R0 = 70; # Cylinder radius Delta = 5; # Search radius NL = 60; # Point resolution in longitudinal direction NPHI = 75; # Point resolution in angular direction PPP obj = { }; obj.read("$case/absorption/absorption_Arplus_10.00us.pos", "A"); obj.read("$case/cell_surfaces.pos", "S"); obj.create_scalar("AxS", A*S); obj.cylinder(X0, Y0, Z0, X1, Y0, Z0, R0, Delta, NL, NPHI, "average"); obj.write_pos_scalar_binary("extract/$case-abs-cyl-Arplus.pos", "Ar+ absorption [1/m^2 s]", (S>0) ? AxS / S ! 0);