Wednesday 18 August 2021

Computational Fluid Dynamics Simulation of a Swimming Fish (Includes UDF)

      This post is about the simulation of a swimming fish. The fish body is made of NACA 0020 and 0015 aero-foils (air-foils). The fluke is made of NACA 0025 aero-foil (air-foil), as shown in Fig. 1. the CAD files with computational domain modelled around the fish is available here.



Fig. 1, The generic fish CAD model

      The motion of the fish's body is achieved using a combination of two user-defined functions (UDF). The UDFs use DEFINE_GRID_MOTION script mentioned below, for the head/front portion. This is taken from the ANSYS Fluent software manual, available in its original form here. The original UDF is modified for present use as required. To move the mesh, dynamic mesh option within ANSYS Fluent is enabled; with smoothing and re-meshing options. The period of oscillation is kept at 2.0 s. The Reynolds number of flow is kept at 100,000; which is typical for a swimming fish.

/**********************************************************

 node motion based on simple beam deflection equation
 compiled UDF
 **********************************************************/
#include "udf.h"

DEFINE_GRID_MOTION(undulating_head,domain,dt,time,dtime)
{
  Thread *tf = DT_THREAD(dt);
  face_t f;
  Node *v;
  real NV_VEC(omega), NV_VEC(axis), NV_VEC(dx);
  real NV_VEC(origin), NV_VEC(rvec);
  real sign;
  int n;
  
  /* set deforming flag on adjacent cell zone */
  SET_DEFORMING_THREAD_FLAG(THREAD_T0(tf));

  sign = 0.15707963267948966192313216916398 * cos (3.1415926535897932384626433832795 * time);
  
  Message ("time = %f, omega = %f\n", time, sign);
  
  NV_S(omega, =, 0.0);
  NV_D(axis, =, 0.0, 1.0, 0.0);
  NV_D(origin, =, 0.7, 0.0, 0.0);
  
  begin_f_loop(f,tf)
    {
      f_node_loop(f,tf,n)
        {
          v = F_NODE(f,tf,n);

          /* update node if x position is greater than 0.02
             and that the current node has not been previously
             visited when looping through previous faces */
          if (NODE_X(v) > 0.05 && NODE_X(v) < 0.7 && NODE_POS_NEED_UPDATE (v))
            {
              /* indicate that node position has been update
                 so that it's not updated more than once */
              NODE_POS_UPDATED(v);

              omega[1] = sign * pow (NODE_X(v), 0.5);
              NV_VV(rvec, =, NODE_COORD(v), -, origin);
              NV_CROSS(dx, omega, rvec);
              NV_S(dx, *=, dtime);
              NV_V(NODE_COORD(v), +=, dx);
            }
        }
    }

  end_f_loop(f,tf);
}

      The computational mesh, as shown in Fig. 2, uses cut-cell method with inflation layers. The mesh has 2,633,133 cells. The near wall y+ is kept at 5. The Spalart-Allmaras turbulence model is used to model the turbulence. The second order upwind scheme is used to discretize the momentum and modified turbulent viscosity equations. The time-step for this study is kept at 100th/period of oscillation.


Fig. 2, The mesh and zoom in view of the trailing edge.

      The animation showing fish motion is shown in Fig. 3. Within Fig. 3, the left side showcases the velocity iso-surfaces coloured by pressure and the vorticity iso-surfaces coloured by velocity magnitude is shown on the right.


Fig. 3, The animation.

      Another animation showing the fish motion is shown in Fig.4. Within Fig. 4, the left side shows surface pressure while the right side shows pressure iso-surfaces coloured by vorticity.


Fig. 4, The animation.

      If you want to collaborate on the research projects related to turbo-machinery, aerodynamics, renewable energy, please reach out. Thank you very much for reading.