---
abstract: '[In this paper we study decaying turbulence in fixed and rotating boxes in two dimensions using the particle method SPH. The boundaries are specified by boundary force particles, and the turbulence is initiated by a set of gaussian vortices. In the case of fixed boxes we recover the results of Clercx and his colleagues obtained using both a high accuracy spectral method and experiments. Our results for fixed boxes are also in close agreement with those of Monaghan [@Monaghan2011] and Robinson and Monaghan [@RobinsonMonaghan2011] obtained using SPH. A feature of decaying turbulence in no-slip, square, fixed boundaries is that the angular momentum of the fluid varies with time because of the reaction on the fluid of the viscous stresses on the boundary. We find that when the box is allowed to rotate freely, so that the total angular momentum of box and fluid is constant, the change in the angular momentum of the fluid is a factor $\sim 500$ smaller than is the case for the fixed box, and the final vorticity distribution is different. We also simulate the behaviour of the turbulence when the box is forced to rotate with small and large Rossby number, and the turbulence is initiated by gaussian vortices as before. If the rotation of the box is maintained after the turbulence is initiated we find that in the rotating frame the decay of kinetic energy, enstrophy and the vortex structure is insensitive to the angular velocity of the box. On the other hand, If the box is allowed to rotate freely after the turbulence is initiated, the evolved vortex structure is completely different. ]{}'
author:
- 'A. Valizadeh'
- 'J.J. Monaghan'
bibliography:
- 'references.bib'
title: 'SPH simulations of turbulence in fixed and rotating boxes in two dimensions with no-slip boundaries\'
---

\[sec:lntro\]Introduction\
==========================

Smoothed particle hydrodynamics is now widely used in computational fluid dynamics especially in problems involving breaking waves, and free surfaces disrupted by the impact of rigid bodies. In many of these systems the flows are initially laminar but develop turbulence as they evolve. A common example is the simulation of a laboratory dam break which becomes turbulent after the head of the flow hits an end wall where it forms a return wave that plunges into the incoming fluid [@Colagrossietal2003]. In order to have confidence in the predicted evolution of the flow it is necessary to determine how accurately SPH can simulate turbulence.

Early studies of turbulence using SPH made use of known sub-grid models applied to two dimensional flows. For example Shao and Gotah [@ShaoGotah2004] and Shao et al. [@Shaoetal2006] used a 2D turbulent viscous stress based on the Smagorinsky model. They applied their model to the turbulence generated by a succession of cnoidal waves breaking on a linear ramp and used extensive phase averaging and other approximations (for example multiplying by a factor 4/3 to bring their results into better agreement with the experiments that are in 3D). They obtained results in reasonable agreement with experiment although SPH simulation without the turbulence model gave very similar results. Dalrymple and Rogers [@DalrympleRogers2006] also used a Smagorinsky model for 2D turbulence. Violeau and Issa [@VioleauIssa2007] studied 2D turbulence and compared the $k-\epsilon$, the EARSM (explicit algebraic Reynolds stress model), and an SPH version of Large Eddy Simulation. The comparison was made for a dam break, but dam breaks have the disadvantage that while they are initially nearly 2D, they become 3D when the fluid strikes the wall of the experimental tank. In particular, the front of the fluid formed by the returning, plunging wave is no longer 2D. Apart from this problem there was not enough detailed information to determine if a particular method was superior. For example, the experiments did not provide them with the decay of the kinetic energy, the decay of the enstrophy, the vortex structure or the velocity correlation functions.

Over the last few years experiments and detailed spectral method simulations have been applied to study 2D turbulence in fluids with no-slip boundaries. These include the discovery of spontaneous spin-up [@Clercxetal1998], experiments on 2D turbulence in a stratified fluid [@Clercxetal1999], and the effects of solid boundaries [@Heijstetal2006]. These results provide a convenient framework within which to study SPH turbulence and this has been exploited by [@RobinsonMonaghan2011], and [@Monaghan2011] to test SPH without turbulence models. In addition Monaghan [@Monaghan2011] discusses and applies an SPH turbulence model for these problems.

A key feature of turbulence in a square no-slip boundary is that the angular momentum is not constant, and may change abruptly from the initial state then decay ([@Clercxetal1999; @Clercxetal1998; @Heijstetal2006; @Maassen2002]). The SPH simulations of [@RobinsonMonaghan2011] predict the same qualitative results though the details depend on the initial state. The SPH and spectral methods give results for the decay of the kinetic energy, and the enstrophy which are in satisfactory agreement. There are differences between the two SPH codes since that of Monaghan and Robinson models the boundary with layers of fixed fluid particles, and uses a cubic spline kernel, while that of Monaghan uses boundary force particles, and one of the Wendland kernels. Robinson (private communication) found that the results for the decay of the kinetic energy converged more rapidly when the cubic spline kernel was replaced by the Wendland kernel. However, as we shall show, most of the features of the turbulence in a fixed box, for example the kinetic energy decay, the enstrophy decay, and the structure of the evolved vorticity field, are very similar.

In the present paper the study of SPH simulation of turbulence will be extended using the SPH code of Monaghan (2011) but without the turbulence. We first confirm that the SPH simulation for the case of decaying turbulence in a no-slip square box converges and the spin-up is consistent with that found using the spectral theory. Second we study decaying turbulence when the box containing the fluid is allowed rotate under the surface stresses produced by the fluid. In this case the total angular momentum of the system of box and fluid is conserved. Third we simulate turbulence when the fluid and box are in rigid rotation when the turbulence is initiated. The evolution of the turbulence was then studied both when the box was forced to rotate at its initial angular velocity, and when it was allowed to be driven by the fluid stress. This problem is related to turbulence in the earth’s atmosphere, but a more complete discussion along the lines of the $\beta$-plane study of [@Krameretal2006], will not be attempted.

The equations of motion in two dimensions
=========================================

We consider an incompressible fluid is moving in two dimensions within a square boundary with no-slip boundary conditions. It is convenient, especially when we give the boundary a mass and allow it to rotate, to refer to the boundary as a box. The acceleration equation for the fluid is $$\frac{d{\bf v}}{dt} = \frac{\partial {\bf v}}{\partial t} + ({\bf v} \cdot \nabla){\bf v} = -\frac{\nabla P}{\rho} + \frac{\mu}{\rho} \nabla^2 {\bf v}.
\label{contNavStokes}$$ From this equation it is straightforward to show that the rate of change of the kinetic energy $E_K$ of the fluid is given by $$\frac{d }{dt} \int_{\mathcal A}  \frac12 \rho {\bf v}^2 dA = - \mu \int_{\mathcal A} \omega^2 dA,
\label{ekdt}$$ where $\omega {\hat {\bf z}} $ is the vorticity, and ${\hat {\bf z}} $ is a unit vector perpendicular to the plane of the fluid. The integration over a volume is equivalent in the present case to an integration over the two dimensions of the fluid, and is denoted by ${\mathcal A}$. Because of the boundary condition, we have used the fact that ${\bf v}$ is zero on the boundary. The rate of change of the vorticity is given by $$\frac{d\omega}{dt} = - \nu  \nabla^2 \omega.
\label{vort}$$ The total enstrophy varies with time according to $$\frac{d }{dt} \int _{\mathcal A}   \frac12 \omega^2 dA = - \nu \int_{\mathcal A} ( \nabla \omega)^2 dA + \nu  \int_{\mathcal B}  \omega (\nabla \omega \cdot {\bf n} ) ds,
\label{enstr}$$ where $\nu$ is the kinematic viscosity, ${\bf n}$ is an outward unit vector, and the second integration is around the boundary. These equations, together with one further equation giving the time variation of the gradients of the vorticity, were used by [@Batchelor1969] to develop his celebrated argument for the existence of a turbulent energy spectrum associated with a vorticity cascade to shorter length scales.

The rate of change of total angular momentum $L$ of the two dimensional fluid is given by $$\frac{d }{dt} \int_{\mathcal A}  \rho\left ( ( {\bf r} \times {\bf v}) \cdot {\hat {\bf z}}\right ) dA =  \int_{\mathcal B} P {\bf r} \cdot {\bf ds} + \mu \int_{\mathcal {A} } {\bf r} \times \nabla^2 {\bf v} dA
\label{angmom}$$ The second integration can be written in terms of a surface stress, but it is convenient to work with the form given noting that for an incompressible fluid $$\nabla^2 {\bf v} = -\nabla \times \omega {\bf \hat z},$$ and for a two dimensional fluid $${\bf r} \times (\nabla \times {\omega \bf \hat z }) = \nabla({\bf r} \cdot \omega \hat z)  - {\bf r} \cdot \nabla \omega.$$

Making use of these various relations we find $$\frac{dL}{dt} = \int_{\mathcal{B}} P {\bf r} \cdot {\bf ds} + \int_{\mathcal{B}} \omega {\bf r} \cdot {\bf n} ds - 2 \int_{\mathcal{A} }\omega dA.$$ The last term can be written as the circulation around the boundary and this vanishes because of the no-slip condition.

In this paper we also consider turbulence in a two dimensional fluid contained within a no-slip, square boundary rigidly rotating with angular velocity $\Omega {\bf \hat z}$. In this case it is useful to consider the equations of motion in a frame rotating with angular velocity $\Omega$. For this purpose, we let ${\bf v}$ denote the velocity in this rotating frame, and $\omega {\bf \hat z}$ its vorticity. The acceleration equation is then $$\frac{d{\bf v}}{dt}  = - 2\Omega {\bf \hat z}\times {\bf v} +  \Omega^2 {\bf r}  -\frac{\nabla P}{\rho} + \frac{\mu}{\rho} \nabla^2 {\bf v}.
\label{contNavStokesRot}$$ where $d/dt$ denotes the derivative following the motion in the rotating frame. By taking the curl of this equation we get the same equations for the rate of change of vorticity as for the non rotating box. The equations for the rate of change of the total energy and total enstrophy, calculated in the rotating frame, are also the same as for the non rotating box. We believe it is therefore reasonable to expect that Batchelor’s argument would apply when the boundary rotates rigidly throughout the simulation. We find that this conjecture is correct.

We also study the case where the boundary is given a mass and a moment of inertia (we then call it a box) and allowed to rotate freely under the stresses from the fluid from the moment the turbulence is initiated. In this case the total angular momentum of the fluid and the box is constant. In addition, the stress felt by the fluid is less because the box moves in response to the stress on it from the fluid. The effect is similar to a person attempting to walk on a platform that is free to move. One consequence of this is that the change in the angular momentum of the fluid is a factor 1/500 less than when the box is fixed. Our simulations also show that the form of the vortices that evolve is very different from that in the case of a fixed box, or a box which rotates rigidly throughout the simulation. There is no simple expression for the rate of change of the fluid energy and vorticity in this case because the dynamics of the fluid must include the effects of the motion of the box.

SPH model {#Sec:SPHmodel}
=========

We consider a weakly compressible fluid with pressure $P$ a function of density $\rho$. Surface tension is neglected. The reader is assumed to be familiar with standard SPH as described in the reviews by [@Monaghan1992; @Monaghan2005]. In the following, the labels $a$ and $j$ are used for SPH fluid and boundary particles respectively, and $\eta$ is used when a summation is over both fluid and boundary particles. The SPH form of continuity equation is

$$\frac{d\rho_a}{dt} = \rho_a \sum_{\eta} \frac{m_\eta}{\rho_\eta}\left({\bf v}_a - {\bf v}_\eta \right) \cdot\nabla_aW_{a\eta} ,
\label{continuity}$$

where the mass, position, velocity, density and pressure of particle $a$ are $m_a$, $r_a$, ${\bf v}_a$, $\rho_a$, and $P_a$, respectively. The summation is over all particles. The function $W_{a\eta }= W(| {\bf r}_{a\eta}|, h)$ is the SPH kernel, $| {\bf r}_{a\eta} |$ is the distance between particle $a$ and particle $\eta$, and $h=(h_a+h_\eta)/2$ is the average smoothing length. In the calculations to be described the kernel is the fourth-order Wendland function [@Wendland1995] for two dimensions. This function, when normalized so that $2 \pi\int W(r,h) rdr = 1$, is given by $$W(z,\ell) = \frac{7}{ 64 \pi h^2} (2-z/h)^4 (1+2z/h),$$ if $z\le 2h$, and zero otherwise. Simulations of a wide variety of problems show that the choice $h_\eta=1.5\delta$, where $\delta$ is the initial particle spacing, gives good results. The interaction between any two fluid particles is zero beyond $3 \delta$. The gradient taken with respect to the coordinates of particle $a$ is denoted by $\nabla_a$. The pressure of fluid particle $a$ is given by $$P_a= \frac{\rho_0 c_s^2}{7}\left(\left(\frac{\rho_a}{\rho_0}\right)^7 - 1\right),
\label{pressure}$$ where $\rho_0$ is the reference density of the fluid. The speed of sound $c_s$ is 10 times the maximum speed of fluid $V_{max}$ which we estimate from the initial velocity field. The boundary particles have zero pressure.

The acceleration equation for the SPH particle $a$ is $$\frac{d{\bf v}_a }{ dt} =-\sum _{\eta}m_\eta \left(\frac{P_{a}}{\rho_a^2}+\frac{P_{\eta }}{\rho_{\eta}^2} - \Pi _{a\eta} \right )\nabla_{a}W_{a\eta}+\sum_{j} m_{j}{\bf f}_{aj}.
\label{momentum1}$$ The first summation in (\[momentum1\]) is over all particles and the second is over the boundary particles. The viscosity is determined by $\Pi _{a\eta}$ for which we use the form $$\Pi _{a\eta}=-\alpha \frac{{\bar c} }{\bar{\rho}_{a\eta} } \frac{ {\bf v}_{a\eta}\cdot {\bf r}_{a\eta} }{|{\bf r}_{a\eta}|},
 \label{viscosity}$$ where $\alpha$ is a constant, ${\bf v}_{a\eta}= {\bf v}_a-{\bf v}_\eta$, ${\bf r}_{a\eta}={\bf r}_a- {\bf r}_\eta$, ${\bar \rho}_{a\eta} =(\rho_a + \rho_\eta )/2$ denotes the average density, and $\bar{c}= (c_a + c_\eta)/2$. The constant $\alpha$ can be written in terms of the kinematic viscosity by converting the summations to integrals. We find for the Wendland kernel [@KajtarMonaghan2010] that

$$\nu=\frac{1}{8}\alpha h\overline{c}.
 \label{kineticviscosity}$$

The last term in Eq. (\[momentum1\]) is the boundary force on fluid particle $a$ due to the boundary particles. This force, together with the viscous forces due to the boundary particles included in the first term, is equivalent to the Sirovich [@Sirovich1967] formulation of the boundary conditions in terms of boundary forces, and closely related to the Immersed Boundary Method of Peskin [@Peskin1977]. ${\bf f}_{aj}$ is given by [@MonaghanKajtar2009] $${\bf f}_{aj}=\frac{\Gamma\ \Phi_{aj}}{(|{\bf r_{aj}}|-\Delta)} \frac{{\bf r}_{aj} }{ |{\bf r}_{aj} |},
 \label{boundforce}$$ where $\Phi_{aj}=\frac{1}{32}(1+\frac{5}{2}q+2q^2)(2-q)^5$ for $q\le 2$ and is otherwise 0. $\Gamma$ is a constant equal to $2V_{max}^2/(m_a+m_j)$ , $\Delta = \delta/3$ is the boundary particle spacing , and $q={|\bf r_{aj}|}/{h_{aj}}$.\
The position of any fluid particle $a$ is found by integrating $$\frac{d{\bf r}_a}{dt} = {\bf v}_a.
 \label{replacement}$$

For convenience in describing the time stepping algorithm we write the equations in the form $$\frac{d{\bf v}_a}{dt}={\bf F}_{a}({\bf r},\rho,{\bf v}),
 \label{momentum2}$$ and $$\frac{d\rho_{a}}{dt}= {\bf D}_{a}({\bf r},{\bf v}).
 \label{continuity2}$$

These equations were integrated using a time stepping scheme that is second order and based on Verlet symplectic method. In the following $A^0$ denotes a quantity $A$ at the beginning of the current time step, $A^{1/2}$ at the midpoint of the step, and $A^1$ at the end of the step. The time stepping equations, where $\delta t$ is the time step, can then be written $$\begin{aligned}
{\bf r}_a^{1/2} &= &{\bf r}_a^0+\frac{\delta t}{2}{\bf v}_a^0,\\
 \label{displacement tstep}
 {\bf v}_a^{1/2}& = &\kappa \ ({\bf v}_a^0+\frac{\delta t}{2}{\bf F}_a^{0}),\\
 \label{velocity tstep}
 \rho_a^{1/2}&= &\rho_a^{0}+\frac{\delta t}{2}{\bf D}_a^0.
 \label{density tstep}\end{aligned}$$ where $\kappa$ is a damping factor used to bring the particles to equilibrium before initializing the turbulence. This is required because the boundary forces are initially unbalanced. The simple and efficient method which we use here is that $\kappa$ is 1.0 for all steps except that every 4th time step it is set to 0.9854. This value of $\kappa$ is optimal to reduce the kinetic energy to the less than 0.01 percent of the total kinetic energy of vortices after 1000 damping steps. For each simulation a minimum time is necessary for damping, so that the number of damping steps will increase as resolution increases ($\delta$ made smaller).

The time step is completed by calculating ${\bf v}_a^1$, ${\bf r}_a^1$, and $\rho_a^1$ according to $$\begin{aligned}
{\bf v}_a^1&= &\kappa \ ({\bf v}_a^0+{\delta t}{\bf F}_a^{1/2} ),\\
 \label{velocity tstep2}
{\bf r}_a^1&= &{\bf r}_a^{1/2}+\frac{\delta t}{2}{\bf v}_a^1,\\
 \label{displacement tstep2}
 \rho_a^{1}&= &\rho_a^{1/2}+\frac{\delta t}{2}{\bf D}_a^1 ({\bf r}_a^1,\rho_a^{1/2},{\bf v}_a^1).
 \label{density tstep2}\end{aligned}$$

To improve the speed we replace ${\bf F}_a^0$ in \[velocity tstep\] by ${\bf F}_a^{-1/2}$, i.e half a step back.\
SI units are used throughout this paper.

The Initial turbulent velocity field {#Sec:velocity field}
====================================

For the numerical study of 2D decaying turbulence in a container the initial velocity field has been set using either Chebyshev polynomials [@Clercxetal1998; @Clercxetal1999; @Clercxetal2001] or Gaussian vortices [@ClercxHeijts2000; @ClercxNielsen2000]. The results for both setups are similar. In this paper Gaussian vortices are used. For the general case N$\times$N equal-size Gaussian vortices are placed on a regular lattice, in a checker-board pattern of positive and negative vorticity. The initial distance between the centres of vortices, $\lambda$ is $S/(N+1)$, where $S=1$ is the width of box. The centres of the vortices were then given a random displacement $0.06\lambda (2\tau-1)$, where $\tau$ is a quasi random number between 0 and 1. The rule for the random number is $jran=mod(jran*k+l,m)$ and $\tau=jran/m$ [@FORTRAN77]. Here $k$, $l$, and $m$ are 106, 1283 and 6075, respectively. When we wish to compare the effect of different initial states we use $12$ different initial values of $jran$. The values were $11$, $13$, $17$, $23$, $37$, $49$, $137$, $191$, $1111$, $1117$, $1139$, and $3737$.

The SPH particles were placed on a grid of squares in the domain $0\le x \le 1$ and $0\le y \le 1$. Each SPH fluid particle‘s velocity was calculated by summation over the vortices according to [@Monaghan2011]:

$$\bar{v}_a =\sum_{k=1}^{N\times N}\textbf{r}_{a k}\frac{\omega_k a_k}{2\pi |{\bf r}_{a k}|^2} \left(1- e^{-|{\bf r}_{a k}|^2/a_k^2 }\right),
 \label{Gaussian vortices}$$

where, ${\bf r}_k$ is the center of the kth vortex, $\omega_k$ is the vortex strength and its absolute amount is equal to $1.0$ for all vortices, and $a_k$ is the amplitude of vortex $k$ equal to $S/{4N}$. Finally, to ensure that the no-slip condition is closely satisfied in the initial state, a smoothing function similar to that used by other authors [@Clercxetal1998] was applied . The final initial velocity field for fluid particle $a$ is ${\bf v}_a (x,y)=f(x_a)f(y_a)\bar{{\bf v}}_a$ where $f(x)=1-exp(-9x'^2)$ and $x' = 1-(2x-1)^2$.

Fixed box: energy, vorticity and spin up {#Sec:self-organization}
========================================

General results
---------------

In order to confirm that our SPH code behaves correctly it is convenient to compare our results against the experimental and computational results of [@Clercxetal1998; @Clercxetal1999; @Clercxetal2001][@Heijstetal2006; @Maassenetal2002]. They showed that the energy and enstrophy decayed approximately as a power of $t$ until the flow is dominated by viscosity, and the angular momentum of the fluid may first increase in magnitude then slowly decay. This change in angular momentum is due to the reactive stress exerted on the fluid through its interaction with the walls. To show that these phenomena are also produced by our code we simulated turbulence in a fixed square of side 1m. The turbulence was initiated using $10\times10$ Gaussian vortices and $275\times275$ SPH particles and $\Re=2000$ as described in the previous section. The SPH particles were damped for $6000$ time steps after which the turbulence was initiated.

The vorticity $\omega_a$ for particle $a$, was determined by assuming that velocity of the particles relative to particle $a$ was a linear function of the relative coordinates $x$ and $y$. The coefficients of this function were determined by least squares after which the derivatives of the velocity components were calculated. In the figures the vorticity field has been scaled between 0 and 1. The total enstrophy of the flow was then calculated according to $$\xi( t)=\frac{1}{2}\sum_a\frac{m_a}{\rho_a}\omega_a^2.
 \label{enstrophy}$$

Fig. \[fig:spontaneous\] shows that the average size of the vortices increases with time as found by [@Clercxetal1999] and [@Maassen2002]. During this time intense shearing occurs near the boundaries as can be seen, for example, in the first frame of the second row on the left and right sides. The increase in the absolute value of the fluid angular momentum (the spin-up) shown in the Fig. \[fig:fixedrandom-angm\], accompanies the formation of relatively large vortices. After spin-up, the angular momentum decays slowly, and this stage is characterised by a relaxation process to a monopolar structure that is more or less situated in the centre of the container. Subsequently, the flow relaxes viscously (the last frame in Fig. \[fig:spontaneous\]).

Figure 2(a) shows the variation of kinetic energy for the present calculations (using $275 \times 275$ particles), those of [@RobinsonMonaghan2011], and those of [@Clercxetal1999] against scaled time $t$ (time is scaled by $S/2U_{RMS}$, where $U_{RMS}$ is the initial RMS velocity of particles and $S$ is the width of box). The scaled time for the results of [@Clercxetal1999] are based on the best estimate of the time scaling used in their graphs. All of these calculations indicate that $E_K \sim 1/t^{0.8}$ for $0 \lesssim t \lesssim 20$, with a more rapid decay for greater $t$. The agreement between the three sets of results is very satisfactory. In figure 2(b) we show the results of the experiments and the present SPH results for the variation of the normalized kinetic energy with time. The agreement is again very satisfactory. The decay of enstrophy is shown in figure 2(c). The results for the different numerical codes and the experimental results are similar to each other, and show an enstrophy decay that is faster than the decay of the kinetic energy and given by $\sim 1/t^{1.4}$. We can reasonably conclude that the decay of energy and enstrophy is not sensitive to the details of the initial velocity field (Gaussian vortices or a Chebyshev expansion), or sensitive to the two different treatment of boundaries in the SPH simulations.

  ------------------------------------------------------ ------------------------------------------------------ --------------------------------------------------------
  ![image](Re=2000t=0vorticity.jpg){width="4.7cm"}       ![image](Re=2000t=8-08vorticity.jpg){width="4.5cm"}    ![image](Re=2000t=13-5vorticity.jpg){width="4.5cm"}
  ![image](Re=2000t=27-0vorticity.jpg){width="4.5cm"}    ![image](Re=2000t=35-14vorticity.jpg){width="4.5cm"}   ![image](Re=2000t=48-7vorticity.jpg){width="4.5cm"}
  ![image](Re=2000t=73-11vorticity.jpg){width="4.5cm"}   ![image](Re=2000t=146-5vorticity.jpg){width="4.5cm"}   ![image](Re=2000t=309-52vorticity.jpg){width="5.05cm"}
  ------------------------------------------------------ ------------------------------------------------------ --------------------------------------------------------

  ------------------------------------------------------------ ------------------------------------------------------------ -------------------------------------------------------------
  **a**![image](EkClercxRobMonSPH-Re1500.jpg){width="4.8cm"}   **b**![image](EkClercxMassenSPH-Re2000.jpg){width="4.8cm"}   **c**![image](EntClercxMassenSPH-Re2000.jpg){width="4.8cm"}
  ------------------------------------------------------------ ------------------------------------------------------------ -------------------------------------------------------------

Convergence {#Sec:convergence}
-----------

In Fig. \[fig:convergence\][**a**]{} shows the variation of $E_k$ with $t$ for different values of $n_y$ the number of particle spacings along a side of the boundary. The initial particle spacing is therefore $1/n_y$. The graphs for $E_k$ indicate that the results are converging. In Fig. \[fig:convergence\][**b**]{} we show $ E_k$ at times 5, 10, 15, 20 and 25s as a function of resolution. These results indicate linear convergence. However, in order to determine the convergence of any quantity $A$ we follow [@Roache1997], and assume $$A(\delta) =A(0)+\beta\delta^p,
 \label{Euler}$$ where $A(0)$ is the value at infinite resolution, $\delta$ is the initial particle spacing, and $\beta$ and $p$ are parameters to be calculated. The parameters $A(0)$, $\beta$ and $p$ can be found by evaluating $A$ at three values of $\delta$. The trend of the kinetic energy with resolution, which is nearly linear, is shown in Fig. \[fig:convergence\].

  --------------------------------------------------------------- ---------
  $\bf a$![image](conv-time-fixede0Re1000-2.jpg){width="6.0cm"}   $\bf b$
  --------------------------------------------------------------- ---------

Fig. \[fig:convergence\]-b, shows that for all times the change of kinetic energy with particle size, $\delta$, is close to linear for high resolutions. From the expression (\[Euler\]) with $E_k$ for $n_y=100$, $200$ and $250$, we can calculate $E_k(0)$, $\beta$, and $p$ at other times , The resulting values are given in Table 1. Using the calculated values of $E_k(0)$, $\beta$, and $p$, it is possible to estimate $E_k$ at other times and other resolutions. Thus in Table I, the two columns under 275x275 show results calculated using SPH (the left column), and results using the convergence formula, denoted by $E_{est}$, are shown in the right column. The agreement between the two columns is very good. In general the difference between the SPH values, and those estimated from the convergence formula, decreases with increased resolution.

  ---- --------------------- ---------- ------- ------- ------- ------- ------- ------- ------- ------- -------
     t  $E_k\left(t\right)$   $-\beta$    $p$
                                                  SPH    Est.     SPH    Est.     SPH    Est.     SPH    Est.
     5         1.255           247.4     1.475   1.192   1.193   1.179   1.171   1.093   1.103   0.957   0.831
    10         1.05            36.33     0.962   0.884   0.886   0.855   0.851   0.746   0.756   0.524   0.476
    15         0.845           29.96     0.917   0.666   0.671   0.638   0.636   0.527   0.542   0.319   0.272
    20         0.730           20.04     0.831   0.541   0.541   0.506   0.506   0.398   0.417   0.212   0.173
    30         0.632           6.786     0.585   0.379   0.377   0.343   0.346   0.252   0.269   0.111   0.088
  ---- --------------------- ---------- ------- ------- ------- ------- ------- ------- ------- ------- -------

Data presented in this table show that the kinetic energy converges less rapidly as the time increases. and for longer times, the order of the convergence is less than one. The reason for the absence of second order convergence is not clear to us.

These convergence results indicate consistency

Angular momentum
----------------

As remarked earlier, a feature of the turbulence in two dimensions is the increase in the magnitude of the angular momentum, the spin-up. To confirm that our SPH simulation recovers the spin-up, we used $4\times4$ vortices with $150\times150$ particles and $\Re=1000$. As noted earlier in $\S \ref{Sec:velocity field}$ we choose 12 different values of $jran$. The time variation of the angular momentum is shown in Fig. \[fig:fixedrandom-angm\]. Among these $12$ simulations, $5$ show a rapid, spontaneous spin-up, and a further $4$ show spontaneous spin-down, which always characterised by the presence of a strong monopolar or a rotating tripolar structure. The other $3$ show no spin-up or very slow spin-up. During the intermediate stage of these runs a dipolar or quadrupolar structure is usually found. For example, the velocity field after 206 seconds is shown in Fig. \[fig:fixedrandom-velocity\], for two different initial setups. This left frame of this figure shows the formation of a monopolar vortex which corresponds to the sudden increase in angular momentum. The right frame shows the formation of dipolar vortices, which corresponds to nearly zero angular momentum during the decay of the turbulent flow.   [@Clercxetal1999] reported similar behaviour for an initial velocity field of Gaussian vortices or Chebyshev polynomials as did [@RobinsonMonaghan2011] for Chebyshev polynomials.

![image](initial-Angm-fixedBox-e=0.jpg){width="14.50000%"}![image](fixedBox-Random-L.jpg){width="60.00000%"}

![image](fixed2239.jpg){width="40.00000%"}

Although the change in angular momentum is considerable when $jran$ is changed the corresponding difference in the decay of kinetic energy with time is small, and all runs have a similar power law decay.

Summary of the results with a fixed box
---------------------------------------

Our SPH simulation recovers the principal phenomena found by other authors for turbulence in a two dimensional box with no-slip boundaries. This includes the growth of vortices, the decay of the kinetic energy and enstrophy, and the initial rapid increase in magnitude of the angular momentum followed by a slow decay. We conclude from this that our SPH code gives satisfactory results for two dimensional turbulence in a no-slip box and, in particular, the effectiveness of our boundary force model is confirmed.

Freely rotating boxes {#Sec:rotating}
=====================

We now consider the fluid angular momentum when the turbulence is initiated and the box is allowed to rotate under the torque produced by the fluid. In this case the angular momentum of the box and fluid is constant. In order to amplify the rotation of the box we give it a mass $ m_{box}=0.001\times {\rm (mass \ of \ fluid) }$ and moment of inertia $I_{\rm box} = \frac23 m_{box} S^2$. The force ${\bf f}_j$ on boundary particle $j$ due to fluid particles is given by $${\bf f}_j = \sum_a m_j {\bf f}_{aj},$$ and the torque on the box about its centre is $${\bf T} = \sum_j {\bf r}_{jo}\times  {\bf f}_j,
 \label{torquebox}$$ where ${\bf r}_{jo}$ is the coordinate vector of boundary particle $b$, relative to the centre of the box. The angular velocity of box $\Omega$ is calculated from $$I_{\rm box} \frac{d \Omega}{dt} = \bf T.$$ The initial set up is same as the previous section. Fig. \[fig:freerandom-Lbox-lfluid\] shows the angular momentum for the different values of $jran$. The left frame of Fig. \[fig:freerandom-Lbox-lfluid\] shows the angular momentum of the fluid. The key point is that the fluid angular momentum remains nearly constant for all values of $jran$. The right hand frame of Fig. \[fig:freerandom-Lbox-lfluid\] shows the angular momentum of the box which may be positive or negative but the magnitude is always small and decreases with time. The magnitude of the change in the fluid angular momentum can be calculated from the box angular momentum. In the case of the fixed box the fluid angular momentum typically changes by $\sim 1$, whereas in the present case it typically varies by 0.002, a factor 500 less. The average size of the vortices increases with time as in the fixed box. For all 12 initial setups, a monopolar vortex formed at the centre of box. In contrast, some of the 12 setups for the fixed box, produce dipole or quadropole vortices, e.g. compare Fig. \[fig:freerandom-velocity\] with Fig. \[fig:fixedrandom-velocity\]. The decay of enstrophy in the freely rotating box is similar to that in the fixed box.

  ------------------------------------------------------ ----------------------------------------------------
  $\textbf{a}$ ![image](angm-fluid.jpg){width="7.0cm"}   $\textbf{b}$ ![image](angm-box.jpg){width="7.0cm"}
  ------------------------------------------------------ ----------------------------------------------------

  --------------------------------------------- --
  ![image](rotate2239.jpg){width="40.00000%"}
  --------------------------------------------- --

The decay of total kinetic energy of the fluid in the rotating box and the fixed box are very close, although, in the last stages of rotation, when the kinetic energy is $\sim 10^{-3}$, the kinetic energy of the fluid in the rotating box is larger than the kinetic energy for the fixed box. In Fig. \[fig:freerandom-rotation\] the results of different runs are sorted according to the initial angular momentum. For each run the initial and final kinetic energy, final box angular momentum, and final box rotation are shown. The kinetic energy is multiplied by $10^4$ in this figure and the box angular momentum is multiplied by $10^3$. The direction of rotation of the box is given by the sign of initial angular momentum of fluid, but the magnitude of box angular velocity is not related to the magnitude of the initial angular momentum. The initial kinetic energy for all runs is nearly same, but the kinetic energy after $206$ seconds can be significantly different according to the initial set of random shifts of the vortices.

  --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  ![Initial total kinetic energy, $E_k(0)$, final total kinetic energy, total fluid angular momentum, $L_ {fluid}$, total box angular momentum, $L_{box}$, and total box rotation, $\theta$, after $206 s$ for a free-rotating box at $\Re=1000$. The horizontal axis shows the number of initial setups for different random numbers, which are sorted according to $L_{fluid}$. []{data-label="fig:freerandom-rotation"}](angm-Ek-teta.jpg "fig:"){width="11.5cm"}
  --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

The effect of Background rotation
=================================

In the previous cases the initial angular velocity $\Omega_0$ of box and fluid before inserting the Gaussian vortices was zero. Another interesting case that is relevant to turbulence in the earth’s atmosphere or ocean, is the behaviour of turbulence when the fluid has a background rotation. Forced quasi-two-dimensional turbulence in rotating containers has been studied both by experiment and by numerical simulations [@Clercxetal2005; @Molenaaretal2004]. By adding an oscillation to the rotation of the container it is possible to determine how shear near the boundary generates vorticity. The vorticity generated in this way subsequently moves into the central regions of the container though in the SPH simulations of [@RobinsonMonaghan2011], the vorticity generated in this way dissipated more rapidly than in the calculations of [@Molenaaretal2004].

In this section we study the turbulence when the fluid and box are set rigidly rotating with angular velocity $\Omega_0$, after which the vortices are added. The vorticity of the initial state is then $\omega_0 = 2\Omega_0$. The additional vorticity due to the gaussian vortices satisfies the usual vorticity diffusion equation for two dimensions (equation \[vort\]). If the turbulence is studied in the frame rotating with angular velocity $\Omega_0$ the centrifugal force is balanced by the radial pressure gradient. The Coriolis force, $2 (\Omega_0 {\bf \hat z} ) \times {\bf v}$, changes the motion of the flow arising from the vortices.

The previous Gaussian vortices were used with $jran=11$, and the rotation was chosen so that the Rossby numbers, $Ro=2U_{rms}/ \Omega_0S$ were in the range $0.57 \le R_o \le 11.0$. $U_{rms}$ is the root mean square velocity of vortices, which is equal to $0.057$, and $S=1$ is the width of box. The results for infinite $Ro$ were discussed in the previous section. Here $Ro\simeq11$, $1.1$, and $0.57$ equivalent to $\Omega_0=0.01$, $0.1$, and $0.2$ respectively. The Reynolds number was set to 1000 for all studies hereafter.

After damping, the box and fluid were rotated with $\Omega_0$ for $2000$ time steps after which the box and fluid were rotating rigidly. The Gaussian vortices were then added to the velocity field. The subsequent velocity and vorticity field then depends on the rotation of the box and how the added vortices change in response to the background rotation. We consider two cases. The first, denoted by A, is where the rigid rotation of the box is maintained. The second, denoted by B, is when the box is allowed to respond freely to the fluid stresses on it. In the following we denote the kinetic energy and the enstrophy in the inertial frame by $E_k$ and $\xi$ respectively, and in the rotating frame by $\hat E_k$ and $\xi_{rot}$.

The box with maintained rigid rotation
--------------------------------------

In this case the box rotates rigidly with angular velocity $\Omega_0$. The total kinetic energy of box and fluid is shown in the left frame of Fig.  \[fig:Ek-L rotating\] for $\Omega_0=0.2$. The dashed line shows the kinetic energy for the rigidly rotating box. The kinetic energy increases suddenly because of the extra kinetic energy of the vorticity field. This extra kinetic energy decays rapidly to a steady state where the fluid and box are rotating rigidly. The relative decay of the kinetic energy, $E_k$, due to the vortices at different $\Omega_0$’s is calculated by $\Delta E_k =(E_k-E_{in})/\hat{E_{in}}\times100$, where $E_{in}$ is the initial kinetic energy before adding vortices, and $\hat{E_{in}}$ is the total initial kinetic energy of vortices. The kinetic energy of the fluid in the inertial frame is $$E_k=\hat{E_k} + \frac{1}{2}I\Omega_0^2 + \Omega_0\hat{L},
 \label{energy}$$ where, $\hat{E_k}$ and $\hat{L}$ are the kinetic energy and angular momentum of the fluid in the rotating frame, respectively, and $I$ is the moment of inertia of the fluid around the box centre. $\hat{E_k}$ and $\hat{L}$ are zero before adding vortices.

The calculated kinetic energy in the rotating frame is the same for all $\Omega$’s, for a given set of vortices. The values of $\Delta E_k$, using $E_k$ as the minimum kinetic energy which occurs nearly at time 100s, is shown in column $7$ of table \[tab:decay\]. The results in table \[tab:decay\] show that the rate of decay of the kinetic energy of the fluid increases significantly by increasing the box angular velocity. Therefore, while the rate of change of kinetic energy in the rotating frame is always negative, the rate of change of kinetic energy in the inertial frame can be negative or positive, due to the last term in equation \[energy\]. This can be seen easily from the left frame of Fig. \[fig:Ek-L rotating\].

  ------------ ----------- ------- ------- ------------ ----------------- ----------------------

           (1)     (2)       (3)     (4)       (5)             (6)                 (7)
    $\Omega_0$  $L_{Box}$   $Min$   $Max$   $\Delta L$   $\hat {E_{in}}$   $\Delta E_k (t=100)$
          0.00    0.000     -0.94   0.00       0.94           1.575               +0.092
          0.01    0.002     0.414   1.61       1.20           1.575               -0.202
          0.10    0.017     14.84   16.10      1.26           1.573               -6.331
          0.20    0.033     30.87   32.21      1.35           1.575               -14.63
  ------------ ----------- ------- ------- ------------ ----------------- ----------------------

  : The rate of decay in kinetic energy, $\Delta E_k$, total angular momentum, of box $L_{Box}$, and fluid, $L_{Fluid}$ for when the box continues to rotate rigidly at different angular velocities, $\Omega_0$. $\hat E_{in}$ is the initial kinetic energy of vortices.[]{data-label="tab:decay"}

  ------------------------------------ --------------------------------------
  ![image](Ek0-2.jpg){width="8.0cm"}   ![image](Lb-F0-2.jpg){width="8.0cm"}
  ------------------------------------ --------------------------------------

  ----------------------------------------------- ----------------------------------------
  ![image](Ek-RotatingFrame.jpg){width="6.2cm"}   ![image](DiffEkEk0.jpg){width="6.0cm"}
  ----------------------------------------------- ----------------------------------------

The right frame of Fig. \[fig:Ek-L rotating\] shows the total angular momentum of the box and the fluid for the case where the box rotates rigidly. The angular momentum of fluid in the inertial frame decreases to a minimum (column 3 of Tab. \[tab:decay\]), then it decays gradually until at infinity it reaches the initial angular momentum of fluid before adding Gaussian vortices (column 4 of Tab. \[tab:decay\]). Recall that in this section the box rotates rigidly throughout the simulation. The change in the angular momentum of the fluid is almost independent of $\Omega_0$, e.g the maximum change in the angular momentum of fluid is shown in column 5 of Tab. \[tab:decay\], which shows the subtraction of column 3 from column 4. In the left frame of Fig. \[fig:kinenergyangvel\] we show the decay of kinetic energy in the rotating frame for different values of the angular velocity of the box. As conjectured after (9) it is expected that the decay of the kinetic energy calculated in the rotating frame should be independent of the rotation because the equations for the decay are identical to those in a fixed box.The right hand frame of Fig. \[fig:kinenergyangvel\] shows that the decay of $E_K$ varies significantly with the angular velocity of the box.

The enstrophy calculated in the rotating frame, $\xi_{rot}$, is independent of $\Omega_0$ and is same as the fixed box, this is shown in the right frame of Fig. \[fig:enstrophy-vortices\]. Using the no-slip boundary conditions it can be shown that the enstrophy $\xi$ calculated in the inertial frame is 8$\Omega_0^2S^2$ larger than $\xi_{rot}$, where $S$ is the half-width of box. As a consequence, when the enstrophy in the rotating frame has decayed to zero, $\xi = 8\Omega_0^2S^2$ as shown in the left frame of Fig. \[fig:enstrophy-vortices\](graphs labelled ’forced ’).

  ----------------------------------------------------------- --------------------------------------------------------------
  $\textbf{a}$![image](entrosphy-total2.jpg){width="7.8cm"}   $\textbf{b}$![image](entrosphy-vortices2.jpg){width="7.8cm"}
  ----------------------------------------------------------- --------------------------------------------------------------

The box freely-rotating after the vortices are initiated
--------------------------------------------------------

In this case the box rotates freely after the vortices are initiated in the rigidly rotating fluid. The subsequent motion of the box is due to the stresses on it from the fluid. This class of problem is relevant to a wide range of engineering fluid-structure interaction problems such as vortex-induced vibrations. The total kinetic energy of box and fluid in the inertial frame, $E_k$, for this case is shown in the left frame of Fig. \[fig:Ek-L rotating\]. By adding Gaussian vortices to the background velocity field, a sudden rise in kinetic energy occurs which is followed by a sharp decline to the background kinetic energy. The kinetic energy is calculated at the same times that the kinetic energy of the box with maintained rigid rotation is minimum for each $\Omega_0$. The relative decay is shown in the last column of table \[tab:decay in rotation freely rotation\]. The decay rate of total kinetic energy (liquid and box) when the box is freely rotating is less than the when it is rigidly rotated, and this difference increases significantly by increasing the box angular velocity (see Tab. \[tab:decay\] and Tab. \[tab:decay in rotation freely rotation\]), around $15 \%$ for $\Omega_0=0.2$. The decay rate of the kinetic energy increases as the angular velocity increases for both the freely rotating box and the rigidly rotating box.\

  ------------ ------- ------- ------------ -------- -------- ------------ ----------------------

      (1)        (2)     (3)       (4)        (5)      (6)        (7)               (8)
   $\Omega_0$   $Min$   $Max$   $\Delta L$   $Min$    $Max$    $\Delta L$   $\Delta E_k (t=100)$
      0.00       0.0    0.005     0.0054     -0.126    0.0       0.126             +1.84
      0.01      0.002   0.007     0.0051     1.484    1.609      0.126             +1.67
      0.10      0.017   0.022     0.0053     15.963   16.107     0.144             +1.46
      0.20      0.033   0.038     0.0050     32.060   32.268     0.208             +0.22
  ------------ ------- ------- ------------ -------- -------- ------------ ----------------------

  : The rate of decay of kinetic energy, $\Delta E_k$, total angular momentum, of box $L_{Box}$, and fluid, $L_{Fluid}$ for the case of a box which is rotated initially with $\Omega_0$ then rotates freely after the vortices are initiated.[]{data-label="tab:decay in rotation freely rotation"}

The right frame of Fig. \[fig:Ek-L rotating\] shows the total angular momentum of box and the total angular momentum of fluid, when the box is free to rotate after the gaussian vortices are initiated. The angular momentum of the box is not constant and increases to a maximum, then it decays gradually until it reaches the angular momentum of the box before initiating the Gaussian vortices. Note that the combined angular momentum of fluid and box is constant and the angular momentum of the box is scaled up by a factor $10^3$. The increase in total angular momentum of the box is not related to the $\Omega_0$ (column 4 of Tab. \[tab:decay in rotation freely rotation\]). The initial angular momentum of vortices is around -0.126. The thin solid line in the right frame of Fig. \[fig:Ek-L rotating\], which shows the total angular momentum of the fluid in the inertial frame, shows a small drop by -0.126 shortly after $t=1$, then remains nearly constant, varying slightly as the box angular momentum changes. These changes in the angular momentum are indicated in columns 5 to 7 of Tab. \[tab:decay in rotation freely rotation\]. Thence the angular momentum of the fluid remains approximately constant for each $\Omega_0$.\
From the right frame of Fig. \[fig:enstrophy-vortices\], and focussing on the graphs labelled ’free’, it can be seen that the decay of enstrophy is independent of $\Omega_0$ as in the case of the rigidly rotating box. The enstrophy of the fluid when the box is freely rotated is always slightly larger than when it is rotating rigidly. The right frame of Fig. \[fig:enstrophy-vortices\] shows the decay of the enstrophy after subtracting the initial background rotation from the total flow. Although the rotation of the box can change when it is freely rotating it is convenient to consider the enstrophy in the frame rotating with the initial angular velocity. The enstrophy shown in the right frame of Fig. \[fig:enstrophy-vortices\] is calculated in this frame both for the forced and free rotations. Our comparison shows that the enstrophy decay in this frame is nearly same for all $\Omega_0$’s, and is very close (0.17 %) to that of the rigidly rotated box .

The angular velocity of the box due to the vortices is shown in the left frame of Fig. \[fig:theta-vortices\]. This figure shows that the effect of vortices is nearly the same for all background rotations and, as a consequence, the total rotation of the box is similar for all values of $\Omega$ as shown in Fig. \[fig:theta-vortices\] for different $\Omega_0$’s.

  ------------------------------------------------------- ---------------------------------------------------------
  $\textbf{a}$![image](Omega-Omega0.jpg){width="7.8cm"}   $\textbf{b}$![image](thetavortices2.jpg){width="7.8cm"}
  ------------------------------------------------------- ---------------------------------------------------------

Summary of the results with Background rotation
-----------------------------------------------

In the case of the box with maintained rigid rotation, if the flow is considered in a rotating frame, the effect of background rotation on the flow characteristics like vorticity structure (see Fig. \[fig:Vort-free-rigid\]), enstrophy, kinetic energy of vortices, and angular momentum of the fluid is negligible. These results are consistent with the fact that the equations for the decay of enstrophy and kinetic energy in the rotating frame are identical to those for a fixed box. The decay rate of the kinetic energy in the inertial frame increases with $\Omega_0$.

When the box is allowed to rotate freely, the effect of the background rotation is negligible, though the vortex structure is completely different from that for the box with maintained rigid rotation (see Fig. \[fig:Vort-free-rigid\]).

  -------------------------------------------- -------------------------------------------- --------------------------------------------
  ![image](forced-00-t76.jpg){width="5.0cm"}   ![image](forced-01-t76.jpg){width="5.0cm"}   ![image](forced-02-t76.jpg){width="5.0cm"}
  ![image](free-00-t76.jpg){width="5.0cm"}     ![image](free-01-t76.jpg){width="5.0cm"}     ![image](free-02-t76.jpg){width="5.0cm"}
  -------------------------------------------- -------------------------------------------- --------------------------------------------

Conclusion
==========

We have described the results of numerical simulations of decaying two-dimensional turbulence inside a rotating square container with rigid no-slip boundaries, using SPH. Three cases were studied here and, in all cases, the turbulence was initiated by superimposing the velocity field of a set of gaussian vortices. The first two cases involve a fixed box, and a box that is free to rotate under the stresses from the fluid. The third involves adding gaussian vortices to a box and fluid rotating rigidly. After which the box was either forced to maintain its rigid rotation, or allowed to rotate under the stresses from the fluid.

Our simulations confirm that our SPH code correctly simulates turbulent flows in a fixed square box with no-slip boundaries. In particular, the simulations show a rapid self-organisation of the flow toward one or two large vortices as the total kinetic energy of the flow decreases. By changing the random shift of the initial vortices from a regular grid the initial conditions can be changed. The resulting simulations provide an ensemble from which more general properties can be deduced. It was observed that 5 of them show a rapid spontaneous spin-up, and a further 4 showed spontaneous spin–down. All of them were accompanied by an increase in the magnitude of the angular momentum of the fluid. That behaviour was always accompanied by a strong monopolar or a rotating tripolar structure. The other 3 simulations showed no spin-up or very slow spin-up. During the intermediate stage of these simulations a dipolar or quadrupolar structure was usually found, and the net angular momentum of flow remains approximately constant or decayed only very slowly. The decay of the total kinetic energy of the flow was more rapid in all cases. These results are in good agreement with other experimental and numerical studies [@Clercxetal1999; @Maassenetal2002; @RobinsonMonaghan2011].

When the box was allowed to rotate under the stresses from the fluid the angular momentum of the fluid remained approximately constant and the total angular momentum of box and fluid remained constant as it should. Simulations with slightly different initial conditions change the dynamics of the box. In particular, the box angular momentum changes and therefore the amount and direction of its rotation. All 12 initially different setups concluded in a strong monopolar vortex. The rate of decay of the kinetic energy is nearly the same as that for the box with maintained rigid rotation.

From the study of the effect of a background rotation on the decaying turbulence, it was seen that for the box with maintained rigid rotation, the effect of box angular velocity on the angular momentum, vorticity structure, velocity field, kinetic energy, and enstrophy is negligible, when these quantities are calculated in a frame rotating with $\Omega_0$. This is consistent with the fact, already noted, that the equations for the decay of kinetic energy and enstrophy in the rotating frame are the same as in the inertial frame. For the box freely-rotating after the turbulence was initiated, kinetic energy, angular momentum,vorticity structure, velocity field, enstrophy, and rotation, calculated in the rotating frame were independent of $\Omega_0$. Although some parameters like kinetic energy or enstrophy calculated in the rotating frame are similar for both the freely rotated box and the box with maintained rigid rotation, the vorticity structure, velocity field and angular momentum are completely different for these two situations.

The resolution required for these SPH simulations depends on the accuracy required and the time for which that accuracy should be maintained. The results of this paper and those of [@RobinsonMonaghan2011], and [@Monaghan2011], show that for the square box of half width $S$ the number of particles should be $\sim 200$ with particle spacing $dp = 2S/200$, in order to determine the energy decay to within $10\%$ for $t<15$. The resolution length can by estimated from $h = 1.5 dp$ and this is $ \sim 0.5S/\sqrt{\Re} $ which agrees with the estimate of [@Clercxetal1999]. We also note that our treatment of the boundaries using boundary forces gives results in good agreement with those of [@RobinsonMonaghan2011] for the energy decay obtained using a boundary modelled by layers of fixed fluid particles. However, the convergence of our results for the energy decay, obtained using the Wendland kernel, appear to be faster than those of [@RobinsonMonaghan2011] (see for example their figure 9) using the cubic spline kernel. This agrees with the experience of Robinson (private communication) who repeated some of his calculations using the Wendland kernel instead of the cubic spline kernel.

In addition to the class of problems considered here SPH can be applied to other turbulent flows where it has many advantages. One of these is the turbulent flow produced by physical stirrers, for example cylindrical rods moving on specified paths. Such a problem can be simulated easily with SPH and, in unpublished work, we have studied the turbulence produced by such stirrers moving on a variety of trajectories. SPH has also proven useful for studying breaking waves especially those formed by a flow hitting and running up a wall and finally forming a backward breaking wave. A region of strong turbulence is created by the impact of the breaking wave on the incoming fluid. This problem, which is a key feature in sloshing in marine tanks, could be tackled using an SPH code of the kind we have described.

Acknowledgments
===============

This research was funded with the support of ARC Discovery grant DP0881447 (Analysis of two-phase sloshing in marine tanks).

References
==========


Watching Hillary get a Liberty Medal on September 10, the day before the anniversary of the attack on the United States soil and the more recent murder of our ambassador and others in Benghazi, I think it’s time to review the record of a woman whose life is marked by deceit and professional failure and ask about the sanity and judgment of her ardent supporters.

She was chosen for this honor not because of grades or character or service to that community but because her influential roommate threatened a strike if she were not allowed to speak. Once the school caved to this demand, Hillary – who just two years earlier supported Senator Edward Brooke, the first black American to be elected to the Senate — hurled a vicious attack on him.. The charges were hurtful to him and without substance. As Christopher Andersen recounts:

Hillary offered nothing more than the muddled, sophomoric peace-and-love dogma that was so prevalent on campuses at the time. And, predictably, when it was over, Hillary’s mesmerized classmates leaped up to their feet and cheered.

What difference does it make? Doesn’t this reflect on the inconstancy of her political views and loyalties, her willingness to demagogue and slander and to use muscle to promote herself? What does it say about her empathy for Black community whom she professes to support?

From Wellesley she went to Yale law school after which she moved to Washington, D.C. to take a job with the House Judiciary Committee investigating Watergate. She was fired from her job and from that point on distinguished herself as a public master of mendacity.

Jerry Zeifman, a lifelong Democrat, supervised the work of the 27-year-old, fired her, and has explained why:

“Because she was a liar,” Zeifman said in an interview last week. “She was an unethical, dishonest lawyer. She conspired to violate the Constitution, the rules of the House, the rules of the committee and the rules of confidentiality.”

What difference does it make? It should seem obvious that she does not feel constrained to follow ethical or legal constraints, and therefore presents a danger whenever she finds herself in a position to exercise power.

At about the same time, Hillary failed the District of Columbia bar exam, hardly one of the more difficult bar exams in the country. What difference does it make? I realize that many voters have uncritically adopted Bill Clinton’s description of her as “the smartest woman in the world”, but except at deceit, self-promotion, and self-enrichment she is a repeat, proven failure whenever tested.

In 1978 she turned a $1,000 cattle commodity trading account into $6,300 overnight and within 10 months into a $100,000 profit. While she first lied and claimed she learned how to make this incredible investment profit in the riskiest of endeavors by educating herself on commodity futures, in fact she was the beneficiary of preferred treatment by an Arkansan when her husband was Arkansas attorney general and slated to become that state’s governor, when in other words Bill was a person in a position to provide favors in return.

The odds of this happening except by design (and preferential treatment ) were calculated at one in 31 trillion. The IRS was somewhat less impressed by the failure to account for income and pay taxes on it, and she was forced to pony up. There was no investigation that time.

What difference does it make? If you think it’s important to have in positions in power someone who can lie without missing a beat, no matter how implausibly, she proved then and a number of times afterward she can do it.

Not all her lies were for herself alone. She regularly covered up her husband’s misogynistic attacks on women, apparently accepted without protest his nuts and sluts defenses, and no one did a better job than she when pretty in pastel green and with a nice girlish headband she stood by her man while incongruously insisting she was no Tammy Wynette.

What difference does it make? She made a mockery of the feminist and Democratic claims that they were going to bat for women, working to make sure they had equal and fair treatment. The feminist movement sacrificed its moral sway on these two who would have pulled off the years-long deceit but for a providently saved little blue dress.

Hillary’s corruption and preposterous lies continued into the White House. Special prosecutors investigating an apparently corrupt loan and land development deal had conducted subpoena searches for Hillary’s law billing records which she claimed had gone missing.

….they were suddenly turned over to the prosecutors by a White House aide, Carolyn Huber. Mrs. Huber said she had found them on a table in a room in the White House living quarters last August and put them in a box, then had realized this month that they were the records that had been subpoenaed.

Hillary became the first First Lady to have to testify to a federal grand jury. In the end she wasn’t indicted in the Whitewater scandal, in part quite obviously because of the unlikelihood that an overwhelmingly Democratic jury in the District of Columbia would ever convict her. What difference does it make? Someone who so obviously lied to escape criminal jeopardy would drive confidence in the fairness and honesty even lower than Obama has and a society in which the leaders are held in such disregard is a vastly weaker one in every respect.

At the time David Maraniss and Susan Schmidt wrote a detailed account of the controversy and had this to say about the missing/late found records and Hillary’s treatment of them

How a public figure reacts to a controversy can be as important as what happened in the first place.

[snip]

From the beginning of the Whitewater controversy, Hillary Clinton has maintained a public posture seemingly at odds with her actions. She was reluctant to release records during the 1992 campaign. She fought David Gergen’s recommendation to turn over all the records in 1993. She led White House opposition to the appointment of a special counsel in early 1994.

There appears to be a four-year pattern of Hillary Clinton avoiding full disclosure, occasionally forgetting places and events that might embarrass her, and revising her story as documents emerge and the knowledge of her questioners deepens. This article examined only one of several areas where her answers could be analyzed. Similar studies could be done in other areas, including the original Whitewater investment itself and the extent to which the Clintons were equal yet passive partners with the McDougals, as they have maintained.

Based on Hillary Clinton’s proclamation of a nonexistent crisis, Congress had been stampeded into passing unnecessary legislation. And even though the worst features of the administration plan had been dropped, the country was still stuck with a program that was more costly, cumbersome and wasteful than the one it replaced. What’s more, the alarming statistics Hillary had cited on the rise in prices of prescription drugs were another myth. It turned out that the Labor Department statisticians had gotten the numbers wrong.

This news came too late for investors. The threat of price controls had caused the blue chip pharmaceutical stocks to decline as much as 40 percent, wiping out over $1 billion worth of market capitalization. Some smaller biotech companies were put out of business permanently.

Only short sellers profited, among them a private hedge fund called ValuePartners I, run by Smith Capital Management of Little Rock, Arkansas. Hillary Clinton held an $87,000 stake in Value Partners I, which also owned a block of stock in United Healthcare, an HMO that stood to benefit under the Clinton reform plan. Lois Quam, a United Healthcare vice president, was a member of the task force.

Unlike the Carters, Bushes and Reagans, the Clintons failed to put their assets into a blind trust when they moved into the White House. Hillary resisted the notion that her financial affairs were anybody’s business but her own, and she reasoned that since she was not a government employee and the money was in her name, she didn’t have to resort to a trust.

What difference does it make? Odd that a program that made vaccinations for children more costly and difficult to obtain benefitted Hillary (and Bill) who had demagogued through this bill using false statistics.

At the same time she barreled through that loser her husband drafted her to head a Task Force to draft new health legislation, Her clumsy handling of the Task Force certainly added to the opposition to this wonk wet dream and by 1994 it was dead. What difference does it make? Yet again we see that she trusts few people, listens to fewer, has a blinkered , highly-exaggerated view of her abilities to formulate or execute legislation.

The day after she was awarded the Liberty Medal, the Washington Post broke yet another Hillary-linked scandal.

A D.C. businessman under investigation for having financed the campaign of the mayor and others, was found to have contributed over $600,000 to Hillary Clinton’s get-out-the-vote campaign in 2008. His contribution was not disclosed by Hillary’s campaign or by Thompson in violation of the Federal campaign laws. The person paid by Thompson to do this work also failed to file corporate income tax which would have revealed the payments. That man (Mr. White) has admitted that he coordinated his efforts with the Clinton campaign. His contact there seems to have been former Rainbow PUSH coalition organizer Minyon Moore, Clinton’s director of political affairs in the White House and a senior adviser to Hillary’s 2008 campaign.

Mrs. Moore, for her part, provided Mr. White with “confidential internal information” about the campaign’s itinerary, and arranged for a Clinton campaign office to give campaign materials to his workers to hand out, according to the documents. Mr. White is now cooperating with what the U.S. attorney says is a “continuing investigation.” That’s an ugly prospect for Hillary 2016.

The shady money funneling is bad enough, but it takes on an extra dimension because Mr. Thompson’s accounting firm was a significant government contractor, providing services inter alia to a number of federal agencies, departments, and the Congressional Black Caucus and many big-name Democrats are the recipients of even his above-board contributions.

As Secretary of State, Hillary proved even a bigger disaster to the country.

She, who had failed to provide the begged-for security to our ambassador and officials in Benghazi and who seems to have done nothing but participate in the bald-faced lies about the murderers and their motive was, in fact, the author of the Red Line dare that has plunged Obama into a Syrian disaster.

The red line was not a gaffe it was the considered policy of the United States. This, if anything, makes the whole incident more egregious as the nation was consciously committed to acting militarily (see Clinton’s statement about “contingencies” and “response”) in case of chemical weapons use in Syria and yet it is obvious no planning was ever accomplished in anticipation of such an event. Yet another blunder by the administration comes home to roost.

Rick Ballard sums up her foreign policy and how it proved an utter catastrophe:

The NYT is drawing attention away from [Hillary] by focusing on [Obama]. Arab Spring belongs to [her]. It was supposed to be a demonstration of her mastery of foreign policy and her “team” of Abedin, Powers and Rice were supposed to demonstrate how marvelous women were in applying “soft” power to effect “change”. It began to go just a little off track when [Gaddafi’s] intransigence in resisting the Franco/US/Brit coup led to the delivery of a few thousand tons of kinetic humanitarian aid to alter the hearts and minds of Libyans who had not yet demonstrated sufficient affection for the bright future designed for them in DC. It continued to drift further from Clinton’s objective when the Egyptian generals determined [Hillary/Obama] had no intention of fulfilling the promises which had induced the generals to allow the Muslim Brotherhood to play FaceBook revolutionaries, so the generals took the KSA/Gazprom hard cash offer and squashed Huma’s buddies like bugs.

Syria is just the last gasp of the Clinton Arab Spring idiocy and [Obama’s] promise of a gentle tap with just a few hardly noticeable Tomahawks was just a continuation of the soft power idiocy promulgated by Clinton and her shrews. The same crew are wholly responsible for the Benghazi fiasco where Clinton’s denial of funding for adequate security led to [Gaddafi’s] arms stockpiles drifting into unkind and uncaring hands.

What difference does it make? Do we really want to follow the community organizer who failed to get the asbestos out of Altgeld Gardens with the woman who has lied, cheated, instigated wrongheaded legislation, botched our foreign policy and seriously diminished our role on the international stage? It’s fine with the Washington Post’s Ruth Marcus, who saw Hillary get the Liberty Medal and is as agog at the possibility as the jejune Wellesley grads were delighted when Hillary shocked the staid graduation ceremony by leveling her unwarranted attack on Senator Brook:

The men who gathered here 226 years ago to draft a new national charter never imagined a woman as president. Indeed, as Clinton noted, it took a constitutional amendment more than a century later to extend to women the right to vote, and “we are still on our way to that more perfect union.”

On a steamy September night, it was not hard to imagine what progress she had in mind.

Hillary Rodham Clinton will receive the 2013 Liberty Medal at the National Constitution Center in Philadelphia.

.

Jeb Bush, the chairman of the Constitution Center, will present the award to Clinton at a ceremony scheduled for Sept. 10.

Both Clinton and Bush are potential contenders in the 2016 presidential elections, for opposing parties. But in a statement, the GOP’s Bush only accentuated the positive.

“Former Secretary Clinton has dedicated her life to serving and engaging people across the world in democracy,” said Bush, the Republican former Governor of Florida, son of a former president and brother of another. “These efforts as a citizen, an activist, and a leader have earned Secretary Clinton this year’s Liberty Medal.”

Tickets for the general public will be made available in August. Details will be released next month, a Constitution Center spokeswoman said.

The Liberty Medal was established in 1988 to commemorate the bicentennial of the U.S. Constitution. Previous recipients include former Presidents George H.W. Bush and Bill Clinton, U2 frontman Bono, filmmaker Steven Spielberg and Nelson Mandela.


//
//  RCDDebugJoinChatroomViewController.m
//  SealTalk
//
//  Created by 孙浩 on 2019/10/17.
//  Copyright © 2019 RongCloud. All rights reserved.
//

#import "RCDDebugJoinChatroomViewController.h"
#import <Masonry/Masonry.h>
#import "RCDDebugChatroomViewController.h"
#import <RongIMLib/RongIMLib.h>

@interface RCDDebugJoinChatroomViewController ()

@property (nonatomic, strong) UIButton *joinChatroom1Btn;
@property (nonatomic, strong) UIButton *joinChatroom2Btn;

@end

@implementation RCDDebugJoinChatroomViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    [self setupUI];
}

#pragma mark - Private Method
- (void)setupUI {
    self.view.backgroundColor = [UIColor whiteColor];

    [self.view addSubview:self.joinChatroom1Btn];
    [self.view addSubview:self.joinChatroom2Btn];

    [self.joinChatroom1Btn mas_makeConstraints:^(MASConstraintMaker *make) {

        make.bottom.equalTo(self.view).offset(-RCDExtraBottomHeight - 40);
        make.left.equalTo(self.view).offset(10);
        make.height.offset(50);
        make.width.equalTo(self.joinChatroom2Btn);
    }];

    [self.joinChatroom2Btn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.bottom.width.height.equalTo(self.joinChatroom1Btn);
        make.left.equalTo(self.joinChatroom1Btn.mas_right).offset(10);
        make.right.equalTo(self.view).offset(-10);
    }];
}

#pragma mark - Target Action
- (void)joinChatroom:(UIButton *)sender {
    NSString *roomId = @"kvchatroom1";
    if (sender.tag == 100002) {
        roomId = @"kvchatroom2";
    }

    [[RCIMClient sharedRCIMClient] joinChatRoom:roomId
        messageCount:20
        success:^{
            dispatch_async(dispatch_get_main_queue(), ^{
                RCDDebugChatroomViewController *vc = [[RCDDebugChatroomViewController alloc] init];
                vc.roomId = roomId;
                [self.navigationController pushViewController:vc animated:YES];
            });
        }
        error:^(RCErrorCode status) {
            dispatch_async(dispatch_get_main_queue(), ^{
                RCDDebugChatroomViewController *vc = [[RCDDebugChatroomViewController alloc] init];
                vc.roomId = roomId;
                [self.navigationController pushViewController:vc animated:YES];
                NSLog(@"debug 测试聊天室状态存储，加入聊天室失败：%ld", (long)status);
            });
        }];
}

#pragma mark - Getter && Setter
- (UIButton *)joinChatroom1Btn {
    if (!_joinChatroom1Btn) {
        _joinChatroom1Btn = [[UIButton alloc] init];
        _joinChatroom1Btn.tag = 100001;
        [_joinChatroom1Btn setTitle:@"加入聊天室1" forState:UIControlStateNormal];
        [_joinChatroom1Btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        [_joinChatroom1Btn addTarget:self
                              action:@selector(joinChatroom:)
                    forControlEvents:(UIControlEventTouchUpInside)];
    }
    return _joinChatroom1Btn;
}

- (UIButton *)joinChatroom2Btn {
    if (!_joinChatroom2Btn) {
        _joinChatroom2Btn = [[UIButton alloc] init];
        _joinChatroom2Btn.tag = 100002;
        [_joinChatroom2Btn setTitle:@"加入聊天室2" forState:UIControlStateNormal];
        [_joinChatroom2Btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        [_joinChatroom2Btn addTarget:self
                              action:@selector(joinChatroom:)
                    forControlEvents:(UIControlEventTouchUpInside)];
    }
    return _joinChatroom2Btn;
}

@end


In this post, I’m going to build a simple Clojure Web app and deploy it to a Jetty application server running on Engine Yard’s cloud application management platform. In a follow-up post, I expand my Web app and show how to integrate it with a MySQL database server running in the Engine Yard environment.

To build my web app, I’m going to use the most common tools in the Clojure web stack:

Ring, a thin abstraction on top of HTTP request and response handling, and

Compojure, a small routing library for working with Ring.

Ring and Compojure are built on and interoperate with, the Java HTTP Servlet (API), so applications built with them can be deployed on any servlet container, such as Jetty or Tomcat.

In you already have a Clojure application, to deploy with Engine Yard, please jump to the packaging section.

If you are new to Clojure Web application development, read on.

What is Clojure?

The description at Clojure.org captures the essence of Clojure as a dynamic, functional language with a solid runtime foundation on the Java Virtual Machine:

Clojure is a dynamic programming language that targets the Java Virtual Machine (and the CLR, and JavaScript). It is designed to be a general-purpose language, combining the approachability and interactive development of a scripting language with an efficient and robust infrastructure for multithreaded programming. Clojure is a compiled language - it compiles directly to JVM bytecode, yet remains completely dynamic. Every feature supported by Clojure is supported at runtime. Clojure provides easy access to the Java frameworks, with optional type hints and type inference, to ensure that calls to Java can avoid reflection.

Clojure is a dialect of Lisp, and shares with Lisp the code-as-data philosophy and a powerful macro system. Clojure is predominantly a functional programming language, and features a rich set of immutable, persistent data structures. When mutable state is needed, Clojure offers a software transactional memory system and reactive Agent system that ensure clean, correct, multithreaded designs.

What is Engine Yard?

Engine yard offers a cloud application management platform for Ruby, PHP, Node. and Java applications. Since we’re going to use it with a JVM language, how does Engine Yard’s Java deployment work?

When you create a Java application environment with Engine Yard, the application server is a cluster of Java stack instances created and provisioned by Engine Yard in virtual machines running in the cloud. Each server instance is an Ubuntu server with a Jetty or Tomcat server running in a Java Virtual Machine. You upload a .war file with class files compiled from your Java (or in this case, Clojure, code), including its dependent libraries, and Engine Yard deploys it to your Jetty or Tomcat app servers.

This post won’t teach you how to program in Clojure, or how to get the most from the Ring and Compojure libraries, or even scratch the surface of using Leiningen. I’d recommend Dmitri Sotnikov‘s excellent book Web Development with Clojure as a comprehensive introduction to these topics. The guestbook app in Dmitri‘s book is definitely the inspiration for the todo list app in this blog post series.

But, this post will give you a flavor of each of these topics and show you how to package and deploy your Clojure web app onto a cloud platform. That said, let’s jump in.

Prerequisites

You need:

A Web application using the Ring and Compojure libraries. We’ll build a simple one from scratch, if you don’t have one already built.

Your application must use Leiningen because we are going to package the app and all its dependencies into a war file with lein-ring commands.

commands. An Engine Yard account. Sign up here.

A Java 7 JVM (Get the JDK - it’s got all the dev tools)

Steps

The steps we’ll go through are:

Create the todoclj project. If you are starting with a Clojure app already built, jump to the packaging in Step 2. Package the project as a .war file Create a Java application environment using Engine Yard and deploy the .war file Test the application

Create the todoclj project.

We’re going to use Leiningen to manage our project. Leiningen allows us to create a project skeleton, build, test, package into a WAR file, and even run it’s own test server. I think it also makes coffee, but I haven’t found that option yet. Think of Leiningen as Maven for Clojure (but not half as annoying). Leiningen has a system of templates that allow for different application types to be created with the lein new command. We’re going to use the Compojure template to create a starter web app that will contain the structure we need.

Assuming we’ve got Leiningen installed as per the README, we just do this:

~/projects $ lein --version

Leiningen 2.3.4 on Java 1.7.0_40 Java HotSpot ( TM ) 64-Bit Server VM

~/projects $ lein new compojure-app todoclj

Retrieving compojure-app/lein-template/0.4.1/lein-template-0.4.1.pom from clojars

Retrieving compojure-app/lein-template/0.4.1/lein-template-0.4.1.jar from clojars

Generating a lovely new Compojure project named todoclj…

In this post, we’re going to walk through the skeleton code that the Leiningen template for Compojure creates, to get to know Clojure, Leiningen, Ring and Compojure a little.

Like Rails, Grails, Play and many other productive frameworks or project environments, Leiningen produces a runnable skeleton. So, now just do this to compile the generated code, start an embedded Jetty app server with the code deployed, and open a browser window pointing to your app’s homepage:

~/projects/todoclj $ lein ring server

Compiling todoclj.handler

Compiling todoclj.repl

Compiling todoclj.routes.home

Compiling todoclj.views.layout

todoclj is starting

2014-04-01 13:10:11.107:INFO:oejs.Server:jetty-7.6.8.v20121106

2014-04-01 13:10:11.173:INFO:oejs.AbstractConnector:Started SelectChannelConnector@0.0.0.0:3000

Started server on port 3000

Fitting Leiningen, Ring and Compojure together

Because Leiningen is so central to Clojure project workflow, its tutorial is essential reading. Leiningen has also helpfully included that full (markdown formatted) tutorial as part of its help. If you do this:

~/projects/todoclj $ lein help tutorial > ~/leintutorial.md

And now view the leintutorial.md file in your favourite markdown reader, such as Mou, Marked, or Draft.

The Compojure app template creates a leiningen project with this layout:

~/projects/todoclj $ find .

.

./.gitignore

./.lein-repl-history

./project.clj

./README.md

./resources

./resources/public

./resources/public/css

./resources/public/css/screen.css

./resources/public/img

./resources/public/js

./src

./src/todoclj

./src/todoclj/handler.clj

./src/todoclj/models

./src/todoclj/repl.clj

./src/todoclj/routes

./src/todoclj/routes/home.clj

./src/todoclj/views

./src/todoclj/views/layout.clj

./test

./test/todoclj

./test/todoclj/test

./test/todoclj/test/handler.clj

In the file layout for the entire todoclj project above, you see src directories for things you find in most Web applications, whether they are MVC-style or not: models, routes, views and in this Leiningen project, also handler.clj and repl.clj files.

What does Ring add? The project wiki for Ring, defines it clearly, as:

Ring is a low-level interface and library for building web applications in the Clojure programming language. It is similar to the Ruby Rack library, the WSGI in Python, or the Java Servlet specification.

The fundamental concept in Ring is a handler, which describes what to do with HTTP requests and responses. The Ring handler (e.g., todoclj.handler/app in the one generated in the ./src/handler.clj file) is just a function (sometimes referred to as ‘middleware’) that maps the request to the response, and is the entry point for the application. Compojure, meanwhile, manages routes.

Leiningen and Ring provide our project with a useful REPL (read-evaluate-print-loop), typical in any dynamic language environment for interactively testing code easily. So when we issue the command:

~/projects/todoclj $ lein repl

Compiling todoclj.handler

Compiling todoclj.repl

Compiling todoclj.routes.home

Compiling todoclj.views.layout

nREPL server started on port 51974 on host 127.0.0.1

REPL-y 0.3.0

Clojure 1.5.1

Docs: ( doc function -name-here )

( find-doc "part-of-name-here" )

Source: ( source function -name-here )

Javadoc: ( javadoc java-object-or-class-here )

Exit: Control+D or ( exit ) or ( quit )

Results: Stored in vars * 1, * 2, * 3, an exception in * e

Leiningen pulls down all the dependencies (from Clojars) and compiles all the Clojure source code in the project. We are now executing in a shell environment in the project’s namespace. So we can, for example, do this:

user=> ( use 'todoclj.repl )

nil

user=> ( start-server )

todoclj is starting

2014-03-31 10 :56:29.802:INFO:oejs.Server:jetty-7.6.8.v20121106

2014-03-31 10 :56:29.849:INFO:oejs.AbstractConnector:Started SelectChannelConnector @ 0.0 .0.0 :8080

Started server on port 8080

You can view the site at http ://localhost:8080

nil

user=>

If you look at the todoclj/src/repl.clj source (listed below) we pulled into our REPL environment, we have just used , or executed, we can see the ring imports in the namespace defintion, and the implementation of start-server which we executed above, it kicks off a local jetty server, listening on port 3000 for HTTP requests and opens a browser window at the root context of the todoclj application.

( ns todoclj.repl

( :use todoclj.handler

ring.server.standalone

[ ring.middleware file-info file ]))

( defn start-server

"used for starting the server in development mode from REPL"

[ & [ port ]]

( let [ port ( if port ( Integer/parseInt port ) 8080 )]

( reset! server

( serve ( get-handler )

{ :port port

:init init

:auto-reload? true

:destroy destroy

:join true }))

( println ( str "You can view the site at http://localhost:" port ))))

The todoclj/project.clj file generated by the Compojure template looks like this:

( defproject todoclj "0.1.0-SNAPSHOT"

:description "todo demo app"

:url "http://example.com/FIXME"

:dependencies [[ org.clojure/clojure "1.5.1" ]

[ compojure "1.1.6" ]

[ hiccup "1.0.5" ]

[ ring-server "0.3.1" ]]

:plugins [[ lein-ring "0.8.10" ]]

:ring { :handler todoclj.handler/app

:init todoclj.handler/init

:destroy todoclj.handler/destroy }

:aot :all

:profiles

{ :production

{ :ring

{ :open-browser? false, :stacktraces? false, :auto-reload? false }}

:dev

{ :dependencies [[ ring-mock "0.1.5" ] [ ring/ring-devel "1.2.1" ]]}})

The :dependencies array in the project.clj tells us that, apart from clojure itself, we are depending on Compojure, Hiccup (a front-end templating library) and ring-server.

So, as we did before right after we generated the project, when you type:

~/projects/todoclj $ lein ring server

the :ring map in section of the project (i.e., the 3 lines below) is examined by the Leiningen executor and passes the :handler function to the Clojure runtime to execute the todolj.handler/app function.

:ring { :handler todoclj.handler/app

:init todoclj.handler/init

:destroy todoclj.handler/destroy }

So, looking at that todoclj/src/handler.clj file, we see definitions for that app handler function, and the init and destroy functions also included in the Ring map. As I mentioned earlier, Compojure builds on Ring to add routes to a Ring application. Routes return Ring handler functions for different HTTP commands, and this is what is going on in the app function below:

( ns todoclj.handler

( :require [ compojure.core :refer [ defroutes routes ]]

[ ring.middleware.resource :refer [ wrap-resource ]]

[ ring.middleware.file-info :refer [ wrap-file-info ]]

[ hiccup.middleware :refer [ wrap-base-url ]]

[ compojure.handler :as handler ]

[ compojure.route :as route ]

[ todoclj.routes.home :refer [ home-routes ]]))

( defn init []

( println "todoclj is starting" ))

( defn destroy []

( println "todoclj is shutting down" ))

( defroutes app-routes

( route/resources "/" )

( route/not-found "Not Found" ))

( def app

( -> ( routes home-routes app-routes )

( handler/site )

( wrap-base-url )))

We see the -> thread-first macro which is useful syntactic sugar, making Clojure heavily nested code more readable. In the app function above, the -> is threading the Compojure site function and wrap-base-url . The Compojure site function sets up Ring middleware for standard website aspects (such as sessions, cookies, multi-part params, etc.)

To define the routes for the :todoclj.routes.home namespace, we need the defroutes function from Compojure. Each route represents a URI to which your application responds, such as “/”, starting with the HTTP verb, such as GET or POST, followed by the parameters (none here) and the body (none here either).

( ns todoclj.routes.home

( :require [ compojure.core :refer :all ]

[ todoclj.views.layout :as layout ]))

( defn home []

( layout/common [ :h1 "Hello World!" ]))

( defroutes home-routes

( GET "/" [] ( home )))

In this route for a GET on the root web context “/”, control is being passed to the home function which is calling the common layout, then using hiccup to add the :h1 "Hello World" . You can see the common layout sets up the head, page, style and includes the body.

( ns todoclj.views.layout

( :require [ hiccup.page :refer [ html5 include-css ]]))

( defn common [ & body ]

( html5

[ :head

[ :title "Welcome to todoclj" ]

( include-css "/css/screen.css" )]

[ :body body ]))

In the followup post of this series, we’ll see how to use more of hiccup to flesh out this todo list app layout.

Package

Step: for deployment

As I mentioned above, Engine Yard doesn’t distinguish between JVM languages. It just deploys a .war file to a running Java web container (jetty or tomcat).

To build a WAR (or Web application ARchive) file using Leiningen, run:

~/projects/todoclj $ lein ring uberwar

Created /Users/richardwatson/projects/todoclj/target/todoclj-0.1.0-SNAPSHOT-standalone.war

You can then easily deploy the resulting WAR to Tomcat, Jetty or any other Java application server (just copy it to the webapps directory). We’re going to deploy this onto an environment we create on Engine Yard.

Handy Tip

A good rule of thumb for working with the JVM and Java environment in Engine Yard is: if an app and its dependencies can be packaged into a .war file and it deploys and runs fine on a local Tomcat or Jetty server, it should work fine on Engine Yard. But, of course, you can’t guess at (or hardcode) information such as hostnames, open ports, or arbitrary file access like you can on your local development environment. Any server-specific information like this that Engine Yard configures as it creates the environment will be exposed to your application through the Jetty (or Tomcat) Java web container (e.g., the JDBC database as JNDI [the next blog in the series will discuss this], other things like Cache server hostnames using ).

Step: Create a Java “application environment” on Engine Yard and deploy the app

Next we’ll walk through setting up an environment for deploying the Clojure app to Engine Yard. The steps we’ll go through to do this are:

Create a project and environment, choose an infrastructure provider, and select a blueprint Customize the blueprint, selecting choices for language, database and application server ‘Update’ the clusters of servers Deploy the war file using the UI

We’ll select a blueprint that matches our use case from Engine Yard library Blueprints are complete descriptions of the application environment.

1. Create a project, choose an infrastructure provider, environment and select a blueprint

The first step is simply to login to your Engine Yard account.

When you are logged in, you are now in the organization page. In your organization, create a project, and an initial environment. For that environment, choose your cloud infrastructure provider (Amazon Web Services or Microsoft Azure). Next, select a blueprint. This is a description of an application’s environment. For our app, we’ll select a blueprint with 3 servers, one each for app server, load-balancer and database.

2. Customize the blueprint by selecting, language, application server and database

We will can now customize the blueprint with what we need for our Clojure application. Having picked our language (Java), we can change the default server locations, pick an alternate supported database or application server. We’ll go with Jetty, MySQL and servers in the AWS US-WEST-1 region.

Engine Yard builds and orchestrates the deployment of an application environment from its blueprint. This is called ‘updating’ in Engine Yard terminology.

Once the update has finished, each of the clusters of servers is up and running:

one with haproxy and nginx to load balance between app server instances (should I add more) and to terminate SSL connections

one server with a Jetty web container running in a Java 7 VM, and

the database server with a running instance of mysql.

These healthy, running servers are indicated in the image below, by the green tick symbols in the server slots or placeholders in the environment.

4. Deploy the war file using the UI

The next step is to deploy the .war file we built with lein ring uberwar . Hitting the green “DEPLOY” button on the application cluster, Engine Yard provides a file selector, or you can drag and drop the .war file in the dialog box.

The deployer uploads the .war file, deploys it to the Jetty server, and the UI tells me the app is deployed.

Test your deployment:

The web module configured by the .war file will be deployed to the root context of the Java web container. To test the application, click the “VISIT YOUR APPLICATION” link in the top right of the application server cluster details page (above).

This link doesn’t point to port 80 (or 8080) on the application server as it would have to test your application on a local development environment. These servers in your cloud environment are all on the public internet (since I haven’t used a VPC). Engine Yard configures firewall rules and ports in this environment so that only explicitly required connections can be made to them and between them. The only externally facing open HTTP port is 80 on the Load balancer, which forwards HTTP requests for the app to the app server.

So, when we click “VISIT YOUR APPLICATION”, the hostname opened is that of the load-balancer. And, by doing that, we’re GETing the root context of my deployed web app, which hits the GET "/" [] home route in our Compojure config.

**So, um, ok, another todo list app? ;) What's the point?** Let's think about why you would do what we've just done.

## Why would you build web applications using Clojure?

* I doubt if traffic to my todo list app is going to hockey stick, but handling web traffic on a real high volume site requires the application to manage concurrent processing of requests in some way. Different languages take different approaches to this. Clojure is built for [concurrency](http://clojure.org/concurrent_programming) by making the core data structures immutable (therefore sharable across threads). Writing real web apps based on purely immutable data structures is tricky, if not downright impossible, so Clojure also provides consistent, easy state changes, using, according to [Clojure.org](http://clojure.org/concurrent_programming):

> The software transactional memory system (STM), exposed through dosync, ref, set, alter, et al, supports sharing changing state between threads in a synchronous and coordinated manner. The agent system supports sharing changing state between threads in an asynchronous and independent manner. The atoms system supports sharing changing state between threads in a synchronous and independent manner. The dynamic var system, exposed through def, binding, et al, supports isolating changing state within threads.

* The Clojure web stack is based on libraries, not frameworks. This approach offers plenty of freedom to mix and match libraries that perform various functions for web apps. This contrasts with the ‘kitchen-sink’ approach of a framework, such as Spring in Java, or Rails with Ruby. Clojure developers appreciate this *just-enough* approach that minimizes the code base for a project.

* [Clojure offers](http://clojure.org/rationale) expressiveness rivaling other dynamic languages like Ruby and Python, while [interoperating easily](http://clojure.org/java_interop) with Java libraries and the rest of the Java ecosystem. In a Clojure application, you can invoke a public Java method, instantiate a class, or get the value of a public field using the special operator `.` also known as dot or host. Some of the simplest examples, to give you a flavor:

clj

(import 'java.util.Date) ; import a single class

(def today (new Date)) ;

(def today (Date.)) ; alternatively use the dot operator

(def now (System/currentTimeMillis)) ; call a static method

(. foo bar 7 4) ; call the method bar of the instance/class foo with arguments 7 and 4

(. alice bob) ; return the value of public field bob of the instance/class alice

Clojure is used by many innovative technology organizations for building full applications. In particular, SoundCloud and Engine Yard’s CI partners, CircleCI are doing interesting , mission critical and scalable things with Clojure.

Other Clojure Web App Approaches

Rather than package up the Leiningen project into a .war file, another popular approach for deploying Web apps in Clojure is to start jetty programmatically using ring.adapter.jetty/run-jetty and passing in Ring handlers. For people who don’t have significant customizations to make, then running “lein ring server-headless” is very typical.

Balancing the hype: Some bad press recently

Like any developing language eco-system, Clojure suffers from growing pains, that manifest themselves, for example, in the lack of out of the box bullet-proof security.

Why would you deploy Clojure code onto Engine Yard?

Primarily because it’s easy. If it works in a local Tomcat or Jetty server, will a local MySQL or PostgreSQL database, it will probably work on Engine Yard unchanged. No need to change your code, or build process.

Your Java components are maintained and kept up-to-date by Engine Yard. This include security updates to Java, which are now issued at least quarterly by Oracle, and Jetty/Tomcat updates, as well as JDBC library updates - all tested for compatibility by Engine Yard stack engineers.

You can scale up by adding app servers to your cluster and the load balancer will round robin requests to each of your app servers (by default, other behavior is configurable).

You can SSH into the server with the Jetty or Tomcat server to recover logs, customize logging, or reconfigure the app server

Engine Yard will tune the JVM heap parameters according to the available memory on the VM you use](get docs reference

You can choose to locate these app servers in different availability zones, different regions or even different cloud infrastructures (we currently support AWS and Microsoft Azure).

Price and performance transparency: The virtual machine in which your JVM is running is not a container, or a slice of a larger VM. It is a full VM, and it’s all yours. For example, if you choose and pay for an EC2 medium, you can dedicate as much of the the 3.75Gb memory to the JVM as you wish.

Community Testing

Testing with developer community groups has always been important to Engine Yard. I want to thank Norman Richards and the Austin Clojure meetup for testing Engine Yard as part of their hack day in January. Thanks also to Norman for his talk, slides here which were really helpful for me understanding the state of the art in Clojure Web Apps.

The Irish Clojure user group meet at the Engine Yard offices in Dublin on 9th April for a functional kata session. I’ll be there helping people deploy their Clojure web apps onto Engine Yard.

Stay tuned for a follow-up post, in which I expand my skeleton todo list app with a way to add tasks, a data model, and show how to integrate it with a MySQL database server running in the Engine Yard environment.