/*********************************************************************/
/*  UDF to compute the orientation of a rotating valve, based on a 
    specified rotational speed.
    
    Christoph Hiemcke, Fluent Inc.,             12 Feb 2004          

        butterlfy_flex_UDF  = name shown in Fluent GUI
                        dt  = thread
                    cg_vel  = cg velocity (global)
                  cg_omega  = angular velocity (global)
                      time  = current time
                     dtime  = time step
                                                                     */
/*********************************************************************/
#include "udf.h"

#define  omega      1.0          /* rotational speed, rad/sec        */
#define  R          0.109        /* radius of the arc, meters        */

DEFINE_CG_MOTION(butterfly_flex_UDF, dt, cg_vel, cg_omega, time, dtime)
{
  cg_vel[0] = 0.0;
  cg_vel[1] = 0.0;
  cg_vel[2] = 0.0;

  cg_omega[0] = 0.0;
  cg_omega[1] = 0.0;
  cg_omega[2] = omega;
}

/***********************************************************************/
/*  
    UDF to define a horizontal plane.  One will thus be able to project 
	boundary nodes upon this plane.

    Christoph Hiemcke, Fluent Inc.,             12 Feb 2004            */
/***********************************************************************/

DEFINE_GEOM(plane, domain, dt, position)
{
	position[1] = R;
}

/***********************************************************************/
/*  
    UDF to define a wall that is initially a circular arc, but then 
	oscillates sinusoidally with time.  

    alpha = angle that dictates the motion of the arc;
	theta = angle that corresponds to the position of the rotating valve

    Christoph Hiemcke, Fluent Inc.,             13 Feb 2004            */
/***********************************************************************/

DEFINE_GRID_MOTION(moving_arc, domain, dt, time, dtime)
{
  Thread *tf = DT_THREAD (dt);
  face_t f;
  Node *node_p;
  real alpha, theta, x, ymag, yfull, y;
  int n;
  
/* Set/activate the deforming flag on adjacent cell zone, which      */
/* means that the cells adjacent to the deforming wall will also be  */
/* deformed, in order to avoid skewness.                             */
  SET_DEFORMING_THREAD_FLAG (THREAD_T0 (tf));

/* Compute the angles:                                               */
  alpha = omega * CURRENT_TIME;
  theta = 2.0 * alpha + 3.0 * M_PI / 2.0;
  
/* Loop over the deforming boundary zone's faces;                    */
/* inner loop loops over all nodes of a given face;                  */
/* Thus, since one node can belong to several faces, one must guard  */
/* against operating on a given node more than once:                 */

  begin_f_loop (f, tf)
    {
      f_node_loop (f, tf, n)
        {
          node_p = F_NODE (f, tf, n);

          /* Update the current node only if it has not been         */
		  /* previously visited:                                     */
          if (NODE_POS_NEED_UPDATE (node_p))
            {
              /* Set flag to indicate that the current node's        */
			  /* position has been updated, so that it will not be   */
              /* updated during a future pass through the loop:      */
              NODE_POS_UPDATED (node_p);

			  x     = NODE_X (node_p);
			  ymag  = sqrt (R*R - x*x) + 0.03;
			  yfull = ymag - 0.1;
			  y     = - 0.1 + yfull * sin(theta);
			  NODE_Y (node_p) = y;
            }
        }
    }
  end_f_loop (f, tf);
}
/*********************************************************************/
/*							                                         */
/*	End of the UDF.   		                                         */
/*							                                         */
/*********************************************************************/