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