/[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 3444 by gross, Tue Jan 18 01:47:36 2011 UTC revision 3445 by gross, Wed Jan 19 06:02:15 2011 UTC
# Line 73  dim_t Paso_Preconditioner_AMG_getNumCoar Line 73  dim_t Paso_Preconditioner_AMG_getNumCoar
73        if (in->A_C == NULL) {        if (in->A_C == NULL) {
74       return 0;       return 0;
75        } else {        } else {
76       Paso_SystemMatrix_getTotalNumRows(in->A_C);       return Paso_SystemMatrix_getTotalNumRows(in->A_C);
77        }        }
78     } else {     } else {
79       return Paso_Preconditioner_AMG_getNumCoarseUnknwons(in->AMG_C);       return Paso_Preconditioner_AMG_getNumCoarseUnknwons(in->AMG_C);
# Line 88  Paso_Preconditioner_AMG* Paso_Preconditi Line 88  Paso_Preconditioner_AMG* Paso_Preconditi
88    
89    Paso_Preconditioner_AMG* out=NULL;    Paso_Preconditioner_AMG* out=NULL;
90    bool_t verbose=options->verbose;    bool_t verbose=options->verbose;
     
91    Paso_SystemMatrix *Atemp=NULL, *A_C=NULL;    Paso_SystemMatrix *Atemp=NULL, *A_C=NULL;
92    const dim_t n=A_p->numRows;  
93      const dim_t my_n=Paso_SystemMatrix_getNumRows(A_p);
94      const dim_t overlap_n=Paso_SystemMatrix_getColOverlap(A_p);
95      const dim_t n = my_n + overlap_n;
96    
97    const dim_t n_block=A_p->row_block_size;    const dim_t n_block=A_p->row_block_size;
98    index_t* F_marker=NULL, *counter=NULL, *mask_C=NULL, *rows_in_F=NULL, *S=NULL, *degree_S=NULL;    index_t* F_marker=NULL, *counter=NULL, *mask_C=NULL, *rows_in_F=NULL;
99    dim_t n_F=0, n_C=0, i;    dim_t n_F=0, n_C=0, i;
100    double time0=0;    double time0=0;
101    const double theta = options->coarsening_threshold;    const double theta = options->coarsening_threshold;
# Line 109  Paso_Preconditioner_AMG* Paso_Preconditi Line 112  Paso_Preconditioner_AMG* Paso_Preconditi
112         (total_n <= options->min_coarse_matrix_size) ||         (total_n <= options->min_coarse_matrix_size) ||
113         (level > options->level_max) ) {         (level > options->level_max) ) {
114    
115      if (verbose) {          if (verbose) {
116            /*            /*
117                print stopping condition:                print stopping condition:
118                        - 'SPAR' = min_coarse_matrix_sparsity exceeded                        - 'SPAR' = min_coarse_matrix_sparsity exceeded
# Line 132  Paso_Preconditioner_AMG* Paso_Preconditi Line 135  Paso_Preconditioner_AMG* Paso_Preconditi
135          printf("Paso_Preconditioner: AMG level %d (limit = %d) stopped. sparsity = %e (limit = %e), unknowns = %d (limit = %d)\n",          printf("Paso_Preconditioner: AMG level %d (limit = %d) stopped. sparsity = %e (limit = %e), unknowns = %d (limit = %d)\n",
136             level,  options->level_max, sparsity, options->min_coarse_sparsity, total_n, options->min_coarse_matrix_size);               level,  options->level_max, sparsity, options->min_coarse_sparsity, total_n, options->min_coarse_matrix_size);  
137    
138      }         }
139    
140       return NULL;         return NULL;
141    }    }  else {
142       /* Start Coarsening : */        /* Start Coarsening : */
143          const dim_t len_S=A_p->mainBlock->pattern->len+A_p->col_coupleBlock->pattern->len;
144    
145       F_marker=TMPMEMALLOC(n,index_t);       F_marker=TMPMEMALLOC(n,index_t);
146       counter=TMPMEMALLOC(n,index_t);       counter=TMPMEMALLOC(n,index_t);
147       degree_S=TMPMEMALLOC(n, dim_t);  
148       S=TMPMEMALLOC(A_p->pattern->len, index_t);       dim_t* degree_S=TMPMEMALLOC(my_n, dim_t);
149       if ( !( Esys_checkPtr(F_marker) || Esys_checkPtr(counter) || Esys_checkPtr(degree_S) || Esys_checkPtr(S) ) ) {       index_t *offset_S=TMPMEMALLOC(my_n, index_t);
150         index_t *S=TMPMEMALLOC(len_S, index_t);
151         if ( !( Esys_checkPtr(F_marker) || Esys_checkPtr(counter) || Esys_checkPtr(degree_S) || Esys_checkPtr(offset_S) || Esys_checkPtr(S) ) ) {
152       /*       /*
153            set splitting of unknows:            set splitting of unknows:
154                
155           */           */
156       time0=Esys_timer();       time0=Esys_timer();
157       if (n_block>1) {       if (n_block>1) {
158             Paso_Preconditioner_AMG_setStrongConnections_Block(A_p, degree_S, S, theta,tau);             Paso_Preconditioner_AMG_setStrongConnections_Block(A_p, degree_S, offset_S, S, theta,tau);
159       } else {       } else {
160             Paso_Preconditioner_AMG_setStrongConnections(A_p, degree_S, S, theta,tau);             Paso_Preconditioner_AMG_setStrongConnections(A_p, degree_S, offset_S, S, theta,tau);
161       }       }
162    
163  /*MPI:  /*MPI:
# Line 165  Paso_Preconditioner_AMG* Paso_Preconditi Line 171  Paso_Preconditioner_AMG* Paso_Preconditi
171  */  */
172    
173       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);
174        
175    #ifdef AAAAA
176       if (Esys_noError() ) {       if (Esys_noError() ) {
177          #pragma omp parallel for private(i) schedule(static)          #pragma omp parallel for private(i) schedule(static)
178          for (i = 0; i < n; ++i) F_marker[i]=(F_marker[i] ==  PASO_AMG_IN_F);          for (i = 0; i < n; ++i) F_marker[i]=(F_marker[i] ==  PASO_AMG_IN_F);
# Line 313  Paso_Preconditioner_AMG* Paso_Preconditi Line 320  Paso_Preconditioner_AMG* Paso_Preconditi
320             TMPMEMFREE(rows_in_F);             TMPMEMFREE(rows_in_F);
321          }          }
322       }       }
323    #endif
324    
325    }    }
326    TMPMEMFREE(counter);    TMPMEMFREE(counter);
327    TMPMEMFREE(F_marker);    TMPMEMFREE(F_marker);
328    TMPMEMFREE(degree_S);    TMPMEMFREE(degree_S);
329      TMPMEMFREE(offset_S);
330    TMPMEMFREE(S);    TMPMEMFREE(S);
331      }
332    
333    if (Esys_noError()) {    if (Esys_noError()) {
334       return out;       return out;
# Line 345  void Paso_Preconditioner_AMG_solve(Paso_ Line 356  void Paso_Preconditioner_AMG_solve(Paso_
356           time0=Esys_timer();           time0=Esys_timer();
357       Paso_Copy(n, amg->r, b);                            /*  r <- b */       Paso_Copy(n, amg->r, b);                            /*  r <- b */
358       Paso_SystemMatrix_MatrixVector_CSR_OFFSET0(-1.,A,x,1.,amg->r); /*r=r-Ax*/       Paso_SystemMatrix_MatrixVector_CSR_OFFSET0(-1.,A,x,1.,amg->r); /*r=r-Ax*/
359       Paso_SystemMatrix_MatrixVector_CSR_OFFSET0_DIAG(1.,amg->R,amg->r,0.,amg->b_C);  /* b_c = R*r  */       Paso_SystemMatrix_MatrixVector_CSR_OFFSET0(1.,amg->R,amg->r,0.,amg->b_C);  /* b_c = R*r  */
360           time0=Esys_timer()-time0;           time0=Esys_timer()-time0;
361       /* coarse level solve */       /* coarse level solve */
362       if ( amg->AMG_C == NULL) {       if ( amg->AMG_C == NULL) {
363          time0=Esys_timer();          time0=Esys_timer();
364          /*  A_C is the coarsest level */          /*  A_C is the coarsest level */
365    #ifdef FIXME
366          switch (amg->A_C->solver_package) {          switch (amg->A_C->solver_package) {
367             case (PASO_MKL):             case (PASO_MKL):
368            Paso_MKL(amg->A_C, amg->x_C,amg->b_C, amg->reordering, amg->refinements, SHOW_TIMING);            Paso_MKL(amg->A_C, amg->x_C,amg->b_C, amg->reordering, amg->refinements, SHOW_TIMING);
# Line 362  void Paso_Preconditioner_AMG_solve(Paso_ Line 374  void Paso_Preconditioner_AMG_solve(Paso_
374            Paso_Preconditioner_Smoother_solve(amg->A_C, amg->A_C->solver_p,amg->x_C,amg->b_C,pre_sweeps+post_sweeps, FALSE);            Paso_Preconditioner_Smoother_solve(amg->A_C, amg->A_C->solver_p,amg->x_C,amg->b_C,pre_sweeps+post_sweeps, FALSE);
375            break;            break;
376          }          }
377    #endif
378            Paso_Preconditioner_Smoother_solve(amg->A_C, amg->A_C->solver_p,amg->x_C,amg->b_C,pre_sweeps+post_sweeps, FALSE);
379          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);
380       } else {       } else {
381          Paso_Preconditioner_AMG_solve(amg->A_C, amg->AMG_C,amg->x_C,amg->b_C); /* x_C=AMG(b_C)     */          Paso_Preconditioner_AMG_solve(amg->A_C, amg->AMG_C,amg->x_C,amg->b_C); /* x_C=AMG(b_C)     */
382       }         }  
383       time0=time0+Esys_timer();       time0=time0+Esys_timer();
384       Paso_SystemMatrix_MatrixVector_CSR_OFFSET0_DIAG(1.,amg->P,amg->x_C,1.,x); /* x = x + P*x_c */           Paso_SystemMatrix_MatrixVector_CSR_OFFSET0(1.,amg->P,amg->x_C,1.,x); /* x = x + P*x_c */    
385            
386           /*postsmoothing*/           /*postsmoothing*/
387                
# Line 391  in the sense that |A_{ij}| >= theta * ma Line 405  in the sense that |A_{ij}| >= theta * ma
405  */  */
406    
407  void Paso_Preconditioner_AMG_setStrongConnections(Paso_SystemMatrix* A,  void Paso_Preconditioner_AMG_setStrongConnections(Paso_SystemMatrix* A,
408                        dim_t *degree_S, index_t *S,                            dim_t *degree_S, index_t *offset_S, index_t *S,
409                        const double theta, const double tau)                        const double theta, const double tau)
410  {  {
411     const dim_t n=A->numRows;     const dim_t my_n=Paso_SystemMatrix_getNumRows(A);
412     index_t iptr, i,j;     index_t iptr, i;
    dim_t kdeg;  
    double max_offdiagonal, threshold, sum_row, main_row, fnorm;  
413    
414    
415        #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) schedule(static)
416        for (i=0;i<n;++i) {                for (i=0;i<my_n;++i) {        
417       max_offdiagonal = 0.;       register double max_offdiagonal = 0.;
418       sum_row=0;       register double sum_row=0;
419       main_row=0;       register double main_row=0;
420       #pragma ivdep       #pragma ivdep
421       for (iptr=A->pattern->ptr[i];iptr<A->pattern->ptr[i+1]; ++iptr) {       for (iptr=A->mainBlock->pattern->ptr[i];iptr<A->mainBlock->pattern->ptr[i+1]; ++iptr) {
422          j=A->pattern->index[iptr];          register index_t j=A->mainBlock->pattern->index[iptr];
423          fnorm=ABS(A->val[iptr]);          register double fnorm=ABS(A->mainBlock->val[iptr]);
424                    
425          if( j != i) {          if( j != i) {
426             max_offdiagonal = MAX(max_offdiagonal,fnorm);             max_offdiagonal = MAX(max_offdiagonal,fnorm);
# Line 416  void Paso_Preconditioner_AMG_setStrongCo Line 428  void Paso_Preconditioner_AMG_setStrongCo
428          } else {          } else {
429             main_row=fnorm;             main_row=fnorm;
430          }          }
431    
432       }       }
433       threshold = theta*max_offdiagonal;       #pragma ivdep
434       kdeg=0;       for (iptr=A->col_coupleBlock->pattern->ptr[i];iptr<A->col_coupleBlock->pattern->ptr[i+1]; ++iptr) {
435                register index_t j=A->col_coupleBlock->pattern->index[iptr];
436            register double fnorm=ABS(A->col_coupleBlock->val[iptr]);
437            max_offdiagonal = MAX(max_offdiagonal,fnorm);
438            sum_row+=fnorm;
439         }
440    
441    
442         const double threshold = theta*max_offdiagonal;
443         register dim_t kdeg=0;
444             register index_t koffset=A->mainBlock->pattern->ptr[i]+A->col_coupleBlock->pattern->ptr[i];
445       if (tau*main_row < sum_row) { /* no diagonal domainance */       if (tau*main_row < sum_row) { /* no diagonal domainance */
446          #pragma ivdep          #pragma ivdep
447          for (iptr=A->pattern->ptr[i];iptr<A->pattern->ptr[i+1]; ++iptr) {          for (iptr=A->mainBlock->pattern->ptr[i];iptr<A->mainBlock->pattern->ptr[i+1]; ++iptr) {
448             j=A->pattern->index[iptr];             register index_t j=A->mainBlock->pattern->index[iptr];
449             if(ABS(A->val[iptr])>threshold && i!=j) {             if(ABS(A->mainBlock->val[iptr])>threshold && i!=j) {
450            S[A->pattern->ptr[i]+kdeg] = j;            S[koffset+kdeg] = j;
451              kdeg++;
452               }
453            }
454            #pragma ivdep
455            for (iptr=A->col_coupleBlock->pattern->ptr[i];iptr<A->col_coupleBlock->pattern->ptr[i+1]; ++iptr) {
456               register index_t j=A->col_coupleBlock->pattern->index[iptr];
457               if(ABS(A->col_coupleBlock->val[iptr])>threshold) {
458              S[koffset+kdeg] = j + my_n;
459            kdeg++;            kdeg++;
460             }             }
461          }          }
462           }           }
463             offset_S[i]=koffset;
464       degree_S[i]=kdeg;       degree_S[i]=kdeg;
465        }        }
   
466  }  }
467    
468  /* theta = threshold for strong connections */  /* theta = threshold for strong connections */
# Line 442  void Paso_Preconditioner_AMG_setStrongCo Line 472  void Paso_Preconditioner_AMG_setStrongCo
472  in the sense that |A_{ij}|_F >= theta * max_k |A_{ik}|_F  in the sense that |A_{ij}|_F >= theta * max_k |A_{ik}|_F
473  */  */
474  void Paso_Preconditioner_AMG_setStrongConnections_Block(Paso_SystemMatrix* A,  void Paso_Preconditioner_AMG_setStrongConnections_Block(Paso_SystemMatrix* A,
475                              dim_t *degree_S, index_t *S,                              dim_t *degree_S, index_t *offset_S, index_t *S,
476                              const double theta, const double tau)                              const double theta, const double tau)
477    
478  {  {
479       const dim_t my_n=Paso_SystemMatrix_getNumRows(A);
480       index_t iptr, i, bi;
481     const dim_t n_block=A->row_block_size;     const dim_t n_block=A->row_block_size;
    const dim_t n=A->numRows;  
    index_t iptr, i,j, bi;  
    dim_t kdeg, max_deg;  
    register double max_offdiagonal, threshold, fnorm, sum_row, main_row;  
    double *rtmp;  
482        
483        
484        #pragma omp parallel private(i,iptr,max_offdiagonal, kdeg, threshold,j, max_deg, fnorm, sum_row, main_row, rtmp)        #pragma omp parallel private(i,iptr, bi)
485        {        {
486       max_deg=0;       dim_t max_deg=0;
487       #pragma omp for schedule(static)       #pragma omp for schedule(static)
488       for (i=0;i<n;++i) max_deg=MAX(max_deg, A->pattern->ptr[i+1]-A->pattern->ptr[i]);       for (i=0;i<my_n;++i) max_deg=MAX(max_deg, A->mainBlock->pattern->ptr[i+1]-A->mainBlock->pattern->ptr[i]
489                                                    +A->col_coupleBlock->pattern->ptr[i+1]-A->col_coupleBlock->pattern->ptr[i]);
490                
491       rtmp=TMPMEMALLOC(max_deg, double);       double *rtmp=TMPMEMALLOC(max_deg, double);
492                
493       #pragma omp for schedule(static)       #pragma omp for schedule(static)
494       for (i=0;i<n;++i) {       for (i=0;i<my_n;++i) {
495            
496          max_offdiagonal = 0.;          register double max_offdiagonal = 0.;
497          sum_row=0;          register double sum_row=0;
498          main_row=0;          register double main_row=0;
499                register index_t rtmp_offset=-A->mainBlock->pattern->ptr[i];
500          for (iptr=A->pattern->ptr[i];iptr<A->pattern->ptr[i+1]; ++iptr) {  
501             j=A->pattern->index[iptr];          for (iptr=A->mainBlock->pattern->ptr[i];iptr<A->mainBlock->pattern->ptr[i+1]; ++iptr) {
502             fnorm=0;             register index_t j=A->mainBlock->pattern->index[iptr];
503               register double fnorm=0;
504             #pragma ivdep             #pragma ivdep
505             for(bi=0;bi<n_block*n_block;++bi) fnorm+=A->val[iptr*n_block*n_block+bi]*A->val[iptr*n_block*n_block+bi];             for(bi=0;bi<n_block*n_block;++bi) {
506                         register double rtmp2 = A->mainBlock->val[iptr*n_block*n_block+bi];
507                         fnorm+=rtmp2*rtmp2;
508                   }
509             fnorm=sqrt(fnorm);             fnorm=sqrt(fnorm);
510             rtmp[iptr-A->pattern->ptr[i]]=fnorm;  
511               rtmp[iptr+rtmp_offset]=fnorm;
512             if( j != i) {             if( j != i) {
513            max_offdiagonal = MAX(max_offdiagonal,fnorm);            max_offdiagonal = MAX(max_offdiagonal,fnorm);
514            sum_row+=fnorm;            sum_row+=fnorm;
# Line 483  void Paso_Preconditioner_AMG_setStrongCo Line 516  void Paso_Preconditioner_AMG_setStrongCo
516            main_row=fnorm;            main_row=fnorm;
517             }             }
518          }          }
519          threshold = theta*max_offdiagonal;              rtmp_offset=A->mainBlock->pattern->ptr[i+1]-A->mainBlock->pattern->ptr[i]-A->col_coupleBlock->pattern->ptr[i];
520                  for (iptr=A->col_coupleBlock->pattern->ptr[i];iptr<A->col_coupleBlock->pattern->ptr[i+1]; ++iptr) {
521          kdeg=0;             register index_t j=A->col_coupleBlock->pattern->index[iptr];
522               register double fnorm=0;
523               #pragma ivdep
524               for(bi=0;bi<n_block*n_block;++bi) {
525                         register double rtmp2 = A->col_coupleBlock->val[iptr*n_block*n_block+bi];
526                         fnorm+=rtmp2*rtmp2;
527                   }
528               fnorm=sqrt(fnorm);
529    
530               rtmp[iptr+rtmp_offset]=fnorm;
531               max_offdiagonal = MAX(max_offdiagonal,fnorm);
532               sum_row+=fnorm;
533            }
534                
535            const double threshold = theta*max_offdiagonal;
536            register dim_t kdeg=0;
537                register index_t koffset=A->mainBlock->pattern->ptr[i]+A->col_coupleBlock->pattern->ptr[i];
538    
539          if (tau*main_row < sum_row) { /* no diagonal domainance */          if (tau*main_row < sum_row) { /* no diagonal domainance */
540                   rtmp_offset=-A->mainBlock->pattern->ptr[i];
541             #pragma ivdep             #pragma ivdep
542             for (iptr=A->pattern->ptr[i];iptr<A->pattern->ptr[i+1]; ++iptr) {             for (iptr=A->mainBlock->pattern->ptr[i];iptr<A->mainBlock->pattern->ptr[i+1]; ++iptr) {
543            j=A->pattern->index[iptr];            register index_t j=A->mainBlock->pattern->index[iptr];
544            if(rtmp[iptr-A->pattern->ptr[i]] > threshold && i!=j) {            if(rtmp[iptr+rtmp_offset] > threshold && i!=j) {
545               S[A->pattern->ptr[i]+kdeg] = j;               S[koffset+kdeg] = j;
546               kdeg++;               kdeg++;
547            }            }
548             }             }
549                   rtmp_offset=A->mainBlock->pattern->ptr[i+1]-A->mainBlock->pattern->ptr[i]-A->col_coupleBlock->pattern->ptr[i];
550               #pragma ivdep
551               for (iptr=A->col_coupleBlock->pattern->index[iptr]; iptr<A->col_coupleBlock->pattern->ptr[i+1]; ++iptr) {
552              register index_t j=A->col_coupleBlock->pattern->index[iptr];
553              if(rtmp[iptr+rtmp_offset] > threshold) {
554                 S[koffset+kdeg] = j + my_n;
555                 kdeg++;
556              }
557               }
558                  
559          }          }
560          degree_S[i]=kdeg;          degree_S[i]=kdeg;
561                offset_S[i]=koffset;
562       }             }      
563       TMPMEMFREE(rtmp);       TMPMEMFREE(rtmp);
564        } /* end of parallel region */        } /* end of parallel region */
565    
566  }    }  
567    
568    #ifdef AAAAA
569  /* the runge stueben coarsening algorithm: */  /* the runge stueben coarsening algorithm: */
570  void Paso_Preconditioner_AMG_RungeStuebenSearch(const dim_t n, const index_t* offset_S,  void Paso_Preconditioner_AMG_RungeStuebenSearch(const dim_t n, const index_t* offset_S,
571                          const dim_t* degree_S, const index_t* S,                          const dim_t* degree_S, const index_t* S,
# Line 713  void Paso_Preconditioner_AMG_enforceFFCo Line 776  void Paso_Preconditioner_AMG_enforceFFCo
776              }              }
777         }         }
778  }  }
779    #endif
780    
781    #ifdef DFG
782  void Paso_Preconditioner_AMG_CIJPCoarsening( )  void Paso_Preconditioner_AMG_CIJPCoarsening( )
783  {  {
784    
785      
786    const dim_t my_n;    const dim_t my_n;
787    const dim_t overlap_n;    const dim_t overlap_n;
788    const dim_t n= my_n + overlap_n;    const dim_t n= my_n + overlap_n;
# Line 729  void Paso_Preconditioner_AMG_CIJPCoarsen Line 796  void Paso_Preconditioner_AMG_CIJPCoarsen
796     }     }
797    
798    
799  Paso_Coupler_add(w, 1., w2,     /* add noise to w */
800     /* adjust w accross processors */     Paso_Coupler_add(n, w, 1., w2, col_coupler);
801      
802     /*  */     /*  */
803     global_n_C=0;     global_n_C=0;
804     global_n_F=..;     global_n_F=..;
# Line 741  Paso_Coupler_add(w, 1., w2, Line 808  Paso_Coupler_add(w, 1., w2,
808                
809        is_in_D[i]=FALSE;        is_in_D[i]=FALSE;
810        /*  test  local connectivit*/        /*  test  local connectivit*/
811        for i ..        /* w2[i] = max(w[k] | k in S_i or k in S^T_i */
812           for k in S_i:        #pragma omp parallel for private(i)
813          for (i=0; i<n; ++i) w2[i]=0;
814                
815          for (i=0; i<my_n; ++i) {
816             for( iPtr =0 ; iPtr < degree_S[i]; ++iPtr) {
817                 k=S[offset_S[i]+iPtr];
818               w2[i]=MAX(w2[i],w[k]);               w2[i]=MAX(w2[i],w[k]);
819               w2[k]=MAX(w2[k],w[i]);               w2[k]=MAX(w2[k],w[i]);
820             }
821          }
822        /* adjust overlaps by MAX */        /* adjust overlaps by MAX */
823        ...        Paso_Coupler_max(n, w2, col_coupler);
       /* points with w[i]>w2[i] become C nodes */  
         
             
         
         
         
   
   
       global_n_C=?  
       global_n_F=?  
824    
825          /* points with w[i]>w2[i] become C nodes */
826     }     }
827        
828  }  }
829    #endif

Legend:
Removed from v.3444  
changed lines
  Added in v.3445

  ViewVC Help
Powered by ViewVC 1.1.26