### Converting a Function object to a VTK object in parallel

100
views
0
4 months ago by
I am looking to use a VTK filter at run time and thus need to convert the dolfin.Function object to a vtkUnstructuredGrid. While I have figured out how to do this in serial as shown in my answer to this question, this does not work in parallel. The line V.tabulate_dof_coordinates() gives the coordinates of the nodes belonging to the current sub-process, which (in all cases I've tested) do not complete the cells in that same sub-process.

As an example, consider the mesh created by dolfin.UnitSquareMesh(1,1), and run this on 2 processes. One cell (out of two) and two nodes (out of four) will go to each process. So both processes contain a local connectivity matrix of (0,1,2), but only have two nodes. How do I access or duplicate the other nodes necessary to complete the cell locally?

This question was originally asked here before the transition.

EDIT:

(I am using fenics-2016.2.0)

Consider the following script:
from __future__ import print_function

import numpy as np
import dolfin as dlf

mesh = dlf.UnitSquareMesh(1, 1)
V = dlf.FunctionSpace(mesh, "CG", 1)
dofmap = V.dofmap()
rank = dlf.MPI.rank(dlf.mpi_comm_world())

n_cells = mesh.num_cells()
n_nodes = dofmap.max_element_dofs()
connectivity = np.zeros([n_cells, n_nodes], dtype=np.int)
for i in range(n_cells):
connectivity[i,:] = dofmap.cell_dofs(i)

print("(rank %i) V.tabulate_dof_coordinates() = " % rank, V.tabulate_dof_coordinates())
print("(rank %i) connectivity = " % rank, connectivity)

When this script is run in one process, it produces the following output:

(rank 0) V.tabulate_dof_coordinates() =  [ 0.  1.  0.  0.  1.  1.  1.  0.]
(rank 0) connectivity =  [[1 3 2]
[1 0 2]]​

and when run on 2 processes:

(rank 0) V.tabulate_dof_coordinates() =  [ 1.  0.]
(rank 1) V.tabulate_dof_coordinates() =  [ 0.  1.  0.  0.  1.  1.]
(rank 0) connectivity =  [[1 0 2]]
(rank 1) connectivity =  [[1 0 2]]​

As you can see from the second output, the number of coordinates owned by process 0 is only 1, but the connectivity refers to nodes with local IDs 1 and 2 as well. The output that I want is

(rank 0) V.tabulate_dof_coordinates() =  [ 1.  0.  0.  0.  1.  1.]
(rank 1) V.tabulate_dof_coordinates() =  [ 0.  1.  0.  0.  1.  1.]
(rank 0) connectivity =  [[1 0 2]]
(rank 1) connectivity =  [[1 0 2]]
so that I may have a complete mesh on each process. Not having these additional nodes duplicated in the appropriate processes causes invalid unstructured grid objects since local DOF indices within the connectivity matrix will be out of range in some processes.
Community: FEniCS Project
I would expect 'V.tabulate_dof_coordinates()' to work, so please post a minimal working example (MWE) and include a descriptions of what you expect/want versus what the MWE does.
written 4 months ago by Garth Wells
I have edited my question to include what you requested. Thank you for your time!
written 4 months ago by Miguel Rodriguez

Don't use Function::tabulate_dof_coordinates. It returns only 'owned' dofs and is intended for a different purpose.