This is a read only copy of the old FEniCS QA forum. Please visit the new QA forum to ask questions

adapt MeshFunctions to refined mesh [cpp]

0 votes

Hi,
after to refine the mesh i would like to adapt to the new mesh the MeshFunctions (types double, bool and std::size_t) defined on the old mesh without the work of redefininig these functions.

I tried to do this (without succes):

adapt(sizet_meshfunction, refined_mesh);
adapt(bool_meshfunction, refined_mesh);
adapt(double_meshfunction, refined_mesh);

any ideas about how to do this?

asked Sep 30, 2015 by hernan_mella FEniCS Expert (19,460 points)

Can you post a full non-working example? The following works for me:

from dolfin import *
mesh = UnitSquareMesh(5,5)
mf = CellFunction("size_t", mesh)
mesh2 = refine(mesh)
mf2 = adapt(mf, mesh2)

Which version of dolfin are you using? What error are you getting?

Hi, thanks for your reply... a full (but minimalist) non-working example is:

#include <dolfin.h>

using namespace dolfin;

// Inclussion
class Omega0 : public SubDomain
{
  bool inside(const Array<double>& x, bool on_boundary) const
  {
    if (x[1]<=-0.75 && x[1]>=-1.75 && std::abs(x[0]) <=1)
      return true;
    else 
      return false;
  }
};

// Mesh dimesions
double b = 0.3, L = 2.5, h = 2.5, Lpml = 1;
Point vertex_1(-(L  +   Lpml), 0);
Point vertex_2(L    +   Lpml, -(h   +   Lpml));

// Density of the mesh
int nx = 40, ny = 0.5*nx;

int main()
{
  // Mesh
  RectangleMesh mesh(vertex_1, vertex_2, nx, ny, "left/right");

  // Create mesh functions over the cells
  MeshFunction<std::size_t> subdomains(mesh, mesh.topology().dim());
  MeshFunction<bool> bool_subdomains(mesh, mesh.topology().dim());
  MeshFunction<double> density(mesh, mesh.topology().dim());

  // Mark all cells subdomains with 0, bool_subdomains with false and density with 1 
  subdomains = 0;
  bool_subdomains = false;
  density = 1.0;

  // Mark on inclusion subdomains with 1, bool_subdomains with true and density with 2 
  Omega0 Omega_0;
  Omega_0.mark(subdomains, 1);
  Omega_0.mark(bool_subdomains, true);
  Omega_0.mark(density, 2.0);

  refine(mesh, mesh, bool_subdomains, true);  // create a refined-mesh overwriting the old mesh

  // HERE IS THE PROBLEM
  adapt(subdomains, mesh);
  adapt(bool_subdomains, mesh);
  adapt(density, mesh); 
}

Actually i'm using dolfin 1.6.0 and the error that (that correspond to the "adapt subdomains meshfunction" line) i'm getting is:

error: no matching function for call to 
‘adapt(dolfin::MeshFunction<long unsigned int>&, dolfin::RectangleMesh&)’

(A similar error occurs with the other two lines).

You still didn't tell me what is wrong - error message or what?

This should work:

CellFunction<std::size_t> markers(mesh);
Mesh new_mesh;
refine(new_mesh, mesh, false);
adapt(markers, new_mesh);

Have a look at: demo/undocumented/meshfunction-refinement/cpp/main.cpp

You should also set the redistribute flag to be false in refine.

I think it could be because you are overwriting the original mesh. Better to create a new object for it.

I tried to do what you said but I still have problems. Doing exactly what you proposed the following error appears:

no matching function for call to ‘adapt(dolfin::MeshFunction<long unsigned int>&, dolfin::Mesh&)’

and running the demo meshfunction-refinement the size of meshfunctions before and after of the refinement is the same, due that the mesh before and after the refinement using adapt function is the same.

Modifying the demo in two different ways i still have problems. First i tried to do this (on the demo):

// Refine mesh
Mesh newmesh;
newmesh = adapt(mesh, cell_markers);  // Original line: adapt(mesh, cell_markers)

// Adapt cell function to refined mesh
adapt(right_cells, newmesh.child_shared_ptr());  // Original line: adapt(right_cells, mesh.child_shared_ptr());

// Adapt facet function to refined mesh
adapt(inflow_facets, newmesh.child_shared_ptr());  // Original line: adapt(inflow_facets, mesh.child_shared_ptr());

getting the following error when i try to adapt the meshfunctions:

*** Process received signal ***
Signal: Segmentation fault (11)
Signal code: Address not mapped (1)
Failing at address: 0x2b0
[ 0] /lib/x86_64-linux-gnu/libc.so.6(+0x36d40) [0x7fc038de8d40]
[ 1] /usr/lib/x86_64-linux-gnu/libdolfin.so.1.6(_ZNK6dolfin8MeshData6existsESsm+0) [0x7fc039eb83e0]
[ 2] /usr/lib/x86_64-linux-gnu/libdolfin.so.1.6(_ZN6dolfin5adaptERKNS_12MeshFunctionImEESt10shared_ptrIKNS_4MeshEE+0x4c6) [0x7fc039db47e6]
[ 3] ./demo_meshfunction-refinement(main+0x573) [0x4052d3]
[ 4] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf5) [0x7fc038dd3ec5]
[ 5] ./demo_meshfunction-refinement() [0x4056fe]
*** End of error message ***
Segmentation fault (core dumped)

Then i tried to do this:

// Refine mesh
Mesh newmesh;
refine(newmesh, mesh, cell_markers, false);

// Adapt cell function to refined mesh
adapt(right_cells, newmesh.child_shared_ptr());

// Adapt facet function to refined mesh
adapt(inflow_facets, newmesh.child_shared_ptr());

getting the same error above.

Thank you in advance!

Recently i've noticed about how works the adapt function... many thanks for your time and sorry for my last reply.

1 Answer

0 votes

Hi hernan,

I am having the same problem using:

# Refine mesh and adapt mesh function
cf = CellFunction('bool', mesh, True)
mesh_1 = refine(mesh, cf, redistribute=False) 
adapt(subdomains, mesh_1)

Where subdomains is a MeshFunction on the mesh before refinement. My problem is that if I have a look at the subdomains plot after refinement, nothing is changed, and it seems like the mesh is not refined at all, or at least the adapt function is not working at all.
Do you have some suggestions please?
Thanks!

answered Feb 5, 2016 by Sebastiano FEniCS Novice (220 points)

Hi, try this:

from dolfin import *

mesh = UnitSquare(30, 30)

class Omega(SubDomain):
  def inside(self, x, on_boundary):
    return x[0]**2 + x[1]**2 <= 0.5**2

Omega = Omega()

cf_bool = CellFunction('bool', mesh)
cf_bool.set_all(False)
cf_size_t = CellFunction('size_t', mesh)
cf_size_t.set_all(0) 

Omega.mark(cf_bool, True)
Omega.mark(cf_size_t, 1)

#plot(mesh, interactive=True)
#plot(cf_size_t, interactive=True)

print "  > Size of MeshFunction before refinement: ", cf_size_t.size()

adapt(mesh, cf_bool)
adapt(cf_size_t, mesh.child())

mesh = mesh.child()
cf_size_t = cf_size_t.child()

#plot(mesh, interactive=True)
#plot(cf_size_t, interactive=True)

print "  > Size of MeshFunction after refinement: ", cf_size_t.size()

As suggestion, if you want to adapt an "adaptable" object consider (see this issue: faulty-memory-management-in-adapt):

  1. Don't ever use returned object of any adapt functions!
  2. Access the result by child() method.

Regards!

...