This routine builds up the matrix for least square fit used in linear interpolation.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(tem_matrix_type), | intent(out) | :: | me |
Matrix to fill |
||
integer, | intent(in) | :: |
Number of stencil directions |
|||
integer, | intent(in) | :: | nDims |
Number of dimensions |
||
integer, | intent(in) | :: | nSources |
Number of sources from coarser found |
||
real(kind=rk), | intent(in) | :: | cxDirRK(3,QQ) |
Stencil directions |
||
integer, | intent(in) | :: | neighDir(nSources) |
direction in which sources are found |
||
integer, | intent(in) | :: | nCoeffs |
nUnknown coeffs |
||
logical, | intent(out) | :: | success |
success if false if matrix is singular reduce interpolation order |
subroutine build_matrixLSF_linearIntp(me, QQ, nDims, nSources, cxDirRK, & & neighDir, nCoeffs, success) ! -------------------------------------------------------------------------- !> Matrix to fill type(tem_matrix_type), intent(out) :: me !> Number of stencil directions integer, intent(in) :: QQ !> Number of dimensions integer, intent(in) :: nDims !> Number of sources from coarser found integer, intent(in) :: nSources !> Stencil directions real(kind=rk), intent(in) :: cxDirRK(3,QQ) !> direction in which sources are found integer, intent(in) :: neighDir(nSources) !> nUnknown coeffs integer, intent(in) :: nCoeffs !> success if false if matrix is singular reduce interpolation order logical, intent(out) :: success ! -------------------------------------------------------------------------- integer :: iDir, iSrc !> Each row represents a polynomial evaluated at coord of elements in ! stencil directions type(tem_matrix_type) :: tmp_matrix real(kind=rk) :: inv_AtA(nCoeffs,nCoeffs), AtA(nCoeffs,nCoeffs) integer :: errCode ! -------------------------------------------------------------------------- write(dbgUnit(4),"(A)") 'Inside build least square fit matrix for linear' ! me%A = ((A^T)A)^-1*(A^T) ! inv_AtA = ((A^T)A)^-1 call alloc_matrix(tmp_matrix, nSources, nCoeffs) select case(nDims) case (1) do iSrc = 1, nSources iDir = neighDir(iSrc) tmp_matrix%A(iSrc,:) = polyLinear_1D( cxDirRK(:,iDir) ) end do case (2) do iSrc = 1, nSources iDir = neighDir(iSrc) tmp_matrix%A(iSrc,:) = polyLinear_2D( cxDirRK(:,iDir) ) end do case (3) do iSrc = 1, nSources iDir = neighDir(iSrc) tmp_matrix%A(iSrc,:) = polyLinear_3D( cxDirRK(:,iDir) ) end do case default write(logUnit(1),*) 'Unknown nDims for quadratic interpolation' call tem_abort() end select write(dbgUnit(4),"(A)") ' tmp matrix:' call tem_matrix_dump(tmp_matrix, dbgUnit(4)) flush(dbgUnit(4)) AtA = matmul( transpose(tmp_matrix%A), tmp_matrix%A) inv_AtA = invert_matrix(AtA, errCode) if (errCode == 0) then ! matrix_LSF size is transpose of tmp_matrix call alloc_matrix(me, nCoeffs, nSources) me%A = matmul( inv_AtA, transpose(tmp_matrix%A) ) success = .true. else ! singular matrix, reduce interpolation order call alloc_matrix(me, 1, 1) success = .false. return end if write(dbgUnit(4),"(A)") ' Matrix LSF:' call tem_matrix_dump(me, dbgUnit(4)) flush(dbgUnit(4)) end subroutine build_matrixLSF_linearIntp