An instance of this class represents a triangulation of a domain.
Field: description::string = ""This field should contain an instance of the domain class (or a subclass), which specifies the domain on which this grid is based.
Field: num_points::integer = 0Number of points in the grid
Field: num_edges::integer = 0Nmber of edges in the grid
Field: num_faces::integer = 0Number of triangular faces in the grid
Field: num_vars::integer = 0Number of degrees of freedom to move the points while respecting the fact that some points are constrained to lie on a side of the domain or at a corner.
Field: points::tableA table of points (represented by instances of the class domain_point), indexed by natural numbers starting with 0. If P=this["points"][i], then P["grid_index"] should be set to i.
Field: edges::tableA table of edges (represented by instances of the class domain_edge), indexed by natural numbers starting with 0. If E=this["edges"][i], then E["grid_index"] should be set to i.
Field: faces::tableA table of faces (represented by instances of the class domain_face), indexed by natural numbers starting with 0. If F=this["faces"][i], then F["grid_index"] should be set to i.
Field: edges_by_ends::tableThis is a table containing the same objects as the edges table, but indexed differently: if there is an edge E from this["points"][i] to this["points"][j], then this["edges_by_ends"][i,j] will be equal to E. This is set up automatically by the add_edge method. Note that edges are directed: we are assuming here that E["end"][0]=this["points"][i] and E["end"][1]=this["points"][j], and this["edges_by_ends"][j,i] (with i and j the wrong way around) will not be set.
Field: faces_by_corners::tableThis is a table containing the same objects as the faces table, but indexed differently: if there is a face F with corners this["points"][i], this["points"][j] and this["points"][k], then this["faces_by_corners"][i,j,k] will be equal to F. This is set up automatically by the add_face method.
Constructor: `new/grid`(X_,)Construct a new grid with no points
Field: total_flat_area::scalar = 0Total area of the simplicial complex whose 2-simplices are affine triangles with the same corners as the grid faces. If the faces are small then this will be a reasonable approximation to the true area of the domain (but convergence is slow).
Field: tension::scalar = 0This is a quantity depending on the edge lengths. The idea is that minimising the tension should give a grid that is quite evenly spaced. We have tried various different versions at different times.
Method: has_edge(i,j)::booleanReturns true if there is an edge whose endpoints have indices i and j.
Returns true if there is an face whose endpoints have indices i, j and k.
Returns the list of pairs [i,j] such that there is an edge from point i to point j
Returns the list of triples [i,j,k] such that there is a face with corners point i, point j and point k (in order)
Add a point (represented by an instance of domain_point) to the grid; return the index of the added point.
Create a new point with constraint c and coordinates x, add it to the grid, and return the index.
Create a new point at $c_k(t)$, add it to the grid, and return the index.
Create a new point at $v_k$, add it to the grid, and return the index.
Add an edge (represented by an instance of domain_edge) to the grid. It is assumed that the endpoints of the edge have already been added. Return the index of the added edge.
Create a new edge from point i to point j, add it to the grid, and return the index.
Add a face (represented by an instance of domain_face) to the grid. It is assumed that the corners and sides of the face have already been added. Return the index of the added face.
Create a new face with corners at point i, point j and point k. Add the edges to the grid if this has not already been done, then add the face, and return the index of the new face.
Return an independent copy of this grid, which can be changed without affecting the original. The points, edges and faces of the new grid are also independent of the points, edges and faces of the old grid
Calculate various auxiliary quantities such as the total_flat_area field. Subclasses may override this method to perform more interesting work.
Set the var_index fields of all the points in the grid.
This method sets the coordinates of all points in the grid to symbolic values involving variables t[j]. The idea is that we can then solve for the values of these variables that minimise some objective function, and then move the grid points accordingly. Note that in order to isolate the variables t[j] from any existing meaning of the symbol t, we have declared t to be a local variable in this procedure. This creates a potentially confusing situation, because this local variable will exist outside the procedure and will be visually indistinguishable from the global symbol t. In order to refer to the correct variables when solving, we need to use the indets() function.
This method subdivides the grid by adding new points at the midpoints of all the original edges, and reconnecting everything in an obvious way. The old information is destroyed by default, so one should use the clone method first if one wants to retain it.
This method takes an argument coords which should be a list of lists, all of the same length, giving a rectangular array. Both dimensions of this array should be even. Each element of the inner lists should itself be a list, giving coordinates of a point in the domain for this grid. The setup method creates a point for each entry in the array. Points in the first row are constrained to lie on $C_1$, those in the last row are constrained to lie in $C_3$, those in the first column are constrained to lie on $C_0$, and those in the last column are constrained to lie on $C_5$. The corners are constrained in the obvious way compatible with this. Edges and faces are added in a slightly non-obvious pattern to ensure that no edge crosses a corner to join points on different sides of the domain.
This method returns a plot structure displaying the edges of the grid. By default, it just uses the raw coordinates of the grid points (which will cause an error if the dimension is larger than three). However, one can supply a map proj_ as an argument, and that map will then be applied to the coordinates before plotting. Additional options for the display() command can also be given as a second argument to the method.