Automatic computation of Hopping_Matrix_Type%Multiplicity
The field Hopping_Matrix_Type%Multiplicity contains the number of times a given orbital appears in the list of bonds. Therefore it could be deduced from Hopping_Matrix_Type%List which contains the bonds emanating from a unit cell. It seems a good idea to have it automatically computed, instead of relying in the user to enter it, in particular if the user defines a new set of hopping with checkerboard decomposition. This will ensure consistency and avoid bugs potentially difficult to detect.
The algorithm to compute it is basically easy (just a loop over Hopping_Matrix_Type%List).
Concerning the design, I see some possibilities:
- Define a procedure like this
Subroutine Set_Multiplicity(this) Type(Hopping_Matrix_Type), intent(INOUT) :: this
Cons: again, we rely in the user to call it. And we have to properly document it.
- Considering that, as far as I can see, Hopping_Matrix_Type%Multiplicity is only used in Predefined_Hoppings_set_OPT, we could remove altogether the field Hopping_Matrix_Type%Multiplicity and define a function that computes it, something like
Subroutine Compute_Multiplicity(hop_matrix, multiplicity) Type(Hopping_Matrix_Type), intent(IN) :: hop_matrix Integer, intent(OUT) :: multiplicity(:)
Pros: we remove completely the possibility of errors in Multiplicity. No need to document it. Cons: at the moment Multiplicity is only used in a subroutine, presumably called only once. Should we use it in more routines, we may lose in efficiency by computing it every time.
- Let the object compute Multiplicity the first time is needed, and cache the result. This is obtained by having a method of Hopping_Matrix_Type like that
Function Multiplicity(n) implicit none n, intent(IN) :: Integer Multiplicity :: dble If (is_cache_valid) then Multiplicity = m_Multiplicity(n) else call Set_Multiplicity() is_cache_valid = .true. Multiplicity = m_Multiplicity(n) end if
Here, is_cache_valid is a boolean that signals if multiplicity has been computed. m_Multiplicity is where the data are stored. Both should be, I think, private variables.
Pro: This can be regarded as a "internal" method that we do not need to necessarily document. Good efficiency. We hide the actual implementation of Multiplicity, without changing the syntax: that is, still Multiplicity(n) gives me the multiplicity of the n-th orbital.
Cons: Perhaps slightly more complex in the logic.
I personally favor solution 3., but I am not entirely sure: does Fortran allow for such type of c++-like design?