'vertex_to_dof_map' and 'dof_to_vertex_map'

Asked by Pietro Maximoff on 2013-04-05

Hi

This may be a silly question but I just wanted to be absolutely certain.

vertex_to_dofmap() gives the dof locations for vertex locations, i.e., I have vertex locations but I want equivalent dof locations. So, a quick example:

std::vector<std::size_t> dof_vertices;
dof_vertices = V.dofmap()->vertex_to_dof_map( mesh );

unsigned int vertex_index = 0;
for (VertexIterator vertex(mesh); !vertex.end(); ++vertex) {
    if ( x_coordinate <= 0.5 )
        (*u.vector() ).setitem( dof_vertices[vertex_index], 1 );
    else
        (*u.vector() ).setitem( dof_vertices[vertex_index], 2 );

    ++vertex_index;
}

This would set the appropriate dof locations for each vertex?!?

The inverse would be using dof_to_vertex_map() which means I have the dofs and now I want the vertex locations!?!

Thx.

Pietro

Question information

Language:
English Edit question
Status:
Solved
For:
DOLFIN Edit question
Assignee:
No assignee Edit question
Solved by:
Johan Hake
Solved:
2013-04-09
Last query:
2013-04-09
Last reply:
2013-04-07
Jan Blechta (blechta) said : #1

On Fri, 05 Apr 2013 16:46:02 -0000
Pietro Maximoff <email address hidden> wrote:
> New question #225987 on DOLFIN:
> https://answers.launchpad.net/dolfin/+question/225987
>
> Hi
>
> This may be a silly question but I just wanted to be absolutely
> certain.
>
> vertex_to_dofmap() gives the dof locations for vertex locations,
> i.e., I have vertex locations but I want equivalent dof locations.
> So, a quick example:
>
> std::vector<std::size_t> dof_vertices;
> dof_vertices = V.dofmap()->vertex_to_dof_map( mesh );
>
> unsigned int vertex_index = 0;
> for (VertexIterator vertex(mesh); !vertex.end(); ++vertex) {
> if ( x_coordinate <= 0.5 )
> (*u.vector() ).setitem( dof_vertices[vertex_index], 1 );
> else
> (*u.vector() ).setitem( dof_vertices[vertex_index], 2 );
>
> ++vertex_index;
> }
>
> This would set the appropriate dof locations for each vertex?!?

I think this is not correct. vertex_to_dof_map maps dof numbers
to vertex indices despite its name. Its name is a little bit confusing
but its quite well explained in docstrings in trunk.

>
> The inverse would be using dof_to_vertex_map() which means I have the
> dofs and now I want the vertex locations!?!

These two arrays are inversions when running in serial. In parallel it's
complicated by ghost dofs and local range. dof_to_vertex_map is array
mapping all process-local vertex indices to (local - i.e. indexed from
0) dof numbers so it includes (possibly negative) values of ghost dofs
numbers. Therefore you need to add local_range.first to these dof
numbers to get global dof numbers. Finally vertex_to_dof_map is
inversion of this mapping if you forget ghost dofs.

Jan

>
> Thx.
>
> Pietro
>
>

Jan Blechta (blechta) said : #2

On Fri, 05 Apr 2013 17:26:09 -0000
Jan Blechta <email address hidden> wrote:
> Question #225987 on DOLFIN changed:
> https://answers.launchpad.net/dolfin/+question/225987
>
> Status: Open => Answered
>
> Jan Blechta proposed the following answer:
> On Fri, 05 Apr 2013 16:46:02 -0000
> Pietro Maximoff <email address hidden> wrote:
> > New question #225987 on DOLFIN:
> > https://answers.launchpad.net/dolfin/+question/225987
> >
> > Hi
> >
> > This may be a silly question but I just wanted to be absolutely
> > certain.
> >
> > vertex_to_dofmap() gives the dof locations for vertex locations,
> > i.e., I have vertex locations but I want equivalent dof locations.
> > So, a quick example:
> >
> > std::vector<std::size_t> dof_vertices;
> > dof_vertices = V.dofmap()->vertex_to_dof_map( mesh );
> >
> > unsigned int vertex_index = 0;
> > for (VertexIterator vertex(mesh); !vertex.end(); ++vertex) {
> > if ( x_coordinate <= 0.5 )
> > (*u.vector() ).setitem( dof_vertices[vertex_index], 1 );
> > else
> > (*u.vector() ).setitem( dof_vertices[vertex_index], 2 );
> >
> > ++vertex_index;
> > }
> >
> > This would set the appropriate dof locations for each vertex?!?
>
> I think this is not correct. vertex_to_dof_map maps dof numbers
> to vertex indices despite its name. Its name is a little bit confusing
> but its quite well explained in docstrings in trunk.
>
> >
> > The inverse would be using dof_to_vertex_map() which means I have
> > the dofs and now I want the vertex locations!?!
>
> These two arrays are inversions when running in serial. In parallel
> it's complicated by ghost dofs and local range. dof_to_vertex_map is
> array mapping all process-local vertex indices to (local - i.e.
> indexed from 0) dof numbers so it includes (possibly negative) values
> of ghost dofs numbers. Therefore you need to add local_range.first to
> these dof numbers to get global dof numbers. Finally
> vertex_to_dof_map is inversion of this mapping if you forget ghost
> dofs.
>
> Jan
>
> >
> > Thx.
> >
> > Pietro
> >
> >
>

And for higher order spaces it's a little more twisted that instead of
vertex indeces these mappings takes/returns
vertex_index*dofs_per_vertex+i, i being 0,1,...,dofs_per_vertex-1.

Jan

Garth Wells (garth-wells) said : #3

On 6 April 2013 01:26, Jan Blechta <email address hidden> wrote:
> Question #225987 on DOLFIN changed:
> https://answers.launchpad.net/dolfin/+question/225987
>
> Status: Open => Answered
>
> Jan Blechta proposed the following answer:
> On Fri, 05 Apr 2013 16:46:02 -0000
> Pietro Maximoff <email address hidden> wrote:
>> New question #225987 on DOLFIN:
>> https://answers.launchpad.net/dolfin/+question/225987
>>
>> Hi
>>
>> This may be a silly question but I just wanted to be absolutely
>> certain.
>>
>> vertex_to_dofmap() gives the dof locations for vertex locations,
>> i.e., I have vertex locations but I want equivalent dof locations.
>> So, a quick example:
>>
>> std::vector<std::size_t> dof_vertices;
>> dof_vertices = V.dofmap()->vertex_to_dof_map( mesh );
>>
>> unsigned int vertex_index = 0;
>> for (VertexIterator vertex(mesh); !vertex.end(); ++vertex) {
>> if ( x_coordinate <= 0.5 )
>> (*u.vector() ).setitem( dof_vertices[vertex_index], 1 );
>> else
>> (*u.vector() ).setitem( dof_vertices[vertex_index], 2 );
>>
>> ++vertex_index;
>> }
>>
>> This would set the appropriate dof locations for each vertex?!?
>
> I think this is not correct. vertex_to_dof_map maps dof numbers
> to vertex indices despite its name. Its name is a little bit confusing
> but its quite well explained in docstrings in trunk.
>

If it map is from dofs to vertices, then the name is confusing and
misleading, and should be changed.
Sounds like it should be dof_to_vertex.

Garth

>>
>> The inverse would be using dof_to_vertex_map() which means I have the
>> dofs and now I want the vertex locations!?!
>
> These two arrays are inversions when running in serial. In parallel it's
> complicated by ghost dofs and local range. dof_to_vertex_map is array
> mapping all process-local vertex indices to (local - i.e. indexed from
> 0) dof numbers so it includes (possibly negative) values of ghost dofs
> numbers. Therefore you need to add local_range.first to these dof
> numbers to get global dof numbers. Finally vertex_to_dof_map is
> inversion of this mapping if you forget ghost dofs.
>
> Jan
>
>>
>> Thx.
>>
>> Pietro
>>
>>
>
> --
> You received this question notification because you are a member of
> DOLFIN Team, which is an answer contact for DOLFIN.

Jan Blechta (blechta) said : #4

On Fri, 05 Apr 2013 23:41:10 -0000
Garth Wells <email address hidden> wrote:
> Question #225987 on DOLFIN changed:
> https://answers.launchpad.net/dolfin/+question/225987
>
> Garth Wells proposed the following answer:
> On 6 April 2013 01:26, Jan Blechta
> <email address hidden> wrote:
> > Question #225987 on DOLFIN changed:
> > https://answers.launchpad.net/dolfin/+question/225987
> >
> > Status: Open => Answered
> >
> > Jan Blechta proposed the following answer:
> > On Fri, 05 Apr 2013 16:46:02 -0000
> > Pietro Maximoff <email address hidden> wrote:
> >> New question #225987 on DOLFIN:
> >> https://answers.launchpad.net/dolfin/+question/225987
> >>
> >> Hi
> >>
> >> This may be a silly question but I just wanted to be absolutely
> >> certain.
> >>
> >> vertex_to_dofmap() gives the dof locations for vertex locations,
> >> i.e., I have vertex locations but I want equivalent dof locations.
> >> So, a quick example:
> >>
> >> std::vector<std::size_t> dof_vertices;
> >> dof_vertices = V.dofmap()->vertex_to_dof_map( mesh );
> >>
> >> unsigned int vertex_index = 0;
> >> for (VertexIterator vertex(mesh); !vertex.end(); ++vertex) {
> >> if ( x_coordinate <= 0.5 )
> >> (*u.vector() ).setitem( dof_vertices[vertex_index], 1 );
> >> else
> >> (*u.vector() ).setitem( dof_vertices[vertex_index], 2 );
> >>
> >> ++vertex_index;
> >> }
> >>
> >> This would set the appropriate dof locations for each vertex?!?
> >
> > I think this is not correct. vertex_to_dof_map maps dof numbers
> > to vertex indices despite its name. Its name is a little bit
> > confusing but its quite well explained in docstrings in trunk.
> >
>
> If it map is from dofs to vertices, then the name is confusing and
> misleading, and should be changed.
> Sounds like it should be dof_to_vertex.

I think the logic behind the naming is motivated by the fact that if
you have some array indexed by vertex indices and you compose it with
vertex_to_dof_map then array[vertex_to_dof_map] is array indexed by dof
numbers.

So vertex_to_dof_map is not mapping from vertex indeces to dof
numbers but mapping transfering another mapping defined on vertex
indeces to mapping defined on dof numbers.

Jan

>
> Garth
>
> >>
> >> The inverse would be using dof_to_vertex_map() which means I have
> >> the dofs and now I want the vertex locations!?!
> >
> > These two arrays are inversions when running in serial. In parallel
> > it's complicated by ghost dofs and local range. dof_to_vertex_map
> > is array mapping all process-local vertex indices to (local - i.e.
> > indexed from 0) dof numbers so it includes (possibly negative)
> > values of ghost dofs numbers. Therefore you need to add
> > local_range.first to these dof numbers to get global dof numbers.
> > Finally vertex_to_dof_map is inversion of this mapping if you
> > forget ghost dofs.
> >
> > Jan
> >
> >>
> >> Thx.
> >>
> >> Pietro
> >>
> >>
> >
> > --
> > You received this question notification because you are a member of
> > DOLFIN Team, which is an answer contact for DOLFIN.
>

Pietro Maximoff (segment-x) said : #5

Is it possible to have a small example?

Thx.

Pietro

Johan Hake (johan-hake) said : #6

On 04/06/2013 08:35 AM, Pietro Maximoff wrote:
> Question #225987 on DOLFIN changed:
> https://answers.launchpad.net/dolfin/+question/225987
>
> Status: Answered => Open
>
> Pietro Maximoff is still having a problem:
> Is it possible to have a small example?
>
> Thx.
>
> Pietro
>

from dolfin import *
import numpy as np

mesh = UnitSquareMesh(10,10)
V = VectorFunctionSpace(mesh, "CG", 1)
u = Function(V)

# Vertex based data
vertex_vector_values = np.zeros(mesh.num_vertices()*2)
vertex_vector_values[::2] = mesh.coordinates().sum(1)
vertex_vector_values[1::2] = 2-mesh.coordinates().sum(1)
vertex_to_dof_map = V.dofmap().vertex_to_dof_map(mesh)

# vertex_to_dof_map maps vertex ordered data to dofmap ordered
# Note that this will work in parallel
u.vector().set_local(vertex_vector_values[vertex_to_dof_map])
plot(u, interactive=True)

Johan

Pietro Maximoff (segment-x) said : #7

Many thanks Johan.

So, is this the C++ serial equivalent:

std::vector<std::size_t>vertex_to_dof_map;
vertex_to_dof_map = V.dofmap()->vertex_to_dof_map( mesh );

for ( int i = 0; i < mesh.num_vertices(); ++i ) {
    ( *u.vector() ).setitem( i, some_value )
}

Pietro

Best Johan Hake (johan-hake) said : #8

On 04/07/2013 01:45 AM, Pietro Maximoff wrote:
> Question #225987 on DOLFIN changed:
> https://answers.launchpad.net/dolfin/+question/225987
>
> Status: Answered => Open
>
> Pietro Maximoff is still having a problem:
> Many thanks Johan.
>
> So, is this the C++ serial equivalent:
>
> std::vector<std::size_t>vertex_to_dof_map;
> vertex_to_dof_map = V.dofmap()->vertex_to_dof_map( mesh );
>
> for ( int i = 0; i < mesh.num_vertices(); ++i ) {
> ( *u.vector() ).setitem( i, some_value )
> }

rather something like:

std::vector<double> values(vertex_to_dof_map.size());
for (int i=0; i<vertex_to_dof_map.size(); ++i)
   values[i] = vertex_based_values[vertex_to_dof_map[i]];

u.vector()->setlocal(values);

Johan

Pietro Maximoff (segment-x) said : #9

Thanks Johan Hake, that solved my question.

Artur Palha (artur-palha) said : #10

Just to confirm.

This does not work for:

V = VectorFunctionSpace(mesh, "CG", 2)

Or does it work?

Thank you

-artur palha