• Ingen resultater fundet

Implementation of the spectral model

6.2 A nonlinear 2D wave tank model

6.2.2 Implementation of the spectral model

The implementation of the spectral model will consist of three parts, a solver for our Laplace problem, the integrator for the time-dependent problem, and a calculation of the pressure.

6.2 A nonlinear 2D wave tank model 85

6.2.2.1 The solver for the Laplace problem

The implementation to our Laplace problem is largely based on (6.28) and the boundary-modifications to the linear operator and right hand side function. We will construct a grid of Legendre points for both dimensions (with Nx andNz points) and generate the differential operators from algorithm 2. We will handle the two dimensions by the methods outlined in section 4.3.3, by ordering our mesh into vectors, and creating differential operators based on this transforma-tion.

We calculate the time-dependent coefficients (6.26) from the input, and form these into diagonal matrices, allowing us to assign the correct value to each point, while being able to use the matrix product when constructingL.

We employ the boundary conditions as described in section 6.2.1.1 by simply changing the values of L for the rows which correspond to boundary points.

For the Neumann boundaries, we substitute the linear operator row by the corresponding row to the differential operator as specified in (6.29). For the Dirichlet boundary, we simply set the whole row to zero for all the points but place in the row corresponding to the point itself, where we will place a 1. We then modify the right-hand-side function, which previously contained all zeroes, to contain the desired value for each point.

The boundaries are calculated in the code

LBCsigma = np.dot(DSIGMADZ,DSIGMA) Lopperator = Lopperator.todense() LBCsigma = LBCsigma.todense() DX = DX.todense()

for i in range(Ny):

Lopperator[index[i,0],:] = -DX[index[i,0],:]

Lopperator[index[i,-1],:] = -DX[index[i,-1],:]

for i in range(Nx):

Lopperator[index[0,i],:] = -LBCsigma[ index[0,i] , : ] Lopperator[index[-1,i],:] = 0

Lopperator[index[-1,i],index[-1,i]] = 1 f[index[-1,:]] = u0

The todense() operation is to allow us to access the elements by using our indexarray, whichSciPys sparse functionality does not allow.

With the linear operator constructed, we can solve forΦ, which is allows us to calculate the time-derivatives (6.26) and output these.

The full Laplacian calculator can be found in appendix G.1

6.2.2.2 The time-integrator

The time integrator is composed of two steps, calculating the initial condition and the time-stepping part. The initial condition is easy to calculate, as we only need to define a surface elevation η and the surface velocity potential φ.˜ For the time-integration part, we will be using the Runge-Kutta 4-step method outlined in (6.14).

For testing this, we introduce the a standing wave in our system, as [YA96, pg.

145], which is defined as

ηS(x) = 1 2

8

X

J=1

J14aJcos (J πx)

There the coefficientsaJ are defined as

J aJ

1 0.8867·10−1 2 0.5243·10−2 3 0.4978·10−3 4 0.6542·10−4 5 0.1007·10−4 6 0.1653·10−5 7 0.2753·10−6 8 0.4522·10−1

This allows us to test our model, and we use this as initial conditions, with the zero vector being the scalar velocity potentialφ.˜

6.2 A nonlinear 2D wave tank model 87

−1.0 −0.5 0.0 0.5 1.0

x

−0.04

−0.02 0.00 0.02 0.04

η

Initial condition

Figure 6.18: The initial value of the standing wave for the wave model.

Figure 6.18 shows us the initial condition for our standing wave, which we use to test our model. [YA96, pg. 145] tells us that the period of the standing wave isT = 1.13409, which allows us to check exactly one period of movement.

−1.0 −0.5 0.0 0.5 1.0

x

−0.04

−0.02 0.00 0.02 0.04

η

Period of the standing wave with 20 steps Initial End

Figure 6.19: The period of movement for the standing wave.

Figure 6.19 shows us that the wave is indeed a standing wave, and the period is as expected, confirming our model.

6.2.2.3 Calculating the force on the right boundary

The calculation of the right boundary is done according to the procedure ex-plained in section 6.2.1.2. We can calculate all parts of the pressure easily from the values we already posses, as we can findU =DXΦandW =∂zσDσΦ. Since we will only be concerning ourselves with the right boundary, the calculation of papart from the integral become simple vector operations. For the calculation of the integral, we will need to transform the interval between the surface and the point to a new Legendre-Gauss-Lobatto grid, where we can approximate the integral using this quadrature. This is done for each point, where the values of W are transformed. Since we will be needing the time-derivative of W, we will need to transform the previous value ofW as well, approximating the time derivative by a simple difference quotient dependent on our time-step size.

This calculation is done by the following code-snippet – where the analytic expressions of the pressure are already stored int

for i in range(Ny):

Z,WZ = LegPol.GaussLobattoQuadrature(Ny-1) V = LegPol.GradVandermonde1D(Z[Ny-1-i:],i,0) V2 = LegPol.GradVandermonde1D(Z,i,0)

VInv = np.linalg.inv(V) TRANS = np.dot(V2,VInv)

W2Z = np.dot(TRANS,W2[Ny-1-i:]) WLASTZ = np.dot(TRANS,WLAST[Ny-1-i:]) WDT = (W2Z-WLASTZ)/tstep

integral = 0

for j in range(Ny):

integral = integral + WZ[Ny-1-j]/2*WDT[Ny-1-j]

p[Ny-1-i] = p[Ny-1-i] + (zeta[-1]-ZREAL[Ny-1-i])/2*integral p = p*dens

Force = 0

for j in range(Ny):

Force = Force + p[j]*WZ[j]

Force = Force*2/(d)

The scaling factors are calculated according to the change in variable from real

6.2 A nonlinear 2D wave tank model 89

basis to Legendre-Gauss-Lobatto basis, as calculated here

zL= 2z+h

η+h−1 dzL dz = 2

η+h = 2 d

z∈[−h, η]

zL∈[−1,1]

˜

zL= 2z˜−z0

η−z0

−1 d˜zL

d˜z = 2 η−z0

˜

z∈[z0, η]

˜

zL∈[−1,1]

In order to test this, we will calculate the force from the standing wave, as well as the force from the completely steady water.

0.0 0.2 0.4 0.6 0.8 1.0 1.2

t 19.45

19.50 19.55 19.60 19.65 19.70 19.75

F

Force on the right boundary

0.0 0.2 0.4 0.6 0.8 1.0 1.2

t 18.5

19.0 19.5 20.0 20.5 21.0

F

Force on the right boundary

Figure 6.20: The force on the right boundary for the standing wave to the left, and the steady water to the right

Figure 6.20 shows us that the force of the steady water is steady, as expected, and that when there is movement in the water, the force will vary around this steady force. We can also compare the static force of the steady water, with the definition of the static force from [EK06, Eq. 2.86]

Fstatic=ρ(η+h)gη−1

2ρg η2−h2

Since the water is steady,η= 0andh= 2, which leads us to the following Fstatic=1

2ρgh2= 2ρg

Since ρ = 0.998 and g = 9.82, we get that Fstatic = 19.6, which excactly the same as we got for our steady water solution shown in figure 6.20.