//----------------------------------------------------------------------------- dual MGL_LOCAL_CONST mgl_ipowc_c(dual x,int n) { dual t; if(n==2) t = x*x; else if(n==1) t = x; else if(n<0) t = mreal(1)/mgl_ipowc_c(x,-n); else if(n==0) t = mreal(1); else { t = mgl_ipowc_c(x,n/2); t = t*t; if(n%2==1) t *= x; } return t; }
//----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_squeeze(HADT d, long rx,long ry,long rz,long smooth) { long kx,ky,kz, nx=d->nx, ny=d->ny, nz=d->nz; dual *b; // simple checking if(rx>=nx) rx=nx-1; if(rx<1) rx=1; if(ry>=ny) ry=ny-1; if(ry<1) ry=1; if(rz>=nz) rz=nz-1; if(rz<1) rz=1; // new sizes kx = 1+(nx-1)/rx; ky = 1+(ny-1)/ry; kz = 1+(nz-1)/rz; b = new dual[kx*ky*kz]; if(!smooth) #pragma omp parallel for collapse(3) for(long k=0;k<kz;k++) for(long j=0;j<ky;j++) for(long i=0;i<kx;i++) b[i+kx*(j+ky*k)] = d->a[i*rx+nx*(j*ry+ny*rz*k)]; else #pragma omp parallel for collapse(3) for(long k=0;k<kz;k++) for(long j=0;j<ky;j++) for(long i=0;i<kx;i++) { long dx,dy,dz,i1,j1,k1; dx = (i+1)*rx<=nx ? rx : nx-i*rx; dy = (j+1)*ry<=ny ? ry : ny-j*ry; dz = (k+1)*rz<=nz ? rz : nz-k*rz; dual s = 0; for(k1=k*rz;k1<k*rz+dz;k1++) for(j1=j*ry;j1<j*ry+dz;j1++) for(i1=i*rx;i1<i*rx+dx;i1++) s += d->a[i1+nx*(j1+ny*k1)]; b[i+kx*(j+ky*k)] = s/mreal(dx*dy*dz); } if(!d->link) delete [](d->a); d->a=b; d->nx = kx; d->ny = ky; d->nz = kz; d->NewId(); d->link=false; }
//----------------------------------------------------------------------------- void MGL_EXPORT mgl_tricontv_xyzc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt) { mreal r = gr->SaveState(opt); long n = (mgl_isnan(r) || r<=0) ? 7:long(r+0.5); mglData v(n); for(long i=0;i<n;i++) v.a[i] = gr->Min.c + (gr->Max.c-gr->Min.c)*mreal(i+1)/(n+1); mgl_tricontv_xyzcv(gr,&v,nums,x,y,z,a,sch,0); }
//----------------------------------------------------------------------------- void MGL_EXPORT mgl_cont_z(HMGL gr, HCDT a, const char *sch, double sv, const char *opt) { mreal r = gr->SaveState(opt); long Num = (mgl_isnan(r) || r<=0) ? 7:long(r+0.5); mglData v(Num); for(long i=0;i<Num;i++) v.a[i] = gr->Min.c + (gr->Max.c-gr->Min.c)*mreal(i+1)/(Num+1); mgl_cont_z_val(gr,&v,a,sch,sv,0); }
//----------------------------------------------------------------------------- MGL_NO_EXPORT void *mgl_cfill_x(void *par) { mglThreadC *t=(mglThreadC *)par; long nx=t->p[0],ny=t->p[1]; dual *b=t->a, x1=t->b[0], dx=t->b[1]; char dir = t->s[0]; #if !MGL_HAVE_PTHREAD #pragma omp parallel for #endif for(long i0=t->id;i0<t->n;i0+=mglNumThr) { if(dir=='x') b[i0] = x1+dx*mreal(i0%nx); else if(dir=='y') b[i0] = x1+dx*mreal((i0/nx)%ny); else if(dir=='z') b[i0] = x1+dx*mreal(i0/(nx*ny)); } return 0; }
dual MGL_LOCAL_CONST acosc(dual x) { return log(x+sqrt(x*x-mreal(1)))/ic; }
dual MGL_LOCAL_CONST atanc(dual x) { return log((ic-x)/(ic+x))/(mreal(2)*ic); }
dual MGL_LOCAL_CONST asinc(dual x) { return log(ic*x+sqrt(mreal(1)-x*x))/ic; }
dual MGL_LOCAL_CONST atanhc(dual x) { return log((mreal(1)+x)/(mreal(1)-x))/mreal(2); }
dual MGL_LOCAL_CONST asinhc(dual x) { return log(x+sqrt(x*x+mreal(1))); }
//----------------------------------------------------------------------------- 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; }
void MGL_EXPORT mgl_rk_step_w(HMPR pr, const wchar_t *Eqs, const wchar_t *Vars, mreal dt) { const std::wstring eqs(Eqs); const std::wstring vars(Vars); std::vector<mglRKdat> rkv; size_t iv=0,jv=0,ie=0,je=0; while(1) { iv = vars.find(';',jv); ie = eqs.find(';',je); mglDataA *vv=mgl_parser_find_varw(pr,vars.substr(jv,iv-jv).c_str()); std::wstring eq = eqs.substr(je,ie-je).c_str(); if(vv) rkv.push_back(mglRKdat(vv, eq )); jv = iv+1; je = ie+1; if(iv==std::wstring::npos || ie==std::wstring::npos) break; } for(size_t i=0;i<rkv.size();i++) rkv[i].allocate(); mreal hh = dt/2; for(size_t i=0;i<rkv.size();i++) { mglRKdat &rk = rkv[i]; if(rk.cmplx) rk.c1.Move(mglFormulaCalcC(rk.e, pr, pr->DataList)); else rk.d1.Move(mglFormulaCalc(rk.e, pr, pr->DataList)); } for(size_t i=0;i<rkv.size();i++) { mglRKdat &rk = rkv[i]; if(rk.cc) { long n = rk.cc->GetNN(); dual a = hh*rk.c1.a[0]; if(rk.c1.GetNN()==n) #pragma omp parallel for for(long j=0;j<n;j++) rk.cc->a[j] = rk.cin.a[j] + hh*rk.c1.a[j]; else #pragma omp parallel for for(long j=0;j<n;j++) rk.cc->a[j] = rk.cin.a[j] + a; } if(rk.dd) { long n = rk.dd->GetNN(); mreal a = hh*rk.d1.a[0]; if(rk.d1.GetNN()==n) #pragma omp parallel for for(long j=0;j<n;j++) rk.dd->a[j] = rk.din.a[j] + hh*rk.d1.a[j]; else #pragma omp parallel for for(long j=0;j<n;j++) rk.dd->a[j] = rk.din.a[j] + a; } } for(size_t i=0;i<rkv.size();i++) { mglRKdat &rk = rkv[i]; if(rk.cmplx) rk.c2.Move(mglFormulaCalcC(rk.e, pr, pr->DataList)); else rk.d2.Move(mglFormulaCalc(rk.e, pr, pr->DataList)); } for(size_t i=0;i<rkv.size();i++) { mglRKdat &rk = rkv[i]; if(rk.cc) { long n = rk.cc->GetNN(); dual a = hh*rk.c2.a[0]; if(rk.c2.GetNN()==n) #pragma omp parallel for for(long j=0;j<n;j++) rk.cc->a[j] = rk.cin.a[j] + hh*rk.c2.a[j]; else #pragma omp parallel for for(long j=0;j<n;j++) rk.cc->a[j] = rk.cin.a[j] + a; } if(rk.dd) { long n = rk.dd->GetNN(); mreal a = hh*rk.d2.a[0]; if(rk.d2.GetNN()==n) #pragma omp parallel for for(long j=0;j<n;j++) rk.dd->a[j] = rk.din.a[j] + hh*rk.d2.a[j]; else #pragma omp parallel for for(long j=0;j<n;j++) rk.dd->a[j] = rk.din.a[j] + a; } } for(size_t i=0;i<rkv.size();i++) { mglRKdat &rk = rkv[i]; if(rk.cmplx) rk.c3.Move(mglFormulaCalcC(rk.e, pr, pr->DataList)); else rk.d3.Move(mglFormulaCalc(rk.e, pr, pr->DataList)); } for(size_t i=0;i<rkv.size();i++) { mglRKdat &rk = rkv[i]; if(rk.cc) { long n = rk.cc->GetNN(); dual a = dt*rk.c3.a[0]; if(rk.c3.GetNN()==n) #pragma omp parallel for for(long j=0;j<n;j++) rk.cc->a[j] = rk.cin.a[j] + dt*rk.c3.a[j]; else #pragma omp parallel for for(long j=0;j<n;j++) rk.cc->a[j] = rk.cin.a[j] + a; } if(rk.dd) { long n = rk.dd->GetNN(); mreal a = dt*rk.d3.a[0]; if(rk.d3.GetNN()==n) #pragma omp parallel for for(long j=0;j<n;j++) rk.dd->a[j] = rk.din.a[j] + dt*rk.d3.a[j]; else #pragma omp parallel for for(long j=0;j<n;j++) rk.dd->a[j] = rk.din.a[j] + a; } } for(size_t i=0;i<rkv.size();i++) { mglRKdat &rk = rkv[i]; if(rk.cmplx) rk.c4.Move(mglFormulaCalcC(rk.e, pr, pr->DataList)); else rk.d4.Move(mglFormulaCalc(rk.e, pr, pr->DataList)); } for(size_t i=0;i<rkv.size();i++) { mglRKdat &rk = rkv[i]; if(rk.cc) { long n = rk.cc->GetNN(); dual a = (rk.c1.a[0]+rk.c2.a[0]+mreal(2)*(rk.c3.a[0]+rk.c4.a[0]))*(dt/6); if(rk.c1.GetNN()==n) #pragma omp parallel for for(long j=0;j<n;j++) rk.cc->a[j] = rk.cin.a[j] + (rk.c1.a[j]+rk.c2.a[j]+mreal(2)*(rk.c3.a[j]+rk.c4.a[j]))*(dt/6); else #pragma omp parallel for for(long j=0;j<n;j++) rk.cc->a[j] = rk.cin.a[j] + a; } if(rk.dd) { long n = rk.dd->GetNN(); mreal a = (rk.d1.a[0]+rk.d2.a[0]+2*(rk.d3.a[0]+rk.d4.a[0]))*(dt/6); if(rk.d1.GetNN()==n) #pragma omp parallel for for(long j=0;j<n;j++) rk.dd->a[j] = rk.din.a[j] + (rk.d1.a[j]+rk.d2.a[j]+2*(rk.d3.a[j]+rk.d4.a[j]))*(dt/6); else #pragma omp parallel for for(long j=0;j<n;j++) rk.dd->a[j] = rk.din.a[j] + a; } } }