void
update_target_point_positions(
			      tbox::Pointer<hier::PatchHierarchy<NDIM> > hierarchy,
			      LDataManager* const l_data_manager,
			      const double current_time,
			      const double dt)
{
  const int finest_ln = hierarchy->getFinestLevelNumber();

  static const double pi = 4*atan(1);
  static const double V = 0.2; //velocity of the wing during translation (meters/sec)
  
  	////////////////////////////////////////////////////////////////////////////////////////
	// these parameters require modification to match the desired geometry and motion
	
    static const double L1 = 1; // length of computational domain (meters)
    static const int N1 = 512; // number of cartesian grid meshwidths at the finest level of the AMR grid
	static const double diameter = 0.1;			// diameter of tube
	static const double R2 = 0.1;				// distance from middle of domain to inner wall
	static const double R1 = R2+diameter;		// distance from middle of domain to outer wall
	static const double pamp = 0.8;				//percent occlusion of the tube
	static const double amp = pamp*diameter/2.0;	//amplitude of contraction of each piece of the actuator
	static const double freq = 1.0;
 
 ////////////////////////////////////////////////////////////////////////////////////////////////

  // Find out the Lagrangian index ranges.
  const std::pair<int,int>& actuator_top_idxs = l_data_manager->getLagrangianStructureIndexRange(0, finest_ln);
  const std::pair<int,int>& actuator_bot_idxs = l_data_manager->getLagrangianStructureIndexRange(1, finest_ln);
	
  // Get the LMesh (which we assume to be associated with the finest level of
  // the patch hierarchy).  Note that we currently need to update both "local"
  // and "ghost" node data.
  Pointer<LMesh> mesh = l_data_manager->getLMesh(finest_ln);
  vector<LNode*> nodes;
  nodes.insert(nodes.end(), mesh->getLocalNodes().begin(), mesh->getLocalNodes().end());
  nodes.insert(nodes.end(), mesh->getGhostNodes().begin(), mesh->getGhostNodes().end());

  // Update the target point positions in their associated target point force
  // specs.
  tbox::Pointer<hier::PatchLevel<NDIM> > level = hierarchy->getPatchLevel(finest_ln);
  for (vector<LNode*>::iterator it = nodes.begin(); it != nodes.end(); ++it)
    {
      LNode* node_idx = *it;
      IBTargetPointForceSpec* force_spec = node_idx->getNodeDataItem<IBTargetPointForceSpec>();
      if (force_spec == NULL) continue;  // skip to next node

      // Here we update the position of the target point.
      //
      // NOTES: lag_idx      is the "index" of the Lagrangian point (lag_idx = 0, 1, ..., N-1, where N is the number of Lagrangian points)
      //        X_target     is the target position of the target point
      //        X_target[0]  is the x component of the target position
      //        X_target[1]  is the y component of the target position
      //        X_target[2]  is the z component of the target position (for a 3D simulation)
      //
      // The target position is shifted to the left or right by the
      // increment dt*V

      const int lag_idx = node_idx->getLagrangianIndex();
      //Depending on the version of IBAMR, you need to select one of the ways of accessing target point positions. 
      //TinyVector<double,NDIM>& X_target = force_spec->getTargetPointPosition();
      //IBTK::Vector<double,NDIM>& X_target = force_spec->getTargetPointPosition();
      Point& X_target = force_spec->getTargetPointPosition();
	  
		//move the top piece
	    if (actuator_top_idxs.first <= lag_idx && lag_idx < actuator_top_idxs.second)
	      {
				X_target[1] = -R2-V*dt;  //(amp/2)*(1+sin(2*pi*freq*current_time - pi/2));
	      }
		//move the bottom piece
		if (actuator_bot_idxs.first <= lag_idx && lag_idx < actuator_bot_idxs.second)
	      {
				X_target[1] = -R1+V*dt; //(amp/2)*(1+sin(2*pi*freq*current_time - pi/2));
	      }
      
    }
  return;
}// update_target_point_positions