37 real(kind=
dp),
allocatable :: centers(:)
39 real(kind=
dp),
allocatable :: edges(:)
41 real(kind=
dp),
allocatable :: widths(:)
55 if (
allocated(bin_grid%centers))
then
70 real(kind=
dp),
intent(in) :: r
72 real(kind=
dp),
intent(in) :: f_vol
74 real(kind=
dp),
intent(out) :: f_lnr
76 f_lnr = f_vol * 4d0 *
const%pi * r**3
88 integer,
intent(in) :: type
90 integer,
intent(in) :: n_bin
92 real(kind=
dp),
intent(in) :: min
94 real(kind=
dp),
intent(in) :: max
96 real(kind=
dp) :: c1, c2
100 "bin_grid requires a non-negative n_bin, not: " &
105 "log bin_grid requires a positive min value, not: " &
109 "bin_grid requires min < max, not: " &
114 if (n_bin == 0)
return
116 bin_grid%edges =
logspace(min, max, n_bin + 1)
120 bin_grid%centers =
logspace(c1, c2, n_bin)
121 bin_grid%widths = [ ((log(max) - log(min)) / real(n_bin, kind=
dp), &
124 bin_grid%edges =
linspace(min, max, n_bin + 1)
127 bin_grid%centers =
linspace(c1, c2, n_bin)
128 bin_grid%widths = [ ((max - min) / real(n_bin, kind=
dp), i=1,n_bin) ]
130 call die_msg(678302366,
"unknown bin_grid type: " &
148 real(kind=
dp),
intent(in) :: val
163 call die_msg(348908641,
"unknown bin_grid type: " &
182 integer,
intent(in) :: i_bin
184 real(kind=
dp),
intent(in) :: val
189 i_bin <=
bin_grid_size(bin_grid) + 1,
"i_bin not a valid bin in " &
195 if (val < bin_grid%edges(1))
then
208 if (bin_grid%edges(i_bin) <= val .and. &
209 val < bin_grid%edges(i_bin + 1))
then
215 val == bin_grid%edges(i_bin + 1))
then
230 real(kind=
dp),
intent(in) :: x_data(:)
232 real(kind=
dp),
intent(in) :: weight_data(
size(x_data))
237 integer :: i_data, x_bin
240 do i_data = 1,
size(x_data)
242 if ((x_bin >= 1) .and. (x_bin <=
bin_grid_size(x_bin_grid)))
then
244 + weight_data(i_data) / x_bin_grid%widths(x_bin)
260 real(kind=
dp),
intent(in) :: x_data(:)
264 real(kind=
dp),
intent(in) :: y_data(
size(x_data))
266 real(kind=
dp),
intent(in) :: weight_data(
size(x_data))
272 integer :: i_data, x_bin, y_bin
275 do i_data = 1,
size(x_data)
278 if ((x_bin >= 1) .and. (x_bin <=
bin_grid_size(x_bin_grid)) &
279 .and. (y_bin >= 1) .and. (y_bin <=
bin_grid_size(y_bin_grid)))
then
282 / x_bin_grid%widths(x_bin) / y_bin_grid%widths(y_bin)
291 subroutine spec_file_read_radius_bin_grid(file, bin_grid)
299 real(kind=
dp) :: d_min, d_max
328 end subroutine spec_file_read_radius_bin_grid
352 character,
intent(inout) :: buffer(:)
354 integer,
intent(inout) :: position
359 integer :: prev_position
361 prev_position = position
378 character,
intent(inout) :: buffer(:)
380 integer,
intent(inout) :: position
385 integer :: prev_position
387 prev_position = position
407 logical :: same_bin_min, same_bin_max
426 if (same_bin_min .and. same_bin_max)
then
447 integer,
intent(in) :: ncid
449 character(len=*),
intent(in) :: dim_name
451 character(len=*),
intent(in) :: unit
453 integer,
intent(out) :: dimid
455 character(len=*),
intent(in),
optional :: long_name
457 real(kind=
dp),
intent(in),
optional :: scale
459 integer :: status, varid, dimid_edges, varid_edges, varid_widths, i
460 real(kind=
dp) :: centers(
size(bin_grid%centers))
461 real(kind=
dp) :: edges(
size(bin_grid%edges))
462 real(kind=
dp) :: widths(
size(bin_grid%widths))
463 character(len=(len_trim(dim_name)+10)) :: dim_name_edges
464 character(len=255) :: use_long_name
466 status = nf90_inq_dimid(ncid, dim_name, dimid)
467 if (status == nf90_noerr)
return
472 dim_name_edges = trim(dim_name) //
"_edges"
473 if (
present(long_name))
then
474 call assert_msg(125084459, len_trim(long_name) <= len(use_long_name), &
475 "long_name is longer than " &
477 use_long_name = trim(long_name)
479 call assert_msg(660927086, len_trim(dim_name) <= len(use_long_name), &
480 "dim_name is longer than " &
482 use_long_name = trim(dim_name)
486 call pmc_nc_check(nf90_def_dim(ncid, dim_name,
size(bin_grid%centers), &
489 size(bin_grid%edges), dimid_edges))
492 centers = bin_grid%centers
493 edges = bin_grid%edges
494 widths = bin_grid%widths
496 if (
present(scale))
then
497 centers = centers * scale
498 edges = edges * scale
501 unit=unit, long_name=(trim(use_long_name) //
" grid centers"), &
502 description=(
"logarithmically spaced centers of " &
503 // trim(use_long_name) //
" grid, so that " // trim(dim_name) &
504 //
"(i) is the geometric mean of " // trim(dim_name_edges) &
505 //
"(i) and " // trim(dim_name_edges) //
"(i + 1)"))
507 (/ dimid_edges /), unit=unit, &
508 long_name=(trim(use_long_name) //
" grid edges"), &
509 description=(
"logarithmically spaced edges of " &
510 // trim(use_long_name) //
" grid, with one more edge than center"))
512 (/ dimid /), unit=
"1", &
513 long_name=(trim(use_long_name) //
" grid widths"), &
514 description=(
"base-e logarithmic widths of " &
515 // trim(use_long_name) //
" grid, with " // trim(dim_name) &
516 //
"_widths(i) = ln(" // trim(dim_name_edges) //
"(i + 1) / " &
517 // trim(dim_name_edges) //
"(i))"))
519 if (
present(scale))
then
520 centers = centers * scale
521 edges = edges * scale
522 widths = widths * scale
525 unit=unit, long_name=(trim(use_long_name) //
" grid centers"), &
526 description=(
"linearly spaced centers of " // trim(use_long_name) &
527 //
" grid, so that " // trim(dim_name) //
"(i) is the mean of " &
528 // trim(dim_name_edges) //
"(i) and " // trim(dim_name_edges) &
531 (/ dimid_edges /), unit=unit, &
532 long_name=(trim(use_long_name) //
" grid edges"), &
533 description=(
"linearly spaced edges of " &
534 // trim(use_long_name) //
" grid, with one more edge than center"))
536 (/ dimid /), unit=unit, &
537 long_name=(trim(use_long_name) //
" grid widths"), &
538 description=(
"widths of " // trim(use_long_name) &
539 //
" grid, with " // trim(dim_name) //
"_widths(i) = " &
540 // trim(dim_name_edges) //
"(i + 1) - " // trim(dim_name_edges) &
543 call die_msg(942560572,
"unknown bin_grid type: " &
558 integer,
intent(in) :: ncid
560 character(len=*),
intent(in) :: dim_name
562 character(len=*),
intent(in) :: unit
564 character(len=*),
intent(in),
optional :: long_name
566 real(kind=
dp),
intent(in),
optional :: scale
583 integer,
intent(in) :: ncid
585 character(len=*),
intent(in) :: dim_name
587 real(kind=
dp),
intent(in),
optional :: scale
589 integer :: dimid, varid, n_bin, type
590 character(len=1000) :: name, description
591 real(kind=
dp),
allocatable :: edges(:)
593 call pmc_nc_check(nf90_inq_dimid(ncid, dim_name, dimid))
594 call pmc_nc_check(nf90_inquire_dimension(ncid, dimid, name, n_bin))
595 call pmc_nc_check(nf90_inq_varid(ncid, dim_name, varid))
596 call pmc_nc_check(nf90_get_att(ncid, varid,
"description", description))
600 if (
starts_with(description,
"logarithmically"))
then
605 call die_msg(792158584,
"cannot identify grid type for NetCDF " &
606 //
"dimension: " // trim(dim_name))
609 if (
present(scale))
then
610 call bin_grid_make(bin_grid,
type, n_bin, scale * edges(1), &
611 scale * edges(n_bin + 1))
613 call bin_grid_make(bin_grid,
type, n_bin, edges(1), edges(n_bin + 1))