//----------------------------------------------------------------------------- HADT MGL_EXPORT mgl_datac_combine(HCDT d1, HCDT d2) { long n1=d1->GetNy(),n2=d2->GetNx(),nx=d1->GetNx(); if(d1->GetNz()>1 || (n1>1 && d2->GetNy()>1) || d2->GetNz()>1) return 0; // wrong dimensions mglDataC *r=new mglDataC; bool dim2=true; if(n1==1) { n1=n2; n2=d2->GetNy(); dim2 = false; } r->Create(nx,n1,n2); if(dim2) n1*=nx; else { n2*=n1; n1=nx; } const mglDataC *c1=dynamic_cast<const mglDataC *>(d1); const mglDataC *c2=dynamic_cast<const mglDataC *>(d2); if(c1 && c2) #pragma omp parallel for collapse(2) for(long j=0;j<n2;j++) for(long i=0;i<n1;i++) r->a[i+n1*j] = c1->a[i]*c2->a[j]; else if(c1) #pragma omp parallel for collapse(2) for(long j=0;j<n2;j++) for(long i=0;i<n1;i++) r->a[i+n1*j] = c1->a[i]*d2->vthr(j); else if(c2) #pragma omp parallel for collapse(2) for(long j=0;j<n2;j++) for(long i=0;i<n1;i++) r->a[i+n1*j] = d1->vthr(i)*c2->a[j]; else #pragma omp parallel for collapse(2) for(long j=0;j<n2;j++) for(long i=0;i<n1;i++) r->a[i+n1*j] = d1->vthr(i)*d2->vthr(j); return r; }
//----------------------------------------------------------------------------- HADT MGL_EXPORT mgl_datac_evaluate(HCDT dat, HCDT idat, HCDT jdat, HCDT kdat, int norm) { if(!idat || (jdat && jdat->GetNN()!=idat->GetNN()) || (kdat && kdat->GetNN()!=idat->GetNN())) return 0; const mglData *dd=dynamic_cast<const mglData *>(dat); const mglDataC *dc=dynamic_cast<const mglDataC *>(dat); long nx=dat->GetNx(), ny=dat->GetNy(), nz=dat->GetNz(); mglDataC *r=new mglDataC(idat->GetNx(),idat->GetNy(),idat->GetNz()); if(dd) #pragma omp parallel for for(long i=0;i<idat->GetNN();i++) { mreal x=idat->vthr(i), y=jdat?jdat->vthr(i):0, z=kdat?kdat->vthr(i):0; r->a[i] = mgl_isnum(x*y*z)?mglSpline3st<mreal>(dd->a,nx,ny,nz, x,y,z):NAN; } else if(dc) #pragma omp parallel for for(long i=0;i<idat->GetNN();i++) { mreal x=idat->vthr(i), y=jdat?jdat->vthr(i):0, z=kdat?kdat->vthr(i):0; r->a[i] = mgl_isnum(x*y*z)?mglSpline3st<dual>(dc->a,nx,ny,nz, x,y,z):NAN; } else #pragma omp parallel for for(long i=0;i<idat->GetNN();i++) { mreal x=idat->vthr(i), y=jdat?jdat->vthr(i):0, z=kdat?kdat->vthr(i):0; r->a[i] = mgl_isnum(x*y*z)?mgl_data_linear(dat, x,y,z):NAN;; } return r; }
//----------------------------------------------------------------------------- // // Dots series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_dots_ca(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT c, HCDT a, const char *sch, const char *opt) { long n = x->GetNN(), d, k=1; if(x->GetNz()>1) k=3; else if(x->GetNy()>1) k=2; if(y->GetNN()!=n || z->GetNN()!=n || c->GetNN()!=n || (a && a->GetNN()!=n)) { gr->SetWarn(mglWarnDim,"Dots"); return; } gr->SaveState(opt); d = gr->MeshNum>0 ? mgl_ipow(gr->MeshNum+1,k) : n; d = n>d ? n/d:1; static int cgid=1; gr->StartGroup("Dots",cgid++); char mk=gr->SetPenPal(sch); long ss=gr->AddTexture(sch); if(mk==0) mk='.'; gr->Reserve(n); for(long i=0;i<n;i+=d) { mglPoint p = mglPoint(x->vthr(i),y->vthr(i),z->vthr(i)); long pp = gr->AddPnt(p,gr->GetC(ss,c->vthr(i)),mglPoint(NAN),a?gr->GetA(a->vthr(i)):-1); gr->mark_plot(pp, mk); } gr->EndGroup(); }
//----------------------------------------------------------------------------- HADT MGL_EXPORT mgl_datac_column(HCDT dat, const char *eq) { const mglData *dd=dynamic_cast<const mglData *>(dat); std::vector<mglDataA*> list; if(dd && dd->id.length()>0) for(size_t i=0;i<dd->id.length();i++) { mglDataT *col = new mglDataT(*dat); col->SetInd(i,dd->id[i]); list.push_back(col); } const mglDataC *dc=dynamic_cast<const mglDataC *>(dat); if(dc && dc->id.length()>0) for(size_t i=0;i<dc->id.length();i++) { mglDataT *col = new mglDataT(*dat); col->SetInd(i,dc->id[i]); list.push_back(col); } if(list.size()==0) return 0; // no named columns mglDataV *t = new mglDataV(dat->GetNy(),dat->GetNz()); t->s=L"#$mgl"; list.push_back(t); mglDataC *r = new mglDataC; r->Set(mglFormulaCalcC(eq,list)); for(size_t i=0;i<list.size();i++) delete list[i]; return r; }
HADT MGL_EXPORT mgl_datac_sum(HCDT dat, const char *dir) { if(!dir || *dir==0) return 0; long nx=dat->GetNx(),ny=dat->GetNy(),nz=dat->GetNz(); long p[3]={nx,ny,nz}; dual *b = new dual[nx*ny*nz]; dual *c = new dual[nx*ny*nz]; const mglDataC *d=dynamic_cast<const mglDataC *>(dat); if(d) memcpy(c,d->a,nx*ny*nz*sizeof(dual)); else #pragma omp parallel for for(long i=0;i<nx*ny*nz;i++) c[i]=dat->vthr(i); if(strchr(dir,'z') && nz>1) { mglStartThreadC(mgl_sumc_z,0,nx*ny,b,c,0,p); memcpy(c,b,nx*ny*sizeof(mreal)); p[2] = 1; } if(strchr(dir,'y') && ny>1) { mglStartThreadC(mgl_sumc_y,0,nx*p[2],b,c,0,p); memcpy(c,b,nx*p[2]*sizeof(mreal)); p[1] = p[2]; p[2] = 1; } if(strchr(dir,'x') && nx>1) { mglStartThreadC(mgl_sumc_x,0,p[1]*p[2],b,c,0,p); p[0] = p[1]; p[1] = p[2]; p[2] = 1; } mglDataC *r=new mglDataC(p[0],p[1],p[2]); memcpy(r->a,b,p[0]*p[1]*p[2]*sizeof(dual)); delete []b; delete []c; return r; }
//----------------------------------------------------------------------------- HADT MGL_EXPORT mgl_datac_trace(HCDT d) { long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(); const mglDataC *dc = dynamic_cast<const mglDataC *>(d); mglDataC *r=new mglDataC(nx); if(dc) { if(ny>=nx && nz>=nx) #pragma omp parallel for for(long i=0;i<nx;i++) r->a[i] = dc->a[i+nx*(i+ny*i)]; else if(ny>=nx) #pragma omp parallel for for(long i=0;i<nx;i++) r->a[i] = dc->a[i+nx*i]; else #pragma omp parallel for for(long i=0;i<nx;i++) r->a[i] = dc->a[i]; } else if(ny>=nx && nz>=nx) #pragma omp parallel for for(long i=0;i<nx;i++) r->a[i] = d->v(i,i,i); else if(ny>=nx) #pragma omp parallel for for(long i=0;i<nx;i++) r->a[i] = d->v(i,i); else #pragma omp parallel for for(long i=0;i<nx;i++) r->a[i] = d->v(i); return r; }
//----------------------------------------------------------------------------- HMDT MGL_EXPORT mgl_datac_arg(HCDT d) { long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(); mglData *r=new mglData(nx,ny,nz); const mglDataC *dd = dynamic_cast<const mglDataC*>(d); if(dd) #pragma omp parallel for for(long i=0;i<nx*ny*nz;i++) r->a[i] = arg(dd->a[i]); return r; }
//----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_set(HADT d, HCDT a) { if(!a) return; const mglDataC *dd = dynamic_cast<const mglDataC *>(a); // faster for mglData mgl_datac_create(d, a->GetNx(), a->GetNy(), a->GetNz()); if(dd) // this one should be much faster memcpy(d->a, dd->a, d->nx*d->ny*d->nz*sizeof(dual)); else // very inefficient!!! { register long i,j,k; for(k=0;k<d->nz;k++) for(j=0;j<d->ny;j++) for(i=0;i<d->nx;i++) d->a[i+d->nx*(j+d->ny*k)] = a->v(i,j,k); } }
HMDT MGL_EXPORT mgl_data_flame_2d(HCDT A, HCDT F, long n, long skip) { if(!A || A->GetNx()<7 || n<1) return 0; // incompatible dimensions if(!F || F->GetNx()<2 || F->GetNz()!=A->GetNy()) return 0; // incompatible dimensions mreal amax=0; for(long i=0; i<A->GetNy(); i++) amax += A->v(6,i); if(amax<=0) return 0; mglData *f = new mglData(3,n); mreal x = 0, y = 0; for(long i=0; i<skip; i++) mgl_flame_2d_point(A, F, x, y,amax); for(long i=0; i<n; i++) { f->a[3*i+2] = mgl_flame_2d_point(A, F, x, y, amax); // TODO color information ?!! f->a[3*i] = x; f->a[3*i+1] = y; } return f; }
//----------------------------------------------------------------------------- HCDT static fill_slice_z(HMGL gr, double sv, HCDT a, mglDataV &xx, mglDataV &yy, mglDataV &zz, mglData &aa) { long n=a->GetNx(),m=a->GetNy(),l=a->GetNz(); xx.Create(n,m); yy.Create(n,m); zz.Create(n,m); if(l>1) { aa.Create(n,m); mreal d = (l-1)*(sv - gr->Min.z)/(gr->Max.z - gr->Min.z); long k = long(d); d = d - k; if(k>l-2) { k=l-2; d=1; } if(k<0) { k=0; d=0; } #pragma omp parallel for collapse(2) for(long j=0;j<m;j++) for(long i=0;i<n;i++) aa.a[i+n*j] = a->v(i,j,k)*(1-d) + d*a->v(i,j,k+1); a = &aa; } zz.Fill(sv, sv); yy.Fill(gr->Min.y, gr->Max.y,'y'); xx.Fill(gr->Min.x, gr->Max.x,'x'); return a; }
//----------------------------------------------------------------------------- HCDT static fill_slice_x(HMGL gr, double sv, HCDT a, mglDataV &xx, mglDataV &yy, mglDataV &zz, mglData &aa) { long n=a->GetNx(),m=a->GetNy(),l=a->GetNz(); if(l>1) { aa.Create(m,l); xx.Create(m,l); yy.Create(m,l); zz.Create(m,l); mreal d = (n-1)*(sv - gr->Min.x)/(gr->Max.x - gr->Min.x); long k = long(d); d = d - k; if(k>n-2) { k=n-2; d=1; } if(k<0) { k=0; d=0; } #pragma omp parallel for collapse(2) for(long j=0;j<l;j++) for(long i=0;i<m;i++) aa.a[i+m*j] = a->v(k,i,j)*(1-d) + d*a->v(k+1,i,j); a = &aa; } else { xx.Create(n,m); yy.Create(n,m); zz.Create(n,m); } xx.Fill(sv, sv); yy.Fill(gr->Min.y, gr->Max.y,'x'); zz.Fill(gr->Min.z, gr->Max.z,'y'); return a; }
//----------------------------------------------------------------------------- HADT MGL_EXPORT mgl_datac_subdata(HCDT d, long xx,long yy,long zz) { long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(), n=1,m=1,l=1; int dx=0,dy=0,dz=0; if(xx<0) { xx=0; dx=1; n=nx; } if(yy<0) { yy=0; dy=1; m=ny; } if(zz<0) { zz=0; dz=1; l=nz; } const mglDataC *dd = dynamic_cast<const mglDataC *>(d); mglDataC *r=new mglDataC(n,m,l); if(xx>=nx || yy>=ny || zz>=nz) #pragma omp parallel for for(long i=0;i<n*m*l;i++) r->a[i] = NAN; else if(dd) #pragma omp parallel for collapse(3) for(long k=0;k<l;k++) for(long j=0;j<m;j++) for(long i=0;i<n;i++) r->a[i+n*(j+m*k)] = dd->a[xx+dx*i + nx*(yy+dy*j + ny*(zz+dz*k))]; else #pragma omp parallel for collapse(3) for(long k=0;k<l;k++) for(long j=0;j<m;j++) for(long i=0;i<n;i++) r->a[i+n*(j+m*k)] = d->v(xx+dx*i, yy+dy*j, zz+dz*k); if(m==1) { r->ny=r->nz; r->nz=1; }// "squeeze" dimensions if(n==1) { r->nx=r->ny; r->ny=r->nz; r->nz=1; r->NewId();} return r; }
//----------------------------------------------------------------------------- HADT MGL_EXPORT mgl_datac_subdata_ext(HCDT d, HCDT xx, HCDT yy, HCDT zz) { if(!xx || !yy || !zz) { mglData tmp; tmp.a[0]=-1; return mgl_datac_subdata_ext(d,xx?xx:&tmp,yy?yy:&tmp,zz?zz:&tmp); } long n=0,m=0,l=0,j,k; bool ix=false, iy=false, iz=false; if(xx->GetNz()>1) // 3d data { n = xx->GetNx(); m = xx->GetNy(); l = xx->GetNz(); j = yy->GetNN(); if(j>1 && j!=n*m*l) return 0; // wrong sizes k = zz->GetNN(); if(k>1 && k!=n*m*l) return 0; // wrong sizes ix = true; iy = j>1; iz = k>1; } else if(yy->GetNz()>1) { n = yy->GetNx(); m = yy->GetNy(); l = yy->GetNz(); j = xx->GetNN(); if(j>1 && j!=n*m*l) return 0; // wrong sizes k = zz->GetNN(); if(k>1 && k!=n*m*l) return 0; // wrong sizes iy = true; ix = j>1; iz = k>1; } else if(zz->GetNz()>1) { n = zz->GetNx(); m = zz->GetNy(); l = zz->GetNz(); j = yy->GetNN(); if(j>1 && j!=n*m*l) return 0; // wrong sizes k = xx->GetNN(); if(k>1 && k!=n*m*l) return 0; // wrong sizes iz = true; iy = j>1; ix = k>1; } else if(xx->GetNy()>1) // 2d data { n = xx->GetNx(); m = xx->GetNy(); l = 1; j = yy->GetNx()*yy->GetNy(); if(j>1 && j!=n*m) return 0; // wrong sizes k = zz->GetNx()*zz->GetNy(); if(k>1 && k!=n*m) return 0; // wrong sizes ix = true; iy = j>1; iz = k>1; } else if(yy->GetNy()>1) { n = yy->GetNx(); m = yy->GetNy(); l = 1; j = xx->GetNx()*xx->GetNy(); if(j>1 && j!=n*m) return 0; // wrong sizes k = zz->GetNx()*zz->GetNy(); if(k>1 && k!=n*m) return 0; // wrong sizes iy = true; ix = j>1; iz = k>1; } else if(zz->GetNy()>1) { n = zz->GetNx(); m = zz->GetNy(); l = 1; j = yy->GetNx()*yy->GetNy(); if(j>1 && j!=n*m) return 0; // wrong sizes k = xx->GetNx()*xx->GetNy(); if(k>1 && k!=n*m) return 0; // wrong sizes iz = true; iy = j>1; ix = k>1; } long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(); long vx=long(xx->v(0)), vy=long(yy->v(0)), vz=long(zz->v(0)); const mglDataC *dd = dynamic_cast<const mglDataC *>(d); if(n*m*l>1) // this is 2d or 3d data { mglDataV tx(n,m,l),ty(n,m,l),tz(n,m,l); if(!ix) { xx = &tx; if(vx>=0) tx.Fill(vx); else tx.All(); } if(!iy) { yy = &ty; if(vy>=0) ty.Fill(vy); else ty.All(); } if(!iz) { zz = &tz; if(vz>=0) tz.Fill(vz); else tz.All(); } mglDataC *r=new mglDataC(n,m,l); if(dd) #pragma omp parallel for for(long i0=0;i0<n*m*l;i0++) { register long x=long(0.5+xx->vthr(i0)), y=long(0.5+yy->vthr(i0)), z=long(0.5+zz->vthr(i0)); r->a[i0] = (x>=0 && x<nx && y>=0 && y<ny && z>=0 && z<nz)?dd->a[x+nx*(y+ny*z)]:NAN; } else #pragma omp parallel for for(long i0=0;i0<n*m*l;i0++) { register long x=long(0.5+xx->vthr(i0)), y=long(0.5+yy->vthr(i0)), z=long(0.5+zz->vthr(i0)); r->a[i0] = (x>=0 && x<nx && y>=0 && y<ny && z>=0 && z<nz)?d->v(x,y,z):NAN; } return r; } // this is 1d data -> try as normal SubData() mglDataV tx(nx),ty(ny),tz(nz); tx.Fill(0,nx-1); ty.Fill(0,ny-1); tz.Fill(0,nz-1); if(xx->GetNx()>1 || vx>=0) n=xx->GetNx(); else { n=nx; xx = &tx; } if(yy->GetNx()>1 || vy>=0) m=yy->GetNx(); else { m=ny; yy = &ty; } if(zz->GetNx()>1 || vz>=0) l=zz->GetNx(); else { l=nz; zz = &tz; } mglDataC *r=new mglDataC(n,m,l); if(dd) #pragma omp parallel for collapse(3) for(long k=0;k<l;k++) for(long j=0;j<m;j++) for(long i=0;i<n;i++) { register long x=long(0.5+xx->v(i)), y=long(0.5+yy->v(j)), z=long(0.5+zz->v(k)); r->a[i+n*(j+m*k)] = (x>=0 && x<nx && y>=0 && y<ny && z>=0 && z<nz)?dd->a[x+nx*(y+ny*z)]:NAN; } else #pragma omp parallel for collapse(3) for(long k=0;k<l;k++) for(long j=0;j<m;j++) for(long i=0;i<n;i++) { register long x=long(0.5+xx->v(i)), y=long(0.5+yy->v(j)), z=long(0.5+zz->v(k)); r->a[i+n*(j+m*k)] = (x>=0 && x<nx && y>=0 && y<ny && z>=0 && z<nz)?d->v(x,y,z):NAN; } if(m==1) { r->ny=r->nz; r->nz=1; }// "squeeze" dimensions if(n==1) { r->nx=r->ny; r->ny=r->nz; r->nz=1; r->NewId();} return r; }
//----------------------------------------------------------------------------- HADT MGL_EXPORT mgl_datac_momentum(HCDT dat, char dir, const char *how) { if(!how || !(*how) || !strchr("xyz",dir)) return 0; long nx=dat->GetNx(),ny=dat->GetNy(),nz=dat->GetNz(); mglDataV x(nx,ny,nz, 0,1,'x'); x.s=L"x"; mglDataV y(nx,ny,nz, 0,1,'y'); y.s=L"y"; mglDataV z(nx,ny,nz, 0,1,'z'); z.s=L"z"; mglDataC u(dat); u.s=L"u"; // NOTE slow !!! std::vector<mglDataA*> list; list.push_back(&x); list.push_back(&y); list.push_back(&z); list.push_back(&u); mglDataC res=mglFormulaCalcC(how,list); mglDataC *b=0; if(dir=='x') { b=new mglDataC(nx); #pragma omp parallel for for(long i=0;i<nx;i++) { register dual i1=0,i0=0; for(long j=0;j<ny*nz;j++) { register dual u=dat->vthr(i+nx*j); i0 += u; i1 += u*res.a[i+nx*j]; } b->a[i] = i0!=mreal(0) ? i1/i0 : 0; } } if(dir=='y') { b=new mglDataC(ny); #pragma omp parallel for for(long i=0;i<ny;i++) { register dual i1=0,i0=0; for(long k=0;k<nz;k++) for(long j=0;j<nx;j++) { register dual u=dat->v(j,i,k); i0 += u; i1 += u*res.a[j+nx*(i+ny*k)]; } b->a[i] = i0!=mreal(0) ? i1/i0 : 0; } } if(dir=='z') { long nn=nx*ny; b=new mglDataC(nz); #pragma omp parallel for for(long i=0;i<nz;i++) { register dual i1=0,i0=0; for(long j=0;j<nn;j++) { register dual u=dat->vthr(j+nn*i); i0 += u; i1 += u*res.a[j+nn*i]; } b->a[i] = i0!=mreal(0) ? i1/i0 : 0; } } return b; }