void DiracAntiSpinor::SetP4(const Vector4<double> &__p4, const double &__mass){ Matrix <complex<double> > sigP(2,2); Matrix <complex<double> > chi(2,1); PauliSigma sigma; _p4 = __p4; _mass = __mass; complex<double> norm = sqrt(__p4.E() + __mass); complex<double> epm = __p4.E() + __mass; sigP = sigma[1]*__p4.X() + sigma[2]*__p4.Y() + sigma[3]*__p4.Z(); // spin up chi(0,0) = 0.; chi(1,0) = 1.; _spinors[1](2,0) = chi(0,0)*norm; _spinors[1](3,0) = chi(1,0)*norm; _spinors[1](0,0) = ((sigP*chi)(0,0))*norm/epm; _spinors[1](1,0) = ((sigP*chi)(1,0))*norm/epm; // spin down chi(0,0) = 1.; chi(1,0) = 0.; _spinors[0](2,0) = chi(0,0)*norm; _spinors[0](3,0) = chi(1,0)*norm; _spinors[0](0,0) = ((sigP*chi)(0,0))*norm/epm; _spinors[0](1,0) = ((sigP*chi)(1,0))*norm/epm; this->_SetProjector(); }
int makeProbe( cfpix &cpix, int nx, int ny, double xp, double yp, float p[], double wavlen, double k2max, double pixel, int multiMode, int ismoth ) { int ix, iy, npixels; double alx, aly, k2, chi0, pi, dx2p, dy2p; /* PIXEL = diagonal width of pixel squared if a pixel is on the aperture boundary give it a weight of 1/2 otherwise 1 or 0 */ npixels = 0; pi = 4.0 * atan( 1.0 ); dx2p = 2.0*pi*xp; dy2p = 2.0*pi*yp; for( iy=0; iy<ny; iy++) { aly = wavlen * ky[iy]; /* y component of angle alpha */ for( ix=0; ix<nx; ix++) { k2 = kx2[ix] + ky2[iy]; alx = wavlen * kx[ix]; /* x component of angle alpha */ if ( ( ismoth != 0) && ( fabs(k2-k2max) <= pixel) ) { chi0 = (2.0*pi/wavlen) * chi( p, alx, aly, multiMode ) - ( (dx2p*kx[ix]) + (dy2p*ky[iy]) ); cpix.re(ix,iy) = (float) ( 0.5 * cos(chi0)); /* real */ cpix.im(ix,iy) = (float) (-0.5 * sin(chi0)); /* imag */ /* printf("smooth by 0.5 at ix=%d, iy=%d\n", ix, iy ); */ } else if ( k2 <= k2max ) { chi0 = (2.0*pi/wavlen) * chi( p, alx, aly, multiMode ) - ( (dx2p*kx[ix]) + (dy2p*ky[iy]) ); cpix.re(ix,iy) = (float) cos(chi0); /* real */ cpix.im(ix,iy) = (float) -sin(chi0); /* imag */ npixels++; } else { cpix.re(ix,iy) = cpix.im(ix,iy) = 0.0F; } } /* end for( ix=0... ) */ } /* end for( iy=0... ) */ cpix.ifft(); // inverse transform back to real space return( npixels ); } /* end makeProbe() */
void LLSideTrayListener::getTabs(const LLSD& event) const { LLSD reply; LLSideTray* tray = mGetter(); LLSD::Integer ord(0); for (LLSideTray::child_list_const_iter_t chi(tray->beginChild()), chend(tray->endChild()); chi != chend; ++chi, ++ord) { LLView* child = *chi; // How much info is important? Toss in as much as seems reasonable for // each tab. But to me, at least for the moment, the most important // item is the tab name. LLSD info; // I like the idea of returning a map keyed by tab name. But as // compared to an array of maps, that loses sequence information. // Address that by indicating the original order in each map entry. info["ord"] = ord; info["visible"] = bool(child->getVisible()); info["enabled"] = bool(child->getEnabled()); info["available"] = child->isAvailable(); reply[child->getName()] = info; } sendReply(reply, event); }
//evaluates add_i polynomial for layer 59+d of the F0 circuit void FLT_add_lvl2(mpz_t rop, const mpz_t* r, int mi, int mip1, int ni, int nip1, const mpz_t prime) { mpz_t tmp, ans; mpz_init(tmp); mpz_init(ans); //even ps go to nip1-1 for in1 and p/2 for both in2 one_sub(ans, r[0]); /* uint64 ans1 = 1+PRIME-r[0]; uint64 temp; */ //now make sure p>>1 matches in2 check_equal(ans, &r[1], &r[mi+mip1], 0, mip1, prime); //make sure in1 matches nip1-1 chi(tmp, nip1-1, r+mi, mip1, prime); modmult(rop, tmp, ans, prime); /* ans1 = myModMult(ans1, chi(nip1-1, r+mi, mip1)); return ans1; */ mpz_clear(tmp); mpz_clear(ans); }
// evaluate v(xi,eta) on reference element using local node numbering double eval(const double v[3], double xi, double eta) { double sum = 0.0; int L; for (L = 0; L < 3; L++) sum += v[L] * chi(L,xi,eta); return sum; }
double C_gi_photoz(double l, double zm, double DZ, double zphot){ double RES,res,k,fK,D_a,GIz,hoverh0,z,a,norm,dz; double array[3] = {l,zphot,zm}; dz = 0.02; RES = 0; norm = 0.; for (z = zm-DZ/2.0+dz/2.0; z< zm+DZ/2.0; z +=dz){ norm +=pow(zdistr(z),2.0)*dz; array[2] = z; a = 1./(1+z); if (zphot<0.5){ fK = f_K(chi(a)); k = array[0]/fK; D_a=growfac(a,1.,1.)/growfac(1.,1.,1.); hoverh0 = sqrt(cosmology.Omega_m /(a*a*a) + (1.-cosmology.Omega_m -cosmology.Omega_v )/(a*a) + omv_vareos(a) ); res= a*a*hoverh0/fK/fK; res = res*0.0134*cosmology.Omega_m/D_a*P_delta(a, k)*pow(zdistr(z),2.0); } else{res = int_GSL_integrate_qag2(int_for_C_gi_photoz,(void*)array,0.35,0.999,NULL,1000)*pow(zdistr(z),2.0);} RES += res*dz; } return cosmology.bias*RES/(norm*norm*10.0); }
void KeccakPermutationOnWords(UINT64 *state) { unsigned int i; //displayStateAsWords(3, "Same, as words", state); for(i=0; i<nrRounds; i++) { //displayRoundNumber(3, i); theta(state); //displayStateAsWords(3, "After theta", state); rho(state); //displayStateAsWords(3, "After rho", state); pi(state); //displayStateAsWords(3, "After pi", state); chi(state); //displayStateAsWords(3, "After chi", state); iota(state, i); //displayStateAsWords(3, "After iota", state); } }
void keccak_coproc(UINT64 *A) { unsigned int i; for(i=0;i<nrRounds;i++) { theta(A); rho(A); pi(A); chi(A); iota(A,i); } }
LLSD LLCommandDispatcher::enumerate() { LLSD response; LLCommandHandlerRegistry& registry(LLCommandHandlerRegistry::instance()); for (std::map<std::string, LLCommandHandlerInfo>::const_iterator chi(registry.mMap.begin()), chend(registry.mMap.end()); chi != chend; ++chi) { LLSD info; info["untrusted"] = chi->second.mUntrustedBrowserAccess; info["untrusted_str"] = lookup(chi->second.mUntrustedBrowserAccess); response[chi->first] = info; } return response; }
double int_for_C_gi_photoz (double a, void *params){ double res,k,fK,D_a,GIz,hoverh0; double *array = (double*)params; fK = f_K(chi(a)); k = array[0]/fK; D_a=growfac(a,1.,1.)/growfac(1.,1.,1.); hoverh0 = sqrt(cosmology.Omega_m /(a*a*a) + (1.-cosmology.Omega_m -cosmology.Omega_v )/(a*a) + omv_vareos(a) ); res= a*a*hoverh0/fK/fK; res = res*0.0134*cosmology.Omega_m/D_a*P_delta(a, k); if (array[1] > 0.5){res = res*pow(p_zspec(1./a-1.,array[3])/(a*a),2.0);} return res; }
void MainHandler::release() { //printf("MainHandler::release()\n"); QDictIterator<CompoundHandler> chi(m_compoundsLoaded); CompoundHandler *ch; for (chi.toFirst();(ch=chi.current());++chi) { debug(1,"Compound %s not released\n",ch->name()->latin1()); } graphhandler_exit(); dochandler_exit(); memberhandler_exit(); sectionhandler_exit(); compoundhandler_exit(); delete this; }
Ts do_eval(const Tp& p) { Ts result(0); for(int i=(this->get_data_set()).size()-1;i>=0;--i) { Ty chi(this->get_data_set().get_data(0).get_y().size()); for(int j=0;j<chi.size();++j) { Ty model_y(this->eval_model(this->get_data_set().get_data(i).get_x(),p)); if(model_y[j]>this->get_data_set().get_data(i).get_y()[j]) { chi[j]=(this->get_data_set().get_data(i).get_y()[j]-model_y[j])/this->get_data_set().get_data(i).get_y_upper_err()[j]; } else { chi[j]=(this->get_data_set().get_data(i).get_y()[j]-model_y[j])/this->get_data_set().get_data(i).get_y_lower_err()[j]; } } result+=sum(chi*chi); } return result; }
double stellar_evo::dmsegdt(){ //Equation (?) AGLB2013 double dmsegdt = 0; dmsegdt += chi()*mynode->MS/mynode->t_rhp; return dmsegdt; }
int main() { char filein[NCMAX], fileout[NCMAX], filestart[NCMAX], filebeam[NCMAX], description[NCMAX], filecross[NCMAX], cline[NCMAX]; const char version[] = "21-nov-2012 (ejk)"; int lstart=0, lpartl=0, lbeams=0, lwobble=0, lcross=0, nwobble=1; int ix, iy, iz, nx, ny, nz, nzout, ixmid, iymid, i, nslic0, islice, nacx,nacy, iqx, iqy, iwobble, ndf, idf, nbout, ib, ncellx, ncelly, ncellz, iycross, ns, NPARAM; int *hbeam, *kbeam; int natom, *Znum, *Znum2, istart, na, done, status, multiMode; long nbeams, nillum; long ltime; unsigned long iseed; long32 nxl, nyl; /* tiffsubs 32 bit integer type */ float *x, *y, *z, *occ, *wobble; float *x2, *y2, *z2, *occ2; float wmin, wmax, xmin,xmax, ymin, ymax, zmin, zmax; float *kx, *ky, *xpos, *ypos, *param, *sparam; float k2, k2max, scale, v0, mm0, wavlen, rx, ry, ax, by, cz, pi, rmin, rmax, aimin, aimax, rx2,ry2, ctiltx, ctilty, tctx, tcty, acmin, acmax, Cs3, Cs5, df, df0, sigmaf, dfdelt, aobj, qx, qy, qy2, q2, q2min, q2max, sumdf, pdf, k2maxo, temperature, ycross, dx, dy; float tr, ti, wr, wi; float **wave0r, **wave0i, **pix, **depthpix, *propxr, *propxi, *propyr, *propyi; cfpix wave; /* complex probe wave functions */ cfpix trans; /* complex transmission functions */ cfpix temp ; /* complex scratch wavefunction */ double sum, timer, xdf, chi0, chi1, chi2, chi3, t, zslice, deltaz, phirms, rsq, vz, alx, aly; FILE *fp1; floatTIFF myFile; /* echo version date and get input file name */ printf("autoslic(e) version dated %s\n", version); printf("Copyright (C) 1998-2012 Earl J. Kirkland\n" ); printf( "This program is provided AS-IS with ABSOLUTELY NO WARRANTY\n " " under the GNU general public license\n\n" ); printf("perform CTEM multislice with automatic slicing and FFTW\n"); #ifdef USE_OPENMP printf( "and multithreaded using openMP\n"); #endif printf( "\n" ); pi = (float) (4.0 * atan( 1.0 )); NPARAM = myFile.maxParam(); param = (float*) malloc1D( NPARAM, sizeof(float), "param" ); sparam = (float*) malloc1D( NPARAM, sizeof(float), "sparam" ); for( ix=0; ix<NPARAM; ix++ ) param[ix] = 0.0F; printf("Name of file with input atomic " "potential in x,y,z format:\n"); ns = scanf("%s", filein ); /* get simulation options */ printf("Replicate unit cell by NCELLX,NCELLY,NCELLZ :\n"); ns = scanf("%d %d %d", &ncellx, &ncelly, &ncellz); if( ncellx < 1 ) ncellx = 1; if( ncelly < 1 ) ncelly = 1; if( ncellz < 1 ) ncellz = 1; printf("Name of file to get binary output of multislice result:\n"); ns = scanf("%s", fileout ); lpartl = askYN("Do you want to include partial coherence"); if( lpartl == 1 ) { printf("Illumination angle min, max in mrad:\n"); ns = scanf("%f %f", &acmin, &acmax); acmin = acmin * 0.001F; acmax = acmax * 0.001F; printf("Spherical aberration Cs3, Cs5(in mm.):\n"); ns = scanf("%g %g", &Cs3, &Cs5); param[pCS] = (float) ( Cs3*1.0e7 ); param[pCS5] = (float) ( Cs5*1.0e7 ); printf("Defocus, mean, standard deviation, and" " sampling size (in Angstroms) =\n"); ns = scanf("%f %f %f", &df0, &sigmaf, &dfdelt); param[pDEFOCUS] = (float) df0; printf("Objective aperture (in mrad) =\n"); ns = scanf("%f", &aobj); aobj = aobj * 0.001F; #ifdef MANY_ABERR /* get higher order aberrations if necessary */ printf("type higher order aber. name (as C32a, etc.) followed\n" " by a value in mm. (END to end)\n"); done = multiMode = 0; do{ ns = scanf( "%20s", cline ); if( strstr( cline, "END" ) != NULL ) { done = 1; } else { ns = scanf( "%lg", &vz ); status = readCnm( cline, param, vz ); if( status < 0 ) { printf( "unrecognized aberration, exit...\n"); exit( EXIT_SUCCESS ); } else multiMode = 1; } } while( !done ); #endif lstart = 0; } else { printf("NOTE, the program image must also be run.\n"); lstart = askYN("Do you want to start from previous result"); } if ( lstart == 1 ) { printf("Name of file to start from:\n"); ns = scanf("%s", filestart); } else { printf("Incident beam energy in kev:\n"); ns = scanf("%g", &v0); printf("Wavefunction size in pixels, Nx,Ny:\n"); ns = scanf("%d %d", &nx, &ny ); } printf("Crystal tilt x,y in mrad.:\n"); ns = scanf("%f %f", &ctiltx, &ctilty); ctiltx = ctiltx /1000; ctilty = ctilty /1000; /* remember that the slice thickness must be > atom size to use projected atomic potential */ printf("Slice thickness (in Angstroms):\n"); ns = scanf("%lf", &deltaz ); if( deltaz < 1.0 ) { printf("WARNING: this slice thickness is probably too thin" " for autoslice to work properly.\n"); } if( lpartl == 0 ) { lbeams = askYN("Do you want to record the (real,imag) value\n" " of selected beams vs. thickness"); if( lbeams == 1 ) { printf("Name of file for beams info:\n"); ns = scanf("%s", filebeam ); printf("Number of beams:\n"); ns = scanf("%d", &nbout); if( nbout<1 ) nbout = 1; hbeam = (int*) malloc1D( nbout, sizeof(int), "hbeam" ); kbeam = (int*) malloc1D( nbout, sizeof(int), "kbeam" ); for( ib=0; ib<nbout; ib++) { printf("Beam %d, h,k=\n", ib+1); ns = scanf("%d %d", &hbeam[ib], &kbeam[ib] ); } } } lwobble = askYN("Do you want to include thermal vibrations"); if( lwobble == 1 ) { printf( "Type the temperature in degrees K:\n"); ns = scanf( "%g", &temperature ); printf( "Type number of configurations to average over:\n"); ns = scanf( "%d", &nwobble ); if( nwobble < 1 ) nwobble = 1; /* get random number seed from time if available otherwise ask for a seed */ ltime = (long) time( NULL ); iseed = (unsigned) ltime; if( ltime == -1 ) { printf("Type initial seed for random number generator:\n"); ns = scanf("%ld", &iseed); } else printf( "Random number seed initialized to %ld\n", iseed ); } else temperature = 0.0F; if( lpartl == 0 ) { lcross = askYN("Do you want to output intensity vs. depth cross section"); if( lcross == 1 ){ printf( "Type name of file to get depth profile image:\n"); ns = scanf("%s", filecross ); printf( "Type y position of depth cross section (in Ang.):\n"); ns = scanf("%f", &ycross ); } } /* start timing the actual computation just for fun */ timer = cputim(); #ifdef USE_OPENMP walltimer = walltim(); /* wall time for opneMP */ #endif /* get starting value of transmitted wavefunction if required (this can only be used in coherent mode) remember to save params for final output pix */ if ( lstart == 1 ) { if( myFile.read( filestart ) != 1 ) { printf("Cannot open input file: %s .\n", filestart ); exit( 0 ); } if( myFile.getnpix() != 2 ) { printf("Input file %s must be complex, can't continue.\n", filestart ); exit( 0 ); } nx = myFile.nx(); ny = myFile.ny(); wave0r = (float**) malloc2D( nx, ny, sizeof(float), "waver" ); nx = nx/2; wave0i = wave0r + nx; // save starting pix for later for( ix=0; ix<nx; ix++) for( iy=0; iy<ny; iy++) { wave0r[ix][iy] = myFile(ix,iy); wave0i[ix][iy] = myFile(ix+nx,iy); } // save parameters to verify successive images are same size etc. for( i=0; i<NPARAM; i++) sparam[i] = myFile.getParam( i ); ax = sparam[pDX] * nx; by = sparam[pDY] * ny; v0 = sparam[pENERGY]; nslic0 = (int) sparam[pNSLICES]; printf("Starting pix range %g to %g real\n" " %g to %g imag\n", sparam[pRMIN], sparam[pRMAX], sparam[pIMIN], sparam[pIMAX] ); printf("Beam voltage = %g kV\n", v0); printf("Old crystal tilt x,y = %g, %g mrad\n", 1000.*sparam[pXCTILT], 1000.*sparam[pYCTILT]); } else nslic0 = 0; /* end if( lstart...) */ /* calculate relativistic factor and electron wavelength */ mm0 = 1.0F + v0/511.0F; wavlen = (float) wavelength( v0 ); printf("electron wavelength = %g Angstroms\n", wavlen); /* read in specimen coordinates and scattering factors */ natom = ReadXYZcoord( filein, ncellx, ncelly, ncellz, &ax, &by, &cz, &Znum, &x, &y, &z, &occ, &wobble, description, NCMAX ); printf("%d atomic coordinates read in\n", natom ); printf("%s", description ); printf("Size in pixels Nx, Ny= %d x %d = %d beams\n", nx,ny, nx*ny); printf("Lattice constant a,b = %12.4f, %12.4f\n", ax,by); /* calculate the total specimen volume and echo */ xmin = xmax = x[0]; ymin = ymax = y[0]; zmin = zmax = z[0]; wmin = wmax = wobble[0]; for( i=0; i<natom; i++) { if( x[i] < xmin ) xmin = x[i]; if( x[i] > xmax ) xmax = x[i]; if( y[i] < ymin ) ymin = y[i]; if( y[i] > ymax ) ymax = y[i]; if( z[i] < zmin ) zmin = z[i]; if( z[i] > zmax ) zmax = z[i]; if( wobble[i] < wmin ) wmin = wobble[i]; if( wobble[i] > wmax ) wmax = wobble[i]; } printf("Total specimen range is\n %g to %g in x\n" " %g to %g in y\n %g to %g in z\n", xmin, xmax, ymin, ymax, zmin, zmax ); if( lwobble == 1 ) printf("Range of thermal rms displacements (300K) = %g to %g\n", wmin, wmax ); #ifdef USE_OPENMP /* force LUT init. to avoid redundant init in parallel form */ rsq = 0.5; /* arbitrary position */ for( i=0; i<natom; i++) vz = vzatomLUT( Znum[i], rsq ); #endif /* calculate spatial frequencies and positions for future use */ rx = 1.0F/ax; rx2= rx*rx; ry = 1.0F/by; ry2= ry*ry; ixmid = nx/2; iymid = ny/2; nxl = nx; nyl = ny; kx = (float*) malloc1D( nx, sizeof(float), "kx" ); kx2 = (float*) malloc1D( nx, sizeof(float), "kx2" ); xpos = (float*) malloc1D( nx, sizeof(float), "xpos" ); freqn( kx, kx2, xpos, nx, ax ); ky = (float*) malloc1D( ny, sizeof(float), "ky" ); ky2 = (float*) malloc1D( ny, sizeof(float), "ky2" ); ypos = (float*) malloc1D( ny, sizeof(float), "ypos" ); freqn( ky, ky2, ypos, ny, by ); /* allocate some more arrays and initialize wavefunction */ trans.resize( nx, ny ); trans.init(); wave.resize( nx, ny ); wave.copyInit( trans ); if( lstart == 0 ) { for( ix=0; ix<nx; ix++) for( iy=0; iy<ny; iy++) { wave.re(ix,iy) = 1.0F; /* real part */ wave.im(ix,iy) = 1.0F; /* imag part */ } } else { for( ix=0; ix<nx; ix++) for( iy=0; iy<ny; iy++) { wave.re(ix,iy) = wave0r[ix][iy]; /* real part */ wave.im(ix,iy) = wave0i[ix][iy]; /* imag part */ } } if( lcross == 1 ) { /* nz may be too small with thermal vibrations so add a few extra */ nz = (int) ( (zmax-zmin)/ deltaz + 3.5); depthpix = (float**) malloc2D( nx, nz, sizeof(float), "depthpix" ); for( ix=0; ix<nx; ix++) for( iz=0; iz<nz; iz++) depthpix[ix][iz] = 0.0F; iycross = (int) ( 0.5 + (ny * ycross / by)); while( iycross < 0 ) iycross += ny; iycross = iycross%ny; /* make periodic in ny */ printf("save xz cross section at iy= %d pixels\n", iycross ); } /* calculate propagator function */ k2max = nx/(2.0F*ax); tctx = ny/(2.0F*by); if( tctx < k2max ) k2max = tctx; k2max = BW * k2max; printf("Bandwidth limited to a real space resolution of %f Angstroms\n", 1.0F/k2max); printf(" (= %.2f mrad) for symmetrical anti-aliasing.\n", wavlen*k2max*1000.0F); k2max = k2max*k2max; tctx = (float) (2.0 * tan(ctiltx)); tcty = (float) (2.0 * tan(ctilty)); propxr = (float*) malloc1D( nx, sizeof(float), "propxr" ); propxi = (float*) malloc1D( nx, sizeof(float), "propxi" ); propyr = (float*) malloc1D( ny, sizeof(float), "propyr" ); propyi = (float*) malloc1D( ny, sizeof(float), "propyi" ); scale = pi * ((float)deltaz); for( ix=0; ix<nx; ix++) { t = scale * ( kx2[ix]*wavlen - kx[ix]*tctx ); propxr[ix] = (float) cos(t); propxi[ix] = (float) -sin(t); } for( iy=0; iy<ny; iy++) { t = scale * ( ky2[iy]*wavlen - ky[iy]*tcty ); propyr[iy] = (float) cos(t); propyi[iy] = (float) -sin(t); } /* iterate the multislice algorithm proper NOTE: zero freg is in the bottom left corner and expands into all other corners - not in the center this is required for the FFT - don't waste time rearranging partial coherence method force the integrals to include the origin and to be symmetric about the origin and to have the same periodic boundary conditions as the sampling grid */ if( lpartl == 1 ) { printf("Illumination angle sampling (in mrad) = %f, %f\n\n", 1000.*rx*wavlen, 1000.*ry*wavlen); pix = (float**) malloc2D( nx, ny, sizeof(float), "pix" ); for( ix=0; ix<nx; ix++) for( iy=0; iy<ny; iy++) pix[ix][iy] = 0.0F; temp.resize( nx, ny ); temp.copyInit( trans ); ndf = (int) ( ( 2.5F * sigmaf ) / dfdelt ); nacx = (int) ( ( acmax / ( wavlen * rx ) ) + 1.5F ); nacy = (int) ( ( acmax / ( wavlen * ry ) ) + 1.5F ); q2max = acmax / wavlen; q2max = q2max*q2max; q2min = acmin / wavlen; q2min = q2min*q2min; k2maxo = aobj / wavlen; k2maxo = k2maxo*k2maxo; chi1 = pi * wavlen; chi2 = 0.5 * Cs3 * wavlen *wavlen; chi3 = Cs5 * wavlen*wavlen*wavlen*wavlen /3.0; nillum = 0; /* for Monte Carlo stuff */ x2 = (float*) malloc1D( natom, sizeof(float), "x2" ); y2 = (float*) malloc1D( natom, sizeof(float), "y2" ); z2 = (float*) malloc1D( natom, sizeof(float), "z2" ); occ2 = (float*) malloc1D( natom, sizeof(float), "occ2" ); Znum2 = (int*) malloc1D( natom, sizeof(int), "Znum2" ); if( lwobble == 0 ) sortByZ( x, y, z, occ, Znum, natom ); /* integrate over the illumination angles */ for( iwobble=0; iwobble<nwobble; iwobble++) { if( lwobble == 1 ) printf("configuration # %d\n", iwobble+1 ); for( iqy= -nacy; iqy<=nacy; iqy++) { qy = iqy * ry; qy2 = qy * qy; for( iqx= -nacx; iqx<=nacx; iqx++) { qx = iqx * rx; q2 = qx*qx + qy2; if( (q2 <= q2max) && (q2 >= q2min) ) { nillum += 1; for( ix=0; ix<nx; ix++) { for( iy=0; iy<ny; iy++) { t = 2.0*pi*( qx*xpos[ix] + qy*ypos[iy] ); wave.re(ix,iy) = (float) cos(t); /* real */ wave.im(ix,iy) = (float) sin(t); /* imag */ } } /* add random thermal displacements scaled by temperature if requested remember that initial wobble is at 300K for each direction */ if( lwobble == 1 ){ scale = (float) sqrt(temperature/300.0) ; for( i=0; i<natom; i++) { x2[i] = x[i] + (float)(wobble[i]*rangauss(&iseed)*scale); y2[i] = y[i] + (float)(wobble[i]*rangauss(&iseed)*scale); z2[i] = z[i] + (float)(wobble[i]*rangauss(&iseed)*scale); occ2[i] = occ[i]; Znum2[i] = Znum[i]; } printf( "Sorting atoms by depth...\n"); sortByZ( x2, y2, z2, occ2, Znum2, natom ); zmin = z2[0]; /* reset zmin/max after wobble */ zmax = z2[natom-1]; printf("Thickness range with thermal displacements" " is %g to %g (in z)\n", zmin, zmax ); } else for( i=0; i<natom; i++) { x2[i] = x[i]; y2[i] = y[i]; z2[i] = z[i]; occ2[i] = occ[i]; Znum2[i] = Znum[i]; } zslice = 0.75*deltaz; /* start a little before top of unit cell */ istart = 0; while( istart < natom ) { /* find range of atoms for current slice */ na = 0; for(i=istart; i<natom; i++) if( z2[i] < zslice ) na++; else break; /* calculate transmission function, skip if layer empty */ if( na > 0 ) { trlayer( &x2[istart], &y2[istart], &occ2[istart], &Znum2[istart],na, ax, by, v0, trans, nxl, nyl, &phirms, &nbeams, k2max ); wave *= trans; // transmit } /* remember: prop needed here to get anti-aliasing right */ wave.fft(); propagate( wave, propxr, propxi, propyr, propyi, kx2, ky2, k2max, nx, ny ); wave.ifft(); zslice += deltaz; istart += na; } /* end while(zslice<=..) */ scale = 1.0F / ( ((float)nx) * ((float)ny) ); sum = 0.0; for( ix=0; ix<nx; ix++) { for( iy=0; iy<ny; iy++) sum += wave.re(ix,iy)*wave.re(ix,iy) + wave.im(ix,iy)*wave.im(ix,iy); } sum = sum * scale; printf("Illumination angle = %7.3f, %7.3f mrad", 1000.*qx*wavlen, 1000.*qy*wavlen); printf(", integrated intensity= %f\n", sum ); /*-------- integrate over +/- 2.5 sigma of defocus ------------ */ wave.fft(); sumdf = 0.0F; for( idf= -ndf; idf<=ndf; idf++) { param[pDEFOCUS] = df = df0 + idf*dfdelt; for( ix=0; ix<nx; ix++) { alx = wavlen * kx[ix]; /* x component of angle alpha */ for( iy=0; iy<ny; iy++) { aly = wavlen * ky[iy]; /* y component of angle alpha */ k2 = kx2[ix] + ky2[iy]; if( k2 <= k2maxo ) { chi0 = (2.0*pi/wavlen) * chi( param, alx, aly, multiMode ); tr = (float) cos(chi0); ti = (float) -sin(chi0); wr = wave.re(ix,iy); wi = wave.im(ix,iy); temp.re(ix,iy) = wr*tr - wi*ti; temp.im(ix,iy) = wr*ti + wi*tr; } else { temp.re(ix,iy) = 0.0F; /* real */ temp.im(ix,iy) = 0.0F; /* imag */ } } /* end for( iy=0... ) */ } /* end for( ix=0... ) */ temp.ifft(); xdf = (double) ( (df - df0) /sigmaf ); pdf = (float) exp( -0.5F * xdf*xdf ); sumdf += pdf; for( ix=0; ix<nx; ix++) { for( iy=0; iy<ny; iy++) { wr = temp.re(ix,iy); wi = temp.im(ix,iy); pix[ix][iy] += pdf* ( wr*wr + wi*wi ); } } }/* end for(idf..) */ }/* end if( q2...) */ } /* end for( iqx..) */ } /* end for( iqy..) */ } /* end for( iwobble...) */ printf("Total number of illumination angle = %ld\n", nillum); printf("Total number of defocus values = %d\n", 2*ndf+1); /* remember that nillum already includes nwobble so don't divide by nwobble! */ scale = 1.0F / ( ((float)nillum) * sumdf ); rmin = pix[0][0] * scale; rmax = rmin; aimin = 0.0F; aimax = 0.0F; for( ix=0; ix<nx; ix++) for( iy=0; iy<ny; iy++) { pix[ix][iy] = pix[ix][iy] * scale; if( pix[ix][iy] < rmin ) rmin = pix[ix][iy]; if( pix[ix][iy] > rmax ) rmax = pix[ix][iy]; } /* ---- start coherent method below ---------------- (remember that waver,i[][] was initialize above) */ } else { if( lbeams ==1 ) { fp1 = fopen( filebeam, "w" ); if( NULL == fp1 ) { printf("can't open file %s\n", filebeam); exit(0); } fprintf( fp1, " (h,k) = " ); for(ib=0; ib<nbout; ib++) fprintf(fp1," (%d,%d)", hbeam[ib], kbeam[ib]); fprintf( fp1, "\n" ); fprintf( fp1, "nslice, (real,imag) (real,imag) ...\n\n"); for( ib=0; ib<nbout; ib++) { if( hbeam[ib] < 0 ) hbeam[ib] = nx + hbeam[ib]; if( kbeam[ib] < 0 ) kbeam[ib] = ny + kbeam[ib]; if( hbeam[ib] < 0 ) hbeam[ib] = 0; if( kbeam[ib] < 0 ) kbeam[ib] = 0; if( hbeam[ib] > nx-1 ) hbeam[ib] = nx-1; if( kbeam[ib] > ny-1 ) kbeam[ib] = ny-1; } } /* add random thermal displacements scaled by temperature if requested remember that initial wobble is at 300K for each direction */ if( lwobble == 1 ){ scale = (float) sqrt(temperature/300.0) ; for( i=0; i<natom; i++) { x[i] += (float) (wobble[i] * rangauss( &iseed ) * scale); y[i] += (float) (wobble[i] * rangauss( &iseed ) * scale); z[i] += (float) (wobble[i] * rangauss( &iseed ) * scale); } } printf( "Sorting atoms by depth...\n"); sortByZ( x, y, z, occ, Znum, natom ); if( lwobble == 1 ){ zmin = z[0]; /* reset zmin/max after wobble */ zmax = z[natom-1]; printf("Thickness range with thermal displacements" " is %g to %g (in z)\n", zmin, zmax ); } scale = 1.0F / ( ((float)nx) * ((float)ny) ); zslice = 0.75*deltaz; /* start a little before top of unit cell */ istart = 0; islice = 1; while( (istart < natom) && ( zslice < (zmax+deltaz) ) ) { /* find range of atoms for current slice */ na = 0; for(i=istart; i<natom; i++) if( z[i] < zslice ) na++; else break; /* calculate transmission function, skip if layer empty */ if( na > 0 ) { trlayer( &x[istart], &y[istart], &occ[istart], &Znum[istart], na, ax, by, v0, trans, nxl, nyl, &phirms, &nbeams, k2max ); /*??? printf("average atompot comparison = %g\n", phirms/(wavlen*mm0) ); */ wave *= trans; // transmit } /* bandwidth limit */ wave.fft(); if( lbeams== 1 ) { fprintf( fp1, "%5d", islice); for( ib=0; ib<nbout; ib++) fprintf(fp1, "%10.6f %10.6f", scale*wave.re(hbeam[ib],kbeam[ib]), /* real */ scale*wave.im(hbeam[ib],kbeam[ib]) ); /* imag */ fprintf( fp1, "\n"); } /* remember: prop needed here to get anti-aliasing right */ propagate( wave, propxr, propxi, propyr, propyi, kx2, ky2, k2max, nx, ny ); wave.ifft(); /* save depth cross section if requested */ if( (lcross == 1) && (islice<=nz) ) { for( ix=0; ix<nx; ix++) { depthpix[ix][islice-1] = wave.re(ix,iycross)*wave.re(ix,iycross) + wave.im(ix,iycross)*wave.im(ix,iycross); } nzout = islice; } sum = 0.0; for( ix=0; ix<nx; ix++) { for( iy=0; iy<ny; iy++) sum += wave.re(ix,iy)*wave.re(ix,iy) + wave.im(ix,iy)*wave.im(ix,iy); } sum = sum * scale; printf("z= %f A, %ld beams, %d coord., \n" " aver. phase= %f, total intensity = %f\n", zslice, nbeams, na, phirms, sum ); zslice += deltaz; istart += na; islice++; } /* end while(istart<natom..) */ rmin = wave.re(0,0); rmax = rmin; aimin = wave.im(0,0); aimax = aimin; for( ix=0; ix<nx; ix++) { for( iy=0; iy<ny; iy++) { wr = wave.re(ix,iy); wi = wave.im(ix,iy); if( wr < rmin ) rmin = wr; if( wr > rmax ) rmax = wr; if( wi < aimin ) aimin = wi; if( wi > aimax ) aimax = wi; } } } /* end else .. coherent section */ /* output results and find min and max to echo remember that complex pix are stored in the file in FORTRAN order for compatibility */ if( lstart == 1 ) for( ix=0; ix<NPARAM; ix++ ) param[ix] = sparam[ix]; param[pRMAX] = rmax; param[pIMAX] = aimax; param[pRMIN] = rmin; param[pIMIN] = aimin; param[pXCTILT] = ctiltx; param[pYCTILT] = ctilty; param[pENERGY] = v0; param[pDX] = dx = (float) ( ax/((float)nx) ); param[pDY] = dy = (float) ( by/((float)ny) ); param[pWAVEL] = wavlen; param[pNSLICES] = 0.0F; /* ??? */ if ( lpartl == 1 ) { param[pDEFOCUS] = df0; param[pOAPERT] = aobj; param[pCAPERT] = acmax; param[pDDF] = sigmaf; } for( ix=0; ix<NPARAM; ix++ ) myFile.setParam( ix, param[ix] ); if ( lpartl == 1 ) { myFile.resize( nx, ny ); myFile.setnpix( 1 ); for( ix=0; ix<nx; ix++) for( iy=0; iy<ny; iy++) myFile(ix,iy) = pix[ix][iy]; i = myFile.write( fileout, rmin, rmax, aimin, aimax, dx, dy ); } else { myFile.resize( 2*nx, ny ); myFile.setnpix( 2 ); for( ix=0; ix<nx; ix++) for( iy=0; iy<ny; iy++) { myFile(ix,iy) = wave.re(ix,iy); myFile(ix+nx,iy) = wave.im(ix,iy); } i = myFile.write( fileout, rmin, rmax, aimin, aimax, dx, dy ); } if( i != 1 ) printf( "autoslice cannot write TIF file %s\n", fileout ); printf( "pix range %g to %g real,\n" " %g to %g imag\n", rmin,rmax,aimin,aimax ); /* output depth cross section if requested */ if( lcross == 1 ){ rmin = depthpix[0][0]; rmax = rmin; for( ix=0; ix<nx; ix++) for( iz=0; iz<nzout; iz++) { wr = depthpix[ix][iz]; if( wr < rmin ) rmin = wr; if( wr > rmax ) rmax = wr; } myFile.setParam( pRMAX, rmax ); myFile.setParam( pIMAX, 0.0F ); myFile.setParam( pRMIN, rmin ); myFile.setParam( pIMIN, 0.0F ); myFile.setParam( pDY, dy = (float) ( deltaz ) ); myFile.resize( nx, nzout ); myFile.setnpix( 1 ); for( ix=0; ix<nx; ix++) for( iz=0; iz<nzout; iz++) { myFile(ix,iz) = depthpix[ix][iz]; } i = myFile.write( filecross, rmin, rmax, aimin, aimax, dx, dy ); if( i != 1 ) printf( "autoslice cannot write TIF file %s\n", filecross ); printf( "depth pix range %g to %g real,\n", rmin,rmax ); } printf("Total CPU time = %f sec.\n", cputim()-timer ); #ifdef USE_OPENMP printf("wall time = %g sec.\n", walltim() - walltimer); #endif return 0; } /* end main() */
/* @brief function that generates a neutron and measures how far it travels before being absorbed. @details a neutron is created in the bounding box using sample_location() for the first batch and sample_fission_site() for the rest of the batches. It moves a distance determined by sample_distance(). It is then either absorbed or scattered as determined by sample_interaction(). When it is absorbed, its distance from its starting point is appended to crow_distances. If the absorption creates a fission event, the number of neutrons emited is sampled. The location of the fission event is added to a list of fission events. @param bounds a Boundaries object containing the limits of the bounding box @param tallies a dictionary containing tallies of crow distances, leakages, absorptions, and fissions @param mesh a Mesh object containing information about the mesh @param old_fission_banks containing the old fission bank @param new_fission_banks containing the new fission bank @param num_groups the number of neutron energy groups @param neutron_num an int used for indexing neutrons @param z_bounds a vector containing the minimum and maximum geometry boundaries along the z axis since OpenMOC only handles 2D geometries */ void transportNeutron(Boundaries bounds, std::vector <Tally> &tallies, bool first_round, Mesh &mesh, Lattice* lattice, Fission* fission_banks, int num_groups, int neutron_num, Universe* root_universe, Geometry* geometry) { const double BOUNDARY_ERROR = 1e-10; Point* neutron_position = new Point(); // new way to sample neutron and set its direction Neutron neutron(neutron_num); neutron.sampleDirection(); // get and set neutron starting poinit if (first_round) bounds.sampleLocation(&neutron); else { fission_banks->sampleSite(&neutron); } // get mesh cell Point* neutron_starting_point; neutron.getPositionVector(neutron_starting_point); std::vector <int> cell (3); cell[0] = lattice->getLatX(neutron_starting_point); cell[1] = lattice->getLatY(neutron_starting_point); cell[2] = lattice->getLatZ(neutron_starting_point); neutron.setCell(cell); // set neutron group Material* cell_mat; Cell* cell_obj; int group; // get cell material LocalCoords* neutron_coord_position = new LocalCoords( neutron_starting_point->getX(), neutron_starting_point->getY(), neutron_starting_point->getZ()); neutron_coord_position->setUniverse(root_universe); cell_obj = geometry->findCellContainingCoords(neutron_coord_position); cell_mat = cell_obj->getFillMaterial(); std::vector <double> chi(num_groups); for (int g=0; g<num_groups; ++g) { chi[g] = cell_mat->getChiByGroup(g+1); } group = neutron.sampleNeutronEnergyGroup(chi); neutron.setGroup(group); // follow neutron while it's alive while (neutron.alive()) { neutron_coord_position->setX(neutron_position->getX()); neutron_coord_position->setY(neutron_position->getY()); neutron_coord_position->setZ(neutron_position->getZ()); neutron_coord_position->setUniverse(root_universe); cell_obj = geometry->findCellContainingCoords(neutron_coord_position); cell_mat = cell_obj->getFillMaterial(); //cell_mat = mesh.getMaterial(cell); group = neutron.getGroup(); double neutron_distance; //sample a distance to travel in the material neutron_distance = -log(neutron.arand()) / cell_mat->getSigmaTByGroup(group+1); // track neutron until collision or leakage while (neutron_distance > BOUNDARY_ERROR) { neutron.getPositionVector(neutron_position); // get cell boundaries std::vector <double> cell_mins (3); std::vector <double> cell_maxes (3); cell_mins[0] = lattice->getMinX() + cell[0] * lattice->getWidthX(); cell_mins[1] = lattice->getMinY() + cell[1] * lattice->getWidthY(); cell_mins[2] = lattice->getMinZ() + cell[2] * lattice->getWidthZ(); cell_maxes[0] = lattice->getMinX() + (cell[0] + 1) * lattice->getWidthX(); cell_maxes[1] = lattice->getMinY() + (cell[1] + 1) * lattice->getWidthY(); cell_maxes[2] = lattice->getMinZ() + (cell[2] + 1) * lattice->getWidthZ(); // calculate distances to cell boundaries std::vector <std::vector <double> > distance_to_cell_edge(3); for (int axis=0; axis<3; ++axis) { distance_to_cell_edge[axis].resize(2); distance_to_cell_edge[axis][0] = cell_mins[axis] - neutron.getPosition(axis); distance_to_cell_edge[axis][1] = cell_maxes[axis] - neutron.getPosition(axis); } // create lim_bounds std::vector <int> cell_lim_bound; std::vector <int> box_lim_bound; // clear lim_bounds cell_lim_bound.clear(); box_lim_bound.clear(); // tempd contains the current smallest r double tempd; tempd = neutron_distance; // test each boundary double r; for (int axis=0; axis<3; ++axis) { for (int side=0; side<2; ++side) { // r is variable that contains the distance // along the direction vector to the boundary being tested. r = distance_to_cell_edge[axis][side] / neutron.getDirection(axis); if (r > BOUNDARY_ERROR & r < tempd) { tempd = r; cell_lim_bound.clear(); cell_lim_bound.push_back(axis*2+side); } else if (r == tempd) { cell_lim_bound.push_back(axis*2+side); } } } // move neutron neutron.move(tempd); // add distance to cell flux mesh.fluxAdd(cell, tempd, group); // shorten neutron distance to collision neutron_distance -= tempd; // determine potential geometry boundaries for (int sur_side=0; sur_side <6; ++sur_side) { int axis = sur_side/2; int side = sur_side%2; // if sur_side is in cell_lim_bound if (std::find(cell_lim_bound.begin(), cell_lim_bound.end(),sur_side) != cell_lim_bound.end()) { if (neutron.getCell()[axis] == 0 && side ==0) box_lim_bound.push_back(sur_side); // if the neutron is on the max side of the cell and the // cell is the highest cell in the geometry if (axis == 0) { if (neutron.getCell()[axis] == lattice->getNumX() - 1 && side == 1) box_lim_bound.push_back(sur_side); } if (axis == 1) { if (neutron.getCell()[axis] == lattice->getNumY() - 1 && side == 1) box_lim_bound.push_back(sur_side); } if (axis == 2) { if (neutron.getCell()[axis] == lattice->getNumZ() - 1 && side == 1) box_lim_bound.push_back(sur_side); } } } // check boundary conditions on all hit surfaces for (int sur_side=0; sur_side <6; ++sur_side) { int axis = sur_side/2; int side = sur_side%2; // if sur_side is in box_lim_bound if (std::find(box_lim_bound.begin(), box_lim_bound.end(),sur_side) != box_lim_bound.end()) { // if the neutron is reflected if (bounds.getSurfaceType(axis, side) == 1) { neutron.reflect(axis); // place neutron on boundary to eliminate roundoff error double bound_val; bound_val = bounds.getSurfaceCoord(axis, side); neutron.setPosition(axis, bound_val); } // if the neutron escapes if (bounds.getSurfaceType(axis, side) == 0) { neutron.kill(); neutron_distance = 0; tallies[LEAKS] += 1; break; } } } // get new neutron cell if (neutron_distance > 0) { cell[0] = lattice->getLatX(neutron_position); cell[1] = lattice->getLatY(neutron_position); cell[2] = lattice->getLatZ(neutron_position); // nudge neutron and find its cell neutron.move(1e-3); neutron.getPositionVector(neutron_position); // withinBounds seems to return true if the point is without if (lattice->withinBounds(neutron_position)) { cell[0] = lattice->getLatX(neutron_position); cell[1] = lattice->getLatY(neutron_position); cell[2] = lattice->getLatZ(neutron_position); } neutron.move(-1e-3); neutron.setCell(cell); } } // check interaction if (neutron.alive()) { neutron_coord_position->setX(neutron_position->getX()); neutron_coord_position->setY(neutron_position->getY()); neutron_coord_position->setZ(neutron_position->getZ()); neutron_coord_position->setUniverse(root_universe); cell_obj = geometry->findCellContainingCoords(neutron_coord_position); cell_mat = cell_obj->getFillMaterial(); // calculate sigma_s for a group in order to sample an interaction std::vector <double> sigma_s_group; double sum_sigma_s_group=0; for (int g=1; g<=cell_mat->getNumEnergyGroups(); ++g) { sigma_s_group.push_back(cell_mat->getSigmaSByGroup(group+1, g)); sum_sigma_s_group += cell_mat->getSigmaSByGroup(group+1, g); } // calculate sigma_a in order to sample an interaction double sigma_a; sigma_a = cell_mat->getSigmaTByGroup(group+1) - sum_sigma_s_group; // sample an interaction int neutron_interaction = (int) (neutron.arand() < (sigma_a / cell_mat->getSigmaTByGroup(group+1))); // scattering event if (neutron_interaction == 0) { // sample scattered direction neutron.sampleDirection(); // sample new energy group int new_group = neutron.sampleScatteredGroup(sigma_s_group, group); // set new group neutron.setGroup(new_group); } // absorption event else { // tally absorption tallies[ABSORPTIONS] += 1; // sample for fission event group = neutron.getGroup(); cell = neutron.getCell(); neutron_coord_position->setX(neutron_position->getX()); neutron_coord_position->setY(neutron_position->getY()); neutron_coord_position->setZ(neutron_position->getZ()); neutron_coord_position->setUniverse(root_universe); cell_obj = geometry->findCellContainingCoords(neutron_coord_position); cell_mat = cell_obj->getFillMaterial(); neutron.getPositionVector(neutron_position); // sample whether fission event occurs int fission_occurs = neutron.arand() < cell_mat->getSigmaFByGroup(group+1) / sigma_a; // fission event if (fission_occurs == 1) { // sample number of neutrons released during fission double nu = cell_mat->getNuSigmaFByGroup(1) / cell_mat->getSigmaFByGroup(1); int lower = (int) nu; int add = (int) (neutron.arand() < nu -lower); int num_neutrons = lower + add; for (int i=0; i<num_neutrons; ++i) { fission_banks->add(neutron_position); tallies[FISSIONS] += 1; } } // end neutron history neutron.kill(); } } } // tally crow distance double crow_distance; crow_distance = neutron.getDistance(neutron_starting_point); tallies[CROWS] += crow_distance; tallies[NUM_CROWS] += 1; }
void Foam::kineticTheoryModel::solve(const volTensorField& gradUat) { if(kineticTheory_) { //if (!kineticTheory_) //{ // return; //} //const scalar sqrtPi = sqrt(mathematicalConstant::pi); if(Berzi_) { Info << "Berzi Model is used" << endl; } else{ const scalar sqrtPi = sqrt(constant::mathematical::pi); surfaceScalarField phi = 1.5*rhoa_*phia_*fvc::interpolate(alpha_); volTensorField dU = gradUat.T();//fvc::grad(Ua_); volSymmTensorField D = symm(dU); // NB, drag = K*alpha*beta, // (the alpha and beta has been extracted from the drag function for // numerical reasons) volScalarField Ur = mag(Ua_ - Ub_); volScalarField betaPrim = alpha_*(1.0 - alpha_)*draga_.K(Ur); // Calculating the radial distribution function (solid volume fraction is // limited close to the packing limit, but this needs improvements) // The solution is higly unstable close to the packing limit. gs0_ = radialModel_->g0 ( min(max(alpha_, 1e-6), alphaMax_ - 0.01), alphaMax_ ); // particle pressure - coefficient in front of Theta (Eq. 3.22, p. 45) volScalarField PsCoeff = granularPressureModel_->granularPressureCoeff ( alpha_, gs0_, rhoa_, e_ ); // 'thermal' conductivity (Table 3.3, p. 49) kappa_ = conductivityModel_->kappa(alpha_, Theta_, gs0_, rhoa_, da_, e_); // particle viscosity (Table 3.2, p.47) mua_ = viscosityModel_->mua(alpha_, Theta_, gs0_, rhoa_, da_, e_); dimensionedScalar Tsmall ( "small", dimensionSet(0 , 2 ,-2 ,0 , 0, 0, 0), 1.0e-6 ); dimensionedScalar TsmallSqrt = sqrt(Tsmall); volScalarField ThetaSqrt = sqrt(Theta_); // dissipation (Eq. 3.24, p.50) volScalarField gammaCoeff = 12.0*(1.0 - sqr(e_))*sqr(alpha_)*rhoa_*gs0_*(1.0/da_)*ThetaSqrt/sqrtPi; // Eq. 3.25, p. 50 Js = J1 - J2 volScalarField J1 = 3.0*betaPrim; volScalarField J2 = 0.25*sqr(betaPrim)*da_*sqr(Ur) /(max(alpha_, 1e-6)*rhoa_*sqrtPi*(ThetaSqrt + TsmallSqrt)); // bulk viscosity p. 45 (Lun et al. 1984). lambda_ = (4.0/3.0)*sqr(alpha_)*rhoa_*da_*gs0_*(1.0+e_)*ThetaSqrt/sqrtPi; // stress tensor, Definitions, Table 3.1, p. 43 volSymmTensorField tau = 2.0*mua_*D + (lambda_ - (2.0/3.0)*mua_)*tr(D)*I; if (!equilibrium_) { // construct the granular temperature equation (Eq. 3.20, p. 44) // NB. note that there are two typos in Eq. 3.20 // no grad infront of Ps // wrong sign infront of laplacian fvScalarMatrix ThetaEqn ( fvm::ddt(1.5*alpha_*rhoa_, Theta_) + fvm::div(phi, Theta_, "div(phi,Theta)") == fvm::SuSp(-((PsCoeff*I) && dU), Theta_) + (tau && dU) + fvm::laplacian(kappa_, Theta_, "laplacian(kappa,Theta)") + fvm::Sp(-gammaCoeff, Theta_) + fvm::Sp(-J1, Theta_) + fvm::Sp(J2/(Theta_ + Tsmall), Theta_) ); ThetaEqn.relax(); ThetaEqn.solve(); } else { // equilibrium => dissipation == production // Eq. 4.14, p.82 volScalarField K1 = 2.0*(1.0 + e_)*rhoa_*gs0_; volScalarField K3 = 0.5*da_*rhoa_* ( (sqrtPi/(3.0*(3.0-e_))) *(1.0 + 0.4*(1.0 + e_)*(3.0*e_ - 1.0)*alpha_*gs0_) +1.6*alpha_*gs0_*(1.0 + e_)/sqrtPi ); volScalarField K2 = 4.0*da_*rhoa_*(1.0 + e_)*alpha_*gs0_/(3.0*sqrtPi) - 2.0*K3/3.0; volScalarField K4 = 12.0*(1.0 - sqr(e_))*rhoa_*gs0_/(da_*sqrtPi); volScalarField trD = tr(D); volScalarField tr2D = sqr(trD); volScalarField trD2 = tr(D & D); volScalarField t1 = K1*alpha_ + rhoa_; volScalarField l1 = -t1*trD; volScalarField l2 = sqr(t1)*tr2D; volScalarField l3 = 4.0*K4*max(alpha_, 1e-6)*(2.0*K3*trD2 + K2*tr2D); Theta_ = sqr((l1 + sqrt(l2 + l3))/(2.0*(alpha_ + 1.0e-4)*K4)); } Theta_.max(1.0e-15); Theta_.min(1.0e+3); volScalarField pf = frictionalStressModel_->frictionalPressure ( alpha_, alphaMinFriction_, alphaMax_, Fr_, eta_, p_ ); PsCoeff += pf/(Theta_+Tsmall); PsCoeff.min(1.0e+10); PsCoeff.max(-1.0e+10); // update particle pressure pa_ = PsCoeff*Theta_; // frictional shear stress, Eq. 3.30, p. 52 volScalarField muf = frictionalStressModel_->muf ( alpha_, alphaMax_, pf, D, phi_ ); // add frictional stress mua_ += muf; //-AO Inconsistency of equations const scalar constSMALL = 0.001; //1.e-06; mua_ /= (fvc::average(alpha_) + scalar(constSMALL)); lambda_ /= (fvc::average(alpha_) + scalar(constSMALL)); //-AO mua_.min(1.0e+2); mua_.max(0.0); Info<< "kinTheory: max(Theta) = " << max(Theta_).value() << endl; volScalarField ktn = mua_/rhoa_; Info<< "kinTheory: min(nua) = " << min(ktn).value() << ", max(nua) = " << max(ktn).value() << endl; Info<< "kinTheory: min(pa) = " << min(pa_).value() << ", max(pa) = " << max(pa_).value() << endl; //} /* volScalarField& Foam::kineticTheoryModel::ppMagf(const volScalarField& alphaUpdate) { volScalarField alpha = alphaUpdate; gs0_ = radialModel_->g0(min(alpha, alphaMinFriction_), alphaMax_); gs0Prime_ = radialModel_->g0prime(min(alpha, alphaMinFriction_), alphaMax_); // Computing ppMagf ppMagf_ = Theta_*granularPressureModel_->granularPressureCoeffPrime ( alpha, gs0_, gs0Prime_, rhoa_, e_ ); volScalarField ppMagfFriction = frictionalStressModel_->frictionalPressurePrime ( alpha, alphaMinFriction_, alphaMax_, Fr_, eta_, p_ ); // NOTE: this might not be appropriate if J&J model is used (verify) forAll(alpha, cellI) { if(alpha[cellI] >= alphaMinFriction_.value()) { ppMagf_[cellI] = ppMagfFriction[cellI]; } } ppMagf_.correctBoundaryConditions(); return ppMagf_; } */} } else if(mofidiedKineticTheoryPU_) { //if (!mofidiedKineticTheoryPU_) //{ // return; //} Info << " " << endl; Info << "Modified kinetic theory model - Chialvo-Sundaresan " << endl; bool testMKTimp(false); if(kineticTheoryProperties_.found("testMKTimp")) { testMKTimp = true; Info << "Modified kinetic theory model - testing implementation (chi=1,eEff=e, ksi=1) " << endl; } bool diluteCorrection(false); if(kineticTheoryProperties_.found("diluteCorrection")) { testMKTimp = false; diluteCorrection = true; Info << "Modified kinetic theory model - Only dilute correction " << endl; } bool denseCorrection(false); if(kineticTheoryProperties_.found("denseCorrection")) { testMKTimp = false; diluteCorrection = false; denseCorrection = true; Info << "Modified kinetic theory model - Only dense correction " << endl; } bool frictionBlending(false); if(kineticTheoryProperties_.found("frictionBlending")) { frictionBlending = true; Info << "Modified kinetic theory model - Include Friction Blneding " << endl; } if(decomposePp_) Info << "Decompose Pp into Pp - PpStar " << endl; bool verboseMKT(false); if(kineticTheoryProperties_.found("verboseMKT")) verboseMKT = true; const scalar Pi = constant::mathematical::pi; const scalar sqrtPi = sqrt(constant::mathematical::pi); const scalar constSMALL = 1.e-06; //1.e-06; 1.e-03; // Read from dictionary muFric_ = readScalar(kineticTheoryProperties_.lookup("muFriction")); eEff_ = e_ - 3.0 / 2.0 * muFric_ * exp(-3.0 * muFric_); // If only test MKT implementation if(testMKTimp) eEff_ = e_; alphaf_ = readScalar(kineticTheoryProperties_.lookup("alphaDiluteInertialUpperLimit")); alphac_ = readScalar(kineticTheoryProperties_.lookup("alphaCritical")); alphad_ = readScalar(kineticTheoryProperties_.lookup("alphaDelta")); upsilons_ = readScalar(kineticTheoryProperties_.lookup("yieldStressRatio")); // Model parameters dimensionedScalar I0(0.2); // Table 2, p.15 dimensionedScalar const_alpha(0.36); // Table 2, p.15 dimensionedScalar const_alpha1(0.06); // Table 2, p.15 // Calculating the radial distribution function (solid volume fraction is // limited close to the packing limit, but this needs improvements) // The solution is higly unstable close to the packing limit. gs0_ = radialModel_->g0jamming ( Ua_.mesh(), //max(alpha, scalar(constSMALL)), min(max(alpha_, scalar(constSMALL)),alphaMax_ - 0.01), //changed by YG alphaMax_, alphad_, ///changed by YG alphac_ ); // particle pressure - coefficient in front of T (Eq. 1, p. 3) volScalarField PsCoeff // -> rho_p * H ( granularPressureModel_->granularPressureCoeff ( alpha_, gs0_, rhoa_, e_ ) ); PsCoeff.max(1.0e-15); // PsCoeff.min(1.0e+10); // PsCoeff.max(-1.0e+10); // Solid kinetic+collisional viscosity mua_ = nu_k^star + nu_c^star, Eq. 8,9, p.4 // If Garzo-Dufty viscosity is used (viscosity is dimensionless), there is issue with dimension of mu1 mua_ = viscosityModel_->mua(alpha_, Theta_, gs0_, rhoa_, da_, e_); // Solid bulk viscosity mua_ = nu_k^star + nu_c^star, Eq. 10, p.4 // If Garzo-Dufty viscosity is used (viscosity is dimensionless), there is issue with dimension of mu1 // Create dimensionedScalar dimensionedScalar viscDim("zero", dimensionSet(1, -1, -1, 0, 0), 1.0); lambda_ = viscDim * 384.0 / ( 25.0 * Pi ) * ( 1.0 + e_ ) * alpha_ * alpha_ * gs0_ ; //lambda_ = (4.0/3.0)*sqr(alpha_)*rhoa_*da_*gs0_*(1.0+e_)*sqrt(Theta_)/sqrtPi; volScalarField ratioBulkShearVisc(lambda_/(mua_+lambda_)); // J Eq.5, p3 volScalarField J_( 5.0 * sqrtPi / 96.0 * ( mua_ + lambda_ ) / viscDim ); // Dimension issue // K Eq.6, p3 volScalarField K_(12.0/sqrtPi*alpha_*alpha_*gs0_*(1.0-e_*e_)); // K' Eq.26, p8 modified dissipation due to friction volScalarField Kmod_(K_*(1.0 - eEff_*eEff_)/(1.0 - e_*e_)); // M Eq.30 p.9 volScalarField M_( max( J_ / max( Kmod_, constSMALL) , const_alpha1 / sqrt( max(alphac_ - alpha_, constSMALL) ) ) ); // Shear stress rate tensor volTensorField dU(gradUat.T()); volSymmTensorField D(symm(dU)); // Shear stress rate (gammaDot) volScalarField gammaDot(sqrt(2.*magSqr(D))); dimensionedScalar gammaDotSmall("gammaDotSmall",dimensionSet(0 , 0 , -1 , 0 , 0, 0, 0), constSMALL); // Dilute inertia temperature Eq.24, p8 volScalarField ThetaDil_ = ( J_ / max ( Kmod_ , 1e-1 ) ) * ( gammaDot * da_ ) * ( gammaDot * da_ ); // Dense inertia temperature Eq.27, p8 // volScalarField ThetaDense_ = const_alpha1 * ( gammaDot * da_ ) * ( gammaDot * da_ ) // / sqrt( max(alphac_ - alpha_, constSMALL) ); volScalarField ThetaDense_ = const_alpha1 * ( gammaDot * da_ ) * ( gammaDot * da_ ) / sqrt( max(alphac_ - alpha_, alphad_) ) + max(alpha_ - (alphac_ - alphad_),0.0) * 0.5 *const_alpha1*( gammaDot * da_ ) * ( gammaDot * da_)*pow(alphad_,-1.5); // Theta Theta_ = max(ThetaDil_,ThetaDense_) ; if(testMKTimp || diluteCorrection) Theta_ = ThetaDil_; if(denseCorrection) Theta_ = ThetaDense_; // Limit granular temperature Theta_.max(1.0e-15); Theta_.min(1.0e+3); // Particle pressure pa_ = PsCoeff * Theta_; if(frictionBlending) { /* volScalarField pf = frictionalStressModel_->frictionalPressure ( alpha_, alphaMinFriction_-0.001, alphaMax_, Fr_, eta_, p_ ); pa_ = pa_ + pf; */ // pa_ =pa_ + dimensionedScalar("1e24", dimensionSet(1, -1, -2, 0, 0), Fr_.value())*pow(max(alpha_ - (alphaMinFriction_), scalar(0)), 2/3); pa_ =pa_ + dimensionedScalar("5810", dimensionSet(1, 0, -2, 0, 0), 581.0)/da_*pow(max(alpha_ - (alphaMinFriction_-0.0), scalar(0)), 2.0/3.0); // pa_ =pa_ + dimensionedScalar("4.7e9", dimensionSet(1, -1, -2, 0, 0), 4.7e9)*pow(max(alpha_ - (alphaMinFriction_-0.0), scalar(0)), 1.56); // forAll(alpha_, cellI) // { // if(alpha_[cellI] >= (alphaMinFriction_.value()-0.00001)) // { // pa_[cellI] = pa_[cellI] + 581.0/da_.value()*pow(alpha_[cellI] - (alphaMinFriction_.value()-0.00001), 2.0/3.0); // } // } } // Psi Eq.32, p.12 dimensionedScalar psi(1.0 + 3.0/10.0*pow((1.0-e_*e_),-1.5)*(1.0-exp(-8.0*muFric_))); if(testMKTimp) psi = 1.0; // Shear stress ratio in dilute regime, Eq.33, p.12 dimensionedScalar paSmall("paSmall",dimensionSet(1, -1, -2, 0, 0), constSMALL); volScalarField inertiaNumber( gammaDot * da_ / sqrt( (pa_ + paSmall) / rhoa_ ) ); // Modified inertia number Eq.35, p.13 volScalarField modInertiaNumber( inertiaNumber / max( alpha_, constSMALL ) ); // Model parameters volScalarField chi( 1.0 / ( pow( I0 / max( modInertiaNumber,constSMALL ) , 1.5 ) + 1.0 )); if(testMKTimp || diluteCorrection) chi = max( modInertiaNumber,constSMALL ) / max( modInertiaNumber,constSMALL ) ; if(denseCorrection) chi= modInertiaNumber - modInertiaNumber; // Beta + Sigma_tau Eq.49 p.14 volScalarField beta(alpha_ * psi * J_ * sqrt( K_ /( max ( (Kmod_ * ( PsCoeff / rhoa_)), constSMALL ) ) ) ); volScalarField sigmaTau( const_alpha / max( beta, constSMALL ) + ( 1 - const_alpha / max( beta, constSMALL ) ) * chi); // Sigma_gamma Eq.51 p.14 volScalarField sigmaGamma( beta * sqrt( PsCoeff/rhoa_ ) / max( ( Kmod_ * M_ ), constSMALL ) * sigmaTau); // dissipation volScalarField gammaCoeff ( // van Wachem (Eq. 3.24, p.50) 12.0*(1.0 - sqr(e_))*sqr(alpha_)*rhoa_*gs0_*(1.0/da_)*ThetaSqrt/sqrtPi // Chialvo & Sundaresan Eq.50 p.14 //rhoa_ / da_ * Kmod_ * Theta_ * sqrt(Theta_) * sigmaGamma rhoa_ / da_ * Kmod_ * sqrt(Theta_) * sigmaGamma ); // Blending function volScalarField func_B( const_alpha + ( beta-const_alpha ) * chi ); // Shear stress ratio upsilon_ = upsilons_ * (1 - chi) + func_B * modInertiaNumber; // Shear stress volSymmTensorField S( D - 1./3.*tr(D)*I ); volSymmTensorField hatS( 2. * S / max( gammaDot, gammaDotSmall ) ); // Shear stress based on pressure and ratio tau_ = pa_ * upsilon_ * hatS; // Viscosity mua_ = ( pa_ * upsilon_ ) / (max( gammaDot, gammaDotSmall )) ; // Divide by alpha (to be consistent with OpenFOAM implementation) /* mua_ /= (fvc::average(alpha_) + scalar(0.001)); tau_ /= (fvc::average(alpha_) + scalar(0.001)); lambda_ /= (fvc::average(alpha_) + scalar(0.001)); */ mua_ /= max(alpha_, scalar(constSMALL)); // Limit mua mua_.min(3e+02); mua_.max(0.0); // Limit lambda lambda_ = mua_ * ratioBulkShearVisc; // Limit shear stress tau_ = mua_ * gammaDot * hatS; // tau_ /= max(alpha_, scalar(constSMALL)); // lambda_ /= max(alpha_, scalar(constSMALL)); //mua_ /= max(alpha_, scalar(constSMALL)); //tau_ /= max(alpha_, scalar(constSMALL)); //lambda_ /= max(alpha_, scalar(constSMALL)); if(verboseMKT) { #include "verboseMKT.H" } //-AO, YG - Decompose particle pressure, Sundar's idea if(decomposePp_) { pa_ /= (fvc::average(alpha_) + scalar(0.001)); //pa_.correctBoundaryConditions(); pa_.max(1.0e-15); } } else { return; } }
int test() { std::vector<std::string> neutrals; std::vector<std::string> ions; neutrals.push_back("N2"); neutrals.push_back("CH4"); ions.push_back("N2+"); ions.push_back("e"); Scalar chi(100.L); std::vector<Scalar> lambda_ref,phy1AU,phy_on_top; std::ifstream flux_1AU("./input/hv_SSI.dat"); std::string line; getline(flux_1AU,line); while(!flux_1AU.eof()) { Scalar wv,ir,dirr; flux_1AU >> wv >> ir >> dirr; if(!lambda_ref.empty() && wv == lambda_ref.back())continue; lambda_ref.push_back(wv);//nm phy1AU.push_back(ir);//W/m2/nm phy_on_top.push_back(ir/std::pow(Planet::Constants::Saturn::d_Sun<Scalar>(),2)); } flux_1AU.close(); Planet::Chapman<Scalar> chapman(chi); Planet::PhotonFlux<Scalar,std::vector<Scalar>, std::vector<std::vector<Scalar> > > photon(chapman); photon.set_photon_flux_top_atmosphere(lambda_ref,phy1AU,Planet::Constants::Saturn::d_Sun<Scalar>()); std::vector<Scalar> molar_frac = {0.96,0.04,0.,0.}; Scalar dens_tot(1e12); Planet::Atmosphere<Scalar, std::vector<Scalar>, std::vector<std::vector<Scalar> > > atm(neutrals,ions,photon); atm.make_altitude_grid(600.,1400.,10.); std::ifstream temp("input/temperature.dat"); std::vector<Scalar> T0,Tz; getline(temp,line); while(!temp.eof()) { Scalar t,tz,dt,dtz; temp >> t >> tz >> dt >> dtz; T0.push_back(t); Tz.push_back(tz); } temp.close(); atm.set_temperature(T0,Tz); std::vector<Scalar> T = atm.temperature_top_to_bottom(); std::vector<std::vector<Scalar> > MatrixTotalDensity; std::vector<Scalar> tot_dens = atm.total_density_top_to_bottom(); std::vector<Scalar> lambda_N2,sigma_N2; std::vector<std::vector<Scalar> > sigma_rate_N2; sigma_rate_N2.resize(3); std::ifstream sig_N2("./input/N2_hv_cross-sections.dat"); std::ifstream sig_CH4("./input/CH4_hv_cross-sections.dat"); getline(sig_N2,line); getline(sig_CH4,line); while(!sig_N2.eof()) { Scalar wv,sigt,sig1,sig2,sig3; sig_N2 >> wv >> sigt >> sig1 >> sig2 >> sig3; lambda_N2.push_back(wv/10.);//A -> nm sigma_N2.push_back(sigt*10.);//cm-2/A -> cm-2/nm sigma_rate_N2[0].push_back(sig1*10.); sigma_rate_N2[1].push_back(sig2*10.); sigma_rate_N2[2].push_back(sig3*10.); } sig_N2.close(); atm.add_photoabsorption("N2",lambda_N2,sigma_N2); std::vector<Scalar> lambda_CH4,sigma_CH4; std::vector<std::vector<Scalar> > sigma_rate_CH4; sigma_rate_CH4.resize(9); while(!sig_CH4.eof()) { Scalar wv,sigt,sig1,sig2,sig3,sig4,sig5,sig6,sig7,sig8,sig9; sig_CH4 >> wv >> sigt >> sig1 >> sig2 >> sig3 >> sig4 >> sig5 >> sig6 >> sig7 >> sig8 >> sig9; lambda_CH4.push_back(wv/10.);//A -> nm sigma_CH4.push_back(sigt*10.);//cm-2/A -> cm-2/nm sigma_rate_CH4[0].push_back(sig1*10.); sigma_rate_CH4[1].push_back(sig2*10.); sigma_rate_CH4[2].push_back(sig3*10.); sigma_rate_CH4[3].push_back(sig4*10.); sigma_rate_CH4[4].push_back(sig5*10.); sigma_rate_CH4[5].push_back(sig6*10.); sigma_rate_CH4[6].push_back(sig7*10.); sigma_rate_CH4[7].push_back(sig8*10.); sigma_rate_CH4[8].push_back(sig9*10.); } sig_CH4.close(); atm.add_photoabsorption("CH4",lambda_CH4,sigma_CH4); atm.init_composition(molar_frac,dens_tot); int return_flag(0); //Phy at top std::vector<Scalar> phy_top; phy_top.resize(lambda_ref.size(),0.L); for(unsigned int il = 0; il < lambda_ref.size(); il++) { phy_top[il] = phy1AU[il]/(Planet::Constants::Saturn::d_Sun<Scalar>() * Planet::Constants::Saturn::d_Sun<Scalar>()); if(check_test(phy_top[il],photon.phy_at_top()[il],"Photon flux at top"))return_flag = 1; } std::ofstream out("phy_z.dat"); std::ofstream out_the("phy_z_the.dat"); out_the << "z N_N N+_N N2+ sCH2_H2 CH3_H CH2_H_H CH4+ CH3+_H CH2+_H2 CH+_H2_H H+_CH3 CH_H2_H" << std::endl; std::vector<Scalar> lamb = atm.hv_flux().lambda(); std::vector<Scalar> sum_over_neutral; sum_over_neutral.resize(2,0.L); std::vector<Scalar> tau_theo; std::vector<Scalar> rate_N2,rate_CH4; rate_N2.resize(3); rate_CH4.resize(9); Scalar MN(14.008L), MC(12.011), MH(1.008L); Scalar MN2 = 2.L*MN , MCH4 = MC + 4.L*MH; unsigned int ialt(0); for(Scalar z = 1400.; z >= 600.; z -= 10.) { Scalar M_the = molar_frac[0] * MN2 + molar_frac[1] * MCH4; Scalar n_tot_the = dens_tot * std::exp(-(z - 600.) / ( (z + Planet::Constants::Titan::radius<Scalar>()) * (600. + Planet::Constants::Titan::radius<Scalar>()) * 1e3L * //to m ( (Planet::Constants::Universal::kb<Scalar>() * Antioch::Constants::Avogadro<Scalar>() * T[ialt]) / (Planet::Constants::Universal::G<Scalar>() * Planet::Constants::Titan::mass<Scalar>() * M_the * 1e-3L) //to kg/mol ) )); tau_theo.clear(); tau_theo.resize(lambda_ref.size(),0.L); for(unsigned int i = 0; i < 2; i++) { sum_over_neutral[i] += molar_frac[i] * n_tot_the; for(unsigned int il = 0; il < lambda_ref.size(); il++) { tau_theo[il] += sum_over_neutral[i] * atm.photon_sigma(i).y_on_custom()[il]; //filtering } } std::vector<Scalar> tau_cal = photon.tau(z,sum_over_neutral); for(unsigned int il = 0; il < lambda_ref.size(); il++) { tau_theo[il] *= chapman.chapman(atm.a(z)); if(check_test(tau_theo[il],tau_cal[il],"tau at altitude z"))return_flag = 1; } for(unsigned int ir = 0; ir < 3; ir++) { rate_N2[ir] = 0.L; for(unsigned int il = 0; il < lamb.size(); il++) { rate_N2[ir] += sigma_rate_N2[ir][il] * phy_on_top[il] * std::exp(-tau_theo[il]); } } for(unsigned int ir = 0; ir < 9; ir++) { rate_CH4[ir] = 0.L; for(unsigned int il = 0; il < lamb.size(); il++) { rate_CH4[ir] += sigma_rate_CH4[ir][il] * phy_on_top[il] * std::exp(-tau_theo[il]); } } std::vector<Scalar> phy_flux = atm.hv_flux().phy(z); for(unsigned int il = 0; il < phy_flux.size(); il++) { if(check_test(phy_on_top[il] * std::exp(-tau_theo[il]),phy_flux[il],"phy at altitude z and lambda"))return_flag = 1; out << lamb[il] << " " << phy_flux[il] << std::endl; } out_the << z << " "; for(unsigned int ir = 0; ir < 3; ir++) { out_the << rate_N2[ir] << " "; } for(unsigned int ir = 0; ir < 9; ir++) { out_the << rate_CH4[ir] << " "; } out_the << std::endl; out << std::endl; ialt++; } out.close(); out_the.close(); return return_flag; }
//********************************************************************** Element_Linear2D::Element_Linear2D(std::vector<size_type> global_node_ids, size_type global_element_index, size_type local_element_index, std::vector<double> x_node_coords, std::vector<double> y_node_coords) : m_global_element_index(global_element_index), m_local_element_index(local_element_index), m_global_node_ids(global_node_ids), m_owns_node(4, false), m_coords_mem(Teuchos::arcp<double>(4*2)), m_phi_mem(Teuchos::arcp<double>(4*4)), m_grad_phi_mem(Teuchos::arcp<double>(4*4*2)), m_grad_phi_xy_mem(Teuchos::arcp<double>(4*4*2)), m_det_jacobian_mem(Teuchos::arcp<double>(4)), m_weights_mem(Teuchos::arcp<double>(4)), m_coords(&(m_coords_mem[0]),4,2), m_phi(&(m_phi_mem[0]),4,4), m_grad_phi(&(m_grad_phi_mem[0]),4,4,2), m_grad_phi_xy(&(m_grad_phi_xy_mem[0]),4,4,2), m_det_jacobian(&(m_det_jacobian_mem[0]),4), m_weights(&(m_weights_mem[0]),4) { // Set node coordinatates m_coords(0,0) = x_node_coords[0]; m_coords(0,1) = y_node_coords[0]; m_coords(1,0) = x_node_coords[1]; m_coords(1,1) = y_node_coords[1]; m_coords(2,0) = x_node_coords[2]; m_coords(2,1) = y_node_coords[2]; m_coords(3,0) = x_node_coords[3]; m_coords(3,1) = y_node_coords[3]; // Quadrature rule defines number of quadrature points - 4 std::vector<double> chi(4); std::vector<double> eta(4); chi[0] = -1.0 / std::sqrt(3); chi[1] = 1.0 / std::sqrt(3); chi[2] = 1.0 / std::sqrt(3); chi[3] = -1.0 / std::sqrt(3); eta[0] = -1.0 / std::sqrt(3); eta[1] = -1.0 / std::sqrt(3); eta[2] = 1.0 / std::sqrt(3); eta[3] = 1.0 / std::sqrt(3); m_weights[0] = 1.0; m_weights[1] = 1.0; m_weights[2] = 1.0; m_weights[3] = 1.0; for (size_type qp=0; qp < this->numQuadraturePoints(); ++qp) { // Phi shards::Array<double,shards::NaturalOrder,Node> phi_qp = m_phi.truncate(qp); evaluatePhi(chi[qp], eta[qp], phi_qp); // Grad Phi in local element coordinates shards::Array<double,shards::NaturalOrder,Node,Dim> grad_phi_qp = m_grad_phi.truncate(qp); evaluateGradPhi(chi[qp], eta[qp], grad_phi_qp); // Determinant of Jacobian and basis function gradients in // real space shards::Array<double,shards::NaturalOrder,Node,Dim> grad_phi_xy_qp = m_grad_phi_xy.truncate(qp); evaluateDetJacobianAndGradients(chi[qp], eta[qp], m_det_jacobian(qp), grad_phi_qp, grad_phi_xy_qp); } // for (std::size_t i=0; i < m_grad_phi_xy.size(); ++i) // m_grad_phi_xy[i] = 0.0; // for (std::size_t qp=0; qp < this->numQuadraturePoints(); ++qp) // for (std::size_t node=0; node < this->numNodes(); ++node) // for (std::size_t dim=0; dim < 2; ++dim) // m_grad_phi_xy(qp,node,dim) = // (1.0 / m_det_jacobian(qp)) * m_grad_phi(qp,node,dim); }
int jitter (double *resi, double *e, double *stdy, double psrfreq, int nint, int nphase, double degree, FILE *fp) // calculate the jitter parameter and its error { //puts (argv[1]); //puts (argv[2]); //int nint=0; //int nsample=0; //double resi[64],e[64]; //double x[1024],y[1024]; //read (argv[1], &nint, resi, e); //read (argv[2], &nsample, x, y); //printf("Number of subint is: %d \n", nint); ///////////////////////////////////////////////////////////////////////////////// // calculate jitter parameter double k; //k=nint-10.0; k = degree; double reduced_chi; double sigma_J; reduced_chi = 1.0; // initial guess of the result ///////////////////////////////////////////////////////////////////// double up = 1.0e-5; double step = up/100.0; double low = 1.0e-5; while( chi(up, k, nint, resi, e, reduced_chi)*chi(low, k, nint, resi, e, reduced_chi) > 0 ) { low = low - step; } ///////////////////////////////////////////////////////////////////// sigma_J = zbrent(chi, low, up, 1.0e-16, k, nint, resi, e, reduced_chi); printf("low: %e \n", low); printf("sigma_J: %e \n", sigma_J); printf("reduced_chisqr: %e \n", chi(sigma_J, k, nint, resi, e, reduced_chi)); //////////////////////////////////////////////////////////////////////////////// double U; U = u_0(stdy, nphase, psrfreq); /////////////////////////////////////////////////////////////////////////////// double jitter; //double N=floor(60*173.687946184761); //jitter=sqrt(N)*sigma_J/U; jitter = sigma_J/sqrt(U); printf ("jitter parameter is: %f\n", jitter); //printf ("jitter parameter is: %f\n", sqrt(N)*sigma_J/0.14e-3); //printf ("jitter parameter is: %f\n", sqrt(N)*sigma_J/1.02e-3); ////////////////////////////////////////////////////////////////////////////////// // calculte the error of jitter parameter struct my_params params; double chisqr_new; Gamma_cal(k, ¶ms); // initial guess of the result ///////////////////////////////////////////////////////////////////// double up_e = k+10; double step_e = up_e/100.0; double low_e = up_e; //printf ("%lf %lf\n", low_e, up_e); while( error(up_e, ¶ms, 500000)*error(low_e, ¶ms, 500000) > 0 ) { low_e = low_e - step_e; } //printf ("%lf %lf\n", low_e, up_e); ///////////////////////////////////////////////////////////////////// //chisqr_new = zbrent_err(error, low_e-10.0, up_e+10.0, 1.0e-16, ¶ms); // get the 1 sigma chisqr chisqr_new = zbrent_err(error, low_e, up_e, 1.0e-16, ¶ms, 500000); // get the 1 sigma chisqr reduced_chi = chisqr_new/k; printf ("chisqr_new: %lf\n", chisqr_new); ///////////////////////////////////////////////////////////////////// // initial guess of the result ///////////////////////////////////////////////////////////////////// up = 1.0e-6; step = up/100.0; low = 1.0e-6; while( chi(up, k, nint, resi, e, reduced_chi)*chi(low, k, nint, resi, e, reduced_chi) > 0 ) { low = low - step; } ///////////////////////////////////////////////////////////////////// double sigma_J_error, jitter_error; //sigma_J_error = zbrent(chi, 1e-7, 1e-5, 1.0e-16, k, nint, resi, e, reduced_chi); // for 1 sigma reduced_chi, get the sigma_J sigma_J_error = zbrent(chi, low, up, 1.0e-16, k, nint, resi, e, reduced_chi); // for 1 sigma reduced_chi, get the sigma_J jitter_error = fabs(sigma_J_error/sqrt(U)-jitter); printf ("The error of jitter parameter is: %f\n", jitter_error); // print out the results fprintf (fp, "%lf %lf\n", jitter, jitter_error); return 0; }
//STARTBDRYRESIDUALS PetscErrorCode FormFunction(SNES snes, Vec u, Vec F, void *ctx) { PetscErrorCode ierr; unfemCtx *user = (unfemCtx*)ctx; const int *abfn, *ae, *as, *abfs, *en, deg = user->quaddeg - 1; const Node *aloc; const double *au; double *aF, unode[3], gradu[2], gradpsi[3][2], uquad[4], aquad[4], fquad[4], dx, dy, dx1, dx2, dy1, dy2, detJ, ls, xmid, ymid, sint, xx, yy, sum; int n, p, na, nb, k, l, q; PetscLogStagePush(user->resstage); //STRIP ierr = VecGetArrayRead(u,&au); CHKERRQ(ierr); ierr = VecSet(F,0.0); CHKERRQ(ierr); ierr = VecGetArray(F,&aF); CHKERRQ(ierr); ierr = UMGetNodeCoordArrayRead(user->mesh,&aloc); CHKERRQ(ierr); // Dirichlet node residuals ierr = ISGetIndices(user->mesh->bfn,&abfn); CHKERRQ(ierr); for (n = 0; n < user->mesh->N; n++) { if (abfn[n] == 2) // node is Dirichlet aF[n] = au[n] - user->gD_fcn(aloc[n].x,aloc[n].y); } // Neumann segment contributions ierr = ISGetIndices(user->mesh->s,&as); CHKERRQ(ierr); ierr = ISGetIndices(user->mesh->bfs,&abfs); CHKERRQ(ierr); for (p = 0; p < user->mesh->P; p++) { if (abfs[p] == 1) { // segment is Neumann na = as[2*p+0]; // nodes at end of segment nb = as[2*p+1]; // length of segment dx = aloc[na].x-aloc[nb].x; dy = aloc[na].y-aloc[nb].y; ls = sqrt(dx * dx + dy * dy); // midpoint rule; psi_na=psi_nb=0.5 at midpoint of segment xmid = 0.5*(aloc[na].x+aloc[nb].x); ymid = 0.5*(aloc[na].y+aloc[nb].y); sint = 0.5 * user->gN_fcn(xmid,ymid) * ls; // nodes at end of segment could be Dirichlet if (abfn[na] != 2) aF[na] -= sint; if (abfn[nb] != 2) aF[nb] -= sint; } } ierr = ISRestoreIndices(user->mesh->s,&as); CHKERRQ(ierr); ierr = ISRestoreIndices(user->mesh->bfs,&abfs); CHKERRQ(ierr); //ENDBDRYRESIDUALS //STARTELEMENTRESIDUALS // element contributions ierr = ISGetIndices(user->mesh->e,&ae); CHKERRQ(ierr); for (k = 0; k < user->mesh->K; k++) { en = ae + 3*k; // en[0], en[1], en[2] are nodes of element k // geometry of element dx1 = aloc[en[1]].x - aloc[en[0]].x; dx2 = aloc[en[2]].x - aloc[en[0]].x; dy1 = aloc[en[1]].y - aloc[en[0]].y; dy2 = aloc[en[2]].y - aloc[en[0]].y; detJ = dx1 * dy2 - dx2 * dy1; // gradients of hat functions for (l = 0; l < 3; l++) { gradpsi[l][0] = ( dy2 * dchi[l][0] - dy1 * dchi[l][1]) / detJ; gradpsi[l][1] = (-dx2 * dchi[l][0] + dx1 * dchi[l][1]) / detJ; } // u and grad u on element gradu[0] = 0.0; gradu[1] = 0.0; for (l = 0; l < 3; l++) { if (abfn[en[l]] == 2) unode[l] = user->gD_fcn(aloc[en[l]].x,aloc[en[l]].y); else unode[l] = au[en[l]]; gradu[0] += unode[l] * gradpsi[l][0]; gradu[1] += unode[l] * gradpsi[l][1]; } // function values at quadrature points on element for (q = 0; q < Q[deg]; q++) { uquad[q] = eval(unode,xi[deg][q],eta[deg][q]); xx = aloc[en[0]].x + dx1 * xi[deg][q] + dx2 * eta[deg][q]; yy = aloc[en[0]].y + dy1 * xi[deg][q] + dy2 * eta[deg][q]; aquad[q] = user->a_fcn(uquad[q],xx,yy); fquad[q] = user->f_fcn(uquad[q],xx,yy); } // residual contribution for each node of element for (l = 0; l < 3; l++) { if (abfn[en[l]] < 2) { // if NOT a Dirichlet node sum = 0.0; for (q = 0; q < Q[deg]; q++) sum += w[deg][q] * ( aquad[q] * InnerProd(gradu,gradpsi[l]) - fquad[q] * chi(l,xi[deg][q],eta[deg][q]) ); aF[en[l]] += fabs(detJ) * sum; } } } ierr = ISRestoreIndices(user->mesh->e,&ae); CHKERRQ(ierr); ierr = ISRestoreIndices(user->mesh->bfn,&abfn); CHKERRQ(ierr); ierr = UMRestoreNodeCoordArrayRead(user->mesh,&aloc); CHKERRQ(ierr); ierr = VecRestoreArrayRead(u,&au); CHKERRQ(ierr); ierr = VecRestoreArray(F,&aF); CHKERRQ(ierr); PetscLogStagePop(); //STRIP return 0; }
ScalarFieldTilde SaLSA::hessian(const ScalarFieldTilde& phiTilde) const { return (-1./(4*M_PI*gInfo.detR)) * L(phiTilde) - chi(phiTilde); }
// For lots of subsets of size nwhich, compute the exact fit to those data // points and the residuals from all the data points. // copied with modification from MASS/src/lqs.c // Copyright (C) 1998-2007 B. D. Ripley // Copyright (C) 1999 R Development Core Team // TODO: rewrite void LQSEstimator::operator()(const Data& data, double* coef_ptr, double* fitted_ptr, double* resid_ptr, double* scale_ptr) { int nnew = nwhich, pp = p; int i, iter, nn = n, trial; int rank, info, n100 = 100; int firsttrial = 1; double a = 0.0, tol = 1.0e-7, sum, thiscrit, best = DBL_MAX, target, old, newp, dummy, k0 = pk0; const arma::vec& y = data.y; const arma::mat& x = data.x; double coef[p]; arma::vec coef_vec(coef, p, false, true); double qraux[p]; double work[2*p]; double res[n]; arma::vec res_vec(res, n, false, true); double yr[nwhich]; double xr[nwhich * p]; arma::vec yr_vec(yr, nwhich, false, true); arma::mat xr_mat(xr, nwhich, p, false, true); double bestcoef[p]; int pivot[p]; arma::uvec which_vec(nwhich); //int bestone[nwhich]; target = (nn - pp)* (beta); for(trial = 0; trial < ntrials; trial++) { R_CheckUserInterrupt(); // get this trial's subset which_vec = indices.col(trial); yr_vec = y.elem(which_vec); xr_mat = x.rows(which_vec); /* compute fit, find residuals */ F77_CALL(dqrdc2)(xr, &nnew, &nnew, &pp, &tol, &rank, qraux, pivot, work); if(rank < pp) { sing++; continue; } F77_CALL(dqrsl)(xr, &nnew, &nnew, &rank, qraux, yr, &dummy, yr, coef, &dummy, &dummy, &n100, &info); res_vec = y - x * coef_vec; /* S estimation */ if(firsttrial) { for(i = 0; i < nn; i ++) res[i] = fabs(res[i]); rPsort(res, nn, nn/2); old = res[nn/2]/0.6745; /* MAD provides the initial scale */ firsttrial = 0; } else { /* only find optimal scale if it will be better than existing best solution */ sum = 0.0; for(i = 0; i < nn; i ++) sum += chi(res[i], k0 * best); if(sum > target) continue; old = best; } /* now solve for scale S by re-substitution */ for(iter = 0; iter < 30; iter++) { /*printf("iter %d, s = %f sum = %f %f\n", iter, old, sum, target);*/ sum = 0.0; for(i = 0; i < nn; i ++) sum += chi(res[i], k0 * old); newp = sqrt(sum/target) * old; if(fabs(sum/target - 1.) < 1e-4) break; old = newp; } thiscrit = newp; /* first trial might be singular, so use fence */ if(thiscrit < best) { sum = 0.0; for(i = 0; i < nn; i ++) sum += chi(res[i], k0 * best); best = thiscrit; for(i = 0; i < pp; i++) bestcoef[i] = coef[i]; bestcoef[0] += a; } } /* for(trial in 0:ntrials) */ crit = (best < 0.0) ? 0.0 : best; if(sample) PutRNGstate(); /* lqs_free(); */ // output arma::vec coef_out(coef_ptr, p, false, true); arma::vec fitted_out(fitted_ptr, n, false, true); arma::vec resid_out(resid_ptr, n, false, true); arma::vec scale_out(scale_ptr, 1, false, true); for (i = 0; i < p; i++) coef_out[i] = bestcoef[i]; fitted_out = x * coef_out; resid_out = y - fitted_out; scale_out = crit; }
//! \return whether partial charges were successfully assigned to this molecule bool EQEqCharges::ComputeCharges(OBMol &mol) { int i, j, a, c, N = mol.NumAtoms(); double cellVolume; VectorXf chi(N), J(N), b(N), x(N); MatrixXf J_ij(N, N), A(N, N); OBUnitCell *obuc; matrix3x3 unitcell, fourier; vector3 dx; int numNeighbors[3]; OBAtom *atom; // If parameters have not yet been loaded, do that if (!_paramFileLoaded) { if (ParseParamFile()) { _paramFileLoaded = true; } else { return false; } } // Calculate atomic properties based around their ionic charge for (i = 0; i < N; i++) { atom = mol.GetAtom(i + 1); a = atom->GetAtomicNum(); c = _chargeCenter[a]; // Fail if ionization data is missing for any atom in the molecule if (_ionizations[a][c + 1] == -1 || _ionizations[a][c] == -1 || a > TABLE_OF_ELEMENTS_SIZE) { obErrorLog.ThrowError(__FUNCTION__, "Insufficient ionization data for atoms in the given molecule. Update `data/eqeqIonizations.txt` with missing information and re-run this function.", obError); return false; } J(i) = _ionizations[a][c + 1] - _ionizations[a][c]; chi(i) = 0.5 * (_ionizations[a][c + 1] + _ionizations[a][c]) - (a == 1? 0 : c * J(i)); } // If a unit cell is defined, use the periodic Ewald calculation if (mol.HasData(OBGenericDataType::UnitCell)) { // Get unit cell and calculate its Fourier transform + volume obuc = (OBUnitCell *) mol.GetData(OBGenericDataType::UnitCell); unitcell = obuc->GetCellMatrix(); fourier = (2 * PI * unitcell.inverse()).transpose(); cellVolume = obuc->GetCellVolume(); // Get the number of radial unit cells to use in x, y, and z numNeighbors[0] = int(ceil(minCellLength / (2.0 * (obuc->GetA())))) - 1; numNeighbors[1] = int(ceil(minCellLength / (2.0 * (obuc->GetB())))) - 1; numNeighbors[2] = int(ceil(minCellLength / (2.0 * (obuc->GetC())))) - 1; for (i = 0; i < N; i++) { atom = mol.GetAtom(i + 1); for (j = 0; j < N; j++) { dx = atom->GetVector() - (mol.GetAtom(j + 1))->GetVector(); J_ij(i, j) = GetPeriodicEwaldJij(J(i), J(j), dx, (i == j), unitcell, fourier, cellVolume, numNeighbors); } } // If no unit cell, use the simplified nonperiodic calculation } else { for (i = 0; i < N; i++) { atom = mol.GetAtom(i + 1); for (j = 0; j < N; j++) { J_ij(i, j) = GetNonperiodicJij(J(i), J(j), atom->GetDistance(j + 1), (i == j)); } return false; } } // Formulate problem as A x = b, where x is the calculated partial charges // First equation is a simple overall balance: sum(Q) = 0 A.row(0) = VectorXf::Ones(N); b(0) = 0; // Remaining equations are based off of the fact that, at equilibrium, the // energy of the system changes equally for a change in any charge: // dE/dQ_1 = dE/dQ_2 = ... = dE/dQ_N A.block(1, 0, N - 1, N) = J_ij.block(0, 0, N - 1, N) - J_ij.block(1, 0, N - 1, N); b.tail(N - 1) = chi.tail(N - 1) - chi.head(N - 1); // The solution is a list of charges in the system x = A.colPivHouseholderQr().solve(b); // Now we are done calculating, pass all this back to OpenBabel molecule mol.SetPartialChargesPerceived(); OBPairData *dp = new OBPairData; dp->SetAttribute("PartialCharges"); dp->SetValue("EQEq"); dp->SetOrigin(perceived); mol.SetData(dp); m_partialCharges.clear(); m_partialCharges.reserve(N); m_formalCharges.clear(); m_formalCharges.reserve(N); for (i = 0; i < N; i ++) { atom = mol.GetAtom(i + 1); atom->SetPartialCharge(x(i)); m_partialCharges.push_back(x(i)); m_formalCharges.push_back(atom->GetFormalCharge()); } obErrorLog.ThrowError(__FUNCTION__, "EQEq charges successfully assigned.", obInfo); return true; }
int test() { std::vector<std::string> neutrals; std::vector<std::string> ions; neutrals.push_back("N2"); neutrals.push_back("CH4"); ions.push_back("N2+"); ions.push_back("e"); //photons std::vector<Scalar> lambda,phy1AU; read_hv_flux<Scalar>(lambda,phy1AU,"./input/hv_SSI.dat"); Scalar chi(100.); Planet::Chapman<Scalar> chapman(chi); Planet::PhotonFlux<Scalar,std::vector<Scalar>, std::vector<std::vector<Scalar> > > photon(chapman); photon.set_photon_flux_top_atmosphere(lambda,phy1AU,Planet::Constants::Saturn::d_Sun<Scalar>()); //densities std::vector<Scalar> molar_frac = {0.96,0.04,0.,0.}; Scalar dens_tot(1e12); //diffusion Planet::BinaryDiffusion<Scalar> N2N2( Antioch::Species::N2, Antioch::Species::N2 , 5.09e+16,0.81, Planet::DiffusionType::Massman); Planet::BinaryDiffusion<Scalar> N2CH4( Antioch::Species::N2, Antioch::Species::CH4, 7.34e+16,0.75, Planet::DiffusionType::Massman); Planet::BinaryDiffusion<Scalar> CH4CH4( Antioch::Species::CH4, Antioch::Species::CH4, 5.73e+16,0.50, Planet::DiffusionType::Massman); //atmosphere Planet::Atmosphere<Scalar, std::vector<Scalar>, std::vector<std::vector<Scalar> > > atm(neutrals,ions,photon); atm.make_altitude_grid(600.,1400.,10.); //temperature std::vector<Scalar> T0,Tz; read_temperature<Scalar>(T0,Tz,"input/temperature.dat"); atm.set_temperature(T0,Tz); //cross-section std::vector<Scalar> sigma; read_crossSection<Scalar>(lambda,sigma,"./input/N2_hv_cross-sections.dat",3); atm.add_photoabsorption("N2",lambda,sigma); read_crossSection<Scalar>(lambda,sigma,"./input/CH4_hv_cross-sections.dat",9); atm.add_photoabsorption("N2",lambda,sigma); atm.add_photoabsorption("CH4",lambda,sigma); //init compo atm.init_composition(molar_frac,dens_tot); //diffusion atm.diffusion().set_binary_coefficient(0,0,N2N2); atm.diffusion().set_binary_coefficient(0,1,N2CH4); atm.diffusion().set_binary_coefficient(1,1,CH4CH4); atm.make_diffusion(); //thermal coefficient Scalar K0(4.3e6L); atm.set_K0(K0); atm.make_thermal_coefficient(); //solver Planet::CrankNicholson<Scalar,std::vector<Scalar>, std::vector<std::vector<Scalar> > > solver; int return_flag(0); return return_flag; }