00001 
00002 
00003 
00004 
00005 
00006 
00007 #include "ParFUM.h"
00008 #include "ParFUM_internals.h"
00009 
00015 void FEM_Interpolate::FEM_InterpolateNodeOnEdge(NodalArgs args)
00016 {
00017   if (nodeEdgeFnPtr) { 
00018     nodeEdgeFnPtr(args,theMesh);
00019     return;
00020   }
00021   
00022   
00023   
00024   
00025   CkVec<FEM_Attribute *>*attrs = (theMesh->node).getAttrVec();
00026   for (int i=0; i<attrs->size(); i++) {
00027     FEM_Attribute *a = (FEM_Attribute *)(*attrs)[i];
00028     if (a->getAttr() < FEM_ATTRIB_TAG_MAX) {
00029       FEM_DataAttribute *d = (FEM_DataAttribute *)a;
00030       d->interpolate(args.nodes[0], args.nodes[1], args.n, args.frac);
00031     } 
00032     else if(a->getAttr()==FEM_BOUNDARY) {
00033       int n1_bound, n2_bound;
00034       FEM_Mesh_dataP(theMesh, FEM_NODE, FEM_BOUNDARY, &n1_bound, args.nodes[0], 1 , FEM_INT, 1);
00035       FEM_Mesh_dataP(theMesh, FEM_NODE, FEM_BOUNDARY, &n2_bound, args.nodes[1], 1 , FEM_INT, 1);
00036       if(args.frac==1.0) {
00037     a->copyEntity(args.n,*a,args.nodes[0]);
00038       } else if(args.frac==0.0) {
00039     a->copyEntity(args.n,*a,args.nodes[1]);
00040       } else {
00041     
00042     
00043     
00044     if(args.addNode) {
00045       if(n1_bound!=0 && n2_bound!=0 && n1_bound!=n2_bound) {
00046         
00047         bool n1corner = theMod->fmAdaptL->isFixedNode(args.nodes[0]);
00048         bool n2corner = theMod->fmAdaptL->isFixedNode(args.nodes[1]);
00049         bool edgeb = theMod->fmAdaptL->isEdgeBoundary(args.nodes[0],args.nodes[1]);
00050         if(!edgeb) { 
00051           int nbound = 0;
00052           FEM_DataAttribute *d = (FEM_DataAttribute *)a;
00053           d->getInt().setRow(args.n,nbound);
00054         }
00055         else if(n1corner && !n2corner && edgeb) {
00056           a->copyEntity(args.n,*a,args.nodes[1]);
00057         }
00058         else if(n2corner && !n1corner && edgeb) {
00059           a->copyEntity(args.n,*a,args.nodes[0]);
00060         }
00061         else if(n2corner && n1corner && edgeb) {
00062           
00063           
00064           
00065           
00066           
00067           
00068           
00069           int nbound = (abs(n1_bound)<abs(n2_bound)) ? n1_bound : n2_bound;
00070           
00071           FEM_DataAttribute *d = (FEM_DataAttribute *)a;
00072           d->getInt().setRow(args.n,nbound);
00073         }
00074         else {
00075           int nbound = 0;
00076           FEM_DataAttribute *d = (FEM_DataAttribute *)a;
00077           d->getInt().setRow(args.n,nbound);
00078         }
00079       }
00080       else if(n1_bound!=0 && n2_bound!=0) {
00081         
00082         a->copyEntity(args.n,*a,args.nodes[0]);
00083       }
00084       else if(n1_bound!=0) {
00085         a->copyEntity(args.n,*a,args.nodes[1]);
00086       }
00087       else if(n2_bound!=0) {
00088         a->copyEntity(args.n,*a,args.nodes[0]);
00089       }
00090       else {
00091         
00092         a->copyEntity(args.n,*a,args.nodes[0]);
00093       }
00094     }
00095     else {
00096       
00097       if(n1_bound!=0 && n2_bound==0) {
00098         a->copyEntity(args.n,*a,args.nodes[0]);
00099       }
00100       else if(n2_bound!=0 && n1_bound==0) {
00101         a->copyEntity(args.n,*a,args.nodes[1]);
00102       }
00103       else if(n1_bound!=0 && n2_bound!=0 && n1_bound==n2_bound) {
00104         
00105         a->copyEntity(args.n,*a,args.nodes[1]);
00106       }
00107       else if(n1_bound==0 && n2_bound==0) {
00108         
00109         a->copyEntity(args.n,*a,args.nodes[1]);
00110       }
00111       else {
00112         
00113         CkAssert(false);
00114       }
00115     }
00116       }
00117     }
00118   }
00119   
00120   if(theMod->fmUtil->isShared(args.n)) {
00121     
00122     int numchunks;
00123     IDXL_Share **chunks1;
00124     theMod->fmUtil->getChunkNos(0,args.n,&numchunks,&chunks1);
00125     char *data;
00126     int size, count;
00127     theMod->fmUtil->packEntData(&data, &size, &count, args.n, true, 0);
00128 
00129     for(int j=0; j<numchunks; j++) {
00130       int chk = chunks1[j]->chk;
00131       if(chk==theMod->getIdx()) continue;
00132       updateAttrsMsg *umsg = new (size,0)updateAttrsMsg(count);
00133       umsg->fromChk = theMod->idx;
00134       umsg->isnode = true;
00135       memcpy(umsg->data, data, size);
00136       umsg->sharedIdx = theMod->fmUtil->exists_in_IDXL(theMesh,args.n,chk,0);
00137       meshMod[chk].updateAttrs(umsg);
00138     }
00139     for(int j=0; j<numchunks; j++) {
00140       delete chunks1[j];
00141     }
00142     free(chunks1);
00143     free(data);
00144   }
00145 
00146   return;
00147 }
00148 
00152 void FEM_Interpolate::FEM_InterpolateNodeOnFace(NodalArgs args)
00153 {
00154   if (nodeFaceFnPtr) { 
00155     nodeFaceFnPtr(args, theMesh);
00156     return;
00157   }
00158   
00159   
00160   
00161 
00162   CkVec<FEM_Attribute *>*attrs = (theMesh->node).getAttrVec();
00163   for (int i=0; i<attrs->size(); i++) {
00164     FEM_Attribute *a = (FEM_Attribute *)(*attrs)[i];
00165     if (a->getAttr() < FEM_ATTRIB_TAG_MAX) {
00166       FEM_DataAttribute *d = (FEM_DataAttribute *)a;
00167       if ((args.nNbrs == 3) || (args.nNbrs == 4)){
00168     d->interpolate(args.nodes, args.n, args.nNbrs);
00169       }
00170       else {
00171     CkPrintf("ERROR: %d node faces not supported for node data interpolation.\n", args.nNbrs);
00172     CkAbort("ERROR: FEM_InterpolateNodeOnFace\n");
00173       }
00174     }
00175   }
00176   return;
00177 }
00178 
00182 void FEM_Interpolate::FEM_InterpolateNodeInElement(NodalArgs args)
00183 {
00184   if (nodeElementFnPtr) { 
00185     nodeElementFnPtr(args, theMesh);
00186     return;
00187   }
00188   
00189   
00190   
00191 
00192   CkVec<FEM_Attribute *>*attrs = (theMesh->node).getAttrVec();
00193   for (int i=0; i<attrs->size(); i++) {
00194     FEM_Attribute *a = (FEM_Attribute *)(*attrs)[i];
00195     if (a->getAttr() < FEM_ATTRIB_TAG_MAX) {
00196       FEM_DataAttribute *d = (FEM_DataAttribute *)a;
00197       if ((args.nNbrs >= 4) && (args.nNbrs <= 8)) {
00198     d->interpolate(args.nodes, args.n, args.nNbrs);
00199       }
00200       else {
00201     CkPrintf("ERROR: %d node elements not supported for node data interpolation.\n", args.nNbrs);
00202     CkAbort("ERROR: FEM_InterpolateNodeInElement\n");
00203       }
00204     }
00205   }
00206   return;
00207 }
00208 
00209 
00210 
00215 void FEM_Interpolate::FEM_InterpolateElementCopy(ElementArgs args)
00216 {
00217   if (elemCopyFnPtr) { 
00218     elemCopyFnPtr(args);
00219     return;
00220   }
00221   
00222   
00223   if(args.e>=0 && args.oldElement>=0) {
00224     CkVec<FEM_Attribute *>*elemattrs = (theMesh->elem[0]).getAttrVec();
00225     for(int j=0;j<elemattrs->size();j++){
00226       FEM_Attribute *elattr = (FEM_Attribute *)(*elemattrs)[j];
00227       if(elattr->getAttr() < FEM_ATTRIB_FIRST){ 
00228     elattr->copyEntity(args.e,*elattr,args.oldElement);
00229       }
00230       else if(elattr->getAttr()==FEM_MESH_SIZING) {
00231     elattr->copyEntity(args.e,*elattr,args.oldElement);
00232       }
00233     }
00234   }
00235   else if(FEM_Is_ghost_index(args.e) && FEM_Is_ghost_index(args.oldElement)) {
00236     const IDXL_Rec *irec1 = theMesh->elem[args.elType].ghost->ghostRecv.getRec(FEM_To_ghost_index(args.oldElement));
00237     int remotechk = irec1->getChk(0);
00238     int sharedIdx1 = irec1->getIdx(0);
00239     int sharedIdx2 = theMod->fmUtil->exists_in_IDXL(theMesh,args.e,remotechk,4,0);
00240     meshMod[remotechk].interpolateElemCopy(theMod->idx, sharedIdx1, sharedIdx2);
00241   }
00242   else {
00243     CkAssert(!FEM_Is_ghost_index(args.e) && FEM_Is_ghost_index(args.oldElement));
00244     const IDXL_Rec *irec1 = theMesh->elem[args.elType].ghost->ghostRecv.getRec(FEM_To_ghost_index(args.oldElement));
00245     int remotechk = irec1->getChk(0);
00246     int sharedIdx = irec1->getIdx(0);
00247     entDataMsg *em = meshMod[remotechk].packEntData(theMod->idx,sharedIdx,false,0);
00248     theMod->fmUtil->updateAttrs(em->data, em->datasize, args.e, false, 0);
00249     delete em;
00250   }
00251   return;
00252 }
00253 
00258 void FEM_Interpolate::FEM_InterpolateElementFromNodes(ElementArgs args)
00259 {
00260   if (elemNodeFnPtr) { 
00261     elemNodeFnPtr(args);
00262     return;
00263   }
00264   
00265   
00266 }
00267 
00271 void FEM_Interpolate::FEM_InterpolateElementToNodes(int e)
00272 {
00273   
00274   
00275   
00276   return;
00277 }
00278 
00279 
00280 
00285 void FEM_Interpolate::FEM_InterpolateCopyAttributes(int oldnode, int newnode) {
00286   int numchunks;
00287   IDXL_Share **chunks1;
00288   int index = theMod->idx;
00289 
00290 #ifndef FEM_SILENT
00291   theMod->fmUtil->FEM_Print_coords(theMesh,oldnode);
00292 #endif
00293   if(FEM_Is_ghost_index(oldnode) || FEM_Is_ghost_index(newnode)) {
00294     theMod->fmUtil->getChunkNos(0,oldnode,&numchunks,&chunks1);
00295   }
00296 
00297   char *data;
00298   int size, count;
00299   entDataMsg *em;
00300   if(!FEM_Is_ghost_index(oldnode)) {
00301     theMod->fmUtil->packEntData(&data, &size, &count, oldnode, true, 0);
00302   }
00303   else {
00304     for(int j=0; j<numchunks; j++) {
00305       int chk = chunks1[j]->chk;
00306       if(chk==index) continue;
00307       int ghostIdx = theMod->fmUtil->exists_in_IDXL(theMesh,oldnode,chk,2);
00308       em = meshMod[chk].packEntData(theMod->idx,ghostIdx,true,0);
00309       data = em->data;
00310       size = em->memsize;
00311       count = em->datasize;
00312       break;
00313     }
00314   }
00315 
00316   
00317   if(FEM_Is_ghost_index(newnode)) {
00318     for(int j=0; j<numchunks; j++) {
00319       int chk = chunks1[j]->chk;
00320       if(chk==index) continue;
00321       int sharedIdx = theMod->fmUtil->exists_in_IDXL(theMesh,newnode,chk,2);
00322       updateAttrsMsg *umsg = new (size, 0)updateAttrsMsg(count);
00323       umsg->fromChk = theMod->idx;
00324       umsg->sharedIdx = sharedIdx;
00325       umsg->isnode = true;
00326       umsg->isGhost = true;
00327       memcpy(umsg->data,data,size);
00328       meshMod[chk].updateAttrs(umsg);
00329     }
00330   }
00331   else {
00332     theMod->fmUtil->updateAttrs(data, count, newnode, true, 0);
00333   }
00334   delete em;
00335 
00336   if(FEM_Is_ghost_index(oldnode) || FEM_Is_ghost_index(newnode)) {
00337     for(int j=0; j<numchunks; j++) {
00338       delete chunks1[j];
00339     }
00340     if(numchunks != 0) free(chunks1);
00341   }
00342 #ifndef FEM_SILENT
00343   theMod->fmUtil->FEM_Print_coords(theMesh,newnode);
00344 #endif
00345   return;
00346 }