/[escript]/branches/domexper/dudley/src/Mesh_resolveNodeIds.c
ViewVC logotype

Diff of /branches/domexper/dudley/src/Mesh_resolveNodeIds.c

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

revision 730 by bcumming, Mon May 15 04:03:49 2006 UTC revision 1739 by gross, Fri Aug 29 06:19:53 2008 UTC
# Line 1  Line 1 
 /*  
  ************************************************************  
  *          Copyright 2006 by ACcESS MNRF                   *  
  *                                                          *  
  *              http://www.access.edu.au                    *  
  *       Primary Business: Queensland, Australia            *  
  *  Licensed under the Open Software License version 3.0    *  
  *     http://www.opensource.org/licenses/osl-3.0.php       *  
  *                                                          *  
  ************************************************************  
 */  
1    
2  /**************************************************************/  /* $Id$ */
   
 /*   Finley: Mesh */  
3    
4  /*   at input the element nodes refers to the numbering defined the Id assigned to the nodes in the */  /*******************************************************
5  /*   NodeFile. At the output, the numbering of the element nodes is between 0 and numNodes */   *
6  /*   degreesOfFreedom are not neccessarily referening to a dense numbering */   *           Copyright 2003-2007 by ACceSS MNRF
7     *       Copyright 2007 by University of Queensland
8     *
9     *                http://esscc.uq.edu.au
10     *        Primary Business: Queensland, Australia
11     *  Licensed under the Open Software License version 3.0
12     *     http://www.opensource.org/licenses/osl-3.0.php
13     *
14     *******************************************************/
15    
16  /**************************************************************/  /**************************************************************/
17    
18  /*   Author: gross@access.edu.au */  /*   Finley: Mesh */
19  /*   Version: $Id$ */  
20    /*   at input the element nodes refers to the numbering defined the global Id assigned to the nodes in the */
21    /*   NodeFile. It is also not ensured that all nodes refered by an element is actually available */
22    /*   on the process.  At the output, a local node labeling is used and all nodes are available */
23    /*   In particular the numbering of the element nodes is between 0 and in->NodeFile->numNodes */
24    /*   The function does not create a distribution of the degrees of freedom. */
25    
26  /**************************************************************/  /**************************************************************/
27    
# Line 31  Line 31 
31  /**************************************************************/  /**************************************************************/
32    
33  void  Finley_Mesh_resolveNodeIds(Finley_Mesh* in) {  void  Finley_Mesh_resolveNodeIds(Finley_Mesh* in) {
34    char error_msg[LenErrorMsg_MAX];  
35    dim_t k,len,numDim,newNumNodes,n;    index_t min_id, max_id,  min_id2, max_id2, global_min_id, global_max_id,
36    index_t min_id,max_id,min_id2,max_id2,*maskNodes=NULL,*maskElements=NULL,*index=NULL;            *globalToNewLocalNodeLabels=NULL, *newLocalToGlobalNodeLabels=NULL;
37      dim_t len, n, newNumNodes, numDim;
38    Finley_NodeFile *newNodeFile=NULL;    Finley_NodeFile *newNodeFile=NULL;
39    Finley_resetError();    #ifdef PASO_MPI
40      index_t id_range[2], global_id_range[2];
41      #endif
42    numDim=Finley_Mesh_getDim(in);    numDim=Finley_Mesh_getDim(in);
43        /*  find the minimum and maximum id used by elements: */
   /*   find the minimum and maximum id used: */  
     
44    min_id=INDEX_T_MAX;    min_id=INDEX_T_MAX;
45    max_id=-INDEX_T_MAX;    max_id=-INDEX_T_MAX;
   Finley_NodeFile_setIdRange(&min_id2,&max_id2,in->Nodes);  
   if (min_id2==INDEX_T_MAX || max_id2==-INDEX_T_MAX) {  
     Finley_setError(VALUE_ERROR,"__FILE__: Mesh has not been defined completely.");  
     goto clean;  
   }  
   
   max_id=MAX(max_id,max_id2);  
   min_id=MIN(min_id,min_id2);  
46    Finley_ElementFile_setNodeRange(&min_id2,&max_id2,in->Elements);    Finley_ElementFile_setNodeRange(&min_id2,&max_id2,in->Elements);
47    max_id=MAX(max_id,max_id2);    max_id=MAX(max_id,max_id2);
48    min_id=MIN(min_id,min_id2);    min_id=MIN(min_id,min_id2);
# Line 62  void  Finley_Mesh_resolveNodeIds(Finley_ Line 55  void  Finley_Mesh_resolveNodeIds(Finley_
55    Finley_ElementFile_setNodeRange(&min_id2,&max_id2,in->Points);    Finley_ElementFile_setNodeRange(&min_id2,&max_id2,in->Points);
56    max_id=MAX(max_id,max_id2);    max_id=MAX(max_id,max_id2);
57    min_id=MIN(min_id,min_id2);    min_id=MIN(min_id,min_id2);
58      #ifdef PASO_MPI
59         id_range[0]=-min_id;
60         id_range[1]=max_id;
61         MPI_Allreduce( id_range, global_id_range, 2, MPI_INT, MPI_MAX, in->MPIInfo->comm );
62         global_min_id=-global_id_range[0];
63         global_max_id=global_id_range[1];
64      #else
65         global_min_id=min_id;
66         global_max_id=max_id;
67      #endif
68    #ifdef Finley_TRACE    #ifdef Finley_TRACE
69    printf("Node id range is %d:%d\n",min_id,max_id);    printf("Node id range used by elements is %d:%d\n",global_min_id,global_max_id);
70    #endif    #endif
71      if (min_id>max_id) {
72         max_id=-1;
73         min_id=0;
74      }
75        
76    /*  allocate a new node file used to gather existing node file: */    /* allocate mappings for new local node labeling to global node labeling (newLocalToGlobalNodeLabels)
77           and global node labeling to the new local node labeling (globalToNewLocalNodeLabels[i-min_id] is the
78         new local id of global node i) */
79    len=max_id-min_id+1;    len=max_id-min_id+1;
80  #ifndef PASO_MPI    globalToNewLocalNodeLabels=TMPMEMALLOC(len,index_t); /* local mask for used nodes */
81    newNodeFile=Finley_NodeFile_alloc(numDim);    newLocalToGlobalNodeLabels=TMPMEMALLOC(len,index_t);
82  #else    if (! ( (Finley_checkPtr(globalToNewLocalNodeLabels) && Finley_checkPtr(newLocalToGlobalNodeLabels) ) ) ) {
83    newNodeFile=Finley_NodeFile_alloc(numDim,in->MPIInfo);  
84           #pragma omp parallel
85           {
86               #pragma omp for private(n) schedule(static)
87               for (n=0;n<len;n++) newLocalToGlobalNodeLabels[n]=-1;
88               #pragma omp for private(n) schedule(static)
89               for (n=0;n<len;n++) globalToNewLocalNodeLabels[n]=-1;
90           }
91    
92           /*  mark the nodes referred by elements in globalToNewLocalNodeLabels which is currently used as a mask: */
93    
94           Finley_Mesh_markNodes(globalToNewLocalNodeLabels,min_id,in,FALSE);
95    
96           /* create a local labeling newLocalToGlobalNodeLabels of the local nodes by packing the mask globalToNewLocalNodeLabels*/
97    
98           newNumNodes=Finley_Util_packMask(len,globalToNewLocalNodeLabels,newLocalToGlobalNodeLabels);
99    
100           /* invert the new labeling and shift the index newLocalToGlobalNodeLabels to global node ids */
101           #pragma omp parallel for private(n) schedule(static)
102           for (n=0;n<newNumNodes;n++) {
103    #ifdef BOUNDS_CHECK
104           if (n >= len || n < 0) { printf("BOUNDS_CHECK %s %d n=%d\n", __FILE__, __LINE__, n); exit(1); }
105           if (newLocalToGlobalNodeLabels[n] >= len || newLocalToGlobalNodeLabels[n] < 0) { printf("BOUNDS_CHECK %s %d n=%d\n", __FILE__, __LINE__, n); exit(1); }
106  #endif  #endif
107    if (! Finley_noError()) goto clean;                globalToNewLocalNodeLabels[newLocalToGlobalNodeLabels[n]]=n;
108                  newLocalToGlobalNodeLabels[n]+=min_id;
109    maskNodes=TMPMEMALLOC(len,index_t);          }
110    if (Finley_checkPtr(maskNodes)) goto clean;          /* create a new table */
111            newNodeFile=Finley_NodeFile_alloc(numDim,in->MPIInfo);
112    maskElements=TMPMEMALLOC(len,index_t);          if (Finley_noError()) {
113    if (Finley_checkPtr(maskElements)) goto clean;             Finley_NodeFile_allocTable(newNodeFile,newNumNodes);
114            }
115    index=TMPMEMALLOC(in->Nodes->numNodes,index_t);          if (Finley_noError())
116                Finley_NodeFile_gather_global(newLocalToGlobalNodeLabels,in->Nodes, newNodeFile);
117    if (Finley_checkPtr(maskElements)) goto clean;          if (Finley_noError()) {
118               Finley_NodeFile_free(in->Nodes);
119    #pragma omp parallel for private(n) schedule(static)             in->Nodes=newNodeFile;
120    for (n=0;n<in->Nodes->numNodes;n++) index[n]=-1;             /*  relable nodes of the elements: */
121    #pragma omp parallel for private(n) schedule(static)             Finley_Mesh_relableElementNodes(globalToNewLocalNodeLabels,min_id,in);
122    for (n=0;n<len;n++) {          }
          maskNodes[n]=-1;  
          maskElements[n]=-1;  
123    }    }
124    /*  mark the nodes referred by elements in maskElements: */    TMPMEMFREE(globalToNewLocalNodeLabels);
125        TMPMEMFREE(newLocalToGlobalNodeLabels);
126    Finley_Mesh_markNodes(maskElements,min_id,in,FALSE);    if (! Finley_noError()) {
127           Finley_NodeFile_free(newNodeFile);
   /*  mark defined nodes */  
   
   #pragma omp parallel for private(k) schedule(static)  
   for (k=0;k<in->Nodes->numNodes;k++) maskNodes[in->Nodes->Id[k]-min_id]=1;  
   
   /*  check if all referenced nodes are actually defined: */  
   
   #pragma omp parallel for private(k) schedule(static)  
   for (k=0;k<len;k++) {  
      /* if a node is refered by an element is there a node defined ?*/  
      if (maskElements[k]>=0 && maskNodes[k]<0) {  
        sprintf(error_msg,"__FILE__:Node id %d is referenced by element but is not defined.",k+min_id);  
        Finley_setError(VALUE_ERROR,error_msg);  
      }  
   }  
   
   Finley_NodeFile_allocTable(newNodeFile,len);  
   if (! Finley_noError() ) goto clean;  
   
   if (Finley_noError()) {  
     
       /*  scatter the nodefile in->nodes into newNodeFile using index; */  
       #pragma omp parallel for private(k) schedule(static)  
       for (k=0;k<in->Nodes->numNodes;k++)  
         index[k]=in->Nodes->Id[k]-min_id;  
       Finley_NodeFile_scatter(index,in->Nodes,newNodeFile);  
   
       /*  relable used nodes: */  
       /* index maps the new node labeling onto the old one */  
       newNumNodes=Finley_Util_packMask(len,maskElements,index);  
       #pragma omp parallel for private(k) schedule(static)  
       for (k=0;k<newNumNodes;k++) maskElements[index[k]]=k;  
   
       /*  create a new table of nodes: */  
       Finley_NodeFile_deallocTable(in->Nodes);  
       Finley_NodeFile_allocTable(in->Nodes,newNumNodes);  
   
       if (! Finley_noError()) goto clean;  
   
       /* gather the new nodefile into in->Nodes */  
       Finley_NodeFile_gather(index,newNodeFile,in->Nodes);  
   
       /*  relable nodes of the elements: */  
       Finley_Mesh_relableElementNodes(maskElements,min_id,in);  
   
128    }    }
   
   /*  clean-up: */  
     
   clean: TMPMEMFREE(maskNodes);  
          TMPMEMFREE(maskElements);  
          TMPMEMFREE(index);  
          Finley_NodeFile_deallocTable(newNodeFile);  
          Finley_NodeFile_dealloc(newNodeFile);  
129  }  }
   
 /*  
 * $Log$  
 * Revision 1.6  2005/09/15 03:44:23  jgs  
 * Merge of development branch dev-02 back to main trunk on 2005-09-15  
 *  
 * Revision 1.5.2.1  2005/09/07 06:26:20  gross  
 * the solver from finley are put into the standalone package paso now  
 *  
 * Revision 1.5  2005/07/08 04:07:54  jgs  
 * Merge of development branch back to main trunk on 2005-07-08  
 *  
 * Revision 1.4  2004/12/15 07:08:33  jgs  
 * *** empty log message ***  
 * Revision 1.1.1.1.2.2  2005/06/29 02:34:53  gross  
 * some changes towards 64 integers in finley  
 *  
 * Revision 1.1.1.1.2.1  2004/11/24 01:37:14  gross  
 * some changes dealing with the integer overflow in memory allocation. Finley solves 4M unknowns now  
 *  
 *  
 *  
 */  
   

Legend:
Removed from v.730  
changed lines
  Added in v.1739

  ViewVC Help
Powered by ViewVC 1.1.26