Ifpack Package Browser (Single Doxygen Collection) Development
Numbering_dh.c
Go to the documentation of this file.
00001 /*@HEADER
00002 // ***********************************************************************
00003 //
00004 //       Ifpack: Object-Oriented Algebraic Preconditioner Package
00005 //                 Copyright (2009) 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 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00025 //
00026 // ***********************************************************************
00027 //@HEADER
00028 */
00029 
00030 #include "Numbering_dh.h"
00031 #include "Mat_dh.h"
00032 #include "Hash_i_dh.h"
00033 #include "Mem_dh.h"
00034 #include "shellSort_dh.h"
00035 #include "Parser_dh.h"
00036 
00037 
00038 #undef __FUNC__
00039 #define __FUNC__ "Numbering_dhCreate"
00040 void
00041 Numbering_dhCreate (Numbering_dh * numb)
00042 {
00043   START_FUNC_DH
00044     struct _numbering_dh *tmp =
00045     (struct _numbering_dh *) MALLOC_DH (sizeof (struct _numbering_dh));
00046   CHECK_V_ERROR;
00047   *numb = tmp;
00048 
00049   tmp->size = 0;
00050   tmp->first = 0;
00051   tmp->m = 0;
00052   tmp->num_ext = 0;
00053   tmp->num_extLo = 0;
00054   tmp->num_extHi = 0;
00055   tmp->idx_ext = NULL;
00056   tmp->idx_extLo = NULL;
00057   tmp->idx_extHi = NULL;
00058   tmp->idx_ext = NULL;
00059   tmp->debug = Parser_dhHasSwitch (parser_dh, "-debug_Numbering");
00060 END_FUNC_DH}
00061 
00062 #undef __FUNC__
00063 #define __FUNC__ "Numbering_dhDestroy"
00064 void
00065 Numbering_dhDestroy (Numbering_dh numb)
00066 {
00067   START_FUNC_DH if (numb->global_to_local != NULL)
00068     {
00069       Hash_i_dhDestroy (numb->global_to_local);
00070       CHECK_V_ERROR;
00071     }
00072   if (numb->idx_ext != NULL)
00073     {
00074       FREE_DH (numb->idx_ext);
00075       CHECK_V_ERROR;
00076     }
00077   FREE_DH (numb);
00078   CHECK_V_ERROR;
00079 END_FUNC_DH}
00080 
00081 
00082 /*
00083 The internal indices are numbered 0 to nlocal-1 so they do not 
00084 need to be sorted.  The external indices are sorted so that 
00085 the indices from a given processor are stored contiguously.
00086 Then in the matvec, no reordering of the data is needed.
00087 */
00088 
00089 #undef __FUNC__
00090 #define __FUNC__ "Numbering_dhSetup"
00091 void
00092 Numbering_dhSetup (Numbering_dh numb, Mat_dh mat)
00093 {
00094   START_FUNC_DH int i, len, *cval = mat->cval;
00095   int num_ext, num_extLo, num_extHi;
00096   int m = mat->m, size;
00097   Hash_i_dh global_to_local_hash;
00098   int first = mat->beg_row, last = first + m;
00099   int *idx_ext;
00100   int data;
00101 /*  int       debug = false; */
00102 
00103 /*   if (logFile != NULL && numb->debug) debug = true; */
00104 
00105   numb->first = first;
00106   numb->m = m;
00107 
00108   /* Allocate space for look-up tables */
00109 
00110   /* initial guess: there are at most 'm' external indices */
00111   numb->size = size = m;
00112   Hash_i_dhCreate (&(numb->global_to_local), m);
00113   CHECK_V_ERROR;
00114 
00115   global_to_local_hash = numb->global_to_local;
00116   idx_ext = numb->idx_ext = (int *) MALLOC_DH (size * sizeof (int));
00117   CHECK_V_ERROR;
00118 
00119   /* find all external indices; at the end of this block, 
00120      idx_ext[] will contain an unsorted list of external indices.
00121    */
00122   len = mat->rp[m];
00123   num_ext = num_extLo = num_extHi = 0;
00124   for (i = 0; i < len; i++)
00125     {       /* for each nonzero "index" in the matrix */
00126       int index = cval[i];
00127 
00128       /* Only interested in external indices */
00129       if (index < first || index >= last)
00130   {
00131 
00132     /* if index hasn't been previously inserted, do so now. */
00133     data = Hash_i_dhLookup (global_to_local_hash, cval[i]);
00134     CHECK_V_ERROR;
00135 
00136     if (data == -1)
00137       {     /* index hasn't been inserted, so do so now  */
00138 
00139         /* reallocate idx_ext array if we're out of
00140            space.  The global_to_local hash table may also need
00141            to be enlarged, but the hash object will take care of that.
00142          */
00143         if (m + num_ext >= size)
00144     {
00145       int newSize = size * 1.5; /* heuristic */
00146       int *tmp = (int *) MALLOC_DH (newSize * sizeof (int));
00147       CHECK_V_ERROR;
00148       memcpy (tmp, idx_ext, size * sizeof (size));
00149       FREE_DH (idx_ext);
00150       CHECK_V_ERROR;
00151       size = numb->size = newSize;
00152       numb->idx_ext = idx_ext = tmp;
00153       SET_INFO ("reallocated ext_idx[]");
00154     }
00155 
00156         /* insert external index */
00157         Hash_i_dhInsert (global_to_local_hash, index, num_ext);
00158         CHECK_V_ERROR;
00159         idx_ext[num_ext] = index;
00160 
00161         num_ext++;
00162         if (index < first)
00163     {
00164       num_extLo++;
00165     }
00166         else
00167     {
00168       num_extHi++;
00169     }
00170       }
00171   }
00172     }
00173 
00174   numb->num_ext = num_ext;
00175   numb->num_extLo = num_extLo;
00176   numb->num_extHi = num_extHi;
00177   numb->idx_extLo = idx_ext;
00178   numb->idx_extHi = idx_ext + num_extLo;
00179 
00180   /* sort the list of external indices, then redo the hash
00181      table; the table is used to convert external indices
00182      in Numbering_dhGlobalToLocal()
00183    */
00184   shellSort_int (num_ext, idx_ext);
00185 
00186   Hash_i_dhReset (global_to_local_hash);
00187   CHECK_V_ERROR;
00188   for (i = 0; i < num_ext; i++)
00189     {
00190       Hash_i_dhInsert (global_to_local_hash, idx_ext[i], i + m);
00191       CHECK_V_ERROR;
00192     }
00193 END_FUNC_DH}
00194 
00195 #undef __FUNC__
00196 #define __FUNC__ "Numbering_dhGlobalToLocal"
00197 void
00198 Numbering_dhGlobalToLocal (Numbering_dh numb, int len,
00199          int *global, int *local)
00200 {
00201   START_FUNC_DH int i;
00202   int first = numb->first;
00203   int last = first + numb->m;
00204   int data;
00205   Hash_i_dh global_to_local = numb->global_to_local;
00206 
00207   for (i = 0; i < len; i++)
00208     {
00209       int idxGlobal = global[i];
00210       if (idxGlobal >= first && idxGlobal < last)
00211   {
00212     local[i] = idxGlobal - first;
00213     /* note: for matvec setup, numb->num_extLo = 0. */
00214   }
00215       else
00216   {
00217     data = Hash_i_dhLookup (global_to_local, idxGlobal);
00218     CHECK_V_ERROR;
00219     if (data == -1)
00220       {
00221         sprintf (msgBuf_dh, "global index %i not found in map\n",
00222            idxGlobal);
00223         SET_V_ERROR (msgBuf_dh);
00224       }
00225     else
00226       {
00227         local[i] = data;
00228       }
00229   }
00230     }
00231 END_FUNC_DH}
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines