|
| 1 | +!> Manager of `ErrorV` (TODO: xref) across the Fortran-Python interface |
| 2 | +!> |
| 3 | +!> Written by hand here. |
| 4 | +!> Generation to be automated in future (including docstrings of some sort). |
| 5 | +! |
| 6 | +! TODO: make it possible to reallocate the number of instances |
| 7 | +module m_error_v_manager |
| 8 | + |
| 9 | + use fpyfgen_derived_type_manager_helpers, only: finalise_derived_type_instance_number, & |
| 10 | + get_derived_type_free_instance_number |
| 11 | + use m_error_v, only: ErrorV |
| 12 | + |
| 13 | + implicit none |
| 14 | + private |
| 15 | + |
| 16 | + integer, public, parameter :: N_INSTANCES_DEFAULT = 4096 |
| 17 | + !! Default maximum number of instances which can be created simultaneously |
| 18 | + ! |
| 19 | + ! TODO: allow reallocation if possible |
| 20 | + |
| 21 | + ! This is the other trick, we hold an array of instances |
| 22 | + ! for tracking what is being passed back and forth across the interface. |
| 23 | + type(ErrorV), target, dimension(N_INSTANCES_DEFAULT) :: instance_array |
| 24 | + logical, dimension(N_INSTANCES_DEFAULT) :: instance_available = .true. |
| 25 | + |
| 26 | + public :: get_free_instance_number, & |
| 27 | + associate_pointer_with_instance, & |
| 28 | + finalise_instance |
| 29 | + |
| 30 | +contains |
| 31 | + |
| 32 | + function get_free_instance_number() result(instance_index) |
| 33 | + !! Get the index of a free instance |
| 34 | + |
| 35 | + integer :: instance_index |
| 36 | + !! Free instance index |
| 37 | + |
| 38 | + call get_derived_type_free_instance_number( & |
| 39 | + instance_index, & |
| 40 | + N_INSTANCES_DEFAULT, & |
| 41 | + instance_available, & |
| 42 | + instance_array & |
| 43 | + ) |
| 44 | + |
| 45 | + end function get_free_instance_number |
| 46 | + |
| 47 | + subroutine associate_pointer_with_instance(instance_index, instance_pointer) |
| 48 | + !! Associate a pointer with the instance corresponding to the given model index |
| 49 | + !! |
| 50 | + !! Stops execution if the instance has not already been initialised. |
| 51 | + |
| 52 | + integer, intent(in) :: instance_index |
| 53 | + !! Index of the instance to point to |
| 54 | + |
| 55 | + type(ErrorV), pointer, intent(inout) :: instance_pointer |
| 56 | + !! Pointer to associate |
| 57 | + |
| 58 | + call check_index_claimed(instance_index) |
| 59 | + instance_pointer => instance_array(instance_index) |
| 60 | + |
| 61 | + end subroutine associate_pointer_with_instance |
| 62 | + |
| 63 | + subroutine finalise_instance(instance_index) |
| 64 | + !! Finalise an instance |
| 65 | + |
| 66 | + integer, intent(in) :: instance_index |
| 67 | + !! Index of the instance to finalise |
| 68 | + |
| 69 | + call check_index_claimed(instance_index) |
| 70 | + call finalise_derived_type_instance_number( & |
| 71 | + instance_index, & |
| 72 | + N_INSTANCES_DEFAULT, & |
| 73 | + instance_available, & |
| 74 | + instance_array & |
| 75 | + ) |
| 76 | + |
| 77 | + end subroutine finalise_instance |
| 78 | + |
| 79 | + subroutine check_index_claimed(instance_index) |
| 80 | + !! Check that an index has already been claimed |
| 81 | + !! |
| 82 | + !! Stops execution if the index has not been claimed. |
| 83 | + |
| 84 | + integer, intent(in) :: instance_index |
| 85 | + !! Instance index to check |
| 86 | + |
| 87 | + if (instance_available(instance_index)) then |
| 88 | + ! TODO: switch to errors here - will require some thinking |
| 89 | + print *, "Index ", instance_index, " has not been claimed" |
| 90 | + error stop 1 |
| 91 | + end if |
| 92 | + |
| 93 | + if (instance_index < 1) then |
| 94 | + ! TODO: switch to errors here - will require some thinking |
| 95 | + print *, "Requested index is ", instance_index, " which is less than 1" |
| 96 | + error stop 1 |
| 97 | + end if |
| 98 | + |
| 99 | + if (instance_array(instance_index) % instance_index < 1) then |
| 100 | + ! TODO: switch to errors here - will require some thinking |
| 101 | + print *, "Index ", instance_index, " is associated with an instance that has instance index < 1", & |
| 102 | + "instance's instance_index attribute ", instance_array(instance_index) % instance_index |
| 103 | + error stop 1 |
| 104 | + end if |
| 105 | + |
| 106 | + end subroutine check_index_claimed |
| 107 | + |
| 108 | +end module m_error_v_manager |
0 commit comments