Class grid


Code: domain/grid.mpl

An instance of this class represents a triangulation of a domain.

Field: description::string = ""
Field: domain::domain

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 = 0

Number of points in the grid

Field: num_edges::integer = 0

Nmber of edges in the grid

Field: num_faces::integer = 0

Number of triangular faces in the grid

Field: num_vars::integer = 0

Number 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::table

A 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::table

A 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::table

A 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::table

This 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::table

This 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 = 0

Total 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 = 0

This 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)::boolean

Returns true if there is an edge whose endpoints have indices i and j.


Method: has_face(i,j,k)::boolean

Returns true if there is an face whose endpoints have indices i, j and k.


Method: edge_indices()::list(list(integer))

Returns the list of pairs [i,j] such that there is an edge from point i to point j


Method: face_indices()::list(list(integer))

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)


Method: add_point(P::domain_point)::integer

Add a point (represented by an instance of domain_point) to the grid; return the index of the added point.


Method: add_new_point(c::integer,x::list(scalar))::integer

Create a new point with constraint c and coordinates x, add it to the grid, and return the index.


Method: add_new_C_point(k::integer,t)::integer

Create a new point at $c_k(t)$, add it to the grid, and return the index.


Method: add_new_v_point(k::integer)::integer

Create a new point at $v_k$, add it to the grid, and return the index.


Method: add_edge(E::domain_edge)

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.


Method: add_new_edge(i,j)

Create a new edge from point i to point j, add it to the grid, and return the index.


Method: add_face(F::domain_face)

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.


Method: add_new_face(i,j,k,s_)

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.


Method: clone()::domain_grid

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


Method: calculate()

Calculate various auxiliary quantities such as the total_flat_area field. Subclasses may override this method to perform more interesting work.


Method: set_var_indices()

Set the var_index fields of all the points in the grid.


Method: raw_adjust()

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.


Method: subdivide()::void

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.


Method: setup(coords::list(list(list(numeric))))

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.


Method: edge_plot(proj_,opts__)

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.