void ReadGlobalTimeCycleData()
{

   int i;
   char *cycle_names;
   char *cycle_name;
   
   char key[IDB_MAX_KEY_LEN];
   char *id_names;
   
   NameArray id_na;

   int id;
   
   char *interval_name;

   /* Get the time cycling information */
   cycle_names = GetString("Cycle.Names");
   GlobalsCycleNames = NA_NewNameArray(cycle_names);

   GlobalsNumCycles = NA_Sizeof(GlobalsCycleNames);

   GlobalsIntervalDivisions  = ctalloc(int,   GlobalsNumCycles);
   GlobalsIntervals          = ctalloc(int *, GlobalsNumCycles);
   GlobalsIntervalNames      = ctalloc(NameArray, GlobalsNumCycles);
   GlobalsRepeatCounts       = ctalloc(int,   GlobalsNumCycles);

   for(i = 0; i < GlobalsNumCycles; i++)
   {
      cycle_name = NA_IndexToName(GlobalsCycleNames, i);

      sprintf(key, "Cycle.%s.Names", cycle_name); 
      id_names = GetString(key);

      id_na = NA_NewNameArray(id_names);
      GlobalsIntervalNames[i] = id_na;

      GlobalsIntervalDivisions[i] = NA_Sizeof(id_na);

      GlobalsIntervals[i] = ctalloc(int, GlobalsIntervalDivisions[i]);

      sprintf(key, "Cycle.%s.Repeat", cycle_name); 
      GlobalsRepeatCounts[i] = GetInt(key);

      for(id = 0; id < GlobalsIntervalDivisions[i]; id++)
      {
	 interval_name = NA_IndexToName(id_na, id);

	 sprintf(key, "Cycle.%s.%s.Length", cycle_name, interval_name);
	 GlobalsIntervals[i][id] = GetInt(key);
      }
   }
}
PFModule  *SelectTimeStepNewPublicXtra()
{

   PFModule      *this_module   = ThisPFModule;
   PublicXtra    *public_xtra;

   Type0            *dummy0;
   Type1            *dummy1;

   char *switch_name;

   NameArray type_na;

   type_na = NA_NewNameArray("Constant Growth");

   public_xtra = ctalloc(PublicXtra, 1);

   switch_name = GetString("TimeStep.Type");
   public_xtra -> type = NA_NameToIndex(type_na, switch_name);
   
   switch((public_xtra -> type))
   {
      case 0:
      {
	 dummy0 = ctalloc(Type0, 1);

	 dummy0 -> step = GetDouble("TimeStep.Value");
	 
	 (public_xtra -> data) = (void *) dummy0;

	 break;
      }
         
      case 1:
      {
	 dummy1 = ctalloc(Type1, 1);

	 dummy1 -> initial_step = GetDouble("TimeStep.InitialStep");
	 dummy1 -> factor = GetDouble("TimeStep.GrowthFactor");
	 dummy1 -> max_step = GetDouble("TimeStep.MaxStep");
	 dummy1 -> min_step = GetDouble("TimeStep.MinStep");

	 (public_xtra -> data) = (void *) dummy1;
	 
	 break;
      }

      default:
      {
	 InputError("Error: invalid type <%s> for key <%s>\n",
		    switch_name, "TimeStep.Type");
      }
   }
   

   NA_FreeNameArray(type_na);

   PFModulePublicXtra(this_module) = public_xtra;
   return this_module;
}
PFModule  *KinsolNonlinSolverNewPublicXtra()
{
  PFModule      *this_module = ThisPFModule;
  PublicXtra    *public_xtra;

  char          *switch_name;
  char key[IDB_MAX_KEY_LEN];
  int switch_value;

  NameArray switch_na;
  NameArray verbosity_switch_na;
  NameArray eta_switch_na;
  NameArray globalization_switch_na;
  NameArray precond_switch_na;

  public_xtra = ctalloc(PublicXtra, 1);

  sprintf(key, "Solver.Nonlinear.ResidualTol");
  (public_xtra->residual_tol) = GetDoubleDefault(key, 1e-7);
  sprintf(key, "Solver.Nonlinear.StepTol");
  (public_xtra->step_tol) = GetDoubleDefault(key, 1e-7);

  sprintf(key, "Solver.Nonlinear.MaxIter");
  (public_xtra->max_iter) = GetIntDefault(key, 15);
  sprintf(key, "Solver.Linear.KrylovDimension");
  (public_xtra->krylov_dimension) = GetIntDefault(key, 10);
  sprintf(key, "Solver.Linear.MaxRestarts");
  (public_xtra->max_restarts) = GetIntDefault(key, 0);

  verbosity_switch_na = NA_NewNameArray("NoVerbosity LowVerbosity "
                                        "NormalVerbosity HighVerbosity");
  sprintf(key, "Solver.Nonlinear.PrintFlag");
  switch_name = GetStringDefault(key, "LowVerbosity");
  (public_xtra->print_flag) = NA_NameToIndex(verbosity_switch_na,
                                             switch_name);
  NA_FreeNameArray(verbosity_switch_na);

  eta_switch_na = NA_NewNameArray("EtaConstant Walker1 Walker2");
  sprintf(key, "Solver.Nonlinear.EtaChoice");
  switch_name = GetStringDefault(key, "Walker2");
  switch_value = NA_NameToIndex(eta_switch_na, switch_name);
  switch (switch_value)
  {
    case 0:
    {
      public_xtra->eta_choice = ETACONSTANT;
      public_xtra->eta_value
        = GetDoubleDefault("Solver.Nonlinear.EtaValue", 1e-4);
      public_xtra->eta_alpha = 0.0;
      public_xtra->eta_gamma = 0.0;
      break;
    }

    case 1:
    {
      public_xtra->eta_choice = ETACHOICE1;
      public_xtra->eta_alpha = 0.0;
      public_xtra->eta_gamma = 0.0;
      break;
    }

    case 2:
    {
      public_xtra->eta_choice = ETACHOICE2;
      public_xtra->eta_alpha
        = GetDoubleDefault("Solver.Nonlinear.EtaAlpha", 2.0);
      public_xtra->eta_gamma
        = GetDoubleDefault("Solver.Nonlinear.EtaGamma", 0.9);
      public_xtra->eta_value = 0.0;
      break;
    }

    default:
    {
      InputError("Error: Invalid value <%s> for key <%s>\n", switch_name,
                 key);
    }
  }
  NA_FreeNameArray(eta_switch_na);

  switch_na = NA_NewNameArray("False True");
  sprintf(key, "Solver.Nonlinear.UseJacobian");
  switch_name = GetStringDefault(key, "False");
  switch_value = NA_NameToIndex(switch_na, switch_name);
  switch (switch_value)
  {
    case 0:
    {
      (public_xtra->matvec) = NULL;
      break;
    }

    case 1:
    {
      (public_xtra->matvec) = KINSolMatVec;
      break;
    }

    default:
    {
      InputError("Error: Invalid value <%s> for key <%s>\n", switch_name,
                 key);
    }
  }
  NA_FreeNameArray(switch_na);

  sprintf(key, "Solver.Nonlinear.DerivativeEpsilon");
  (public_xtra->derivative_epsilon) = GetDoubleDefault(key, 1e-7);

  globalization_switch_na = NA_NewNameArray("InexactNewton LineSearch");
  sprintf(key, "Solver.Nonlinear.Globalization");
  switch_name = GetStringDefault(key, "LineSearch");
  switch_value = NA_NameToIndex(globalization_switch_na, switch_name);
  switch (switch_value)
  {
    case 0:
    {
      (public_xtra->globalization) = INEXACT_NEWTON;
      break;
    }

    case 1:
    {
      (public_xtra->globalization) = LINESEARCH;
      break;
    }

    default:
    {
      InputError("Error: Invalid value <%s> for key <%s>\n", switch_name,
                 key);
    }
  }
  NA_FreeNameArray(globalization_switch_na);

  precond_switch_na = NA_NewNameArray("NoPC MGSemi SMG PFMG PFMGOctree");
  sprintf(key, "Solver.Linear.Preconditioner");
  switch_name = GetStringDefault(key, "MGSemi");
  switch_value = NA_NameToIndex(precond_switch_na, switch_name);
  if (switch_value == 0)
  {
    (public_xtra->precond) = NULL;
    (public_xtra->pcinit) = NULL;
    (public_xtra->pcsolve) = NULL;
  }
  else if (switch_value > 0)
  {
    (public_xtra->precond) = PFModuleNewModuleType(
                                                   KinsolPCNewPublicXtraInvoke,
                                                   KinsolPC,
                                                   (key, switch_name));
    (public_xtra->pcinit) = (KINSpgmrPrecondFn)KINSolInitPC;
    (public_xtra->pcsolve) = (KINSpgmrPrecondSolveFn)KINSolCallPC;
  }
  else
  {
    InputError("Error: Invalid value <%s> for key <%s>\n", switch_name,
               key);
  }
  NA_FreeNameArray(precond_switch_na);

  public_xtra->nl_function_eval = PFModuleNewModule(NlFunctionEval, ());
  public_xtra->neq = ((public_xtra->max_restarts) + 1)
                     * (public_xtra->krylov_dimension);

  if (public_xtra->matvec != NULL)
    public_xtra->richards_jacobian_eval =
      PFModuleNewModuleType(
                            RichardsJacobianEvalNewPublicXtraInvoke,
                            RichardsJacobianEval,
                            ("Solver.Nonlinear.Jacobian"));
  else
    public_xtra->richards_jacobian_eval = NULL;

  (public_xtra->time_index) = RegisterTiming("KINSol");

  PFModulePublicXtra(this_module) = public_xtra;

  return this_module;
}