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 }