FE-Project
Loading...
Searching...
No Matches
scale_file_restart_meshfield.F90
Go to the documentation of this file.
1!-------------------------------------------------------------------------------
2!> module FElib / File / Restart
3!!
4!! @par Description
5!! A module for outputting data to restart simulations
6!!
7!! @author Yuta Kawai, Team SCALE
8!!
9!<
10!-------------------------------------------------------------------------------
11#include "scaleFElib.h"
13 !-----------------------------------------------------------------------------
14 !
15 !++ Used modules
16 !
17 use scale_precision
18 use scale_io
19 use scale_prc, only: &
20 prc_myrank, &
21 prc_abort
22 use scale_file_h, only: &
23 file_file_max
26
38
41
42 use scale_file_base_meshfield, only: &
44
45 use scale_mesh_base1d, only: &
46 mf1d_dimtype_x => meshbase1d_dimtypeid_x, &
47 mf1d_dtype_num => meshbase1d_dimtype_num
48 use scale_mesh_base2d, only: &
49 mf2d_dimtype_x => meshbase2d_dimtypeid_x, &
50 mf2d_dimtype_y => meshbase2d_dimtypeid_y, &
51 mf2d_dtype_num => meshbase2d_dimtype_num
52 use scale_mesh_base3d, only: &
53 mf3d_dimtype_x => meshbase3d_dimtypeid_x, &
54 mf3d_dimtype_y => meshbase3d_dimtypeid_y, &
55 mf3d_dimtype_z => meshbase3d_dimtypeid_z, &
56 mf3d_dtype_num => meshbase3d_dimtype_num
57
58 !-----------------------------------------------------------------------------
59 implicit none
60 private
61 !-----------------------------------------------------------------------------
62 !
63 !++ Public type & procedures
64 !
65
66 !> Base derived type to manage restart file with each component
67 type :: file_restart_meshfield
68 type(FILE_base_meshfield), pointer :: file_ptr => null() !< Pointer to the file object for managing restart file with each component
69 logical :: is_file_ptr_main !< Flag whether the file_ptr is the main file object
70
71 logical :: flag_output !< Flag whether output restart file
72 character(len=H_LONG) :: in_basename !< Basename of the input file
73 logical :: in_postfix_timelabel !< Flag whether timelabel is added to the basename of input file
74
75 character(len=H_LONG) :: out_basename !< Basename of the output file
76 logical :: out_postfix_timelabel !< Flag whether timelabel is added to the basename of output file
77 character(len=H_MID) :: out_title !< Title of the output file
78 character(len=H_SHORT) :: out_dtype !< Output data type (DEFAULT, REAL4 or REAL8)
79 contains
80 procedure, private :: Set_information => file_restart_meshfield_component_set_information
81 end type file_restart_meshfield
82 type(file_restart_meshfield), public :: restart_file !< An object to manage main restart file
83
84 !> Derived type to manage restart file with each component
85 type, extends(file_restart_meshfield), public :: file_restart_meshfield_component
86 integer :: registered_comp_id !< ID of the component registered for restart file
87 contains
88 procedure :: init1 => file_restart_meshfield_component_init1
89 procedure :: init2 => file_restart_meshfield_component_init2
90 generic :: init => init1, init2
91 procedure :: open => file_restart_meshfield_component_open
92 procedure :: file_restart_meshfield_component_create
93 generic :: create => file_restart_meshfield_component_create
94 procedure :: file_restart_meshfield_component_def_var
95 generic :: def_var => file_restart_meshfield_component_def_var
96 procedure :: end_def => file_restart_meshfield_component_enddef
97 procedure :: file_restart_meshfield_component_write_var2d
98 procedure :: file_restart_meshfield_component_write_var3d
99 generic :: write_var => &
100 file_restart_meshfield_component_write_var2d, &
101 file_restart_meshfield_component_write_var3d
102 procedure :: close => file_restart_meshfield_component_close
103 procedure :: file_restart_meshfield_component_read_var2d
104 procedure :: file_restart_meshfield_component_read_var3d
105 generic :: read_var => &
106 file_restart_meshfield_component_read_var2d, &
107 file_restart_meshfield_component_read_var3d
108 procedure :: final => file_restart_meshfield_component_final
109 end type
110
111 ! Public procedures for main restart file
114
115 !-----------------------------------------------------------------------------
116 !
117 !++ Public parameters & variables
118 !
119
120 !-----------------------------------------------------------------------------
121 !
122 !++ Private procedures & variables
123 !
124 type(file_base_meshfield), target :: file_main !< A file object to manage main restart file
125
126 logical :: is_file_main_opened !< Flag whether the main restart file is opened
127 logical :: is_file_main_created !< Flag whether the main restart file is created
128 logical :: is_file_main_enddef !< Flag whether the main restart file is in enddef mode
129 logical :: is_file_main_closed !< Flag whether the main restart file is closed
130
131contains
132
133!----------------
134 !> Setup the main restart file
135!OCL SERIAL
137 implicit none
138
139 logical :: output_flag = .false. !< Flag whether output restart file
140 character(len=H_LONG) :: in_basename = '' !< Basename of the input file
141 logical :: in_postfix_timelabel = .false. !< Flag whether timelabel is added to the basename of input file
142 character(len=H_LONG) :: out_basename = '' !< Basename of the output file
143 logical :: out_postfix_timelabel = .true. !< Flag whether timelabel is added to the basename of output file
144 character(len=H_MID) :: out_title = '' !< Title of the output file
145 character(len=H_SHORT) :: out_dtype = 'DEFAULT' !< Output data type (DEFAULT, REAL4 or REAL8)
146
147 namelist / param_restart / &
148 output_flag, &
149 in_basename, &
150 in_postfix_timelabel, &
151 out_basename, &
152 out_postfix_timelabel, &
153 out_title, &
154 out_dtype
155
156 integer :: ierr
157 !----------------------------------------
158
159 log_newline
160
161 !--- read namelist
162 rewind(io_fid_conf)
163 read(io_fid_conf,nml=param_restart,iostat=ierr)
164 if( ierr < 0 ) then !--- missing
165 log_info("FILE_restart_meshfield_setup",*) 'Not found namelist. Default used.'
166 elseif( ierr > 0 ) then !--- fatal error
167 log_error("FILE_restart_meshfield_setup",*) 'Not appropriate names in namelist PARAM_RESTART. Check!'
168 call prc_abort
169 endif
170 log_nml(param_restart)
171
172 ! Setup the information of the main restart file
173
174 call restart_file%Set_information( in_basename, in_postfix_timelabel, &
175 out_basename, out_postfix_timelabel, out_dtype, out_title )
176
177 restart_file%flag_output = output_flag
178
179 restart_file%file_ptr => null() ! Initialize the pointer to null
180 is_file_main_opened = .false.
181 is_file_main_created = .false.
182 is_file_main_enddef = .false.
183 is_file_main_closed = .false.
184
185 return
186 end subroutine file_restart_meshfield_setup
187
188 !> Finalize the main restart file
189!OCL SERIAL
191 implicit none
192 !--------------------------------------------------
193 if ( associated(restart_file%file_ptr) ) then
194 call restart_file%file_ptr%Final()
195 nullify( restart_file%file_ptr )
196 end if
197 return
199
200 !> Initialize an object to manage restart file with each component, and register the component to the main restart file
201!OCL SERIAL
202 subroutine file_restart_meshfield_component_init1( this, &
203 comp_name, var_num, dim_name_postfix, &
204 mesh1D, mesh2D, meshCubedSphere2D, &
205 mesh3D, meshCubedSphere3D )
206
207 use scale_file_common_meshfield, only: &
209 implicit none
210
211 class(file_restart_meshfield_component), intent(inout) :: this
212 character(*), intent(in) :: comp_name
213 integer, intent(in) :: var_num
214 character(len=*), optional, intent(in) :: dim_name_postfix
215 class(meshbase1d), target, optional, intent(in) :: mesh1d
216 class(meshrectdom2d), target, optional, intent(in) :: mesh2d
217 class(meshcubedspheredom2d), target, optional, intent(in) :: meshcubedsphere2d
218 class(meshcubedom3d), target, optional, intent(in) :: mesh3d
219 class(meshcubedspheredom3d), target, optional, intent(in) :: meshcubedsphere3d
220
221 character(len=H_SHORT) :: dim_name_postfix_
222 !--------------------------------------------------
223
224 ! Setup an object to manage restart file with each component, and register the component to the main restart file
225
226 if (present(dim_name_postfix)) then
227 dim_name_postfix_ = trim(dim_name_postfix)
228 else
229 dim_name_postfix_ = ""
230 end if
231
232 if ( .not. associated(restart_file%file_ptr) ) then
233 ! Initialize the main restart file
234 call file_main%Init( var_num, comp_name, dim_name_postfix_, &
235 mesh1d, mesh2d, meshcubedsphere2d, mesh3d, meshcubedsphere3d )
236
237 restart_file%file_ptr => file_main
238 ! The first registered component is the main component, and its ID is 1
239 this%registered_comp_id = 1
240 else
241 ! Register the subsequent component to the main restart file
242 call file_main%Register_comp( this%registered_comp_id, & ! (out)
243 comp_name, var_num, dim_name_postfix_, & ! (in)
244 mesh1d, mesh2d, meshcubedsphere2d, mesh3d, meshcubedsphere3d ) ! (in)
245 end if
246
247 this%file_ptr => file_main
248 this%is_file_ptr_main = .true.
249
250 ! Setup the information of the component restart file based on the main restart file
251 call this%Set_information( &
252 restart_file%in_basename, restart_file%in_postfix_timelabel, &
253 restart_file%out_basename, restart_file%out_postfix_timelabel, &
254 restart_file%out_dtype, restart_file%out_title )
255
256 return
257 end subroutine file_restart_meshfield_component_init1
258
259 !> Initialize an object to manage restart file with each component.
260 !! Restart data for this component are individually outputted to a separate file, not to the main restart file.
261 !!
262!OCL SERIAL
263 subroutine file_restart_meshfield_component_init2( this, &
264 comp_name, &
265 in_basename, in_postfix_timelabel, &
266 out_basename, out_postfix_timelabel, &
267 out_dtype, out_title, &
268 var_num, dim_name_postfix, &
269 mesh1D, &
270 mesh2D, meshCubedSphere2D, &
271 mesh3D, meshCubedSphere3D )
272
273 implicit none
274
275 class(file_restart_meshfield_component), intent(inout) :: this
276 character(*), intent(in) :: comp_name
277 character(*), intent(in) :: in_basename
278 logical, intent(in) :: in_postfix_timelabel
279 character(*), intent(in) :: out_basename
280 logical, intent(in) :: out_postfix_timelabel
281 character(*), intent(in) :: out_title
282 character(*), intent(in) :: out_dtype
283 integer, intent(in) :: var_num
284 character(len=*), intent(in) :: dim_name_postfix
285 class(meshbase1d), target, optional, intent(in) :: mesh1d
286 class(meshrectdom2d), target, optional, intent(in) :: mesh2d
287 class(meshcubedspheredom2d), target, optional, intent(in) :: meshcubedsphere2d
288 class(meshcubedom3d), target, optional, intent(in) :: mesh3d
289 class(meshcubedspheredom3d), target, optional, intent(in) :: meshcubedsphere3d
290 !--------------------------------------------------
291
292 call this%Set_information( in_basename, in_postfix_timelabel, &
293 out_basename, out_postfix_timelabel, out_dtype, out_title )
294
295 if ( .not. associated(this%file_ptr) ) then
296 ! In this case, restart data for this component is individually outputted to a separate file, not to the main restart file.
297 ! Therefore, a new file object is created for this component.
298 allocate( this%file_ptr )
299 call this%file_ptr%Init( var_num, comp_name, dim_name_postfix, &
300 mesh1d, mesh2d, meshcubedsphere2d, mesh3d, meshcubedsphere3d )
301
302 this%registered_comp_id = 1
303 this%is_file_ptr_main = .false.
304 else
305 log_info("FILE_restart_meshfield_component_Init2",*) 'File object for this component is already associated, which is unexpected. Check!'
306 call prc_abort
307 end if
308
309 return
310 end subroutine file_restart_meshfield_component_init2
311
312 !> Open a restart file
313!OCL SERIAL
314 subroutine file_restart_meshfield_component_open( &
315 this )
316
317 use scale_time, only: &
318 time_gettimelabel
319 implicit none
320
321 class(file_restart_meshfield_component), intent(inout) :: this
322
323 character(len=19) :: timelabel
324 character(len=H_LONG) :: basename
325 !--------------------------------------------------------------
326
327 if ( this%in_basename == '' ) then
328 log_info("FILE_restart_meshfield_component_open",*) 'Restart file is not specified. Check!'
329 call prc_abort
330 return
331 end if
332
333 if ( this%is_file_ptr_main ) then
334 if ( is_file_main_opened ) then
335 log_info("FILE_restart_meshfield_component_open",*) 'Main restart file is already opened. Skipping opening.'
336 else
337 is_file_main_opened = .true.
338 end if
339 end if
340
341 !--------------------------------
342
343 if ( this%in_postfix_timelabel ) then
344 call time_gettimelabel( timelabel )
345 basename = trim(this%in_basename)//'_'//trim(timelabel)
346 else
347 basename = trim(this%in_basename)
348 endif
349
350 !--------------------------------
351
352 log_newline
353 log_info("FILE_restart_meshfield_component_open",*) 'Open restart file'
354 call this%file_ptr%open( basename, myrank=prc_myrank )
355
356 return
357 end subroutine file_restart_meshfield_component_open
358
359 !> Create a restart file
360!OCL SERIAL
361 subroutine file_restart_meshfield_component_create( &
362 this )
363
364 use scale_time, only: &
365 time_gettimelabel, &
366 nowdate => time_nowdate, &
367 nowsubsec => time_nowsubsec
368 implicit none
369
370 class(file_restart_meshfield_component), intent(inout) :: this
371
372 character(len=19) :: timelabel
373 character(len=H_LONG) :: basename
374 character(len=34) :: tunits
375 character(len=H_SHORT) :: calendar
376 logical :: fileexisted
377 !--------------------------------------------------------------
378
379 if ( this%out_basename == '' ) return
380
381 if ( this%is_file_ptr_main ) then
382 if ( is_file_main_created ) then
383 log_info("FILE_restart_meshfield_component_create",*) 'Main restart file is already created. Skipping creation.'
384 else
385 is_file_main_created = .true.
386 end if
387 end if
388
389 !--------------------------------
390
391 log_newline
392 log_info("FILE_restart_meshfield_component_create",*) 'Create restart file'
393
394 if ( this%out_postfix_timelabel ) then
395 call time_gettimelabel( timelabel )
396 basename = trim(this%out_basename)//'_'//trim(timelabel)
397 else
398 basename = trim(this%out_basename)
399 endif
400
401 log_info("FILE_restart_meshfield_component_create",*) 'basename: ', trim(basename)
402
403
404 call this%file_ptr%Create( basename, this%out_title, this%out_dtype, & ! (in)
405 fileexisted, & ! (out)
406 myrank=prc_myrank, tunits=tunits, calendar=calendar ) ! (in)
407
408 if ( .not. fileexisted ) then
409 call this%file_ptr%Put_GlobalAttribute_time( nowdate, nowsubsec )
410 end if
411
412 return
413 end subroutine file_restart_meshfield_component_create
414
415 !> Define a variable in the restart file
416!OCL SERIAL
417 subroutine file_restart_meshfield_component_def_var( this, &
418 field, desc, vid, dim_type_id )
419 implicit none
420
421 class(file_restart_meshfield_component), intent(inout) :: this
422 class(meshfieldbase), intent(in) :: field
423 character(len=*), intent(in) :: desc
424 integer, intent(in) :: vid
425 integer, intent(in) :: dim_type_id
426 !------------------------------------------------------------------
427
428 call this%file_ptr%Def_var( &
429 field, desc, vid, dim_type_id, this%out_dtype, &
430 comp_id=this%registered_comp_id )
431
432 return
433 end subroutine file_restart_meshfield_component_def_var
434
435 !> Finalize the definition of variables in the restart file
436!OCL SERIAL
437 subroutine file_restart_meshfield_component_enddef( this )
438 implicit none
439 class(file_restart_meshfield_component), intent(inout) :: this
440 !--------------------------------------------------------------
441
442 if ( this%is_file_ptr_main ) then
443 if ( is_file_main_enddef ) then
444 log_info("FILE_restart_meshfield_component_enddef",*) 'Main restart file is already in enddef mode. Skipping enddef.'
445 else
446 is_file_main_enddef = .true.
447 end if
448 end if
449
450 call this%file_ptr%End_def()
451 return
452 end subroutine file_restart_meshfield_component_enddef
453
454 !> Write a 2D variable to the restart file
455!OCL SERIAL
456 subroutine file_restart_meshfield_component_write_var2d( this, &
457 vid, field2d )
458
459 use scale_time, only: time_nowdaysec
460 implicit none
461
462 class(file_restart_meshfield_component), intent(inout) :: this
463 integer, intent(in) :: vid
464 class(meshfield2d), intent(in) :: field2d
465 !--------------------------------------------------
466
467 call this%file_ptr%Write_var2D( vid, field2d, time_nowdaysec, time_nowdaysec, &
468 comp_id=this%registered_comp_id )
469
470 return
471 end subroutine file_restart_meshfield_component_write_var2d
472
473 !> Write a 3D variable to the restart file
474!OCL SERIAL
475 subroutine file_restart_meshfield_component_write_var3d( this, &
476 vid, field3d )
477
478 use scale_time, only: time_nowdaysec
479 implicit none
480
481 class(file_restart_meshfield_component), intent(inout) :: this
482 integer, intent(in) :: vid
483 class(meshfield3d), intent(in) :: field3d
484 !--------------------------------------------------
485
486 call this%file_ptr%Write_var3D( vid, field3d, time_nowdaysec, time_nowdaysec, &
487 comp_id=this%registered_comp_id )
488
489 return
490 end subroutine file_restart_meshfield_component_write_var3d
491
492 !> Read a 2D variable from the restart file
493!OCL SERIAL
494 subroutine file_restart_meshfield_component_read_var2d( this, &
495 dim_typeid, varname, field2d, step, allow_missing )
496
497
498 implicit none
499
500 class(file_restart_meshfield_component), intent(inout) :: this
501 integer, intent(in) :: dim_typeid
502 character(*), intent(in) :: varname
503 class(meshfield2d), intent(inout) :: field2d
504 integer, intent(in), optional :: step
505 logical, intent(in), optional :: allow_missing
506 !------------------------------------------------------
507
508 call this%file_ptr%Read_Var( &
509 dim_typeid, varname, field2d, step, allow_missing, &
510 comp_id=this%registered_comp_id )
511
512 return
513 end subroutine file_restart_meshfield_component_read_var2d
514
515 !> Read a 3D variable from the restart file
516!OCL SERIAL
517 subroutine file_restart_meshfield_component_read_var3d( this, &
518 dim_typeid, varname, field3d, step, allow_missing )
519
520
521 implicit none
522
523 class(file_restart_meshfield_component), intent(inout) :: this
524 integer, intent(in) :: dim_typeid
525 character(*), intent(in) :: varname
526 class(meshfield3d), intent(inout) :: field3d
527 integer, intent(in), optional :: step
528 logical, intent(in), optional :: allow_missing
529 !------------------------------------------------------
530
531 call this%file_ptr%Read_Var( &
532 dim_typeid, varname, field3d, step, allow_missing, &
533 comp_id=this%registered_comp_id )
534
535 return
536 end subroutine file_restart_meshfield_component_read_var3d
537
538 !> Close a restart file
539!OCL SERIAL
540 subroutine file_restart_meshfield_component_close( this )
541 implicit none
542
543 class(file_restart_meshfield_component), intent(inout) :: this
544 !--------------------------------------------------
545
546 if ( this%is_file_ptr_main ) then
547 if ( is_file_main_closed ) then
548 log_info("FILE_restart_meshfield_component_close",*) 'Main restart file is already closed. Skipping closure.'
549 else
550 is_file_main_closed = .true.
551 end if
552 end if
553
554 if ( this%file_ptr%fid /= -1 ) then
555 log_newline
556 log_info("FILE_restart_meshfield_component_close",*) 'Close restart file'
557 call this%file_ptr%Close()
558 end if
559
560 return
561 end subroutine file_restart_meshfield_component_close
562
563 !> Finalize an object to manage restart file with each component
564!OCL SERIAL
565 subroutine file_restart_meshfield_component_final( this )
566 implicit none
567 class(file_restart_meshfield_component), intent(inout) :: this
568 !--------------------------------------------------
569
570 ! Release the file object for managing restart file with each component
571
572 if ( .not. this%is_file_ptr_main ) then
573 call this%file_ptr%Final()
574 deallocate( this%file_ptr )
575 end if
576
577 nullify( this%file_ptr )
578 return
579 end subroutine file_restart_meshfield_component_final
580
581 !- Private -----------
582
583 !> Set the information of an object to manage restart file with each component
584!OCL SERIAL
585 subroutine file_restart_meshfield_component_set_information( this, &
586 in_basename, in_postfix_timelabel, &
587 out_basename, out_postfix_timelabel, &
588 out_dtype, out_title )
589 implicit none
590
591 class(file_restart_meshfield), intent(inout) :: this
592 character(*), intent(in) :: in_basename
593 logical, intent(in) :: in_postfix_timelabel
594 character(*), intent(in) :: out_basename
595 logical, intent(in) :: out_postfix_timelabel
596 character(*), intent(in) :: out_title
597 character(*), intent(in) :: out_dtype
598 !--------------------------------------------------
599
600 this%in_basename = in_basename
601 this%in_postfix_timelabel = in_postfix_timelabel
602
603 this%out_basename = out_basename
604 this%out_postfix_timelabel = out_postfix_timelabel
605 this%out_title = out_title
606 this%out_dtype = out_dtype
607 return
608 end subroutine file_restart_meshfield_component_set_information
609
module FElib / Element / Base
subroutine, public file_restart_meshfield_finalize()
Finalize the main restart file.
type(file_base_meshfield), target file_main
A file object to manage main restart file.
subroutine, public file_restart_meshfield_setup()
Setup the main restart file.
type(file_restart_meshfield), public restart_file
An object to manage main restart file.
module FElib / Mesh / Local 1D
module FElib / Mesh / Local 2D
module FElib / Mesh / Local 3D
module FElib / Mesh / Base 1D
integer, public meshbase1d_dimtype_num
integer, public meshbase1d_dimtypeid_x
module FElib / Mesh / Base 2D
integer, public meshbase2d_dimtypeid_x
integer, public meshbase2d_dimtype_num
integer, public meshbase2d_dimtypeid_y
module FElib / Mesh / Base 3D
integer, public meshbase3d_dimtypeid_y
integer, public meshbase3d_dimtypeid_z
integer, public meshbase3d_dimtype_num
integer, public meshbase3d_dimtypeid_x
module FElib / Mesh / Cubic 3D domain
module FElib / Mesh / Cubed-sphere 2D domain
module FElib / Mesh / Cubed-sphere 3D domain
module FElib / Mesh / Rectangle 2D domain
module FElib / Data / base
module FElib / Data / base
Derived type representing a 1D reference element.
Derived type representing a 2D reference element.
Derived type representing a 3D reference element.
Derived type to manage file output with MeshField data.
Derived type to manage restart file with each component.
Derived type representing a local mesh for 1D domain.
Derived type representing a local mesh for 2D domain.
Derived type to manage a local 3D computational domain.
Derived type to manage a computational mesh (base type for 1D domain)
Derived type to manage a computational mesh (base type for 2D domain)
Derived type to manage a computational mesh (base type for 3D domain)
Derived type to manage a cubic 3D computational domain.
Derived type to manage a cubed-sphere 2D computational domain.
Derived type to manage a cubed-sphere 3D computational domain.
Derived type to manage a rectangular 2D computational domain.
Derived type representing a field with 1D mesh.
Derived type representing a field with 2D mesh.
Derived type representing a field with 3D mesh.
Derived type representing a field (base type)