Syntax:
read_surf filename keyword args ...
type arg = none NOTE: if the type or custom keywords are used, they must come first custom args = name datatype Nc name = name of custom per-surf vector or array datatype = int or float = for integer or floating point values Nc = 0 for a vector (single value), Nc >= 1 for an array (one or more values) NOTE: if the type or custom keywords are used, they must come first origin args = Ox Oy Oz Ox,Oy,Oz = set origin of surface to this point (distance units) trans args = Dx Dy Dz Dx,Dy,Dz = translate origin by this displacement (distance units) atrans args = Ax Ay Az Ax,Ax,Az = translate origin to this absolute point (distance units) ftrans args = Fx Fy Fz Fx,Fy,Fz = translate origin to this fractional point in simulation box scale args = Sx Sy Sz Sx,Sy,Sz = scale surface by these factors around origin rotate args = theta Rx Ry Rz theta = rotate surface by this angle in counter-clockwise direction (degrees) Rx,Ry,Rz = rotate around vector starting at origin pointing in this direction transparent args = none invert args = none clip args = none or fraction fraction = push points close to the box boundary to the boundary (optional) group arg = group-ID group-ID = new or existing surface group to assign the surface elements to typeadd arg = Noffset Noffset = add Noffset to the type value of each element particle args = none or check or keep none = allow no particles in simulation when read surfs (default) check = delete particles inside surfs or in cells intersected by surfs keep = keep all particles file args = identical to those defined for the write_surf command NOTE: if used, the file keyword must come last
Examples:
read_surf surf.sphere read_surf surf.sphere type custom temperature float 0 read_surf surf.sphere group sphere2 typeadd 1 read_surf surf.file trans 10 5 0 scale 3 3 3 invert clip read_surf surf.file trans 10 5 0 scale 3 3 3 invert clip 1.0e-6 read_surf surf.file trans 10 5 0 scale 3 3 3 invert clip file tmp.surfs read_surf surf.file trans 10 5 0 scale 3 3 3 invert clip file tmp.surfs.% points no nfile 32
Description:
Read the geometry of a surface from the specified file. In SPARTA, a "surface" is a collection of surface elements that represent the surface(s) of one or more physical objects which will be embedded in the global simulation box. Surfaces can be explicit or implicit. This command reads explicit surfaces from a file containing a list of explicit surfaces. See the read_isurf command to read implicit surfaces from a different kind of file. See the Howto 6.13 section of the manual for an explantion of explicit versus implicit surfaces as well as distributed versus non-distributed storage. You cannot mix explicit and implicit surfaces in the same simulation.
Surface elements are triangles in 3d or line segments in 2d. Surface elements for each physical object are required to be a complete, connected set that tile the entire surface of the object. See the discussion of watertight objects below.
Particles collide with surface elements as they advect. Each surface element is assigned to a collision model, specified by the surf_collide command which affects how a particle bounces off the surface. Each surface element can optionally be assigned to a reaction model, specified by the surf_react command which determines if any surface chemistry occurs during a collision. Statistics for each surface element due to their interactions with particles can be tallied via the compute surf command, time-averaged via the fix ave/surf command, and ouput via the dump surface command.
Surface elememts can be assigned to surface groups via the group surf command. Surface group IDs are used by other commands to operate on selected sets of elements. This command has group and typeadd keywords which can be used to help assign different elements or different objects to different groups.
Explicit surface elements can be stored in a distributed fashion (each processor only stores elements which overlap grid cells it owns or has a ghost cell copy of). Or each processor can store a copy of all surface elements (the default). See the global surfs command to change this setting.
Note that the read_surf command can be used multiple times to read multiple objects from multiple files and add them to the simulation domain. The format of a surface file for explicit elements is discussed below. Optional keywords allow the vertices in the file to be translated, scaled, and rotated in various ways. This allows a single surface file, e.g. containing a unit sphere, to be used multiple times in a single simulation or in different simulations.
The tools directory contains tools that can create surface files with simple geometric objects (spheres, blocks, etc). It also has tools that can convert surface files in other formats to the SPARTA format for explicit surfaces, e.g. for files created by a mesh-generation program.
If all the surface elements are contained in a single file, the specified file can be a text file or a gzipped text file (detected by a .gz suffix).
If a "%" character appears in the surface filename, SPARTA expects a set of multiple files to exist. The write_surf command explains how such sets are created. Read_surf will first read a filename where "%" is replaced by "base". This file tells SPARTA how many total surfaces and files are in the set (i.e. just the header information described below). The read_surf command then reads the additional files. For example, if the surface file was specified as save.% when it was written, then read_surf reads the files save.base, save.0, save.1, ... save.P-1, where P is the number of processors that created the surface file.
Note that P could be the total number of processors in the previous simulation, or some subset of those processors, if the fileper or nfile options were used when the surface file was written; see the write_surf command for details. The processors in the current SPARTA simulation share the work of reading these files; each reads a roughly equal subset of the files. The number of processors which created the set can be different than the number of processors in the current SPARTA simulation. This can be a fast mode of input on parallel machines that support parallel I/O.
The remainder of this section describes the format of a single surface file, whether it is the only file or one of multiple files flagged with a processor number.
A surface file for explicit surfaces has a header and a body. The header appears first. The first line of the header is always skipped; it typically contains a description of the file. Then lines are read one at a time. Lines can have a trailing comment starting with '#' that is ignored. If the line is blank (only whitespace after comment is deleted), it is skipped. If the line contains a header keyword, the corresponding value is read from the line. If it doesn't contain a header keyword, the line begins the body of the file.
The body of the file contains one or more sections. The first line of a section has only a keyword. The next line is skipped. The remaining lines of the section contain values. The number of lines in a section depends on the section keyword as described below. Zero or more blank lines can be used between sections. Sections can appear in any order.
The formatting of individual lines in the surface file (indentation, spacing between words and numbers) is not important except that header and section keywords must be capitalized as shown and can't have extra white space between their words.
These are the recognized header keywords. Header lines can come in any order. The value(s) are read from the beginning of the line. Thus the keyword points should be in a line like "1000 points".
The files keyword only appears in the "base" file for a set of multiple files indicated by the "%" character in the filename. It tells SPARTA how many additional files exist in the set. A "base" file has no additional sections, i.e. no body.
The points keyword is optional (see below). For a set of multiple files, it cannot appear in the "base" file, but only in individual files in the set.
The points, lines, triangles keywords refer to the number of points, lines, triangles in an individual file. Except in the case of a "base" file for a set of multiple files. In that case, the lines and triangles keywords give the number of lines or triangles in the entire set.
These are the recognized section keywords for the body of the file.
The Points section consists of N consecutive entries, where N = # of points, each of this form:
index x y z (for 3d) index x y (for 2d)
The index value is ignored; it is only added to assist in examining the file. When lines and triangles reference point indices they are simply ordered from 1 to N, regardless of the actual value of the index in the file. X,y,z are the coordinates of the point in distance units. Note that for 2d simulations, z should be omitted.
IMPORTANT NOTE: Unless points are on the surface of the simulation box, they will be part of multiple lines or triangles. However, there is no requirement that each point appear exactly once in the Points list. For example, a point that is the common corner point of M triangles, could appear 1 or 2 or up to M times. However, if the same point appears multiple times in the Points list, the coordinates of all copies must be numerically identical, in order for SPARTA to verify the surface is a watertight object, as discussed below.
IMPORTANT NOTE: The points keyword and Points section are not required. You must either use both or neither. As explained next, an optional format for the Lines or Triangles sections includes point coordinates directly with each line or triangle.
The Lines section is only allowed for 2d simulations and consists of N entries, where N = # of lines. All entries must be in the same format, either A or B. If a Points section was included, use format A. If it was not, use format B.
line-ID (type) p1 p2 (custom1) (custom2) ... # format A line-ID (type) p1x p1y p2x p2y (custom1) (custom2) ... # format B
The line-ID is stored internally with the line and can be output by the dump surf command. If the read_surf commmand is reading a single file, the line-IDs should be unique values from 1 to N where N is the number of lines specified in the header of the file. For a set of multiple files, each line in the collection of all files should have a unique ID, and the IDs should range from 1 to N, where N is the number of lines specified in the base file.
Note that SPARTA does not check line-IDs for uniqueness, only that the smallest values is 1 and the largest value is N. Also note that lines in an individual file (single or multiple) do not need to be listed by ID order; they can be in any order.
IMPORTANT NOTE: If the read_surf command is used when lines already exist, i.e. to add new lines, then each line-ID is incremented by Nprevious = the # of lines that already exist.
Type is an optional integer value and can only be specified if the type keyword is used. It must be a positive integer for each line. If not specified, the type of each line is set to 1. Line IDs and types can be used to assign lines to surface groups via the group surf command.
For format A, p1 and p2 are the indices of the 2 end points of the line segment, as found in the Points section. Each is a value from 1 to the # of points, as described above. For format B, (p1x,p1y) and (p2x,p2y) are the (x,y) coordinates of the two points (1,2) in the line.
The ordering of p1, p2 is important as it defines the direction of the outward normal for the line segment when a particle collides with it. Molecules only collide with the "outer" edge of a line segment. This is defined by a right-hand rule. The outward normal N = (0,0,1) x (p2-p1). In other words, a unit z-direction vector is crossed into the vector from p1 to p2 to determine the normal.
The custom values are optional and can only be specified if the custom keyword is used one or more times. Each use of the custom keyword determines how many values are appended to each line. For a custom per-surf vector, a single value is appended. For a custom per-surf array, Nc values are appended. The values are assigned to custom vectors or arrays in the order the custom keywords are specified. For example, for this read_surf command, 4 custom values should be added to the end of each line in the Lines section of the input file:
read_surf surf.sphere type custom temperature float 0 custom flags int 3
The first floating-point value will be the temperature, the next 3 integers will be flags.
The Triangles section is only allowed for 3d simulations and consists of N entries, where N = # of triangles. All entries must be in the same format, either A or B. If a Points section was included, use format A. If it was not, use format B.
tri-ID (type) p1 p2 p3 (custom1) (custom2) ... # format A tri-ID (type) p1x p1y p1z p2x p2y p2z p3x p3y p3z (custom1) custom2) ... # format B
The tri-ID is stored internally with the triangle and can be output with the dump surf comand. If the read_surf command is reading a single file, the tri-IDs should be unique values from 1 to N where N is the number of triangles specified in the header of the file. For a set of multiple files, each triangle in the collection of all files should have a unique ID, and the IDs should range from 1 to N, where N is the number of triangles specified in the base file.
Note that SPARTA does not check tri-IDs for uniqueness, only that the smallest values is 1 and the largest value is N. Also note that triangles in an individual file (single or multiple) do not need to be listed by ID order; they can be in any order.
IMPORTANT NOTE: If the read_surf command is used when triangles already exist, i.e. to add new triangles, then each tri-ID is incremented by Nprevious = the # of triangles that already exist.
Type is an optional integer value and can only be specified if the type keyword is used. It must be a positive integer for each triangle. If not specified, the type of each triangle is set to 1. Triangle IDs and types can be used to assign triangles to surface groups via the group surf command.
For format A, p1, p2, and p3 are the indices of the 3 corner points of the triangle, as found in the Points section. Each is a value from 1 to the # of points, as described above. For format B, (p1x,p1y,p1z), (p2x,p2y,p2z), and (p3x,p3y,p3z) are the (x,y,z) coordinates of the three corner points (1,2,3) of the triangle.
The ordering of p1, p2, p3 is important as it defines the direction of the outward normal for the triangle when a particle collides with it. Molecules only collide with the "outer" face of a triangle. This is defined by a right-hand rule. The outward normal N = (p2-p1) x (p3-p1). In other words, the edge from p1 to p2 is crossed into the edge from p1 to p3 to determine the normal.
The custom values are optional and can only be specified if the custom keyword is used one or more times. Each use of the custom keyword determines how many values are appended to each triangle. For a custom per-surf vector, a single value is appended. For a custom per-surf array, Nc values are appended. The values are assigned to custom vectors or arrays in the order the custom keywords are specified. For example, for this read_surf command, 4 custom values should be added to the end of each triangle in the Triangles section:
read_surf surf.sphere type custom temperature float 0 custom flags int 3
The first floating-point value will be the temperature, the next 3 integers will be flags.
The following optional keywords affect the format of the surface file(s) that are read. If used, these two keywords must come before any other keywords.
The type keyword means that each surface element in the Lines or Triangles section will include a surface element type, which is a positive integer. See the discussion of the format of the Lines and Triangles sections above for details.
The custom keyword allows a custom per-surf vector or array to be created and initialized. Custom vectors or arrays associate a single value or multiple values with each surface element. They can be output by the dump surf command and uses as inputs by other commands. For example, many of the models for the surf_collide command take temperature as an input; use of a per-surf vector allows the temperature of individual surface elements to be specified.
The name argument is the name assigned to the new custom vector or array. The datatype argument is int or float which determines whether the vector/array stores integer or floating point values. The final Nc argument is 0 for a per-surf vector and an integer >= 1 for an array with Nc columns. A per-surf vector stores a single value per surface element; a per-surf array stores Nc values per element.
The custom keyword can be used multiple times. See the discussion of the format of the Lines and Triangles sections above for details.
If the read_surf command is used multiple times and the same custom options are not used when reading each file, then the same custom vectors or arrays attributes will be defined for all surface elements. However, their values will only be initialized for the elements in the surface files which included custom values. Otherwise the custom attributes of elements that were not specified in surface files are are initialized to zero.
The following optional keywords affect the geometry of the read-in surface elements. The geometric transformations they describe are performed in the order they are listed, which gives flexibility in how surfaces can be manipulated.
Note that the order of these arguments may be important; e.g. performing an origin operation followed by a rotate operation may not be the same as a rotate operation followed by an origin operation.
Most of the keywords perform a geometric transformation on all the vertices in the surface file with respect to an origin point. By default the origin is (0.0,0.0,0.0), regardless of the position of individual vertices in the file.
The origin keyword resets the origin to the specified Ox,Oy,Oz. This operation has no effect on the vertices.
The trans keyword shifts or displaces the origin by the vector (Dx,Dy,Dz). It also displaces each vertex by (Dx,Dy,Dz).
The atrans keyword resets the origin to an absolute point (Ax,Ay,Az) which implies a displacement (Dx,Dy,Dz) from the current origin. It also displaces each vertex by (Dx,Dy,Dz).
The ftrans keyword resets the origin to a fractional point (Fx,Fy,Fz). Fractional means that Fx = 0.0 is the lower edge/face in the x-dimension and Fx = 1.0 is the upper edge/face in the x-dimension, and similarly for Fy and Fz. This change of origin implies a displacement (Dx,Dy,Dz) from the current origin. This operation also displaces each vertex by (Dx,Dy,Dz).
The scale keyword does not change the origin. It computes the displacement vector of each vertex from the origin (delx,dely,delz) and scales that vector by (Sx,Sy,Sz), so that the new vertex coordinate is (Ox + Sx*delx,Oy + Sy*dely,Oz + Sz*delz).
The rotate keyword does not change the origin. It rotates the coordinates of all vertices by an angle theta in a counter-clockwise direction, around the vector starting at the origin and pointing in the direction Rx,Ry,Rz. Any rotation can be represented by an appropriate choice of origin, theta and (Rx,Ry,Rz).
The transparent keyword flags all the read in surface elements as transparent, meaning particles pass through them. This is useful for tallying flow statistics. The surf_collide transparent command must also be used to assign a transparent collision model to those the surface elements. The compute surf command will tally fluxes differently for transparent surf elements. The Section 6.15 doc page provides an overview of transparent surfaces. See those doc pages for details.
The invert keyword does not change the origin or any vertex coordinates. It flips the direction of the outward surface normal of each surface element by changing the ordering of its vertices. Since particles only collide with the outer surface of a surface element, this is a mechanism for using a surface files containing a single sphere (for example) as either a sphere to embed in a flow field, or a spherical outer boundary containing the flow.
The clip keyword does not change the origin. It truncates or "clips" a surface that extends outside the simulation box in the following manner. In 3d, each of the 6 clip planes represented by faces of the global simulation box are considered in turn. Any triangle that straddles the face (with points on both sides of the clip plane), is truncated at the plane. New points along the edges that cross the plane are created. A triangle may also become a trapezoid, in which case it turned into 2 triangles. Then all the points on the side of the clip plane that is outside the box, are projected onto the clip plane. Finally, all triangles that lie in the clip plane are removed, as are any points that are unused after the triangle removal. After this operation is repeated for all 6 faces, the remaining surface is entirely inside the simulation box, though some of its triangles may include points on the faces of the simulation box. A similar operation is performed in 2d with the 4 clip edges represented by the edges of the global simulation box.
IMPORTANT NOTE: If a surface you clip crosses a periodic boundary, as specified by the boundary command, then the clipping that takes place must be consistent on both the low and high end of the box (in the periodic dimension). This means any point on the boundary that is generated by the clip operation should be generated twice, once on the low side of the box and once on the high side. And those two points must be periodic images of each other, as implied by periodicity. If the surface you are reading does not clip in this manner, then SPARTA will likely generate an error about mis-matched or inconsistent cells when it attempts to mark all the grid cells and their corner points as inside vs outside the surface.
If you use the clip keyword, you should check the resulting statistics of the clipped surface printed out by this command, including the minimum size of line and triangle edge lengths. It is possible that very short lines or very small triangles will be created near the box surface due to the clipping operation, depending on the coordinates of the initial unclipped points.
If this is the case, an optional fraction argument can be appended to the clip keyword. Fraction is a unitless value which is converted to a distance delta in each dimension where delta = fraction * (boxhi - boxlo). If a point is nearer than delta to the lo or hi boundary in a dimension, the point is moved to be on the boundary, before the clipping operation takes place. This can prevent tiny surface elements from being created due to clipping. If fraction is not specified, the default value is 0.0, which means points are not moved. If specified, fraction must be a value between 0.0 and 0.5.
Note that the clip operation may delete some surface elements and create new ones. Likewise for the points that define the end points or corner points of surface element lines (2d) or triangles (3d). The resulting altered set of surface elements can be written out to a file by the write_surf command, which can then be used an input to a new simulation or for post-processing and visualization.
IMPORTANT NOTE: When the clip operation deletes or adds surface elements, the line-IDs or tri-IDs will be renumbered to produce IDs that are consective values from 1 to the # of surface elements. The ID of a surface element that is unclipped may change due to this reordering.
The following optional keywords affect group and type settings for the read-in surface elements as well as how particles are treated when surface elements are added.
Surface groups are collections of surface elements. Each surface element belongs to one or more surface groups; all elements belong to the "all" group, which is created by default. Surface group IDs are used by other commands to identify a group of suface elements to operate on. See the group surf command for more details.
Every surface element also stores a type which is a positive integer. Type values are useful for flagging subsets of elements or different objects in the surface file. For example, a patch of triangles on a sphere. Or one sphere out of several that the file contains. Surface element types can be used to define surface groups. See the group surf command for details.
The group keyword specifies an extra surface group-ID to assign all the read-in surface elements to. All the read-in elements are assigned to the "all" group and to group-ID. If group-ID does not exist, a new surface group is created. If it does exist the read-in surface elements are added to that group.
The typeadd keyword defines an Noffset value which is added to the type of each read-in surface element. The default is Noffset = 0, which means the read-in type values are not altered. If type values are not included in the file, they default to 1 for every element, but can still be altered by the typeadd keyword.
Note that use of the group and typeadd keywords allow the same surface file to be read multiple times (e.g. with different origins, tranlations, rotations, etc) to define multiple objects, and assign their surface elements to different groups or different type values.
The particle keyword determines how particles in the simulation are affected by the new surface elements. If the setting is none, which is the default, then no particles can exist in the simulation. If the setting is check, then particles in grid cells that are inside the new watertight surface object(s) or in grid cells intersected by the new surface elements are deleted. This is to insure no particles will end up inside a surface object, which will typically generate errors when particles move. If the setting is keep then no particles are deleted. It is up to you to insure that no particles are inside surface object(s), else an error may occur later. This setting can be useful if a remove_surf was used to remove a surface object, and a new object is being read in, and you know the new object is smaller than the one it replaced. E.g. for a model of a shrinking or ablating object.
IMPORTANT NOTE: The final optional keyword is file, which must be must be the last keyword specified. This is because all the remaining arguments in the read_surf command are passed to the write_surf command.
If the file keyword is used, the surfaces will be written out to the specified filename immediately after they are read in (and transformed by any of the optional keywords).
The arguments for this keyword are identical to those used for the write_surf command. This includes a file name with optional "*" and "%" wildcard characters as well as the write_surf optional keyword/arguments.
The format for the output file is the same as for the file read by this command.
Note that it can be useful to write out a new surface file after it is read if clipping was performed. This is beacuse the new file will contain surface elements altered by clipping and will not contain any surface elements removed by clipping. This may include a renumbering of the surface element IDs.
Restrictions:
This command can only be used after the simulation box is defined by the create_box command, and after a grid has been created by the create_grid command. If particles already exist in the simulation, you must insure particles do not end up inside the added surfaces. See the particle keyword for options with regard to particles.
To read gzipped surface files, you must compile SPARTA with the -DSPARTA_GZIP option - see Section 2.2 of the manual for details.
The clip keyword cannot be used when the global surfs explicit/distributed command has been used. This is because we have not yet figured out how to clip distributed surfaces.
Every vertex in the final surface (after translation, rotation, scaling, etc) must be inside or on the surface of the global simulation box. Note that using the clip operation guarantees that this will be the case.
The surface elements in a single surface file must represent a "watertight" surface. For a 2d simulation this means that every point is part of exactly 2 line segments. For a 3d simulation it means that every triangle edge is part of exactly 2 triangles. Exceptions to these rules allow for triangle edges (in 3d) that lie entirely in a global face of the simulation box, or for line points (in 2d) that are on a global edge of the simulation box. This can be the case after clipping, which allows for use of watertight surface object (e.g. a sphere) that is only partially inside the simulation box, but which when clipped to the box becomes non-watertight, e.g. half of a sphere.
Note that this definition of watertight does not require that the surface elements in a file represent a single physical object; multiple objects (e.g. spheres) can be represented, provided each is watertight.
Another restriction on surfaces is that they do not represent an object that is "infinitely thin", so that two sides of the same object lie in the same plane (3d) or on the same line (2d). This will not generate an error when the surface file is read, assuming the watertight rule is followed. However when particles collide with the surface, errors will be generated if a particle hits the "inside" of a surface element before hitting the "outside" of another element. This can occur for infinitely thin surfaces due to numeric round-off.
When running a simulation with multiple objects, read from one or more surface files, you should insure they do not touch or overlap with each other. SPARTA does not check for this, but it will typically lead to unphysical particle dynamics.
Related commands:
Default:
The default origin for the vertices in the surface file is (0,0,0). The defaults for group = all, typeadd = 0, particle = none.