//Obtain so transformed 1D curve expression of this curve that //f(t)={sum(xi(t)*g[i]) for i=0(x), 1(y), 2(z)}-g[3], where f(t) is the output //of oneD and xi(t) is i-th coordinate expression of this curve. //This is used to compute intersections with a plane g[4]. std::auto_ptr<MGCurve> MGRLBRep::oneD( const double g[4] //Plane expression(a,b,c,d) where ax+by+cz=d. )const{ size_t i, nbd=bdim(); size_t j, w_id=sdim(); size_t k=order(); size_t ncod=3; if(ncod>w_id) ncod=w_id; const MGBPointSeq& cf=m_line.line_bcoef(); MGLBRep* brep=new MGLBRep(); MGBPointSeq& rcoef=brep->line_bcoef(); rcoef.resize(nbd,1); MGKnotVector& knotv=brep->knot_vector(); knotv.size_change(k,nbd); double min,max; const MGKnotVector& t=knot_vector(); double rt=0.; for(j=0; j<ncod; j++) rt+=coef(0,j)*g[j]; min=max=rt-=coef(0,w_id)*g[3]; rcoef(0,0)=rt; knotv(0)=t(0); for(i=1; i<nbd; i++){ rt=0.; for(j=0; j<ncod; j++) rt+=coef(i,j)*g[j]; rcoef(i,0)=rt-=coef(i,w_id)*g[3]; knotv(i)=t(i); if(min>rt) min=rt; if(max<rt) max=rt; } size_t npk=nbd+k; for(i=nbd; i<npk; i++) knotv(i)=t(i); MGInterval minmax(min,max); m_box=new MGBox(1,&minmax); return std::auto_ptr<MGCurve>(brep); }
void distribute_conn_mass(floatVector& lc, floatVector& rc, intVector& lc_cgrid, intVector& rc_cgrid, int val) { floatVector lcoef(3), rcoef(3); // frational value indicating connectivity assignment along 3 axes for (int i=0; i<3; i++) { lcoef[i]=lc[i]-floor(lc[i]); rcoef[i]=rc[i]-floor(rc[i]); } intVector tmpCoords(3); int lc_cgrid_ind=coarse_map()[lc_cgrid]-1, rc_cgrid_ind=coarse_map()[rc_cgrid]-1; for (int z=0; z<2; z++) { // Note: we assume that all points are in the interios, therefore exactly 8 points float lfracZ=(1-lcoef[2])*(1-z)+lcoef[2]*z; float rfracZ=(1-rcoef[2])*(1-z)+rcoef[2]*z; for (int y=0; y<2; y++) { float lfracZY=lfracZ * ( (1-lcoef[1])*(1-y)+lcoef[1]*y ); float rfracZY=rfracZ * ( (1-rcoef[1])*(1-y)+rcoef[1]*y ); for (int x=0; x<2; x++) { float lfracZYX=lfracZY * ( (1-lcoef[0])*(1-x)+lcoef[0]*x ); float rfracZYX=rfracZY * ( (1-rcoef[0])*(1-x)+rcoef[0]*x ); tmpCoords[0]=(int)lc[0]+x; tmpCoords[1]=(int)lc[1]+y; tmpCoords[2]=(int)lc[2]+z; // left conn_profile()[tmpCoords][rc_cgrid_ind] += lfracZYX * val; tmpCoords[0]=(int)rc[0]+x; tmpCoords[1]=(int)rc[1]+y; tmpCoords[2]=(int)rc[2]+z; // right conn_profile()[tmpCoords][lc_cgrid_ind] += rfracZYX * val; } } } }
// Compute parameter line. MGLBRep MGSBRep::parameter_line( int is_u //Indicates x is u-value if is_u is true. , double x //Parameter value. //The value is u or v according to is_u. , unsigned nderiv //Order of derivative. )const{ unsigned ku=order_u(); size_t lud=bdim_u(); unsigned kv=order_v(); size_t lvd=bdim_v(); size_t is1,is2; surface_bcoef().capacity(is1,is2); size_t ncd=sdim(), len; int kx; int k; if(is_u){ kx=1; len=lvd; k=kv; } else { kx=0; len=lud; k=ku; } MGLBRep lb(len,k,ncd); MGBPointSeq& rcoef=lb.line_bcoef(); MGKnotVector& t=lb.knot_vector(); int n; bsepl_(ku,lud,knot_data_u(),kv,lvd,knot_data_v(),coef_data(), is1,is2,ncd,kx,x,nderiv,len,&k,&n,&t(0),&rcoef(0,0)); return lb; }
void tet_hp_cns::minvrt() { int i,j,k,n,tind,msgn,sgn,sind,v0; Array<FLT,2> spokemass; int last_phase, mp_phase; Array<double,1> lcl(NV), lclug(NV),lclres(NV),uavg(NV); Array<TinyVector<double,MXGP>,2> P(NV,NV); Array<TinyVector<double,MXGP>,1> u1d(NV),res1d(NV),temp1d(NV); Array<TinyVector<double,MXTM>,1> ucoef(NV),rcoef(NV),tcoef(NV); if (basis::tet(log2p).p > 2) { *gbl->log << "cns minvrt only works for p = 1 and 2" << endl; exit(4); } /* LOOP THROUGH EDGES */ if (basis::tet(log2p).em > 0) { for(int eind = 0; eind<nseg;++eind) { /* SUBTRACT SIDE CONTRIBUTIONS TO VERTICES */ for (k=0; k <basis::tet(log2p).em; ++k) { for (i=0; i<2; ++i) { v0 = seg(eind).pnt(i); for(n=0;n<NV;++n) gbl->res.v(v0,n) -= basis::tet(log2p).sfmv(i,k)*gbl->res.e(eind,k,n); } } } } gbl->res.v(Range(0,npnt-1),Range::all()) *= gbl->vprcn(Range(0,npnt-1),Range::all())*basis::tet(log2p).vdiag; /* LOOP THROUGH VERTICES */ for(int i=0;i<npnt;++i){ for(int n = 0; n < NV; ++n) lclres(n) = gbl->res.v(i,n); if(gbl->preconditioner == 0 || gbl->preconditioner == 1) { for(int n = 0; n < NV; ++n) lclug(n) = ug.v(i,n); switch_variables(lclug,lclres); for(int j=0;j<NV;++j){ FLT lcl0 = lclres(j); for(int k=0;k<j;++k){ lcl0 -= gbl->vpreconditioner(i,j,k)*lclres(k); } lclres(j) = lcl0/gbl->vpreconditioner(i,j,j); } } else { int info,ipiv[NV]; Array<double,2> P(NV,NV); for(int j=0;j<NV;++j) for(int k=0;k<NV;++k) P(j,k) = gbl->vpreconditioner(i,j,k); GETRF(NV, NV, P.data(), NV, ipiv, info); if (info != 0) { *gbl->log << "DGETRF FAILED FOR CNS MINVRT" << std::endl; sim::abort(__LINE__,__FILE__,gbl->log); } char trans[] = "T"; GETRS(trans,NV,1,P.data(),NV,ipiv,lclres.data(),NV,info); } for(int n = 0; n < NV; ++n) gbl->res.v(i,n) = lclres(n); } for(last_phase = false, mp_phase = 0; !last_phase; ++mp_phase) { pc0load(mp_phase,gbl->res.v.data()); pmsgpass(boundary::all_phased,mp_phase,boundary::symmetric); last_phase = true; last_phase &= pc0wait_rcv(mp_phase,gbl->res.v.data()); } /* APPLY VERTEX DIRICHLET B.C.'S */ for(i=0;i<nfbd;++i) hp_fbdry(i)->vdirichlet(); for(i=0;i<nebd;++i) hp_ebdry(i)->vdirichlet3d(); for(i=0;i<nvbd;++i) hp_vbdry(i)->vdirichlet3d(); if(basis::tet(log2p).em == 0) return; /* LOOP THROUGH SIDES */ for(int sind=0;sind<nseg;++sind) { for(int n = 0; n < NV; ++n) lclres(n) = gbl->res.e(sind,0,n); Array<FLT,2> P(NV,NV); for(int j=0;j<NV;++j){ for(int k=0;k<NV;++k){ P(j,k) = gbl->epreconditioner(sind,j,k); //P(j,k) = 0.5*(gbl->vpreconditioner(seg(sind).pnt(0),j,k)+gbl->vpreconditioner(seg(sind).pnt(1),j,k)); } } if(gbl->preconditioner == 0 || gbl->preconditioner == 1) { for(int n = 0; n < NV; ++n) uavg(n) = 0.5*(ug.v(seg(sind).pnt(0),n)+ug.v(seg(sind).pnt(1),n)); switch_variables(uavg,lclres); for(int j=0;j<NV;++j){ FLT lcl0 = lclres(j); for(int k=0;k<j;++k){ lcl0 -= P(j,k)*lclres(k); } lclres(j) = lcl0/P(j,j); } } else { int info,ipiv[NV]; GETRF(NV, NV, P.data(), NV, ipiv, info); if (info != 0) { *gbl->log << "DGETRF FAILED FOR CNS MINVRT EDGE" << std::endl; sim::abort(__LINE__,__FILE__,gbl->log); } char trans[] = "T"; GETRS(trans,NV,1,P.data(),NV,ipiv,lclres.data(),NV,info); } for(int n = 0; n < NV; ++n) gbl->res.e(sind,0,n) = lclres(n); } /* REMOVE VERTEX CONTRIBUTION FROM SIDE MODES */ /* SOLVE FOR SIDE MODES */ /* PART 1 REMOVE VERTEX CONTRIBUTIONS */ for(tind=0;tind<ntet;++tind) { for(i=0;i<4;++i) { v0 = tet(tind).pnt(i); for(n=0;n<NV;++n) uht(n)(i) = gbl->res.v(v0,n)*gbl->iprcn(tind,n); } /* edges */ for(i=0;i<6;++i) { sind = tet(tind).seg(i); sgn = tet(tind).sgn(i); for(j=0;j<4;++j) { msgn = 1; for(k=0;k<basis::tet(log2p).em;++k) { for(n=0;n<NV;++n) gbl->res.e(sind,k,n) -= msgn*basis::tet(log2p).vfms(j,4+k+i*basis::tet(log2p).em)*uht(n)(j); msgn *= sgn; } } } } basis::tet(log2p).ediag(0) = 100.0;//for fast convergence //basis::tet(log2p).ediag(0) = 48.0; //for accuracy mass lumped edge modes gbl->res.e(Range(0,nseg-1),0,Range::all()) *= gbl->eprcn(Range(0,nseg-1),Range::all())*basis::tet(log2p).ediag(0); for(last_phase = false, mp_phase = 0; !last_phase; ++mp_phase) { sc0load(mp_phase,gbl->res.e.data(),0,0,gbl->res.e.extent(secondDim)); smsgpass(boundary::all_phased,mp_phase,boundary::symmetric); last_phase = true; last_phase &= sc0wait_rcv(mp_phase,gbl->res.e.data(),0,0,gbl->res.e.extent(secondDim)); } /* APPLY DIRCHLET B.C.S TO MODE */ for(int i=0;i<nfbd;++i) hp_fbdry(i)->edirichlet(); for (int i=0;i<nebd;++i) hp_ebdry(i)->edirichlet3d(); return; }