module classes_rectangle_writer use, intrinsic :: iso_fortran_env, only: DP => REAL64 use data_strings, only: max_line_length use procedures_checks, only: check_string_not_empty use classes_number_to_string, only: Concrete_Number_to_String, Null_Number_to_String, & Number_to_String_Wrapper implicit none private type, abstract, public :: Abstract_Rectangle_Writer private type(Number_to_String_Wrapper), allocatable :: strings(:, :) integer :: file_unit = 0 contains procedure :: construct => Abstract_construct procedure :: destroy => Abstract_destroy procedure, private :: allocate_strings => Abstract_allocate_strings procedure :: write => Abstract_write end type Abstract_Rectangle_Writer type, extends(Abstract_Rectangle_Writer), public :: Concrete_Rectangle_Writer end type Concrete_Rectangle_Writer type, extends(Abstract_Rectangle_Writer), public :: Null_Rectangle_Writer contains procedure :: construct => Null_construct procedure :: destroy => Null_destroy procedure :: write => Null_write end type Null_Rectangle_Writer type, public :: Rectangle_Writer_Wrapper class(Abstract_Rectangle_Writer), allocatable :: writer end type Rectangle_Writer_Wrapper contains !implementation Abstract_Rectangle_Writer subroutine Abstract_construct(this, filename, selectors) class(Abstract_Rectangle_Writer), intent(out) :: this character(len=*), intent(in) :: filename logical, intent(in) :: selectors(:, :) character(len=:), allocatable :: legend integer :: file_unit call check_string_not_empty("Abstract_Rectangle_Writer: construct: filename", filename) open(newunit=file_unit, recl=max_line_length, file=filename, action="write") this%file_unit = file_unit legend = "# i_step" call this%allocate_strings(legend, selectors) write(this%file_unit, *) legend end subroutine Abstract_construct subroutine Abstract_allocate_strings(this, legend, selectors) class(Abstract_Rectangle_Writer), intent(inout) :: this character(len=:), allocatable, intent(inout) :: legend logical, intent(in) :: selectors(:, :) type(Concrete_Number_to_String) :: string integer :: i_element, j_element allocate(this%strings(size(selectors, 1), size(selectors, 2))) do j_element = 1, size(this%strings, 2) do i_element = 1, size(this%strings, 1) if (selectors(i_element, j_element)) then allocate(Concrete_Number_to_String :: this%strings(i_element, j_element)%& string) legend = legend//" "//string%get(i_element)//"->"//string%get(j_element) else allocate(Null_Number_to_String :: this%strings(i_element, j_element)%string) end if end do end do end subroutine Abstract_allocate_strings subroutine Abstract_destroy(this) class(Abstract_Rectangle_Writer), intent(inout) :: this if (allocated(this%strings)) deallocate(this%strings) close(this%file_unit) end subroutine Abstract_destroy subroutine Abstract_write(this, i_step, observables) class(Abstract_Rectangle_Writer), intent(in) :: this integer, intent(in) :: i_step real(DP), intent(in) :: observables(:, :) character(len=:), allocatable :: string integer :: i_element, j_element string = "" do j_element = 1, size(this%strings, 2) do i_element = 1, size(this%strings, 1) string = string//this%strings(i_element, j_element)%string%& get(observables(i_element, j_element)) end do end do write(this%file_unit, *) i_step, string end subroutine Abstract_write !end implementation Abstract_Rectangle_Writer !implementation Null_Rectangle_Writer subroutine Null_construct(this, filename, selectors) class(Null_Rectangle_Writer), intent(out) :: this character(len=*), intent(in) :: filename logical, intent(in) :: selectors(:, :) end subroutine Null_construct subroutine Null_destroy(this) class(Null_Rectangle_Writer), intent(inout) :: this end subroutine Null_destroy subroutine Null_write(this, i_step, observables) class(Null_Rectangle_Writer), intent(in) :: this integer, intent(in) :: i_step real(DP), intent(in) :: observables(:, :) end subroutine Null_write !end implementation Null_Rectangle_Writer end module classes_rectangle_writer