FEniCS version: 2019.1.0.r3
System: Docker on Windows
I am trying to adaptively mesh my domain based on custom-defined markers inside a loop. Here I am presenting a simplified version of my code. The code is working fine and is adaptively refining the domain and underlying LinearVariationalProblem.
from dolfin import *
parameters["refinement_algorithm"] = "plaza_with_parent_facets"
cpp_code = """
#include<pybind11/pybind11.h>
#include<dolfin/adaptivity/adapt.h>
#include<dolfin/mesh/Mesh.h>
#include<dolfin/mesh/MeshFunction.h>
#include<dolfin/fem/DirichletBC.h>
#include<dolfin/function/FunctionSpace.h>
#include<dolfin/fem/Form.h>
#include <dolfin/fem/LinearVariationalProblem.h>
#include <dolfin/fem/NonlinearVariationalProblem.h>
#include <dolfin/refinement/LocalMeshCoarsening.h>
namespace py = pybind11;
using namespace dolfin;
PYBIND11_MODULE(SIGNATURE, m) {
m.def("adapt", [](const dolfin::LinearVariationalProblem& problem,
std::shared_ptr<const dolfin::Mesh> adapted_mesh)
{return dolfin::adapt(problem, adapted_mesh);});
m.def("adapt", [](const dolfin::NonlinearVariationalProblem& problem,
std::shared_ptr<const dolfin::Mesh> adapted_mesh)
{return dolfin::adapt(problem, adapted_mesh);});
}
"""
mm = compile_cpp_code(cpp_code)
def adapt_problem(f,mesh):
return mm.adapt(f, mesh)
# Create mesh and define function space
mesh = UnitSquareMesh(2, 2)
V = FunctionSpace(mesh, "Lagrange", 1)
# Define boundary condition
u0 = Function(V)
bc = DirichletBC(V, u0, "x[0] < DOLFIN_EPS || x[0] > 1.0 - DOLFIN_EPS")
# Define variational problem
u = TrialFunction(V)
v = TestFunction(V)
f = Expression("10*exp(-(pow(x[0] - 0.5, 2) + pow(x[1] - 0.5, 2)) / 0.02)",
degree=1)
g = Expression("sin(5*x[0])", degree=1)
a = inner(grad(u), grad(v))*dx()
L = f*v*dx() + g*v*ds()
# Define function for the solution
u = Function(V)
problem = LinearVariationalProblem(a, L, u, bc)
solver = LinearVariationalSolver(problem)
for i in range(4000):
#mesh = refine(mesh)
problem = adapt_problem(problem,mesh)
solver = LinearVariationalSolver(problem)
solver.solve()
print("Step number: ", i)
The above code results in the following error after 2038 steps.
RuntimeError: *** Error: Duplication of MPI communicator failed (MPI_Comm_dup
The above is just a test case to reproduce the error. From the following two posts I have understood two points:
- MPICH during transient simulation: MPICH limits to 2048 communicators per process on systems.
- Crash when using project function: Some methods creates a new function space (which in turn uses 1 MPI communicator). Normally DOLFIN will free these communicators when the subfunctions are freed from memory. This is not happening in my case.
I can not use the in-built AdaptiveLinearVariationalSolver
as I need more control over adaptivity for my simulations. How can I use the adapt
method available in C++ to adapt the LinearVariationalProblem
without running into this error?