Loading...
Searching...
No Matches
gtvarlimitbinary.f90 File Reference

Go to the source code of this file.

Functions/Subroutines

subroutine gtvarxformbinary (var1, var2, err)
subroutine adjust_slice (var1, var2, idim1, idim2, offset, stepfact)

Function/Subroutine Documentation

◆ adjust_slice()

subroutine gtvarxformbinary::adjust_slice ( type(gt_variable), intent(in) var1,
type(gt_variable), intent(in) var2,
integer, intent(in) idim1,
integer, intent(in) idim2,
integer, intent(out) offset,
integer, intent(out) stepfact )

Definition at line 118 of file gtvarlimitbinary.f90.

119 use gtdata_generic, only: get, open, close
120 type(GT_VARIABLE), intent(in):: var1, var2
121 integer, intent(in):: idim1, idim2
122 integer, intent(out):: offset, stepfact
123 type(GT_VARIABLE):: var_d
124 integer:: n, buf(1)
125 real, allocatable:: val1(:), val2(:)
126 continue
127 call beginsub('adjust_slice')
128 call open(var_d, source_var=var1, dimord=idim1, count_compact=.true.)
129 call inquire(var_d, size=n)
130 allocate(val1(n))
131 call get(var_d, val1, n)
132 call close(var_d)
133 !
134 call open(var_d, source_var=var2, dimord=idim2, count_compact=.true.)
135 call inquire(var_d, size=n)
136 allocate(val2(n))
137 call get(var_d, val2, n)
138 call close(var_d)
139 !
140 buf(1:1) = minloc(abs(val1(:) - val2(1)))
141 offset = buf(1) - 1
142 if (size(val2) < 2 .or. size(val1) < 2) then
143 stepfact = 1
144 else
145 buf(1:1) = minloc(abs(val1(:) - val2(2)))
146 stepfact = buf(1) - (offset + 1)
147 endif
148 !
149 deallocate(val1, val2)
150 call endsub('adjust_slice')

References dc_units::add_okay(), and dc_types::string.

Here is the call graph for this function:

◆ gtvarxformbinary()

subroutine gtvarxformbinary ( type(gt_variable), intent(inout) var1,
type(gt_variable), intent(inout) var2,
logical, intent(out), optional err )

Definition at line 13 of file gtvarlimitbinary.f90.

14 !
15 !== 2 つの変数の次元配置の共通化
16 !
17 ! 変数 <b>var1</b> の次元構成が <b>var2</b> の次元構成と同じになるように
18 ! 範囲拘束を行います。過剰な次元が <b>var1</b> にある場合、隠蔽
19 ! を行います。(追加もできるようにする予定です)。
20 !
21 ! エラーが生じた場合、メッセージを出力
22 ! してプログラムは強制終了します。*err* を与えてある場合には
23 ! の引数に .true. が返り、プログラムは終了しません。
24 !
25 !--
26 ! 二つの変数 var1, var2 に入出力範囲拘束を加えて次元配置を共通化する。
27 ! 結果の次元構成はとりあえずモデルで使えるように決めた。
28 ! var2 の空間を保持する。var1 を変形する。
29 ! var2 の次元は (有幅・縮退ともに) var2 における幅がとられる。
30 ! したがって var1 においては存在しないか var2 をカバーする幅で
31 ! なければならない。
32 ! var2 にない var1 の次元は見えないようになるので縮退しているか
33 ! 存在しないのでなければならない。
34 !++
35 use gtdata_types, only: gt_variable
36 use gtdata_generic, only: inquire, get_slice
39 use dc_trace, only: beginsub, endsub, dbgmessage
40 implicit none
41 type(GT_VARIABLE), intent(inout):: var1, var2
42 logical, intent(out), optional:: err
43 integer:: ndim1, ndim2, ndimo
44 integer, allocatable:: map1(:), map2(:)
45 type(GT_DIMMAP), pointer:: newmap(:)
46 integer:: i, j, stat
47 character(*), parameter:: subnam = "GTVarXformBinary"
48continue
49 call beginsub(subnam, 'mapid=[%d, %d]', i=(/var1%mapid, var2%mapid/))
50 call gtvar_dump(var1)
51 call gtvar_dump(var2)
52 !
53 ! 二つの変数 var1, var2 から共有次元を調べ、対応表 map1, map2 をつくる。
54 !
55 if (present(err)) err = .false.
56 call inquire(var1, alldims=ndim1)
57 call inquire(var2, alldims=ndim2)
58 ndimo = max(ndim1, ndim2, 0)
59 allocate(map1(1:ndim1), map2(1:ndim2))
60 call getmatch(var1, var2, ndim1, ndim2, map1, map2)
61 call dbgmessage('map1=%*d map2=%*d', i=(/map1(1:ndim1), map2(1:ndim2)/), n=(/ndim1, ndim2/))
62 if (all(map2(1:ndim2) == 0)) then
63 stat = gt_enomatchdim
64 goto 999
65 endif
66 !
67 ! 再配置テーブル作成開始
68 !
69 ndimo = ndim2 + count(map1(1:ndim1) == 0)
70 call map_allocate(newmap, ndimo)
71 !
72 ! 1..ndim2 は map2 によって var2 の次元たちにマップする
73 !
74 newmap(1:ndim2)%dimno = map2(1:ndim2)
75 call inquire(var2, allcount=newmap(1:ndim2)%allcount)
76 call get_slice(var2, count=newmap(1:ndim2)%count)
77 do, j = 1, ndim2
78 if (map2(j) == 0) then
79 newmap(j)%start = 1
80 newmap(j)%stride = 1
81 call inquire(var2, j, url=newmap(j)%url)
82 else
83 ! 位置対応によって var1 側での開始位置を決定する
84 call adjust_slice(var1, var2, map2(j), j, &
85 & newmap(j)%start, newmap(j)%stride)
86 endif
87 enddo
88 !
89 ! ndim2+1.. ndimo は var2 に対応させられない var1 の次元をおく
90 !
91 j = 0
92 loop1: do, i = ndim2 + 1, ndimo
93 do
94 j = j + 1
95 if (j > ndim1) exit loop1
96 if (map1(j) <= 0) exit
97 enddo
98 newmap(i)%dimno = j
99 call inquire(var1, dimord=j, allcount=newmap(i)%allcount)
100 call get_slice(var1, dimord=j, start=newmap(i)%start, &
101 & count=newmap(i)%count, stride=newmap(i)%stride)
102 end do loop1
103 !
104 call map_apply(var1, map=newmap)
105 !
106 stat = dc_noerr
107999 continue
108 call storeerror(stat, subnam, err)
109 call endsub(subnam, 'stat=%d', i=(/stat/))
110 deallocate(map1, map2)
111 return
112contains
113
114 !
115 ! 二つの次元変数を調べ、軸上位置が対応するように
116 ! start シフト数と stride ファクタを決定する
117 !
118 subroutine adjust_slice(var1, var2, idim1, idim2, offset, stepfact)
119 use gtdata_generic, only: get, open, close
120 type(GT_VARIABLE), intent(in):: var1, var2
121 integer, intent(in):: idim1, idim2
122 integer, intent(out):: offset, stepfact
123 type(GT_VARIABLE):: var_d
124 integer:: n, buf(1)
125 real, allocatable:: val1(:), val2(:)
126 continue
127 call beginsub('adjust_slice')
128 call open(var_d, source_var=var1, dimord=idim1, count_compact=.true.)
129 call inquire(var_d, size=n)
130 allocate(val1(n))
131 call get(var_d, val1, n)
132 call close(var_d)
133 !
134 call open(var_d, source_var=var2, dimord=idim2, count_compact=.true.)
135 call inquire(var_d, size=n)
136 allocate(val2(n))
137 call get(var_d, val2, n)
138 call close(var_d)
139 !
140 buf(1:1) = minloc(abs(val1(:) - val2(1)))
141 offset = buf(1) - 1
142 if (size(val2) < 2 .or. size(val1) < 2) then
143 stepfact = 1
144 else
145 buf(1:1) = minloc(abs(val1(:) - val2(2)))
146 stepfact = buf(1) - (offset + 1)
147 endif
148 !
149 deallocate(val1, val2)
150 call endsub('adjust_slice')
151 end subroutine adjust_slice
152
153 !
154 ! 二つの変数から共有次元を調べ、対応表 map1, map2 を作る。
155 ! すなわち、それぞれの次元番号から相方の次元番号を得る表である。
156 !
157 subroutine getmatch(var1, var2, ndim1, ndim2, map1, map2)
158 use dc_types, only: string
159 use dc_units, only: units, add_okay, assignment(=), clear, deallocate
160 use gtdata_generic, only: get_attr, open, close
161 type(GT_VARIABLE), intent(in):: var1, var2
162 integer, intent(in):: ndim1, ndim2
163 integer, intent(out):: map1(:), map2(:)
164 type(GT_VARIABLE):: var_d
165 integer, allocatable:: map(:, :)
166 integer:: i, j
167 character(STRING):: su1, su2
168 type(UNITS), allocatable:: u1(:), u2(:)
169 continue
170 call beginsub('getmatch')
171 ! 返却値はデフォルト 0
172 map1(:) = 0
173 map2(:) = 0
174 ! 表の構築: 初期値は消去法をとることを示す
175 allocate(map(ndim1, ndim2))
176 map(:, :) = 1
177
178 ! 単位による対応 --- 加算可能でなければ対にしない
179 ! 単位の構成
180 allocate(u1(ndim1), u2(ndim2))
181 do, i = 1, ndim1
182 call open(var_d, var1, i, count_compact=.true.)
183 call get_attr(var_d, 'units', su1)
184 call close(var_d)
185 call clear(u1(i))
186 u1(i) = su1
187 enddo
188 do, j = 1, ndim2
189 call open(var_d, var2, j, count_compact=.true.)
190 call get_attr(var_d, 'units', su2)
191 call close(var_d)
192 call clear(u2(j))
193 u2(j) = su2
194 enddo
195 ! 処理
196 do, i = 1, ndim1
197 do, j = 1, ndim2
198 if (.not. add_okay(u1(i), u2(j))) &
199 & map(i, j) = 0
200 enddo
201 enddo
202 ! 単位の廃棄
203 do, i = 1, ndim1
204 call deallocate(u1(i))
205 enddo
206 do, j = 1, ndim2
207 call deallocate(u2(j))
208 enddo
209 deallocate(u1, u2)
210
211 if (map_finished(map)) goto 1000
212
213 ! --- it fails ---
214 call endsub('getmatch', 'fail')
215 return
216
2171000 continue
218 do, i = 1, ndim1
219 call dbgmessage('map(%d, :)=%*d', i=(/i, map(i,:)/), n=(/ndim2/))
220 enddo
221 do, i = 1, ndim1
222 if (all(map(i, :) <= 0)) then
223 map1(i) = 0
224 else
225 map1(i:i) = maxloc(map(i, :))
226 endif
227 enddo
228 do, j = 1, ndim2
229 if (all(map(:, j) <= 0)) then
230 map2(j) = 0
231 else
232 map2(j:j) = maxloc(map(:, j), dim=1)
233 endif
234 enddo
235 call endsub('getmatch', 'okay')
236 end subroutine getmatch
237
238 logical function map_finished(map) result(result)
239 integer:: map(:, :)
240 integer:: i, j, ni
241 continue
242 call beginsub('map_finished')
243 ni = size(map, dim=1)
244 do, i = 1, ni
245 if (count(map(i, :) > 0) > 1) then
246 result = .false.
247 goto 999
248 endif
249 enddo
250 do, j = 1, ni
251 if (count(map(j, :) > 0) > 1) then
252 result = .false.
253 goto 999
254 endif
255 enddo
256 result = .true.
257999 continue
258 call endsub('map_finished')
259 end function map_finished
260
subroutine adjust_slice(var1, var2, idim1, idim2, offset, stepfact)
subroutine, public storeerror(number, where, err, cause_c, cause_i)
Definition dc_error.f90:830
integer, parameter, public gt_enomatchdim
Definition dc_error.f90:537
integer, parameter, public gt_efake
Definition dc_error.f90:523
integer, parameter, public dc_noerr
Definition dc_error.f90:509
Provides kind type parameter values.
Definition dc_types.f90:49
integer, parameter, public string
Character length for string
Definition dc_types.f90:118
logical function, public add_okay(u1, u2)
Definition dc_units.f90:175
subroutine map_apply(var, map)
subroutine map_allocate(map, ndims)

References adjust_slice(), dc_error::dc_noerr, dc_error::gt_efake, dc_error::gt_enomatchdim, gtdata_internal_map::gtvar_dump(), gtdata_internal_map::map_allocate(), gtdata_internal_map::map_apply(), and dc_error::storeerror().

Here is the call graph for this function: