/* TODO renumber doesn't work in parallel */ static INT RenumberVertices (MULTIGRID *theMG, INT min_level, INT max_level) { INT l, i; ResetVertexFlags(theMG, min_level, max_level); /* reset used flags in vertices */ i = 0; for (l=min_level; l<=max_level; l++) { NODE *theNode; GRID *theGrid = GRID_ON_LEVEL(theMG,l); /* reset USED flags in all vertices */ for (theNode=FIRSTNODE(theGrid); theNode!=NULL; theNode=SUCCN(theNode)) { if (USED(MYVERTEX(theNode))) continue; SETUSED(MYVERTEX(theNode),1); ID(MYVERTEX(theNode)) = i; i++; } } return(0); }
static INT SetUnsymmetric (MULTIGRID *mg, INT fl, INT tl, const VECDATA_DESC *x, INT xclass, INT index) { SHORT i,j; INT vtype; INT lev; for (lev=fl; lev<=tl; lev++) l_setindex(GRID_ON_LEVEL(mg,lev)); j = 0; for (vtype=0; vtype<NVECTYPES; vtype++) if (VD_ISDEF_IN_TYPE(x,vtype)) { SHORT ncomp = VD_NCMPS_IN_TYPE(x,vtype); VECTOR *v; DOUBLE_VECTOR pos; A_VLOOP__TYPE_CLASS(lev,fl,tl,v,mg,vtype,xclass) { for (i=0; i<ncomp; i++) VVALUE(v,VD_CMP_OF_TYPE(x,vtype,i)) = 0.0; if (VECSKIP(v) != 0) continue; if (j++ < index) continue; if (VINDEX(v) % (index+2) == 0) continue; VectorPosition(v,pos); for (i=0; i<ncomp; i++) VVALUE(v,VD_CMP_OF_TYPE(x,vtype,i)) = pos[i]+1.0/(1.0+index*VINDEX(v)*VINDEX(v)); } } #ifdef ModelP if (a_vector_consistent(mg,fl,tl,x)) return(NUM_ERROR); #endif return (NUM_OK); }
static INT ComputeSurfaceGridStats (MULTIGRID *theMG, COVISE_HEADER *covise) { NODE *theNode; INT l, n_vertices, n_elem, n_conn; /* surface grid up to current level */ n_vertices = n_elem = n_conn = 0; for (l=covise->min_level; l<=covise->max_level; l++) { ELEMENT *theElement; GRID *theGrid = GRID_ON_LEVEL(theMG,l); /* reset USED flags in all vertices to be counted */ for (theNode=FIRSTNODE(theGrid); theNode!=NULL; theNode=SUCCN(theNode)) { SETUSED(MYVERTEX(theNode),0); } /* count geometric objects */ for (theElement=FIRSTELEMENT(theGrid); theElement!=NULL; theElement=SUCCE(theElement)) { if ((EstimateHere(theElement)) || (l==covise->max_level)) { int i, coe = CORNERS_OF_ELEM(theElement); n_elem++; for (i=0; i<coe; i++) { theNode = CORNER(theElement,i); n_conn++; if (USED(MYVERTEX(theNode))) continue; SETUSED(MYVERTEX(theNode),1); if ((SONNODE(theNode)==NULL) || (l==covise->max_level)) { #ifdef ModelP if (PRIO(theNode) == PrioMaster) #endif n_vertices++; } } } } } #ifdef ModelP n_vertices = UG_GlobalSumINT(n_vertices); n_elem = UG_GlobalSumINT(n_elem); n_conn = UG_GlobalSumINT(n_conn); #endif covise->n_vertices = n_vertices; covise->n_elems = n_elem; covise->n_conns = n_conn; return(0); }
INT NS_DIM_PREFIX CheckPartitioning (MULTIGRID *theMG) { INT i,_restrict_; ELEMENT *theElement; ELEMENT *theFather; GRID *theGrid; _restrict_ = 0; /* reset used flags */ for (i=TOPLEVEL(theMG); i>0; i--) { theGrid = GRID_ON_LEVEL(theMG,i); for (theElement=FIRSTELEMENT(theGrid); theElement!=NULL; theElement=SUCCE(theElement)) { if (LEAFELEM(theElement)) { theFather = theElement; while (EMASTER(theFather) && ECLASS(theFather)!=RED_CLASS && LEVEL(theFather)>0) { theFather = EFATHER(theFather); } /* if element with red element class does not exist */ /* or is ghost -> partitioning must be restricted */ if (!EMASTER(theFather)) { UserWriteF(PFMT "elem=" EID_FMTX " cannot be refined\n", me,EID_PRTX(theFather)); _restrict_ = 1; continue; } if (COARSEN(theFather)) { /* level 0 elements cannot be coarsened */ if (LEVEL(theFather)<=1) continue; if (!EMASTER(EFATHER(theFather))) { UserWriteF(PFMT "elem=" EID_FMTX " cannot be coarsened\n", me,EID_PRTX(theFather)); _restrict_ = 1; } } } } } _restrict_ = UG_GlobalMaxINT(_restrict_); if (me==master && _restrict_==1) { UserWriteF("CheckPartitioning(): partitioning is not valid for refinement\n"); UserWriteF(" cleaning up ...\n"); } return(_restrict_); }
static void ClearVertexMarkers(MULTIGRID *mg) { VERTEX *v; int i; for (i = 0; i <= TOPLEVEL(mg); i++) for (v = FIRSTVERTEX(GRID_ON_LEVEL(mg, i)); v != NULL; v = SUCCV(v)) SETUSED(v,0); }
static INT ResetVertexFlags (MULTIGRID *theMG, INT min_level, INT max_level) { INT l; /* reset used flags in vertices */ for (l=min_level; l<=max_level; l++) { NODE *theNode; GRID *theGrid = GRID_ON_LEVEL(theMG,l); /* reset USED flags in all vertices */ for (theNode=FIRSTNODE(theGrid); theNode!=NULL; theNode=SUCCN(theNode)) { SETUSED(MYVERTEX(theNode),0); } } return(0); /* no error */ }
int NS_DIM_PREFIX BalanceGridRCB (MULTIGRID *theMG, int level) { HEAP *theHeap = theMG->theHeap; GRID *theGrid = GRID_ON_LEVEL(theMG,level); /* balance grid of level */ LB_INFO *lbinfo; ELEMENT *e; int i, son; INT MarkKey; /* distributed grids cannot be redistributed by this function */ if (me!=master && FIRSTELEMENT(theGrid) != NULL) { printf("Error: Redistributing distributed grids using recursive coordinate bisection is not implemented!\n"); return (1); } if (me==master) { if (NT(theGrid) == 0) { UserWriteF("WARNING in BalanceGridRCB: no elements in grid\n"); return (1); } Mark(theHeap,FROM_TOP,&MarkKey); lbinfo = (LB_INFO *) GetMemUsingKey(theHeap, NT(theGrid)*sizeof(LB_INFO), FROM_TOP, MarkKey); if (lbinfo==NULL) { Release(theHeap,FROM_TOP,MarkKey); UserWrite("ERROR in BalanceGridRCB: could not allocate memory from the MGHeap\n"); return (1); } /* construct LB_INFO list */ for (i=0, e=FIRSTELEMENT(theGrid); e!=NULL; i++, e=SUCCE(e)) { lbinfo[i].elem = e; CenterOfMass(e, lbinfo[i].center); } /* apply coordinate bisection strategy */ theRCB(lbinfo, NT(theGrid), 0, 0, DimX, DimY, 0); IFDEBUG(dddif,1) for (e=FIRSTELEMENT(theGrid); e!=NULL; e=SUCCE(e)) { UserWriteF("elem %08x has dest=%d\n", DDD_InfoGlobalId(PARHDRE(e)), PARTITION(e)); } ENDDEBUG for (i=0, e=FIRSTELEMENT(theGrid); e!=NULL; i++, e=SUCCE(e)) { InheritPartition (e); } Release(theHeap,FROM_TOP,MarkKey); } return 0; }
static INT AMGSolver (NP_LINEAR_SOLVER *theNP, INT level, VECDATA_DESC *x, VECDATA_DESC *b, MATDATA_DESC *A, VEC_SCALAR abslimit, VEC_SCALAR reduction, LRESULT *lresult) { NP_AMG *theAMGC; VEC_SCALAR defect2reach; INT rv,i,bl,PrintID; char text[DISPLAY_WIDTH+4]; VEC_SCALAR Factor_One; MULTIGRID *theMG; GRID *theGrid; INT converged=0; int xcomp,bcomp; VECTOR *theVector; int k; INT nComp_x,nComp_b; int blocksize; double ti; int ii; #ifdef ModelP double clock_start; #else clock_t clock_start; #endif /* prepare solving */ theAMGC = (NP_AMG *) theNP; theMG = theAMGC->ls.base.mg; theGrid = GRID_ON_LEVEL(theMG,level); theAMGC->sc.red_factor=reduction[0]; theAMGC->sc.dnorm_min=abslimit[0]; if (theAMGC->AMG_Build_failed) { dset(NP_MG(theNP),level,level,ALL_VECTORS,x,0.0); return (0); } bl = 0; for (i=0; i<MAX_VEC_COMP; i++) Factor_One[i] = 1.0; /* allocate correction */ if (AllocVDFromVD(theNP->base.mg,0,level,x,&theAMGC->c)) { lresult->error_code = __LINE__; return(1); } /* print defect */ CenterInPattern(text,DISPLAY_WIDTH,ENVITEM_NAME(theAMGC),'*',"\n"); if (PreparePCR(x,theAMGC->display,text,&PrintID)) { lresult->error_code = __LINE__; return(1); } for (i=0; i<VD_NCOMP(x); i++) lresult->first_defect[i] = lresult->last_defect[i]; if (sc_mul_check(defect2reach,lresult->first_defect,reduction,b)) { lresult->error_code = __LINE__; return(1); } if (DoPCR(PrintID,lresult->first_defect,PCR_CRATE)) { lresult->error_code = __LINE__; return(1); } if (sc_cmp(lresult->first_defect,abslimit,b)) lresult->converged = 1; else lresult->converged = 0; CSTART(); ti=0; ii=0; /* fill values in x,b */ xcomp = VD_ncmp_cmpptr_of_otype(theAMGC->c,NODEVEC,&nComp_x)[0]; bcomp = VD_ncmp_cmpptr_of_otype(b,NODEVEC,&nComp_b)[0]; blocksize = nComp_x; if (blocksize==0) goto exit; if (nComp_b!=blocksize) goto exit; for (theVector=FIRSTVECTOR(theGrid); theVector!= NULL; theVector=SUCCVC(theVector)) { i = VINDEX(theVector); for (k=0; k<blocksize; k++) { AMG_VECTOR_ENTRY(theAMGC->b,i*blocksize+k,0)=VVALUE(theVector,bcomp+k); } } #ifdef ModelP /* only master solves */ if (me == master) { #endif AMG_dset(theAMGC->x,0.0); if ((rv=AMG_Solve(theAMGC->x,theAMGC->b))<0) { lresult->error_code = __LINE__; lresult->converged = 0; goto exit; } lresult->converged = 1; lresult->number_of_linear_iterations = rv; /* write back solution values */ for (theVector=FIRSTVECTOR(theGrid); theVector!= NULL; theVector=SUCCVC(theVector)) { i = VINDEX(theVector); for (k=0; k<blocksize; k++) VVALUE(theVector,xcomp+k)=AMG_VECTOR_ENTRY(theAMGC->x,i*blocksize+k,0); } if (dmatmul_minus(theNP->base.mg,0,level,ON_SURFACE,b,A,theAMGC->c) != NUM_OK) { lresult->error_code = __LINE__; return(1); } if (daxpyx(theAMGC->ls.base.mg,0,level, ON_SURFACE,x,Factor_One,theAMGC->c) != NUM_OK) { lresult->error_code = __LINE__; return(1); } #ifdef ModelP } #endif if (AMGSolverResiduum(theNP,bl,level,x,b,A,lresult)) return(1); if (DoPCR(PrintID, lresult->last_defect,PCR_CRATE)) { lresult->error_code = __LINE__; return (1); } if (DoPCR(PrintID,lresult->last_defect,PCR_AVERAGE)) { lresult->error_code = __LINE__; return (1); } FreeVD(theNP->base.mg,0,level,theAMGC->c); if (PostPCR(PrintID,NULL)) { lresult->error_code = __LINE__; return (1); } CSTOP(ti,ii); if (theAMGC->sc.verbose>0) { if (lresult->number_of_linear_iterations != 0) UserWriteF("AMG : L=%2d N=%2d TSOLVE=%10.4g TIT=%10.4g\n",level, lresult->number_of_linear_iterations,ti, ti/lresult->number_of_linear_iterations); else UserWriteF("AMG : L=%2d N=%2d TSOLVE=%10.4g\n",level, lresult->number_of_linear_iterations,ti); } return (0); exit: return(1); }
static INT AMGSolverPreProcess (NP_LINEAR_SOLVER *theNP, INT level, VECDATA_DESC *VD_x, VECDATA_DESC *VD_b, MATDATA_DESC *MD_A, INT *baselevel, INT *result) { MULTIGRID *theMG; GRID *theGrid; int n,nonzeros,blocksize; int Acomp; MATRIX *theMatrix; VECTOR *theVector; int i,j,block_i,block_j; int nRows_A,nCols_A,nComp_x,nComp_b; NP_AMG *theAMGC; double ti; int ii; #ifdef ModelP double clock_start; #else clock_t clock_start; #endif theAMGC = (NP_AMG *) theNP; /* prepare solving */ theMG = theAMGC->ls.base.mg; theGrid = GRID_ON_LEVEL(theMG,level); /* mark heap for use by amg */ #ifndef DYNAMIC_MEMORY_ALLOCMODEL Mark(MGHEAP(theMG),FROM_BOTTOM,&amg_MarkKey); #else Mark(MGHEAP(theMG),FROM_TOP,&amg_MarkKey); #endif mark_counter++; /* initialize sp package */ AMG_InstallPrintHandler((AMG_PrintFuncPtr)UserWrite); amgMG=theMG; /* make it global for memory handler */ AMG_InstallMallocHandler((AMG_MallocFuncPtr)amgmalloc); /* get access to components */ nRows_A = MD_ROWS_IN_RT_CT(MD_A,NODEVEC,NODEVEC); nCols_A = MD_COLS_IN_RT_CT(MD_A,NODEVEC,NODEVEC); nComp_x = VD_NCMPS_IN_TYPE(VD_x,NODEVEC); nComp_b = VD_NCMPS_IN_TYPE(VD_b,NODEVEC); blocksize = nComp_x; if (blocksize==0) goto exit; if (nComp_b!=blocksize) goto exit; if (nCols_A!=blocksize) goto exit; if (nRows_A!=blocksize) goto exit; Acomp = MD_MCMP_OF_RT_CT(MD_A,NODEVEC,NODEVEC,0); CSTART(); ti=0; ii=0; /* diagonal scaling */ if (theAMGC->scale) if (DiagonalScaleSystem(theGrid,MD_A,MD_A,VD_b)!=NUM_OK) { UserWrite("Error in scaling system\n"); goto exit; } /* gather some data for the matrix */ n = nonzeros = 0; /* loop through all vectors, we assume there are only node vectors ! */ for (theVector=FIRSTVECTOR(theGrid); theVector!= NULL; theVector=SUCCVC(theVector)) { VINDEX(theVector) = n++; /* renumber vectors just to be sure ... */ /* now speed through this row */ for (theMatrix=VSTART(theVector); theMatrix!=NULL; theMatrix = MNEXT(theMatrix)) nonzeros++; } #ifdef ModelP if (me == master) { #endif /* now allocate fine grid vectors x and b */ theAMGC->x = AMG_NewVector(n*blocksize,1,"x"); if (theAMGC->x==NULL) { UserWrite("no memory for x\n"); goto exit; } theAMGC->b = AMG_NewVector(n*blocksize,1,"b"); if (theAMGC->b==NULL) { UserWrite("no memory for b\n"); goto exit; } /* and a new matrix */ theAMGC->A = AMG_NewMatrix(n*blocksize,1,nonzeros*blocksize*blocksize,blocksize,"fine grid A"); if (theAMGC->A==NULL) { UserWrite("no memory for A\n"); goto exit; } #ifdef ModelP } else { /* no master vectors allowed */ assert(n==0); /* only master builds up coarse levels */ return (0); } #endif /* now fill matrix */ for (theVector=FIRSTVECTOR(theGrid); theVector!= NULL; theVector=SUCCVC(theVector)) { i = VINDEX(theVector); /* count row length */ nonzeros=0; for (theMatrix=VSTART(theVector); theMatrix!=NULL; theMatrix = MNEXT(theMatrix)) nonzeros++; /* for each row */ for (block_i=0; block_i<blocksize; block_i++) { /* allocate row */ if (AMG_SetRowLength(theAMGC->A,i*blocksize+block_i,nonzeros*blocksize)!=AMG_OK) { UserWrite("Error in AMG_SetRowLength\n"); goto exit; } /* the diagonal block, be careful to allocate the main diagonal first */ theMatrix=VSTART(theVector); if (AMG_InsertValues(theAMGC->A,i*blocksize+block_i,i*blocksize+block_i, &(MVALUE(theMatrix,Acomp+block_i*blocksize+block_i)))<0) { UserWrite("Error in AMG_InsertValues\n"); goto exit; } for (block_j=0; block_j<blocksize; block_j++) { if (block_j==block_i) continue; if (AMG_InsertValues(theAMGC->A,i*blocksize+block_i,i*blocksize+block_j, &(MVALUE(theMatrix,Acomp+block_i*blocksize+block_j)))<0) { UserWrite("Error in AMG_InsertValues\n"); goto exit; } } /* all the offdiagonal blocks */ for (theMatrix=MNEXT(VSTART(theVector)); theMatrix!=NULL; theMatrix = MNEXT(theMatrix)) { j = VINDEX(MDEST(theMatrix)); for (block_j=0; block_j<blocksize; block_j++) { if (AMG_InsertValues(theAMGC->A,i*blocksize+block_i,j*blocksize+block_j, &(MVALUE(theMatrix,Acomp+block_i*blocksize+block_j)))<0) { UserWrite("Error in AMG_InsertValues\n"); goto exit; } } } } } /*AMG_PrintMatrix(theAMGC->A,"Matrix");*/ /* call algebraic multigrid solver */ if (AMG_Build(&theAMGC->sc,&theAMGC->cc,theAMGC->A)!=AMG_OK) theAMGC->AMG_Build_failed=1; theAMGC->AMG_Build_failed=0; CSTOP(ti,ii); if (theAMGC->sc.verbose>0) UserWriteF("AMG : L=%2d BUILD=%10.4g\n",level,ti); return(0); /* ok, matrix is set up */ exit: /* error */ if (mark_counter>0) { #ifndef DYNAMIC_MEMORY_ALLOCMODEL Release(MGHEAP(theMG),FROM_BOTTOM,amg_MarkKey); #else Release(MGHEAP(theMG),FROM_TOP,amg_MarkKey); #endif mark_counter--; } return(1); }
INT NS_DIM_PREFIX CheckNP (MULTIGRID *theMG, INT argc, char **argv) { MATDATA_DESC *A; VECDATA_DESC *x,*y; INT i,level,nerr; char value[VALUELEN]; VEC_SCALAR damp; DOUBLE nrm,diff; if (ReadArgvChar("A",value,argc,argv) == 0) { A = GetMatDataDescByName(theMG,value); if (A == NULL) { UserWriteF("ERROR: no matrix %s in npckeck\n",value); return(1); } if (ReadArgvOption("S",argc,argv)) { for (level=theMG->bottomLevel; level<=TOPLEVEL(theMG); level++) if (CheckSymmetryOfMatrix(GRID_ON_LEVEL(theMG,level),A)) UserWriteF("matrix %s not symmetric on level %d\n", ENVITEM_NAME(A),level); return(0); } if (ReadArgvOption("G",argc,argv)) { if (ReadArgvChar("x",value,argc,argv)) { UserWriteF("ERROR: no vector in npckeck\n"); return(1); } x = GetVecDataDescByName(theMG,value); if (x == NULL) { UserWriteF("ERROR: no vector %s in npckeck\n",value); return(1); } level = CURRENTLEVEL(theMG); if (level == BOTTOMLEVEL(theMG)) { UserWriteF("ERROR: no GalerkinCheck," "level %d is bottomlevel\n",level); return(1); } if (AllocVDFromVD(theMG,level-1,level,x,&y)) return(1); dmatset(theMG,level-1,level-1,ALL_VECTORS,A,0.0); dset(theMG,level,level,ALL_VECTORS,x,0.0); dset(theMG,level-1,level,ALL_VECTORS,y,0.0); AssembleGalerkinByMatrix(GRID_ON_LEVEL(theMG,level),A,0); for (i=0; i<VD_NCOMP(x); i++) damp[i] = 1.0; InterpolateCorrectionByMatrix(GRID_ON_LEVEL(theMG,level),x,x,damp); if (dmatmul(theMG,level,level,ALL_VECTORS,y,A,x) != NUM_OK) return(1); RestrictByMatrix(GRID_ON_LEVEL(theMG,level),y,y,damp); IFDEBUG(np,1) UserWriteF("x %d\n",level-1); PrintVector(GRID_ON_LEVEL(theMG,level-1),x,3,3); UserWriteF("x %d\n",level); PrintVector(GRID_ON_LEVEL(theMG,level),x,3,3); UserWriteF("y %d\n",level); PrintVector(GRID_ON_LEVEL(theMG,level),y,3,3); UserWriteF("y %d\n",level-1); PrintVector(GRID_ON_LEVEL(theMG,level-1),y,3,3); ENDDEBUG if (dmatmul_minus(theMG,level-1,level-1,ALL_VECTORS,y,A,x)!=NUM_OK) return(1); IFDEBUG(np,1) UserWriteF("y %d\n",level-1); PrintVector(GRID_ON_LEVEL(theMG,level-1),y,3,3); ENDDEBUG dnrm2(theMG,level-1,level-1,ALL_VECTORS,x,&nrm); dnrm2(theMG,level-1,level-1,ALL_VECTORS,y,&diff); UserWriteF("Galerkin test: nrm(x) = %f nrm(Ax-RAPx) = %f\n", nrm,diff); return(0); } }
static INT SendSolution (MULTIGRID *theMG, COVISE_HEADER *covise, INT idx_sol) { INT l, remaining, sent, n_comp_sol; TokenBuffer tb; Message* msg = new Message; msg->type = (covise_msg_type)0; printf("CoviseIF: SendSolution start, idx_sol=%d\n", idx_sol); n_comp_sol = covise->solutions[idx_sol].n_components; /* reset vertex flags */ ResetVertexFlags(theMG, covise->min_level, covise->max_level); /* start first buffer */ tb.reset(); remaining = MIN(covise->n_vertices,MAX_ITEMS_SENT); tb << MT_UGSCALAR; tb << idx_sol; tb << remaining; sent = 0; /* extract data, loop from max_level to min_level! */ /* TODO: special handling in ModelP */ for (l=covise->max_level; l>=covise->min_level; l--) { NODE *theNode; GRID *theGrid = GRID_ON_LEVEL(theMG,l); for (theNode=FIRSTNODE(theGrid); theNode!=NULL; theNode=SUCCN(theNode)) { VECTOR *theVector; INT i; INT vid; if (USED(MYVERTEX(theNode))) continue; SETUSED(MYVERTEX(theNode),1); /* NOTE: vid is sent along with data! this increases msg sizes, but is the secure solution (resistent to message order a.s.o.) */ vid = ID(MYVERTEX(theNode)); tb << (INT32)vid; theVector = NVECTOR(theNode); /* extract data from vector */ for(i=0; i<n_comp_sol; i++) { INT comp = covise->solutions[idx_sol].comps[i]; tb << (FLOAT32) VVALUE(theVector,comp); } remaining--; sent++; if (remaining==0) { /* send this buffer */ msg->data = (char*)tb.get_data(); msg->length = tb.get_length(); covise_connection->send_msg(msg); /* start next buffer */ tb.reset(); remaining = MIN(covise->n_vertices - sent, MAX_ITEMS_SENT); tb << MT_UGSCALAR; tb << idx_sol; tb << remaining; } } } delete msg; printf("CoviseIF: SendSolution stop\n"); return(0); }
static INT SendSurfaceGrid (MULTIGRID *theMG, COVISE_HEADER *covise) { INT l, remaining, sent; TokenBuffer tb; Message* msg = new Message; msg->type = (covise_msg_type)0; printf("CoviseIF: SendSurfaceGrid start\n"); /* renumber vertex IDs */ /* TODO doesn't work in ModelP */ RenumberVertices(theMG, covise->min_level, covise->max_level); /* send surface vertices, part1: set flags */ ResetVertexFlags(theMG, covise->min_level, covise->max_level); /* send surface vertices, part2: send data */ sent = 0; /* start first buffer */ tb.reset(); remaining = MIN(covise->n_vertices,MAX_ITEMS_SENT); tb << MT_UGGRIDV; tb << remaining; for (l=covise->min_level; l<=covise->max_level; l++) { NODE *theNode; GRID *theGrid = GRID_ON_LEVEL(theMG,l); for (theNode=FIRSTNODE(theGrid); theNode!=NULL; theNode=SUCCN(theNode)) { INT vid; DOUBLE *pos; if (USED(MYVERTEX(theNode))) continue; SETUSED(MYVERTEX(theNode),1); /* extract data from vertex */ /* TODO use VXGID in ModelP */ vid = ID(MYVERTEX(theNode)); pos = CVECT(MYVERTEX(theNode)); tb << (INT32)vid; tb << (FLOAT32)pos[0]; tb << (FLOAT32)pos[1]; tb << (FLOAT32)pos[2]; remaining--; sent++; if (remaining==0) { /* send this buffer */ msg->data = (char*)tb.get_data(); msg->length = tb.get_length(); covise_connection->send_msg(msg); /* start next buffer */ tb.reset(); tb << MT_UGGRIDV; remaining = MIN(covise->n_vertices - sent, MAX_ITEMS_SENT); tb << remaining; } } } printf("CoviseIF: SendSurfaceGrid ...\n"); /* next buffer */ tb.reset(); tb << MT_UGGRIDE; remaining = MIN(covise->n_elems,MAX_ITEMS_SENT); tb << remaining; sent = 0; /* send surface elems and connectivity */ for (l=covise->min_level; l<=covise->max_level; l++) { ELEMENT *theElement; GRID *theGrid = GRID_ON_LEVEL(theMG,l); for (theElement=FIRSTELEMENT(theGrid); theElement!=NULL; theElement=SUCCE(theElement)) { if ((EstimateHere(theElement)) || (l==covise->max_level)) { int i, coe = CORNERS_OF_ELEM(theElement); tb << (INT32)coe; for (i=0; i<coe; i++) { NODE *theNode = CORNER(theElement,i); INT vid; vid = ID(MYVERTEX(theNode)); /* TODO use VXGID in ModelP */ tb << (INT32)vid; } remaining--; sent++; if (remaining==0) { /* send this buffer */ msg->data = (char*)tb.get_data(); msg->length = tb.get_length(); covise_connection->send_msg(msg); /* start next buffer */ tb.reset(); tb << MT_UGGRIDE; remaining = MIN(covise->n_elems - sent, MAX_ITEMS_SENT); tb << remaining; } } } } /* cleanup */ delete msg; printf("CoviseIF: SendSurfaceGrid stop\n"); return(0); }
INT NS_DIM_PREFIX RestrictPartitioning (MULTIGRID *theMG) { INT i,j; ELEMENT *theElement; ELEMENT *theFather; ELEMENT *SonList[MAX_SONS]; GRID *theGrid; /* reset used flags */ for (i=TOPLEVEL(theMG); i>=0; i--) { theGrid = GRID_ON_LEVEL(theMG,i); for (theElement=PFIRSTELEMENT(theGrid); theElement!=NULL; theElement=SUCCE(theElement)) { SETUSED(theElement,0); } } /* set flags on elements which violate restriction */ for (i=TOPLEVEL(theMG); i>=0; i--) { theGrid = GRID_ON_LEVEL(theMG,i); for (theElement=FIRSTELEMENT(theGrid); theElement!=NULL; theElement=SUCCE(theElement)) { if (GLEVEL(theGrid) == 0) break; if (LEAFELEM(theElement) || USED(theElement)) { theFather = theElement; while (EMASTER(theFather) && ECLASS(theFather)!=RED_CLASS && LEVEL(theFather)>0) { theFather = EFATHER(theFather); } /* if father with red refine class is not master */ /* partitioning must be restricted */ if (!EMASTER(theFather)) { /* the sons of father will be sent to partition of father */ SETUSED(theFather,1); } /* if element is marked for coarsening and father */ /* of element is not master -> restriction is needed */ if (COARSEN(theFather)) { /* level 0 elements are not coarsened */ if (LEVEL(theFather)<=1) continue; if (!EMASTER(EFATHER(theFather))) SETUSED(EFATHER(theFather),1); } } } /* transfer restriction flags to master copies of father */ DDD_IFAOneway(ElementVHIF,GRID_ATTR(theGrid),IF_BACKWARD,sizeof(INT), Gather_ElementRestriction, Scatter_ElementRestriction); } /* send restricted sons to partition of father */ for (i=0; i<=TOPLEVEL(theMG); i++) { theGrid = GRID_ON_LEVEL(theMG,i); /* transfer (new) partitions of elements to non master copies */ DDD_IFAOnewayX(ElementVHIF,GRID_ATTR(theGrid),IF_FORWARD,sizeof(INT), Gather_RestrictedPartition, Scatter_RestrictedPartition); for (theElement=PFIRSTELEMENT(theGrid); theElement!=NULL; theElement=SUCCE(theElement)) { if (!USED(theElement)) continue; /* push partition to the sons */ GetAllSons(theElement,SonList); for (j=0; SonList[j]!=NULL; j++) { SETUSED(SonList[j],1); if (EMASTER(SonList[j])) PARTITION(SonList[j]) = PARTITION(theElement); } } } if (TransferGrid(theMG) != 0) RETURN(GM_FATAL); return(GM_OK); }
static INT TecplotCommand (INT argc, char **argv) { INT i,j,k,v; /* counters etc. */ INT counter; /* for formatting output */ char item[1024],it[256]; /* item buffers */ INT ic=0; /* item length */ VECTOR *vc; /* a vector pointer */ ELEMENT *el; /* an element pointer */ MULTIGRID *mg; /* our multigrid */ char filename[NAMESIZE]; /* file name for output file */ PFILE *pf; /* the output file pointer */ INT nv; /* number of variables (eval functions) */ EVALUES *ev[MAXVARIABLES]; /* pointers to eval function descriptors */ char ev_name[MAXVARIABLES][NAMESIZE]; /* names for eval functions */ char s[NAMESIZE]; /* name of eval proc */ char zonename[NAMESIZE+7] = ""; /* name for zone (initialized to empty string) */ INT numNodes; /* number of data points */ INT numElements; /* number of elements */ INT gnumNodes; /* number of data points globally */ INT gnumElements; /* number of elements globallay */ PreprocessingProcPtr pre; /* pointer to prepare function */ ElementEvalProcPtr eval; /* pointer to evaluation function */ DOUBLE *CornersCoord[MAX_CORNERS_OF_ELEM]; /* pointers to coordinates */ DOUBLE LocalCoord[DIM]; /* is one of the corners local coordinates */ DOUBLE local[DIM]; /* local coordinate in DOUBLE */ DOUBLE value; /* returned by user eval proc */ INT oe,on; INT saveGeometry; /* save geometry flag */ /* get current multigrid */ mg = GetCurrentMultigrid(); if (mg==NULL) { PrintErrorMessage('W',"tecplot","no multigrid open\n"); return (OKCODE); } /* scan options */ nv = 0; saveGeometry = 0; for(i=1; i<argc; i++) { switch(argv[i][0]) { case 'e' : /* read eval proc */ if (nv>=MAXVARIABLES) { PrintErrorMessage('E',"tecplot","too many variables specified\n"); break; } sscanf(argv[i],"e %s", s); ev[nv] = GetElementValueEvalProc(s); if (ev[nv]==NULL) { PrintErrorMessageF('E',"tecplot","could not find eval proc %s\n",s); break; } if (sscanf(argv[i+1],"s %s", s) == 1) { strcpy(ev_name[nv],s); i++; } else strcpy(ev_name[nv],ev[nv]->v.name); nv++; break; case 'z' : sscanf(argv[i],"z %s", zonename+3); memcpy(zonename, "T=\"", 3); memcpy(zonename+strlen(zonename), "\", \0", 4); break; case 'g' : sscanf(argv[i],"g %d", &saveGeometry); if (saveGeometry<0) saveGeometry=0; if (saveGeometry>1) saveGeometry=1; break; } } if (nv==0) UserWrite("tecplot: no variables given, printing mesh data only\n"); /* get file name and open output file */ if (sscanf(argv[0],expandfmt(CONCAT3(" tecplot %",NAMELENSTR,"[ -~]")),filename)!=1) { PrintErrorMessage('E',"tecplot","could not read name of logfile"); return(PARAMERRORCODE); } pf = pfile_open(filename); if (pf==NULL) return(PARAMERRORCODE); /********************************/ /* TITLE */ /********************************/ ic = 0; sprintf(it,"TITLE = \"UG TECPLOT OUTPUT\"\n"); strcpy(item+ic,it); ic+=strlen(it); sprintf(it,"VARIABLES = \"X\", \"Y\""); strcpy(item+ic,it); ic+=strlen(it); if (DIM==3) { sprintf(it,", \"Z\""); strcpy(item+ic,it); ic+=strlen(it); } for (i=0; i<nv; i++) { sprintf(it,", \"%s\"",ev[i]->v.name); strcpy(item+ic,it); ic+=strlen(it); } sprintf(it,"\n"); strcpy(item+ic,it); ic+=strlen(it); pfile_master_puts(pf,item); ic=0; /********************************/ /* compute sizes */ /********************************/ /* clear VCFLAG on all levels */ for (k=0; k<=TOPLEVEL(mg); k++) for (vc=FIRSTVECTOR(GRID_ON_LEVEL(mg,k)); vc!=NULL; vc=SUCCVC(vc)) SETVCFLAG(vc,0); /* run thru all levels of elements and set index */ numNodes = numElements = 0; for (k=0; k<=TOPLEVEL(mg); k++) for (el=FIRSTELEMENT(GRID_ON_LEVEL(mg,k)); el!=NULL; el=SUCCE(el)) { if (!EstimateHere(el)) continue; /* process finest level elements only */ numElements++; /* increase element counter */ for (i=0; i<CORNERS_OF_ELEM(el); i++) { vc = NVECTOR(CORNER(el,i)); if (VCFLAG(vc)) continue; /* we have this one already */ VINDEX(vc) = ++numNodes; /* number of data points, begins with 1 ! */ SETVCFLAG(vc,1); /* tag vector as visited */ } } #ifdef ModelP gnumNodes = TPL_GlobalSumINT(numNodes); gnumElements = TPL_GlobalSumINT(numElements); on=get_offset(numNodes); oe=get_offset(numElements); /* clear VCFLAG on all levels */ for (k=0; k<=TOPLEVEL(mg); k++) for (vc=FIRSTVECTOR(GRID_ON_LEVEL(mg,k)); vc!=NULL; vc=SUCCVC(vc)) SETVCFLAG(vc,0); /* number in unique way */ for (k=0; k<=TOPLEVEL(mg); k++) for (el=FIRSTELEMENT(GRID_ON_LEVEL(mg,k)); el!=NULL; el=SUCCE(el)) { if (!EstimateHere(el)) continue; /* process finest level elements only */ for (i=0; i<CORNERS_OF_ELEM(el); i++) { vc = NVECTOR(CORNER(el,i)); if (VCFLAG(vc)) continue; /* we have this one already */ VINDEX(vc) += on; /* add offset */ SETVCFLAG(vc,1); /* tag vector as visited */ } } #else gnumNodes = numNodes; gnumElements = numElements; oe=on=0; #endif /********************************/ /* write ZONE data */ /* uses FEPOINT for data */ /* uses QUADRILATERAL in 2D */ /* and BRICK in 3D */ /********************************/ /* write zone record header */ if (DIM==2) sprintf(it,"ZONE %sN=%d, E=%d, F=FEPOINT, ET=QUADRILATERAL\n", zonename, gnumNodes,gnumElements); if (DIM==3) sprintf(it,"ZONE %sN=%d, E=%d, F=FEPOINT, ET=BRICK\n", zonename, gnumNodes,gnumElements); strcpy(item+ic,it); ic+=strlen(it); pfile_master_puts(pf,item); ic=0; /* write data in FEPOINT format, i.e. all variables of a node per line*/ for (k=0; k<=TOPLEVEL(mg); k++) for (vc=FIRSTVECTOR(GRID_ON_LEVEL(mg,k)); vc!=NULL; vc=SUCCVC(vc)) SETVCFLAG(vc,0); /* clear all flags */ counter=0; for (k=0; k<=TOPLEVEL(mg); k++) for (el=FIRSTELEMENT(GRID_ON_LEVEL(mg,k)); el!=NULL; el=SUCCE(el)) { if (!EstimateHere(el)) continue; /* process finest level elements only */ for (i=0; i<CORNERS_OF_ELEM(el); i++) CornersCoord[i] = CVECT(MYVERTEX(CORNER(el,i))); /* x,y,z of corners */ for (i=0; i<CORNERS_OF_ELEM(el); i++) { vc = NVECTOR(CORNER(el,i)); if (VCFLAG(vc)) continue; /* we have this one alre ady */ SETVCFLAG(vc,1); /* tag vector as visited */ sprintf(it,"%g",(double)XC(MYVERTEX(CORNER(el,i)))); strcpy(item+ic,it); ic+=strlen(it); sprintf(it," %g",(double)YC(MYVERTEX(CORNER(el,i)))); strcpy(item+ic,it); ic+=strlen(it); if (DIM == 3) { sprintf(it," %g",(double)ZC(MYVERTEX(CORNER(el,i)))); strcpy(item+ic,it); ic+=strlen(it); } /* now all the user variables */ /* get local coordinate of corner */ LocalCornerCoordinates(DIM,TAG(el),i,local); for (j=0; j<DIM; j++) LocalCoord[j] = local[j]; for (v=0; v<nv; v++) { pre = ev[v]->PreprocessProc; eval = ev[v]->EvalProc; /* execute prepare function */ /* This is not really equivalent to the FEBLOCK-version sinc we call "pre" more often than there. D.Werner */ if (pre!=NULL) pre(ev_name[v],mg); /* call eval function */ value = eval(el,(const DOUBLE **)CornersCoord,LocalCoord); sprintf(it," %g",value); strcpy(item+ic,it); ic+=strlen(it); } sprintf(it,"\n"); strcpy(item+ic,it); ic+=strlen(it); pfile_tagged_puts(pf,item,counter+on); ic=0; counter++; } } pfile_sync(pf); /* end of segment */ sprintf(it,"\n"); strcpy(item+ic,it); ic+=strlen(it); pfile_master_puts(pf,item); ic=0; /* finally write the connectivity list */ counter=0; for (k=0; k<=TOPLEVEL(mg); k++) for (el=FIRSTELEMENT(GRID_ON_LEVEL(mg,k)); el!=NULL; el=SUCCE(el)) { if (!EstimateHere(el)) continue; /* process finest level elements only */ switch(DIM) { case 2 : switch(TAG(el)) { case TRIANGLE : sprintf(it,"%d %d %d %d\n", VINDEX(NVECTOR(CORNER(el,0))), VINDEX(NVECTOR(CORNER(el,1))), VINDEX(NVECTOR(CORNER(el,2))), VINDEX(NVECTOR(CORNER(el,2))) ); break; case QUADRILATERAL : sprintf(it,"%d %d %d %d\n", VINDEX(NVECTOR(CORNER(el,0))), VINDEX(NVECTOR(CORNER(el,1))), VINDEX(NVECTOR(CORNER(el,2))), VINDEX(NVECTOR(CORNER(el,3))) ); break; default : UserWriteF("tecplot: unknown 2D element type with tag(el) = %d detected. Aborting further processing of command tecplot\n", TAG(el)); return CMDERRORCODE; break; } break; case 3 : switch(TAG(el)) { case HEXAHEDRON : sprintf(it,"%d %d %d %d " "%d %d %d %d\n", VINDEX(NVECTOR(CORNER(el,0))), VINDEX(NVECTOR(CORNER(el,1))), VINDEX(NVECTOR(CORNER(el,2))), VINDEX(NVECTOR(CORNER(el,3))), VINDEX(NVECTOR(CORNER(el,4))), VINDEX(NVECTOR(CORNER(el,5))), VINDEX(NVECTOR(CORNER(el,6))), VINDEX(NVECTOR(CORNER(el,7))) ); break; case TETRAHEDRON : sprintf(it,"%d %d %d %d " "%d %d %d %d\n", VINDEX(NVECTOR(CORNER(el,0))), VINDEX(NVECTOR(CORNER(el,1))), VINDEX(NVECTOR(CORNER(el,2))), VINDEX(NVECTOR(CORNER(el,2))), VINDEX(NVECTOR(CORNER(el,3))), VINDEX(NVECTOR(CORNER(el,3))), VINDEX(NVECTOR(CORNER(el,3))), VINDEX(NVECTOR(CORNER(el,3))) ); break; case PYRAMID : sprintf(it,"%d %d %d %d " "%d %d %d %d\n", VINDEX(NVECTOR(CORNER(el,0))), VINDEX(NVECTOR(CORNER(el,1))), VINDEX(NVECTOR(CORNER(el,2))), VINDEX(NVECTOR(CORNER(el,3))), VINDEX(NVECTOR(CORNER(el,4))), VINDEX(NVECTOR(CORNER(el,4))), VINDEX(NVECTOR(CORNER(el,4))), VINDEX(NVECTOR(CORNER(el,4))) ); break; case PRISM : sprintf(it,"%d %d %d %d " "%d %d %d %d\n", VINDEX(NVECTOR(CORNER(el,0))), VINDEX(NVECTOR(CORNER(el,1))), VINDEX(NVECTOR(CORNER(el,2))), VINDEX(NVECTOR(CORNER(el,2))), VINDEX(NVECTOR(CORNER(el,3))), VINDEX(NVECTOR(CORNER(el,4))), VINDEX(NVECTOR(CORNER(el,5))), VINDEX(NVECTOR(CORNER(el,5))) ); break; default : UserWriteF("tecplot: unknown 3D element type with tag(el) = %d detected. Aborting further processing of command tecplot\n", TAG(el)); return CMDERRORCODE; break; } break; } strcpy(item+ic,it); ic+=strlen(it); pfile_tagged_puts(pf,item,counter+oe); ic=0; counter++; } pfile_sync(pf); /* end of segment */ /********************************/ /* GEOMETRY */ /* we will do this later, since */ /* domain interface will change */ /********************************/ pfile_close(pf); return(OKCODE); }