/[escript]/trunk/paso/src/AMG.c
ViewVC logotype

Diff of /trunk/paso/src/AMG.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 3312 by gross, Tue Oct 26 07:54:58 2010 UTC revision 3436 by plaub, Mon Jan 10 02:06:07 2011 UTC
# Line 51  void Paso_Preconditioner_LocalAMG_free(P Line 51  void Paso_Preconditioner_LocalAMG_free(P
51       }       }
52  }  }
53    
54    index_t Paso_Preconditioner_LocalAMG_getMaxLevel(const Paso_Preconditioner_LocalAMG * in) {
55       if (in->AMG_C == NULL) {
56          return in->level;
57       } else {
58          return Paso_Preconditioner_LocalAMG_getMaxLevel(in->AMG_C);
59       }
60    }
61    double Paso_Preconditioner_LocalAMG_getCoarseLevelSparsity(const Paso_Preconditioner_LocalAMG * in) {
62          if (in->AMG_C == NULL) {
63         if (in->A_C == NULL) {
64            return 1.;
65         } else {
66            return DBLE(in->A_C->pattern->len)/DBLE(in->A_C->numRows)/DBLE(in->A_C->numRows);
67         }
68          } else {
69            return Paso_Preconditioner_LocalAMG_getCoarseLevelSparsity(in->AMG_C);
70          }
71    }
72    dim_t Paso_Preconditioner_LocalAMG_getNumCoarseUnknwons(const Paso_Preconditioner_LocalAMG * in) {
73       if (in->AMG_C == NULL) {
74          if (in->A_C == NULL) {
75         return 0;
76          } else {
77         return in->A_C->numRows;
78          }
79       } else {
80         return Paso_Preconditioner_LocalAMG_getNumCoarseUnknwons(in->AMG_C);
81       }
82    }
83  /*****************************************************************  /*****************************************************************
84    
85     constructs AMG     constructs AMG
# Line 69  Paso_Preconditioner_LocalAMG* Paso_Preco Line 98  Paso_Preconditioner_LocalAMG* Paso_Preco
98    double time0=0;    double time0=0;
99    const double theta = options->coarsening_threshold;    const double theta = options->coarsening_threshold;
100    const double tau = options->diagonal_dominance_threshold;    const double tau = options->diagonal_dominance_threshold;
101      
102        
103    /*    /*
104        is the input matrix A suitable for coarsening        is the input matrix A suitable for coarsening
105                
106    */    */
107    if ( (A_p->pattern->len >= options->min_coarse_sparsity * n * n ) || (n <= options->min_coarse_matrix_size) || (level > options->level_max) ) {    if ( (A_p->pattern->len >= options->min_coarse_sparsity * n * n ) || (n <= options->min_coarse_matrix_size) || (level > options->level_max) ) {
108       if (verbose) printf("Paso: AMG level %d (limit = %d) stopped. sparsity = %e (limit = %e), unknowns = %d (limit = %d)\n",  
109      level,  options->level_max, A_p->pattern->len/(1.*n * n), options->min_coarse_sparsity, n, options->min_coarse_matrix_size  );        if (verbose) {
110              /*
111                  print stopping condition:
112                          - 'SPAR' = min_coarse_matrix_sparsity exceeded
113                          - 'SIZE' = min_coarse_matrix_size exceeded
114                          - 'LEVEL' = level_max exceeded
115              */
116              printf("Paso_Preconditioner: Stopping condition: ");
117    
118              if (A_p->pattern->len >= options->min_coarse_sparsity * n * n)
119                  printf("SPAR ");
120    
121              if (n <= options->min_coarse_matrix_size)
122                  printf("SIZE ");
123    
124              if (level > options->level_max)
125                  printf("LEVEL ");
126    
127              printf("\n");
128    
129            printf("Paso_Preconditioner: AMG level %d (limit = %d) stopped. sparsity = %e (limit = %e), unknowns = %d (limit = %d)\n",
130                        level,  options->level_max, A_p->pattern->len/(1.*n * n), options->min_coarse_sparsity, n, options->min_coarse_matrix_size);  
131    
132        }
133    
134       return NULL;       return NULL;
135    }    }
136       /* Start Coarsening : */       /* Start Coarsening : */
# Line 97  Paso_Preconditioner_LocalAMG* Paso_Preco Line 150  Paso_Preconditioner_LocalAMG* Paso_Preco
150       } else {       } else {
151             Paso_Preconditioner_AMG_setStrongConnections(A_p, degree, S, theta,tau);             Paso_Preconditioner_AMG_setStrongConnections(A_p, degree, S, theta,tau);
152       }       }
153       Paso_Preconditioner_AMG_RungeStuebenSearch(n, A_p->pattern->ptr, degree, S, split_marker);       Paso_Preconditioner_AMG_RungeStuebenSearch(n, A_p->pattern->ptr, degree, S, split_marker, options->usePanel);
154       options->coarsening_selection_time=Esys_timer()-time0 + MAX(0, options->coarsening_selection_time);       options->coarsening_selection_time=Esys_timer()-time0 + MAX(0, options->coarsening_selection_time);
155            
156       if (Esys_noError() ) {       if (Esys_noError() ) {
# Line 109  Paso_Preconditioner_LocalAMG* Paso_Preco Line 162  Paso_Preconditioner_LocalAMG* Paso_Preco
162          */          */
163          n_F=Paso_Util_cumsum_maskedTrue(n,counter, split_marker);          n_F=Paso_Util_cumsum_maskedTrue(n,counter, split_marker);
164          n_C=n-n_F;          n_C=n-n_F;
165          if (verbose) printf("Paso: AMG level %d: %d unknowns are flagged for elimination. %d left.\n",level,n_F,n-n_F);          if (verbose) printf("Paso_Preconditioner: AMG level %d: %d unknowns are flagged for elimination. %d left.\n",level,n_F,n-n_F);
166            
167          if ( n_F == 0 ) {  /*  is a nasty case. a direct solver should be used, return NULL */          if ( n_F == 0 ) {  /*  is a nasty case. a direct solver should be used, return NULL */
168             out = NULL;             out = NULL;
169          } else {          } else {
170             out=MEMALLOC(1,Paso_Preconditioner_LocalAMG);             out=MEMALLOC(1,Paso_Preconditioner_LocalAMG);
171             mask_C=TMPMEMALLOC(n,index_t);             if (! Esys_checkPtr(out)) {
            rows_in_F=TMPMEMALLOC(n_F,index_t);  
            if ( !( Esys_checkPtr(mask_C) || Esys_checkPtr(rows_in_F) || Esys_checkPtr(out)) ) {  
172            out->level = level;            out->level = level;
173            out->n = n;            out->n = n;
174            out->n_F = n_F;            out->n_F = n_F;
# Line 131  Paso_Preconditioner_LocalAMG* Paso_Preco Line 182  Paso_Preconditioner_LocalAMG* Paso_Preco
182            out->x_C = NULL;            out->x_C = NULL;
183            out->b_C = NULL;            out->b_C = NULL;
184            out->AMG_C = NULL;            out->AMG_C = NULL;
185              out->Smoother=NULL;
186               }
187               mask_C=TMPMEMALLOC(n,index_t);
188               rows_in_F=TMPMEMALLOC(n_F,index_t);
189               Esys_checkPtr(mask_C);
190               Esys_checkPtr(rows_in_F);
191               if ( Esys_noError() ) {
192    
193            out->Smoother = Paso_Preconditioner_LocalSmoother_alloc(A_p, (options->smoother == PASO_JACOBI), verbose);            out->Smoother = Paso_Preconditioner_LocalSmoother_alloc(A_p, (options->smoother == PASO_JACOBI), verbose);
194                    
195            if ( n_F < n ) { /* if nothing is been removed we have a diagonal dominant matrix and we just run a few steps of the smoother */            if (n_C != 0) {
196                   /* if nothing is been removed we have a diagonal dominant matrix and we just run a few steps of the smoother */
197        
              /* creates index for F:*/  
             #pragma omp parallel for private(i) schedule(static)  
             for (i = 0; i < n; ++i) {  
                if  (split_marker[i]) rows_in_F[counter[i]]=i;  
             }            
             /*  create mask of C nodes with value >-1 gives new id */  
             i=Paso_Util_cumsum_maskedFalse(n,counter, split_marker);  
   
             #pragma omp parallel for private(i) schedule(static)  
             for (i = 0; i < n; ++i) {  
                if  (split_marker[i]) {  
                   mask_C[i]=-1;  
                } else {  
                   mask_C[i]=counter[i];;  
                }  
             }  
             /*  
                   get Restriction :    
             */                    
             time0=Esys_timer();  
             out->P=Paso_Preconditioner_AMG_getDirectProlongation(A_p,degree,S,n_C,mask_C);  
             if (SHOW_TIMING) printf("timing: level %d: getProlongation: %e\n",level, Esys_timer()-time0);  
     /*        
                construct Prolongation operator as transposed of restriction operator:  
             */  
             time0=Esys_timer();  
             out->R=Paso_SparseMatrix_getTranspose(out->P);  
             if (SHOW_TIMING) printf("timing: level %d: Paso_SparseMatrix_getTranspose: %e\n",level,Esys_timer()-time0);  
                       
             /*  
             construct coarse level matrix:  
             */  
             time0=Esys_timer();  
             Atemp=Paso_SparseMatrix_MatrixMatrix(A_p,out->P);  
             A_C=Paso_SparseMatrix_MatrixMatrix(out->R,Atemp);  
             Paso_SparseMatrix_free(Atemp);  
             if (SHOW_TIMING) printf("timing: level %d : getCoarseMatrix: %e\n",level,Esys_timer()-time0);  
               
198              /* allocate helpers :*/              /* allocate helpers :*/
199              out->x_C=MEMALLOC(n_block*n_C,double);              out->x_C=MEMALLOC(n_block*n_C,double);
200              out->b_C=MEMALLOC(n_block*n_C,double);              out->b_C=MEMALLOC(n_block*n_C,double);
201              out->r=MEMALLOC(n_block*n,double);              out->r=MEMALLOC(n_block*n,double);
202                            
203              Esys_checkPtr(out->r);              Esys_checkPtr(out->r);
             Esys_checkPtr(out->Smoother);  
204              Esys_checkPtr(out->x_C);              Esys_checkPtr(out->x_C);
205              Esys_checkPtr(out->b_C);              Esys_checkPtr(out->b_C);
206                
207                if ( Esys_noError() ) {
208                   /* creates index for F:*/
209                   #pragma omp parallel private(i)
210                   {
211                      #pragma omp for schedule(static)
212                      for (i = 0; i < n; ++i) {
213                     if  (split_marker[i]) rows_in_F[counter[i]]=i;
214                      }
215                   }
216                   /*  create mask of C nodes with value >-1 gives new id */
217                   i=Paso_Util_cumsum_maskedFalse(n,counter, split_marker);
218    
219                   #pragma omp parallel for private(i) schedule(static)
220                   for (i = 0; i < n; ++i) {
221                      if  (split_marker[i]) {
222                     mask_C[i]=-1;
223                      } else {
224                     mask_C[i]=counter[i];;
225                      }
226                   }
227                   /*
228                      get Restriction :  
229                   */                  
230                   time0=Esys_timer();
231                   out->P=Paso_Preconditioner_AMG_getDirectProlongation(A_p,degree,S,n_C,mask_C);
232                   if (SHOW_TIMING) printf("timing: level %d: getProlongation: %e\n",level, Esys_timer()-time0);
233                }
234                /*      
235                   construct Prolongation operator as transposed of restriction operator:
236                */
237                if ( Esys_noError()) {
238                   time0=Esys_timer();
239                   out->R=Paso_SparseMatrix_getTranspose(out->P);
240                   if (SHOW_TIMING) printf("timing: level %d: Paso_SparseMatrix_getTranspose: %e\n",level,Esys_timer()-time0);
241                }      
242                /*
243                construct coarse level matrix:
244                */
245                if ( Esys_noError()) {
246                   time0=Esys_timer();
247                   Atemp=Paso_SparseMatrix_MatrixMatrix(A_p,out->P);
248                   A_C=Paso_SparseMatrix_MatrixMatrix(out->R,Atemp);
249                   Paso_SparseMatrix_free(Atemp);
250                   if (SHOW_TIMING) printf("timing: level %d : construct coarse matrix: %e\n",level,Esys_timer()-time0);            
251                }
252    
253                            
254              /*              /*
255                 constructe courser level:                 constructe courser level:
256                                
257              */              */
258              out->AMG_C=Paso_Preconditioner_LocalAMG_alloc(A_C,level+1,options);              if ( Esys_noError()) {
259                               out->AMG_C=Paso_Preconditioner_LocalAMG_alloc(A_C,level+1,options);
260                }
261              if ( Esys_noError()) {              if ( Esys_noError()) {
262                 if ( out->AMG_C == NULL ) {                 if ( out->AMG_C == NULL ) {
263                    out->reordering = options->reordering;                    out->reordering = options->reordering;
# Line 198  Paso_Preconditioner_LocalAMG* Paso_Preco Line 267  Paso_Preconditioner_LocalAMG* Paso_Preco
267                      out->A_C=Paso_SparseMatrix_unroll(MATRIX_FORMAT_BLK1 + MATRIX_FORMAT_OFFSET1, A_C);                      out->A_C=Paso_SparseMatrix_unroll(MATRIX_FORMAT_BLK1 + MATRIX_FORMAT_OFFSET1, A_C);
268                      Paso_SparseMatrix_free(A_C);                      Paso_SparseMatrix_free(A_C);
269                      out->A_C->solver_package = PASO_MKL;                      out->A_C->solver_package = PASO_MKL;
270                        if (verbose) printf("Paso_Preconditioner: AMG: use MKL direct solver on the coarsest level (number of unknowns = %d).\n",n_C*n_block);
271                    #else                    #else
272                      #ifdef UMFPACK                      #ifdef UMFPACK
273                         out->A_C=Paso_SparseMatrix_unroll(MATRIX_FORMAT_BLK1 + MATRIX_FORMAT_CSC, A_C);                         out->A_C=Paso_SparseMatrix_unroll(MATRIX_FORMAT_BLK1 + MATRIX_FORMAT_CSC, A_C);
274                         Paso_SparseMatrix_free(A_C);                         Paso_SparseMatrix_free(A_C);
275                         out->A_C->solver_package = PASO_UMFPACK;                         out->A_C->solver_package = PASO_UMFPACK;
276                           if (verbose) printf("Paso_Preconditioner: AMG: use UMFPACK direct solver on the coarsest level (number of unknowns = %d).\n",n_C*n_block);
277                      #else                      #else
278                         out->A_C=A_C;                         out->A_C=A_C;
279                         out->A_C->solver_p=Paso_Preconditioner_LocalSmoother_alloc(out->A_C, (options->smoother == PASO_JACOBI), verbose);                         out->A_C->solver_p=Paso_Preconditioner_LocalSmoother_alloc(out->A_C, (options->smoother == PASO_JACOBI), verbose);
280                         out->A_C->solver_package = PASO_SMOOTHER;                         out->A_C->solver_package = PASO_SMOOTHER;
281                           if (verbose) printf("Paso_Preconditioner: AMG: use smoother on the coarsest level (number of unknowns = %d).\n",n_C*n_block);
282                      #endif                      #endif
283                    #endif                    #endif
284                 } else {                 } else {
# Line 266  void Paso_Preconditioner_LocalAMG_solve( Line 338  void Paso_Preconditioner_LocalAMG_solve(
338            Paso_UMFPACK(amg->A_C, amg->x_C,amg->b_C, amg->refinements, SHOW_TIMING);            Paso_UMFPACK(amg->A_C, amg->x_C,amg->b_C, amg->refinements, SHOW_TIMING);
339            break;            break;
340             case (PASO_SMOOTHER):             case (PASO_SMOOTHER):
341            Paso_Preconditioner_LocalSmoother_solve(amg->A_C, amg->Smoother,amg->x_C,amg->b_C,pre_sweeps, FALSE);            Paso_Preconditioner_LocalSmoother_solve(amg->A_C, amg->A_C->solver_p,amg->x_C,amg->b_C,pre_sweeps+post_sweeps, FALSE);
342            break;            break;
343          }          }
344          if (SHOW_TIMING) printf("timing: level %d: DIRECT SOLVER: %e\n",amg->level,Esys_timer()-time0);          if (SHOW_TIMING) printf("timing: level %d: DIRECT SOLVER: %e\n",amg->level,Esys_timer()-time0);
# Line 308  void Paso_Preconditioner_AMG_setStrongCo Line 380  void Paso_Preconditioner_AMG_setStrongCo
380    
381    
382        #pragma omp parallel for private(i,iptr,max_offdiagonal, threshold,j, kdeg, sum_row, main_row, fnorm) schedule(static)        #pragma omp parallel for private(i,iptr,max_offdiagonal, threshold,j, kdeg, sum_row, main_row, fnorm) schedule(static)
383        for (i=0;i<n;++i) {        for (i=0;i<n;++i) {        
             
384       max_offdiagonal = 0.;       max_offdiagonal = 0.;
385       sum_row=0;       sum_row=0;
386       main_row=0;       main_row=0;
# Line 327  void Paso_Preconditioner_AMG_setStrongCo Line 398  void Paso_Preconditioner_AMG_setStrongCo
398       }       }
399       threshold = theta*max_offdiagonal;       threshold = theta*max_offdiagonal;
400       kdeg=0;       kdeg=0;
401        
402       if (tau*main_row < sum_row) { /* no diagonal domainance */       if (tau*main_row < sum_row) { /* no diagonal domainance */
403          #pragma ivdep          #pragma ivdep
404          for (iptr=A->pattern->ptr[i];iptr<A->pattern->ptr[i+1]; ++iptr) {          for (iptr=A->pattern->ptr[i];iptr<A->pattern->ptr[i+1]; ++iptr) {
# Line 411  void Paso_Preconditioner_AMG_setStrongCo Line 483  void Paso_Preconditioner_AMG_setStrongCo
483    
484  /* the runge stueben coarsening algorithm: */  /* the runge stueben coarsening algorithm: */
485  void Paso_Preconditioner_AMG_RungeStuebenSearch(const dim_t n, const index_t* offset,  void Paso_Preconditioner_AMG_RungeStuebenSearch(const dim_t n, const index_t* offset,
486                           const dim_t* degree, const index_t* S,                          const dim_t* degree, const index_t* S,
487                           index_t*split_marker)                          index_t*split_marker, const bool_t usePanel)
488  {  {
489     index_t *lambda=NULL, j, *ST=NULL;    
490     dim_t i,k, p, q, *degreeT=NULL, itmp;     index_t *lambda=NULL, *ST=NULL, *notInPanel=NULL, *panel=NULL, lambda_max, lambda_k;
491       dim_t i,k, p, q, *degreeT=NULL, len_panel, len_panel_new;
492       register index_t j, itmp;
493        
494     if (n<=0) return; /* make sure that the return of Paso_Util_arg_max is not pointing to nirvana */     if (n<=0) return; /* make sure that the return of Paso_Util_arg_max is not pointing to nirvana */
495        
496     lambda=TMPMEMALLOC(n, index_t);     lambda=TMPMEMALLOC(n, index_t); Esys_checkPtr(lambda);
497     degreeT=TMPMEMALLOC(n, dim_t);     degreeT=TMPMEMALLOC(n, dim_t); Esys_checkPtr(degreeT);
498     ST=TMPMEMALLOC(offset[n], index_t);     ST=TMPMEMALLOC(offset[n], index_t);  Esys_checkPtr(ST);
499       if (usePanel) {
500          notInPanel=TMPMEMALLOC(n, bool_t); Esys_checkPtr(notInPanel);
501          panel=TMPMEMALLOC(n, index_t); Esys_checkPtr(panel);
502       }
503      
504        
505     if (! ( Esys_checkPtr(lambda) || Esys_checkPtr(degreeT) || Esys_checkPtr(ST) ) ) {    
506       if (Esys_noError() ) {
507        /* initialize  split_marker and split_marker :*/        /* initialize  split_marker and split_marker :*/
508        /* those unknows which are not influenced go into F, the rest is available for F or C */        /* those unknows which are not influenced go into F, the rest is available for F or C */
509        #pragma omp parallel for private(i) schedule(static)        #pragma omp parallel for private(i) schedule(static)
# Line 461  void Paso_Preconditioner_AMG_RungeStuebe Line 541  void Paso_Preconditioner_AMG_RungeStuebe
541          lambda[i]=itmp;          lambda[i]=itmp;
542       }       }
543        }        }
544          if (usePanel) {
545         #pragma omp parallel for private(i) schedule(static)
546         for (i=0;i<n;++i) notInPanel[i]=TRUE;
547          }
548        /* start search :*/        /* start search :*/
549        i=Paso_Util_arg_max(n,lambda);        i=Paso_Util_arg_max(n,lambda);
550        while (lambda[i]>-1) { /* is there any undecided unknowns? */        while (lambda[i]>-1) { /* is there any undecided unknown? */
551        
552       /* the unknown i is moved to C */       if (usePanel) {
553       split_marker[i]=PASO_AMG_IN_C;          len_panel=0;
554       lambda[i]=-1;  /* lambda fro unavailable unknowns is set to -1 */          do {
555                   /* the unknown i is moved to C */
556       /* all undecided unknown strongly coupled to i are moved to F */             split_marker[i]=PASO_AMG_IN_C;
557       for (p=0; p<degreeT[i]; ++p) {             lambda[i]=-1;  /* lambda from unavailable unknowns is set to -1 */
558          j=ST[offset[i]+p];            
559                   /* all undecided unknown strongly coupled to i are moved to F */
560          if (split_marker[j]==PASO_AMG_UNDECIDED) {             for (p=0; p<degreeT[i]; ++p) {
561                    j=ST[offset[i]+p];
562             split_marker[j]=PASO_AMG_IN_F;            
563             lambda[j]=-1;            if (split_marker[j]==PASO_AMG_UNDECIDED) {
564                      
565             for (q=0; q<degreeT[j]; ++q) {               split_marker[j]=PASO_AMG_IN_F;
566            k=ST[offset[j]+q];               lambda[j]=-1;
567            if (split_marker[k]==PASO_AMG_UNDECIDED) lambda[k]++;              
568                 for (q=0; q<degreeT[j]; ++q) {
569                k=ST[offset[j]+q];
570                if (split_marker[k]==PASO_AMG_UNDECIDED) {
571                   lambda[k]++;
572                   if (notInPanel[k]) {
573                      notInPanel[k]=FALSE;
574                      panel[len_panel]=k;
575                      len_panel++;
576                   }
577    
578                }    /* the unknown i is moved to C */
579                split_marker[i]=PASO_AMG_IN_C;
580                lambda[i]=-1;  /* lambda from unavailable unknowns is set to -1 */
581                 }
582                
583              }
584               }
585               for (p=0; p<degree[i]; ++p) {
586              j=S[offset[i]+p];
587              if (split_marker[j]==PASO_AMG_UNDECIDED) {
588                 lambda[j]--;
589                 if (notInPanel[j]) {
590                notInPanel[j]=FALSE;
591                panel[len_panel]=j;
592                len_panel++;
593                 }
594              }
595             }             }
596    
597               /* consolidate panel */
598               /* remove lambda[q]=-1 */
599               lambda_max=-1;
600               i=-1;
601               len_panel_new=0;
602               for (q=0; q<len_panel; q++) {
603                 k=panel[q];
604                 lambda_k=lambda[k];
605                 if (split_marker[k]==PASO_AMG_UNDECIDED) {
606                panel[len_panel_new]=k;
607                len_panel_new++;
608    
609                if (lambda_max == lambda_k) {
610                   if (k<i) i=k;
611                } else if (lambda_max < lambda_k) {
612                   lambda_max =lambda_k;
613                   i=k;
614                }
615                 }
616               }
617               len_panel=len_panel_new;
618            } while (len_panel>0);    
619         } else {
620            /* the unknown i is moved to C */
621            split_marker[i]=PASO_AMG_IN_C;
622            lambda[i]=-1;  /* lambda from unavailable unknowns is set to -1 */
623            
624            /* all undecided unknown strongly coupled to i are moved to F */
625            for (p=0; p<degreeT[i]; ++p) {
626               j=ST[offset[i]+p];
627               if (split_marker[j]==PASO_AMG_UNDECIDED) {
628            
629              split_marker[j]=PASO_AMG_IN_F;
630              lambda[j]=-1;
631            
632              for (q=0; q<degreeT[j]; ++q) {
633                 k=ST[offset[j]+q];
634                 if (split_marker[k]==PASO_AMG_UNDECIDED) lambda[k]++;
635              }
636    
637               }
638          }          }
639            for (p=0; p<degree[i]; ++p) {
640               j=S[offset[i]+p];
641               if(split_marker[j]==PASO_AMG_UNDECIDED) lambda[j]--;
642            }
643            
644       }       }
      for (p=0; p<degree[i]; ++p) {  
         j=S[offset[i]+p];  
         if(split_marker[j]==PASO_AMG_UNDECIDED) lambda[j]--;  
      }  
       
645       i=Paso_Util_arg_max(n,lambda);       i=Paso_Util_arg_max(n,lambda);
646        }        }
647     }     }
648     TMPMEMFREE(lambda);     TMPMEMFREE(lambda);
649     TMPMEMFREE(ST);     TMPMEMFREE(ST);
650     TMPMEMFREE(degreeT);     TMPMEMFREE(degreeT);
651       TMPMEMFREE(panel);
652       TMPMEMFREE(notInPanel);
653  }  }

Legend:
Removed from v.3312  
changed lines
  Added in v.3436

  ViewVC Help
Powered by ViewVC 1.1.26