text: /******************************************************************************
   * Copyright 1998-2019 Lawrence Livermore National Security, LLC and other
   * HYPRE Project Developers. See the top-level COPYRIGHT file for details.
   *
   * SPDX-License-Identifier: (Apache-2.0 OR MIT)
   ******************************************************************************/
  
  /******************************************************************************
   *
   * ParAMG functions
   *
   *****************************************************************************/
  
  #include "_hypre_parcsr_ls.h"
  #include "par_amg.h"
  #ifdef HYPRE_USING_DSUPERLU
  #include <math.h>
  #include "superlu_ddefs.h"
  #endif
  /*--------------------------------------------------------------------------
   * hypre_BoomerAMGCreate
   *--------------------------------------------------------------------------*/
  
  void *
  hypre_BoomerAMGCreate()
  {
     hypre_ParAMGData  *amg_data;
  
     /* setup params */
     HYPRE_Int    max_levels;
     HYPRE_Int    max_coarse_size;
     HYPRE_Int    min_coarse_size;
     HYPRE_Int    coarsen_cut_factor;
     HYPRE_Real   strong_threshold;
     HYPRE_Real   strong_threshold_R;
     HYPRE_Real   filter_threshold_R;
     HYPRE_Int    Sabs;
     HYPRE_Real   max_row_sum;
     HYPRE_Real   trunc_factor;
     HYPRE_Real   agg_trunc_factor;
     HYPRE_Real   agg_P12_trunc_factor;
     HYPRE_Real   jacobi_trunc_threshold;
     HYPRE_Real   S_commpkg_switch;
     HYPRE_Real   CR_rate;
     HYPRE_Real   CR_strong_th;
     HYPRE_Real   A_drop_tol;
     HYPRE_Int    A_drop_type;
     HYPRE_Int    interp_type;
     HYPRE_Int    sep_weight;
     HYPRE_Int    coarsen_type;
     HYPRE_Int    measure_type;
     HYPRE_Int    setup_type;
     HYPRE_Int    P_max_elmts;
     HYPRE_Int    num_functions;
     HYPRE_Int    nodal, nodal_levels, nodal_diag;
     HYPRE_Int    num_paths;
     HYPRE_Int    agg_num_levels;
     HYPRE_Int    agg_interp_type;
     HYPRE_Int    agg_P_max_elmts;
     HYPRE_Int    agg_P12_max_elmts;
     HYPRE_Int    post_interp_type;
     HYPRE_Int    num_CR_relax_steps;
     HYPRE_Int    IS_type;
     HYPRE_Int    CR_use_CG;
     HYPRE_Int    cgc_its;
     HYPRE_Int    seq_threshold;
     HYPRE_Int    redundant;
  
     /* solve params */
     HYPRE_Int    min_iter;
     HYPRE_Int    max_iter;
     HYPRE_Int    fcycle;
     HYPRE_Int    cycle_type;
  
     HYPRE_Int    converge_type;
     HYPRE_Real   tol;
  
     HYPRE_Int    num_sweeps;
     HYPRE_Int    relax_down;
     HYPRE_Int    relax_up;
     HYPRE_Int    relax_coarse;
     HYPRE_Int    relax_order;
     HYPRE_Real   relax_wt;
     HYPRE_Real   outer_wt;
     HYPRE_Real   nongalerkin_tol;
     HYPRE_Int    smooth_type;
     HYPRE_Int    smooth_num_levels;
     HYPRE_Int    smooth_num_sweeps;
  
     HYPRE_Int    variant, overlap, domain_type, schwarz_use_nonsymm;
     HYPRE_Real   schwarz_rlx_weight;
     HYPRE_Int    level, sym;
     HYPRE_Int    eu_level, eu_bj;
     HYPRE_Int    max_nz_per_row;
     HYPRE_Real   thresh, filter;
     HYPRE_Real   drop_tol;
     HYPRE_Real   eu_sparse_A;
     char    *euclidfile;
  
     HYPRE_Int cheby_order;
     HYPRE_Int cheby_eig_est;
     HYPRE_Int cheby_variant;
     HYPRE_Int cheby_scale;
     HYPRE_Real cheby_eig_ratio;
  
     HYPRE_Int block_mode;
  
     HYPRE_Int    additive;
     HYPRE_Int    mult_additive;
     HYPRE_Int    simple;
     HYPRE_Int    add_last_lvl;
     HYPRE_Real   add_trunc_factor;
     HYPRE_Int    add_P_max_elmts;
     HYPRE_Int    add_rlx_type;
     HYPRE_Real   add_rlx_wt;
  
     /* log info */
     HYPRE_Int    num_iterations;
     HYPRE_Int    cum_num_iterations;
  
     /* output params */
     HYPRE_Int    print_level;
     HYPRE_Int    logging;
     /* HYPRE_Int      cycle_op_count; */
     char     log_file_name[256];
     HYPRE_Int    debug_flag;
  
     char     plot_file_name[251] = {0};
  
     /*-----------------------------------------------------------------------
      * Setup default values for parameters
      *-----------------------------------------------------------------------*/
  
     /* setup params */
     max_levels = 25;
     max_coarse_size = 9;
     min_coarse_size = 0;
     seq_threshold = 0;
     redundant = 0;
     coarsen_cut_factor = 0;
     strong_threshold = 0.25;
     strong_threshold_R = 0.25;
     filter_threshold_R = 0.0;
     Sabs = 0;
     max_row_sum = 0.9;
     trunc_factor = 0.0;
     agg_trunc_factor = 0.0;
     agg_P12_trunc_factor = 0.0;
     jacobi_trunc_threshold = 0.01;
     S_commpkg_switch = 1.0;
     interp_type = 0;
     sep_weight = 0;
     coarsen_type = 10;
     interp_type = 6;
     measure_type = 0;
     setup_type = 1;
     P_max_elmts = 4;
     agg_P_max_elmts = 0;
     agg_P12_max_elmts = 0;
     num_functions = 1;
     nodal = 0;
     nodal_levels = max_levels;
     nodal_diag = 0;
     num_paths = 1;
     agg_num_levels = 0;
     post_interp_type = 0;
     agg_interp_type = 4;
     num_CR_relax_steps = 2;
     CR_rate = 0.7;
     CR_strong_th = 0;
     A_drop_tol = 0.0;
     A_drop_type = -1;
     IS_type = 1;
     CR_use_CG = 0;
     cgc_its = 1;
  
     variant = 0;
     overlap = 1;
     domain_type = 2;
     schwarz_rlx_weight = 1.0;
     smooth_num_sweeps = 1;
     smooth_num_levels = 0;
     smooth_type = 6;
     schwarz_use_nonsymm = 0;
  
     level = 1;
     sym = 0;
     thresh = 0.1;
     filter = 0.05;
     drop_tol = 0.0001;
     max_nz_per_row = 20;
     euclidfile = NULL;
     eu_level = 0;
     eu_sparse_A = 0.0;
     eu_bj = 0;
  
     /* solve params */
     min_iter  = 0;
     max_iter  = 20;
     fcycle = 0;
     cycle_type = 1;
     converge_type = 0;
     tol = 1.0e-7;
  
     num_sweeps = 1;
     relax_down = 13;
     relax_up = 14;
     relax_coarse = 9;
     relax_order = 0;
     relax_wt = 1.0;
     outer_wt = 1.0;
  
     cheby_order = 2;
     cheby_variant = 0;
     cheby_scale = 1;
     cheby_eig_est = 10;
     cheby_eig_ratio = .3;
  
     block_mode = 0;
  
     additive = -1;
     mult_additive = -1;
     simple = -1;
     add_last_lvl = -1;
     add_trunc_factor = 0.0;
     add_P_max_elmts = 0;
     add_rlx_type = 18;
     add_rlx_wt = 1.0;
  
     /* log info */
     num_iterations = 0;
     cum_num_iterations = 0;
  
     /* output params */
     print_level = 0;
     logging = 0;
     hypre_sprintf(log_file_name, "%s", "amg.out.log");
     /* cycle_op_count = 0; */
     debug_flag = 0;
  
     nongalerkin_tol = 0.0;
  
     HYPRE_ANNOTATE_FUNC_BEGIN;
  
     /*-----------------------------------------------------------------------
      * Create the hypre_ParAMGData structure and return
      *-----------------------------------------------------------------------*/
  
     amg_data = hypre_CTAlloc(hypre_ParAMGData, 1, HYPRE_MEMORY_HOST);
  
     hypre_ParAMGDataMemoryLocation(amg_data) = HYPRE_MEMORY_UNDEFINED;
  
     hypre_ParAMGDataMaxLevels(amg_data) =  max_levels;
     hypre_ParAMGDataUserCoarseRelaxType(amg_data) = 9;
     hypre_ParAMGDataUserRelaxType(amg_data) = -1;
     hypre_ParAMGDataUserNumSweeps(amg_data) = -1;
     hypre_ParAMGDataUserRelaxWeight(amg_data) = relax_wt;
     hypre_ParAMGDataOuterWt(amg_data) = outer_wt;
     hypre_BoomerAMGSetMaxCoarseSize(amg_data, max_coarse_size);
     hypre_BoomerAMGSetMinCoarseSize(amg_data, min_coarse_size);
     hypre_BoomerAMGSetCoarsenCutFactor(amg_data, coarsen_cut_factor);
     hypre_BoomerAMGSetStrongThreshold(amg_data, strong_threshold);
     hypre_BoomerAMGSetStrongThresholdR(amg_data, strong_threshold_R);
     hypre_BoomerAMGSetFilterThresholdR(amg_data, filter_threshold_R);
     hypre_BoomerAMGSetSabs(amg_data, Sabs);
     hypre_BoomerAMGSetMaxRowSum(amg_data, max_row_sum);
     hypre_BoomerAMGSetTruncFactor(amg_data, trunc_factor);
     hypre_BoomerAMGSetAggTruncFactor(amg_data, agg_trunc_factor);
     hypre_BoomerAMGSetAggP12TruncFactor(amg_data, agg_P12_trunc_factor);
     hypre_BoomerAMGSetJacobiTruncThreshold(amg_data, jacobi_trunc_threshold);
     hypre_BoomerAMGSetSCommPkgSwitch(amg_data, S_commpkg_switch);
     hypre_BoomerAMGSetSepWeight(amg_data, sep_weight);
     hypre_BoomerAMGSetMeasureType(amg_data, measure_type);
     hypre_BoomerAMGSetCoarsenType(amg_data, coarsen_type);
     hypre_BoomerAMGSetInterpType(amg_data, interp_type);
     hypre_BoomerAMGSetSetupType(amg_data, setup_type);
     hypre_BoomerAMGSetPMaxElmts(amg_data, P_max_elmts);
     hypre_BoomerAMGSetAggPMaxElmts(amg_data, agg_P_max_elmts);
     hypre_BoomerAMGSetAggP12MaxElmts(amg_data, agg_P12_max_elmts);
     hypre_BoomerAMGSetNumFunctions(amg_data, num_functions);
     hypre_BoomerAMGSetNodal(amg_data, nodal);
     hypre_BoomerAMGSetNodalLevels(amg_data, nodal_levels);
     hypre_BoomerAMGSetNodal(amg_data, nodal_diag);
     hypre_BoomerAMGSetNumPaths(amg_data, num_paths);
     hypre_BoomerAMGSetAggNumLevels(amg_data, agg_num_levels);
     hypre_BoomerAMGSetAggInterpType(amg_data, agg_interp_type);
     hypre_BoomerAMGSetPostInterpType(amg_data, post_interp_type);
     hypre_BoomerAMGSetNumCRRelaxSteps(amg_data, num_CR_relax_steps);
     hypre_BoomerAMGSetCRRate(amg_data, CR_rate);
     hypre_BoomerAMGSetCRStrongTh(amg_data, CR_strong_th);
     hypre_BoomerAMGSetADropTol(amg_data, A_drop_tol);
     hypre_BoomerAMGSetADropType(amg_data, A_drop_type);
     hypre_BoomerAMGSetISType(amg_data, IS_type);
     hypre_BoomerAMGSetCRUseCG(amg_data, CR_use_CG);
     hypre_BoomerAMGSetCGCIts(amg_data, cgc_its);
     hypre_BoomerAMGSetVariant(amg_data, variant);
     hypre_BoomerAMGSetOverlap(amg_data, overlap);
     hypre_BoomerAMGSetSchwarzRlxWeight(amg_data, schwarz_rlx_weight);
     hypre_BoomerAMGSetSchwarzUseNonSymm(amg_data, schwarz_use_nonsymm);
     hypre_BoomerAMGSetDomainType(amg_data, domain_type);
     hypre_BoomerAMGSetSym(amg_data, sym);
     hypre_BoomerAMGSetLevel(amg_data, level);
     hypre_BoomerAMGSetThreshold(amg_data, thresh);
     hypre_BoomerAMGSetFilter(amg_data, filter);
     hypre_BoomerAMGSetDropTol(amg_data, drop_tol);
     hypre_BoomerAMGSetMaxNzPerRow(amg_data, max_nz_per_row);
     hypre_BoomerAMGSetEuclidFile(amg_data, euclidfile);
     hypre_BoomerAMGSetEuLevel(amg_data, eu_level);
     hypre_BoomerAMGSetEuSparseA(amg_data, eu_sparse_A);
     hypre_BoomerAMGSetEuBJ(amg_data, eu_bj);
  
     hypre_BoomerAMGSetMinIter(amg_data, min_iter);
     hypre_BoomerAMGSetMaxIter(amg_data, max_iter);
     hypre_BoomerAMGSetCycleType(amg_data, cycle_type);
     hypre_BoomerAMGSetFCycle(amg_data, fcycle);
     hypre_BoomerAMGSetConvergeType(amg_data, converge_type);
     hypre_BoomerAMGSetTol(amg_data, tol);
     hypre_BoomerAMGSetNumSweeps(amg_data, num_sweeps);
     hypre_BoomerAMGSetCycleRelaxType(amg_data, relax_down, 1);
     hypre_BoomerAMGSetCycleRelaxType(amg_data, relax_up, 2);
     hypre_BoomerAMGSetCycleRelaxType(amg_data, relax_coarse, 3);
     hypre_BoomerAMGSetRelaxOrder(amg_data, relax_order);
     hypre_BoomerAMGSetRelaxWt(amg_data, relax_wt);
     hypre_BoomerAMGSetOuterWt(amg_data, outer_wt);
     hypre_BoomerAMGSetSmoothType(amg_data, smooth_type);
     hypre_BoomerAMGSetSmoothNumLevels(amg_data, smooth_num_levels);
     hypre_BoomerAMGSetSmoothNumSweeps(amg_data, smooth_num_sweeps);
  
     hypre_BoomerAMGSetChebyOrder(amg_data, cheby_order);
     hypre_BoomerAMGSetChebyFraction(amg_data, cheby_eig_ratio);
     hypre_BoomerAMGSetChebyEigEst(amg_data, cheby_eig_est);
     hypre_BoomerAMGSetChebyVariant(amg_data, cheby_variant);
     hypre_BoomerAMGSetChebyScale(amg_data, cheby_scale);
  
     hypre_BoomerAMGSetNumIterations(amg_data, num_iterations);
  
     hypre_BoomerAMGSetAdditive(amg_data, additive);
     hypre_BoomerAMGSetMultAdditive(amg_data, mult_additive);
     hypre_BoomerAMGSetSimple(amg_data, simple);
     hypre_BoomerAMGSetMultAddPMaxElmts(amg_data, add_P_max_elmts);
     hypre_BoomerAMGSetMultAddTruncFactor(amg_data, add_trunc_factor);
     hypre_BoomerAMGSetAddRelaxType(amg_data, add_rlx_type);
     hypre_BoomerAMGSetAddRelaxWt(amg_data, add_rlx_wt);
     hypre_ParAMGDataAddLastLvl(amg_data) = add_last_lvl;
     hypre_ParAMGDataLambda(amg_data) = NULL;
     hypre_ParAMGDataXtilde(amg_data) = NULL;
     hypre_ParAMGDataRtilde(amg_data) = NULL;
     hypre_ParAMGDataDinv(amg_data) = NULL;
  
  #ifdef CUMNUMIT
     hypre_ParAMGDataCumNumIterations(amg_data) = cum_num_iterations;
  #endif
     hypre_BoomerAMGSetPrintLevel(amg_data, print_level);
     hypre_BoomerAMGSetLogging(amg_data, logging);
     hypre_BoomerAMGSetPrintFileName(amg_data, log_file_name);
     hypre_BoomerAMGSetDebugFlag(amg_data, debug_flag);
     hypre_BoomerAMGSetRestriction(amg_data, 0);
     hypre_BoomerAMGSetIsTriangular(amg_data, 0);
     hypre_BoomerAMGSetGMRESSwitchR(amg_data, 64);
  
     hypre_BoomerAMGSetGSMG(amg_data, 0);
     hypre_BoomerAMGSetNumSamples(amg_data, 0);
  
     hypre_ParAMGDataAArray(amg_data) = NULL;
     hypre_ParAMGDataPArray(amg_data) = NULL;
     hypre_ParAMGDataRArray(amg_data) = NULL;
     hypre_ParAMGDataCFMarkerArray(amg_data) = NULL;
     hypre_ParAMGDataVtemp(amg_data)  = NULL;
     hypre_ParAMGDataRtemp(amg_data)  = NULL;
     hypre_ParAMGDataPtemp(amg_data)  = NULL;
     hypre_ParAMGDataZtemp(amg_data)  = NULL;
     hypre_ParAMGDataFArray(amg_data) = NULL;
     hypre_ParAMGDataUArray(amg_data) = NULL;
     hypre_ParAMGDataDofFunc(amg_data) = NULL;
     hypre_ParAMGDataDofFuncArray(amg_data) = NULL;
     hypre_ParAMGDataDofPointArray(amg_data) = NULL;
     hypre_ParAMGDataDofPointArray(amg_data) = NULL;
     hypre_ParAMGDataPointDofMapArray(amg_data) = NULL;
     hypre_ParAMGDataSmoother(amg_data) = NULL;
     hypre_ParAMGDataL1Norms(amg_data) = NULL;
  
     hypre_ParAMGDataABlockArray(amg_data) = NULL;
     hypre_ParAMGDataPBlockArray(amg_data) = NULL;
     hypre_ParAMGDataRBlockArray(amg_data) = NULL;
  
     /* this can not be set by the user currently */
     hypre_ParAMGDataBlockMode(amg_data) = block_mode;
  
     /* Stuff for Chebyshev smoothing */
     hypre_ParAMGDataMaxEigEst(amg_data) = NULL;
     hypre_ParAMGDataMinEigEst(amg_data) = NULL;
     hypre_ParAMGDataChebyDS(amg_data) = NULL;
     hypre_ParAMGDataChebyCoefs(amg_data) = NULL;
  
     /* BM Oct 22, 2006 */
     hypre_ParAMGDataPlotGrids(amg_data) = 0;
     hypre_BoomerAMGSetPlotFileName (amg_data, plot_file_name);
  
     /* BM Oct 17, 2006 */
     hypre_ParAMGDataCoordDim(amg_data) = 0;
     hypre_ParAMGDataCoordinates(amg_data) = NULL;
  
    /* for fitting vectors for interp */
     hypre_BoomerAMGSetInterpVecVariant(amg_data, 0);
     hypre_BoomerAMGSetInterpVectors(amg_data, 0, NULL);
     hypre_ParAMGNumLevelsInterpVectors(amg_data) = max_levels;
     hypre_ParAMGInterpVectorsArray(amg_data) = NULL;
     hypre_ParAMGInterpVecQMax(amg_data) = 0;
     hypre_ParAMGInterpVecAbsQTrunc(amg_data) = 0.0;
     hypre_ParAMGInterpRefine(amg_data) = 0;
     hypre_ParAMGInterpVecFirstLevel(amg_data) = 0;
     hypre_ParAMGNumInterpVectors(amg_data) = 0;
     hypre_ParAMGSmoothInterpVectors(amg_data) = 0;
     hypre_ParAMGDataExpandPWeights(amg_data) = NULL;
  
     /* for redundant coarse grid solve */
     hypre_ParAMGDataSeqThreshold(amg_data) = seq_threshold;
     hypre_ParAMGDataRedundant(amg_data) = redundant;
     hypre_ParAMGDataCoarseSolver(amg_data) = NULL;
     hypre_ParAMGDataACoarse(amg_data) = NULL;
     hypre_ParAMGDataFCoarse(amg_data) = NULL;
     hypre_ParAMGDataUCoarse(amg_data) = NULL;
     hypre_ParAMGDataNewComm(amg_data) = hypre_MPI_COMM_NULL;
  
     /* for Gaussian elimination coarse grid solve */
     hypre_ParAMGDataGSSetup(amg_data) = 0;
     hypre_ParAMGDataAMat(amg_data) = NULL;
     hypre_ParAMGDataAInv(amg_data) = NULL;
     hypre_ParAMGDataBVec(amg_data) = NULL;
     hypre_ParAMGDataCommInfo(amg_data) = NULL;
  
     hypre_ParAMGDataNonGalerkinTol(amg_data) = nongalerkin_tol;
     hypre_ParAMGDataNonGalTolArray(amg_data) = NULL;
  
  #if defined(HYPRE_USING_CUDA) || defined(HYPRE_USING_DEVICE_OPENMP)
     hypre_ParAMGDataRAP2(amg_data)              = 1;
     hypre_ParAMGDataKeepTranspose(amg_data)     = 1;
     hypre_ParAMGDataModularizedMatMat(amg_data) = 1;
  #else
     hypre_ParAMGDataRAP2(amg_data)              = 0;
     hypre_ParAMGDataKeepTranspose(amg_data)     = 0;
     hypre_ParAMGDataModularizedMatMat(amg_data) = 0;
  #endif
  
     /* information for preserving indices as coarse grid points */
     hypre_ParAMGDataCPointsMarker(amg_data)      = NULL;
     hypre_ParAMGDataCPointsLocalMarker(amg_data) = NULL;
     hypre_ParAMGDataCPointsLevel(amg_data)       = 0;
     hypre_ParAMGDataNumCPoints(amg_data)         = 0;
  
     /* information for preserving indices as special fine grid points */
     hypre_ParAMGDataIsolatedFPointsMarker(amg_data) = NULL;
     hypre_ParAMGDataNumIsolatedFPoints(amg_data) = 0;
  
  #ifdef HYPRE_USING_DSUPERLU
     hypre_ParAMGDataDSLUThreshold(amg_data) = 0;
     hypre_ParAMGDataDSLUSolver(amg_data) = NULL;
  #endif
  
     HYPRE_ANNOTATE_FUNC_END;
  
     return (void *) amg_data;
  }
  
  /*--------------------------------------------------------------------------
   * hypre_BoomerAMGDestroy
   *--------------------------------------------------------------------------*/
  
  HYPRE_Int
  hypre_BoomerAMGDestroy( void *data )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
     HYPRE_Int num_levels = hypre_ParAMGDataNumLevels(amg_data);
     HYPRE_Int smooth_num_levels = hypre_ParAMGDataSmoothNumLevels(amg_data);
     HYPRE_Solver *smoother = hypre_ParAMGDataSmoother(amg_data);
     void *amg = hypre_ParAMGDataCoarseSolver(amg_data);
     MPI_Comm new_comm = hypre_ParAMGDataNewComm(amg_data);
     HYPRE_Int i;
     HYPRE_Int *grid_relax_type = hypre_ParAMGDataGridRelaxType(amg_data);
  
     HYPRE_ANNOTATE_FUNC_BEGIN;
  
  #ifdef HYPRE_USING_DSUPERLU
  //   if (hypre_ParAMGDataDSLUThreshold(amg_data) > 0)
     if (hypre_ParAMGDataDSLUSolver(amg_data) != NULL)
     {
        hypre_SLUDistDestroy(hypre_ParAMGDataDSLUSolver(amg_data));
        hypre_ParAMGDataDSLUSolver(amg_data) = NULL;
     }
  #endif
  
     if (hypre_ParAMGDataMaxEigEst(amg_data))
     {
        hypre_TFree(hypre_ParAMGDataMaxEigEst(amg_data), HYPRE_MEMORY_HOST);
        hypre_ParAMGDataMaxEigEst(amg_data) = NULL;
     }
     if (hypre_ParAMGDataMinEigEst(amg_data))
     {
        hypre_TFree(hypre_ParAMGDataMinEigEst(amg_data), HYPRE_MEMORY_HOST);
        hypre_ParAMGDataMinEigEst(amg_data) = NULL;
     }
     if (hypre_ParAMGDataNumGridSweeps(amg_data))
     {
        hypre_TFree(hypre_ParAMGDataNumGridSweeps(amg_data), HYPRE_MEMORY_HOST);
        hypre_ParAMGDataNumGridSweeps(amg_data) = NULL;
     }
     if (grid_relax_type)
     {
        HYPRE_Int num_levels = hypre_ParAMGDataNumLevels(amg_data);
        if (grid_relax_type[1] == 15 || grid_relax_type[3] == 15 )
        {
           if (grid_relax_type[1] == 15)
              for (i=0; i < num_levels; i++)
                 HYPRE_ParCSRPCGDestroy(smoother[i]);
           if (grid_relax_type[3] == 15 && grid_relax_type[1] != 15)
              HYPRE_ParCSRPCGDestroy(smoother[num_levels-1]);
           hypre_TFree(smoother, HYPRE_MEMORY_HOST);
        }
  
        hypre_TFree(hypre_ParAMGDataGridRelaxType(amg_data), HYPRE_MEMORY_HOST);
        hypre_ParAMGDataGridRelaxType(amg_data) = NULL;
     }
     if (hypre_ParAMGDataRelaxWeight(amg_data))
     {
        hypre_TFree(hypre_ParAMGDataRelaxWeight(amg_data), HYPRE_MEMORY_HOST);
        hypre_ParAMGDataRelaxWeight(amg_data) = NULL;
     }
     if (hypre_ParAMGDataOmega(amg_data))
     {
        hypre_TFree(hypre_ParAMGDataOmega(amg_data), HYPRE_MEMORY_HOST);
        hypre_ParAMGDataOmega(amg_data) = NULL;
     }
     if (hypre_ParAMGDataNonGalTolArray(amg_data))
     {
        hypre_TFree(hypre_ParAMGDataNonGalTolArray(amg_data), HYPRE_MEMORY_HOST);
        hypre_ParAMGDataNonGalTolArray(amg_data) = NULL;
     }
     if (hypre_ParAMGDataDofFunc(amg_data))
     {
        hypre_TFree(hypre_ParAMGDataDofFunc(amg_data), HYPRE_MEMORY_HOST);
        hypre_ParAMGDataDofFunc(amg_data) = NULL;
     }
     if (hypre_ParAMGDataGridRelaxPoints(amg_data))
     {
        for (i=0; i < 4; i++)
           hypre_TFree(hypre_ParAMGDataGridRelaxPoints(amg_data)[i], HYPRE_MEMORY_HOST);
        hypre_TFree(hypre_ParAMGDataGridRelaxPoints(amg_data), HYPRE_MEMORY_HOST);
        hypre_ParAMGDataGridRelaxPoints(amg_data) = NULL;
     }
     for (i=1; i < num_levels; i++)
     {
        hypre_ParVectorDestroy(hypre_ParAMGDataFArray(amg_data)[i]);
        hypre_ParVectorDestroy(hypre_ParAMGDataUArray(amg_data)[i]);
  
        if (hypre_ParAMGDataAArray(amg_data)[i])
           hypre_ParCSRMatrixDestroy(hypre_ParAMGDataAArray(amg_data)[i]);
  
        if (hypre_ParAMGDataPArray(amg_data)[i-1])
           hypre_ParCSRMatrixDestroy(hypre_ParAMGDataPArray(amg_data)[i-1]);
  
        if (hypre_ParAMGDataRestriction(amg_data))
        {
           if (hypre_ParAMGDataRArray(amg_data)[i-1])
           {
              hypre_ParCSRMatrixDestroy(hypre_ParAMGDataRArray(amg_data)[i-1]);
           }
        }
  
        hypre_TFree(hypre_ParAMGDataCFMarkerArray(amg_data)[i-1], HYPRE_MEMORY_HOST);
  
        /* get rid of any block structures */
        if (hypre_ParAMGDataABlockArray(amg_data)[i])
           hypre_ParCSRBlockMatrixDestroy(hypre_ParAMGDataABlockArray(amg_data)[i]);
  
        if (hypre_ParAMGDataPBlockArray(amg_data)[i-1])
           hypre_ParCSRBlockMatrixDestroy(hypre_ParAMGDataPBlockArray(amg_data)[i-1]);
  
        /* RL */
        if (hypre_ParAMGDataRestriction(amg_data))
        {
           if (hypre_ParAMGDataRBlockArray(amg_data)[i-1])
           {
              hypre_ParCSRBlockMatrixDestroy(hypre_ParAMGDataRBlockArray(amg_data)[i-1]);
           }
        }
     }
  
     if (hypre_ParAMGDataLambda(amg_data))
     {
        hypre_ParCSRMatrixDestroy(hypre_ParAMGDataLambda(amg_data));
     }
  
     if (hypre_ParAMGDataAtilde(amg_data))
     {
        hypre_ParCSRMatrix *Atilde = hypre_ParAMGDataAtilde(amg_data);
        hypre_CSRMatrixDestroy(hypre_ParCSRMatrixDiag(Atilde));
        hypre_CSRMatrixDestroy(hypre_ParCSRMatrixOffd(Atilde));
        hypre_TFree(Atilde, HYPRE_MEMORY_HOST);
     }
  
     if (hypre_ParAMGDataXtilde(amg_data))
        hypre_ParVectorDestroy(hypre_ParAMGDataXtilde(amg_data));
  
     if (hypre_ParAMGDataRtilde(amg_data))
        hypre_ParVectorDestroy(hypre_ParAMGDataRtilde(amg_data));
  
     if (hypre_ParAMGDataL1Norms(amg_data))
     {
        for (i = 0; i < num_levels; i++)
        {
           hypre_SeqVectorDestroy(hypre_ParAMGDataL1Norms(amg_data)[i]);
        }
        hypre_TFree(hypre_ParAMGDataL1Norms(amg_data), HYPRE_MEMORY_HOST);
     }
  
     if (hypre_ParAMGDataChebyCoefs(amg_data))
     {
        for (i=0; i < num_levels; i++)
           if (hypre_ParAMGDataChebyCoefs(amg_data)[i])
              hypre_TFree(hypre_ParAMGDataChebyCoefs(amg_data)[i], HYPRE_MEMORY_HOST);
        hypre_TFree(hypre_ParAMGDataChebyCoefs(amg_data), HYPRE_MEMORY_HOST);
     }
  
     if (hypre_ParAMGDataChebyDS(amg_data))
     {
        for (i=0; i < num_levels; i++)
           if (hypre_ParAMGDataChebyDS(amg_data)[i])
              hypre_TFree(hypre_ParAMGDataChebyDS(amg_data)[i], HYPRE_MEMORY_HOST);
        hypre_TFree(hypre_ParAMGDataChebyDS(amg_data), HYPRE_MEMORY_HOST);
     }
  
     if (hypre_ParAMGDataDinv(amg_data))
        hypre_TFree(hypre_ParAMGDataDinv(amg_data), HYPRE_MEMORY_HOST);
  
     /* get rid of a fine level block matrix */
     if (hypre_ParAMGDataABlockArray(amg_data))
        if (hypre_ParAMGDataABlockArray(amg_data)[0])
           hypre_ParCSRBlockMatrixDestroy(hypre_ParAMGDataABlockArray(amg_data)[0]);
  
  
     /* see comments in par_coarsen.c regarding special case for CF_marker */
     if (num_levels == 1)
     {
        hypre_TFree(hypre_ParAMGDataCFMarkerArray(amg_data)[0], HYPRE_MEMORY_HOST);
     }
     hypre_ParVectorDestroy(hypre_ParAMGDataVtemp(amg_data));
     hypre_TFree(hypre_ParAMGDataFArray(amg_data), HYPRE_MEMORY_HOST);
     hypre_TFree(hypre_ParAMGDataUArray(amg_data), HYPRE_MEMORY_HOST);
     hypre_TFree(hypre_ParAMGDataAArray(amg_data), HYPRE_MEMORY_HOST);
     hypre_TFree(hypre_ParAMGDataABlockArray(amg_data), HYPRE_MEMORY_HOST);
     hypre_TFree(hypre_ParAMGDataPBlockArray(amg_data), HYPRE_MEMORY_HOST);
     hypre_TFree(hypre_ParAMGDataPArray(amg_data), HYPRE_MEMORY_HOST);
     hypre_TFree(hypre_ParAMGDataCFMarkerArray(amg_data), HYPRE_MEMORY_HOST);
  
     if (hypre_ParAMGDataRtemp(amg_data))
        hypre_ParVectorDestroy(hypre_ParAMGDataRtemp(amg_data));
     if (hypre_ParAMGDataPtemp(amg_data))
        hypre_ParVectorDestroy(hypre_ParAMGDataPtemp(amg_data));
     if (hypre_ParAMGDataZtemp(amg_data))
        hypre_ParVectorDestroy(hypre_ParAMGDataZtemp(amg_data));
  
     if (hypre_ParAMGDataDofFuncArray(amg_data))
     {
        for (i=1; i < num_levels; i++)
           hypre_TFree(hypre_ParAMGDataDofFuncArray(amg_data)[i], HYPRE_MEMORY_HOST);
        hypre_TFree(hypre_ParAMGDataDofFuncArray(amg_data), HYPRE_MEMORY_HOST);
        hypre_ParAMGDataDofFuncArray(amg_data) = NULL;
     }
     if (hypre_ParAMGDataRestriction(amg_data))
     {
        hypre_TFree(hypre_ParAMGDataRBlockArray(amg_data),HYPRE_MEMORY_HOST);
        hypre_TFree(hypre_ParAMGDataRArray(amg_data),HYPRE_MEMORY_HOST);
        hypre_ParAMGDataRArray(amg_data) = NULL;
     }
     if (hypre_ParAMGDataDofPointArray(amg_data))
     {
        for (i=0; i < num_levels; i++)
           hypre_TFree(hypre_ParAMGDataDofPointArray(amg_data)[i], HYPRE_MEMORY_HOST);
        hypre_TFree(hypre_ParAMGDataDofPointArray(amg_data), HYPRE_MEMORY_HOST);
        hypre_ParAMGDataDofPointArray(amg_data) = NULL;
     }
     if (hypre_ParAMGDataPointDofMapArray(amg_data))
     {
        for (i=0; i < num_levels; i++)
           hypre_TFree(hypre_ParAMGDataPointDofMapArray(amg_data)[i], HYPRE_MEMORY_HOST);
        hypre_TFree(hypre_ParAMGDataPointDofMapArray(amg_data), HYPRE_MEMORY_HOST);
        hypre_ParAMGDataPointDofMapArray(amg_data) = NULL;
     }
  
     if (smooth_num_levels)
     {
        if (hypre_ParAMGDataSmoothType(amg_data) == 7 || hypre_ParAMGDataSmoothType(amg_data) == 17)
        {
           for (i=0; i < smooth_num_levels; i++)
           {
              HYPRE_ParCSRPilutDestroy(smoother[i]);
           }
        }
        else if (hypre_ParAMGDataSmoothType(amg_data) == 8 || hypre_ParAMGDataSmoothType(amg_data) == 18)
        {
           for (i=0; i < smooth_num_levels; i++)
           {
              HYPRE_ParCSRParaSailsDestroy(smoother[i]);
           }
        }
        else if (hypre_ParAMGDataSmoothType(amg_data) == 9 || hypre_ParAMGDataSmoothType(amg_data) == 19 )
        {
           for (i=0; i < smooth_num_levels; i++)
           {
              HYPRE_EuclidDestroy(smoother[i]);
           }
        }
        else if (hypre_ParAMGDataSmoothType(amg_data) == 5 || hypre_ParAMGDataSmoothType(amg_data) == 15 )
        {
           for (i=0; i < smooth_num_levels; i++)
  	 {
  	    HYPRE_ILUDestroy(smoother[i]);
           }
        }
        else if (hypre_ParAMGDataSmoothType(amg_data) == 6 || hypre_ParAMGDataSmoothType(amg_data) == 16)
        {
           for (i=0; i < smooth_num_levels; i++)
           {
              HYPRE_SchwarzDestroy(smoother[i]);
           }
        }
        hypre_TFree(hypre_ParAMGDataSmoother(amg_data), HYPRE_MEMORY_HOST);
     }
     if ( hypre_ParAMGDataResidual(amg_data) ) {
        /* jfp: was... hypre_TFree( hypre_ParAMGDataResidual(amg_data) );*/
        hypre_ParVectorDestroy( hypre_ParAMGDataResidual(amg_data) );
        hypre_ParAMGDataResidual(amg_data) = NULL;
     }
  
  
     if (hypre_ParAMGInterpVecVariant(amg_data) > 0
           &&  hypre_ParAMGNumInterpVectors(amg_data) > 0)
     {
  
        HYPRE_Int j;
        HYPRE_Int num_vecs =  hypre_ParAMGNumInterpVectors(amg_data);
        hypre_ParVector **sm_vecs;
        HYPRE_Int num_il;
        num_il = hypre_min(hypre_ParAMGNumLevelsInterpVectors(amg_data),num_levels);
  
        /* don't destroy lev = 0 - this was user input */
        for (i = 1; i< num_il; i++)
        {
           sm_vecs = hypre_ParAMGInterpVectorsArray(amg_data)[i];
           for (j = 0; j< num_vecs; j++)
           {
              hypre_ParVectorDestroy(sm_vecs[j]);
           }
           hypre_TFree(sm_vecs, HYPRE_MEMORY_HOST);
        }
        hypre_TFree( hypre_ParAMGInterpVectorsArray(amg_data), HYPRE_MEMORY_HOST);
  
     }
  
     if (amg) hypre_BoomerAMGDestroy(amg);
  
     if (hypre_ParAMGDataACoarse(amg_data))
        hypre_ParCSRMatrixDestroy(hypre_ParAMGDataACoarse(amg_data));
  
     if (hypre_ParAMGDataUCoarse(amg_data))
        hypre_ParVectorDestroy(hypre_ParAMGDataUCoarse(amg_data));
  
     if (hypre_ParAMGDataFCoarse(amg_data))
        hypre_ParVectorDestroy(hypre_ParAMGDataFCoarse(amg_data));
  
     /* destroy input CF_marker data */
     if (hypre_ParAMGDataCPointsMarker(amg_data))
     {
        hypre_TFree(hypre_ParAMGDataCPointsMarker(amg_data), HYPRE_MEMORY_HOST);
     }
     if (hypre_ParAMGDataCPointsLocalMarker(amg_data))
     {
        hypre_TFree(hypre_ParAMGDataCPointsLocalMarker(amg_data), HYPRE_MEMORY_HOST);
     }
     if (hypre_ParAMGDataFPointsMarker(amg_data))
     {
        hypre_TFree(hypre_ParAMGDataFPointsMarker(amg_data), HYPRE_MEMORY_HOST);
     }
     if (hypre_ParAMGDataIsolatedFPointsMarker(amg_data))
     {
        hypre_TFree(hypre_ParAMGDataIsolatedFPointsMarker(amg_data), HYPRE_MEMORY_HOST);
     }
  
     if (hypre_ParAMGDataAMat(amg_data)) hypre_TFree(hypre_ParAMGDataAMat(amg_data), HYPRE_MEMORY_HOST);
     if (hypre_ParAMGDataAInv(amg_data)) hypre_TFree(hypre_ParAMGDataAInv(amg_data), HYPRE_MEMORY_HOST);
     if (hypre_ParAMGDataBVec(amg_data)) hypre_TFree(hypre_ParAMGDataBVec(amg_data), HYPRE_MEMORY_HOST);
     if (hypre_ParAMGDataCommInfo(amg_data)) hypre_TFree(hypre_ParAMGDataCommInfo(amg_data), HYPRE_MEMORY_HOST);
  
     if (new_comm != hypre_MPI_COMM_NULL)
     {
        hypre_MPI_Comm_free (&new_comm);
     }
     hypre_TFree(amg_data, HYPRE_MEMORY_HOST);
  
     HYPRE_ANNOTATE_FUNC_END;
  
     return hypre_error_flag;
  }
  
  /*--------------------------------------------------------------------------
   * Routines to set the setup phase parameters
   *--------------------------------------------------------------------------*/
  
  HYPRE_Int
  hypre_BoomerAMGSetRestriction( void *data,
                                 HYPRE_Int   restr_par )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     /* RL: currently, only 0: R = P^T
      *                     1: AIR
      *                     2: AIR-2
      *                     15: a special version of AIR-2 with less communication cost
      *                     k(k>=3,k!=15): Neumann AIR of degree k-3
      */
     if (restr_par < 0)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
  
     hypre_ParAMGDataRestriction(amg_data) = restr_par;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetIsTriangular(void *data,
                                 HYPRE_Int is_triangular )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     hypre_ParAMGDataIsTriangular(amg_data) = is_triangular;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetGMRESSwitchR(void *data,
                                 HYPRE_Int gmres_switch )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     hypre_ParAMGDataGMRESSwitchR(amg_data) = gmres_switch;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetMaxLevels( void *data,
                            HYPRE_Int   max_levels )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
     HYPRE_Int old_max_levels;
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     if (max_levels < 1)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
  
     old_max_levels = hypre_ParAMGDataMaxLevels(amg_data);
     if (old_max_levels < max_levels)
     {
        HYPRE_Real *relax_weight, *omega, *nongal_tol_array;
        HYPRE_Real relax_wt, outer_wt, nongalerkin_tol;
        HYPRE_Int i;
        relax_weight = hypre_ParAMGDataRelaxWeight(amg_data);
        if (relax_weight)
        {
           relax_wt = hypre_ParAMGDataUserRelaxWeight(amg_data);
           relax_weight = hypre_TReAlloc(relax_weight,  HYPRE_Real,  max_levels, HYPRE_MEMORY_HOST);
           for (i=old_max_levels; i < max_levels; i++)
              relax_weight[i] = relax_wt;
           hypre_ParAMGDataRelaxWeight(amg_data) = relax_weight;
        }
        omega = hypre_ParAMGDataOmega(amg_data);
        if (omega)
        {
           outer_wt = hypre_ParAMGDataOuterWt(amg_data);
           omega = hypre_TReAlloc(omega,  HYPRE_Real,  max_levels, HYPRE_MEMORY_HOST);
           for (i=old_max_levels; i < max_levels; i++)
              omega[i] = outer_wt;
           hypre_ParAMGDataOmega(amg_data) = omega;
        }
        nongal_tol_array = hypre_ParAMGDataNonGalTolArray(amg_data);
        if (nongal_tol_array)
        {
           nongalerkin_tol = hypre_ParAMGDataNonGalerkinTol(amg_data);
           nongal_tol_array = hypre_TReAlloc(nongal_tol_array,  HYPRE_Real,  max_levels, HYPRE_MEMORY_HOST);
           for (i=old_max_levels; i < max_levels; i++)
              nongal_tol_array[i] = nongalerkin_tol;
           hypre_ParAMGDataNonGalTolArray(amg_data) = nongal_tol_array;
        }
     }
     hypre_ParAMGDataMaxLevels(amg_data) = max_levels;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetMaxLevels( void *data,
                               HYPRE_Int *  max_levels )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     *max_levels = hypre_ParAMGDataMaxLevels(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetMaxCoarseSize( void *data,
                            HYPRE_Int   max_coarse_size )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     if (max_coarse_size < 1)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
  
     hypre_ParAMGDataMaxCoarseSize(amg_data) = max_coarse_size;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetMaxCoarseSize( void *data,
                               HYPRE_Int *  max_coarse_size )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     *max_coarse_size = hypre_ParAMGDataMaxCoarseSize(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetMinCoarseSize( void *data,
                            HYPRE_Int   min_coarse_size )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     if (min_coarse_size < 0)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
  
     hypre_ParAMGDataMinCoarseSize(amg_data) = min_coarse_size;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetMinCoarseSize( void *data,
                               HYPRE_Int *  min_coarse_size )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     *min_coarse_size = hypre_ParAMGDataMinCoarseSize(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetSeqThreshold( void *data,
                            HYPRE_Int   seq_threshold )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     if (seq_threshold < 0)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
  
     hypre_ParAMGDataSeqThreshold(amg_data) = seq_threshold;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetSeqThreshold( void *data,
                               HYPRE_Int *  seq_threshold )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     *seq_threshold = hypre_ParAMGDataSeqThreshold(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetRedundant( void *data,
                            HYPRE_Int   redundant )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     if (redundant < 0)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
  
     hypre_ParAMGDataRedundant(amg_data) = redundant;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetRedundant( void *data,
                               HYPRE_Int *  redundant )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     *redundant = hypre_ParAMGDataRedundant(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetCoarsenCutFactor( void       *data,
                                      HYPRE_Int   coarsen_cut_factor )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     if (coarsen_cut_factor < 0)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
  
     hypre_ParAMGDataCoarsenCutFactor(amg_data) = coarsen_cut_factor;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetCoarsenCutFactor( void       *data,
                                      HYPRE_Int  *coarsen_cut_factor )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     *coarsen_cut_factor = hypre_ParAMGDataCoarsenCutFactor(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetStrongThreshold( void     *data,
                                  HYPRE_Real    strong_threshold )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     if (strong_threshold < 0 || strong_threshold > 1)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
  
     hypre_ParAMGDataStrongThreshold(amg_data) = strong_threshold;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetStrongThreshold( void     *data,
                                  HYPRE_Real *  strong_threshold )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     *strong_threshold = hypre_ParAMGDataStrongThreshold(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetStrongThresholdR( void         *data,
                                      HYPRE_Real    strong_threshold )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     if (strong_threshold < 0 || strong_threshold > 1)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
  
     hypre_ParAMGDataStrongThresholdR(amg_data) = strong_threshold;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetStrongThresholdR( void       *data,
                                      HYPRE_Real *strong_threshold )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     *strong_threshold = hypre_ParAMGDataStrongThresholdR(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetFilterThresholdR( void         *data,
                                      HYPRE_Real    filter_threshold )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     if (filter_threshold < 0 || filter_threshold > 1)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
  
     hypre_ParAMGDataFilterThresholdR(amg_data) = filter_threshold;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetFilterThresholdR( void       *data,
                                      HYPRE_Real *filter_threshold )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     *filter_threshold = hypre_ParAMGDataFilterThresholdR(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetSabs( void         *data,
                          HYPRE_Int     Sabs )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     hypre_ParAMGDataSabs(amg_data) = Sabs != 0;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetMaxRowSum( void     *data,
                            HYPRE_Real    max_row_sum )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     if (max_row_sum <= 0 || max_row_sum > 1)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
  
     hypre_ParAMGDataMaxRowSum(amg_data) = max_row_sum;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetMaxRowSum( void     *data,
                            HYPRE_Real *  max_row_sum )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     *max_row_sum = hypre_ParAMGDataMaxRowSum(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetTruncFactor( void     *data,
                              HYPRE_Real    trunc_factor )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     if (trunc_factor < 0 || trunc_factor >= 1)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
  
     hypre_ParAMGDataTruncFactor(amg_data) = trunc_factor;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetTruncFactor( void     *data,
                              HYPRE_Real *  trunc_factor )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     *trunc_factor = hypre_ParAMGDataTruncFactor(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetPMaxElmts( void     *data,
                              HYPRE_Int    P_max_elmts )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     if (P_max_elmts < 0)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
  
     hypre_ParAMGDataPMaxElmts(amg_data) = P_max_elmts;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetPMaxElmts( void     *data,
                              HYPRE_Int *  P_max_elmts )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     *P_max_elmts = hypre_ParAMGDataPMaxElmts(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetJacobiTruncThreshold( void     *data,
                              HYPRE_Real    jacobi_trunc_threshold )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     if (jacobi_trunc_threshold < 0 || jacobi_trunc_threshold >= 1)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
  
     hypre_ParAMGDataJacobiTruncThreshold(amg_data) = jacobi_trunc_threshold;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetJacobiTruncThreshold( void     *data,
                              HYPRE_Real *  jacobi_trunc_threshold )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     *jacobi_trunc_threshold = hypre_ParAMGDataJacobiTruncThreshold(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetPostInterpType( void     *data,
                                    HYPRE_Int    post_interp_type )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     if (post_interp_type < 0)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
  
     hypre_ParAMGDataPostInterpType(amg_data) = post_interp_type;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetPostInterpType( void     *data,
                                    HYPRE_Int  * post_interp_type )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     *post_interp_type = hypre_ParAMGDataPostInterpType(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetSCommPkgSwitch( void     *data,
                                    HYPRE_Real    S_commpkg_switch )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     hypre_ParAMGDataSCommPkgSwitch(amg_data) = S_commpkg_switch;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetSCommPkgSwitch( void     *data,
                                    HYPRE_Real *  S_commpkg_switch )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     *S_commpkg_switch = hypre_ParAMGDataSCommPkgSwitch(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetInterpType( void     *data,
                             HYPRE_Int       interp_type )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
  
     if ((interp_type < 0 || interp_type > 25) && interp_type != 100)
  
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
  
     hypre_ParAMGDataInterpType(amg_data) = interp_type;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetInterpType( void     *data,
                             HYPRE_Int *     interp_type )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     *interp_type = hypre_ParAMGDataInterpType(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetSepWeight( void     *data,
                             HYPRE_Int       sep_weight )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     hypre_ParAMGDataSepWeight(amg_data) = sep_weight;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetMinIter( void     *data,
                          HYPRE_Int       min_iter )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     hypre_ParAMGDataMinIter(amg_data) = min_iter;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetMinIter( void     *data,
                          HYPRE_Int *     min_iter )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     *min_iter = hypre_ParAMGDataMinIter(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetMaxIter( void     *data,
                          HYPRE_Int     max_iter )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     if (max_iter < 0)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
  
     hypre_ParAMGDataMaxIter(amg_data) = max_iter;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetMaxIter( void     *data,
                          HYPRE_Int *   max_iter )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     *max_iter = hypre_ParAMGDataMaxIter(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetCoarsenType( void  *data,
                            HYPRE_Int    coarsen_type )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     hypre_ParAMGDataCoarsenType(amg_data) = coarsen_type;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetCoarsenType( void  *data,
                            HYPRE_Int *  coarsen_type )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     *coarsen_type = hypre_ParAMGDataCoarsenType(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetMeasureType( void  *data,
                              HYPRE_Int    measure_type )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     hypre_ParAMGDataMeasureType(amg_data) = measure_type;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetMeasureType( void  *data,
                              HYPRE_Int *  measure_type )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     *measure_type = hypre_ParAMGDataMeasureType(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetSetupType( void  *data,
                               HYPRE_Int    setup_type )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     hypre_ParAMGDataSetupType(amg_data) = setup_type;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetSetupType( void  *data,
                               HYPRE_Int  *  setup_type )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     *setup_type = hypre_ParAMGDataSetupType(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetCycleType( void  *data,
                            HYPRE_Int    cycle_type )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     if (cycle_type < 0 || cycle_type > 2)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
  
     hypre_ParAMGDataCycleType(amg_data) = cycle_type;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetCycleType( void  *data,
                            HYPRE_Int *  cycle_type )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     *cycle_type = hypre_ParAMGDataCycleType(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetFCycle( void     *data,
                            HYPRE_Int fcycle )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     hypre_ParAMGDataFCycle(amg_data) = fcycle != 0;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetFCycle( void      *data,
                            HYPRE_Int *fcycle )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     *fcycle = hypre_ParAMGDataFCycle(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetConvergeType( void     *data,
                                  HYPRE_Int type  )
  {
     /* type 0: default. relative over ||b||
      *      1:          relative over ||r0||
      */
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     /*
     if ()
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
     */
  
     hypre_ParAMGDataConvergeType(amg_data) = type;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetConvergeType( void      *data,
                                  HYPRE_Int *type  )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     *type = hypre_ParAMGDataConvergeType(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetTol( void     *data,
                         HYPRE_Real    tol  )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     if (tol < 0 || tol > 1)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
  
     hypre_ParAMGDataTol(amg_data) = tol;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetTol( void     *data,
                      HYPRE_Real *  tol  )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     *tol = hypre_ParAMGDataTol(amg_data);
  
     return hypre_error_flag;
  }
  
  /* The "Get" function for SetNumSweeps is GetCycleNumSweeps. */
  HYPRE_Int
  hypre_BoomerAMGSetNumSweeps( void     *data,
                                HYPRE_Int      num_sweeps )
  {
     HYPRE_Int i;
     HYPRE_Int *num_grid_sweeps;
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     if (num_sweeps < 1)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
  
     if (hypre_ParAMGDataNumGridSweeps(amg_data) == NULL)
         hypre_ParAMGDataNumGridSweeps(amg_data) = hypre_CTAlloc(HYPRE_Int, 4, HYPRE_MEMORY_HOST);
  
     num_grid_sweeps = hypre_ParAMGDataNumGridSweeps(amg_data);
  
     for (i=0; i < 3; i++)
        num_grid_sweeps[i] = num_sweeps;
     num_grid_sweeps[3] = 1;
  
     hypre_ParAMGDataUserNumSweeps(amg_data) = num_sweeps;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetCycleNumSweeps( void     *data,
                                    HYPRE_Int      num_sweeps,
                                    HYPRE_Int      k )
  {
     HYPRE_Int i;
     HYPRE_Int *num_grid_sweeps;
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     if (num_sweeps < 0)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
  
     if (k < 1 || k > 3)
     {
        hypre_error_in_arg(3);
        return hypre_error_flag;
     }
  
     if (hypre_ParAMGDataNumGridSweeps(amg_data) == NULL)
     {
         num_grid_sweeps = hypre_CTAlloc(HYPRE_Int, 4, HYPRE_MEMORY_HOST);
         for (i=0; i < 4; i++)
            num_grid_sweeps[i] = 1;
         hypre_ParAMGDataNumGridSweeps(amg_data) = num_grid_sweeps;
     }
  
     hypre_ParAMGDataNumGridSweeps(amg_data)[k] = num_sweeps;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetCycleNumSweeps( void     *data,
                                    HYPRE_Int *    num_sweeps,
                                    HYPRE_Int      k )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if (k < 1 || k > 3)
     {
        hypre_error_in_arg(3);
        return hypre_error_flag;
     }
  
     if (hypre_ParAMGDataNumGridSweeps(amg_data) == NULL)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     *num_sweeps = hypre_ParAMGDataNumGridSweeps(amg_data)[k];
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetNumGridSweeps( void     *data,
                                HYPRE_Int      *num_grid_sweeps )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if (!num_grid_sweeps)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
  
     if (hypre_ParAMGDataNumGridSweeps(amg_data))
        hypre_TFree(hypre_ParAMGDataNumGridSweeps(amg_data), HYPRE_MEMORY_HOST);
     hypre_ParAMGDataNumGridSweeps(amg_data) = num_grid_sweeps;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetNumGridSweeps( void     *data,
                                HYPRE_Int    ** num_grid_sweeps )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     *num_grid_sweeps = hypre_ParAMGDataNumGridSweeps(amg_data);
  
     return hypre_error_flag;
  }
  
  /* The "Get" function for SetRelaxType is GetCycleRelaxType. */
  HYPRE_Int
  hypre_BoomerAMGSetRelaxType( void     *data,
                                HYPRE_Int      relax_type )
  {
     HYPRE_Int i;
     HYPRE_Int *grid_relax_type;
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if (relax_type < 0)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
  
     if (hypre_ParAMGDataGridRelaxType(amg_data) == NULL)
         hypre_ParAMGDataGridRelaxType(amg_data) = hypre_CTAlloc(HYPRE_Int, 4, HYPRE_MEMORY_HOST);
     grid_relax_type = hypre_ParAMGDataGridRelaxType(amg_data);
  
     for (i=0; i < 3; i++)
        grid_relax_type[i] = relax_type;
     grid_relax_type[3] = 9;
     hypre_ParAMGDataUserCoarseRelaxType(amg_data) = 9;
     hypre_ParAMGDataUserRelaxType(amg_data) = relax_type;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetCycleRelaxType( void     *data,
                                    HYPRE_Int      relax_type,
                                    HYPRE_Int      k )
  {
     HYPRE_Int i;
     HYPRE_Int *grid_relax_type;
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if (k < 1 || k > 3)
     {
        hypre_error_in_arg(3);
        return hypre_error_flag;
     }
     if (relax_type < 0)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
  
     if (hypre_ParAMGDataGridRelaxType(amg_data) == NULL)
     {
        grid_relax_type = hypre_CTAlloc(HYPRE_Int, 4, HYPRE_MEMORY_HOST);
        for (i=0; i < 3; i++)
        {
           grid_relax_type[i] = 3;
        }
        grid_relax_type[3] = 9;
        hypre_ParAMGDataGridRelaxType(amg_data) = grid_relax_type;
     }
  
     hypre_ParAMGDataGridRelaxType(amg_data)[k] = relax_type;
     if (k == 3)
     {
        hypre_ParAMGDataUserCoarseRelaxType(amg_data) = relax_type;
     }
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetCycleRelaxType( void     *data,
                                    HYPRE_Int    * relax_type,
                                    HYPRE_Int      k )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if (k < 1 || k > 3)
     {
        hypre_error_in_arg(3);
        return hypre_error_flag;
     }
  
     if (hypre_ParAMGDataGridRelaxType(amg_data) == NULL)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     *relax_type = hypre_ParAMGDataGridRelaxType(amg_data)[k];
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetRelaxOrder( void     *data,
                                HYPRE_Int       relax_order)
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_ParAMGDataRelaxOrder(amg_data) = relax_order;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetRelaxOrder( void     *data,
                                HYPRE_Int     * relax_order)
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     *relax_order = hypre_ParAMGDataRelaxOrder(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetGridRelaxType( void     *data,
                                HYPRE_Int      *grid_relax_type )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if (!grid_relax_type)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
  
     if (hypre_ParAMGDataGridRelaxType(amg_data))
        hypre_TFree(hypre_ParAMGDataGridRelaxType(amg_data), HYPRE_MEMORY_HOST);
     hypre_ParAMGDataGridRelaxType(amg_data) = grid_relax_type;
     hypre_ParAMGDataUserCoarseRelaxType(amg_data) = grid_relax_type[3];
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetGridRelaxType( void     *data,
                                HYPRE_Int    ** grid_relax_type )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     *grid_relax_type = hypre_ParAMGDataGridRelaxType(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetGridRelaxPoints( void     *data,
                                  HYPRE_Int      **grid_relax_points )
  {
     HYPRE_Int i;
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if (!grid_relax_points)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
  
     if (hypre_ParAMGDataGridRelaxPoints(amg_data))
     {
        for (i=0; i < 4; i++)
      hypre_TFree(hypre_ParAMGDataGridRelaxPoints(amg_data)[i], HYPRE_MEMORY_HOST);
        hypre_TFree(hypre_ParAMGDataGridRelaxPoints(amg_data), HYPRE_MEMORY_HOST);
     }
     hypre_ParAMGDataGridRelaxPoints(amg_data) = grid_relax_points;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetGridRelaxPoints( void     *data,
                                  HYPRE_Int    *** grid_relax_points )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     *grid_relax_points = hypre_ParAMGDataGridRelaxPoints(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetRelaxWeight( void     *data,
                                 HYPRE_Real   *relax_weight )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if (!relax_weight)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
  
     if (hypre_ParAMGDataRelaxWeight(amg_data))
        hypre_TFree(hypre_ParAMGDataRelaxWeight(amg_data), HYPRE_MEMORY_HOST);
     hypre_ParAMGDataRelaxWeight(amg_data) = relax_weight;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetRelaxWeight( void     *data,
                                 HYPRE_Real ** relax_weight )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     *relax_weight = hypre_ParAMGDataRelaxWeight(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetRelaxWt( void     *data,
                             HYPRE_Real    relax_weight )
  {
     HYPRE_Int i, num_levels;
     HYPRE_Real *relax_weight_array;
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     num_levels = hypre_ParAMGDataMaxLevels(amg_data);
     if (hypre_ParAMGDataRelaxWeight(amg_data) == NULL)
        hypre_ParAMGDataRelaxWeight(amg_data) = hypre_CTAlloc(HYPRE_Real, num_levels, HYPRE_MEMORY_HOST);
  
     relax_weight_array = hypre_ParAMGDataRelaxWeight(amg_data);
     for (i=0; i < num_levels; i++)
        relax_weight_array[i] = relax_weight;
  
     hypre_ParAMGDataUserRelaxWeight(amg_data) = relax_weight;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetLevelRelaxWt( void    *data,
                                  HYPRE_Real   relax_weight,
                                  HYPRE_Int      level )
  {
     HYPRE_Int i, num_levels;
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     num_levels = hypre_ParAMGDataMaxLevels(amg_data);
     if (level > num_levels-1 || level < 0)
     {
        hypre_error_in_arg(3);
        return hypre_error_flag;
     }
     if (hypre_ParAMGDataRelaxWeight(amg_data) == NULL)
     {
        hypre_ParAMGDataRelaxWeight(amg_data) = hypre_CTAlloc(HYPRE_Real, num_levels, HYPRE_MEMORY_HOST);
        for (i=0; i < num_levels; i++)
           hypre_ParAMGDataRelaxWeight(amg_data)[i] = 1.0;
     }
  
     hypre_ParAMGDataRelaxWeight(amg_data)[level] = relax_weight;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetLevelRelaxWt( void    *data,
                                  HYPRE_Real * relax_weight,
                                  HYPRE_Int      level )
  {
     HYPRE_Int num_levels;
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     num_levels = hypre_ParAMGDataMaxLevels(amg_data);
     if (level > num_levels-1 || level < 0)
     {
        hypre_error_in_arg(3);
        return hypre_error_flag;
     }
     if (hypre_ParAMGDataRelaxWeight(amg_data) == NULL)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     *relax_weight = hypre_ParAMGDataRelaxWeight(amg_data)[level];
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetOmega( void     *data,
                           HYPRE_Real   *omega )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if (!omega)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
     if (hypre_ParAMGDataOmega(amg_data))
        hypre_TFree(hypre_ParAMGDataOmega(amg_data), HYPRE_MEMORY_HOST);
     hypre_ParAMGDataOmega(amg_data) = omega;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetOmega( void     *data,
                           HYPRE_Real ** omega )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     *omega = hypre_ParAMGDataOmega(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetOuterWt( void     *data,
                             HYPRE_Real    omega )
  {
     HYPRE_Int i, num_levels;
     HYPRE_Real *omega_array;
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     num_levels = hypre_ParAMGDataMaxLevels(amg_data);
     if (hypre_ParAMGDataOmega(amg_data) == NULL)
        hypre_ParAMGDataOmega(amg_data) = hypre_CTAlloc(HYPRE_Real, num_levels, HYPRE_MEMORY_HOST);
  
     omega_array = hypre_ParAMGDataOmega(amg_data);
     for (i=0; i < num_levels; i++)
        omega_array[i] = omega;
     hypre_ParAMGDataOuterWt(amg_data) = omega;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetLevelOuterWt( void    *data,
                                  HYPRE_Real   omega,
                                  HYPRE_Int      level )
  {
     HYPRE_Int i, num_levels;
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     num_levels = hypre_ParAMGDataMaxLevels(amg_data);
     if (level > num_levels-1)
     {
        hypre_error_in_arg(3);
        return hypre_error_flag;
     }
     if (hypre_ParAMGDataOmega(amg_data) == NULL)
     {
        hypre_ParAMGDataOmega(amg_data) = hypre_CTAlloc(HYPRE_Real, num_levels, HYPRE_MEMORY_HOST);
        for (i=0; i < num_levels; i++)
           hypre_ParAMGDataOmega(amg_data)[i] = 1.0;
     }
  
     hypre_ParAMGDataOmega(amg_data)[level] = omega;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetLevelOuterWt( void    *data,
                                  HYPRE_Real * omega,
                                  HYPRE_Int      level )
  {
     HYPRE_Int num_levels;
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     num_levels = hypre_ParAMGDataMaxLevels(amg_data);
     if (level > num_levels-1)
     {
        hypre_error_in_arg(3);
        return hypre_error_flag;
     }
     if (hypre_ParAMGDataOmega(amg_data) == NULL)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     *omega = hypre_ParAMGDataOmega(amg_data)[level];
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetSmoothType( void     *data,
                                HYPRE_Int   smooth_type )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     hypre_ParAMGDataSmoothType(amg_data) = smooth_type;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetSmoothType( void     *data,
                                HYPRE_Int * smooth_type )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     *smooth_type = hypre_ParAMGDataSmoothType(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetSmoothNumLevels( void     *data,
                              HYPRE_Int   smooth_num_levels )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if (smooth_num_levels < 0)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
     hypre_ParAMGDataSmoothNumLevels(amg_data) = smooth_num_levels;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetSmoothNumLevels( void     *data,
                              HYPRE_Int * smooth_num_levels )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     *smooth_num_levels = hypre_ParAMGDataSmoothNumLevels(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetSmoothNumSweeps( void     *data,
                              HYPRE_Int   smooth_num_sweeps )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if (smooth_num_sweeps < 0)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
     hypre_ParAMGDataSmoothNumSweeps(amg_data) = smooth_num_sweeps;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetSmoothNumSweeps( void     *data,
                              HYPRE_Int * smooth_num_sweeps )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     *smooth_num_sweeps = hypre_ParAMGDataSmoothNumSweeps(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetLogging( void     *data,
                              HYPRE_Int       logging )
  {
     /* This function should be called before Setup.  Logging changes
        may require allocation or freeing of arrays, which is presently
        only done there.
        It may be possible to support logging changes at other times,
        but there is little need.
     */
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_ParAMGDataLogging(amg_data) = logging;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetLogging( void     *data,
                              HYPRE_Int     * logging )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     *logging = hypre_ParAMGDataLogging(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetPrintLevel( void     *data,
                          HYPRE_Int print_level )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_ParAMGDataPrintLevel(amg_data) = print_level;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetPrintLevel( void     *data,
                          HYPRE_Int * print_level )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     *print_level =  hypre_ParAMGDataPrintLevel(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetPrintFileName( void       *data,
                                 const char *print_file_name )
  {
     hypre_ParAMGData  *amg_data =  (hypre_ParAMGData*)data;
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if ( strlen(print_file_name) > 256 )
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
  
     hypre_sprintf(hypre_ParAMGDataLogFileName(amg_data), "%s", print_file_name);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetPrintFileName( void       *data,
                                   char ** print_file_name )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_sprintf( *print_file_name, "%s", hypre_ParAMGDataLogFileName(amg_data) );
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetNumIterations( void    *data,
                                HYPRE_Int      num_iterations )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_ParAMGDataNumIterations(amg_data) = num_iterations;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetDebugFlag( void     *data,
                            HYPRE_Int       debug_flag )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_ParAMGDataDebugFlag(amg_data) = debug_flag;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetDebugFlag( void     *data,
                            HYPRE_Int     * debug_flag )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     *debug_flag = hypre_ParAMGDataDebugFlag(amg_data);
  
     return hypre_error_flag;
  }
  
  /*--------------------------------------------------------------------------
   * hypre_BoomerAMGSetGSMG
   *--------------------------------------------------------------------------*/
  
  HYPRE_Int
  hypre_BoomerAMGSetGSMG( void       *data,
                          HYPRE_Int   par )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     amg_data->gsmg = par;
  
     return hypre_error_flag;
  }
  
  /*--------------------------------------------------------------------------
   * hypre_BoomerAMGSetNumSamples
   *--------------------------------------------------------------------------*/
  
  HYPRE_Int
  hypre_BoomerAMGSetNumSamples( void *data,
                          HYPRE_Int   par )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     amg_data->num_samples = par;
  
     return hypre_error_flag;
  }
  
  /* BM Aug 25, 2006 */
  
  HYPRE_Int
  hypre_BoomerAMGSetCGCIts( void *data,
                            HYPRE_Int  its)
  {
    HYPRE_Int ierr = 0;
    hypre_ParAMGData *amg_data = (hypre_ParAMGData*) data;
  
    hypre_ParAMGDataCGCIts(amg_data) = its;
    return (ierr);
  }
  
  /* BM Oct 22, 2006 */
  HYPRE_Int
  hypre_BoomerAMGSetPlotGrids( void *data,
                            HYPRE_Int plotgrids)
  {
    HYPRE_Int ierr = 0;
    hypre_ParAMGData *amg_data = (hypre_ParAMGData*) data;
  
    hypre_ParAMGDataPlotGrids(amg_data) = plotgrids;
    return (ierr);
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetPlotFileName( void       *data,
                                const char *plot_file_name )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if ( strlen(plot_file_name)>251 )
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
     if (strlen(plot_file_name)==0 )
       hypre_sprintf(hypre_ParAMGDataPlotFileName(amg_data), "%s", "AMGgrids.CF.dat");
     else
       hypre_sprintf(hypre_ParAMGDataPlotFileName(amg_data), "%s", plot_file_name);
  
     return hypre_error_flag;
  }
  /* Get the coarse grid hierarchy. Assumes cgrid is preallocated to the size of the local matrix.
   * Adapted from par_amg_setup.c, and simplified by ignoring printing in block mode.
   * We do a memcpy on the final grid hierarchy to avoid modifying user allocated data.
  */
  HYPRE_Int
  hypre_BoomerAMGGetGridHierarchy( void       *data,
                                HYPRE_Int *cgrid )
  {
     HYPRE_Int *ibuff = NULL;
     HYPRE_Int *wbuff, *cbuff, *tmp;
     HYPRE_Int local_size, lev_size, i, j, level, num_levels, block_mode;
     HYPRE_Int          **CF_marker_array;
  
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if (!cgrid)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
  
     block_mode = hypre_ParAMGDataBlockMode(amg_data);
  
     if( block_mode)
     {
        hypre_ParCSRBlockMatrix **A_block_array;
        A_block_array = hypre_ParAMGDataABlockArray(amg_data);
        if(A_block_array == NULL)
        {
           hypre_error_w_msg(HYPRE_ERROR_GENERIC,"Invalid AMG data. AMG setup has not been called!!\n");
           return hypre_error_flag;
        }
  
        CF_marker_array = hypre_ParAMGDataCFMarkerArray(amg_data);
  
        // get local size and allocate some memory
        local_size = hypre_CSRMatrixNumRows(hypre_ParCSRBlockMatrixDiag(A_block_array[0]));
        ibuff  = hypre_CTAlloc(HYPRE_Int, (2 * local_size), HYPRE_MEMORY_HOST);
        wbuff  = ibuff;
        cbuff  = ibuff + local_size;
  
        num_levels = hypre_ParAMGDataNumLevels(amg_data);
        for (level = (num_levels - 2); level >= 0; level--)
        {
           /* swap pointers */
           tmp = wbuff;
           wbuff = cbuff;
           cbuff = tmp;
  
           lev_size = hypre_CSRMatrixNumRows(hypre_ParCSRBlockMatrixDiag(A_block_array[level]));
  
           for (i = 0, j = 0; i < lev_size; i++)
           {
              /* if a C-point */
              cbuff[i] = 0;
              if (CF_marker_array[level][i] > -1)
              {
                 cbuff[i] = wbuff[j] + 1;
                 j++;
              }
           }
        }
     }
     else
     {
        hypre_ParCSRMatrix **A_array;
        A_array = hypre_ParAMGDataAArray(amg_data);
        if(A_array == NULL)
        {
           hypre_error_w_msg(HYPRE_ERROR_GENERIC,"Invalid AMG data. AMG setup has not been called!!\n");
           return hypre_error_flag;
        }
  
        CF_marker_array = hypre_ParAMGDataCFMarkerArray(amg_data);
  
        // get local size and allocate some memory
        local_size = hypre_CSRMatrixNumRows(hypre_ParCSRMatrixDiag(A_array[0]));
        wbuff  = hypre_CTAlloc(HYPRE_Int, (2 * local_size), HYPRE_MEMORY_HOST);
        cbuff  = wbuff + local_size;
  
        num_levels = hypre_ParAMGDataNumLevels(amg_data);
        for (level = (num_levels - 2); level >= 0; level--)
        {
           /* swap pointers */
           tmp = wbuff;
           wbuff = cbuff;
           cbuff = tmp;
  
           lev_size = hypre_CSRMatrixNumRows(hypre_ParCSRMatrixDiag(A_array[level]));
  
           for (i = 0, j = 0; i < lev_size; i++)
           {
              /* if a C-point */
              cbuff[i] = 0;
              if (CF_marker_array[level][i] > -1)
              {
                 cbuff[i] = wbuff[j] + 1;
                 j++;
              }
           }
        }
     }
     // copy hierarchy into user provided array
     hypre_TMemcpy(cgrid, cbuff, HYPRE_Int, local_size, HYPRE_MEMORY_HOST, HYPRE_MEMORY_HOST);
     // free memory
     hypre_TFree(ibuff, HYPRE_MEMORY_HOST);
  
     return hypre_error_flag;
  }
  
  /* BM Oct 17, 2006 */
  HYPRE_Int
  hypre_BoomerAMGSetCoordDim( void *data,
                            HYPRE_Int coorddim)
  {
    HYPRE_Int ierr = 0;
    hypre_ParAMGData *amg_data = (hypre_ParAMGData*) data;
  
    hypre_ParAMGDataCoordDim(amg_data) = coorddim;
    return (ierr);
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetCoordinates( void *data,
                               float *coordinates)
  {
    HYPRE_Int ierr = 0;
    hypre_ParAMGData *amg_data = (hypre_ParAMGData*) data;
  
    hypre_ParAMGDataCoordinates(amg_data) = coordinates;
    return (ierr);
  }
  
  /*--------------------------------------------------------------------------
   * Routines to set the problem data parameters
   *--------------------------------------------------------------------------*/
  
  HYPRE_Int
  hypre_BoomerAMGSetNumFunctions( void     *data,
                              HYPRE_Int       num_functions )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if (num_functions < 1)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
     hypre_ParAMGDataNumFunctions(amg_data) = num_functions;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetNumFunctions( void     *data,
                              HYPRE_Int     * num_functions )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     *num_functions = hypre_ParAMGDataNumFunctions(amg_data);
  
     return hypre_error_flag;
  }
  
  /*--------------------------------------------------------------------------
   * Indicate whether to use nodal systems function
   *--------------------------------------------------------------------------*/
  
  HYPRE_Int
  hypre_BoomerAMGSetNodal( void     *data,
                            HYPRE_Int    nodal )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_ParAMGDataNodal(amg_data) = nodal;
  
     return hypre_error_flag;
  }
  /*--------------------------------------------------------------------------
   * Indicate number of levels for nodal coarsening
   *--------------------------------------------------------------------------*/
  
  HYPRE_Int
  hypre_BoomerAMGSetNodalLevels( void     *data,
                            HYPRE_Int    nodal_levels )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_ParAMGDataNodalLevels(amg_data) = nodal_levels;
  
     return hypre_error_flag;
  }
  
  
  /*--------------------------------------------------------------------------
   * Indicate how to treat diag for primary matrix with  nodal systems function
   *--------------------------------------------------------------------------*/
  
  HYPRE_Int
  hypre_BoomerAMGSetNodalDiag( void     *data,
                            HYPRE_Int    nodal )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_ParAMGDataNodalDiag(amg_data) = nodal;
  
     return hypre_error_flag;
  }
  /*--------------------------------------------------------------------------
   * Indicate the degree of aggressive coarsening
   *--------------------------------------------------------------------------*/
  
  HYPRE_Int
  hypre_BoomerAMGSetNumPaths( void     *data,
                              HYPRE_Int       num_paths )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if (num_paths < 1)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
     hypre_ParAMGDataNumPaths(amg_data) = num_paths;
  
     return hypre_error_flag;
  }
  
  /*--------------------------------------------------------------------------
   * Indicates the number of levels of aggressive coarsening
   *--------------------------------------------------------------------------*/
  
  HYPRE_Int
  hypre_BoomerAMGSetAggNumLevels( void     *data,
                              HYPRE_Int       agg_num_levels )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if (agg_num_levels < 0)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
     hypre_ParAMGDataAggNumLevels(amg_data) = agg_num_levels;
  
     return hypre_error_flag;
  }
  
  /*--------------------------------------------------------------------------
   * Indicates the interpolation used with aggressive coarsening
   *--------------------------------------------------------------------------*/
  
  HYPRE_Int
  hypre_BoomerAMGSetAggInterpType( void     *data,
                              HYPRE_Int       agg_interp_type )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if (agg_interp_type < 0 || agg_interp_type > 7)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
     hypre_ParAMGDataAggInterpType(amg_data) = agg_interp_type;
  
     return hypre_error_flag;
  }
  
  /*--------------------------------------------------------------------------
   * Indicates max number of elements per row for aggressive coarsening
   * interpolation
   *--------------------------------------------------------------------------*/
  
  HYPRE_Int
  hypre_BoomerAMGSetAggPMaxElmts( void     *data,
                              HYPRE_Int       agg_P_max_elmts )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if (agg_P_max_elmts < 0)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
     hypre_ParAMGDataAggPMaxElmts(amg_data) = agg_P_max_elmts;
  
     return hypre_error_flag;
  }
  
  /*--------------------------------------------------------------------------
   * Indicates max number of elements per row for smoothed
   * interpolation in mult-additive or simple method
   *--------------------------------------------------------------------------*/
  
  HYPRE_Int
  hypre_BoomerAMGSetMultAddPMaxElmts( void     *data,
                              HYPRE_Int       add_P_max_elmts )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if (add_P_max_elmts < 0)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
     hypre_ParAMGDataMultAddPMaxElmts(amg_data) = add_P_max_elmts;
  
     return hypre_error_flag;
  }
  
  /*--------------------------------------------------------------------------
   * Indicates Relaxtion Type for Additive Cycle
   *--------------------------------------------------------------------------*/
  
  HYPRE_Int
  hypre_BoomerAMGSetAddRelaxType( void     *data,
                              HYPRE_Int       add_rlx_type )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_ParAMGDataAddRelaxType(amg_data) = add_rlx_type;
  
     return hypre_error_flag;
  }
  
  /*--------------------------------------------------------------------------
   * Indicates Relaxation Weight for Additive Cycle
   *--------------------------------------------------------------------------*/
  
  HYPRE_Int
  hypre_BoomerAMGSetAddRelaxWt( void     *data,
                              HYPRE_Real       add_rlx_wt )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_ParAMGDataAddRelaxWt(amg_data) = add_rlx_wt;
  
     return hypre_error_flag;
  }
  
  /*--------------------------------------------------------------------------
   * Indicates max number of elements per row for 1st stage of aggressive
   * coarsening two-stage interpolation
   *--------------------------------------------------------------------------*/
  
  HYPRE_Int
  hypre_BoomerAMGSetAggP12MaxElmts( void     *data,
                              HYPRE_Int       agg_P12_max_elmts )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if (agg_P12_max_elmts < 0)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
     hypre_ParAMGDataAggP12MaxElmts(amg_data) = agg_P12_max_elmts;
  
     return hypre_error_flag;
  }
  
  /*--------------------------------------------------------------------------
   * Indicates truncation factor for aggressive coarsening interpolation
   *--------------------------------------------------------------------------*/
  
  HYPRE_Int
  hypre_BoomerAMGSetAggTruncFactor( void     *data,
                              HYPRE_Real  agg_trunc_factor )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if (agg_trunc_factor < 0)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
     hypre_ParAMGDataAggTruncFactor(amg_data) = agg_trunc_factor;
  
     return hypre_error_flag;
  }
  
  /*--------------------------------------------------------------------------
   * Indicates the truncation factor for smoothed interpolation when using
   * mult-additive or simple method
   *--------------------------------------------------------------------------*/
  
  HYPRE_Int
  hypre_BoomerAMGSetMultAddTruncFactor( void     *data,
                              HYPRE_Real      add_trunc_factor )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if (add_trunc_factor < 0)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
     hypre_ParAMGDataMultAddTruncFactor(amg_data) = add_trunc_factor;
  
     return hypre_error_flag;
  }
  
  /*--------------------------------------------------------------------------
   * Indicates truncation factor for 1 stage of aggressive coarsening
   * two stage interpolation
   *--------------------------------------------------------------------------*/
  
  HYPRE_Int
  hypre_BoomerAMGSetAggP12TruncFactor( void     *data,
                              HYPRE_Real  agg_P12_trunc_factor )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if (agg_P12_trunc_factor < 0)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
     hypre_ParAMGDataAggP12TruncFactor(amg_data) = agg_P12_trunc_factor;
  
     return hypre_error_flag;
  }
  
  /*--------------------------------------------------------------------------
   * Indicates the number of relaxation steps for Compatible relaxation
   *--------------------------------------------------------------------------*/
  
  HYPRE_Int
  hypre_BoomerAMGSetNumCRRelaxSteps( void     *data,
                              HYPRE_Int       num_CR_relax_steps )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if (num_CR_relax_steps < 1)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
     hypre_ParAMGDataNumCRRelaxSteps(amg_data) = num_CR_relax_steps;
  
     return hypre_error_flag;
  }
  
  /*--------------------------------------------------------------------------
   * Indicates the desired convergence rate for Compatible relaxation
   *--------------------------------------------------------------------------*/
  
  HYPRE_Int
  hypre_BoomerAMGSetCRRate( void     *data,
                            HYPRE_Real    CR_rate )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_ParAMGDataCRRate(amg_data) = CR_rate;
  
     return hypre_error_flag;
  }
  
  /*--------------------------------------------------------------------------
   * Indicates the desired convergence rate for Compatible relaxation
   *--------------------------------------------------------------------------*/
  
  HYPRE_Int
  hypre_BoomerAMGSetCRStrongTh( void     *data,
                                HYPRE_Real    CR_strong_th )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_ParAMGDataCRStrongTh(amg_data) = CR_strong_th;
  
     return hypre_error_flag;
  }
  
  /*--------------------------------------------------------------------------
   * Indicates the drop tolerance for A-matrices from the 2nd level of AMG
   *--------------------------------------------------------------------------*/
  
  HYPRE_Int
  hypre_BoomerAMGSetADropTol( void     *data,
                              HYPRE_Real  A_drop_tol )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_ParAMGDataADropTol(amg_data) = A_drop_tol;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetADropType( void      *data,
                               HYPRE_Int  A_drop_type )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_ParAMGDataADropType(amg_data) = A_drop_type;
  
     return hypre_error_flag;
  }
  /*--------------------------------------------------------------------------
   * Indicates which independent set algorithm is used for CR
   *--------------------------------------------------------------------------*/
  
  HYPRE_Int
  hypre_BoomerAMGSetISType( void     *data,
                              HYPRE_Int      IS_type )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if (IS_type < 0)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
     hypre_ParAMGDataISType(amg_data) = IS_type;
  
     return hypre_error_flag;
  }
  
  /*--------------------------------------------------------------------------
   * Indicates whether to use CG for compatible relaxation
   *--------------------------------------------------------------------------*/
  
  HYPRE_Int
  hypre_BoomerAMGSetCRUseCG( void     *data,
                              HYPRE_Int      CR_use_CG )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_ParAMGDataCRUseCG(amg_data) = CR_use_CG;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetNumPoints( void     *data,
                            HYPRE_Int       num_points )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_ParAMGDataNumPoints(amg_data) = num_points;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetDofFunc( void     *data,
                             HYPRE_Int      *dof_func )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_TFree(hypre_ParAMGDataDofFunc(amg_data), HYPRE_MEMORY_HOST);
     hypre_ParAMGDataDofFunc(amg_data) = dof_func;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetPointDofMap( void     *data,
                           HYPRE_Int      *point_dof_map )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_TFree(hypre_ParAMGDataPointDofMap(amg_data), HYPRE_MEMORY_HOST);
     hypre_ParAMGDataPointDofMap(amg_data) = point_dof_map;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetDofPoint( void     *data,
                           HYPRE_Int      *dof_point )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_TFree(hypre_ParAMGDataDofPoint(amg_data), HYPRE_MEMORY_HOST);
     hypre_ParAMGDataDofPoint(amg_data) = dof_point;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetNumIterations( void     *data,
                                HYPRE_Int      *num_iterations )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     *num_iterations = hypre_ParAMGDataNumIterations(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetCumNumIterations( void     *data,
                                      HYPRE_Int      *cum_num_iterations )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  #ifdef CUMNUMIT
     *cum_num_iterations = hypre_ParAMGDataCumNumIterations(amg_data);
  #endif
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetResidual( void * data, hypre_ParVector ** resid )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     *resid = hypre_ParAMGDataResidual( amg_data );
     return hypre_error_flag;
  }
  
  
  HYPRE_Int
  hypre_BoomerAMGGetRelResidualNorm( void     *data,
                                       HYPRE_Real   *rel_resid_norm )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     *rel_resid_norm = hypre_ParAMGDataRelativeResidualNorm(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetVariant( void     *data,
                              HYPRE_Int       variant)
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if (variant < 0)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
     hypre_ParAMGDataVariant(amg_data) = variant;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetVariant( void     *data,
                              HYPRE_Int     * variant)
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     *variant = hypre_ParAMGDataVariant(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetOverlap( void     *data,
                              HYPRE_Int       overlap)
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if (overlap < 0)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
     hypre_ParAMGDataOverlap(amg_data) = overlap;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetOverlap( void     *data,
                              HYPRE_Int     * overlap)
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     *overlap = hypre_ParAMGDataOverlap(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetDomainType( void     *data,
                              HYPRE_Int       domain_type)
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if (domain_type < 0)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
     hypre_ParAMGDataDomainType(amg_data) = domain_type;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetDomainType( void     *data,
                              HYPRE_Int     * domain_type)
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     *domain_type = hypre_ParAMGDataDomainType(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetSchwarzRlxWeight( void     *data,
                              HYPRE_Real schwarz_rlx_weight)
  {
     hypre_ParAMGData  *amg_data =  (hypre_ParAMGData*)data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_ParAMGDataSchwarzRlxWeight(amg_data) = schwarz_rlx_weight;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetSchwarzRlxWeight( void     *data,
                              HYPRE_Real   * schwarz_rlx_weight)
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     *schwarz_rlx_weight = hypre_ParAMGDataSchwarzRlxWeight(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetSchwarzUseNonSymm( void     *data,
                                       HYPRE_Int use_nonsymm)
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_ParAMGDataSchwarzUseNonSymm(amg_data) = use_nonsymm;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetSym( void     *data,
                              HYPRE_Int       sym)
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_ParAMGDataSym(amg_data) = sym;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetLevel( void     *data,
                              HYPRE_Int       level)
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_ParAMGDataLevel(amg_data) = level;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetThreshold( void     *data,
                               HYPRE_Real    thresh)
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_ParAMGDataThreshold(amg_data) = thresh;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetFilter( void     *data,
                            HYPRE_Real    filter)
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_ParAMGDataFilter(amg_data) = filter;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetDropTol( void     *data,
                             HYPRE_Real    drop_tol)
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_ParAMGDataDropTol(amg_data) = drop_tol;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetMaxNzPerRow( void     *data,
                                 HYPRE_Int       max_nz_per_row)
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if (max_nz_per_row < 0)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
     hypre_ParAMGDataMaxNzPerRow(amg_data) = max_nz_per_row;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetEuclidFile( void     *data,
                                char     *euclidfile)
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_ParAMGDataEuclidFile(amg_data) = euclidfile;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetEuLevel( void     *data,
                              HYPRE_Int      eu_level)
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_ParAMGDataEuLevel(amg_data) = eu_level;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetEuSparseA( void     *data,
                               HYPRE_Real    eu_sparse_A)
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_ParAMGDataEuSparseA(amg_data) = eu_sparse_A;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetEuBJ( void     *data,
                          HYPRE_Int       eu_bj)
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_ParAMGDataEuBJ(amg_data) = eu_bj;
  
     return hypre_error_flag;
  }
  HYPRE_Int
  hypre_BoomerAMGSetChebyOrder( void     *data,
                                HYPRE_Int       order)
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if (order < 1)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
     hypre_ParAMGDataChebyOrder(amg_data) = order;
  
     return hypre_error_flag;
  }
  HYPRE_Int
  hypre_BoomerAMGSetChebyFraction( void     *data,
                                   HYPRE_Real  ratio)
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if (ratio <= 0.0 || ratio > 1.0 )
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
     hypre_ParAMGDataChebyFraction(amg_data) = ratio;
  
     return hypre_error_flag;
  }
  HYPRE_Int
  hypre_BoomerAMGSetChebyEigEst( void     *data,
                                HYPRE_Int     cheby_eig_est)
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if (cheby_eig_est < 0)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
     hypre_ParAMGDataChebyEigEst(amg_data) = cheby_eig_est;
  
     return hypre_error_flag;
  }
  HYPRE_Int
  hypre_BoomerAMGSetChebyVariant( void     *data,
                                HYPRE_Int     cheby_variant)
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_ParAMGDataChebyVariant(amg_data) = cheby_variant;
  
     return hypre_error_flag;
  }
  HYPRE_Int
  hypre_BoomerAMGSetChebyScale( void     *data,
                                HYPRE_Int     cheby_scale)
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_ParAMGDataChebyScale(amg_data) = cheby_scale;
  
     return hypre_error_flag;
  }
  
  
  /*--------------------------------------------------------------------------
   * hypre_BoomerAMGSetInterpVectors
   * -used for post-interpolation fitting of smooth vectors
   *--------------------------------------------------------------------------*/
  
  HYPRE_Int hypre_BoomerAMGSetInterpVectors(void *solver,
                                      HYPRE_Int  num_vectors,
                                      hypre_ParVector **interp_vectors)
  
  {
     hypre_ParAMGData *amg_data = (hypre_ParAMGData*) solver;
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     hypre_ParAMGInterpVectors(amg_data) =  interp_vectors;
     hypre_ParAMGNumInterpVectors(amg_data) = num_vectors;
  
     return hypre_error_flag;
  }
  
  /*--------------------------------------------------------------------------
   * hypre_BoomerAMGSetInterpVectorValues
   * -used for post-interpolation fitting of smooth vectors
   *--------------------------------------------------------------------------*/
  
  /*HYPRE_Int hypre_BoomerAMGSetInterpVectorValues(void *solver,
                                      HYPRE_Int  num_vectors,
                                      HYPRE_Complex *interp_vector_values)
  
  {
     hypre_ParAMGData *amg_data = solver;
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     hypre_ParAMGInterpVectors(amg_data) =  interp_vectors;
     hypre_ParAMGNumInterpVectors(amg_data) = num_vectors;
  
     return hypre_error_flag;
  }*/
  
  HYPRE_Int hypre_BoomerAMGSetInterpVecVariant(void *solver,
                                         HYPRE_Int  var)
  
  
  {
     hypre_ParAMGData *amg_data = (hypre_ParAMGData*) solver;
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     if (var < 1)
        var = 0;
     if (var > 3)
        var = 3;
  
     hypre_ParAMGInterpVecVariant(amg_data) = var;
  
     return hypre_error_flag;
  
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetInterpVecQMax( void     *data,
                                   HYPRE_Int    q_max)
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_ParAMGInterpVecQMax(amg_data) = q_max;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetInterpVecAbsQTrunc( void     *data,
                                        HYPRE_Real    q_trunc)
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     hypre_ParAMGInterpVecAbsQTrunc(amg_data) = q_trunc;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int hypre_BoomerAMGSetSmoothInterpVectors(void *solver,
                                            HYPRE_Int  smooth_interp_vectors)
  
  {
     hypre_ParAMGData *amg_data = (hypre_ParAMGData*) solver;
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     hypre_ParAMGSmoothInterpVectors(amg_data) = smooth_interp_vectors;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetInterpRefine( void     *data,
                                  HYPRE_Int       num_refine )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     hypre_ParAMGInterpRefine(amg_data) = num_refine;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetInterpVecFirstLevel( void     *data,
                                         HYPRE_Int  level )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     hypre_ParAMGInterpVecFirstLevel(amg_data) = level;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetAdditive( void *data,
                            HYPRE_Int   additive )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     hypre_ParAMGDataAdditive(amg_data) = additive;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetAdditive( void *data,
                               HYPRE_Int *  additive )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     *additive = hypre_ParAMGDataAdditive(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetMultAdditive( void *data,
                            HYPRE_Int   mult_additive )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     hypre_ParAMGDataMultAdditive(amg_data) = mult_additive;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetMultAdditive( void *data,
                               HYPRE_Int *  mult_additive )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     *mult_additive = hypre_ParAMGDataMultAdditive(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetSimple( void *data,
                            HYPRE_Int   simple )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     hypre_ParAMGDataSimple(amg_data) = simple;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGGetSimple( void *data,
                               HYPRE_Int *  simple )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     *simple = hypre_ParAMGDataSimple(amg_data);
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetAddLastLvl( void *data,
                            HYPRE_Int   add_last_lvl )
  {
     hypre_ParAMGData  *amg_data = (hypre_ParAMGData*) data;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     hypre_ParAMGDataAddLastLvl(amg_data) = add_last_lvl;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetNonGalerkinTol( void   *data,
                              HYPRE_Real nongalerkin_tol)
  {
     hypre_ParAMGData *amg_data = (hypre_ParAMGData*) data;
     HYPRE_Int i, max_num_levels;
     HYPRE_Real *nongal_tol_array;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if (nongalerkin_tol < 0)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
     max_num_levels = hypre_ParAMGDataMaxLevels(amg_data);
     nongal_tol_array = hypre_ParAMGDataNonGalTolArray(amg_data);
  
     if (nongal_tol_array == NULL)
     {
        nongal_tol_array = hypre_CTAlloc(HYPRE_Real,  max_num_levels, HYPRE_MEMORY_HOST);
        hypre_ParAMGDataNonGalTolArray(amg_data) = nongal_tol_array;
     }
     hypre_ParAMGDataNonGalerkinTol(amg_data) = nongalerkin_tol;
  
     for (i=0; i < max_num_levels; i++)
        nongal_tol_array[i] = nongalerkin_tol;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetLevelNonGalerkinTol( void   *data,
                              HYPRE_Real   nongalerkin_tol,
                              HYPRE_Int level)
  {
     hypre_ParAMGData *amg_data = (hypre_ParAMGData*) data;
     HYPRE_Real *nongal_tol_array;
     HYPRE_Int max_num_levels;
  
     if (!amg_data)
     {
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     if (nongalerkin_tol < 0)
     {
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
  
     nongal_tol_array = hypre_ParAMGDataNonGalTolArray(amg_data);
     max_num_levels = hypre_ParAMGDataMaxLevels(amg_data);
  
     if (nongal_tol_array == NULL)
     {
        nongal_tol_array = hypre_CTAlloc(HYPRE_Real,  max_num_levels, HYPRE_MEMORY_HOST);
        hypre_ParAMGDataNonGalTolArray(amg_data) = nongal_tol_array;
     }
  
     if (level+1 > max_num_levels)
     {
        hypre_error_in_arg(3);
        return hypre_error_flag;
     }
  
     nongal_tol_array[level] = nongalerkin_tol;
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetNonGalerkTol( void   *data,
                              HYPRE_Int   nongalerk_num_tol,
                              HYPRE_Real *nongalerk_tol)
  {
    hypre_ParAMGData *amg_data = (hypre_ParAMGData*) data;
  
    hypre_ParAMGDataNonGalerkNumTol(amg_data) = nongalerk_num_tol;
    hypre_ParAMGDataNonGalerkTol(amg_data) = nongalerk_tol;
    return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetRAP2( void      *data,
                          HYPRE_Int  rap2 )
  {
    hypre_ParAMGData *amg_data = (hypre_ParAMGData*) data;
  
    hypre_ParAMGDataRAP2(amg_data) = rap2;
    return hypre_error_flag;
  }
  
  
  HYPRE_Int
  hypre_BoomerAMGSetModuleRAP2( void      *data,
                                HYPRE_Int  mod_rap2 )
  {
    hypre_ParAMGData *amg_data = (hypre_ParAMGData*) data;
  
    hypre_ParAMGDataModularizedMatMat(amg_data) = mod_rap2;
    return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetKeepTranspose( void       *data,
                                   HYPRE_Int   keepTranspose)
  {
    hypre_ParAMGData *amg_data = (hypre_ParAMGData*) data;
  
    hypre_ParAMGDataKeepTranspose(amg_data) = keepTranspose;
    return hypre_error_flag;
  }
  
  #ifdef HYPRE_USING_DSUPERLU
  HYPRE_Int
  hypre_BoomerAMGSetDSLUThreshold( void   *data,
                              HYPRE_Int   dslu_threshold)
  {
    hypre_ParAMGData *amg_data = (hypre_ParAMGData*) data;
  
    hypre_ParAMGDataDSLUThreshold(amg_data) = dslu_threshold;
    return hypre_error_flag;
  }
  #endif
  
  HYPRE_Int
  hypre_BoomerAMGSetCPoints(void         *data,
                            HYPRE_Int     cpt_coarse_level,
                            HYPRE_Int     num_cpt_coarse,
                            HYPRE_BigInt *cpt_coarse_index)
  {
     hypre_ParAMGData *amg_data = (hypre_ParAMGData*) data;
  
     HYPRE_BigInt     *C_points_marker = NULL;
     HYPRE_Int        *C_points_local_marker = NULL;
     HYPRE_Int         cpt_level;
     HYPRE_Int         i;
  
     if (!amg_data)
     {
        hypre_error_w_msg(HYPRE_ERROR_GENERIC, "Warning! AMG object empty!\n");
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
     if (cpt_coarse_level < 0)
     {
        hypre_error_w_msg(HYPRE_ERROR_GENERIC, "Warning! cpt_coarse_level < 0 !\n");
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
     if (num_cpt_coarse < 0)
     {
        hypre_error_w_msg(HYPRE_ERROR_GENERIC, "Warning! num_cpt_coarse < 0 !\n");
        hypre_error_in_arg(3);
        return hypre_error_flag;
     }
  
     /* free data not previously destroyed */
     if (hypre_ParAMGDataCPointsLevel(amg_data))
     {
        hypre_TFree(hypre_ParAMGDataCPointsMarker(amg_data), HYPRE_MEMORY_HOST);
        hypre_TFree(hypre_ParAMGDataCPointsLocalMarker(amg_data), HYPRE_MEMORY_HOST);
        hypre_ParAMGDataCPointsMarker(amg_data) = NULL;
        hypre_ParAMGDataCPointsLocalMarker(amg_data) = NULL;
     }
  
     /* set Cpoint data */
     if (hypre_ParAMGDataMaxLevels(amg_data) < cpt_coarse_level)
     {
        cpt_level = hypre_ParAMGDataNumLevels(amg_data);
     }
     else
     {
        cpt_level = cpt_coarse_level;
     }
  
     if (cpt_level)
     {
        C_points_marker       = hypre_CTAlloc(HYPRE_BigInt, num_cpt_coarse, HYPRE_MEMORY_HOST);
        C_points_local_marker = hypre_CTAlloc(HYPRE_Int, num_cpt_coarse, HYPRE_MEMORY_HOST);
  
        /* copy Cpoints indexes */
        for (i = 0; i < num_cpt_coarse; i++)
        {
           C_points_marker[i] = cpt_coarse_index[i];
        }
     }
     hypre_ParAMGDataCPointsMarker(amg_data)      = C_points_marker;
     hypre_ParAMGDataCPointsLocalMarker(amg_data) = C_points_local_marker;
     hypre_ParAMGDataNumCPoints(amg_data)         = num_cpt_coarse;
     hypre_ParAMGDataCPointsLevel(amg_data)       = cpt_level;
  
     return hypre_error_flag;
  }
  
  HYPRE_Int
  hypre_BoomerAMGSetFPoints(void         *data,
                            HYPRE_Int     isolated,
                            HYPRE_Int     num_points,
                            HYPRE_BigInt *indices)
  {
     hypre_ParAMGData   *amg_data = (hypre_ParAMGData*) data;
     HYPRE_BigInt       *marker = NULL;
     HYPRE_Int           i;
  
     if (!amg_data)
     {
        hypre_error_w_msg(HYPRE_ERROR_GENERIC, "AMG object empty!\n");
        hypre_error_in_arg(1);
        return hypre_error_flag;
     }
  
     if (num_points < 0)
     {
        hypre_error_w_msg(HYPRE_ERROR_GENERIC, "Warning! negative number of points!\n");
        hypre_error_in_arg(2);
        return hypre_error_flag;
     }
  
  
     if ((num_points > 0) && (!indices))
     {
        hypre_error_w_msg(HYPRE_ERROR_GENERIC, "Warning! indices not given!\n");
        hypre_error_in_arg(4);
        return hypre_error_flag;
     }
  
     /* Set marker data */
     if (num_points > 0)
     {
        marker = hypre_CTAlloc(HYPRE_BigInt, num_points, HYPRE_MEMORY_HOST);
        for (i = 0; i < num_points; i++)
        {
           marker[i] = indices[i];
        }
     }
  
     if (isolated)
     {
        /* Free data not previously destroyed */
        if (hypre_ParAMGDataIsolatedFPointsMarker(amg_data))
        {
           hypre_TFree(hypre_ParAMGDataIsolatedFPointsMarker(amg_data), HYPRE_MEMORY_HOST);
           hypre_ParAMGDataIsolatedFPointsMarker(amg_data) = NULL;
        }
  
        hypre_ParAMGDataNumIsolatedFPoints(amg_data)    = num_points;
        hypre_ParAMGDataIsolatedFPointsMarker(amg_data) = marker;
     }
     else
     {
        /* Free data not previously destroyed */
        if (hypre_ParAMGDataFPointsMarker(amg_data))
        {
           hypre_TFree(hypre_ParAMGDataFPointsMarker(amg_data), HYPRE_MEMORY_HOST);
           hypre_ParAMGDataFPointsMarker(amg_data) = NULL;
        }
  
        hypre_ParAMGDataNumFPoints(amg_data)    = num_points;
        hypre_ParAMGDataFPointsMarker(amg_data) = marker;
     }
  
     return hypre_error_flag;
  }
  