wiki:SubSampling

Version 2 (modified by Jonathan, 12 years ago) ( diff )

Sub Sampling

Cell centered quantities

  • AstroBEAR stores most fluid quantities as volume averages in the array Info%q(i,j,k,:)
  • Each cell is a cube with a side dx=levels(Info%level)%dx
  • The 'lower' corner of the cube is located at Info%xbounds(:,1) + ((/i,j,k/)-1)*dx
  • The 'upper' corner of the cube is located at Info%xbounds(:,1) + ((/i,j,k/))*dx
  • The 'center' of the cube is located at Info%xbounds(:,1) + (REAL(/i,j,k/)-.5)*dx

Sub-sampling

  • If we break each cube into NxNxN sub-pieces, and set ddx=dx/N then the center of the [ii,jj,kk] sub piece will be at Info%xBounds(:,1)+(/i-1,j-1,k-1/)*dx + (REAL(/ii,jj,kk/)-.5)*ddx
  • So we could use the following routine to initialize cell centered quantities in q. Here is a routine for density.
    dx=levels(Info%level)%dx
    ddx=dx/N
    DO i=1,Info%mX(1)
      DO j=1,Info%mx(2)
        DO k=1,Info%mx(3)
          new_rho=0d0
          DO ii=1,N
            DO jj=1,N
              DO kk=1,N
                pos=Info%xBounds(:,1)+(/i-1,j-1,k-1/)*dx + (REAL(/ii,jj,kk/)-.5)*ddx
                new_rho=new_rho+rho_func(pos)
              END DO
            END DO
          END DO
          Info%q(i,j,k,1)=new_rho/N**nDim
        END DO
      END DO
    END DO
    

or we could try to speed it up by reducing some repeated computations.

dx=levels(Info%level)%dx
ddx=dx/N
DO i=1,Info%mX(1)
  pos(1)=Info%xBbounds(1,1)+(i-1)*dx
  DO j=1,Info%mx(2)
    pos(2)=Info%xBbounds(1,1)+(i-1)*dx
    DO k=1,Info%mx(3)
      pos(3)=Info%xBbounds(1,1)+(i-1)*dx
      new_rho=0d0
      DO ii=1,N
        ppos(1)=pos(1)+(REAL(ii)-.5)*ddx
        DO jj=1,N
          ppos(2)=pos(2)+(REAL(jj)-.5)*ddx
          DO kk=1,N
            ppos(3)=pos(3)+(REAL(kk)-.5)*ddx
            new_rho=new_rho+rho_func(pos)
          END DO
        END DO
      END DO
      Info%q(i,j,k,1)=new_rho/N**nDim
    END DO
  END DO
END DO

and sometimes we may be implementing a function that is only defined for a certain region (like a clump object etc…) where the value for q outside of a given radius is unknown. In that case, we just want to add up changes to q for subcells within the region. So for example to calculate the x component of the potential along a given edge we would

dx=levels(Info%level)%dx
ddx=dx/N
DO i=1,Info%mX(1)+1
  pos(1)=Info%xBbounds(1,1)+(i-1)*dx
  DO j=1,Info%mx(2)+1
    pos(2)=Info%xBbounds(1,1)+(i-1)*dx
    DO k=1,Info%mx(3)+1
      pos(3)=Info%xBbounds(1,1)+(i-1)*dx
      drho=0d0
      DO ii=1,N
        ppos(1)=pos(1)+(REAL(ii)-.5)*ddx
        DO jj=1,N
          ppos(2)=pos(2)+(REAL(jj)-.5)*ddx
          DO kk=1,N
            ppos(3)=pos(3)+(REAL(kk)-.5)*ddx
            drho=(rho_func(ppos)-Info%q(i,j,k,1))
          END DO
        END DO
      END DO
      Info%q(i,j,k,1)=Info%q(i,j,k,1)+drho/N**nDim
    END DO
  END DO
END DO

For face centered fields we could also subsample, but their is the divergence criterion to consider for B-fields. We could calculate the potential on a subgrid, and then take a bunch of curls on each face and add them up, but Stoke's theorem lets us just do the integral around the outside. So we really just need to subsample along the appropriate edge for each component of the vector potential.

dx=levels(Info%level)%dx
ddx=dx/N
DO i=1,Info%mX(1)
  pos(1)=Info%xBbounds(1,1)+(i-1)*dx
  DO j=1,Info%mx(2)
    pos(2)=Info%xBbounds(1,1)+(i-1)*dx
    DO k=1,Info%mx(3)
      pos(3)=Info%xBbounds(1,1)+(i-1)*dx
      drho=0d0
      DO ii=1,N
        ppos(1)=pos(1)+(REAL(ii)-.5)*ddx
        DO jj=1,N
          ppos(2)=pos(2)+(REAL(jj)-.5)*ddx
          DO kk=1,N
            ppos(3)=pos(3)+(REAL(kk)-.5)*ddx
            drho=(rho_func(ppos)-Info%q(i,j,k,1))
          END DO
        END DO
      END DO
      Info%q(i,j,k,1)=Info%q(i,j,k,1)+drho/N**nDim
    END DO
  END DO
END DO
Note: See TracWiki for help on using the wiki.