-
Notifications
You must be signed in to change notification settings - Fork 5
Geometry
To use a particular 2-D geometry in GITR, it must be processed into a .cfg
file. This involves having the points in the correct order, superimposing the divertor geometry over the device geometry, increasing the fineness, defining the inside of the device, converting the points to line segments, and defining the materials of the device and divertor. Most of this work can be done inside the user-made make_geom_<example>.py
.
The following example is done with solps.
Steps:
-
Read the file
USER INPUT for reading in wall geometry file type
-
Order points
USER INPUT for writing
manual_indices
-
Replace divertor target points on the wall with the corresponding points from b2fgmtry
-
Differentiate wall, divertor, and surface
USER INPUT for identifying interactive surfaces by defining
W_indices_coarse
-
Increase the fineness of interactive surface points
USER INPUT for
numAddedPoints
-
Identify interior
USER INPUT for creating
inDir
-
Create line segments
-
Define target material
USER INPUT for defining
Z
Read in your wall geometry from any file. This example has a .ogr
file type.
Requires USER INPUT to properly extract numpy arrays for r and z:
# read data in ogr r,z wall geometry from original geometry file
with open(solps_geomfile) as f: solps_geom = f.readlines()[1:]
solps_geom[-1] += '\n' # need this for index counting in r,z extraction
# populate matrices for r_ogr and z_ogr
r_original = z_original = np.empty(0)
for row in solps_geom:
rvalue = float(row.split(' ')[0])
r_original = np.append(r_original, rvalue)
zvalue = float(row.split(' ')[1][0:-1])
z_original = np.append(z_original, zvalue)
To visualize the order of the points, save the points in a .txt
or .m
file to be visualized in another script.
with open(solps_rz, 'w') as f:
for i in range(0,len(r_original)):
f.write(str(r_original[i]) +' '+ str(z_original[i]) +'\n')
The points provided by the imported file should be assumed to not be in order. Plot them using viz_geom.m
or a similar script in any language (MATLAB, Python, etc.) and order them chronologically. Typically, these points are located with the coordinates r and z, or (r,z)
. All units should be in meters.
Requires USER INPUT to define manual_indices
:
# order points r and z as determined visually using viz_geom.m or a similar plotting script
manual_indices = np.array(range(2, 8))
manual_indices = np.append(manual_indices, range(9, 11))
manual_indices = np.append(manual_indices, range(13, 17))
manual_indices = np.append(manual_indices, 20)
manual_indices = np.append(manual_indices, range(24, 28))
manual_indices = np.append(manual_indices, [30, 31, 40])
manual_indices = np.append(manual_indices, range(45, 50))
manual_indices = np.append(manual_indices, 52)
manual_indices = np.append(manual_indices, range(53, 57))
manual_indices = np.append(manual_indices, range(60, 64))
# create a closed geometry by putting the first data point at the end
manual_indices = np.append(manual_indices, 2))
# ensure all units are in meters
r_wall = r_original[manual_indices]/1000 #mm->m
z_wall = z_original[manual_indices]/1000 #mm->m
The geometry for the target may be contained separately in b2fgmtry or a similar file. This must be superimposed over the device geometry and stitched together using gitr.py
.
Requires no user input:
#get target geometry from b2fgmtry (SOLPS) and stitch to wall geometry
r_right_target, z_right_target, r_left_target, z_left_target = solps.get_target_coordinates(solps_b2fgmtry_targfile)
# Replace wall points with b2fgmtry target points
r_final_coarse, z_final_coarse = gitr.replace_line_segment(r_left_target, z_left_target, r_wall, z_wall)
r_final_coarse, z_final_coarse = gitr.replace_line_segment(r_right_target, z_right_target, r_wall, z_wall)
Once the divertor geometry has been superimposed, the material of the divertor must be defined. This is how surface tiles are defined, which are line segments capable of self-sputtering and tracking erosion and redeposition. The output information for these segments will appear in surface.nc
after running GITR. In this case, a portion of the divertor is made out of tungsten while the rest is the same material as the wall.
Requires USER INPUT to choose surface tiles:
# Define Tungsten surface in divertor
W_indices_coarse = np.array(range(21,29))
Depending on the fineness of the geometry, the number of points may have to be increased in the divertor area to achieve better statistics in erosion results. numAddedPoints
is the number of additional points to be added. W_indices_coarse
is an array of the target (tungsten) while it is coarse.
Requires no user editing for this section. However, the user must define numAddedPoints
in the setup.py
script:
# Increase Fineness of W Divertor Surface
#set number of added points in a line segment to be proportional to the length of the segment
rSurfCoarse = r_final_coarse[W_indices_coarse]
zSurfCoarse = z_final_coarse[W_indices_coarse]
dist = np.sqrt((rSurfCoarse[:-1]-rSurfCoarse[1:])**2 + (zSurfCoarse[:-1]-zSurfCoarse[1:])**2)
totalDist = np.sum(dist)
addedPoints = numAddedPoints*dist/totalDist
print('addedPoints',addedPoints)
for i,v in enumerate(addedPoints): addedPoints[i] = round(v)
addedPoints = np.array(addedPoints,dtype='int')
#populate rSurfFine and zSurfFine with the added points
rSurfFine = rSurfCoarse[0]
zSurfFine = zSurfCoarse[0]
for i,v in enumerate(addedPoints):
rBegin = rSurfCoarse[i]
zBegin = zSurfCoarse[i]
rEnd = rSurfCoarse[i+1]
zEnd = zSurfCoarse[i+1]
dr = (rEnd-rBegin)/(v+1)
dz = (zEnd-zBegin)/(v+1)
for j in range(1,v+1):
rSurfFine = np.append(rSurfFine,rSurfCoarse[i]+j*dr)
zSurfFine = np.append(zSurfFine,zSurfCoarse[i]+j*dz)
rSurfFine = np.append(rSurfFine,rSurfCoarse[i+1])
zSurfFine = np.append(zSurfFine,zSurfCoarse[i+1])
r_final, z_final = gitr.replace_line_segment(rSurfFine, zSurfFine, r_final_coarse, z_final_coarse)
W_indices_fine = np.array(range(W_indices_coarse[0], W_indices_coarse[-1]+numAddedPoints))
Using a function in gitr.py
, the inward direction of each line segment must be defined. This will most likely have to be set manually. The following code will show the original direction of each line segment and inDir indices are modified to switch the direction of any line segment not pointing inward. These inDir indices are specific to this example where 0 starts at the top left corner.
Requires USER INPUT to set inDir
for some indices to -1:
#define interior side of each line segment in the geometry with inDir
inDir = np.ones(len(r_final))
inDir[0:20] = inDir[22] = inDir[26:30] = -1
The points are connected as line segments to create a whole geometry. This step also plots the inward direction, so this step and the previous one should be performed iteratively to affirm that inDir
is properly defined.
#populate lines and check that vectors point inward
#edit lines above so that interior is correctly defined
lines = gitr.gitr_lines_from_points(r_final, z_final)
gitr.lines_to_vectors(lines, inDir, 'inDir', plt)
Define the material of the target area. These line segments will be the only interactive surfaces recognized by the simulation. They will be capable of reflection and sputtering. The remainder of the wall will not be interactive, and particles that strike those line segments will simply be absorbed and re-sampled.
Requires no user editing for this section. However, the user must define the element for the surface tiles as surface_Z
in the setup.py
script:
#define the divertor target segments, targ_indices, a material and an interactive surface
Z = np.zeros(len(r_final))
surfaces = np.zeros(len(r_final))
Z[W_indices_fine] = surface_Z;
surfaces[W_indices_fine] = 1;
Once the geometry is complete, convert it into a .cfg
file using gitr.py
.
Requires no user input:
#populate geometry input file to GITR
gitr.lines_to_gitr_geometry(gitr_geometry_filename+'0', lines, Z, surfaces, inDir)
gitr.removeQuotes(gitr_geometry_filename+'0', gitr_geometry_filename)
Anything unclear or inaccurate? Please let us know by creating an Issue in the GitHub Issues tab.