gtool5 Fortran 90/95 ライブラリ 1.0.0-rc5
English
Loading...
Searching...
No Matches
gtdata_internal_map.f90
Go to the documentation of this file.
1!> @file gtdata_internal_map.f90
2!>
3!> @author Eizi TOYODA, Yasuhiro MORIKAWA
4!> @copyright Copyright (C) GFD Dennou Club, 2000-2026. All rights reserved. <br/>
5!> License is BSD-2-Clause. See [COPYRIGHT](@ref COPYRIGHT) in detail
6!>
7!> @en
8!> @brief Internal map table module for gtool variables
9!>
10!> @private
11!> This module should not be used directly by users.
12!> @enden
13!>
14!> @ja
15!> @brief gtool 変数用の内部マップテーブルモジュール
16!>
17!> @private
18!> このモジュールはユーザが直接使用すべきではありません。
19!> @endja
20!>
21
22!>
23!> @en
24!> @brief Map table management for gtool variables
25!>
26!> @private
27!> A gtool variable is actually an integer handle that serves as a key
28!> to the map table. The map table (maptab) contains the entity table
29!> entry number and dimension rewriting/iterator tables.
30!>
31!> Reference counting is not implemented at this level. That is,
32!> map table and entity table have one-to-one correspondence,
33!> and users are free to copy handles.
34!> Of course, users must close (i.e., MapTabDelete) the handle
35!> exactly once.
36!> @enden
37!>
38!> @ja
39!> @brief gtool 変数のマップテーブル管理
40!>
41!> @private
42!> gtool 変数というのは実はマップ表のキーとなる整数ハンドルである。
43!> マップ表 maptab には実体表のエントリ番号と次元書き換え/イテレータ
44!> の表が載っている。
45!>
46!> このレベルにおける参照カウントは作らないことにする。つまり、
47!> マップ表と実体表は一対一対応するし、
48!> ユーザがハンドルをコピーするのは勝手である。
49!> もちろんユーザには必ずただ1回
50!> 当該ハンドルを close すなわち maptabdelete する義務がある。
51!> @endja
52!>
54
55 use dc_types, only: string
58 ! これらは, 外部から gtdata_internal_vartable を直接呼ばないようにするため,
59 ! gtdata_internal_map を介して公開する.
60
61 implicit none
62
63 !>
64 !> @en
65 !> @brief Dimension mapping table entry type
66 !>
67 !> Contains dimension rewriting information and iterator state.
68 !> @enden
69 !>
70 !> @ja
71 !> @brief 次元マッピングテーブルエントリ型
72 !>
73 !> 次元書き換え情報とイテレータ状態を格納します。
74 !> @endja
75 !>
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
105 !>
106 !> @en
107 !> @brief Map table entry type
108 !>
109 !> Contains variable ID, number of dimensions, and pointer to dimension map array.
110 !> @enden
111 !>
112 !> @ja
113 !> @brief マップテーブルエントリ型
114 !>
115 !> 変数ID、次元数、次元マップ配列へのポインタを格納します。
116 !> @endja
117 !>
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
138 !>
139 !> @en
140 !> @brief Get internal index range for specified dimension
141 !> @param[in] var Variable handle
142 !> @param[in] dimno Dimension number
143 !> @param[out] dimlo Lower bound of dimension
144 !> @param[out] dimhi Upper bound of dimension
145 !> @enden
146 !>
147 !> @ja
148 !> @brief 指定された次元の内部的添字番号範囲を取得
149 !> @param[in] var 変数ハンドル
150 !> @param[in] dimno 次元番号
151 !> @param[out] dimlo 次元の下限
152 !> @param[out] dimhi 次元の上限
153 !> @endja
154 !>
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
171 !>
172 !> @en
173 !> @brief Duplicate a variable
174 !> @param[out] var Duplicated variable handle
175 !> @param[in] source_var Source variable handle to copy
176 !> @enden
177 !>
178 !> @ja
179 !> @brief 変数を複製
180 !> @param[out] var 複製された変数ハンドル
181 !> @param[in] source_var コピー元の変数ハンドル
182 !> @endja
183 !>
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
217 !>
218 !> @en
219 !> @brief Create a variable with specified properties
220 !>
221 !> Creates variable var with internal class, internal cid,
222 !> apparent number of dimensions ndims, and apparent dimension lengths allcount(:).
223 !> Initialization is performed assuming zero offset.
224 !> @param[out] var Created variable handle
225 !> @param[in] class Internal class (VTB_CLASS_NETCDF, etc.)
226 !> @param[in] cid Internal identifier
227 !> @param[in] ndims Number of dimensions
228 !> @param[in] allcount Array of dimension lengths
229 !> @param[out] stat Status code
230 !> @enden
231 !>
232 !> @ja
233 !> @brief 指定されたプロパティで変数を作成
234 !>
235 !> 変数 var を作成する。内部種別 class, 内部識別子 cid,
236 !> 外見的次元数 ndims, 外見的次元長 allcount(:) を与える。
237 !> オフセットゼロを仮定して諸元の初期化が行われる。
238 !> @param[out] var 作成された変数ハンドル
239 !> @param[in] class 内部種別 (VTB_CLASS_NETCDF 等)
240 !> @param[in] cid 内部識別子
241 !> @param[in] ndims 次元数
242 !> @param[in] allcount 次元長の配列
243 !> @param[out] stat ステータスコード
244 !> @endja
245 !>
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
298 !>
299 !> @en
300 !> @brief Add entry to map table
301 !>
302 !> Adds an entry to the map table with the specified vid
303 !> (which should already be added to the entity table).
304 !> @param[out] mapid Map table entry ID
305 !> @param[in] vid Variable table entry ID
306 !> @enden
307 !>
308 !> @ja
309 !> @brief マップテーブルにエントリを追加
310 !>
311 !> すでに実体表に追加されたエントリ番号 vid を指定して、
312 !> マップ表にエントリを追加する。
313 !> @param[out] mapid マップテーブルエントリID
314 !> @param[in] vid 変数テーブルエントリID
315 !> @endja
316 !>
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
355 !>
356 !> @en
357 !> @brief Delete variable from map table
358 !>
359 !> Removes variable var from the map table.
360 !> Does not touch the entity table.
361 !> @param[in] var Variable handle to delete
362 !> @param[out] err Error flag (optional)
363 !> @enden
364 !>
365 !> @ja
366 !> @brief 変数をマップテーブルから削除
367 !>
368 !> 変数 var をマップ表から削除する。
369 !> 実体表には手をつけない。
370 !> @param[in] var 削除する変数ハンドル
371 !> @param[out] err エラーフラグ (省略可能)
372 !> @endja
373 !>
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
395 !>
396 !> @en
397 !> @brief Look up map table entry
398 !> @param[in] var Variable handle
399 !> @param[out] vid Variable table entry ID (optional)
400 !> @param[out] map Dimension map array (optional)
401 !> @param[out] ndims Number of dimensions (optional)
402 !> @enden
403 !>
404 !> @ja
405 !> @brief マップテーブルエントリを検索
406 !> @param[in] var 変数ハンドル
407 !> @param[out] vid 変数テーブルエントリID (省略可能)
408 !> @param[out] map 次元マップ配列 (省略可能)
409 !> @param[out] ndims 次元数 (省略可能)
410 !> @endja
411 !>
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
434 !>
435 !> @en
436 !> @brief Set map table values
437 !> @param[in] var Variable handle
438 !> @param[in] map Dimension map array to set
439 !> @param[out] stat Status code
440 !> @enden
441 !>
442 !> @ja
443 !> @brief マップテーブルの値を設定
444 !> @param[in] var 変数ハンドル
445 !> @param[in] map 設定する次元マップ配列
446 !> @param[out] stat ステータスコード
447 !> @endja
448 !>
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
469 !>
470 !> @en
471 !> @brief Get internal class and identifier of variable
472 !> @param[in] var Variable handle
473 !> @param[out] class Internal class (optional)
474 !> @param[out] cid Internal identifier (optional)
475 !> @enden
476 !>
477 !> @ja
478 !> @brief 変数の内部種別と識別子を取得
479 !> @param[in] var 変数ハンドル
480 !> @param[out] class 内部種別 (省略可能)
481 !> @param[out] cid 内部識別子 (省略可能)
482 !> @endja
483 !>
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
494 !>
495 !> @en
496 !> @brief Change number of dimensions of variable
497 !> @param[in] var Variable handle
498 !> @param[in] ndims New number of dimensions
499 !> @param[out] stat Status code
500 !> @enden
501 !>
502 !> @ja
503 !> @brief 変数の次元数を変更
504 !> @param[in] var 変数ハンドル
505 !> @param[in] ndims 新しい次元数
506 !> @param[out] stat ステータスコード
507 !> @endja
508 !>
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
538 !>
539 !> @en
540 !> @brief Reduce variable rank to specified value
541 !>
542 !> Reduces the rank (number of non-degenerate dimensions) of variable var
543 !> to rank by setting count values to 1.
544 !> Does not increase rank or manipulate apparent dimension count.
545 !> @param[in] var Variable handle
546 !> @param[in] rank Target rank
547 !> @param[out] stat Status code
548 !> @enden
549 !>
550 !> @ja
551 !> @brief 変数のランクを指定値に減少
552 !>
553 !> 変数 var のランク(非縮退次元数)を rank に減らすように
554 !> count 値を1に減らす。ランクを増やすことや外見次元数の操作はしない。
555 !> @param[in] var 変数ハンドル
556 !> @param[in] rank 目標ランク
557 !> @param[out] stat ステータスコード
558 !> @endja
559 !>
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
586 !>
587 !> @en
588 !> @brief Convert map table to netCDF internal specifications
589 !>
590 !> Creates start, count, stride, imap suitable for netCDF arguments
591 !> from the map table. Note that negative stride is not handled
592 !> (temporarily handled by gdncvarget/gdncvarput).
593 !> @param[in] var Variable handle
594 !> @param[out] specs Pointer to specs array (allocated internally)
595 !> @param[out] ndims Number of internal dimensions (optional)
596 !> @enden
597 !>
598 !> @ja
599 !> @brief マップテーブルをnetCDF内部仕様に変換
600 !>
601 !> マップ表から netCDF の引数にふさわしい start, count, stride, imap
602 !> を作成する。ただし、stride が負になるばあいは対策されていない。
603 !> (暫定的に gdncvarget/gdncvarput が対応している)
604 !> @param[in] var 変数ハンドル
605 !> @param[out] specs specs配列へのポインタ (内部で割り当て)
606 !> @param[out] ndims 内部次元数 (省略可能)
607 !> @endja
608 !>
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
642 !>
643 !> @en
644 !> @brief Allocate and initialize dimension map entries
645 !> @param[out] map Pointer to allocated map array
646 !> @param[in] ndims Number of entries to allocate
647 !> @enden
648 !>
649 !> @ja
650 !> @brief 次元マップエントリを割り当て初期化
651 !> @param[out] map 割り当てられたマップ配列へのポインタ
652 !> @param[in] ndims 割り当てるエントリ数
653 !> @endja
654 !>
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
674 !>
675 !> @en
676 !> @brief Apply map table to variable
677 !> @param[inout] var Variable handle
678 !> @param[inout] map Dimension map to apply (deallocated and replaced)
679 !> @enden
680 !>
681 !> @ja
682 !> @brief 変数にマップテーブルを適用
683 !> @param[inout] var 変数ハンドル
684 !> @param[inout] map 適用する次元マップ (解放され置き換えられる)
685 !> @endja
686 !>
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
715 !>
716 !> @en
717 !> @brief Resize dimension table of variable
718 !> @param[in] var Variable handle
719 !> @param[in] ndims New size of dimension table
720 !> @enden
721 !>
722 !> @ja
723 !> @brief 変数の次元テーブルのサイズを変更
724 !> @param[in] var 変数ハンドル
725 !> @param[in] ndims 次元テーブルの新しいサイズ
726 !> @endja
727 !>
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
756 !>
757 !> @en
758 !> @brief Dump variable properties for debugging
759 !> @param[in] var Variable handle
760 !> @enden
761 !>
762 !> @ja
763 !> @brief デバッグ用変数プロパティのダンプ
764 !> @param[in] var 変数ハンドル
765 !> @endja
766 !>
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
804 !>
805 !> @en
806 !> @brief Find external dimension number for compact dimension order
807 !>
808 !> Identifies the dimension at compact dimension order dimord
809 !> (counting only non-degenerate dimensions) and returns
810 !> the external dimension number.
811 !> @param[in] dimord Compact dimension order
812 !> @param[in] map Dimension map array
813 !> @return External dimension number (-1 if not found)
814 !> @enden
815 !>
816 !> @ja
817 !> @brief 縮約次元番号に対する外部次元番号を検索
818 !>
819 !> 次元表の中で非縮退次元だけを数えた次元番号 dimord の次元を
820 !> 特定し、外部向けの次元番号を返す。
821 !> @param[in] dimord 縮約次元番号
822 !> @param[in] map 次元マップ配列
823 !> @return 外部次元番号 (見つからない場合は -1)
824 !> @endja
825 !>
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
エラー処理用モジュール
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
エラー等を保持
Definition dc_error.f90:468
integer, parameter, public gt_enomoredims
-101 以下: データ構造のエラー
Definition dc_error.f90:507
デバッグ時の追跡用モジュール
Definition dc_trace.f90:150
subroutine, public dbgmessage(fmt, i, r, d, l, n, c1, c2, c3, ca)
Definition dc_trace.f90:680
種別型パラメタを提供します。
Definition dc_types.f90:55
integer, parameter, public 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