# Changing mesh coordinates¶

Users may want to change the coordinates of an existing mesh object
for certain reasons. The coordinates can be accessed as a
`Function`

through `mesh.coordinates`

where `mesh`

is
a mesh object. For example,

```
mesh.coordinates.dat.data[:, 1] *= 2.0
```

streches the mesh in the *y*-direction. Another possibility is to use
`assign()`

:

```
Vc = mesh.coordinates.function_space()
x, y = SpatialCoordinate(mesh)
f = Function(Vc).interpolate(as_vector([x, y*2.0]))
mesh.coordinates.assign(f)
```

This can also be used if f is a solution to a PDE.

Warning

Features which rely on the coordinates field of a mesh’s PETSc `DM`

(usually a `DMPlex`

) such as `VertexOnlyMesh()`

and
`MeshHierarchy()`

will not work as expected if the
`mesh.coordinates`

field has been modified: at present, the this
does not correspondingly update the coordinates field of the `DM`

.
This will be fixed in a future Firedrake update.

## Changing the coordinate function space¶

For more complicated situations, one might wish to replace the mesh
coordinates with a field which lives on a different
`FunctionSpace`

(e.g. higher-order meshes).

Note

Re-assigning the `coordinates`

property of a mesh used to be an
undocumented feature. However, this no longer works:

```
mesh.coordinates = f # Raises an exception
```

Instead of re-assigning the coordinates of a mesh, one can create new mesh object from a field f:

```
new_mesh = Mesh(f)
```

`new_mesh`

has the same mesh topology as the original mesh, but its
coordinate values and coordinate function space are from f. The
coordinate function space must be a rank-1
`FunctionSpace`

, constructed either with
`VectorFunctionSpace()`

, or by providing a
`VectorElement`

to `FunctionSpace()`

. For
efficiency, the new mesh object shares data with f. That is,
changing the values of f will change the coordinate values of the
mesh, and *vice versa*. If this behaviour is undesired, one should
explicitly copy:

```
g = Function(f) # creates a copy of f
new_mesh = Mesh(g)
```

Or simply:

```
new_mesh = Mesh(Function(f))
```

## Replacing the mesh geometry of an existing function¶

Creating a new mesh geometry object, as described above, leaves any
existing `Function`

s untouched – they continue to live
on their original mesh geometries. One may wish to move these
functions over to the new mesh. To move f over to `mesh`

, use:

```
g = Function(functionspaceimpl.WithGeometry.create(f.function_space(), mesh),
val=f.topological)
```

This creates a `Function`

g which shares data with f,
but its mesh geometry is `mesh`

.

Warning

The example above uses Firedrake internal APIs, which might change in the future.