Solves the linear(ised) system represented by this finite difference block, for a given right hand side state vector (represented by a scalar field).
Currently this is only implemented for a 1-D field.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(pseudospec_block), | intent(inout) | :: | this | |||
class(scalar_field), | intent(in) | :: | rhs | The right hand side of the linear(ised) system. |
||
integer, | intent(in) | :: | bound_loc | Which boundary is being set. The boundary will be the one
normal to dimension of number |
||
class(scalar_field), | intent(in) | :: | bound_val | The value of the result at the specified boundary. |
||
integer, | intent(in), | optional | :: | good_bound | If provided, indicates which boundary contains trusted
information from which to calculate the power of the highest
frequency mode. Defaults to the opposite of |
function pseudospec_block_solve_scalar(this, rhs, bound_loc, bound_val, &
good_bound) result(solution)
!* Author: Chris MacMackin
! Date: September 2017
!
! Solves the linear(ised) system represented by this finite
! difference block, for a given right hand side state vector
! (represented by a scalar field).
!
! @Warning Currently this is only implemented for a 1-D field.
!
class(pseudospec_block), intent(inout) :: this
class(scalar_field), intent(in) :: rhs
!! The right hand side of the linear(ised) system.
integer, intent(in) :: bound_loc
!! Which boundary is being set. The boundary will be the one
!! normal to dimension of number `abs(boundary)`. If the
!! argument is negative, then the lower boundary is returned. If
!! positive, then the upper boundary is returned.
class(scalar_field), intent(in) :: bound_val
!! The value of the result at the specified boundary.
integer, intent(in), optional :: good_bound
!! If provided, indicates which boundary contains trusted
!! information from which to calculate the power of the highest
!! frequency mode. Defaults to the opposite of `bound_loc`.
class(scalar_field), pointer :: solution
real(r8), dimension(:), allocatable :: sol_vector, bound_vec
logical :: valid_bound
integer :: bloc
call rhs%guard_temp(); call bound_val%guard_temp()
valid_bound = .true.
select case(bound_loc)
case(1)
bloc = 1
case(-1)
bloc = size(this%xvals)
case default
valid_bound = .false.
!call logger%warning('pseudospec_block%solve_for', '1-D field does not '// &
! 'have boundary in dimension '//str(bound_loc))
end select
sol_vector = rhs%raw()
if (valid_bound) then
bound_vec = bound_val%raw()
call integrate_1d(sol_vector, this%xvals, bloc, bound_vec(1), good_bound)
else
call integrate_1d(sol_vector, this%xvals, good_bound=good_bound)
end if
#ifdef DEBUG
call logger%debug('pseudospec_block%solve_for', &
'Successfully performed Chebyshev pseudospectral integration.')
#endif
call rhs%allocate_scalar_field(solution)
call solution%unset_temp()
call solution%assign_meta_data(rhs)
call solution%set_from_raw(sol_vector)
call rhs%clean_temp(); call bound_val%clean_temp()
call solution%set_temp()
end function pseudospec_block_solve_scalar