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); }
INT l_nlgs (NP_NLGS *nlgs, NP_NL_ASSEMBLE *ass, GRID *grid, const DOUBLE *damp, VECDATA_DESC *x, VECDATA_DESC *v, MATDATA_DESC *M, VECDATA_DESC *d) { VECTOR *vec,*w,*first_vec; NODE *theNode; MULTIGRID *mg; INT level; INT rtype,ctype,myindex,error; register MATRIX *mat; register SHORT *tmpptr,*dcomp,*xcomp,*vcomp; register SHORT i; register SHORT n; DEFINE_VD_CMPS(cy); DEFINE_MD_CMPS(m); DOUBLE r[MAX_SINGLE_VEC_COMP]; mg = nlgs->smoother.iter.base.mg; level = GLEVEL(grid); first_vec = FIRSTVECTOR(grid); L_VLOOP__CLASS(vec,first_vec,ACTIVE_CLASS) { rtype = VTYPE(vec); /* get node */ theNode = (NODE*)VOBJECT(vec); n = VD_NCMPS_IN_TYPE(v,rtype); if (n == 0) continue; dcomp = VD_CMPPTR_OF_TYPE(d,rtype); xcomp = VD_CMPPTR_OF_TYPE(x,rtype); vcomp = VD_CMPPTR_OF_TYPE(v,rtype); myindex = VINDEX(vec); /* local Jacobi matrix */ if ((*ass->NLNAssembleMatrix)(ass,level,level,theNode,x,d,v,M,&error)) { error = __LINE__; REP_ERR_RETURN(error); } /* get defect */ for (i=0; i<n; i++) r[i] = VVALUE(vec,dcomp[i]); /* rhs */ for (ctype=0; ctype<=NVECTYPES; ctype++) if (MD_ROWS_IN_RT_CT(M,rtype,ctype)>0) { SET_CMPS_22(cy,v,m,M,rtype,ctype,tmpptr); s0 = s1 = 0.0; for (mat=MNEXT(VSTART(vec)); mat!=NULL; mat=MNEXT(mat)) if (((VTYPE(w=MDEST(mat))==ctype) && (VCLASS(w)>=ACTIVE_CLASS)) && (myindex>VINDEX(w))) MATMUL_22(s,mat,m,w,cy); r[0] -= s0; r[1] -= s1; } /* solve */ if (MySolveSmallBlock(n,VD_CMPPTR_OF_TYPE(v,rtype),VVALPTR(vec), MD_MCMPPTR_OF_RT_CT(M,rtype,rtype), MVALPTR(VSTART(vec)),r)!=0) return (__LINE__); /* damp */ for (i=0; i<n; i++) VVALUE(vec,vcomp[i]) *= damp[i]; /* update solution */ for (i=0; i<n; i++) VVALUE(vec,xcomp[i]) -= VVALUE(vec,vcomp[i]); }
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 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); }