259 subroutine initialize(this, aero_rep_set, aero_phase_set, chem_spec_data)
270 type(
property_t),
pointer :: spec_props, ion_pairs, ion_pair, &
271 sub_props, ions, interactions, interaction, poly_coeffs
272 character(len=:),
allocatable :: key_name, spec_name, phase_name, &
273 string_val, inter_spec_name
274 integer(kind=i_kind) :: n_phase, n_ion_pair, n_int_param, n_float_param
275 integer(kind=i_kind) :: i_aero_rep, i_phase, i_ion_pair, i_ion, i_spec, &
276 i_poly_coeff, i_interaction, j_ion_pair, j_interaction
277 integer(kind=i_kind) :: qty, int_val, charge, total_charge, tracer_type
278 real(kind=
dp) :: real_val, molecular_weight, min_rh, max_rh
279 type(
string_t),
allocatable :: unique_spec_names(:)
280 character(len=:),
allocatable :: ion_pair_name, ion_name
281 type(
string_t),
allocatable :: ion_pair_names(:), temp_ion_pair_names(:)
282 integer(kind=i_kind),
allocatable :: num_inter(:)
283 real(kind=
dp),
allocatable :: rh_range(:)
286 if (.not.
associated(this%property_set))
call die_msg(101529793, &
287 "Missing property set needed to initialize PDFiTE activity"// &
291 key_name =
"aerosol phase"
293 this%property_set%get_string(key_name, phase_name), &
294 "Missing aerosol phase in PDFiTE activity reaction.")
298 do i_aero_rep = 1,
size(aero_rep_set)
301 n_phase = n_phase + &
302 aero_rep_set(i_aero_rep)%val%num_phase_instances(phase_name)
307 "Aerosol phase '"//phase_name//
"' not present in any aerosol "// &
308 "representation for PDFiTE activity reaction.")
311 key_name =
"calculate for"
313 this%property_set%get_property_t(key_name, ion_pairs), &
314 "Missing ion pairs to calculate activity for in PDFiTE "// &
315 " activity reaction.")
318 n_ion_pair = ion_pairs%size()
319 call assert_msg(479529522, n_ion_pair .gt. 0, &
320 "Empty ion pair set in PDFiTE activity reaction.")
324 allocate(ion_pair_names(n_ion_pair))
327 call ion_pairs%iter_reset()
328 do i_ion_pair = 1, n_ion_pair
331 call assert(497564051, ion_pairs%get_key(ion_pair_name))
332 ion_pair_names(i_ion_pair)%string = ion_pair_name
334 call ion_pairs%iter_next()
339 n_int_param = num_int_prop_ + n_phase
341 n_float_param = num_real_prop_
342 call ion_pairs%iter_reset()
343 do i_ion_pair = 1, n_ion_pair
346 call assert(680654801, ion_pairs%get_key(ion_pair_name))
349 call assert_msg(287766741, ion_pairs%get_property_t(val=ion_pair), &
350 "Missing ion pair properties for '"//ion_pair_name// &
351 "' in PDFiTE activity reaction.")
354 key_name =
"interactions"
356 ion_pair%get_property_t(key_name, interactions), &
357 "Missing interaction parameters for '"//ion_pair_name// &
358 "' in PDFiTE activity reaction.")
361 call interactions%iter_reset()
362 do i_interaction = 1, interactions%size()
365 call assert(347348920, interactions%get_property_t(val=interaction))
368 key_name =
"ion pair"
370 interaction%get_string(key_name, inter_spec_name), &
371 "Missing interaction species name for ion pair '"// &
372 ion_pair_name//
"' in PD-FiTE activity reaction")
377 interaction%get_property_t(key_name, poly_coeffs), &
378 "Missing 'B' array of polynomial coefficients for ion "// &
379 "pair '"//inter_spec_name//
"' in activity coefficient "// &
380 "calculation for ion pair '"//ion_pair_name//
"' in "// &
381 "PD-FiTE activity reaction.")
384 call assert_msg(320927773, poly_coeffs%size().gt.0, &
385 "Insufficient polynomial coefficients for PDFiTE activity "//&
386 "calculation for ion_pair '"//ion_pair_name//
"'.")
389 n_float_param = n_float_param + 2 + poly_coeffs%size()
393 n_int_param = n_int_param + 3
397 do j_ion_pair = 1,
size(ion_pair_names)
398 if (inter_spec_name.eq.ion_pair_names(j_ion_pair)%string)
exit
399 if (j_ion_pair.eq.
size(ion_pair_names))
then
400 allocate(temp_ion_pair_names(j_ion_pair))
401 forall (i_spec=1:j_ion_pair)
402 temp_ion_pair_names(i_spec)%string = &
403 ion_pair_names(i_spec)%string
405 deallocate(ion_pair_names)
406 allocate(ion_pair_names(j_ion_pair+1))
407 forall (i_spec=1:j_ion_pair)
408 ion_pair_names(i_spec)%string = &
409 temp_ion_pair_names(i_spec)%string
411 deallocate(temp_ion_pair_names)
412 ion_pair_names(j_ion_pair+1)%string = inter_spec_name
416 call interactions%iter_next()
419 call ion_pairs%iter_next()
424 n_ion_pair =
size(ion_pair_names)
431 n_int_param = n_int_param + (8+(1+2*n_ion_pair)*n_phase)*n_ion_pair
434 n_float_param = n_float_param + 4*n_ion_pair
438 allocate(num_inter(n_ion_pair))
439 allocate(rh_range(n_ion_pair))
442 allocate(this%condensed_data_int(n_int_param))
443 allocate(this%condensed_data_real(n_float_param))
444 this%condensed_data_int(:) = int(9999, kind=
i_kind)
445 this%condensed_data_real(:) = real(9999.0, kind=
dp)
448 this%num_env_params = num_env_param_
452 num_ion_pairs_ = n_ion_pair
453 total_int_param_ = n_int_param
454 total_float_param_ = n_float_param
457 key_name =
"gas-phase water"
459 this%property_set%get_string(key_name,
spec_name), &
460 "Missing gas-phase water species name in PDFiTE activity "// &
463 gas_water_id_ = chem_spec_data%gas_state_id(
spec_name)
465 call assert_msg(442608616, gas_water_id_ .gt. 0, &
466 "Cannot find gas-phase water species '"//
spec_name//
"' for "// &
467 "PDFiTE activity reaction.")
470 key_name =
"aerosol-phase water"
472 this%property_set%get_string(key_name,
spec_name), &
473 "Missing aerosol-phase water species name in PDFiTE activity "// &
480 do i_aero_rep = 1,
size(aero_rep_set)
481 unique_spec_names = aero_rep_set(i_aero_rep)%val%unique_names( &
483 if (.not.
allocated(unique_spec_names)) cycle
484 do i_spec = 1,
size(unique_spec_names)
485 phase_id_(i_phase) = aero_rep_set(i_aero_rep)%val%spec_state_id( &
486 unique_spec_names(i_spec)%string)
487 call assert(658622226, phase_id_(i_phase).gt.0)
488 i_phase = i_phase + 1
490 deallocate(unique_spec_names)
492 i_phase = i_phase - 1
493 call assert_msg(653357919, i_phase.eq.num_phase_, &
494 "Incorrect number of aerosol water instances in PDFiTE "// &
495 "activity reaction. Expected "//trim(
to_string(num_phase_))// &
499 n_int_param = num_int_prop_ + num_phase_ + 2*num_ion_pairs_
500 n_float_param = num_real_prop_
501 call ion_pairs%iter_reset()
502 do i_ion_pair = 1, n_ion_pair
505 ion_pair_name = ion_pair_names(i_ion_pair)%string
509 pair_int_param_loc_(i_ion_pair) = n_int_param + 1
510 pair_float_param_loc_(i_ion_pair) = n_float_param + 1
514 do i_aero_rep = 1,
size(aero_rep_set)
515 unique_spec_names = aero_rep_set(i_aero_rep)%val%unique_names( &
516 phase_name = phase_name,
spec_name = ion_pair_name)
517 if (.not.
allocated(unique_spec_names)) cycle
518 do i_spec = 1,
size(unique_spec_names)
519 if (i_phase.eq.1)
then
520 ion_pair_act_id_(i_ion_pair) = &
521 aero_rep_set(i_aero_rep)%val%spec_state_id( &
522 unique_spec_names(i_spec)%string) - &
525 call assert(142173386, ion_pair_act_id_(i_ion_pair).eq. &
526 aero_rep_set(i_aero_rep)%val%spec_state_id( &
527 unique_spec_names(i_spec)%string) - &
530 i_phase = i_phase + 1
532 deallocate(unique_spec_names)
534 i_phase = i_phase - 1
535 call assert_msg(700406338, i_phase.eq.num_phase_, &
536 "Incorrect number of instances of ion pair '"// &
537 ion_pair_name//
"' in PDFiTE activity reaction. Expected "// &
538 trim(
to_string(num_phase_))//
" but got "// &
543 chem_spec_data%get_property_set(ion_pair_name, ion_pair), &
544 "Missing species properties for ion pair '"// &
545 ion_pair_name//
"' in PDFiTE activity reaction.")
549 chem_spec_data%get_type(ion_pair_name, tracer_type))
551 "Ion pair '"//ion_pair_name//
"' must have a tracer type '"// &
552 "ION_PAIR' to participate in a PD-FiTE activity reaction.")
556 call assert_msg(974596824, ion_pair%get_property_t(key_name, ions), &
557 "Mission ions for ion pair '"//ion_pair_name// &
558 "' in PDFiTE activity reaction.")
560 call assert_msg(852202160, ions%size().eq.2, &
561 "Invalid number of unique ions specified for ion pair '"// &
562 ion_pair_name//
"' in for PDFiTE in activity reaction. "// &
563 "Expected 2 got "//trim(
to_string(ions%size())))
567 call ions%iter_reset()
572 call assert(622753458, ions%get_key(ion_name))
576 if (ions%get_property_t(val=sub_props))
then
578 if (sub_props%get_int(key_name, int_val)) qty = int_val
583 chem_spec_data%get_property_set(ion_name, spec_props), &
584 "Missing species properties for ion '"//ion_name// &
585 "' in PDFiTE activity reaction.")
588 key_name =
"molecular weight [kg mol-1]"
590 spec_props%get_real(key_name, molecular_weight), &
591 "Missing molecular weight for ion '"//ion_name// &
592 "' in PDFiTE activity reaction.")
596 call assert_msg(663798152, spec_props%get_int(key_name, charge), &
597 "Missing charge for ion '"//ion_name//
"' in PDFiTE "// &
598 "activity reaction.")
600 if (charge.gt.0)
then
601 num_cation_(i_ion_pair) = qty
602 cation_mw_(i_ion_pair) = molecular_weight
603 else if (charge.lt.0)
then
604 num_anion_(i_ion_pair) = qty
605 anion_mw_(i_ion_pair) = molecular_weight
607 call die_msg(939555855,
"Neutral species '"//ion_name// &
608 "' not allowed in PDFiTE activity reaction ion pair")
612 total_charge = total_charge + qty * charge
616 do i_aero_rep = 1,
size(aero_rep_set)
617 unique_spec_names = aero_rep_set(i_aero_rep)%val%unique_names( &
618 phase_name = phase_name,
spec_name = ion_name)
619 if (.not.
allocated(unique_spec_names)) cycle
620 do i_spec = 1,
size(unique_spec_names)
621 if (charge.gt.0)
then
622 if (i_phase.eq.1)
then
623 cation_id_(i_ion_pair) = &
624 aero_rep_set(i_aero_rep)%val%spec_state_id( &
625 unique_spec_names(i_spec)%string) - &
628 call assert(425726370, cation_id_(i_ion_pair).eq. &
629 aero_rep_set(i_aero_rep)%val%spec_state_id( &
630 unique_spec_names(i_spec)%string) - &
634 if (i_phase.eq.1)
then
635 anion_id_(i_ion_pair) = &
636 aero_rep_set(i_aero_rep)%val%spec_state_id( &
637 unique_spec_names(i_spec)%string) - &
640 call assert(192466600, anion_id_(i_ion_pair).eq. &
641 aero_rep_set(i_aero_rep)%val%spec_state_id( &
642 unique_spec_names(i_spec)%string) - &
646 i_phase = i_phase + 1
648 deallocate(unique_spec_names)
650 i_phase = i_phase - 1
651 call assert_msg(759322632, i_phase.eq.num_phase_, &
652 "Incorrect number of instances of ion species '"// &
653 ion_name//
"' in PDFiTE activity reaction. Expected "// &
654 trim(
to_string(num_phase_))//
" but got "// &
658 call ions%iter_next()
662 call assert_msg(415650051, total_charge.eq.0, &
663 "Charge imbalance for ion_pair '"//ion_pair_name// &
664 " in PDFiTE activity reaction. Total charge: "// &
667 n_float_param = n_float_param + 4
668 n_int_param = n_int_param + 6 + (1+2*num_ion_pairs_)*num_phase_
672 if (i_ion_pair.le.ion_pairs%size())
then
673 call assert(362061689, ion_pairs%get_key(string_val))
674 call assert(444603372, string_val.eq.ion_pair_name)
677 call assert(520886936, ion_pairs%get_property_t(val=ion_pair))
680 key_name =
"interactions"
681 call assert(216229321, ion_pair%get_property_t(key_name,interactions))
684 num_inter_(i_ion_pair) = interactions%size()
688 call interactions%iter_reset()
689 do i_interaction = 1, interactions%size()
692 inter_spec_loc_(i_ion_pair, i_interaction) = n_float_param + 1
695 call assert(105466070, interactions%get_property_t(val=interaction))
698 key_name =
"ion pair"
700 interaction%get_string(key_name, inter_spec_name), &
701 "Missing interacting species name for ion pair '"// &
702 ion_pair_name//
"' in PDFiTE activity reaction.")
706 do i_spec = 1,
size(ion_pair_names)
707 if (ion_pair_names(i_spec)%string.eq.inter_spec_name)
then
708 num_inter(i_spec) = num_inter(i_spec) + 1
709 inter_spec_id_(i_ion_pair,i_interaction) = i_spec
717 interaction%get_real(key_name, &
718 min_rh_(i_ion_pair, i_interaction)), &
719 "Missing minimum RH value for ion pair '"// &
720 ion_pair_name//
"' interaction with '"//inter_spec_name// &
721 "' in PD-FiTE activity reaction.")
722 min_rh = min_rh_(i_ion_pair, i_interaction)
724 min_rh.ge.real(0.0, kind=
dp).and. &
725 min_rh.lt.real(1.0, kind=
dp), &
726 "Invalid value for minimum RH for ion pair '"// &
727 ion_pair_name//
"' interaction with '"//inter_spec_name// &
728 "' in PD-FiTE activity reaction: "//
to_string(min_rh))
733 interaction%get_real(key_name, &
734 max_rh_(i_ion_pair, i_interaction)), &
735 "Missing maximum RH value for ion pair '"// &
736 ion_pair_name//
"' interaction with '"//inter_spec_name// &
737 "' in PD-FiTE activity reaction.")
738 max_rh = max_rh_(i_ion_pair, i_interaction)
740 max_rh.gt.real(0.0, kind=
dp).and. &
741 max_rh.le.real(1.0, kind=
dp), &
742 "Invalid value for maximum RH for ion pair '"// &
743 ion_pair_name//
"' interaction with '"//inter_spec_name// &
744 "' in PD-FiTE activity reaction: "//
to_string(max_rh))
749 interaction%get_property_t(key_name, poly_coeffs))
750 num_b_(i_ion_pair, i_interaction) = poly_coeffs%size()
753 call poly_coeffs%iter_reset()
754 do i_poly_coeff = 1, poly_coeffs%size()
755 call assert_msg(988796931, poly_coeffs%get_real(val=real_val), &
756 "Invalid polynomial coefficient for ion_pair '"// &
757 ion_pair_name//
"' interaction with '"//inter_spec_name// &
758 "' in PDFiTE activity reaction.")
759 b_z_(i_ion_pair, i_interaction, i_poly_coeff) = real_val
760 call poly_coeffs%iter_next()
763 n_float_param = n_float_param + 2 + num_b_(i_ion_pair, i_interaction)
764 n_int_param = n_int_param + 3
766 call interactions%iter_next()
770 do i_spec = 1,
size(num_inter)
772 "Missing interaction parameters between ion_pair '"// &
773 ion_pair_name//
"' and '"//ion_pair_names(i_spec)%string// &
774 "' in PDFiTE activity interaction: "// &
782 do i_interaction = 1, num_inter_(i_ion_pair)
786 do j_interaction = i_interaction+1, num_inter_(i_ion_pair)
787 if (inter_spec_id_(i_ion_pair, i_interaction).ne. &
788 inter_spec_id_(i_ion_pair, j_interaction)) cycle
790 min_rh_(i_ion_pair, i_interaction).ge. &
791 max_rh_(i_ion_pair, j_interaction).or. &
792 max_rh_(i_ion_pair, i_interaction).le. &
793 min_rh_(i_ion_pair, j_interaction), &
794 "Overlapping RH range for interactions for ion pair '"// &
795 ion_pair_name//
"' in PD-FiTE activity reaction.")
800 rh_range(inter_spec_id_(i_ion_pair, i_interaction)) = &
801 rh_range(inter_spec_id_(i_ion_pair, i_interaction)) + &
802 (max_rh_(i_ion_pair, i_interaction) - &
803 min_rh_(i_ion_pair, i_interaction))
807 do i_spec = 1,
size(rh_range)
809 rh_range(i_spec).eq.real(1.0, kind=
dp).or. &
810 num_inter(i_spec).eq.0, &
811 "Incomplete RH coverage for interaction with ion pair '"// &
812 ion_pair_names(i_spec)%string//
"' for '"//ion_pair_name// &
813 "' PD-FiTE activity coefficient calculation.")
816 call ion_pairs%iter_next()
825 num_inter_(i_ion_pair) = 0
831 call assert(938415336, n_int_param.eq.total_int_param_)
832 call assert(433208931, n_float_param.eq.total_float_param_)
834 deallocate(ion_pair_names)
835 deallocate(num_inter)