Edit values of a dolfin::Function at certain co-ordinates (C++)

Hi,
My problem requires me to perform a transformation on the solved values of a dolfin::Function at certain coordinates in the domain.

Some examples are available for Python, namely the answer by MiroK

I would like to perform similarly in C++.

I have extracted the coordinates from the mesh by

auto co_ordinates = mesh->coordinates();

and the Generic vector from Function as

auto E_vec = E->vector();

There are two methods namely get_local() and set_local() respectively which could facilitate me in modifying the values. But I am not really sure about the input parameters to that function.

Any alternate methods to achieve this is also highly appreciated.

Hi,

an example that I use to set negative values in a vector of a function is shown below, which illustrates the usage of get_local() and set_local():

uvals = u.vector().get_local()     # temporary copy of function value arrays
uvals[uvals < 0.] = 0.               # numpy syntax for overwriting negative values
u.vector().set_local(uvals)        # overwrite function values with corrected array

This in the end returns a Dolfin function again with the corrected values. I think the notation of get/set_local will be the same in C++.
Hope this helps

Thank you. I thought the same.

But, the dolfin::Function.vector() returns a reference to dolfin::GenericVector.

The get_local() method of the GenericVector has a declaration of

void get_local(double* block, const dolfin::la_index* num_rows, const dolfin::la_index* const* rows) const

I am not sure what these input parameters exactly mean.

Did you find any solution to that problem? I’m currently working on that.

I also need to do exactly this and it is solved by using the vertex-to-dof mapping provided by dolfin.
First, get/set_local() is used to extract and then write-back the values using a C++ vector. They are only used for reading and writing the solution vector wholesale and not for addressing any individual degree of freedom (dof). To convert the position in the 1D vector as returned by get_local() to a physical position in your grid, you need to use the following in some way like (given a function space V and mesh):

    auto dof_from_vertex 	= dolfin::vertex_to_dof_map(*V);
    auto mesh_coords 		= mesh->coordinates();

Depending on the dimension of your problem, mesh->coordinates() will return the x,y,… position of the vertex associated with the point (x,y,…). Thus, if your mesh is 2D, the coordinates are in pairs x,y and the first two entries are for vertex entry ‘0’ (the first entry at index=0), whose dof entry is then looked up at dof_from_vertex(0); Note the size of mesh->coordinates() is d*#vertices, where d is the dimension of your mesh (1d, 2d,…).

Thus, you need to build a lookup table to convert your simulation (x,y) coordinates to dof entry, or otherwise be able to get the vertex # you want to modify. The sequence is then

std::vector<double> solution_vector;
u->vector()->get_local(solution_vector);
size_t dof = <use lookup table you made>;
solution_vector(dof) = modifiedValue;
<repeat for all dofs desired>
u->vector()->set_local(solution_vector);

u is the dolfin::Function that is the problem solution, and you might actually want to write it back to a “u0” or initial condition for the next time step (depending on your problem).

–James W.

1 Like