IFPACK  Development
 All Classes Files Functions Variables Enumerations Friends
Numbering_dh.c
00001 /*@HEADER
00002 // ***********************************************************************
00003 //
00004 //       Ifpack: Object-Oriented Algebraic Preconditioner Package
00005 //                 Copyright (2002) Sandia Corporation
00006 //
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00038 //
00039 // ***********************************************************************
00040 //@HEADER
00041 */
00042 
00043 #include "Numbering_dh.h"
00044 #include "Mat_dh.h"
00045 #include "Hash_i_dh.h"
00046 #include "Mem_dh.h"
00047 #include "shellSort_dh.h"
00048 #include "Parser_dh.h"
00049 
00050 
00051 #undef __FUNC__
00052 #define __FUNC__ "Numbering_dhCreate"
00053 void
00054 Numbering_dhCreate (Numbering_dh * numb)
00055 {
00056   START_FUNC_DH
00057     struct _numbering_dh *tmp =
00058     (struct _numbering_dh *) MALLOC_DH (sizeof (struct _numbering_dh));
00059   CHECK_V_ERROR;
00060   *numb = tmp;
00061 
00062   tmp->size = 0;
00063   tmp->first = 0;
00064   tmp->m = 0;
00065   tmp->num_ext = 0;
00066   tmp->num_extLo = 0;
00067   tmp->num_extHi = 0;
00068   tmp->idx_ext = NULL;
00069   tmp->idx_extLo = NULL;
00070   tmp->idx_extHi = NULL;
00071   tmp->idx_ext = NULL;
00072   tmp->debug = Parser_dhHasSwitch (parser_dh, "-debug_Numbering");
00073 END_FUNC_DH}
00074 
00075 #undef __FUNC__
00076 #define __FUNC__ "Numbering_dhDestroy"
00077 void
00078 Numbering_dhDestroy (Numbering_dh numb)
00079 {
00080   START_FUNC_DH if (numb->global_to_local != NULL)
00081     {
00082       Hash_i_dhDestroy (numb->global_to_local);
00083       CHECK_V_ERROR;
00084     }
00085   if (numb->idx_ext != NULL)
00086     {
00087       FREE_DH (numb->idx_ext);
00088       CHECK_V_ERROR;
00089     }
00090   FREE_DH (numb);
00091   CHECK_V_ERROR;
00092 END_FUNC_DH}
00093 
00094 
00095 /*
00096 The internal indices are numbered 0 to nlocal-1 so they do not 
00097 need to be sorted.  The external indices are sorted so that 
00098 the indices from a given processor are stored contiguously.
00099 Then in the matvec, no reordering of the data is needed.
00100 */
00101 
00102 #undef __FUNC__
00103 #define __FUNC__ "Numbering_dhSetup"
00104 void
00105 Numbering_dhSetup (Numbering_dh numb, Mat_dh mat)
00106 {
00107   START_FUNC_DH int i, len, *cval = mat->cval;
00108   int num_ext, num_extLo, num_extHi;
00109   int m = mat->m, size;
00110   Hash_i_dh global_to_local_hash;
00111   int first = mat->beg_row, last = first + m;
00112   int *idx_ext;
00113   int data;
00114 /*  int       debug = false; */
00115 
00116 /*   if (logFile != NULL && numb->debug) debug = true; */
00117 
00118   numb->first = first;
00119   numb->m = m;
00120 
00121   /* Allocate space for look-up tables */
00122 
00123   /* initial guess: there are at most 'm' external indices */
00124   numb->size = size = m;
00125   Hash_i_dhCreate (&(numb->global_to_local), m);
00126   CHECK_V_ERROR;
00127 
00128   global_to_local_hash = numb->global_to_local;
00129   idx_ext = numb->idx_ext = (int *) MALLOC_DH (size * sizeof (int));
00130   CHECK_V_ERROR;
00131 
00132   /* find all external indices; at the end of this block, 
00133      idx_ext[] will contain an unsorted list of external indices.
00134    */
00135   len = mat->rp[m];
00136   num_ext = num_extLo = num_extHi = 0;
00137   for (i = 0; i < len; i++)
00138     {               /* for each nonzero "index" in the matrix */
00139       int index = cval[i];
00140 
00141       /* Only interested in external indices */
00142       if (index < first || index >= last)
00143     {
00144 
00145       /* if index hasn't been previously inserted, do so now. */
00146       data = Hash_i_dhLookup (global_to_local_hash, cval[i]);
00147       CHECK_V_ERROR;
00148 
00149       if (data == -1)
00150         {           /* index hasn't been inserted, so do so now  */
00151 
00152           /* reallocate idx_ext array if we're out of
00153              space.  The global_to_local hash table may also need
00154              to be enlarged, but the hash object will take care of that.
00155            */
00156           if (m + num_ext >= size)
00157         {
00158           int newSize = size * 1.5; /* heuristic */
00159           int *tmp = (int *) MALLOC_DH (newSize * sizeof (int));
00160           CHECK_V_ERROR;
00161           memcpy (tmp, idx_ext, size * sizeof (size));
00162           FREE_DH (idx_ext);
00163           CHECK_V_ERROR;
00164           size = numb->size = newSize;
00165           numb->idx_ext = idx_ext = tmp;
00166           SET_INFO ("reallocated ext_idx[]");
00167         }
00168 
00169           /* insert external index */
00170           Hash_i_dhInsert (global_to_local_hash, index, num_ext);
00171           CHECK_V_ERROR;
00172           idx_ext[num_ext] = index;
00173 
00174           num_ext++;
00175           if (index < first)
00176         {
00177           num_extLo++;
00178         }
00179           else
00180         {
00181           num_extHi++;
00182         }
00183         }
00184     }
00185     }
00186 
00187   numb->num_ext = num_ext;
00188   numb->num_extLo = num_extLo;
00189   numb->num_extHi = num_extHi;
00190   numb->idx_extLo = idx_ext;
00191   numb->idx_extHi = idx_ext + num_extLo;
00192 
00193   /* sort the list of external indices, then redo the hash
00194      table; the table is used to convert external indices
00195      in Numbering_dhGlobalToLocal()
00196    */
00197   shellSort_int (num_ext, idx_ext);
00198 
00199   Hash_i_dhReset (global_to_local_hash);
00200   CHECK_V_ERROR;
00201   for (i = 0; i < num_ext; i++)
00202     {
00203       Hash_i_dhInsert (global_to_local_hash, idx_ext[i], i + m);
00204       CHECK_V_ERROR;
00205     }
00206 END_FUNC_DH}
00207 
00208 #undef __FUNC__
00209 #define __FUNC__ "Numbering_dhGlobalToLocal"
00210 void
00211 Numbering_dhGlobalToLocal (Numbering_dh numb, int len,
00212                int *global, int *local)
00213 {
00214   START_FUNC_DH int i;
00215   int first = numb->first;
00216   int last = first + numb->m;
00217   int data;
00218   Hash_i_dh global_to_local = numb->global_to_local;
00219 
00220   for (i = 0; i < len; i++)
00221     {
00222       int idxGlobal = global[i];
00223       if (idxGlobal >= first && idxGlobal < last)
00224     {
00225       local[i] = idxGlobal - first;
00226       /* note: for matvec setup, numb->num_extLo = 0. */
00227     }
00228       else
00229     {
00230       data = Hash_i_dhLookup (global_to_local, idxGlobal);
00231       CHECK_V_ERROR;
00232       if (data == -1)
00233         {
00234           sprintf (msgBuf_dh, "global index %i not found in map\n",
00235                idxGlobal);
00236           SET_V_ERROR (msgBuf_dh);
00237         }
00238       else
00239         {
00240           local[i] = data;
00241         }
00242     }
00243     }
00244 END_FUNC_DH}
 All Classes Files Functions Variables Enumerations Friends