Writing VTK files
Once a solution exists (the result of the forms tutorial, or any grid function), the last step is usually getting it into a viewer. export_vtk writes a mesh and any number of named fields to a .vtr file, readable by ParaView or any other VTK-aware tool. This tutorial covers:
- Writing a mesh with a named field.
- The shorthand for a single field.
- A composite element as one vector field, not several scalar ones.
- The 1D case.
export_vtk needs WriteVTK.jl, which is a weak dependency: using WriteVTK before calling it, or the call errors with a message that says so rather than a bare MethodError.
Every code block below was run before being written down, and each produces the files it claims to.
1. A mesh and a named field
export_vtk takes a filename, a mesh, and any number of name => data pairs:
using Bramble, WriteVTK
Ωₕ = mesh(domain(interval(0.0, 1.0) × interval(0.0, 1.0)), (20, 20), (true, true))
Wₕ = gridspace(Ωₕ)
uₕ = Rₕ(Wₕ, x -> sin(x[1]) * x[2])
files = export_vtk(joinpath(mktempdir(), "solution"), Ωₕ, "u" => uₕ)1-element Vector{String}:
"/tmp/jl_2yUm28/solution.vtr"data can be a VectorElement, which is reshaped to match the grid the same way reshape does, or a plain array already shaped that way. Passing more than one pair writes more than one field into the same file:
vₕ = Rₕ(Wₕ, x -> x[1] + x[2])
export_vtk(joinpath(mktempdir(), "two_fields"), Ωₕ, "u" => uₕ, "v" => vₕ)2. One field, without naming the mesh
A lone VectorElement already carries its mesh, so the field can be written directly. The field is named "u" unless told otherwise:
export_vtk(joinpath(mktempdir(), "shorthand"), uₕ)3. A composite element is one vector field
An element over a composite space (Wₕ^Val(2) and the rest) writes as a single field with one component per block, rather than as separate scalar fields per component. This is the shape of a Stokes solve's output: a vector velocity next to a scalar pressure, on the same mesh, in one file.
Vₕ = Wₕ^Val(2)
velocity = Rₕ(Vₕ, x -> (sin(π * x[1]) * cos(π * x[2]), -cos(π * x[1]) * sin(π * x[2])))
pressure = Rₕ(Wₕ, x -> cos(2π * x[1]) * cos(2π * x[2]))
export_vtk(joinpath(mktempdir(), "stokes"), Ωₕ, "velocity" => velocity, "pressure" => pressure)velocity is the classical divergence-free field $(\sin(\pi x)\cos(\pi y),\, -\cos(\pi x)\sin(\pi y))$, not the result of solving anything: a stand-in to check that export_vtk gives a viewer one two-component velocity vector alongside a one-component pressure scalar, which is what a coupled solve's fields look like once assembled. Solving the system that produces them is the forms tutorial's subject; this one is only about writing the result out once you have it.
4. One dimension
VTK has no dedicated 1D grid type, so a 1D mesh gets a rectilinear grid one point deep in y, which opens and renders correctly, rather than being refused:
Ω1 = mesh(domain(interval(0.0, 1.0)), 33, true)
W1 = gridspace(Ω1)
f1 = Rₕ(W1, sin)
export_vtk(joinpath(mktempdir(), "curve"), f1)Where to go next
A full VTK file is usually more than a single plot going into a LaTeX document needs. For that, the PGFPlots export tutorial writes the plain text table pgfplots reads directly, with no external package at all. And for a plot inside the current Julia session, with no file at all, see Plotting directly.