260 subroutine initialize(this, aero_rep_set, aero_phase_set, chem_spec_data)
271 type(
property_t),
pointer :: spec_props, ion_pairs, ion_pair, &
272 sub_props, ions, interactions, interaction, poly_coeffs
273 character(len=:),
allocatable :: key_name, spec_name, phase_name, &
274 string_val, inter_spec_name
275 integer(kind=i_kind) :: n_phase, n_ion_pair, n_int_param, n_float_param
276 integer(kind=i_kind) :: i_aero_rep, i_phase, i_ion_pair, i_ion, i_spec, &
277 i_poly_coeff, i_interaction, j_ion_pair, j_interaction
278 integer(kind=i_kind) :: qty, int_val, charge, total_charge, tracer_type
279 real(kind=
dp) :: real_val, molecular_weight, min_rh, max_rh
280 type(
string_t),
allocatable :: unique_spec_names(:)
281 character(len=:),
allocatable :: ion_pair_name, ion_name
282 type(
string_t),
allocatable :: ion_pair_names(:), temp_ion_pair_names(:)
283 integer(kind=i_kind),
allocatable :: num_inter(:)
284 real(kind=
dp),
allocatable :: rh_range(:)
287 if (.not.
associated(this%property_set))
call die_msg(101529793, &
288 "Missing property set needed to initialize PDFiTE activity"// &
292 key_name =
"aerosol phase"
294 this%property_set%get_string(key_name, phase_name), &
295 "Missing aerosol phase in PDFiTE activity reaction.")
299 do i_aero_rep = 1,
size(aero_rep_set)
302 n_phase = n_phase + &
303 aero_rep_set(i_aero_rep)%val%num_phase_instances(phase_name)
308 "Aerosol phase '"//phase_name//
"' not present in any aerosol "// &
309 "representation for PDFiTE activity reaction.")
312 key_name =
"calculate for"
314 this%property_set%get_property_t(key_name, ion_pairs), &
315 "Missing ion pairs to calculate activity for in PDFiTE "// &
316 " activity reaction.")
319 n_ion_pair = ion_pairs%size()
320 call assert_msg(479529522, n_ion_pair .gt. 0, &
321 "Empty ion pair set in PDFiTE activity reaction.")
325 allocate(ion_pair_names(n_ion_pair))
328 call ion_pairs%iter_reset()
329 do i_ion_pair = 1, n_ion_pair
332 call assert(497564051, ion_pairs%get_key(ion_pair_name))
333 ion_pair_names(i_ion_pair)%string = ion_pair_name
335 call ion_pairs%iter_next()
340 n_int_param = num_int_prop_ + n_phase
342 n_float_param = num_real_prop_
343 call ion_pairs%iter_reset()
344 do i_ion_pair = 1, n_ion_pair
347 call assert(680654801, ion_pairs%get_key(ion_pair_name))
350 call assert_msg(287766741, ion_pairs%get_property_t(val=ion_pair), &
351 "Missing ion pair properties for '"//ion_pair_name// &
352 "' in PDFiTE activity reaction.")
355 key_name =
"interactions"
357 ion_pair%get_property_t(key_name, interactions), &
358 "Missing interaction parameters for '"//ion_pair_name// &
359 "' in PDFiTE activity reaction.")
362 call interactions%iter_reset()
363 do i_interaction = 1, interactions%size()
366 call assert(347348920, interactions%get_property_t(val=interaction))
369 key_name =
"ion pair"
371 interaction%get_string(key_name, inter_spec_name), &
372 "Missing interaction species name for ion pair '"// &
373 ion_pair_name//
"' in PD-FiTE activity reaction")
378 interaction%get_property_t(key_name, poly_coeffs), &
379 "Missing 'B' array of polynomial coefficients for ion "// &
380 "pair '"//inter_spec_name//
"' in activity coefficient "// &
381 "calculation for ion pair '"//ion_pair_name//
"' in "// &
382 "PD-FiTE activity reaction.")
385 call assert_msg(320927773, poly_coeffs%size().gt.0, &
386 "Insufficient polynomial coefficients for PDFiTE activity "//&
387 "calculation for ion_pair '"//ion_pair_name//
"'.")
390 n_float_param = n_float_param + 2 + poly_coeffs%size()
394 n_int_param = n_int_param + 3
398 do j_ion_pair = 1,
size(ion_pair_names)
399 if (inter_spec_name.eq.ion_pair_names(j_ion_pair)%string)
exit
400 if (j_ion_pair.eq.
size(ion_pair_names))
then
401 allocate(temp_ion_pair_names(j_ion_pair))
402 forall (i_spec=1:j_ion_pair)
403 temp_ion_pair_names(i_spec)%string = &
404 ion_pair_names(i_spec)%string
406 deallocate(ion_pair_names)
407 allocate(ion_pair_names(j_ion_pair+1))
408 forall (i_spec=1:j_ion_pair)
409 ion_pair_names(i_spec)%string = &
410 temp_ion_pair_names(i_spec)%string
412 deallocate(temp_ion_pair_names)
413 ion_pair_names(j_ion_pair+1)%string = inter_spec_name
417 call interactions%iter_next()
420 call ion_pairs%iter_next()
425 n_ion_pair =
size(ion_pair_names)
432 n_int_param = n_int_param + (8+(1+2*n_ion_pair)*n_phase)*n_ion_pair
435 n_float_param = n_float_param + 4*n_ion_pair
439 allocate(num_inter(n_ion_pair))
440 allocate(rh_range(n_ion_pair))
443 allocate(this%condensed_data_int(n_int_param))
444 allocate(this%condensed_data_real(n_float_param))
445 this%condensed_data_int(:) = int(9999, kind=
i_kind)
446 this%condensed_data_real(:) = real(9999.0, kind=
dp)
449 this%num_env_params = num_env_param_
453 num_ion_pairs_ = n_ion_pair
454 total_int_param_ = n_int_param
455 total_float_param_ = n_float_param
458 key_name =
"gas-phase water"
460 this%property_set%get_string(key_name,
spec_name), &
461 "Missing gas-phase water species name in PDFiTE activity "// &
464 gas_water_id_ = chem_spec_data%gas_state_id(
spec_name)
466 call assert_msg(442608616, gas_water_id_ .gt. 0, &
467 "Cannot find gas-phase water species '"//
spec_name//
"' for "// &
468 "PDFiTE activity reaction.")
471 key_name =
"aerosol-phase water"
473 this%property_set%get_string(key_name,
spec_name), &
474 "Missing aerosol-phase water species name in PDFiTE activity "// &
481 do i_aero_rep = 1,
size(aero_rep_set)
482 unique_spec_names = aero_rep_set(i_aero_rep)%val%unique_names( &
484 if (.not.
allocated(unique_spec_names)) cycle
485 do i_spec = 1,
size(unique_spec_names)
486 phase_id_(i_phase) = aero_rep_set(i_aero_rep)%val%spec_state_id( &
487 unique_spec_names(i_spec)%string)
488 call assert(658622226, phase_id_(i_phase).gt.0)
489 i_phase = i_phase + 1
491 deallocate(unique_spec_names)
493 i_phase = i_phase - 1
494 call assert_msg(653357919, i_phase.eq.num_phase_, &
495 "Incorrect number of aerosol water instances in PDFiTE "// &
496 "activity reaction. Expected "//trim(
to_string(num_phase_))// &
500 n_int_param = num_int_prop_ + num_phase_ + 2*num_ion_pairs_
501 n_float_param = num_real_prop_
502 call ion_pairs%iter_reset()
503 do i_ion_pair = 1, n_ion_pair
506 ion_pair_name = ion_pair_names(i_ion_pair)%string
510 pair_int_param_loc_(i_ion_pair) = n_int_param + 1
511 pair_float_param_loc_(i_ion_pair) = n_float_param + 1
515 do i_aero_rep = 1,
size(aero_rep_set)
516 unique_spec_names = aero_rep_set(i_aero_rep)%val%unique_names( &
517 phase_name = phase_name,
spec_name = ion_pair_name)
518 if (.not.
allocated(unique_spec_names)) cycle
519 do i_spec = 1,
size(unique_spec_names)
520 if (i_phase.eq.1)
then
521 ion_pair_act_id_(i_ion_pair) = &
522 aero_rep_set(i_aero_rep)%val%spec_state_id( &
523 unique_spec_names(i_spec)%string) - &
526 call assert(142173386, ion_pair_act_id_(i_ion_pair).eq. &
527 aero_rep_set(i_aero_rep)%val%spec_state_id( &
528 unique_spec_names(i_spec)%string) - &
531 i_phase = i_phase + 1
533 deallocate(unique_spec_names)
535 i_phase = i_phase - 1
536 call assert_msg(700406338, i_phase.eq.num_phase_, &
537 "Incorrect number of instances of ion pair '"// &
538 ion_pair_name//
"' in PDFiTE activity reaction. Expected "// &
539 trim(
to_string(num_phase_))//
" but got "// &
544 chem_spec_data%get_property_set(ion_pair_name, ion_pair), &
545 "Missing species properties for ion pair '"// &
546 ion_pair_name//
"' in PDFiTE activity reaction.")
550 chem_spec_data%get_type(ion_pair_name, tracer_type))
552 "Ion pair '"//ion_pair_name//
"' must have a tracer type '"// &
553 "ION_PAIR' to participate in a PD-FiTE activity reaction.")
557 call assert_msg(974596824, ion_pair%get_property_t(key_name, ions), &
558 "Mission ions for ion pair '"//ion_pair_name// &
559 "' in PDFiTE activity reaction.")
561 call assert_msg(852202160, ions%size().eq.2, &
562 "Invalid number of unique ions specified for ion pair '"// &
563 ion_pair_name//
"' in for PDFiTE in activity reaction. "// &
564 "Expected 2 got "//trim(
to_string(ions%size())))
568 call ions%iter_reset()
573 call assert(622753458, ions%get_key(ion_name))
577 if (ions%get_property_t(val=sub_props))
then
579 if (sub_props%get_int(key_name, int_val)) qty = int_val
584 chem_spec_data%get_property_set(ion_name, spec_props), &
585 "Missing species properties for ion '"//ion_name// &
586 "' in PDFiTE activity reaction.")
589 key_name =
"molecular weight [kg mol-1]"
591 spec_props%get_real(key_name, molecular_weight), &
592 "Missing molecular weight for ion '"//ion_name// &
593 "' in PDFiTE activity reaction.")
597 call assert_msg(663798152, spec_props%get_int(key_name, charge), &
598 "Missing charge for ion '"//ion_name//
"' in PDFiTE "// &
599 "activity reaction.")
601 if (charge.gt.0)
then
602 num_cation_(i_ion_pair) = qty
603 cation_mw_(i_ion_pair) = molecular_weight
604 else if (charge.lt.0)
then
605 num_anion_(i_ion_pair) = qty
606 anion_mw_(i_ion_pair) = molecular_weight
608 call die_msg(939555855,
"Neutral species '"//ion_name// &
609 "' not allowed in PDFiTE activity reaction ion pair")
613 total_charge = total_charge + qty * charge
617 do i_aero_rep = 1,
size(aero_rep_set)
618 unique_spec_names = aero_rep_set(i_aero_rep)%val%unique_names( &
619 phase_name = phase_name,
spec_name = ion_name)
620 if (.not.
allocated(unique_spec_names)) cycle
621 do i_spec = 1,
size(unique_spec_names)
622 if (charge.gt.0)
then
623 if (i_phase.eq.1)
then
624 cation_id_(i_ion_pair) = &
625 aero_rep_set(i_aero_rep)%val%spec_state_id( &
626 unique_spec_names(i_spec)%string) - &
629 call assert(425726370, cation_id_(i_ion_pair).eq. &
630 aero_rep_set(i_aero_rep)%val%spec_state_id( &
631 unique_spec_names(i_spec)%string) - &
635 if (i_phase.eq.1)
then
636 anion_id_(i_ion_pair) = &
637 aero_rep_set(i_aero_rep)%val%spec_state_id( &
638 unique_spec_names(i_spec)%string) - &
641 call assert(192466600, anion_id_(i_ion_pair).eq. &
642 aero_rep_set(i_aero_rep)%val%spec_state_id( &
643 unique_spec_names(i_spec)%string) - &
647 i_phase = i_phase + 1
649 deallocate(unique_spec_names)
651 i_phase = i_phase - 1
652 call assert_msg(759322632, i_phase.eq.num_phase_, &
653 "Incorrect number of instances of ion species '"// &
654 ion_name//
"' in PDFiTE activity reaction. Expected "// &
655 trim(
to_string(num_phase_))//
" but got "// &
659 call ions%iter_next()
663 call assert_msg(415650051, total_charge.eq.0, &
664 "Charge imbalance for ion_pair '"//ion_pair_name// &
665 " in PDFiTE activity reaction. Total charge: "// &
668 n_float_param = n_float_param + 4
669 n_int_param = n_int_param + 6 + (1+2*num_ion_pairs_)*num_phase_
673 if (i_ion_pair.le.ion_pairs%size())
then
674 call assert(362061689, ion_pairs%get_key(string_val))
675 call assert(444603372, string_val.eq.ion_pair_name)
678 call assert(520886936, ion_pairs%get_property_t(val=ion_pair))
681 key_name =
"interactions"
682 call assert(216229321, ion_pair%get_property_t(key_name,interactions))
685 num_inter_(i_ion_pair) = interactions%size()
689 call interactions%iter_reset()
690 do i_interaction = 1, interactions%size()
693 inter_spec_loc_(i_ion_pair, i_interaction) = n_float_param + 1
696 call assert(105466070, interactions%get_property_t(val=interaction))
699 key_name =
"ion pair"
701 interaction%get_string(key_name, inter_spec_name), &
702 "Missing interacting species name for ion pair '"// &
703 ion_pair_name//
"' in PDFiTE activity reaction.")
707 do i_spec = 1,
size(ion_pair_names)
708 if (ion_pair_names(i_spec)%string.eq.inter_spec_name)
then
709 num_inter(i_spec) = num_inter(i_spec) + 1
710 inter_spec_id_(i_ion_pair,i_interaction) = i_spec
718 interaction%get_real(key_name, &
719 min_rh_(i_ion_pair, i_interaction)), &
720 "Missing minimum RH value for ion pair '"// &
721 ion_pair_name//
"' interaction with '"//inter_spec_name// &
722 "' in PD-FiTE activity reaction.")
723 min_rh = min_rh_(i_ion_pair, i_interaction)
725 min_rh.ge.real(0.0, kind=
dp).and. &
726 min_rh.lt.real(1.0, kind=
dp), &
727 "Invalid value for minimum RH for ion pair '"// &
728 ion_pair_name//
"' interaction with '"//inter_spec_name// &
729 "' in PD-FiTE activity reaction: "//
to_string(min_rh))
734 interaction%get_real(key_name, &
735 max_rh_(i_ion_pair, i_interaction)), &
736 "Missing maximum RH value for ion pair '"// &
737 ion_pair_name//
"' interaction with '"//inter_spec_name// &
738 "' in PD-FiTE activity reaction.")
739 max_rh = max_rh_(i_ion_pair, i_interaction)
741 max_rh.gt.real(0.0, kind=
dp).and. &
742 max_rh.le.real(1.0, kind=
dp), &
743 "Invalid value for maximum RH for ion pair '"// &
744 ion_pair_name//
"' interaction with '"//inter_spec_name// &
745 "' in PD-FiTE activity reaction: "//
to_string(max_rh))
750 interaction%get_property_t(key_name, poly_coeffs))
751 num_b_(i_ion_pair, i_interaction) = poly_coeffs%size()
754 call poly_coeffs%iter_reset()
755 do i_poly_coeff = 1, poly_coeffs%size()
756 call assert_msg(988796931, poly_coeffs%get_real(val=real_val), &
757 "Invalid polynomial coefficient for ion_pair '"// &
758 ion_pair_name//
"' interaction with '"//inter_spec_name// &
759 "' in PDFiTE activity reaction.")
760 b_z_(i_ion_pair, i_interaction, i_poly_coeff) = real_val
761 call poly_coeffs%iter_next()
764 n_float_param = n_float_param + 2 + num_b_(i_ion_pair, i_interaction)
765 n_int_param = n_int_param + 3
767 call interactions%iter_next()
771 do i_spec = 1,
size(num_inter)
773 "Missing interaction parameters between ion_pair '"// &
774 ion_pair_name//
"' and '"//ion_pair_names(i_spec)%string// &
775 "' in PDFiTE activity interaction: "// &
783 do i_interaction = 1, num_inter_(i_ion_pair)
787 do j_interaction = i_interaction+1, num_inter_(i_ion_pair)
788 if (inter_spec_id_(i_ion_pair, i_interaction).ne. &
789 inter_spec_id_(i_ion_pair, j_interaction)) cycle
791 min_rh_(i_ion_pair, i_interaction).ge. &
792 max_rh_(i_ion_pair, j_interaction).or. &
793 max_rh_(i_ion_pair, i_interaction).le. &
794 min_rh_(i_ion_pair, j_interaction), &
795 "Overlapping RH range for interactions for ion pair '"// &
796 ion_pair_name//
"' in PD-FiTE activity reaction.")
801 rh_range(inter_spec_id_(i_ion_pair, i_interaction)) = &
802 rh_range(inter_spec_id_(i_ion_pair, i_interaction)) + &
803 (max_rh_(i_ion_pair, i_interaction) - &
804 min_rh_(i_ion_pair, i_interaction))
808 do i_spec = 1,
size(rh_range)
810 (rh_range(i_spec).ge.ieee_next_after(1.0_dp, 0.0_dp) .and. &
811 rh_range(i_spec).le.ieee_next_after(1.0_dp, 2.0_dp)) .or. &
812 num_inter(i_spec).eq.0, &
813 "Incomplete RH coverage for interaction with ion pair '"// &
814 ion_pair_names(i_spec)%string//
"' for '"//ion_pair_name// &
815 "' PD-FiTE activity coefficient calculation.")
818 call ion_pairs%iter_next()
827 num_inter_(i_ion_pair) = 0
833 call assert(938415336, n_int_param.eq.total_int_param_)
834 call assert(433208931, n_float_param.eq.total_float_param_)
836 deallocate(ion_pair_names)
837 deallocate(num_inter)