A FEniCS Tutorial - FEniCS Project
A FEniCS Tutorial - FEniCS Project
A FEniCS Tutorial - FEniCS Project
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
subdomain1 = Omega1()<br />
subdomain1.mark(subdomains, 1)<br />
Callingsubdomains.array()returnsanumpyarrayofthesubdomainvalues.<br />
That is, subdomain.array()[i] is the subdomain value of cell number i. This<br />
array is used to look up the subdomain or material number of a specific element.<br />
We need a function k that is constant in each subdomain Ω 0 and Ω 1 . Since<br />
we want k to be a finite element function, it is natural to choose a space of<br />
functions that are constant over each element. The family of discontinuous<br />
Galerkin methods, in <strong>FEniCS</strong> denoted by ’DG’, is suitable for this purpose.<br />
Since we want functions that are piecewise constant, the value of the degree<br />
parameter is zero:<br />
V0 = FunctionSpace(mesh, ’DG’, 0)<br />
k = Function(V0)<br />
To fill k with the right values in each element, we loop over all cells (i.e., indices<br />
in subdomain.array()), extract the corresponding subdomain number of a cell,<br />
and assign the corresponding k value to the k.vector() array:<br />
k_values = [1.5, 50] # values of k in the two subdomains<br />
for cell_no in range(len(subdomains.array())):<br />
subdomain_no = subdomains.array()[cell_no]<br />
k.vector()[cell_no] = k_values[subdomain_no]<br />
Long loops in Python are known to be slow, so for large meshes it is preferable<br />
to avoid such loops and instead use vectorized code. Normally this implies<br />
that the loop must be replaced by calls to functions from the numpy library<br />
that operate on complete arrays (in efficient C code). The functionality<br />
we want in the present case is to compute an array of the same size as<br />
subdomain.array(), but where the value i of an entry in subdomain.array()<br />
is replaced by k_values[i]. Such an operation is carried out by the numpy<br />
function choose:<br />
help = numpy.asarray(subdomains.array(), dtype=numpy.int32)<br />
k.vector()[:] = numpy.choose(help, k_values)<br />
The help array is required since choose cannot work with subdomain.array()<br />
because this array has elements of type uint32. We must therefore transform<br />
this array to an array help with standard int32 integers.<br />
Having the k function ready for finite element computations, we can proceed<br />
in the normal manner with defining essential boundary conditions, as in<br />
Section 1.14, and the a(u,v) and L(v) forms, as in Section 1.10. All the details<br />
can be found in the file mat2_p2D.py.<br />
5.3 Multiple Neumann, Robin, and Dirichlet Condition<br />
Let us go back to the model problem from Section 1.14 where we had both<br />
Dirichlet and Neumann conditions. The term v*g*ds in the expression for L<br />
77