Neko 1.99.1
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
generic_file.f90
Go to the documentation of this file.
1! Copyright (c) 2019-2023, The Neko Authors
2! All rights reserved.
3!
4! Redistribution and use in source and binary forms, with or without
5! modification, are permitted provided that the following conditions
6! are met:
7!
8! * Redistributions of source code must retain the above copyright
9! notice, this list of conditions and the following disclaimer.
10!
11! * Redistributions in binary form must reproduce the above
12! copyright notice, this list of conditions and the following
13! disclaimer in the documentation and/or other materials provided
14! with the distribution.
15!
16! * Neither the name of the authors nor the names of its
17! contributors may be used to endorse or promote products derived
18! from this software without specific prior written permission.
19!
20! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21! "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22! LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23! FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24! COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25! INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26! BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27! LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28! CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29! LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30! ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31! POSSIBILITY OF SUCH DAMAGE.
32!
34 use num_types, only: rp
35 use utils, only: neko_warning, neko_error, &
37 use comm, only: pe_rank, neko_comm
38 use mpi_f08, only: mpi_bcast, mpi_logical
39 implicit none
40
42 type, abstract :: generic_file_t
43 character(len=1024), private :: fname
44 integer, private :: counter = -1
45 integer, private :: start_counter = 0
47 logical :: serial = .false.
48 logical :: overwrite = .false.
49 contains
51 procedure :: init => generic_file_init
52
53 procedure(generic_file_write), deferred :: write
54
55 procedure(generic_file_read), deferred :: read
57 procedure :: get_fname => generic_file_get_fname
59 procedure :: get_base_fname => generic_file_get_base_fname
61 procedure :: set_counter => generic_file_set_counter
63 procedure :: get_counter => generic_file_get_counter
65 procedure :: set_start_counter => generic_file_set_start_counter
67 procedure :: get_start_counter => generic_file_get_start_counter
69 procedure :: increment_counter => generic_file_increment_counter
71 procedure :: check_exists => generic_file_check_exists
73 procedure :: set_overwrite => generic_file_set_overwrite
74 end type generic_file_t
75
76 abstract interface
77 subroutine generic_file_write(this, data, t)
78 import :: generic_file_t
79 import :: rp
80 class(generic_file_t), intent(inout) :: this
81 class(*), target, intent(in) :: data
82 real(kind=rp), intent(in), optional :: t
83 end subroutine generic_file_write
84 end interface
85
86 abstract interface
87 subroutine generic_file_read(this, data)
88 import :: generic_file_t
89 class(generic_file_t) :: this
90 class(*), target, intent(inout) :: data
91 end subroutine generic_file_read
92 end interface
93
94contains
95
98 subroutine generic_file_init(this, fname)
99 class(generic_file_t) :: this
100 character(len=*) :: fname
101
102 this%fname = fname
103 this%counter = -1
104
105 end subroutine generic_file_init
106
108 function generic_file_get_fname(this) result(fname)
109 class(generic_file_t), intent(in) :: this
110 character(len=1024) :: fname
111 integer :: suffix_pos
112 character(len=5) :: id_str
113
114 if (this%counter .ne. -1) then
115 suffix_pos = filename_suffix_pos(this%fname)
116 write(id_str, '(i5.5)') this%counter
117 fname = trim(this%fname(1:suffix_pos-1)) // id_str // &
118 this%fname(suffix_pos:)
119 else
120 fname = this%fname
121 end if
122
123 end function generic_file_get_fname
124
126 function generic_file_get_base_fname(this) result(fname)
127 class(generic_file_t), intent(in) :: this
128 character(len=1024) :: fname
129 integer :: suffix_pos
130
131 fname = trim(this%fname)
132
133 end function generic_file_get_base_fname
134
136 subroutine generic_file_set_counter(this, n)
137 class(generic_file_t), intent(inout) :: this
138 integer, intent(in) :: n
139 this%counter = n
140 end subroutine generic_file_set_counter
141
144 class(generic_file_t), intent(inout) :: this
145
146 if (this%counter .eq. -1) then
147 this%counter = this%start_counter
148 else
149 this%counter = this%counter + 1
150 end if
151 end subroutine generic_file_increment_counter
152
155 class(generic_file_t), intent(inout) :: this
156 integer, intent(in) :: n
157 this%start_counter = n
158 end subroutine generic_file_set_start_counter
159
161 pure function generic_file_get_counter(this) result(n)
162 class(generic_file_t), intent(in) :: this
163 integer :: n
164 n = this%counter
165 end function generic_file_get_counter
166
168 pure function generic_file_get_start_counter(this) result(n)
169 class(generic_file_t), intent(in) :: this
170 integer :: n
171 n = this%start_counter
173
176 class(generic_file_t), intent(in) :: this
177 character(len=1024) :: fname
178 logical :: file_exists
179 integer :: neko_mpi_ierr
180
181 fname = this%get_fname()
182 file_exists = .false.
183
184 if (pe_rank .eq. 0 .or. this%serial) then
185 ! Stop if the file does not exist
186 inquire(file = fname, exist = file_exists)
187 end if
188
189 if (.not. this%serial) then
190 call mpi_bcast(file_exists, 1, mpi_logical, 0, neko_comm, neko_mpi_ierr)
191 end if
192
193 if (.not. file_exists) then
194 call neko_error('File does not exist: ' // trim(fname))
195 end if
196
197 end subroutine generic_file_check_exists
198
200 subroutine generic_file_set_overwrite(this, overwrite)
201 class(generic_file_t), intent(inout) :: this
202 logical, intent(in) :: overwrite
203 character(len=80) :: suffix
204
205 call filename_suffix(this%get_fname(), suffix)
206 call neko_warning("No set_overwrite defined for " // trim(suffix) // " yet")
207 end subroutine generic_file_set_overwrite
208end module generic_file
Definition comm.F90:1
integer, public pe_rank
MPI rank.
Definition comm.F90:55
type(mpi_comm), public neko_comm
MPI communicator.
Definition comm.F90:42
Module for file I/O operations.
Definition file.f90:34
character(len=1024) function generic_file_get_fname(this)
Get a file's name.
subroutine generic_file_check_exists(this)
check if the file exists
pure integer function generic_file_get_counter(this)
Get the file counter.
subroutine generic_file_set_start_counter(this, n)
Set the file start counter to n.
subroutine generic_file_increment_counter(this)
Increment the file counter by 1.
subroutine generic_file_init(this, fname)
Generic file constructor.
character(len=1024) function generic_file_get_base_fname(this)
Get base name without counter.
pure integer function generic_file_get_start_counter(this)
Get the file start counter.
subroutine generic_file_set_overwrite(this, overwrite)
Set overwrite mode.
subroutine generic_file_set_counter(this, n)
Set the file counter to n.
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:12
Utilities.
Definition utils.f90:35
subroutine, public neko_warning(warning_msg)
Reports a warning to standard output.
Definition utils.f90:346
subroutine, public filename_suffix(fname, suffix)
Extract a filename's suffix.
Definition utils.f90:108
pure integer function, public filename_suffix_pos(fname)
Find position (in the string) of a filename's suffix.
Definition utils.f90:58
A generic file handler.