gtool5 Fortran 90/95 Library 1.0.0-rc5
日本語
Loading...
Searching...
No Matches
gtdata_internal_map.f90
Go to the documentation of this file.
1
21
54
55 use dc_types, only: string
58 ! これらは, 外部から gtdata_internal_vartable を直接呼ばないようにするため,
59 ! gtdata_internal_map を介して公開する.
60
61 implicit none
62
77 integer:: dimno
78 ! 正ならば実体変数の次元番号, 他変数参照時は非正値
79 character(len=STRING):: url
80 ! 次元変数の url
81 integer:: offset
82 !=== 実体と gtool ユーザの格子番号対応
83 !
84 ! ユーザからみて 1..allcount が実体の
85 ! (1..allcount) * step + offset に写像される。
86 ! これらの値の変更の際は実体変数の許容添字範囲および
87 ! 成長可能性を確認する必要あり。
88 ! start 値に対するオフセット。
89 integer:: step
90 ! 1 か -1 の値をとることが期待される。
91 integer:: allcount
92 ! 見掛けの格子番号上限: start + count * stride <= allcount
93 integer:: start
94 !=== イテレータ本体
95 ! 入出力範囲は (start:start+count*stride:stride) である。
96 ! イテレータ start 値
97 integer:: count
98 ! イテレータ count 値
99 integer:: stride
100 ! イテレータ stride 値
101 logical:: scalar
102 ! スカラー変数である場合, .true.
103 end type gt_dimmap
104
119 integer:: vid
120 integer:: ndims
121 type(gt_dimmap), pointer:: map(:)
122 end type map_table_entry
123
124 type(map_table_entry), save, target, allocatable:: maptab(:)
125 integer, parameter:: maptab_init_size = 16
126
130 private:: maptab, maptab_init_size
131
132 interface dimrange
133 module procedure dimrange_by_dimno
134 end interface
135
136contains
137
155 subroutine dimrange_by_dimno(var, dimno, dimlo, dimhi)
156 use gtdata_types, only: gt_variable
157 use gtdata_generic, only: open, close
159 type(gt_variable), intent(in):: var
160 integer, intent(in):: dimno
161 integer, intent(out):: dimlo, dimhi
162 type(gt_variable):: dimvar
163 integer:: vid
164 call open(dimvar, var, dimno, count_compact=.true., &
165 & inherit_slice=.false.)
166 call map_lookup(dimvar, vid=vid)
167 call dimrange(vid, dimlo, dimhi)
168 call close(dimvar)
169 end subroutine dimrange_by_dimno
170
184 subroutine map_dup(var, source_var)
185 use gtdata_types, only: gt_variable
187 use dc_trace, only: dbgmessage
188 type(gt_variable), intent(out):: var
189 type(gt_variable), intent(in):: source_var
190 integer:: vid, mid1, mid2, vid2, nd, class, cid
191 call map_lookup(source_var, vid=vid)
192 if (vid < 0) then
193 var = gt_variable(-1)
194 return
195 endif
196 if (vid == 0) then
197 vid2 = 0
198 else
199 call vartablelookup(vid, class=class, cid=cid)
200 call vartableadd(vid2, class, cid)
201 endif
202 call maptabadd(var%mapid, vid2)
203 mid1 = source_var%mapid
204 mid2 = var%mapid
205 maptab(mid2)%ndims = maptab(mid1)%ndims
206 if (associated(maptab(mid1)%map)) then
207 nd = size(maptab(mid1)%map)
208 allocate(maptab(mid2)%map(nd))
209 maptab(mid2)%map(1:nd) = maptab(mid1)%map(1:nd)
210 else
211 nullify(maptab(mid2)%map)
212 endif
213 call dbgmessage('map_dup mapid(%d from %d) vid(%d from %d)', &
214 & i=(/mid2, mid1, maptab(mid2)%vid, maptab(mid1)%vid/))
215 end subroutine map_dup
216
246 subroutine map_create(var, class, cid, ndims, allcount, stat)
247 use gtdata_types, only: gt_variable
250 type(gt_variable), intent(out):: var
251 integer, intent(in):: class, cid, ndims, allcount(:)
252 integer, intent(out):: stat
253 type(gt_dimmap), pointer:: map(:)
254 integer:: vid, i
255 continue
256
257 stat = dc_noerr
258 if ( ndims < 0 ) then
259 stat = gt_enomoredims
260 goto 999
261 end if
262 call vartableadd(vid, class, cid)
263 call maptabadd(var%mapid, vid)
264 if (ndims > 0) then
265 call map_allocate(map, ndims)
266 maptab(var%mapid)%ndims = ndims
267 maptab(var%mapid)%map => map
268
269 do, i = 1, ndims
270 map(i)%dimno = i
271 map(i)%allcount = allcount(i)
272 map(i)%count = allcount(i)
273 map(i)%offset = 0
274 map(i)%start = 1
275 map(i)%step = 1
276 map(i)%stride = 1
277 map(i)%scalar = .false.
278 enddo
279 else
280 ! スカラー変数 (ndims = 0) の場合
281 call map_allocate(map, 1)
282 maptab(var%mapid)%ndims = 0
283 maptab(var%mapid)%map => map
284 map(1)%dimno = 1
285 map(1)%allcount = 1
286 map(1)%count = 1
287 map(1)%offset = 0
288 map(1)%start = 1
289 map(1)%step = 1
290 map(1)%stride = 1
291 map(1)%scalar = .true.
292 end if
293
294999 continue
295 return
296 end subroutine map_create
297
317 subroutine maptabadd(mapid, vid)
318 integer, intent(out):: mapid
319 integer, intent(in):: vid
320 type(map_table_entry), allocatable:: tmp_maptab(:)
321 integer:: i, n
322 ! 必要なら初期確保
323 if (.not. allocated(maptab)) then
324 allocate(maptab(maptab_init_size))
325 maptab(:)%vid = vid_invalid
326 do, n = 1, maptab_init_size
327 nullify(maptab(n)%map)
328 enddo
329 endif
330 ! 空き地があればそこに割り当て
331 do, i = 1, size(maptab)
332 if (maptab(i)%vid == vid_invalid) then
333 mapid = i
334 maptab(mapid)%vid = vid
335 return
336 endif
337 enddo
338 ! 空き地はなかったのだから倍幅確保
339 n = size(maptab)
340 allocate(tmp_maptab(n))
341 tmp_maptab(:) = maptab(:)
342 deallocate(maptab)
343 allocate(maptab(n * 2))
344 ! 確保したところはクリア
345 maptab(1:n) = tmp_maptab(1:n)
346 do, i = n + 1, (2 * size(tmp_maptab))
347 maptab(i)%vid = vid_invalid
348 nullify(maptab(i)%map)
349 enddo
350 deallocate(tmp_maptab)
351 mapid = n + 1
352 maptab(mapid)%vid = vid
353 end subroutine maptabadd
354
374 subroutine maptabdelete(var, err)
375 use dc_error, only: nf90_enotvar, storeerror, dc_noerr
376 use gtdata_types, only: gt_variable
377 use dc_trace, only: dbgmessage
378 implicit none
379 type(gt_variable), intent(in):: var
380 logical, intent(out), optional:: err
381 integer:: mapid
382 mapid = var%mapid
383 if (.not. allocated(maptab)) goto 999
384 if (mapid <= 0 .or. mapid > size(maptab)) goto 999
385 if (maptab(mapid)%vid == vid_invalid) goto 999
386 maptab(mapid)%vid = vid_invalid
387 if (associated(maptab(mapid)%map)) deallocate(maptab(mapid)%map)
388 call storeerror(dc_noerr, 'maptabdelete', err)
389 call dbgmessage('gtdata_internal_map table %d deleted', i=(/mapid/))
390 return
391999 continue
392 call storeerror(nf90_enotvar, 'maptabdelete', err)
393 end subroutine maptabdelete
394
412 subroutine map_lookup(var, vid, map, ndims)
413 use gtdata_types, only: gt_variable
414 type(gt_variable), intent(in):: var
415 integer, intent(out), optional:: vid
416 type(gt_dimmap), intent(out), optional:: map(:)
417 integer, intent(out), optional:: ndims
418 if (.not. allocated(maptab)) goto 999
419 if (var%mapid <= 0 .or. var%mapid > size(maptab)) goto 999
420 if (maptab(var%mapid)%vid == vid_invalid) goto 999
421 if (present(vid)) vid = maptab(var%mapid)%vid
422 if (present(map)) map(:) = maptab(var%mapid)%map(1:size(map))
423 if (present(ndims)) ndims = maptab(var%mapid)%ndims
424 return
425999 continue
426 if (present(vid)) vid = vid_invalid
427 if (present(map)) then
428 map(:)%dimno = -1
429 map(:)%url = " "
430 endif
431 if (present(ndims)) ndims = 0
432 end subroutine map_lookup
433
449 subroutine map_set(var, map, stat)
450 use gtdata_types, only: gt_variable
451 use dc_error, only: nf90_enotvar, gt_enomoredims, dc_noerr
452 type(gt_variable), intent(in):: var
453 type(gt_dimmap), intent(in):: map(:)
454 integer, intent(out):: stat
455 if (.not. allocated(maptab)) goto 999
456 if (var%mapid <= 0 .or. var%mapid > size(maptab)) goto 999
457 if (maptab(var%mapid)%vid == vid_invalid) goto 999
458 if (size(map) > size(maptab(var%mapid)%map)) then
459 stat = gt_enomoredims
460 return
461 endif
462 maptab(var%mapid)%map(1:size(map)) = map(:)
463 stat = dc_noerr
464 return
465999 continue
466 stat = nf90_enotvar
467 end subroutine map_set
468
484 subroutine var_class(var, class, cid)
485 use gtdata_types, only: gt_variable
487 type(gt_variable), intent(in):: var
488 integer, intent(out), optional:: class, cid
489 integer:: vid
490 call map_lookup(var, vid=vid)
491 call vartablelookup(vid, class=class, cid=cid)
492 end subroutine var_class
493
509 subroutine map_set_ndims(var, ndims, stat)
510 use gtdata_types, only: gt_variable
511 use dc_error, only: nf90_enotvar, gt_enomoredims, dc_noerr
512 type(gt_variable), intent(in):: var
513 integer, intent(in):: ndims
514 integer, intent(out):: stat
515 integer:: vid
516 call map_lookup(var, vid=vid)
517 if (vid == vid_invalid) then
518 stat = nf90_enotvar
519 return
520 endif
521 if (.not. associated(maptab(var%mapid)%map)) then
522 if (ndims == 0) then
523 stat = dc_noerr
524 maptab(var%mapid)%ndims = 0
525 else
526 stat = gt_enomoredims
527 endif
528 else
529 if (ndims > size(maptab(var%mapid)%map)) then
530 stat = gt_enomoredims
531 else
532 stat = dc_noerr
533 maptab(var%mapid)%ndims = ndims
534 endif
535 endif
536 end subroutine map_set_ndims
537
560 subroutine map_set_rank(var, rank, stat)
561 use gtdata_types, only: gt_variable
562 use dc_error, only: nf90_enotvar, gt_enomoredims, dc_noerr
563 type(gt_variable), intent(in):: var
564 integer, intent(in):: rank
565 integer, intent(out):: stat
566 type(gt_dimmap), pointer:: tmpmap(:)
567 integer:: ndims
568 integer:: vid, nd
569 call map_lookup(var, vid, ndims=ndims)
570 if (vid == vid_invalid) then
571 stat = nf90_enotvar
572 return
573 endif
574 if (ndims < rank) then
575 stat = gt_enomoredims
576 return
577 endif
578 tmpmap => maptab(var%mapid)%map
579 do, nd = ndims, 1, -1
580 if (count(tmpmap(1:ndims)%count > 1) <= rank) exit
581 tmpmap(nd)%count = 1
582 enddo
583 stat = dc_noerr
584 end subroutine map_set_rank
585
609 subroutine map_to_internal_specs(var, specs, ndims)
610 use gtdata_types, only: gt_variable
611 use gtdata_internal_vartable, only: num_dimensions => ndims
612 type(gt_variable), intent(in):: var
613 integer, pointer:: specs(:, :)
614 integer, intent(out), optional:: ndims
615 type(gt_dimmap), pointer:: it
616 integer:: vid, i, j, imap, internal_ndims
617 integer:: external_ndims
618 continue
619 call map_lookup(var, vid, ndims=external_ndims)
620 internal_ndims = num_dimensions(vid)
621 if (present(ndims)) ndims = internal_ndims
622 allocate(specs(max(1, internal_ndims), 4))
623 specs(:, 1) = 1
624 specs(:, 2) = 1
625 specs(:, 3) = 1
626 specs(:, 4) = 0
627 imap = 1
628 do, i = 1, size(maptab(var%mapid)%map)
629 it => maptab(var%mapid)%map(i)
630 j = it%dimno
631 if (j > 0 .and. j <= internal_ndims) then
632 specs(j, 1) = it%start + it%offset
633 specs(j, 2) = it%count
634 if (i > external_ndims) specs(j, 2) = 1
635 specs(j, 3) = it%stride * it%step
636 specs(j, 4) = imap
637 endif
638 imap = imap * it%count
639 enddo
640 end subroutine map_to_internal_specs
641
655 subroutine map_allocate(map, ndims)
656 type(gt_dimmap), pointer:: map(:)
657 integer, intent(in):: ndims
658 if (ndims <= 0) then
659 nullify(map)
660 return
661 endif
662 allocate(map(1:ndims))
663 map(1:ndims)%dimno = -1
664 map(1:ndims)%url = ' '
665 map(1:ndims)%allcount = 0
666 map(1:ndims)%offset = 0
667 map(1:ndims)%step = 1
668 map(1:ndims)%start = 1
669 map(1:ndims)%count = 0
670 map(1:ndims)%stride = 1
671 map(1:ndims)%scalar = .false.
672 end subroutine map_allocate
673
687 subroutine map_apply(var, map)
688 use gtdata_types, only: gt_variable
689 type(gt_variable), intent(inout):: var
690 type(gt_dimmap), pointer:: map(:)
691 type(gt_dimmap), pointer:: tmpmap(:), varmap
692 integer:: i, nd
693 nd = size(map)
694 allocate(tmpmap(nd))
695 do, i = 1, nd
696 tmpmap(i)%allcount = map(i)%allcount
697 tmpmap(i)%count = map(i)%count
698 if (map(i)%dimno > 0) then
699 varmap => maptab(var%mapid)%map(map(i)%dimno)
700 tmpmap(i)%url = varmap%url
701 tmpmap(i)%dimno = varmap%dimno
702 tmpmap(i)%offset = varmap%offset + map(i)%offset
703 tmpmap(i)%step = varmap%step * map(i)%step
704 else
705 tmpmap(i)%url = map(i)%url
706 tmpmap(i)%dimno = 0
707 tmpmap(i)%offset = map(i)%offset
708 tmpmap(i)%step = map(i)%step
709 endif
710 enddo
711 deallocate(map)
712 map => tmpmap
713 end subroutine map_apply
714
728 subroutine map_resize(var, ndims)
729 use gtdata_types, only: gt_variable
730 type(gt_variable), intent(in):: var
731 integer, intent(in):: ndims
732 type(gt_dimmap), pointer:: newmap(:)
733 type(gt_dimmap), pointer:: tmpmap(:)
734 integer:: n
735 if (associated(maptab(var%mapid)%map)) then
736 tmpmap => maptab(var%mapid)%map
737 call map_allocate(newmap, ndims)
738 n = min(size(tmpmap), ndims)
739 newmap(1:n) = tmpmap(1:n)
740 deallocate(tmpmap)
741 maptab(var%mapid)%map => newmap
742 newmap(n+1:ndims)%dimno = -1
743 newmap(n+1:ndims)%url = ' '
744 newmap(n+1:ndims)%allcount = 0
745 newmap(n+1:ndims)%offset = 0
746 newmap(n+1:ndims)%step = 1
747 newmap(n+1:ndims)%start = 1
748 newmap(n+1:ndims)%count = 0
749 newmap(n+1:ndims)%stride = 1
750 else
751 call map_allocate(maptab(var%mapid)%map, ndims)
752 n = 1
753 endif
754 end subroutine map_resize
755
767 subroutine gtvar_dump(var)
768 use gtdata_types, only: gt_variable
770 use dc_trace, only: debug, dbgmessage
771 type(gt_variable), intent(in):: var
772 integer:: idim, imap
773 logical:: dbg_mode
774 continue
775 call debug( dbg_mode )
776 if (.not. dbg_mode) return
777 imap = var%mapid
778 if (imap < 1 .or. imap > size(maptab)) then
779 call dbgmessage('[gt_variable %d: invalid id]', i=(/imap/))
780 return
781 endif
782 if (associated(maptab(imap)%map)) then
783 call dbgmessage('[gt_variable %d: ndims=%d, map.size=%d]', &
784 & i=(/imap, maptab(imap)%ndims, size(maptab(imap)%map)/))
785 do, idim = 1, size(maptab(imap)%map)
786 call dbgmessage('[dim%d dimno=%d ofs=%d step=%d' &
787 &// ' all=%d start=%d count=%d stride=%d url=%c]', &
788 & c1=trim(maptab(imap)%map(idim)%url), &
789 & i=(/idim, maptab(imap)%map(idim)%dimno, &
790 & maptab(imap)%map(idim)%offset, &
791 & maptab(imap)%map(idim)%step, &
792 & maptab(imap)%map(idim)%allcount, &
793 & maptab(imap)%map(idim)%start, &
794 & maptab(imap)%map(idim)%count, &
795 & maptab(imap)%map(idim)%stride/))
796 enddo
797 else
798 call dbgmessage('[gt_variable %d: ndims=%d, map=null]', &
799 & i=(/imap, maptab(imap)%ndims/))
800 endif
801 call vartable_dump(maptab(imap)%vid)
802 end subroutine gtvar_dump
803
826 integer function dimord_skip_compact(dimord, map) result(result)
827 use dc_trace, only: dbgmessage
828 integer, intent(in):: dimord
829 type(gt_dimmap), intent(in):: map(:)
830 integer:: nd, id
831 result = -1
832 nd = 0
833 do, id = 1, size(map)
834 if (map(id)%count < 2) cycle
835 nd = nd + 1
836 if (nd < dimord) cycle
837 result = id
838 call dbgmessage('compact dim skip: %d <= %d', i=(/result, dimord/))
839 exit
840 enddo
841 end function dimord_skip_compact
842
843end module gtdata_internal_map
Error handling module.
Definition dc_error.f90:454
subroutine, public storeerror(number, where, err, cause_c, cause_i)
Definition dc_error.f90:891
integer, parameter, public dc_noerr
Error storage variables
Definition dc_error.f90:468
integer, parameter, public gt_enomoredims
-101 or less: Data structure errors
Definition dc_error.f90:507
Debug tracing module.
Definition dc_trace.f90:150
subroutine, public dbgmessage(fmt, i, r, d, l, n, c1, c2, c3, ca)
Definition dc_trace.f90:680
Provides kind type parameter values.
Definition dc_types.f90:55
integer, parameter, public string
Character length for string
Definition dc_types.f90:137
subroutine, public map_lookup(var, vid, map, ndims)
subroutine map_apply(var, map)
subroutine map_set_ndims(var, ndims, stat)
subroutine map_set(var, map, stat)
subroutine, public map_to_internal_specs(var, specs, ndims)
integer function dimord_skip_compact(dimord, map)
subroutine, public maptabdelete(var, err)
subroutine map_allocate(map, ndims)
subroutine, public var_class(var, class, cid)
subroutine, public maptabadd(mapid, vid)
subroutine dimrange_by_dimno(var, dimno, dimlo, dimhi)
subroutine, public map_create(var, class, cid, ndims, allcount, stat)
subroutine map_dup(var, source_var)
subroutine map_set_rank(var, rank, stat)
subroutine map_resize(var, ndims)
subroutine, public vartablelookup(vid, class, cid)
integer, parameter, public vid_invalid
subroutine, public vartableadd(vid, class, cid)
integer, parameter, public vtb_class_netcdf
subroutine, public vartable_dump(vid)
integer function, public ndims(vid)
integer, parameter, public vtb_class_unused