• No se han encontrado resultados

Actividades de la Etapa de Preparación del Sitio y Construcción

V. DESCRIPCION DEL PROYECTO Y SUS ALTERNATIVAS

5.4 Actividades del Proyecto

5.4.1 Actividades de la Etapa de Preparación del Sitio y Construcción

Our simulation software is written in Python 2.7.6. For the matrix computation, we use the NumPy 1.12.1 and SciPy 0.17.1 packages, and for the graphical output, we use Matplotlib 1.5.1 or 2.0.2.

Python is increasingly popular for scientific computing, being open source, well- supported in the number of libraries, and being generally well-documented online. It is therefore filling the role typically taken by Matlab, with the advantage of also being used outside of academia. Its easy-to-read syntax makes it a good choice for scientific projects which may be developed and used by multiple people on different machines. Two major drawbacks to using Python for scientific computing are that there are often multiple ways of performing an operation, without it being clear which is the optimal choice; and that since Python is untyped, unoptimised code can be quite slow. For-loops, in particular, are much slower than in C or Fortran. Often these are avoidable by using library methods (for example, in matrix multiplication), but sometimes they are not. Part of the aim of this project is to replace old Fortran code, so we pre-compile basic functions which are called a large order of times (for example, the Oseen tensor 𝐽𝑖𝑗) using Cython. This operates as a Python extension which takes code mostly written in Python syntax (but with typing), and compiles it into C functions. These optimised functions are then called from Python and give fast, C-like performance.

All the Stokesian Dynamics code is written in this way. Resistance and mobility scalars are generated by the slightly adapted 2-sphere code of Wilson (2013), which is written in Fortran 95.

A novel feature of the software is that it admits particles of theoretically any mix of sizes. In practicality, the dispersity of the suspension is dictated by the requirement to generate resistance scalars for all size ratios prior to running the simulation, reducing it to ‘𝑛-dispersity’. In this thesis, we restrict our attention to bidisperse suspensions.

An independent novel feature is the ability to compute the motion of some particles through full 𝑭 -𝑻 -S simulations (the ‘spheres’), and some through reduced 𝑭 sim- ulations (the dumbbells). This couples well with the bidispersity as it allows us to speed up computation with particles—typically the smaller ones—whose angular behaviour we are not interested in.

2.6.1 Program to generate matrix formulation

Recall that the aim of this approach is to construct the grand resistance matrix eq. (2.13),

R = (M)−1+R2B,exactR2B,∞. (2.160) For this we need to input

• the positions of the particles, • the sizes of the particles.

Having done this, we construct the component matrices in the following ways:

Far-field mobility matrix, M

As shown in section 2.3, Faxén’s laws allow for an analytic derivation of the elements of the far-field mobility matrix, which have been explicitly displayed in table 2.1. Pre-calculated, explicit forms of the Oseen tensor (J) and its derivatives from ap- pendix A.2.3 are used in these calculations.

Two-body resistance matrix, R2B,exactR2B,∞

The combined two-body resistance matrix R2B =R2B,exactR2B,∞ is constructed from scalar resistance functions, section 2.4.2, which have been altered to include the effect of subtracting R2B,∞.

Following the description in section 2.4, we fill the upper-triangular half of the R2B matrix according to the expressions in eq. (2.69), using row and column operations to fill the dumbbell sections, and then use the symmetry of R2B,exact shown in section 2.4.5 to complete the matrix.

We need now to subtract off the R2B,∞ contribution to the scalars. For each value of 𝑠′ and 𝜆, we generate a two-body far-field mobility matrix, using the method described in section 2.3. We invert it and subtract it from the exact resistance matrix found using the above method,

(R2B)(𝛼 ̃𝛼) = (R2B,exact)(𝛼 ̃𝛼)− ((M)(𝛼 ̃𝛼))−1. (2.161) By choosing the same convenient input choices in table 2.2, we can extract the value of the R2B scalars. Choosing to store these scalars gives a significant time saving when computing the combined resistance matrix R2B.

2.6.2 Composition and timestepping

Finally, we add the inverted far-field mobility matrix to the two-body resistance matrix for each timestep, and solve the matrix equation

F = [(M)−1+R2B]U, (2.162)

for the velocity vector, U, in order to determine the positions and orientations of the particles at the next timestep.

Inverting matrices is a slow, unparallelisable procedure which can cause bottlenecks in the code. Rather than inverting the grand resistance matrix above to solve the equation, we call the matrix equation solve function from the Numpy library. This in turn calls the matrix equation solver from the LAPACK library, which uses LU decomposition for both a speed and accuracy increase.

Even avoiding inverting the grand resistance matrix, it still appears that we have to invert the dense far-field mobility matrix, M. However, this can be avoided by multiplying eq. (2.162) through by Mand rewriting:

MF = (I + MR2B)U. (2.163)

We instead solve this equation using the matrix equation solve function. It ap- pears that we have simply switched inverting Mwith computing MR2B, and same-sized matrix multiplication has the same computational complexity as matrix inversion. However, R2B is sparse, and computing MR2BU is performed in the Numpy solver as M∞(R2BU), i.e. two quick matrix-vector multiplications.

Whether to use this method has to be weighed up against simply generating M∞ explicitly every 𝑚 timesteps. We timestep using the fourth-order Runge–Kutta ‘RK4’ numerical integration scheme, so one explicit generation of (M)−1 can be used (given the particles do not move sufficiently) 4𝑚 times. The speed difference versus the above method we find to depend on the system, and so we leave both methods as options.

2.6.3 Representing the geometry

A nice feature of this simulation approach is that interesting geometries are quickly and easily constructed. Walls are formed by placing rows of nearly-touching spheres with a fixed zero velocity, allowing for the free formation of many boundaries. We can simulate pipe flow or shear flow, for example, by constructing parallel walls

u0

u1 h

Figure 2.11: We can create flow in a channel of width ℎ by setting up nearly-touching spheres as walls with fixed velocities 𝒖0 and 𝒖1.

a distance apart, and fixing constant parallel velocities upon them as boundary conditions. Figure 2.11 shows such a construction, where we have dumbbells alone in the bulk of the flow.