/*BHEADER********************************************************************** * Copyright (c) 2008, Lawrence Livermore National Security, LLC. * Produced at the Lawrence Livermore National Laboratory. * This file is part of HYPRE. See file COPYRIGHT for details. * * HYPRE is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License (as published by the Free * Software Foundation) version 2.1 dated February 1999. * * $Revision: 2.4 $ ***********************************************************************EHEADER*/ /****************************************************************************** * *****************************************************************************/ #include "headers.h" /*==========================================================================*/ /*==========================================================================*/ /** Augments measures by some random value between 0 and 1. {\bf Input files:} headers.h @return Error code. @param S [IN] parent graph matrix in CSR format @param measure_array [IN/OUT] measures assigned to each node of the parent graph @see hypre_AMGIndepSet */ /*--------------------------------------------------------------------------*/ int hypre_BoomerAMGIndepSetInit( hypre_ParCSRMatrix *S, double *measure_array , int seq_rand) { hypre_CSRMatrix *S_diag = hypre_ParCSRMatrixDiag(S); MPI_Comm comm = hypre_ParCSRMatrixComm(S); int S_num_nodes = hypre_CSRMatrixNumRows(S_diag); HYPRE_BigInt i; int j, my_id; int ierr = 0; MPI_Comm_rank(comm,&my_id); j = 2747+my_id; if (seq_rand) j = 2747; hypre_SeedRand(j); if (seq_rand) { for (i = 0; i < hypre_ParCSRMatrixFirstRowIndex(S); i++) hypre_Rand(); } for (j = 0; j < S_num_nodes; j++) { measure_array[j] += hypre_Rand(); } return (ierr); } /*==========================================================================*/ /*==========================================================================*/ /** Select an independent set from a graph. This graph is actually a subgraph of some parent graph. The parent graph is described as a matrix in compressed sparse row format, where edges in the graph are represented by nonzero matrix coefficients (zero coefficients are ignored). A positive measure is given for each node in the subgraph, and this is used to pick the independent set. A measure of zero must be given for all other nodes in the parent graph. The subgraph is a collection of nodes in the parent graph. Positive entries in the `IS\_marker' array indicate nodes in the independent set. All other entries are zero. The algorithm proceeds by first setting all nodes in `graph\_array' to be in the independent set. Nodes are then removed from the independent set by simply comparing the measures of adjacent nodes. {\bf Input files:} headers.h @return Error code. @param S [IN] parent graph matrix in CSR format @param measure_array [IN] measures assigned to each node of the parent graph @param graph_array [IN] node numbers in the subgraph to be partitioned @param graph_array_size [IN] number of nodes in the subgraph to be partitioned @param IS_marker [IN/OUT] marker array for independent set @see hypre_InitAMGIndepSet */ /*--------------------------------------------------------------------------*/ int hypre_BoomerAMGIndepSet( hypre_ParCSRMatrix *S, double *measure_array, int *graph_array, int graph_array_size, int *graph_array_offd, int graph_array_offd_size, int *IS_marker, int *IS_marker_offd ) { hypre_CSRMatrix *S_diag = hypre_ParCSRMatrixDiag(S); int *S_diag_i = hypre_CSRMatrixI(S_diag); int *S_diag_j = hypre_CSRMatrixJ(S_diag); hypre_CSRMatrix *S_offd = hypre_ParCSRMatrixOffd(S); int *S_offd_i = hypre_CSRMatrixI(S_offd); int *S_offd_j; int local_num_vars = hypre_CSRMatrixNumRows(S_diag); int i, j, ig, jS, jj; int ierr = 0; /*------------------------------------------------------- * Initialize IS_marker by putting all nodes in * the independent set. *-------------------------------------------------------*/ if (hypre_CSRMatrixNumCols(S_offd)) { S_offd_j = hypre_CSRMatrixJ(S_offd); } for (ig = 0; ig < graph_array_size; ig++) { i = graph_array[ig]; if (measure_array[i] > 1) { IS_marker[i] = 1; } } for (ig = 0; ig < graph_array_offd_size; ig++) { i = graph_array_offd[ig]; if (measure_array[i+local_num_vars] > 1) { IS_marker_offd[i] = 1; } } /*------------------------------------------------------- * Remove nodes from the initial independent set *-------------------------------------------------------*/ for (ig = 0; ig < graph_array_size; ig++) { i = graph_array[ig]; if (measure_array[i] > 1) { for (jS = S_diag_i[i]; jS < S_diag_i[i+1]; jS++) { j = S_diag_j[jS]; if (j < 0) j = -j-1; /* only consider valid graph edges */ /* if ( (measure_array[j] > 1) && (S_diag_data[jS]) ) */ if (measure_array[j] > 1) { if (measure_array[i] > measure_array[j]) { IS_marker[j] = 0; } else if (measure_array[j] > measure_array[i]) { IS_marker[i] = 0; } } } for (jS = S_offd_i[i]; jS < S_offd_i[i+1]; jS++) { jj = S_offd_j[jS]; if (jj < 0) jj = -jj-1; j = local_num_vars+jj; /* only consider valid graph edges */ /* if ( (measure_array[j] > 1) && (S_offd_data[jS]) ) */ if (measure_array[j] > 1) { if (measure_array[i] > measure_array[j]) { IS_marker_offd[jj] = 0; } else if (measure_array[j] > measure_array[i]) { IS_marker[i] = 0; } } } } } return (ierr); }