Converting a Function object to a VTK object in parallel
10 months ago by
dolfin.Functionobject 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.
(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
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.
(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]]
Community: FEniCS Project
10 months ago by
Function::tabulate_dof_coordinates. It returns only 'owned' dofs and is intended for a different purpose.
Each process holds a 'proper' mesh got it's part of the domain. From a vector of dofs you can get all the values, and use the dofmap to figured how the values relate to dofs on the mesh.
Please login to add an answer/comment or follow this question.