19.06.2015 Views

A FEniCS Tutorial - FEniCS Project

A FEniCS Tutorial - FEniCS Project

A FEniCS Tutorial - FEniCS Project

SHOW MORE
SHOW LESS

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!