The main documentation of the Add_Values_ELL_Matrix Procedure contains additional explanation of this code listing.
subroutine Add_Values_ELL_Matrix_0 (ELLM, Value, Row, Column, Global)
! Note: this routine is very similar to Set_Values_ELL_Matrix_0.
! Input variable.
type(real), intent(in) :: Value ! Value scalar.
type(integer), intent(in) :: Row ! Row integer scalar.
type(integer), intent(in) :: Column ! Column integer scalar.
type(logical), intent(in), optional :: Global ! Global/local index toggle.
! Input/Output variable.
type(ELL_Matrix_type), intent(inout) :: ELLM ! Variable to be incremented.
! Internal variables.
type(logical) :: A_Global ! Actual global/local toggle.
type(integer) :: Column_Location ! Location in Columns array for the entry.
type(integer) :: location ! Loop index.
type(integer) :: shift ! Index shift.
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! Verify requirements.
VERIFY(Valid_State(ELLM),5) ! ELLM is valid.
VERIFY(Valid_State(Value),5) ! Value is valid.
VERIFY(Valid_State(Row),5) ! Row is valid.
VERIFY(Valid_State(Column),5) ! Column is valid.
! Global/Local toggle.
if (PRESENT(Global)) then
A_Global = Global
else
A_Global = .true.
end if
if (A_Global) then
shift = -First_PE(ELLM%Row_Structure) + 1
else
shift = 0
end if
! Another requirement check -- require that Row be in the correct range.
VERIFY(Row + shift .InInterval. (/1, Length_PE(ELLM%Row_Structure)/),5)
! Add the value.
if (Row /= 0) then
! Find a column location to store the entry.
Column_Location = 0
do location = 1, ELLM%Max_Nonzeros
if (ELLM%Columns(Row + shift, location) == 0 .or. &
ELLM%Columns(Row + shift, location) == Column) then
Column_Location = location
exit
end if
end do
! Add the entry.
ELLM%Values(Row + shift, Column_Location) = &
ELLM%Values(Row + shift, Column_Location) + Value
ELLM%Columns(Row + shift, Column_Location) = Column
else
! Make sure Column_Location has a non-zero value if Row=0,
! so the check below executes correctly.
Column_Location = -1
end if
! Make sure Max_Nonzeros is not exceeded (that is, that we
! found a spot to put the entry).
VERIFY(Column_Location /= 0,1)
! Unset the updated? variables.
call Set_Not_Up_to_Date (ELLM)
! Verify guarantees.
VERIFY(Valid_State(ELLM),5) ! ELLM is still valid.
return
end subroutine Add_Values_ELL_Matrix_0
subroutine Add_Values_ELL_Matrix_1 (ELLM, Values, Rows, Columns, Global)
! Note: this routine is very similar to Set_Values_ELL_Matrix_1.
! Input variable.
type(real,1,np), intent(in) :: Values ! Values bare naked array.
type(integer,1,np), intent(in) :: Rows ! Rows integer vector.
type(integer,1,np), intent(in) :: Columns ! Columns integer vector.
type(logical), intent(in), optional :: Global ! Global/local index toggle.
! Input/Output variable.
type(ELL_Matrix_type), intent(inout) :: ELLM ! Variable to be incremented.
! Internal variables.
type(logical) :: A_Global ! Actual global/local toggle.
type(integer) :: Column_Location ! Location in Columns array
! for the entry.
type(integer) :: i ! Loop parameter.
type(integer) :: location ! Loop index.
type(logical) :: Max_Nonzeros_Not_Exceeded ! Toggle for error check.
type(integer) :: shift ! Index shift.
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! Verify requirements.
VERIFY(Valid_State(ELLM),5) ! ELLM is valid.
VERIFY(Valid_State_NP(Values),5) ! Values is valid.
VERIFY(Valid_State_NP(Rows),5) ! Rows is valid.
VERIFY(Valid_State_NP(Columns),5) ! Columns is valid.
! Values, Rows & Columns size checks.
VERIFY(SIZE(Values,1) <= Length_PE(ELLM%Row_Structure),5)
VERIFY(SIZE(Rows) <= Length_PE(ELLM%Row_Structure),5)
VERIFY(SIZE(Rows) == SIZE(Values,1),5)
VERIFY(SIZE(Values) == SIZE(Columns),5)
! Global/Local toggle.
if (PRESENT(Global)) then
A_Global = Global
else
A_Global = .true.
end if
if (A_Global) then
shift = -First_PE(ELLM%Row_Structure) + 1
else
shift = 0
end if
! More requirement checks -- require that Rows entries are in the
! correct range.
VERIFY(Rows + shift .InInterval. (/1, Length_PE(ELLM%Row_Structure)/),5)
! Add the values.
Max_Nonzeros_Not_Exceeded = .true.
do i = 1, SIZE(Rows)
if (Rows(i) /= 0) then
! Find a column location to store the entry.
Column_Location = 0
do location = 1, ELLM%Max_Nonzeros
if (ELLM%Columns(Rows(i) + shift, location) == 0 .or. &
ELLM%Columns(Rows(i) + shift, location) == Columns(i)) then
Column_Location = location
exit
end if
end do
! Make sure Max_Nonzeros is not exceeded (that is, that we
! found a spot to put the entry).
Max_Nonzeros_Not_Exceeded = &
Max_Nonzeros_Not_Exceeded .and. Column_Location /= 0
! Increment the entry.
ELLM%Values(Rows(i) + shift, Column_Location) = &
ELLM%Values(Rows(i) + shift, Column_Location) + Values(i)
ELLM%Columns(Rows(i) + shift, Column_Location) = Columns(i)
end if
end do
! Make sure Max_Nonzeros is not exceeded (that is, that we
! found a spot to put all of the entries).
VERIFY(Max_Nonzeros_Not_Exceeded,1)
! Unset the updated? variables.
call Set_Not_Up_to_Date (ELLM)
! Verify guarantees.
VERIFY(Valid_State(ELLM),5) ! ELLM is still valid.
return
end subroutine Add_Values_ELL_Matrix_1
subroutine Add_Values_ELL_Matrix_2 (ELLM, Values, Rows, Columns, Global)
! Note: this routine is very similar to Set_Values_ELL_Matrix_2.
! Input variable.
type(real,2,np), intent(in) :: Values ! Values bare naked array.
type(integer,1,np), intent(in) :: Rows ! Rows integer vector.
type(integer,2,np), intent(in) :: Columns ! Columns integer array.
type(logical), intent(in), optional :: Global ! Global/local index toggle.
! Input/Output variable.
type(ELL_Matrix_type), intent(inout) :: ELLM ! Variable to be incremented.
! Internal variables.
type(logical) :: A_Global ! Actual global/local toggle.
type(integer) :: Column_Location ! Location in Columns array
! for the entry.
type(integer) :: i, j ! Loop parameters.
type(integer) :: location ! Loop index.
type(logical) :: Max_Nonzeros_Not_Exceeded ! Toggle for error check.
type(integer) :: shift ! Index shift.
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! Verify requirements.
VERIFY(Valid_State(ELLM),5) ! ELLM is valid.
VERIFY(Valid_State_NP(Values),5) ! Values is valid.
VERIFY(Valid_State_NP(Rows),5) ! Rows is valid.
VERIFY(Valid_State_NP(Columns),5) ! Columns is valid.
! Values, Rows & Columns size checks.
VERIFY(SIZE(Values,1) <= Length_PE(ELLM%Row_Structure),5)
VERIFY(SIZE(Values,2) <= ELLM%Max_Nonzeros,5)
VERIFY(SIZE(Rows) <= Length_PE(ELLM%Row_Structure),5)
VERIFY(SIZE(Rows) == SIZE(Values,1),5)
VERIFY(SIZE(Values) == SIZE(Columns),5)
! Global/Local toggle.
if (PRESENT(Global)) then
A_Global = Global
else
A_Global = .true.
end if
if (A_Global) then
shift = -First_PE(ELLM%Row_Structure) + 1
else
shift = 0
end if
! More requirement checks -- require that Rows entries are in the
! correct range.
VERIFY(Rows + shift .InInterval. (/1, Length_PE(ELLM%Row_Structure)/),5)
! Add the values.
Max_Nonzeros_Not_Exceeded = .true.
do i = 1, SIZE(Rows)
if (Rows(i) /= 0) then
do j = 1, SIZE(Values,2)
! Find a column location to store the entry.
Column_Location = 0
do location = 1, ELLM%Max_Nonzeros
if (ELLM%Columns(Rows(i) + shift, location) == 0 .or. &
ELLM%Columns(Rows(i) + shift, location) == Columns(i,j)) then
Column_Location = location
exit
end if
end do
! Make sure Max_Nonzeros is not exceeded (that is, that we
! found a spot to put the entry).
Max_Nonzeros_Not_Exceeded = &
Max_Nonzeros_Not_Exceeded .and. Column_Location /= 0
! Increment the entry.
ELLM%Values(Rows(i) + shift, Column_Location) = &
ELLM%Values(Rows(i) + shift, Column_Location) + Values(i,j)
ELLM%Columns(Rows(i) + shift, Column_Location) = Columns(i,j)
end do
end if
end do
! Make sure Max_Nonzeros is not exceeded (that is, that we
! found a spot to put all of the entries).
VERIFY(Max_Nonzeros_Not_Exceeded,1)
! Unset the updated? variables.
call Set_Not_Up_to_Date (ELLM)
! Verify guarantees.
VERIFY(Valid_State(ELLM),5) ! ELLM is still valid.
return
end subroutine Add_Values_ELL_Matrix_2