gtool5 Fortran 90/95 Library 1.0.0-rc5
日本語
Loading...
Searching...
No Matches
Functions/Subroutines
gtvarlimitbinary.f90 File Reference

Unify dimension structure of two variables. More...

Go to the source code of this file.

Functions/Subroutines

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

Detailed Description

Unify dimension structure of two variables.

Author
Eizi TOYODA, Yasuhiro MORIKAWA

Definition in file gtvarlimitbinary.f90.

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 142 of file gtvarlimitbinary.f90.

143 use gtdata_generic, only: get, open, close
144 type(GT_VARIABLE), intent(in):: var1, var2
145 integer, intent(in):: idim1, idim2
146 integer, intent(out):: offset, stepfact
147 type(GT_VARIABLE):: var_d
148 integer:: n, buf(1)
149 real, allocatable:: val1(:), val2(:)
150 continue
151 call beginsub('adjust_slice')
152 call open(var_d, source_var=var1, dimord=idim1, count_compact=.true.)
153 call inquire(var_d, size=n)
154 allocate(val1(n))
155 call get(var_d, val1, n)
156 call close(var_d)
157 !
158 call open(var_d, source_var=var2, dimord=idim2, count_compact=.true.)
159 call inquire(var_d, size=n)
160 allocate(val2(n))
161 call get(var_d, val2, n)
162 call close(var_d)
163 !
164 buf(1:1) = minloc(abs(val1(:) - val2(1)))
165 offset = buf(1) - 1
166 if (size(val2) < 2 .or. size(val1) < 2) then
167 stepfact = 1
168 else
169 buf(1:1) = minloc(abs(val1(:) - val2(2)))
170 stepfact = buf(1) - (offset + 1)
171 endif
172 !
173 deallocate(val1, val2)
174 call endsub('adjust_slice')

References dc_units::add_okay(), dc_trace::beginsub(), dc_trace::dbgmessage(), dc_trace::endsub(), 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 
)

Unify dimension arrangement of two variables

Applies range constraints so that the dimension structure of var1 matches that of var2. If var1 has excess dimensions, they are hidden.

The result preserves var2's space and transforms var1. Dimensions of var2 take var2's width. Dimensions in var1 not in var2 become invisible and must be degenerate or absent.

If an error occurs, outputs a message and terminates. If err is provided, returns .true. and does not terminate.

Parameters
[in,out]var1First variable (to be transformed)
[in,out]var2Second variable (reference)
[out]errError flag (optional)

Definition at line 58 of file gtvarlimitbinary.f90.

59 use gtdata_types, only: gt_variable
64 implicit none
65 type(GT_VARIABLE), intent(inout):: var1, var2
66 logical, intent(out), optional:: err
67 integer:: ndim1, ndim2, ndimo
68 integer, allocatable:: map1(:), map2(:)
69 type(GT_DIMMAP), pointer:: newmap(:)
70 integer:: i, j, stat
71 character(*), parameter:: subnam = "GTVarXformBinary"
72continue
73 call beginsub(subnam, 'mapid=[%d, %d]', i=(/var1%mapid, var2%mapid/))
74 call gtvar_dump(var1)
75 call gtvar_dump(var2)
76 !
77 ! 二つの変数 var1, var2 から共有次元を調べ、対応表 map1, map2 をつくる。
78 !
79 if (present(err)) err = .false.
80 call inquire(var1, alldims=ndim1)
81 call inquire(var2, alldims=ndim2)
82 ndimo = max(ndim1, ndim2, 0)
83 allocate(map1(1:ndim1), map2(1:ndim2))
84 call getmatch(var1, var2, ndim1, ndim2, map1, map2)
85 call dbgmessage('map1=%*d map2=%*d', i=(/map1(1:ndim1), map2(1:ndim2)/), n=(/ndim1, ndim2/))
86 if (all(map2(1:ndim2) == 0)) then
87 stat = gt_enomatchdim
88 goto 999
89 endif
90 !
91 ! 再配置テーブル作成開始
92 !
93 ndimo = ndim2 + count(map1(1:ndim1) == 0)
94 call map_allocate(newmap, ndimo)
95 !
96 ! 1..ndim2 は map2 によって var2 の次元たちにマップする
97 !
98 newmap(1:ndim2)%dimno = map2(1:ndim2)
99 call inquire(var2, allcount=newmap(1:ndim2)%allcount)
100 call get_slice(var2, count=newmap(1:ndim2)%count)
101 do, j = 1, ndim2
102 if (map2(j) == 0) then
103 newmap(j)%start = 1
104 newmap(j)%stride = 1
105 call inquire(var2, j, url=newmap(j)%url)
106 else
107 ! 位置対応によって var1 側での開始位置を決定する
108 call adjust_slice(var1, var2, map2(j), j, &
109 & newmap(j)%start, newmap(j)%stride)
110 endif
111 enddo
112 !
113 ! ndim2+1.. ndimo は var2 に対応させられない var1 の次元をおく
114 !
115 j = 0
116 loop1: do, i = ndim2 + 1, ndimo
117 do
118 j = j + 1
119 if (j > ndim1) exit loop1
120 if (map1(j) <= 0) exit
121 enddo
122 newmap(i)%dimno = j
123 call inquire(var1, dimord=j, allcount=newmap(i)%allcount)
124 call get_slice(var1, dimord=j, start=newmap(i)%start, &
125 & count=newmap(i)%count, stride=newmap(i)%stride)
126 end do loop1
127 !
128 call map_apply(var1, map=newmap)
129 !
130 stat = dc_noerr
131999 continue
132 call storeerror(stat, subnam, err)
133 call endsub(subnam, 'stat=%d', i=(/stat/))
134 deallocate(map1, map2)
135 return
136contains
137
138 !
139 ! 二つの次元変数を調べ、軸上位置が対応するように
140 ! start シフト数と stride ファクタを決定する
141 !
142 subroutine adjust_slice(var1, var2, idim1, idim2, offset, stepfact)
143 use gtdata_generic, only: get, open, close
144 type(GT_VARIABLE), intent(in):: var1, var2
145 integer, intent(in):: idim1, idim2
146 integer, intent(out):: offset, stepfact
147 type(GT_VARIABLE):: var_d
148 integer:: n, buf(1)
149 real, allocatable:: val1(:), val2(:)
150 continue
151 call beginsub('adjust_slice')
152 call open(var_d, source_var=var1, dimord=idim1, count_compact=.true.)
153 call inquire(var_d, size=n)
154 allocate(val1(n))
155 call get(var_d, val1, n)
156 call close(var_d)
157 !
158 call open(var_d, source_var=var2, dimord=idim2, count_compact=.true.)
159 call inquire(var_d, size=n)
160 allocate(val2(n))
161 call get(var_d, val2, n)
162 call close(var_d)
163 !
164 buf(1:1) = minloc(abs(val1(:) - val2(1)))
165 offset = buf(1) - 1
166 if (size(val2) < 2 .or. size(val1) < 2) then
167 stepfact = 1
168 else
169 buf(1:1) = minloc(abs(val1(:) - val2(2)))
170 stepfact = buf(1) - (offset + 1)
171 endif
172 !
173 deallocate(val1, val2)
174 call endsub('adjust_slice')
175 end subroutine adjust_slice
176
177 !
178 ! 二つの変数から共有次元を調べ、対応表 map1, map2 を作る。
179 ! すなわち、それぞれの次元番号から相方の次元番号を得る表である。
180 !
181 subroutine getmatch(var1, var2, ndim1, ndim2, map1, map2)
182 use dc_types, only: string
183 use dc_units, only: units, add_okay, assignment(=), clear, deallocate
184 use gtdata_generic, only: get_attr, open, close
185 type(GT_VARIABLE), intent(in):: var1, var2
186 integer, intent(in):: ndim1, ndim2
187 integer, intent(out):: map1(:), map2(:)
188 type(GT_VARIABLE):: var_d
189 integer, allocatable:: map(:, :)
190 integer:: i, j
191 character(STRING):: su1, su2
192 type(UNITS), allocatable:: u1(:), u2(:)
193 continue
194 call beginsub('getmatch')
195 ! 返却値はデフォルト 0
196 map1(:) = 0
197 map2(:) = 0
198 ! 表の構築: 初期値は消去法をとることを示す
199 allocate(map(ndim1, ndim2))
200 map(:, :) = 1
201
202 ! 単位による対応 --- 加算可能でなければ対にしない
203 ! 単位の構成
204 allocate(u1(ndim1), u2(ndim2))
205 do, i = 1, ndim1
206 call open(var_d, var1, i, count_compact=.true.)
207 call get_attr(var_d, 'units', su1)
208 call close(var_d)
209 call clear(u1(i))
210 u1(i) = su1
211 enddo
212 do, j = 1, ndim2
213 call open(var_d, var2, j, count_compact=.true.)
214 call get_attr(var_d, 'units', su2)
215 call close(var_d)
216 call clear(u2(j))
217 u2(j) = su2
218 enddo
219 ! 処理
220 do, i = 1, ndim1
221 do, j = 1, ndim2
222 if (.not. add_okay(u1(i), u2(j))) &
223 & map(i, j) = 0
224 enddo
225 enddo
226 ! 単位の廃棄
227 do, i = 1, ndim1
228 call deallocate(u1(i))
229 enddo
230 do, j = 1, ndim2
231 call deallocate(u2(j))
232 enddo
233 deallocate(u1, u2)
234
235 if (map_finished(map)) goto 1000
236
237 ! --- it fails ---
238 call endsub('getmatch', 'fail')
239 return
240
2411000 continue
242 do, i = 1, ndim1
243 call dbgmessage('map(%d, :)=%*d', i=(/i, map(i,:)/), n=(/ndim2/))
244 enddo
245 do, i = 1, ndim1
246 if (all(map(i, :) <= 0)) then
247 map1(i) = 0
248 else
249 map1(i:i) = maxloc(map(i, :))
250 endif
251 enddo
252 do, j = 1, ndim2
253 if (all(map(:, j) <= 0)) then
254 map2(j) = 0
255 else
256 map2(j:j) = maxloc(map(:, j), dim=1)
257 endif
258 enddo
259 call endsub('getmatch', 'okay')
260 end subroutine getmatch
261
262 logical function map_finished(map) result(result)
263 integer:: map(:, :)
264 integer:: i, j, ni
265 continue
266 call beginsub('map_finished')
267 ni = size(map, dim=1)
268 do, i = 1, ni
269 if (count(map(i, :) > 0) > 1) then
270 result = .false.
271 goto 999
272 endif
273 enddo
274 do, j = 1, ni
275 if (count(map(j, :) > 0) > 1) then
276 result = .false.
277 goto 999
278 endif
279 enddo
280 result = .true.
281999 continue
282 call endsub('map_finished')
283 end function map_finished
284
subroutine adjust_slice(var1, var2, idim1, idim2, offset, stepfact)
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 gt_enomatchdim
Definition dc_error.f90:516
integer, parameter, public dc_noerr
Error storage variables
Definition dc_error.f90:468
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
subroutine, public beginsub(name, fmt, i, r, d, l, n, c1, c2, c3, ca, version)
Definition dc_trace.f90:476
subroutine, public endsub(name, fmt, i, r, d, l, n, c1, c2, c3, ca)
Definition dc_trace.f90:599
Provides kind type parameter values.
Definition dc_types.f90:55
integer, parameter, public string
Character length for string
Definition dc_types.f90:137
Unit system processing module.
Definition dc_units.f90:52
logical function, public add_okay(u1, u2)
Definition dc_units.f90:308
subroutine map_apply(var, map)
subroutine map_allocate(map, ndims)

References adjust_slice(), dc_trace::beginsub(), dc_trace::dbgmessage(), dc_error::dc_noerr, dc_trace::endsub(), 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: