I hope all is well. I am writing with regard to generating an expression to create an anisotropic Poisson equation in Fenics, based on the tutorial.
I firstly, run the data.py file and after that the C_matrix.py file. However, when I run the latter, I face the following errors:
Traceback (most recent call last):
File "C_matrix.py", line 67, in <module>
c = CompiledExpression(compile_cpp_code(conductivity_code).Conductivity(),
File "/usr/local/lib/python3.6/dist-packages/dolfin/jit/pybind11jit.py", line 96, in compile_cpp_code
generate=jit_generate)
File "/usr/local/lib/python3.6/dist-packages/dolfin/jit/jit.py", line 47, in mpi_jit
return local_jit(*args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/dolfin/jit/jit.py", line 103, in dijitso_jit
return dijitso.jit(*args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/dijitso/jit.py", line 212, in jit
lib = load_library(signature, cache_params)
File "/usr/local/lib/python3.6/dist-packages/dijitso/cache.py", line 363, in load_library
lib = __import__(signature)
ImportError: generic_type: type "Conductivity" referenced unknown base type "dolfin::Expression"
I was wondering if you can help me solve these errors.
Also, is it possible to write this code in Python language? Do you have any template of how to do this?
Looking forward to hearing from you,
All the best,
Sajjad
data. py:
from dolfin import *
# Create mesh
mesh = UnitSquareMesh(32, 32)
# Create mesh functions for c00, c01, c11
c00 = MeshFunction("double", mesh, 2)
c01 = MeshFunction("double", mesh, 2)
c11 = MeshFunction("double", mesh, 2)
# Iterate over mesh and set values
for cell in cells(mesh):
if cell.midpoint().x() < 0.5:
c00[cell] = 1.0
c01[cell] = 0.3
c11[cell] = 2.0
else:
c00[cell] = 3.0
c01[cell] = 0.5
c11[cell] = 4.0
# Store to file
mesh_file = File("mesh.xml.gz")
c00_file = File("c00.xml.gz")
c01_file = File("c01.xml.gz")
c11_file = File("c11.xml.gz")
mesh_file << mesh
c00_file << c00
c01_file << c01
c11_file << c11
# Plot mesh functions
plot(c00, title="C00")
plot(c01, title="C01")
plot(c11, title="C11")
C_matrix.py:
from dolfin import *
# Read mesh from file and create function space
mesh = Mesh("mesh.xml.gz")
V = FunctionSpace(mesh, "Lagrange", 1)
# Define Dirichlet boundary (x = 0 or x = 1)
def boundary(x):
return x[0] < DOLFIN_EPS or x[0] > 1.0 - DOLFIN_EPS
# Define boundary condition
u0 = Constant(0.0)
bc = DirichletBC(V, u0, boundary)
# Define conductivity expression and matrix
c00 = MeshFunction("double", mesh, "c00.xml.gz")
c01 = MeshFunction("double", mesh, "c01.xml.gz")
c11 = MeshFunction("double", mesh, "c11.xml.gz")
# Code for C++ evaluation of conductivity
conductivity_code = """
#include <pybind11/pybind11.h>
#include <pybind11/eigen.h>
namespace py = pybind11;
#include <dolfin/function/Expression.h>
#include <dolfin/mesh/MeshFunction.h>
class Conductivity : public dolfin::Expression
{
public:
// Create expression with 3 components
Conductivity() : dolfin::Expression(3) {}
// Function for evaluating expression on each cell
void eval(Eigen::Ref<Eigen::VectorXd> values, Eigen::Ref<const Eigen::VectorXd> x, const ufc::cell& cell) const override
{
const uint cell_index = cell.index;
values[0] = (*c00)[cell_index];
values[1] = (*c01)[cell_index];
values[2] = (*c11)[cell_index];
}
// The data stored in mesh functions
std::shared_ptr<dolfin::MeshFunction<double>> c00;
std::shared_ptr<dolfin::MeshFunction<double>> c01;
std::shared_ptr<dolfin::MeshFunction<double>> c11;
};
PYBIND11_MODULE(SIGNATURE, m)
{
py::class_<dolfin::Expression>(m, "dolfin::Expression");
py::class_<Conductivity, std::shared_ptr<Conductivity>, dolfin::Expression>(m, "Conductivity")
.def(py::init<>())
.def_readwrite("c00", &Conductivity::c00)
.def_readwrite("c01", &Conductivity::c01)
.def_readwrite("c11", &Conductivity::c11);
}
"""
c = CompiledExpression(compile_cpp_code(conductivity_code).Conductivity(),
c00=c00, c01=c01, c11=c11, degree=0)
#c=Expression("const uint cell_index = cell.index;values[0] = (*c00)[cell_index];values[1] = (*c01)[cell_index];values[2] = (*c11)[cell_index];");
C = as_matrix(((c[0], c[1]), (c[1], c[2])))
# 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)")
a = inner(C*grad(u), grad(v))*dx
L = f*v*dx
# Compute solution
u = Function(V)
solve(a == L, u, bc)
# Save solution in VTK format
file = File("poisson.pvd")
file << u
# Plot solution
plot(u, interactive=True)