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