Index: trunk/share/debug/Makefile_full =================================================================== --- trunk/share/debug/Makefile_full (revision 8787) +++ trunk/share/debug/Makefile_full (revision 8788) @@ -1,628 +1,635 @@ FC=pgfortran_2019 FCFLAGS=-Mbackslash CC=gcc CCFLAGS= MODELS = \ SM.mdl \ SM_hadrons.mdl \ Test.mdl CC_SRC = \ sprintf_interface.c \ signal_interface.c F77_SRC = \ pythia.F \ pythia_pdf.f \ pythia6_up.f \ toppik.f \ toppik_axial.f FC0_SRC = FC_SRC = \ format_defs.f90 \ io_units.f90 \ kinds.f90 \ constants.f90 \ iso_varying_string.f90 \ unit_tests.f90 \ unit_tests_sub.f90 \ numeric_utils.f90 \ numeric_utils_sub.f90 \ system_dependencies.f90 \ string_utils.f90 \ string_utils_sub.f90 \ system_defs.f90 \ system_defs_sub.f90 \ debug_master.f90 \ diagnostics.f90 \ diagnostics_sub.f90 \ sorting.f90 \ physics_defs.f90 \ physics_defs_sub.f90 \ pdg_arrays.f90 \ bytes.f90 \ hashes.f90 \ md5.f90 \ model_data.f90 \ model_data_sub.f90 \ auto_components.f90 \ var_base.f90 \ model_testbed.f90 \ auto_components_uti.f90 \ auto_components_ut.f90 \ os_interface.f90 \ os_interface_sub.f90 \ c_particles.f90 \ c_particles_sub.f90 \ format_utils.f90 \ lorentz.f90 \ lorentz_sub.f90 \ phs_points.f90 \ phs_points_sub.f90 \ colors.f90 \ colors_sub.f90 \ flavors.f90 \ flavors_sub.f90 \ helicities.f90 \ helicities_sub.f90 \ quantum_numbers.f90 \ quantum_numbers_sub.f90 \ state_matrices.f90 \ state_matrices_sub.f90 \ interactions.f90 \ interactions_sub.f90 \ CppStringsWrap_dummy.f90 \ FastjetWrap_dummy.f90 \ cpp_strings.f90 \ cpp_strings_sub.f90 \ fastjet.f90 \ fastjet_sub.f90 \ jets.f90 \ subevents.f90 \ su_algebra.f90 \ su_algebra_sub.f90 \ bloch_vectors.f90 \ bloch_vectors_sub.f90 \ polarizations.f90 \ polarizations_sub.f90 \ particles.f90 \ particles_sub.f90 \ event_base.f90 \ event_base_sub.f90 \ eio_data.f90 \ eio_data_sub.f90 \ event_handles.f90 \ eio_base.f90 \ eio_base_sub.f90 \ eio_base_uti.f90 \ eio_base_ut.f90 \ variables.f90 \ variables_sub.f90 \ rng_base.f90 \ rng_base_sub.f90 \ tao_random_numbers.f90 \ rng_tao.f90 \ rng_tao_sub.f90 \ rng_stream.f90 \ rng_stream_sub.f90 \ rng_base_uti.f90 \ rng_base_ut.f90 \ dispatch_rng.f90 \ dispatch_rng_sub.f90 \ dispatch_rng_uti.f90 \ dispatch_rng_ut.f90 \ beam_structures.f90 \ beam_structures_sub.f90 \ evaluators.f90 \ evaluators_sub.f90 \ beams.f90 \ beams_sub.f90 \ sm_physics.f90 \ sm_physics_sub.f90 \ file_registries.f90 \ file_registries_sub.f90 \ sf_aux.f90 \ sf_aux_sub.f90 \ sf_mappings.f90 \ sf_mappings_sub.f90 \ sf_base.f90 \ sf_base_sub.f90 \ electron_pdfs.f90 \ electron_pdfs_sub.f90 \ sf_isr.f90 \ sf_isr_sub.f90 \ sf_epa.f90 \ sf_epa_sub.f90 \ sf_ewa.f90 \ sf_ewa_sub.f90 \ sf_escan.f90 \ sf_escan_sub.f90 \ sf_gaussian.f90 \ sf_gaussian_sub.f90 \ sf_beam_events.f90 \ sf_beam_events_sub.f90 \ circe1.f90 \ sf_circe1.f90 \ sf_circe1_sub.f90 \ circe2.f90 \ selectors.f90 \ selectors_sub.f90 \ sf_circe2.f90 \ sf_circe2_sub.f90 \ sm_qcd.f90 \ sm_qcd_sub.f90 \ sm_qed.f90 \ sm_qed_sub.f90 \ mrst2004qed.f90 \ cteq6pdf.f90 \ mstwpdf.f90 \ ct10pdf.f90 \ CJpdf.f90 \ ct14pdf.f90 \ pdf_builtin.f90 \ pdf_builtin_sub.f90 \ LHAPDFWrap_dummy.f90 \ lhapdf5_full_dummy.f90 \ lhapdf5_has_photon_dummy.f90 \ lhapdf.f90 \ hoppet_dummy.f90 \ hoppet_interface.f90 \ sf_pdf_builtin.f90 \ sf_pdf_builtin_sub.f90 \ sf_lhapdf.f90 \ sf_lhapdf_sub.f90 \ dispatch_beams.f90 \ dispatch_beams_sub.f90 \ process_constants.f90 \ process_constants_sub.f90 \ prclib_interfaces.f90 \ prc_core_def.f90 \ prc_core_def_sub.f90 \ particle_specifiers.f90 \ particle_specifiers_sub.f90 \ process_libraries.f90 \ process_libraries_sub.f90 \ prc_test.f90 \ prc_test_sub.f90 \ prc_core.f90 \ + prc_core_sub.f90 \ prc_test_core.f90 \ + prc_test_core_sub.f90 \ sm_qed.f90 \ + sm_qed_sub.f90 \ prc_omega.f90 \ + prc_omega_sub.f90 \ phs_base.f90 \ ifiles.f90 \ lexers.f90 \ syntax_rules.f90 \ parser.f90 \ expr_base.f90 \ formats.f90 \ formats_sub.f90 \ analysis.f90 \ user_code_interface.f90 \ observables.f90 \ observables_sub.f90 \ eval_trees.f90 \ interpolation.f90 \ interpolation_sub.f90 \ nr_tools.f90 \ ttv_formfactors.f90 \ ttv_formfactors_use.f90 \ ttv_formfactors_uti.f90 \ ttv_formfactors_ut.f90 \ models.f90 \ prclib_stacks.f90 \ prclib_stacks_sub.f90 \ user_files.f90 \ cputime.f90 \ cputime_sub.f90 \ mci_base.f90 \ integration_results.f90 \ integration_results_uti.f90 \ integration_results_ut.f90 \ mappings.f90 \ permutations.f90 \ resonances.f90 \ phs_trees.f90 \ phs_forests.f90 \ prc_external.f90 \ blha_config.f90 \ blha_olp_interfaces.f90 \ prc_openloops.f90 \ prc_threshold.f90 \ + prc_threshold_sub.f90 \ process_config.f90 \ process_counter.f90 \ process_mci.f90 \ pcm_base.f90 \ nlo_data.f90 \ cascades.f90 \ cascades2_lexer.f90 \ cascades2_lexer_uti.f90 \ cascades2_lexer_ut.f90 \ cascades2.f90 \ cascades2_uti.f90 \ cascades2_ut.f90 \ phs_none.f90 \ phs_rambo.f90 \ phs_wood.f90 \ phs_fks.f90 \ phs_single.f90 \ fks_regions.f90 \ virtual.f90 \ pdf.f90 \ pdf_sub.f90 \ real_subtraction.f90 \ dglap_remnant.f90 \ dispatch_fks.f90 \ dispatch_phase_space.f90 \ pcm.f90 \ recola_wrapper_dummy.f90 \ prc_recola.f90 \ subevt_expr.f90 \ parton_states.f90 \ prc_template_me.f90 \ + prc_template_me_sub.f90 \ process.f90 \ process_stacks.f90 \ iterations.f90 \ rt_data.f90 \ file_utils.f90 \ file_utils_sub.f90 \ prc_gosam.f90 \ dispatch_me_methods.f90 \ sf_base_uti.f90 \ sf_base_ut.f90 \ dispatch_uti.f90 \ dispatch_ut.f90 \ formats_uti.f90 \ formats_ut.f90 \ md5_uti.f90 \ md5_ut.f90 \ os_interface_uti.f90 \ os_interface_ut.f90 \ sorting_uti.f90 \ sorting_ut.f90 \ grids.f90 \ grids_uti.f90 \ grids_ut.f90 \ solver.f90 \ solver_uti.f90 \ solver_ut.f90 \ cputime_uti.f90 \ cputime_ut.f90 \ sm_qcd_uti.f90 \ sm_qcd_ut.f90 \ sm_physics_uti.f90 \ sm_physics_ut.f90 \ lexers_uti.f90 \ lexers_ut.f90 \ parser_uti.f90 \ parser_ut.f90 \ xml.f90 \ xml_uti.f90 \ xml_ut.f90 \ colors_uti.f90 \ colors_ut.f90 \ state_matrices_uti.f90 \ state_matrices_ut.f90 \ analysis_uti.f90 \ analysis_ut.f90 \ particles_uti.f90 \ particles_ut.f90 \ radiation_generator.f90 \ radiation_generator_uti.f90 \ radiation_generator_ut.f90 \ blha_uti.f90 \ blha_ut.f90 \ evaluators_uti.f90 \ evaluators_ut.f90 \ models_uti.f90 \ models_ut.f90 \ eval_trees_uti.f90 \ eval_trees_ut.f90 \ resonances_uti.f90 \ resonances_ut.f90 \ phs_trees_uti.f90 \ phs_trees_ut.f90 \ phs_forests_uti.f90 \ phs_forests_ut.f90 \ beams_uti.f90 \ beams_ut.f90 \ su_algebra_uti.f90 \ su_algebra_ut.f90 \ bloch_vectors_uti.f90 \ bloch_vectors_ut.f90 \ polarizations_uti.f90 \ polarizations_ut.f90 \ sf_aux_uti.f90 \ sf_aux_ut.f90 \ sf_mappings_uti.f90 \ sf_mappings_ut.f90 \ sf_pdf_builtin_uti.f90 \ sf_pdf_builtin_ut.f90 \ sf_lhapdf_uti.f90 \ sf_lhapdf_ut.f90 \ sf_isr_uti.f90 \ sf_isr_ut.f90 \ sf_epa_uti.f90 \ sf_epa_ut.f90 \ sf_ewa_uti.f90 \ sf_ewa_ut.f90 \ sf_circe1_uti.f90 \ sf_circe1_ut.f90 \ sf_circe2_uti.f90 \ sf_circe2_ut.f90 \ sf_gaussian_uti.f90 \ sf_gaussian_ut.f90 \ sf_beam_events_uti.f90 \ sf_beam_events_ut.f90 \ sf_escan_uti.f90 \ sf_escan_ut.f90 \ phs_base_uti.f90 \ phs_base_ut.f90 \ phs_none_uti.f90 \ phs_none_ut.f90 \ phs_single_uti.f90 \ phs_single_ut.f90 \ phs_rambo_uti.f90 \ phs_rambo_ut.f90 \ phs_wood_uti.f90 \ phs_wood_ut.f90 \ phs_fks_uti.f90 \ phs_fks_ut.f90 \ fks_regions_uti.f90 \ fks_regions_ut.f90 \ mci_midpoint.f90 \ mci_base_uti.f90 \ mci_base_ut.f90 \ mci_midpoint_uti.f90 \ mci_midpoint_ut.f90 \ kinematics.f90 \ instances.f90 \ mci_none.f90 \ mci_none_uti.f90 \ mci_none_ut.f90 \ processes_uti.f90 \ processes_ut.f90 \ process_stacks_uti.f90 \ process_stacks_ut.f90 \ prc_recola_uti.f90 \ prc_recola_ut.f90 \ rng_tao_uti.f90 \ rng_tao_ut.f90 \ rng_stream_uti.f90 \ rng_stream_ut.f90 \ selectors_uti.f90 \ selectors_ut.f90 \ vegas.f90 \ vegas_uti.f90 \ vegas_ut.f90 \ vamp2.f90 \ vamp2_uti.f90 \ vamp2_ut.f90 \ exceptions.f90 \ vamp_stat.f90 \ utils.f90 \ divisions.f90 \ linalg.f90 \ vamp.f90 \ mci_vamp.f90 \ mci_vamp_uti.f90 \ mci_vamp_ut.f90 \ mci_vamp2.f90 \ mci_vamp2_uti.f90 \ mci_vamp2_ut.f90 \ prclib_interfaces_uti.f90 \ prclib_interfaces_ut.f90 \ particle_specifiers_uti.f90 \ particle_specifiers_ut.f90 \ process_libraries_uti.f90 \ process_libraries_ut.f90 \ prclib_stacks_uti.f90 \ prclib_stacks_ut.f90 \ slha_interface.f90 \ slha_interface_uti.f90 \ slha_interface_ut.f90 \ cascades_uti.f90 \ cascades_ut.f90 \ prc_test_uti.f90 \ prc_test_ut.f90 \ prc_template_me_uti.f90 \ prc_template_me_ut.f90 \ prc_omega_uti.f90 \ prc_omega_ut.f90 \ event_transforms.f90 \ event_transforms_uti.f90 \ event_transforms_ut.f90 \ hep_common.f90 \ hep_common_sub.f90 \ hepev4_aux.f90 \ tauola_dummy.f90 \ tauola_interface.f90 \ + tauola_interface_sub.f90 \ shower_base.f90 \ shower_partons.f90 \ muli.f90 \ matching_base.f90 \ powheg_matching.f90 \ shower_core.f90 \ shower_base_uti.f90 \ shower_base_ut.f90 \ shower.f90 \ shower_uti.f90 \ shower_ut.f90 \ shower_pythia6.f90 \ whizard_lha.f90 \ whizard_lha_uti.f90 \ whizard_lha_ut.f90 \ LHAWhizard_dummy.f90 \ Pythia8Wrap_dummy.f90 \ pythia8.f90 \ pythia8_uti.f90 \ pythia8_ut.f90 \ shower_pythia8.f90 \ hadrons.f90 \ ktclus.f90 \ mlm_matching.f90 \ ckkw_matching.f90 \ jets_uti.f90 \ jets_ut.f90 \ pdg_arrays_uti.f90 \ pdg_arrays_ut.f90 \ interactions_uti.f90 \ interactions_ut.f90 \ decays.f90 \ decays_uti.f90 \ decays_ut.f90 \ evt_nlo.f90 \ events.f90 \ events_uti.f90 \ events_ut.f90 \ HepMCWrap_dummy.f90 \ hepmc_interface.f90 \ hepmc_interface_sub.f90 \ hepmc_interface_uti.f90 \ hepmc_interface_ut.f90 \ LCIOWrap_dummy.f90 \ lcio_interface.f90 \ lcio_interface_sub.f90 \ lcio_interface_uti.f90 \ lcio_interface_ut.f90 \ hep_events.f90 \ hep_events_sub.f90 \ hep_events_uti.f90 \ hep_events_ut.f90 \ expr_tests_uti.f90 \ expr_tests_ut.f90 \ parton_states_uti.f90 \ parton_states_ut.f90 \ eio_data_uti.f90 \ eio_data_ut.f90 \ eio_raw.f90 \ eio_raw_uti.f90 \ eio_raw_ut.f90 \ eio_checkpoints.f90 \ eio_checkpoints_sub.f90 \ eio_checkpoints_uti.f90 \ eio_checkpoints_ut.f90 \ eio_lhef.f90 \ eio_lhef_sub.f90 \ eio_lhef_uti.f90 \ eio_lhef_ut.f90 \ eio_hepmc.f90 \ eio_hepmc_sub.f90 \ eio_hepmc_uti.f90 \ eio_hepmc_ut.f90 \ eio_lcio.f90 \ eio_lcio_sub.f90 \ eio_lcio_uti.f90 \ eio_lcio_ut.f90 \ stdhep_dummy.f90 \ xdr_wo_stdhep.f90 \ eio_stdhep.f90 \ eio_stdhep_sub.f90 \ eio_stdhep_uti.f90 \ eio_stdhep_ut.f90 \ eio_ascii.f90 \ eio_ascii_sub.f90 \ eio_ascii_uti.f90 \ eio_ascii_ut.f90 \ eio_weights.f90 \ eio_weights_sub.f90 \ eio_weights_uti.f90 \ eio_weights_ut.f90 \ eio_dump.f90 \ eio_dump_sub.f90 \ eio_dump_uti.f90 \ eio_dump_ut.f90 \ eio_callback.f90 \ eio_callback_sub.f90 \ real_subtraction_uti.f90 \ real_subtraction_ut.f90 \ iterations_uti.f90 \ iterations_ut.f90 \ rt_data_uti.f90 \ rt_data_ut.f90 \ dispatch_mci.f90 \ dispatch_mci_uti.f90 \ dispatch_mci_ut.f90 \ dispatch_phs_uti.f90 \ dispatch_phs_ut.f90 \ resonance_insertion.f90 \ resonance_insertion_uti.f90 \ resonance_insertion_ut.f90 \ recoil_kinematics.f90 \ recoil_kinematics_uti.f90 \ recoil_kinematics_ut.f90 \ isr_epa_handler.f90 \ isr_epa_handler_uti.f90 \ isr_epa_handler_ut.f90 \ dispatch_transforms.f90 \ dispatch_transforms_uti.f90 \ dispatch_transforms_ut.f90 \ beam_structures_uti.f90 \ beam_structures_ut.f90 \ process_configurations.f90 \ process_configurations_uti.f90 \ process_configurations_ut.f90 \ compilations.f90 \ compilations_uti.f90 \ compilations_ut.f90 \ integrations.f90 \ integrations_uti.f90 \ integrations_ut.f90 \ event_streams.f90 \ event_streams_uti.f90 \ event_streams_ut.f90 \ restricted_subprocesses.f90 \ eio_direct.f90 \ eio_direct_sub.f90 \ eio_direct_uti.f90 \ eio_direct_ut.f90 \ simulations.f90 \ restricted_subprocesses_uti.f90 \ restricted_subprocesses_ut.f90 \ simulations_uti.f90 \ simulations_ut.f90 \ commands.f90 \ commands_uti.f90 \ commands_ut.f90 \ cmdline_options.f90 \ libmanager.f90 \ features.f90 \ whizard.f90 \ api.f90 \ api_hepmc_uti.f90 \ api_hepmc_ut.f90 \ api_lcio_uti.f90 \ api_lcio_ut.f90 \ api_uti.f90 \ api_ut.f90 FC_OBJ = $(FC0_SRC:.f90=.o) $(F77_SRC:.f=.o) $(FC_SRC:.f90=.o) CC_OBJ = $(CC_SRC:.c=.o) all: whizard_test check: whizard_test ./whizard_test --check resonances whizard_test: $(FC_OBJ) $(CC_OBJ) main_ut.f90 $(FC) $(FC_OBJ) $(CC_OBJ) -ldl -o $@ main_ut.f90 whizard: $(FC_OBJ) $(CC_OBJ) main.f90 $(FC) $(FC_OBJ) $(CC_OBJ) -ldl -o $@ main.f90 %.o: %.f90 $(FC) $(FCFLAGS) -c $< %.o: %.f $(FC) $(FCFLAGS) -c $< %.o: %.c $(CC) $(CCFLAGS) -c $< tar: $(FC_SRC) $(F77_SRC) $(FC0_SRC) $(CC_SRC) $(MODELS) tar cvvzf whizard-`date +%y%m%d`-`date +%H%M`.tar.gz $(FC_SRC) $(FC0_SRC) \ $(F77_SRC) $(CC_SRC) main_ut.f90 Makefile $(MODELS) clean: rm -f *.mod *.o whizard_test Index: trunk/src/me_methods/me_methods.nw =================================================================== --- trunk/src/me_methods/me_methods.nw (revision 8787) +++ trunk/src/me_methods/me_methods.nw (revision 8788) @@ -1,7031 +1,8167 @@ % -*- ess-noweb-default-code-mode: f90-mode; noweb-default-code-mode: f90-mode; -*- % WHIZARD code as NOWEB source: matrix elements and process libraries %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{Interface for Matrix Element Objects} \includemodulegraph{me_methods} These modules manage internal and, in particular, external matrix-element code. \begin{description} \item[prc\_core] We define the abstract [[prc_core_t]] type which handles all specific features of kinematics matrix-element evaluation that depend on a particular class of processes. This abstract type supplements the [[prc_core_def_t]] type and related types in another module. Together, they provide a complete set of matrix-element handlers that are implemented in the concrete types below. \end{description} These are the implementations: \begin{description} \item[prc\_template\_me] Implements matrix-element code without actual content (trivial value), but full-fledged interface. This can be used for injecting user-defined matrix-element code. \item[prc\_omega] Matrix elements calculated by \oMega\ are the default for WHIZARD. Here, we provide all necessary support. \item[prc\_external] Matrix elements provided or using external (not \oMega) code or libraries. This is an abstract type, with concrete extensions below: \item[prc\_external\_test] Concrete implementation of the external-code type, actually using some pre-defined test matrix elements. \item[prc\_gosam] Interface for matrix elements computed using \gosam. \item[prc\_openloops] Interface for matrix elements computed using OpenLoops. \item[prc\_recola] Interface for matrix elements computed using Recola. \item[prc\_threshold] Interface for matrix elements for the top-pair threshold, that use external libraries. \end{description} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Abstract process core} In this module we provide abstract data types for process classes. Each process class represents a set of processes which are handled by a common ``method'', e.g., by the \oMega\ matrix-element generator. The process class is also able to select a particular implementation for the phase-space and integration modules. For a complete implementation of a process class, we have to provide extensions of the following abstract types: \begin{description} \item[prc\_core\_def\_t] process and matrix-element configuration \item[prc\_writer\_t] (optional) writing external matrix-element code \item[prc\_driver\_t] accessing the matrix element (internal or external) \item[prc\_core\_t] evaluating kinematics and matrix element. The process core also selects phase-space and integrator implementations as appropriate for the process class and configuration. \end{description} In the actual process-handling data structures, each process component contains an instance of such a process class as its core. This allows us to keep the [[processes]] module below, which supervises matrix-element evaluation, integration, and event generation, free of any reference to concrete implementations (for the process class, phase space, and integrator). There are no unit tests, these are deferred to the [[processes]] module. <<[[prc_core.f90]]>>= <> module prc_core <> <> use io_units use diagnostics use os_interface, only: os_data_t use lorentz use interactions use variables, only: var_list_t use model_data, only: model_data_t use process_constants use prc_core_def use process_libraries use sf_base <> <> <> <> + interface +<> + end interface + +end module prc_core +@ %def prc_core +@ +<<[[prc_core_sub.f90]]>>= +<> + +submodule (prc_core) prc_core_s + + implicit none + contains <> -end module prc_core -@ %def prc_core +end submodule prc_core_s + +@ %def prc_core_s @ \subsection{The process core} The process core is of abstract data type. Different types of matrix elements will be represented by different implementations. <>= public :: prc_core_t <>= type, abstract :: prc_core_t class(prc_core_def_t), pointer :: def => null () logical :: data_known = .false. type(process_constants_t) :: data class(prc_core_driver_t), allocatable :: driver logical :: use_color_factors = .false. integer :: nc = 3 contains <> end type prc_core_t @ %def prc_core_t @ In any case there must be an output routine. <>= procedure(prc_core_write), deferred :: write <>= abstract interface subroutine prc_core_write (object, unit) import class(prc_core_t), intent(in) :: object integer, intent(in), optional :: unit end subroutine prc_core_write end interface @ %def prc_core_write @ Just type the name of the actual core method. <>= procedure(prc_core_write_name), deferred :: write_name <>= abstract interface subroutine prc_core_write_name (object, unit) import class(prc_core_t), intent(in) :: object integer, intent(in), optional :: unit end subroutine prc_core_write_name end interface @ %def prc_core_write_name @ For initialization, we assign a pointer to the process entry in the relevant library. This allows us to access all process functions via the implementation of [[prc_core_t]]. We declare the [[object]] as [[intent(inout)]], since just after allocation it may be useful to store some extra data in the object, which we can then use in the actual initialization. This applies to extensions of [[prc_core]] which override the [[init]] method. <>= procedure :: init => prc_core_init procedure :: base_init => prc_core_init +<>= + module subroutine prc_core_init (object, def, lib, id, i_component) + class(prc_core_t), intent(inout) :: object + class(prc_core_def_t), intent(in), target :: def + type(process_library_t), intent(in), target :: lib + type(string_t), intent(in) :: id + integer, intent(in) :: i_component + end subroutine prc_core_init <>= - subroutine prc_core_init (object, def, lib, id, i_component) + module subroutine prc_core_init (object, def, lib, id, i_component) class(prc_core_t), intent(inout) :: object class(prc_core_def_t), intent(in), target :: def type(process_library_t), intent(in), target :: lib type(string_t), intent(in) :: id integer, intent(in) :: i_component object%def => def call lib%connect_process (id, i_component, object%data, object%driver) object%data_known = .true. end subroutine prc_core_init @ %def prc_core_init @ Return true if the matrix element generation was successful. This can be tested by looking at the number of generated flavor states, which should be nonzero. <>= procedure :: has_matrix_element => prc_core_has_matrix_element +<>= + module function prc_core_has_matrix_element (object) result (flag) + class(prc_core_t), intent(in) :: object + logical :: flag + end function prc_core_has_matrix_element <>= - function prc_core_has_matrix_element (object) result (flag) + module function prc_core_has_matrix_element (object) result (flag) class(prc_core_t), intent(in) :: object logical :: flag flag = object%data%n_flv /= 0 end function prc_core_has_matrix_element @ %def prc_core_has_matrix_element @ Return true if this process-core type needs extra code that has to be compiled and/or linked, beyond the default \oMega\ framework. This depends only on the concrete type, and the default is no. <>= procedure, nopass :: needs_external_code => prc_core_needs_external_code +<>= + module function prc_core_needs_external_code () result (flag) + logical :: flag + end function prc_core_needs_external_code <>= - function prc_core_needs_external_code () result (flag) + module function prc_core_needs_external_code () result (flag) logical :: flag flag = .false. end function prc_core_needs_external_code @ %def prc_core_needs_external_code @ The corresponding procedure to create and load extra libraries. The base procedure must not be called but has to be overridden, if extra code is required. <>= procedure :: prepare_external_code => & prc_core_prepare_external_code +<>= + module subroutine prc_core_prepare_external_code & + (core, flv_states, var_list, os_data, libname, model, i_core, is_nlo) + class(prc_core_t), intent(inout) :: core + integer, intent(in), dimension(:,:), allocatable :: flv_states + type(var_list_t), intent(in) :: var_list + type(os_data_t), intent(in) :: os_data + type(string_t), intent(in) :: libname + type(model_data_t), intent(in), target :: model + integer, intent(in) :: i_core + logical, intent(in) :: is_nlo + end subroutine prc_core_prepare_external_code <>= - subroutine prc_core_prepare_external_code & + module subroutine prc_core_prepare_external_code & (core, flv_states, var_list, os_data, libname, model, i_core, is_nlo) class(prc_core_t), intent(inout) :: core integer, intent(in), dimension(:,:), allocatable :: flv_states type(var_list_t), intent(in) :: var_list type(os_data_t), intent(in) :: os_data type(string_t), intent(in) :: libname type(model_data_t), intent(in), target :: model integer, intent(in) :: i_core logical, intent(in) :: is_nlo call core%write () call msg_bug ("prc_core_prepare_external_code called & &but not overridden") end subroutine prc_core_prepare_external_code @ %def prc_core_prepare_external_code @ Return true if this process-core type uses the BLHA interface. This depends only on the concrete type, and the default is no. <>= procedure, nopass :: uses_blha => prc_core_uses_blha +<>= + module function prc_core_uses_blha () result (flag) + logical :: flag + end function prc_core_uses_blha <>= - function prc_core_uses_blha () result (flag) + module function prc_core_uses_blha () result (flag) logical :: flag flag = .false. end function prc_core_uses_blha @ %def prc_core_uses_blha @ Tell whether a particular combination of flavor/helicity/color state is allowed for the matrix element. <>= procedure(prc_core_is_allowed), deferred :: is_allowed <>= abstract interface function prc_core_is_allowed (object, i_term, f, h, c) result (flag) import class(prc_core_t), intent(in) :: object integer, intent(in) :: i_term, f, h, c logical :: flag end function prc_core_is_allowed end interface @ %def prc_core_is_allowed @ Set the constant process data for a specific term. By default, these are the constants stored inside the object, ignoring the term index. Type extensions may override this and provide term-specific data. <>= procedure :: get_constants => prc_core_get_constants +<>= + module subroutine prc_core_get_constants (object, data, i_term) + class(prc_core_t), intent(in) :: object + type(process_constants_t), intent(out) :: data + integer, intent(in) :: i_term + end subroutine prc_core_get_constants <>= - subroutine prc_core_get_constants (object, data, i_term) + module subroutine prc_core_get_constants (object, data, i_term) class(prc_core_t), intent(in) :: object type(process_constants_t), intent(out) :: data integer, intent(in) :: i_term data = object%data end subroutine prc_core_get_constants @ %def prc_core_get_constants @ The strong coupling is not among the process constants. The default implementation is to return a negative number, which indicates that $\alpha_s$ is not available. This may be overridden by an implementation that provides an (event-specific) value. The value can be stored in the process-specific workspace. <>= procedure :: get_alpha_s => prc_core_get_alpha_s +<>= + module function prc_core_get_alpha_s (object, core_state) result (alpha_qcd) + class(prc_core_t), intent(in) :: object + class(prc_core_state_t), intent(in), allocatable :: core_state + real(default) :: alpha_qcd + end function prc_core_get_alpha_s <>= - function prc_core_get_alpha_s (object, core_state) result (alpha_qcd) + module function prc_core_get_alpha_s (object, core_state) result (alpha_qcd) class(prc_core_t), intent(in) :: object class(prc_core_state_t), intent(in), allocatable :: core_state real(default) :: alpha_qcd alpha_qcd = -1 end function prc_core_get_alpha_s @ %def prc_core_get_alpha_s -@ We follow the same strategy for the electromagnetic coupling $\alpha_\text{em}$. +@ We follow the same strategy for the electromagnetic coupling +$\alpha_\text{em}$. <>= procedure :: get_alpha_qed => prc_core_get_alpha_qed +<>= + module function prc_core_get_alpha_qed & + (object, core_state) result (alpha_qed) + class(prc_core_t), intent(in) :: object + class(prc_core_state_t), intent(in), allocatable :: core_state + real(default) :: alpha_qed + end function prc_core_get_alpha_qed <>= - function prc_core_get_alpha_qed (object, core_state) result (alpha_qed) + module function prc_core_get_alpha_qed & + (object, core_state) result (alpha_qed) class(prc_core_t), intent(in) :: object class(prc_core_state_t), intent(in), allocatable :: core_state real(default) :: alpha_qed alpha_qed = -1 end function prc_core_get_alpha_qed @ %def prc_core_get_alpha_qed @ -Setup an index mapping for flavor structures and helicities that give the same matrix -element. The index mapping is according to the order of flavor structures known to the -[[prc_core]] class. This procedure here acts as a fallback in case there is no overridden -procedure in the [[prc_core]] extension. +Setup an index mapping for flavor structures and helicities that give +the same matrix element. The index mapping is according to the order +of flavor structures known to the [[prc_core]] class. This procedure +here acts as a fallback in case there is no overridden procedure in +the [[prc_core]] extension. <>= - procedure :: set_equivalent_flv_hel_indices => prc_core_set_equivalent_flv_hel_indices + procedure :: set_equivalent_flv_hel_indices => & + prc_core_set_equivalent_flv_hel_indices +<>= + module subroutine prc_core_set_equivalent_flv_hel_indices (object) + class(prc_core_t), intent(inout) :: object + end subroutine prc_core_set_equivalent_flv_hel_indices <>= - subroutine prc_core_set_equivalent_flv_hel_indices (object) + module subroutine prc_core_set_equivalent_flv_hel_indices (object) class(prc_core_t), intent(inout) :: object integer :: i, n_flv, n_hel n_flv = object%data%n_flv n_hel = object%data%n_hel if (.not. allocated (object%data%eqv_flv_index)) & allocate (object%data%eqv_flv_index(n_flv)) if (.not. allocated (object%data%eqv_hel_index)) & allocate (object%data%eqv_hel_index(n_hel)) if (size (object%data%eqv_flv_index) /= n_flv) & call msg_bug ("BLHA Core: Size mismatch between eqv_flv_index and number of flavors.") if (size (object%data%eqv_hel_index) /= n_hel) & call msg_bug ("BLHA Core: Size mismatch between eqv_hel_index and number of helicities.") object%data%eqv_flv_index = [(i, i = 1, n_flv)] object%data%eqv_hel_index = [(i, i = 1, n_hel)] end subroutine prc_core_set_equivalent_flv_hel_indices @ %def prc_core_set_equivalent_flv_hel_indices @ Get the index mappings for flavor and helicity mappings set up in [[prc_core_get_equivalent_flv_index]] or any overriding variation. <>= procedure :: get_equivalent_flv_index => prc_core_get_equivalent_flv_index procedure :: get_equivalent_hel_index => prc_core_get_equivalent_hel_index +<>= + module function prc_core_get_equivalent_flv_index & + (object) result (eqv_flv_index) + class(prc_core_t), intent(in) :: object + integer, dimension(:), allocatable :: eqv_flv_index + end function prc_core_get_equivalent_flv_index + module function prc_core_get_equivalent_hel_index & + (object) result (eqv_hel_index) + class(prc_core_t), intent(in) :: object + integer, dimension(:), allocatable :: eqv_hel_index + end function prc_core_get_equivalent_hel_index <>= - function prc_core_get_equivalent_flv_index (object) result (eqv_flv_index) + module function prc_core_get_equivalent_flv_index & + (object) result (eqv_flv_index) class(prc_core_t), intent(in) :: object integer, dimension(:), allocatable :: eqv_flv_index eqv_flv_index = object%data%eqv_flv_index end function prc_core_get_equivalent_flv_index - function prc_core_get_equivalent_hel_index (object) result (eqv_hel_index) + module function prc_core_get_equivalent_hel_index & + (object) result (eqv_hel_index) class(prc_core_t), intent(in) :: object integer, dimension(:), allocatable :: eqv_hel_index eqv_hel_index = object%data%eqv_hel_index end function prc_core_get_equivalent_hel_index @ %def prc_core_get_equivalent_flv_index prc_core_get_equivalent_hel_index @ Allocate the workspace associated to a process component. The default is that there is no workspace, so we do nothing. A type extension may override this and allocate a workspace object of appropriate type, which can be used in further calculations. In any case, the [[intent(out)]] attribute deletes any previously allocated workspace. <>= procedure :: allocate_workspace => prc_core_ignore_workspace +<>= + module subroutine prc_core_ignore_workspace (object, core_state) + class(prc_core_t), intent(in) :: object + class(prc_core_state_t), intent(inout), allocatable :: core_state + end subroutine prc_core_ignore_workspace <>= - subroutine prc_core_ignore_workspace (object, core_state) + module subroutine prc_core_ignore_workspace (object, core_state) class(prc_core_t), intent(in) :: object class(prc_core_state_t), intent(inout), allocatable :: core_state end subroutine prc_core_ignore_workspace @ %def prc_core_ignore_workspace @ Compute the momenta in the hard interaction, taking the seed kinematics as input. The [[i_term]] index tells us which term we want to compute. (The standard method is to just transfer the momenta to the hard interaction.) <>= procedure(prc_core_compute_hard_kinematics), deferred :: & compute_hard_kinematics <>= abstract interface subroutine prc_core_compute_hard_kinematics & (object, p_seed, i_term, int_hard, core_state) import class(prc_core_t), intent(in) :: object type(vector4_t), dimension(:), intent(in) :: p_seed integer, intent(in) :: i_term type(interaction_t), intent(inout) :: int_hard class(prc_core_state_t), intent(inout), allocatable :: core_state end subroutine prc_core_compute_hard_kinematics end interface @ %def prc_core_compute_hard_kinematics @ Compute the momenta in the effective interaction, taking the hard kinematics as input. (This is called only if parton recombination is to be applied for the process variant.) <>= procedure(prc_core_compute_eff_kinematics), deferred :: & compute_eff_kinematics <>= abstract interface subroutine prc_core_compute_eff_kinematics & (object, i_term, int_hard, int_eff, core_state) import class(prc_core_t), intent(in) :: object integer, intent(in) :: i_term type(interaction_t), intent(in) :: int_hard type(interaction_t), intent(inout) :: int_eff class(prc_core_state_t), intent(inout), allocatable :: core_state end subroutine prc_core_compute_eff_kinematics end interface @ %def prc_core_compute_eff_kinematics @ The process core must implement this function. Here, [[j]] is the index of the particular term we want to compute. The amplitude may depend on the factorization and renormalization scales. The [[core_state]] (workspace) argument may be used if it is provided by the caller. Otherwise, the routine should compute the result directly. <>= procedure(prc_core_compute_amplitude), deferred :: compute_amplitude <>= abstract interface function prc_core_compute_amplitude & (object, j, p, f, h, c, fac_scale, ren_scale, alpha_qcd_forced, & core_state) result (amp) import complex(default) :: amp class(prc_core_t), intent(in) :: object integer, intent(in) :: j type(vector4_t), dimension(:), intent(in) :: p integer, intent(in) :: f, h, c real(default), intent(in) :: fac_scale, ren_scale real(default), intent(in), allocatable :: alpha_qcd_forced class(prc_core_state_t), intent(inout), allocatable, optional :: & core_state end function prc_core_compute_amplitude end interface @ %def prc_core_compute_amplitude @ \subsection{Storage for intermediate results} The abstract [[prc_core_state_t]] type allows process cores to set up temporary workspace. The object is an extra argument for each of the individual calculations between kinematics setup and matrix-element evaluation. <>= public :: prc_core_state_t <>= type, abstract :: prc_core_state_t contains procedure(workspace_write), deferred :: write procedure(workspace_reset_new_kinematics), deferred :: reset_new_kinematics end type prc_core_state_t @ %def prc_core_state_t @ For debugging, we should at least have an output routine. <>= abstract interface subroutine workspace_write (object, unit) import class(prc_core_state_t), intent(in) :: object integer, intent(in), optional :: unit end subroutine workspace_write end interface @ %def workspace_write @ This is used during the NLO calculation, see there for more information. <>= abstract interface subroutine workspace_reset_new_kinematics (object) import class(prc_core_state_t), intent(inout) :: object end subroutine workspace_reset_new_kinematics end interface @ %def workspace_reset_new_kinematics @ \subsection{Helicity selection data} This is intended for use with \oMega, but may also be made available to other process methods. We set thresholds for counting the times a specific helicity amplitude is zero. When the threshold is reached, we skip this amplitude in subsequent calls. For initializing the helicity counters, we need an object that holds the two parameters, the threshold (large real number) and the cutoff (integer). A helicity value suppressed by more than [[threshold]] (a value which multiplies [[epsilon]], to be compared with the average of the current amplitude, default is $10^{10}$) is treated as zero. A matrix element is assumed to be zero and not called again if it has been zero [[cutoff]] times. <>= public :: helicity_selection_t <>= type :: helicity_selection_t logical :: active = .false. real(default) :: threshold = 0 integer :: cutoff = 0 contains <> end type helicity_selection_t @ %def helicity_selection_t @ Output. If the selection is inactive, print nothing. <>= procedure :: write => helicity_selection_write +<>= + module subroutine helicity_selection_write (object, unit) + class(helicity_selection_t), intent(in) :: object + integer, intent(in), optional :: unit + end subroutine helicity_selection_write <>= - subroutine helicity_selection_write (object, unit) + module subroutine helicity_selection_write (object, unit) class(helicity_selection_t), intent(in) :: object integer, intent(in), optional :: unit integer :: u u = given_output_unit (unit) if (object%active) then write (u, "(3x,A)") "Helicity selection data:" write (u, "(5x,A,ES17.10)") & "threshold =", object%threshold write (u, "(5x,A,I0)") & "cutoff = ", object%cutoff end if end subroutine helicity_selection_write @ %def helicity_selection_write @ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Test process type} For the following tests, we define a simple implementation of the abstract [[prc_core_t]], designed such as to complement the [[prc_test_t]] process definition type. Note that it is not given that the actual process is defined as [[prc_test_t]] type. We enforce this by calling [[prc_test_create_library]]. The driver component in the process core will then become of type [[prc_test_t]]. @ <<[[prc_test_core.f90]]>>= <> module prc_test_core <> - use io_units use lorentz use interactions use prc_test use prc_core <> <> <> + interface +<> + end interface + +end module prc_test_core +@ %def prc_test_core +@ +<<[[prc_test_core_sub.f90]]>>= +<> + +submodule (prc_test_core) prc_test_core_s + + use io_units + + implicit none + contains <> -end module prc_test_core -@ %def prc_test_core +end submodule prc_test_core_s + +@ %def prc_test_core_s +@ <>= public :: test_t <>= type, extends (prc_core_t) :: test_t contains <> end type test_t @ %def test_t <>= procedure :: write => test_write +<>= + module subroutine test_write (object, unit) + class(test_t), intent(in) :: object + integer, intent(in), optional :: unit + end subroutine test_write <>= - subroutine test_write (object, unit) + module subroutine test_write (object, unit) class(test_t), intent(in) :: object integer, intent(in), optional :: unit integer :: u u = given_output_unit (unit) write (u, "(3x,A)") "test type implementing prc_test" end subroutine test_write @ %def test_write <>= procedure :: write_name => test_write_name +<>= + module subroutine test_write_name (object, unit) + class(test_t), intent(in) :: object + integer, intent(in), optional :: unit + end subroutine test_write_name <>= - subroutine test_write_name (object, unit) + module subroutine test_write_name (object, unit) class(test_t), intent(in) :: object integer, intent(in), optional :: unit integer :: u u = given_output_unit (unit) write (u,"(1x,A)") "Core: prc_test" end subroutine test_write_name @ %def test_write_name @ This process type always needs a MC parameter set and a single term. This only state is always allowed. <>= procedure :: needs_mcset => test_needs_mcset procedure :: get_n_terms => test_get_n_terms procedure :: is_allowed => test_is_allowed +<>= + module function test_needs_mcset (object) result (flag) + class(test_t), intent(in) :: object + logical :: flag + end function test_needs_mcset + module function test_get_n_terms (object) result (n) + class(test_t), intent(in) :: object + integer :: n + end function test_get_n_terms + module function test_is_allowed (object, i_term, f, h, c) result (flag) + class(test_t), intent(in) :: object + integer, intent(in) :: i_term, f, h, c + logical :: flag + end function test_is_allowed <>= - function test_needs_mcset (object) result (flag) + module function test_needs_mcset (object) result (flag) class(test_t), intent(in) :: object logical :: flag flag = .true. end function test_needs_mcset - function test_get_n_terms (object) result (n) + module function test_get_n_terms (object) result (n) class(test_t), intent(in) :: object integer :: n n = 1 end function test_get_n_terms - function test_is_allowed (object, i_term, f, h, c) result (flag) + module function test_is_allowed (object, i_term, f, h, c) result (flag) class(test_t), intent(in) :: object integer, intent(in) :: i_term, f, h, c logical :: flag flag = .true. end function test_is_allowed @ %def test_needs_mcset @ %def test_get_n_terms @ %def test_is_allowed @ Transfer the generated momenta directly to the hard interaction in the (only) term. We assume that everything has been set up correctly, so the array fits. <>= procedure :: compute_hard_kinematics => test_compute_hard_kinematics +<>= + module subroutine test_compute_hard_kinematics & + (object, p_seed, i_term, int_hard, core_state) + class(test_t), intent(in) :: object + type(vector4_t), dimension(:), intent(in) :: p_seed + integer, intent(in) :: i_term + type(interaction_t), intent(inout) :: int_hard + class(prc_core_state_t), intent(inout), allocatable :: core_state + end subroutine test_compute_hard_kinematics <>= - subroutine test_compute_hard_kinematics & + module subroutine test_compute_hard_kinematics & (object, p_seed, i_term, int_hard, core_state) class(test_t), intent(in) :: object type(vector4_t), dimension(:), intent(in) :: p_seed integer, intent(in) :: i_term type(interaction_t), intent(inout) :: int_hard class(prc_core_state_t), intent(inout), allocatable :: core_state call int_hard%set_momenta (p_seed) end subroutine test_compute_hard_kinematics @ %def test_compute_hard_kinematics @ This procedure is not called for [[test_t]], just a placeholder. <>= procedure :: compute_eff_kinematics => test_compute_eff_kinematics +<>= + module subroutine test_compute_eff_kinematics & + (object, i_term, int_hard, int_eff, core_state) + class(test_t), intent(in) :: object + integer, intent(in) :: i_term + type(interaction_t), intent(in) :: int_hard + type(interaction_t), intent(inout) :: int_eff + class(prc_core_state_t), intent(inout), allocatable :: core_state + end subroutine test_compute_eff_kinematics <>= - subroutine test_compute_eff_kinematics & + module subroutine test_compute_eff_kinematics & (object, i_term, int_hard, int_eff, core_state) class(test_t), intent(in) :: object integer, intent(in) :: i_term type(interaction_t), intent(in) :: int_hard type(interaction_t), intent(inout) :: int_eff class(prc_core_state_t), intent(inout), allocatable :: core_state end subroutine test_compute_eff_kinematics @ %def test_compute_eff_kinematics @ Transfer the incoming momenta of [[p_seed]] directly to the effective interaction, and vice versa for the outgoing momenta. [[int_hard]] is left untouched since [[int_eff]] is an alias (via pointer) to it. <>= procedure :: recover_kinematics => test_recover_kinematics +<>= + module subroutine test_recover_kinematics & + (object, p_seed, int_hard, int_eff, core_state) + class(test_t), intent(in) :: object + type(vector4_t), dimension(:), intent(inout) :: p_seed + type(interaction_t), intent(inout) :: int_hard + type(interaction_t), intent(inout) :: int_eff + class(prc_core_state_t), intent(inout), allocatable :: core_state + end subroutine test_recover_kinematics <>= - subroutine test_recover_kinematics & + module subroutine test_recover_kinematics & (object, p_seed, int_hard, int_eff, core_state) class(test_t), intent(in) :: object type(vector4_t), dimension(:), intent(inout) :: p_seed type(interaction_t), intent(inout) :: int_hard type(interaction_t), intent(inout) :: int_eff class(prc_core_state_t), intent(inout), allocatable :: core_state integer :: n_in n_in = int_eff%get_n_in () call int_eff%set_momenta (p_seed(1:n_in), outgoing = .false.) p_seed(n_in+1:) = int_eff%get_momenta (outgoing = .true.) end subroutine test_recover_kinematics @ %def test_recover_kinematics @ Compute the amplitude. The driver ignores all quantum numbers and, in fact, returns a constant. Nevertheless, we properly transfer the momentum vectors. <>= procedure :: compute_amplitude => test_compute_amplitude +<>= + module function test_compute_amplitude & + (object, j, p, f, h, c, fac_scale, ren_scale, alpha_qcd_forced, & + core_state) result (amp) + class(test_t), intent(in) :: object + integer, intent(in) :: j + type(vector4_t), dimension(:), intent(in) :: p + integer, intent(in) :: f, h, c + real(default), intent(in) :: fac_scale, ren_scale + real(default), intent(in), allocatable :: alpha_qcd_forced + class(prc_core_state_t), intent(inout), allocatable, optional :: & + core_state + complex(default) :: amp + end function test_compute_amplitude <>= - function test_compute_amplitude & - (object, j, p, f, h, c, fac_scale, ren_scale, alpha_qcd_forced, core_state) & - result (amp) + module function test_compute_amplitude & + (object, j, p, f, h, c, fac_scale, ren_scale, alpha_qcd_forced, & + core_state) result (amp) class(test_t), intent(in) :: object integer, intent(in) :: j type(vector4_t), dimension(:), intent(in) :: p integer, intent(in) :: f, h, c real(default), intent(in) :: fac_scale, ren_scale real(default), intent(in), allocatable :: alpha_qcd_forced class(prc_core_state_t), intent(inout), allocatable, optional :: core_state complex(default) :: amp real(default), dimension(:,:), allocatable :: parray integer :: i, n_tot select type (driver => object%driver) type is (prc_test_t) if (driver%scattering) then n_tot = 4 else n_tot = 3 end if allocate (parray (0:3,n_tot)) forall (i = 1:n_tot) parray(:,i) = vector4_get_components (p(i)) amp = driver%get_amplitude (parray) end select end function test_compute_amplitude @ %def test_compute_amplitude @ @ \section{Template matrix elements} Here, we provide template matrix elements that are in structure very similar to \oMega\ matrix elements, but do not need its infrastructure. Per default, the matrix elements are flat, i.e. they have the constant value one. Analogous to the \oMega\ implementation, this section implements the interface to the templates (via the makefile) and the driver. <<[[prc_template_me.f90]]>>= <> module prc_template_me use, intrinsic :: iso_c_binding !NODEP! use kinds <> - use io_units - use system_defs, only: TAB - use diagnostics use os_interface use lorentz - use flavors use interactions use model_data use particle_specifiers, only: new_prt_spec use process_constants use prclib_interfaces use prc_core_def use process_libraries use prc_core <> <