Precision Stencil::apply( const DiscreteFunction& u, const Position pos, const Index sx, const Index sy) const { const Index nx = u.getNx(); const Index ny = u.getNy(); const Precision hx = u.getHx(); const Precision hy = u.getHy(); const Point origin = u.getOrigin(); NumericArray opL = getL(pos,sx,sy,nx,ny,hx,hy,origin); PositionArray jX = getJx(pos,nx,ny); PositionArray jY = getJy(pos,nx,ny); Precision result = 0.0; for (Index i = 0; i<opL.size(); ++i) result+=opL[i]*u(sx+jX[i],sy+jY[i]); return result; }
T NumericArray<T>::DotProduct (const NumericArray<T>& source) const // Dot porduct fucntion. { if (Size() != source.Size()) { throw SizeMissmatchException(); } T sum = 0; for (int i = 0; i < (Size()); i++) { sum += source[i]* (*this)[i] ; } return sum; }
NumericArray<T> NumericArray<T>::operator + (const NumericArray<T>& source) const { cout << "operator + (const NumericArray<T>& source) const is called \n " <<endl ; if (Size() != source.Size()) { throw SizeMissmatchException(); } NumericArray<T> temp(Size()); for (int i = 0; i < Size(); i++) { temp[i] = source[i] + (*this)[i]; } return temp; }
NumericArray<T> NumericArray<T>::operator + (const NumericArray<T>& arr) const { if (this->Size() == arr.Size()) { NumericArray<T> temp(this->Size()); for (int i = 0; i < this->Size(); i++) { temp.SetElement(i, (*this)[i] + arr[i]); } } else { throw DifferentSizeException(-1); } }
double NumericArray<T>::DotProduct(const NumericArray<T>& arr) const { double product = 0; if (this->Size() == arr.Size()) { for (int i = 0; i < this->Size(); i++) { product += (*this)[i] * arr[i]; } } else { // Throw different size exception throw DifferentSizeException(-1); } return product; }
NumericArray Stencil::getLInSize( const Position pos, const Index sx, const Index sy, const Index nx, const Index ny, const Precision hx, const Precision hy, const Point origin, const Index size ) const { ASSERT( size == 1 || size == 2 ); NumericArray result( 0.0, size == 1 ? 9 : 25 ); NumericArray operatorL = getL( pos, sx, sy, nx, ny, hx, hy, origin ); PositionArray jX = getJx( pos, nx, ny ); PositionArray jY = getJy( pos, nx, ny ); for ( Index i = 0; i < operatorL.size(); i++ ) { if( jX[ i ] == -1 ) { if( jY[ i ] == -1 ) result[ SW ] = operatorL[ i ]; else if( jY[ i ] == 0 ) result[ W ] = operatorL[ i ]; else if( jY[ i ] == 1) result[ NW ] = operatorL[ i ]; if ( size > 1 ) { if ( jY[ i ] == -2 ) result[ SSW ] = operatorL[ i ]; else if( jY[ i ] == 2 ) result[ NNW ] = operatorL[ i ]; } else if ( jY[i] == -2 || jY[i] == 2 ) { result[ C ] += operatorL[ i ]; } } else if( jX[ i ] == 0 ) { if( jY[ i ] == -1 ) result[ S ] = operatorL[ i ]; else if( jY[ i ] == 0 ) result[ C ] += operatorL[ i ]; else if( jY[ i ] == 1 ) result[ N ] = operatorL[ i ]; if ( size > 1 ) { if ( jY[ i ] == -2 ) result[ SS ] = operatorL[ i ]; else if( jY[ i ] == 2 ) result[ NN ] = operatorL[ i ]; } else if ( jY[ i ] == -2 || jY[ i ] == 2 ) { result[ C ] += operatorL[ i ]; } } else if( jX[ i ] == 1 ) { if( jY[ i ] == -1 ) result[ SE ] = operatorL[ i ]; else if( jY[ i ] == 0 ) result[ E ] = operatorL[ i ]; else if( jY[ i ] == 1 ) result[ NE ] = operatorL[ i ]; if ( size > 1 ) { if ( jY[ i ] == -2 ) result[ SSE ] = operatorL[ i ]; else if( jY[ i ] == 2 ) result[ NNE ] = operatorL[ i ]; } else if ( jY[ i ] == -2 || jY[ i ] == 2 ) { result[ C ] += operatorL[ i ]; } } if ( size > 1 ) { if ( jX[ i ] == -2 ) { if ( jY[ i ] == -2 ) result[ SSWW ] = operatorL[ i ]; else if ( jY[ i ] == -1 ) result[ SWW ] = operatorL[ i ]; else if ( jY[ i ] == 0 ) result[ WW ] = operatorL[ i ]; else if ( jY[ i ] == 1 ) result[ NWW ] = operatorL[ i ]; else if ( jY[ i ] == 2 ) result[ NNWW ] = operatorL[ i ]; } else if ( jX[ i ] == 2 ) { if ( jY[ i ] == -2 ) result[ SSEE ] = operatorL[ i ]; else if ( jY[ i ] == -1 ) result[ SEE ] = operatorL[ i ]; else if ( jY[ i ] == 0 ) result[ EE ] = operatorL[ i ]; else if ( jY[ i ] == 1 ) result[ NEE ] = operatorL[ i ]; else if ( jY[ i ] == 2 ) result[ NNEE ] = operatorL[ i ]; } } else if ( jX[ i ] == -2 || jX[ i ] == 2 ) { result[ C ] += operatorL[ i ]; } } return result; }
// This function only works for max. compact 9-point stencils NumericArray DendyInterpolation::prolongate( const NumericArray& u, const Stencil& stencil, const Index nx, const Index ny) const { const Index nxNew=2*nx; const Index nyNew=2*ny; NumericArray result((nxNew+1)*(nyNew+1)); NumericArray stencilL; Precision scale=0; Precision weight1=0; Precision weight2=0; Precision erg=0; // linear interpolation on the borders for (Index sy=0; sy<=ny; sy++) { result[2*sy*(nxNew+1)]=u[sy*(nx+1)]; result[2*sy*(nxNew+1)+2*nx]=u[sy*(nx+1)+nx]; } for (Index sx=0; sx<=nx; sx++) { result[2*sx]=u[sx]; result[2*ny*(nxNew+1)+2*sx]=u[ny*(nx+1)+sx]; } for (Index sy=0; sy<=ny-1; sy++) { result[(2*sy+1)*(nxNew+1)] = 0.5 * (result[2*sy*(nxNew+1)] + result[2*(sy+1)*(nxNew+1)]); result[(2*sy+1)*(nxNew+1)+2*nx] = 0.5 * (result[2*sy*(nxNew+1)+2*nx] + result[2*(sy+1)*(nxNew+1)+2*nx]); } for (Index sx=0; sx<=nx-1; sx++) { result[2*sx+1] = 0.5 * (result[2*sx] + result[2*sx+2]); result[2*ny*(nxNew+1)+2*sx+1] = 0.5 * (result[2*ny*(nxNew+1)+2*sx] + result[2*ny*(nxNew+1)+2*sx+2]); } //copy coarse grid points for (Index sy=1; sy<=ny-1; sy++) for (Index sx=1; sx<=nx-1; sx++) result[2*sy*(nxNew+1)+2*sx]=u[sy*(nx+1)+sx]; stencilL.resize( stencil.getLInSize(C,2,1,nxNew,nyNew, 1).size()); //interpolation of fine grid points on coarse grid lines for (Index sy=2; sy<=nyNew-2; sy+=2) for (Index sx=1; sx<=nxNew-1; sx+=2) { stencilL=stencil.getLInSize(C,sx,sy,nxNew,nyNew, 1); scale=0; scale-=stencilL[C]; scale-=stencilL[S]; scale-=stencilL[N]; weight1=0; weight1+=stencilL[W]; weight1+=stencilL[SW]; weight1+=stencilL[NW]; weight2=0; weight2+=stencilL[E]; weight2+=stencilL[SE]; weight2+=stencilL[NE]; result[sy*(nxNew+1)+sx]= ( weight1*result[sy*(nxNew+1)+sx-1] +weight2*result[sy*(nxNew+1)+sx+1] )/scale; } //interpolation of fine grid points on fine grid lines and coarse grid columns for (Index sy=1; sy<=nyNew-1; sy+=2) for (Index sx=2; sx<=nxNew-2; sx+=2) { stencilL=stencil.getLInSize(C,sx,sy,nxNew,nyNew,1); scale=0; scale-=stencilL[C]; scale-=stencilL[W]; scale-=stencilL[E]; weight1=0; weight1+=stencilL[S]; weight1+=stencilL[SW]; weight1+=stencilL[SE]; weight2=0; weight2+=stencilL[N]; weight2+=stencilL[NW]; weight2+=stencilL[NE]; result[sy*(nxNew+1)+sx]= ( weight1*result[(sy-1)*(nxNew+1)+sx] +weight2*result[(sy+1)*(nxNew+1)+sx] )/scale; } //interpolation of fine grid points on fine grid lines and fine grid columns for (Index sy=1; sy<=nyNew-1; sy+=2) for (Index sx=1; sx<=nxNew-1; sx+=2) { stencilL=stencil.getLInSize(C,sx,sy,nxNew,nyNew,1); erg=0; scale=-stencilL[0]; erg+=stencilL[W] *result[ sy *(nxNew+1)+sx-1]; erg+=stencilL[E] *result[ sy *(nxNew+1)+sx+1]; erg+=stencilL[S] *result[(sy-1)*(nxNew+1)+sx ]; erg+=stencilL[SW]*result[(sy-1)*(nxNew+1)+sx-1]; erg+=stencilL[SE]*result[(sy-1)*(nxNew+1)+sx+1]; erg+=stencilL[N] *result[(sy+1)*(nxNew+1)+sx ]; erg+=stencilL[NW]*result[(sy+1)*(nxNew+1)+sx-1]; erg+=stencilL[NE]*result[(sy+1)*(nxNew+1)+sx+1]; result[sy*(nxNew+1)+sx]=erg/scale; } return result; }