📄 cic.pro
字号:
FUNCTION cic,value,posx,nx,posy,ny,posz,nz, $ AVERAGE=average,WRAPAROUND=wraparound,ISOLATED=isolated, $ NO_MESSAGE=no_message;+; NAME:; CIC;; PURPOSE:; Interpolate an irregularly sampled field using Cloud in Cell method;; EXPLANATION:; This function interpolates an irregularly sampled field to a; regular grid using Cloud In Cell (nearest grid point gets; weight 1-dngp, point on other side gets weight dngp, where; dngp is the distance to the nearest grid point in units of the; cell size).;; CATEGORY:; Mathematical functions, Interpolation;; CALLING SEQUENCE:; Result = CIC, VALUE, POSX, NX[, POSY, NY, POSZ, NZ, ; AVERAGE = average, WRAPAROUND = wraparound,; ISOLATED = isolated, NO_MESSAGE = no_message];; INPUTS:; VALUE: Array of sample weights (field values). For e.g. a; temperature field this would be the temperature and the; keyword AVERAGE should be set. For e.g. a density field; this could be either the particle mass (AVERAGE should; not be set) or the density (AVERAGE should be set).; POSX: Array of X coordinates of field samples, unit indices: [0,NX>.; NX: Desired number of grid points in X-direction.; ; OPTIONAL INPUTS:; POSY: Array of Y coordinates of field samples, unit indices: [0,NY>.; NY: Desired number of grid points in Y-direction.; POSZ: Array of Z coordinates of field samples, unit indices: [0,NZ>.; NZ: Desired number of grid points in Z-direction.;; KEYWORD PARAMETERS:; AVERAGE: Set this keyword if the nodes contain field samples; (e.g. a temperature field). The value at each grid; point will then be the weighted average of all the; samples allocated to it. If this keyword is not; set, the value at each grid point will be the; weighted sum of all the nodes allocated to it; (e.g. for a density field from a distribution of; particles). (D=0). ; WRAPAROUND: Set this keyword if you want the first grid point; to contain samples of both sides of the volume; (see below).; ISOLATED: Set this keyword if the data is isolated, i.e. not; periodic. In that case total `mass' is not conserved.; This keyword cannot be used in combination with the; keyword WRAPAROUND.; NO_MESSAGE: Suppress informational messages.;; Example of default allocation of nearest grid points: n0=4, *=gridpoint.;; 0 1 2 3 Index of gridpoints; * * * * Grid points; |---|---|---|---| Range allocated to gridpoints ([0.0,1.0> --> 0, etc.); 0 1 2 3 4 posx;; Example of ngp allocation for WRAPAROUND: n0=4, *=gridpoint.;; 0 1 2 3 Index of gridpoints; * * * * Grid points; |---|---|---|---|-- Range allocated to gridpoints ([0.5,1.5> --> 1, etc.); 0 1 2 3 4=0 posx;;; OUTPUTS:; Prints that a CIC interpolation is being performed of x; samples to y grid points, unless NO_MESSAGE is set. ;; RESTRICTIONS:; Field data is assumed to be periodic with the sampled volume; the basic cell, unless ISOLATED is set.; All input arrays must have the same dimensions.; Postition coordinates should be in `index units' of the; desired grid: POSX=[0,NX>, etc.; Keywords ISOLATED and WRAPAROUND cannot both be set.;; PROCEDURE:; Nearest grid point is determined for each sample.; CIC weights are computed for each sample.; Samples are interpolated to the grid.; Grid point values are computed (sum or average of samples).; NOTES:; Use tsc.pro for a higher-order interpolation scheme, ngp.pro for a lower; order interpolation scheme. A standard reference for these ; interpolation methods is: R.W. Hockney and J.W. Eastwood, Computer ; Simulations Using Particles (New York: McGraw-Hill, 1981).; EXAMPLE:; nx=20; ny=10; posx=randomu(s,1000); posy=randomu(s,1000); value=posx^2+posy^2; field=cic(value,posx*nx,nx,posy*ny,ny,/average); surface,field,/lego;; MODIFICATION HISTORY:; Written by Joop Schaye, Feb 1999.; Avoid integer overflow for large dimensions P.Riley/W.Landsman Dec. 1999;-nrsamples=n_elements(value)nparams=n_params()dim=(nparams-1)/2IF dim LE 2 THEN BEGIN nz=1 IF dim EQ 1 THEN ny=1ENDIFnxny=long(nx)*long(ny);---------------------; Some error handling.;---------------------on_error,2 ; Return to caller if an error occurs.IF NOT (nparams EQ 3 OR nparams EQ 5 OR nparams EQ 7) THEN BEGIN message,'Incorrect number of arguments!',/continue message,'Syntax: CIC, VALUE, POSX, NX[, POSY, NY, POSZ, NZ,' + $ ' AVERAGE = average, PERIODIC = periodic]'ENDIF IF (nrsamples NE n_elements(posx)) OR $ (dim GE 2 AND nrsamples NE n_elements(posy)) OR $ (dim EQ 3 AND nrsamples NE n_elements(posz)) THEN $ message,'Input arrays must have the same dimensions!'IF keyword_set(isolated) AND keyword_set(wraparound) THEN $ message,'Keywords ISOLATED and WRAPAROUND cannot both be set!'IF NOT keyword_set(no_message) THEN $ print,'Interpolating ' + strtrim(string(nrsamples,format='(i10)'),1) $ + ' samples to ' + strtrim(string(nxny*nz,format='(i10)'),1) + $ ' grid points using CIC...';-----------------------; Calculate CIC weights.;-----------------------; Compute weights per axis, in order to reduce memory (everything; needs to be in memory if we compute all nearest grid points first).;*************; X-direction.;*************; Coordinates of nearest grid point (ngp).IF keyword_set(wraparound) THEN ngx=fix(posx+0.5) $ELSE ngx=fix(posx)+0.5; Distance from sample to ngp.dngx=ngx-posx; Index of ngp.IF keyword_set(wraparound) THEN kx1=temporary(ngx) $ELSE kx1=temporary(ngx)-0.5; Weight of ngp.wx1=1.0-abs(dngx); Other side.left=where(dngx LT 0.0,nrleft) ; samples with ngp to the left.; The following is only correct if x(ngp)>posx (ngp to the right).kx2=kx1-1; Correct points where x(ngp)<posx (ngp to the left).IF nrleft NE 0 THEN kx2[left]=kx2[left]+2wx2=abs(temporary(dngx)); Free memory.left=0; Periodic boundary conditions.; Note that kx2 can be both -1 and nx at this point, regardless of; wraparound or not. The reason is that dngx can be exactly zero.bad=where(kx2 EQ -1,count)IF count NE 0 THEN BEGIN kx2[bad]=nx-1 IF keyword_set(isolated) THEN wx2[bad]=0.ENDIFbad=where(kx2 EQ nx,count)IF count NE 0 THEN BEGIN kx2[bad]=0 IF keyword_set(isolated) THEN wx2[bad]=0.ENDIFIF keyword_set(wraparound) THEN BEGIN bad=where(kx1 EQ nx,count) IF count NE 0 THEN kx1[bad]=0ENDIFbad=0 ; Free memory.;*************; Y-direction.;*************IF dim GE 2 THEN BEGIN ; Coordinates of nearest grid point (ngp). IF keyword_set(wraparound) THEN ngy=fix(posy+0.5) $ ELSE ngy=fix(posy)+0.5 ; Distance from sample to ngp. dngy=ngy-posy ; Index of ngp. IF keyword_set(wraparound) THEN ky1=temporary(ngy) $ ELSE ky1=temporary(ngy)-0.5 ; Weight of ngp. wy1=1.0-abs(dngy) ; Other side. left=where(dngy LT 0.0,nrleft) ; samples with ngp to the left. ; The following is only correct if y(ngp)>posy (ngp to the right). ky2=ky1-1 ; Correct points where y(ngp)<posy (ngp to the left). IF nrleft NE 0 THEN ky2[left]=ky2[left]+2 wy2=abs(temporary(dngy)) ; Free memory. left=0 ; Periodic boundary conditions. bad=where(ky2 EQ -1,count) IF count NE 0 THEN BEGIN ky2[bad]=ny-1 IF keyword_set(isolated) THEN wy2[bad]=0. ENDIF bad=where(ky2 EQ ny,count) IF count NE 0 THEN BEGIN ky2[bad]=0 IF keyword_set(isolated) THEN wy2[bad]=0. ENDIF IF keyword_set(wraparound) THEN BEGIN bad=where(ky1 EQ ny,count) IF count NE 0 THEN ky1[bad]=0 ENDIF bad=0 ; Free memory.ENDIF ELSE BEGIN ky1=0 ky2=0 wy1=1 wy2=1ENDELSE;*************; Z-direction.;*************IF dim EQ 3 THEN BEGIN ; Coordinates of nearest grid point (ngp). IF keyword_set(wraparound) THEN ngz=fix(posz+0.5) $ ELSE ngz=fix(posz)+0.5 ; Distance from sample to ngp. dngz=ngz-posz ; Index of ngp. IF keyword_set(wraparound) THEN kz1=temporary(ngz) $ ELSE kz1=temporary(ngz)-0.5 ; Weight of ngp. wz1=1.0-abs(dngz) ; Other side. left=where(dngz LT 0.0,nrleft) ; samples with ngp to the left. ; The following is only correct if z(ngp)>posz (ngp to the right). kz2=kz1-1 ; Correct points where z(ngp)<posz (ngp to the left). IF nrleft NE 0 THEN kz2[left]=kz2[left]+2 wz2=abs(temporary(dngz)) ; Free memory. left=0 ; Periodic boundary conditions. bad=where(kz2 EQ -1,count) IF count NE 0 THEN BEGIN kz2[bad]=nz-1 IF keyword_set(isolated) THEN wz2[bad]=0. ENDIF bad=where(kz2 EQ nz,count) IF count NE 0 THEN BEGIN kz2[bad]=0 IF keyword_set(isolated) THEN wz2[bad]=0. ENDIF IF keyword_set(wraparound) THEN BEGIN bad=where(kz1 EQ nz,count) IF count NE 0 THEN kz1[bad]=0 ENDIF bad=0 ; Free memory.ENDIF ELSE BEGIN kz1=0 kz2=0 wz1=1 wz2=1ENDELSE;-----------------------------; Interpolate samples to grid.;-----------------------------field=fltarr(nx,ny,nz)IF keyword_set(average) THEN totcicweight=fltarr(nx,ny,nz); Cicweight adds up all cic weights allocated to a grid point, we need; to keep track of this in order to compute the temperature.; Note that total(cicweight) is equal to nrsamples and that; total(field)=n0^3 if sph.plot NE 'sph,temp' (not 1 because we use; posx=[0,n0> --> cube length different from EDFW paper).index=kx1+ky1*nx+kz1*nxnycicweight=wx1*wy1*wz1IF keyword_set(average) THEN BEGIN FOR j=0l,nrsamples-1l DO BEGIN field[index[j]]=field[index[j]]+cicweight[j]*value[j] totcicweight[index[j]]=totcicweight[index[j]]+cicweight[j] ENDFORENDIF ELSE FOR j=0l,nrsamples-1l DO $ field[index[j]]=field[index[j]]+cicweight[j]*value[j]index=kx2+ky1*nx+kz1*nxnycicweight=wx2*wy1*wz1IF keyword_set(average) THEN BEGIN FOR j=0l,nrsamples-1l DO BEGIN field[index[j]]=field[index[j]]+cicweight[j]*value[j] totcicweight[index[j]]=totcicweight[index[j]]+cicweight[j] ENDFORENDIF ELSE FOR j=0l,nrsamples-1l DO $ field[index[j]]=field[index[j]]+cicweight[j]*value[j]IF dim GE 2 THEN BEGIN index=kx1+ky2*nx+kz1*nxny cicweight=wx1*wy2*wz1 IF keyword_set(average) THEN BEGIN FOR j=0l,nrsamples-1l DO BEGIN field[index[j]]=field[index[j]]+cicweight[j]*value[j] totcicweight[index[j]]=totcicweight[index[j]]+cicweight[j] ENDFOR ENDIF ELSE FOR j=0l,nrsamples-1l DO $ field[index[j]]=field[index[j]]+cicweight[j]*value[j] index=kx2+ky2*nx+kz1*nxny cicweight=wx2*wy2*wz1 IF keyword_set(average) THEN BEGIN FOR j=0l,nrsamples-1l DO BEGIN field[index[j]]=field[index[j]]+cicweight[j]*value[j] totcicweight[index[j]]=totcicweight[index[j]]+cicweight[j] ENDFOR ENDIF ELSE FOR j=0l,nrsamples-1l DO $ field[index[j]]=field[index[j]]+cicweight[j]*value[j] IF dim EQ 3 THEN BEGIN index=kx1+ky1*nx+kz2*nxny cicweight=wx1*wy1*wz2 IF keyword_set(average) THEN BEGIN FOR j=0l,nrsamples-1l DO BEGIN field[index[j]]=field[index[j]]+cicweight[j]*value[j] totcicweight[index[j]]=totcicweight[index[j]]+cicweight[j] ENDFOR ENDIF ELSE FOR j=0l,nrsamples-1l DO $ field[index[j]]=field[index[j]]+cicweight[j]*value[j] index=kx2+ky1*nx+kz2*nxny cicweight=wx2*wy1*wz2 IF keyword_set(average) THEN BEGIN FOR j=0l,nrsamples-1l DO BEGIN field[index[j]]=field[index[j]]+cicweight[j]*value[j] totcicweight[index[j]]=totcicweight[index[j]]+cicweight[j] ENDFOR ENDIF ELSE FOR j=0l,nrsamples-1l DO $ field[index[j]]=field[index[j]]+cicweight[j]*value[j] index=kx1+ky2*nx+kz2*nxny cicweight=wx1*wy2*wz2 IF keyword_set(average) THEN BEGIN FOR j=0l,nrsamples-1l DO BEGIN field[index[j]]=field[index[j]]+cicweight[j]*value[j] totcicweight[index[j]]=totcicweight[index[j]]+cicweight[j] ENDFOR ENDIF ELSE FOR j=0l,nrsamples-1l DO $ field[index[j]]=field[index[j]]+cicweight[j]*value[j] index=kx2+ky2*nx+kz2*nxny cicweight=wx2*wy2*wz2 IF keyword_set(average) THEN BEGIN FOR j=0l,nrsamples-1l DO BEGIN field[index[j]]=field[index[j]]+cicweight[j]*value[j] totcicweight[index[j]]=totcicweight[index[j]]+cicweight[j] ENDFOR ENDIF ELSE FOR j=0l,nrsamples-1l DO $ field[index[j]]=field[index[j]]+cicweight[j]*value[j] ENDIFENDIF; Free memory (no need to free any more local arrays, will not lower; maximum memory usage).index=0;--------------------------; Compute weighted average.;--------------------------IF keyword_set(average) THEN BEGIN good=where(totcicweight NE 0,nrgood) field[good]=temporary(field[good])/temporary(totcicweight[good])ENDIFreturn,fieldEND ; End of function cic.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -