Neko 0.9.99
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
csv_file.f90
Go to the documentation of this file.
1! Copyright (c) 2020-2024, 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!
36 use vector, only: vector_t
37 use matrix, only: matrix_t
39 use utils, only: neko_error
40 use num_types, only: rp
41 use logger, only: neko_log, log_size
42 use comm
43 implicit none
44
45 type, public, extends(generic_file_t) :: csv_file_t
46 character(len=1024) :: header = ""
47 logical :: header_is_written = .false.
48 contains
50 procedure :: write => csv_file_write
52 procedure :: read => csv_file_read
54 procedure :: set_header => csv_file_set_header
56 procedure :: count_lines => csv_file_count_lines
57 end type csv_file_t
58
59contains
60
65 subroutine csv_file_write(this, data, t)
66 class(csv_file_t), intent(inout) :: this
67 class(*), target, intent(in) :: data
68 real(kind=rp), intent(in), optional :: t
69
70 type(vector_t), pointer :: vec
71 type(matrix_t), pointer :: mat
72
73 nullify(vec)
74 nullify(mat)
75
76 select type (data)
77 type is (vector_t)
78 if (.not. allocated(data%x)) then
79 call neko_error("Vector is not allocated. Use &
80&vector%init() to associate your array &
81&with a vector_t object")
82 end if
83 vec => data
84
85 type is (matrix_t)
86 if (.not. allocated(data%x)) then
87 call neko_error("Matrix is not allocated. Use &
88&matrix%init() to associate your array &
89&with a matrix_t object")
90 end if
91 mat => data
92
93 class default
94 call neko_error("Invalid data. Expected vector_t or &
95&matrix_t")
96 end select
97
98 ! Write is performed on rank 0
99 if (pe_rank .eq. 0) then
100
101 call neko_log%message("Writing to " // trim(this%fname))
102 if (associated(vec)) then
103 call csv_file_write_vector(this, vec, t)
104 else if (associated(mat)) then
105 call csv_file_write_matrix(this, mat, t)
106 end if
107
108 end if
109
110 end subroutine csv_file_write
111
120 subroutine csv_file_write_vector(f, data, t)
121 class(csv_file_t), intent(inout) :: f
122 type(vector_t), intent(in) :: data
123 real(kind=rp), intent(in), optional :: t
124 integer :: file_unit, ierr
125
126 open(file = trim(f%fname), position = "append", iostat = ierr, &
127 newunit = file_unit)
128 if (ierr .ne. 0) call neko_error("Error while opening " // trim(f%fname))
129
130 ! write header if not empty and if not already written
131 if (f%header .ne. "" .and. .not. f%header_is_written) then
132 write (file_unit, '(A)') trim(f%header)
133 f%header_is_written = .true.
134 end if
135
136 ! Add time at the beginning if specified
137 if (present(t)) write (file_unit, '(g0,",")', advance = "no") t
138
139 write (file_unit, '(*(g0,","))', advance = "no") data%x(1:data%n-1)
140 write (file_unit,'(g0)') data%x(data%n)
141
142 close(file_unit)
143
144 end subroutine csv_file_write_vector
145
151 subroutine csv_file_write_matrix(f, data, t)
152 class(csv_file_t), intent(inout) :: f
153 type(matrix_t), intent(in) :: data
154 real(kind=rp), intent(in), optional :: t
155 integer :: file_unit, i, ierr
156
157 open(file = trim(f%fname), position = "append", iostat = ierr, &
158 newunit = file_unit)
159 if (ierr .ne. 0) call neko_error("Error while opening " // trim(f%fname))
160
161 ! write header if not empty and if not already written
162 if (f%header .ne. "" .and. .not. f%header_is_written) then
163 write (file_unit, '(A)') trim(f%header)
164 f%header_is_written = .true.
165 end if
166
167 do i = 1, data%nrows
168 if (present(t)) write (file_unit, '(g0,",")', advance = "no") t
169 write (file_unit, '(*(g0,","))', advance = "no") &
170 data%x(i, 1:data%ncols-1)
171 write (file_unit, '(g0)') data%x(i, data%ncols)
172 end do
173
174 close(file_unit)
175
176 end subroutine csv_file_write_matrix
177
181 subroutine csv_file_read(this, data)
182 class(csv_file_t) :: this
183 class(*), target, intent(inout) :: data
184 type(vector_t), pointer :: vec
185 type(matrix_t), pointer :: mat
186
187 call this%check_exists()
188
189 nullify(vec)
190 nullify(mat)
191
192 select type (data)
193 type is (vector_t)
194 vec => data
195 if (.not. allocated(data%x)) then
196 call neko_error("Vector is not allocated. Use &
197&vector%init() to associate your array &
198&with a vector_t object")
199 end if
200
201 type is (matrix_t)
202 mat => data
203 if (.not. allocated(data%x)) then
204 call neko_error("Matrix is not allocated. Use &
205&matrix%init() to associate your array &
206&with a matrix_t object")
207 end if
208
209
210 class default
211 call neko_error("Invalid data type for csv_file (expected: vector_t, &
212&matrix_t)")
213 end select
214
215 if (pe_rank .eq. 0) then
216
217 call neko_log%newline()
218 call neko_log%message("Reading csv file " // trim(this%fname))
219 if (associated(vec)) then
220 call csv_file_read_vector(this, vec)
221 else if (associated(mat)) then
222 call csv_file_read_matrix(this, mat)
223 end if
224
225 end if
226
227 end subroutine csv_file_read
228
236 subroutine csv_file_read_vector(f, vec)
237 type(csv_file_t), intent(inout) :: f
238 type(vector_t), intent(inout) :: vec
239 integer :: ierr, file_unit, n_lines
240 character(len=80) :: tmp
241
242 n_lines = f%count_lines()
243
244 open(file = trim(f%fname), status = 'old', newunit = file_unit, &
245 iostat = ierr)
246 if (ierr .ne. 0) call neko_error("Error while opening " // trim(f%fname))
247
248 ! If there is more than 1 line, assume that means there is a header
249 if (n_lines .gt. 1) then
250 read (file_unit, '(A)') tmp
251 f%header = trim(tmp)
252 end if
253
254 read (file_unit,*) vec%x
255 close(unit = file_unit)
256
257
258 end subroutine csv_file_read_vector
259
265 subroutine csv_file_read_matrix(f, mat)
266 type(csv_file_t), intent(inout) :: f
267 type(matrix_t), intent(inout) :: mat
268 integer :: ierr, file_unit, i, n_lines
269 character(len=80) :: tmp
270
271 n_lines = f%count_lines()
272
273 open(file = trim(f%fname), status = 'old', newunit = file_unit, &
274 iostat = ierr)
275 if (ierr .ne. 0) call neko_error("Error while opening " // trim(f%fname))
276
277 ! If the number of lines is larger than the number of rows in the
278 ! matrix, assume that means there is a header
279 if (n_lines .gt. mat%nrows) then
280 read (file_unit, '(A)') tmp
281 f%header = trim(tmp)
282 end if
283
284 do i = 1, mat%nrows
285 read (file_unit,*) mat%x(i,:)
286 end do
287 close(unit = file_unit)
288
289 end subroutine csv_file_read_matrix
290
295 subroutine csv_file_set_header(this, hd)
296 class(csv_file_t), intent(inout) :: this
297 character(len=*), intent(in) :: hd
298
299 this%header = trim(hd)
300
301 end subroutine csv_file_set_header
302
305 function csv_file_count_lines(this) result(n)
306 class(csv_file_t), intent(in) :: this
307
308 integer :: n
309 integer :: ierr, file_unit
310
311 call this%check_exists()
312
313 open(file = trim(this%fname), status = 'old', newunit = file_unit, &
314 iostat = ierr)
315 if (ierr .ne. 0) call neko_error("Error while opening " // trim(this%fname))
316 rewind(file_unit)
317
318 n = 0
319
320 ! Keep reading (ierr = 0) until we reach the end (ierr != 0)
321 do
322 read (file_unit, *, iostat = ierr)
323 if (ierr .ne. 0) exit
324 n = n + 1
325 end do
326 rewind(file_unit)
327 close(unit = file_unit)
328
329 end function csv_file_count_lines
330
331
332end module csv_file
Definition comm.F90:1
integer pe_rank
MPI rank.
Definition comm.F90:28
File format for .csv files, used for any read/write operations involving floating point data.
Definition csv_file.f90:35
subroutine csv_file_set_header(this, hd)
Sets the header for a csv file. For example: hd = "u,v,w,p".
Definition csv_file.f90:296
subroutine csv_file_write_matrix(f, data, t)
Writes a matrix_t object to an output file. If the parameter t is present, it will be appended at the...
Definition csv_file.f90:152
subroutine csv_file_write_vector(f, data, t)
Writes a vector_t object to an output file, in a row format. If the parameter t is present,...
Definition csv_file.f90:121
subroutine csv_file_write(this, data, t)
Writes data to an output file.
Definition csv_file.f90:66
subroutine csv_file_read(this, data)
Reads data from an input file.
Definition csv_file.f90:182
subroutine csv_file_read_matrix(f, mat)
Read a matrix from a csv file.
Definition csv_file.f90:266
integer function csv_file_count_lines(this)
Count the number of lines in a file by going through it entirely until the end is reached.
Definition csv_file.f90:306
subroutine csv_file_read_vector(f, vec)
Read a vector (i.e. data on a single row) from a csv file.
Definition csv_file.f90:237
Module for file I/O operations.
Definition file.f90:34
Logging routines.
Definition log.f90:34
type(log_t), public neko_log
Global log stream.
Definition log.f90:65
integer, parameter, public log_size
Definition log.f90:42
Defines a matrix.
Definition matrix.f90:34
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:12
Utilities.
Definition utils.f90:35
Defines a vector.
Definition vector.f90:34
A generic file handler.