Timer unit: 1e-06 s Total time: 12.4112 s File: /pfs/work/g2pbloch/jintrac/python/jintrac_imas_driver.py Function: jetto_wrapper at line 304 Line # Hits Time Per Hit % Time Line Contents ============================================================== 304 @profile 305 def jetto_wrapper(noprocessors, in_imas_control, in_ids_bundle_updated, in_ids_bundle_work, in_ids_bundle_prev): 306 """Wrapper for Jetto Fortran actor.""" 307 308 1 9.2 9.2 0.0 if verbose: print("JINTRAC_IMAS_DRIVER: jetto wrapper called...", mpicfg.myrank) 309 310 1 0.9 0.9 0.0 in_prof = in_ids_bundle_work['core_profiles'] 311 1 0.5 0.5 0.0 in_src = in_ids_bundle_work['core_sources'] 312 1 0.4 0.4 0.0 in_trans = in_ids_bundle_work['core_transport'] 313 1 0.5 0.5 0.0 in_equil = in_ids_bundle_work['equilibrium'] 314 1 0.4 0.4 0.0 in_nbi = in_ids_bundle_work['nbi'] 315 1 0.3 0.3 0.0 in_pel = in_ids_bundle_work['pellets'] 316 1 0.4 0.4 0.0 in_pulse = in_ids_bundle_work['pulse_schedule'] 317 1 0.4 0.4 0.0 in_contr = in_ids_bundle_work['controllers'] 318 1 0.4 0.4 0.0 in_summ = in_ids_bundle_work['summary'] 319 1 0.5 0.5 0.0 in_num = in_ids_bundle_updated['transport_solver_numerics'] 320 1 0.3 0.3 0.0 in_work = in_ids_bundle_updated['workflow'] 321 322 1 5.8 5.8 0.0 if verbose: print("JINTRAC_IMAS_DRIVER: Calling jetto_actor...", mpicfg.myrank) 323 1 0.7 0.7 0.0 out_prof, out_src, out_trans, out_equil, out_summ, out_num, out_work \ 324 1 8768238.1 8768238.1 70.6 = jetto(in_prof, in_src, in_trans, in_equil, in_nbi, 325 1 0.3 0.3 0.0 in_pel, in_pulse, in_contr, in_summ, in_num, in_work) 326 1 30.7 30.7 0.0 if verbose: print("JINTRAC_IMAS_DRIVER: ...jetto_actor done!", mpicfg.myrank) 327 328 1 2.2 2.2 0.0 if mpicfg.init and mpicfg.size > 1: 329 out_prof = mpicfg.comm.bcast(out_prof, root=0) 330 out_src = mpicfg.comm.bcast(out_src, root=0) 331 out_trans = mpicfg.comm.bcast(out_trans, root=0) 332 out_equil = mpicfg.comm.bcast(out_equil, root=0) 333 out_summ = mpicfg.comm.bcast(out_summ, root=0) 334 out_num = mpicfg.comm.bcast(out_num, root=0) 335 out_work = mpicfg.comm.bcast(out_work, root=0) 336 337 8 8.7 1.1 0.0 for ii in range(len(out_work.time_loop.component)): 338 7 9.6 1.4 0.0 if out_work.time_loop.component[ii].name == 'jetto': 339 1 0.3 0.3 0.0 jetto_index = ii 340 1 9.0 9.0 0.0 time = out_work.time_loop.workflow_cycle[0].component[jetto_index].control_float[0] 341 342 # time is not correctly transferred back from JETTO via out_work.time[0] 343 # even though out_work.time[0] still has the correct value at the very end 344 # of the JETTO actor routine jetto_actor.f90 ; the time for a time slice 345 # does not seem to become passed back for any IDS structure; to circumvent 346 # this bug, the time is written also to 347 # time_loop.workflow_cycle[0].component[jetto_index].control_float[0] in 348 # JETTO and re-set in out_work.time[0] with this quantity 349 350 1 1.6 1.6 0.0 out_work.ids_properties.homogeneous_time = imas.imasdef.IDS_TIME_MODE_HOMOGENEOUS 351 1 3.0 3.0 0.0 out_work.time[0] = time 352 353 1 4.7 4.7 0.0 timereached = out_work.time[0] + out_work.time_loop.workflow_cycle[0].component[jetto_index].time_interval 354 1 2.1 2.1 0.0 if out_prof.ids_properties.homogeneous_time == imas.imasdef.IDS_TIME_MODE_HOMOGENEOUS: 355 1 1.0 1.0 0.0 out_prof.time[0] = timereached 356 1 1.7 1.7 0.0 if out_src.ids_properties.homogeneous_time == imas.imasdef.IDS_TIME_MODE_HOMOGENEOUS: 357 1 0.8 0.8 0.0 out_src.time[0] = timereached 358 1 2.0 2.0 0.0 if out_trans.ids_properties.homogeneous_time == imas.imasdef.IDS_TIME_MODE_HOMOGENEOUS: 359 1 0.7 0.7 0.0 out_trans.time[0] = timereached 360 1 1.6 1.6 0.0 if out_equil.ids_properties.homogeneous_time == imas.imasdef.IDS_TIME_MODE_HOMOGENEOUS: 361 1 0.7 0.7 0.0 out_equil.time[0] = timereached 362 1 1.3 1.3 0.0 if out_summ.ids_properties.homogeneous_time == imas.imasdef.IDS_TIME_MODE_HOMOGENEOUS: 363 1 0.5 0.5 0.0 out_summ.time[0] = timereached 364 1 0.8 0.8 0.0 if out_num.ids_properties.homogeneous_time == imas.imasdef.IDS_TIME_MODE_HOMOGENEOUS: 365 1 0.6 0.6 0.0 out_num.time[0] = timereached 366 367 1 3589306.4 3589306.4 28.9 out_ids_bundle = bundle_copy(in_ids_bundle_work) 368 1 714.8 714.8 0.0 out_ids_bundle['core_profiles'] = out_prof 369 1 1774.6 1774.6 0.0 out_ids_bundle['core_sources'] = out_src 370 1 17.9 17.9 0.0 out_ids_bundle['core_transport'] = out_trans 371 1 50381.1 50381.1 0.4 out_ids_bundle['equilibrium'] = out_equil 372 1 557.6 557.6 0.0 out_ids_bundle['summary'] = out_summ 373 1 24.4 24.4 0.0 out_ids_bundle['transport_solver_numerics'] = out_num 374 1 30.8 30.8 0.0 out_ids_bundle['workflow'] = out_work 375 376 1 0.2 0.2 0.0 return out_ids_bundle Total time: 155.404 s File: /pfs/work/g2pbloch/jintrac/python/jintrac_imas_driver.py Function: jintrac_imas_driver at line 735 Line # Hits Time Per Hit % Time Line Contents ============================================================== 735 @profile 736 def jintrac_imas_driver(params, mpi='no'): 737 738 """ 739 JINTRAC-IMAS generic workflow driver. 740 :param dict params: Data loaded and converted by PyYAML from the jintrac_imas_config.yaml file. 741 """ 742 743 global mpi_root 744 global verbose 745 746 1 2.8 2.8 0.0 mpi_root = True 747 1 0.6 0.6 0.0 verbose = True # 'master' switch 748 749 1 0.5 0.5 0.0 if debug: print("JINTRAC_IMAS_DRIVER: Python Driver started") 750 751 # Workflow configuration parameters 752 753 1 0.8 0.8 0.0 user_in = params["Input IDS user"] 754 1 0.6 0.6 0.0 machine_in = params["Input IDS machine"] 755 1 0.5 0.5 0.0 shot_in = params["Input IDS shot"] 756 1 0.3 0.3 0.0 run_in = params["Input IDS run"] 757 1 0.5 0.5 0.0 user_out = params["Output IDS user"] 758 1 0.4 0.4 0.0 machine_out = params["Output IDS machine"] 759 1 0.6 0.6 0.0 shot_out = params["Output IDS shot"] 760 1 0.4 0.4 0.0 run_out = params["Output IDS run"] 761 1 13.1 13.1 0.0 user_tmp = os.environ['HOME']+'/public/tempdb' 762 763 1 0.5 0.5 0.0 tstart = params["Start time"] 764 1 0.4 0.4 0.0 tend = params["End time"] 765 1 0.5 0.5 0.0 noprocessors = params["Number of processors for parallelised actors"] 766 1 0.5 0.5 0.0 lreplace = params["Replace existing IDS"] 767 1 0.4 0.4 0.0 components = params["Active components"] 768 769 1 0.4 0.4 0.0 if debug: print("JINTRAC_IMAS_DRIVER: Workflow configuration has been read") 770 771 # To wrap into jintrac_mpi_init 772 1 0.4 0.4 0.0 if mpi == 'yes': 773 1 0.3 0.3 0.0 if debug: print("JINTRAC_IMAS_DRIVER: MPI starting...") 774 1 174562.8 174562.8 0.1 from mpi4py import MPI # This import performs an implicit MPI_INIT 775 1 0.8 0.8 0.0 if debug: print("JINTRAC_IMAS_DRIVER: MPI started okay") 776 1 2.4 2.4 0.0 mpicfg.init = True 777 1 2.1 2.1 0.0 mpicfg.comm = MPI.COMM_WORLD 778 1 7.6 7.6 0.0 mpicfg.size = mpicfg.comm.Get_size() 779 1 3.9 3.9 0.0 mpicfg.rank = mpicfg.comm.Get_rank() 780 1 6.3 6.3 0.0 mpicfg.myrank = "(MPI process "+str(mpicfg.rank)+")" 781 1 1.2 1.2 0.0 mpi_root = (mpicfg.rank == 0) 782 1 0.9 0.9 0.0 verbose = verbose and mpi_root 783 1 1.2 1.2 0.0 if mpicfg.size == 1: 784 1 21.5 21.5 0.0 if verbose: print("JINTRAC_IMAS_DRIVER: Parallel MPI execution (1 process)") 785 else: 786 if verbose: print("JINTRAC_IMAS_DRIVER: Parallel MPI execution ({0} processes)".format(mpicfg.size)) 787 else: 788 if verbose: print("JINTRAC_IMAS_DRIVER: Serial execution (no MPI)") 789 noprocessors = 1 790 791 1 0.9 0.9 0.0 if verbose: 792 1 3.6 3.6 0.0 print("") 793 1 2.6 2.6 0.0 print("JINTRAC_IMAS_DRIVER: Workflow configuration parameters") 794 1 12.2 12.2 0.0 print("JINTRAC_IMAS_DRIVER: tstart =", tstart) 795 1 5.5 5.5 0.0 print("JINTRAC_IMAS_DRIVER: tend =", tend) 796 1 7.7 7.7 0.0 print("JINTRAC_IMAS_DRIVER: shot,run(in) =", shot_in, run_in) 797 1 5.2 5.2 0.0 print("JINTRAC_IMAS_DRIVER: machine(in) =", machine_in) 798 1 5.8 5.8 0.0 print("JINTRAC_IMAS_DRIVER: user(in) =", user_in) 799 1 8.8 8.8 0.0 print("JINTRAC_IMAS_DRIVER: shot,run(out) =", shot_out, run_out) 800 1 6.4 6.4 0.0 print("JINTRAC_IMAS_DRIVER: machine(out) =", machine_out) 801 1 5.9 5.9 0.0 print("JINTRAC_IMAS_DRIVER: user(out) =", user_out) 802 1 5.6 5.6 0.0 print("JINTRAC_IMAS_DRIVER: no. processors =", noprocessors) 803 1 5.6 5.6 0.0 print("JINTRAC_IMAS_DRIVER: replace IDS =", lreplace) 804 805 1 10.9 10.9 0.0 print("\nJINTRAC_IMAS_DRIVER: Active Components:", components) 806 807 1 0.8 0.8 0.0 comment_file = 'ids_comment' 808 809 1 49.6 49.6 0.0 imas_control = WorkflowControl() 810 1 4.3 4.3 0.0 num_components = imas_control.get_num_components() 811 812 # Build list of components to be used 813 1 0.8 0.8 0.0 component_list = [] # component_list is identical to components but with upper case enforcement 814 3 1.5 0.5 0.0 for item in components: 815 3 4.1 1.4 0.0 component_list.append(item.upper()) 816 817 # Reference Python actors as global functions 818 1 0.8 0.8 0.0 list_of_jintrac_actors = ['edge2d', 'jetto', 'coconut'] 819 1 6.4 6.4 0.0 for name in [name for name in list_of_jintrac_actors if name.upper() in component_list]: 820 1 0.6 0.6 0.0 if debug: print("JINTRAC_IMAS_DRIVER: Trying to import "+name+" actor...") 821 1 0.4 0.4 0.0 try: 822 1 81445.3 81445.3 0.1 ierr = import_actor(name) 823 1 1.9 1.9 0.0 if ierr != 0: 824 error_exit("JINTRAC_IMAS_DRIVER: Failed to import JINTRAC Python actor "+name.upper()) 825 except: 826 error_exit("JINTRAC_IMAS_DRIVER: Reference to JINTRAC Python actor "+name.upper()+" not found!") 827 1 0.8 0.8 0.0 if debug: print("JINTRAC_IMAS_DRIVER: Successful import of "+name+" actor") 828 829 1 1.1 1.1 0.0 if 'HCD' in component_list: 830 try: 831 globals()['hcd_jintrac_interface'] = getattr(import_module('hcd_jintrac_interface'), 'hcd_jintrac_interface') 832 globals()['hcd_jintrac_interface_init'] = getattr(import_module('hcd_jintrac_interface'), 'hcd_jintrac_interface_init') 833 except: 834 error_exit("JINTRAC_IMAS_DRIVER: Reference to HCD JINTRAC plugin interface routines not found!") 835 836 # Make list of input and output IDS objects 837 # from combined lists of required IDS structures for each workflow component 838 1 0.5 0.5 0.0 ids_list = [] 839 3 1.8 0.6 0.0 for elem in component_list: 840 3 11.4 3.8 0.0 ids_list.extend(imas_control.get_ids_list_required(elem)) 841 1 6.6 6.6 0.0 ids_list = list(set(ids_list)) # Remove duplicates 842 843 # Determine IMAS backend -> wrap into a function 844 1 16.1 16.1 0.0 backendtype = os.environ['JINTRAC_IMAS_BACKEND'] 845 1 1.2 1.2 0.0 if backendtype == None: 846 if mpi_root: print("JINTRAC_IMAS_DRIVER: No IMAS IDS backend ($JINTRAC_IMAS_BACKEND) selected, using MDSPLUS.") 847 backendtype = 'MDSPLUS' 848 1 0.6 0.6 0.0 if backendtype == 'MDSPLUS': 849 # previous IDS data access scheme in use with MDSPLUS backend selection 850 # for backwards compatibility while IMAS versions < 3.35 are still in use on some clusters 851 backend = imas.imasdef.MDSPLUS_BACKEND 852 1 0.6 0.6 0.0 elif backendtype == 'HDF5': 853 1 2.1 2.1 0.0 backend = imas.imasdef.HDF5_BACKEND 854 else: 855 error_exit("JINTRAC_IMAS_DRIVER: Selected IMAS IDS backend ($JINTRAC_IMAS_BACKEND=" 856 +backendtype+") not supported!") 857 858 # Open/create output local datafile -> Should be handled by the AL 859 1 6.5 6.5 0.0 version = os.environ['IMAS_VERSION'][:1] 860 1 0.7 0.7 0.0 if mpi_root: 861 1 18.4 18.4 0.0 if verbose: print("JINTRAC_IMAS_DRIVER: Creating local database "+user_out+'/'+machine_out+'/'+version) 862 1 1.0 1.0 0.0 if user_out[0] != '/': 863 user_out_root = os.environ['HOME']+'/public/imasdb' 864 else: 865 1 0.5 0.5 0.0 user_out_root = user_out 866 1 23.9 23.9 0.0 if not os.path.exists(user_out_root+'/'+machine_out+'/'+version): 867 os.makedirs(user_out_root+'/'+machine_out+'/'+version) 868 1 0.6 0.6 0.0 if backendtype == 'MDSPLUS': 869 if user_out[0] != '/': 870 os.popen("imasdb "+machine_out).read() 871 else: 872 os.popen("imasdb "+user_out_root+'/'+machine_out+'/'+version).read() 873 1 0.5 0.5 0.0 elif backendtype == 'HDF5': 874 1 3.4 3.4 0.0 hdf5_outdir = user_out_root+'/'+machine_out+'/'+version+'/'+str(shot_out) 875 1 12.4 12.4 0.0 if not os.path.exists(hdf5_outdir): 876 os.mkdir(hdf5_outdir) 877 878 1 1.8 1.8 0.0 if mpicfg.init and mpicfg.size > 1: mpicfg.comm.barrier() 879 880 # Setup output IDS -> move into IDSOUT_init wrapper 881 1 0.5 0.5 0.0 idx_out = -9999 882 1 1.0 1.0 0.0 if 'IDSOUT' in component_list: 883 1 7.3 7.3 0.0 if verbose: print("JINTRAC_IMAS_DRIVER: Initialising output IDS...") 884 1 23.4 23.4 0.0 DBentry.idsout = imas.DBEntry(backend, machine_out, shot_out, run_out, user_name=user_out) 885 886 1 0.5 0.5 0.0 create_ids = lreplace 887 1 0.9 0.9 0.0 if create_ids == False: 888 if verbose: print("JINTRAC_IMAS_DRIVER: ...Opening output IDS environment...", user_out, machine_out, version) 889 status, idx_out = DBentry.idsout.open() # idx_out points to output IDS file index 890 if status != 0: 891 if verbose: print("JINTRAC_IMAS_DRIVER: IDS output file does not exist; creating new file instead...") 892 create_ids = True 893 894 1 0.5 0.5 0.0 if create_ids: 895 1 0.4 0.4 0.0 if mpi_root: 896 1 19.2 19.2 0.0 if verbose: print("JINTRAC_IMAS_DRIVER: ...Creating output IDS environment...", user_out, machine_out, version) 897 1 7264.6 7264.6 0.0 status, idx_out = DBentry.idsout.create() # idx_out points to output IDS file index 898 1 2.0 2.0 0.0 if status != 0: 899 error_exit("IDS output file creation has failed... Aborting with status = "+str(status)) 900 901 1 2.4 2.4 0.0 if mpicfg.init and mpicfg.size > 1: 902 idx_out = mpicfg.comm.bcast(idx_out, root=0) 903 904 905 # Open input datafile; shot_in=0 indicates no IDS inputs -> move into IDSIN_init wrapper 906 1 16647.4 16647.4 0.0 ids_in = imas.ids(0, 0, 0, 0) 907 1 0.3 0.3 0.0 idx_in = -9999 908 1 1.0 1.0 0.0 if shot_in == 0 or not mpi_root: 909 if 'IDSOUT' in component_list: 910 idx_in = idx_out 911 if DBentry.API == 'NEW': 912 DBentry.idsin = DBentry.idsout 913 else: 914 # Set up dummy input IDS file (required for input slice initialisation) 915 if DBentry.API == 'NEW': 916 DBentry.idsin = imas.DBEntry(backend, '', 0, 0) 917 else: 918 1 13.3 13.3 0.0 if verbose: print("JINTRAC_IMAS_DRIVER: Opening input IDS...") 919 1 1.1 1.1 0.0 if DBentry.API == 'OLD': 920 ids_in = imas.ids(shot_in, run_in) 921 ids_in.open_env(user_in, machine_in, version) 922 idx_in = ids_in.core_profiles.getPulseCtx() # idx_in points to input IDS file index 923 else: 924 1 18.1 18.1 0.0 DBentry.idsin = imas.DBEntry(backend, machine_in, shot_in, run_in, user_name=user_in) 925 1 669.9 669.9 0.0 status, idx_in = DBentry.idsin.open() # idx_in points to input IDS file index 926 1 1.0 1.0 0.0 if status != 0: 927 error_exit("Failure to open input IDS file... Aborting with status = "+str(status)) 928 929 # Initialise temporary IDS file 930 # Required by all workflows calling physics actors - see JIRA issue IMAS-2921 931 1 348864.7 348864.7 0.2 alenv = ALEnv(user_temp=user_tmp) 932 1 10.3 10.3 0.0 tmp_db = alenv.ids_tmp 933 934 # Set up IDS bundles, to make it easier to pass the IDSs between actors 935 # ids_bundle_input: IDS time slice from input database file, used i.a. for initialisation 936 # ids_bundle_work: input IDSs of the current timestep, only one timeslice 937 # ids_bundle_prev: collection of component-specific output IDSs from the previous component call 938 # (initialised by subset of ids_bundle_work), only one timeslice 939 # ids_bundle_updated: output IDSs of the current timestep, only one timeslice 940 941 # Initial IDS bundle (must contain all IDSs likely to be used) 942 # Unused IDSs are removed from this list below 943 1 9.3 9.3 0.0 ids_list_complete = imas_control.get_complete_ids_list() 944 1 1.8 1.8 0.0 ids_bundle_input = {} 945 946 # Read IDS input data -> move into a wrapper 947 1 1.2 1.2 0.0 if mpi_root: 948 # Check which subset of IDS from the complete list are present in the data entry 949 22 14.0 0.6 0.0 for ids_struct in ids_list_complete: 950 22 27.0 1.2 0.0 if DBentry.API == 'OLD': 951 ids_bundle_input[ids_struct] = eval('ids_in.'+ids_struct) 952 else: 953 22 5.1 0.2 0.0 try: 954 # Next line currently causes problems if: 955 # - no IDSIN is required (i.e. shot_in==0), AND 956 # - IDSOUT datafile does not yet exist 957 22 44253622.5 2011528.3 28.5 ids_bundle_input[ids_struct] = eval('DBentry.idsin.get("'+ids_struct+'")') 958 except: 959 # Fall-back to using old-style API call to define structure 960 ids_bundle_input[ids_struct] = eval('ids_in.'+ids_struct) 961 962 1 46906374.5 46906374.5 30.2 tmpdict = bundle_copy(ids_bundle_input) 963 22 9.2 0.4 0.0 for elem in tmpdict: 964 12 9.4 0.8 0.0 if elem not in ids_list: 965 10 76.9 7.7 0.0 del ids_bundle_input[elem] 966 else: 967 12 7.3 0.6 0.0 if shot_in != 0 and mpi_root: 968 12 9.2 0.8 0.0 if DBentry.API == 'OLD': 969 ids_bundle_input[elem].ids_properties.homogeneous_time = ids_bundle_input[elem].getField('ids_properties/homogeneous_time') 970 else: 971 12 15614.8 1301.2 0.0 ids_bundle_input[elem].ids_properties.homogeneous_time = DBentry.idsin.get_node(elem, 'ids_properties/homogeneous_time') 972 973 # Read in input IDS data, if present 974 1 0.3 0.3 0.0 if shot_in != 0 and mpi_root: 975 1 17.6 17.6 0.0 print("Reading input IDS...") 976 12 7.9 0.7 0.0 for elem in ids_bundle_input: 977 9 76.9 8.5 0.0 if is_populated(ids_bundle_input[elem],1): 978 3 57.2 19.1 0.0 if verbose: print("Getting first slice from ", elem, "...") 979 2 2.2 1.1 0.0 if elem != 'equilibrium' and elem != 'summary' and elem != 'core_sources' and elem != 'workflow' and elem != 'pulse_schedule': 980 1 0.4 0.4 0.0 if DBentry.API == 'OLD': 981 ids_bundle_input[elem].getSlice(tstart, interp_value) 982 else: 983 1 738373.0 738373.0 0.5 ids_bundle_input[elem] = DBentry.idsin.get_slice(elem, tstart, interp_value) 984 2 1.6 0.8 0.0 elif elem == 'summary' or elem == 'workflow': # getSlice procedure does not work for summary IDS in test case #130011/public/iter/1 as array heating_current_drive.nbi[0].power.values does not seem to be populated 985 ids_bundle_input[elem].ids_properties.homogeneous_time = imas.imasdef.IDS_TIME_MODE_HOMOGENEOUS # set homogeneous time flag and add dummy time as empty IDS structures cannot be passed as argument to Python actors with IMAS version >= 3.28.0 even if they are not used by the actors 986 ids_bundle_input[elem].time = np.array([-9999.0]) 987 2 1.2 0.6 0.0 elif elem == 'pulse_schedule': 988 if DBentry.API == 'OLD': 989 ids_bundle_input[elem].get() 990 else: 991 ids_bundle_input[elem] = DBentry.idsin.get(elem) 992 else: # getSlice interpolation option does not seem to work for equilibrium IDS in test case #130011/public/iter/1 (segmentation fault for unknown reasons); core_sources contains time slice for t = 1.5 s three times, once at the beginning and two times at the end of the times array; core_sources contains two sources with the same identifier 'ec'; names and indices for core_sources source identifiers are not in agreement with name-index association given in the data dictionary 993 2 3.4 1.7 0.0 if DBentry.API == 'OLD': 994 ids_bundle_input[elem].getSlice(tstart, interp_value) 995 else: 996 2 5116586.7 2558293.3 3.3 ids_bundle_input[elem] = DBentry.idsin.get_slice(elem, tstart, interp_value) 997 else: # set homogeneous time flag and add dummy time as empty IDS structures cannot be passed as argument to Python actors with IMAS version >= 3.28.0 even if they are not used by the actors 998 9 9.0 1.0 0.0 ids_bundle_input[elem].ids_properties.homogeneous_time = imas.imasdef.IDS_TIME_MODE_HOMOGENEOUS 999 9 44.3 4.9 0.0 ids_bundle_input[elem].time = np.array([-9999.0]) 1000 else: 1001 for elem in ids_bundle_input: 1002 ids_bundle_input[elem].ids_properties.homogeneous_time = imas.imasdef.IDS_TIME_MODE_HOMOGENEOUS 1003 ids_bundle_input[elem].time = np.array([-9999.0]) 1004 1005 1 3.0 3.0 0.0 if mpicfg.init and mpicfg.size > 1: 1006 if verbose: print('bcast ids_bundle_input...') 1007 ids_bundle_input = mpicfg.comm.bcast(ids_bundle_input, root=0) 1008 if verbose: print('...done') 1009 1010 # Copy slice from ids_bundle_input to ids_bundle_work and ids_bundle_updated 1011 1 3447098.9 3447098.9 2.2 ids_bundle_work = bundle_copy(ids_bundle_input) 1012 1 4400338.9 4400338.9 2.8 ids_bundle_updated = bundle_copy(ids_bundle_input) 1013 1014 # Set up initial workflow IDS, turn on required components and set initial time intervals 1015 # Trigger first component only 1016 1 13.0 13.0 0.0 ids_bundle_work['workflow'].time = np.array([tstart]) 1017 1 69.6 69.6 0.0 ids_bundle_work['workflow'].time_loop.component.resize(num_components) 1018 1 23.2 23.2 0.0 ids_bundle_work['workflow'].time_loop.workflow_cycle.resize(1) 1019 1 91.5 91.5 0.0 ids_bundle_work['workflow'].time_loop.workflow_cycle[0].component.resize(num_components) 1020 1 13.1 13.1 0.0 names = imas_control.get_array_order() 1021 8 2.6 0.3 0.0 for icomponent in range(num_components): 1022 8 8.1 1.0 0.0 ids_bundle_work['workflow'].time_loop.component[icomponent].name = names[icomponent] 1023 8 11.2 1.4 0.0 ids_bundle_work['workflow'].time_loop.workflow_cycle[0].component[icomponent].index = icomponent + 1 #index in Fortran notation 1024 8 9.2 1.1 0.0 ids_bundle_work['workflow'].time_loop.workflow_cycle[0].component[icomponent].execution_mode = 0 1025 8 9.1 1.1 0.0 ids_bundle_work['workflow'].time_loop.workflow_cycle[0].component[icomponent].time_interval = 0.0 1026 8 21.0 2.6 0.0 ids_bundle_work['workflow'].time_loop.workflow_cycle[0].component[icomponent].control_integer = np.array([0, 0, 0, 0]) 1027 8 16.8 2.1 0.0 ids_bundle_work['workflow'].time_loop.workflow_cycle[0].component[icomponent].control_float = np.array([0.0]) 1028 3 1.4 0.5 0.0 for icomponent in component_list: 1029 3 4.8 1.6 0.0 icomponent_index = imas_control.get_component_index(icomponent) 1030 3 4.4 1.5 0.0 ids_bundle_work['workflow'].time_loop.workflow_cycle[0].component[icomponent_index].time_interval = tend-tstart 1031 1 0.8 0.8 0.0 ids_bundle_work['workflow'].time_loop.time_end = tend 1032 1 1.0 1.0 0.0 first_component_index = imas_control.get_component_index(component_list[0]) 1033 1 1.3 1.3 0.0 ids_bundle_work['workflow'].time_loop.workflow_cycle[0].component[first_component_index].execution_mode = 1 1034 # Always set JETTO trigger, required for decomposed COCONUT runs: 1035 1 0.7 0.7 0.0 if 'JETTO' in component_list: 1036 1 0.9 0.9 0.0 jetto_component_index = imas_control.get_component_index('JETTO') 1037 1 1.1 1.1 0.0 ids_bundle_work['workflow'].time_loop.workflow_cycle[0].component[jetto_component_index].execution_mode = 1 1038 1 0.4 0.4 0.0 if 'IDSIN' in component_list: 1039 1 0.8 0.8 0.0 idsin_component_index = imas_control.get_component_index('IDSIN') 1040 1 2.8 2.8 0.0 ids_bundle_work['workflow'].time_loop.workflow_cycle[0].component[idsin_component_index].control_integer[2] = idx_in 1041 1 0.4 0.4 0.0 if 'IDSOUT' in component_list: 1042 1 1.0 1.0 0.0 idsout_component_index = imas_control.get_component_index('IDSOUT') 1043 1 1.6 1.6 0.0 ids_bundle_work['workflow'].time_loop.workflow_cycle[0].component[idsout_component_index].control_integer[2] = idx_out 1044 1 0.6 0.6 0.0 if create_ids == False: 1045 # Do not recreate IDS datafile if it exists already in case of restart from IMAS case; 1046 # instead, append to the existing IDS datafile, assuming that put() procedure has already been run 1047 # for each IDS structure in the preceding run. This assumption may need to be revised later on! 1048 for elem in ids_list: 1049 elemidx = imas_control.get_idsname_index(elem) 1050 ids_bundle_work['workflow'].time_loop.workflow_cycle[0].component[idsout_component_index].control_integer[3] += 2**(elemidx) 1051 1052 # Zero HCD sources as they may be supposed to be provided from external actor that has not yet been called 1053 # (this part can be removed pending adaptations in JINTRAC for non-consideration of external source input 1054 # at (non-restart) initialisation step if HCD workflow is active and sources are not supposed to come from input IDS files): 1055 # TEMPORARILY(?) COMMENTED-OUT, BECAUSE IF THIS IS EXECUTED WITH AN EDGE2D-ONLY RUN WE GET A 1056 # KeyError('core_sources') EXCEPTION FOR REASONS NOT CLEAR TO ME (PJK) - IF ANYONE CAN EXPLAIN, PLEASE... 1057 #for isource in range(len(ids_bundle_work['core_sources'].source)): 1058 # ids_bundle_work['core_sources'].source[isource].profiles_1d[0].electrons.energy[:] = 0.0 1059 # ids_bundle_work['core_sources'].source[isource].profiles_1d[0].total_ion_energy[:] = 0.0 1060 # ids_bundle_work['core_sources'].source[isource].profiles_1d[0].j_parallel[:] = 0.0 1061 # for iion in range(len(ids_bundle_work['core_sources'].source[isource].profiles_1d[0].ion)): 1062 # ids_bundle_work['core_sources'].source[isource].profiles_1d[0].ion[iion].particles[:] = 0.0 1063 # ids_bundle_work['core_sources'].source[isource].profiles_1d[0].momentum_tor[:] = 0.0 1064 1065 1 0.3 0.3 0.0 ids_bundle_prev = {} 1066 3 2.0 0.7 0.0 for item in component_list: 1067 3 6886544.4 2295514.8 4.4 ids_bundle_prev[item] = bundle_copy(ids_bundle_work,imas_control.get_ids_sublist_updates(item)) 1068 1069 1 1.6 1.6 0.0 if 'IDSOUT' in component_list: 1070 1 24.3 24.3 0.0 if verbose: print("JINTRAC_IMAS_DRIVER: Writing dataset_description") 1071 1 7.1 7.1 0.0 ids_bundle_updated['dataset_description'] \ 1072 1 889.9 889.9 0.0 = dd.init(ids_bundle_work['dataset_description'], 0, 1073 1 0.3 0.3 0.0 comment_file) 1074 1 20.3 20.3 0.0 ids_bundle_updated['dataset_description'].setPulseCtx(idx_out) 1075 1 0.6 0.6 0.0 if mpi_root: 1076 1 13900.2 13900.2 0.0 DBentry.idsout.put(ids_bundle_updated['dataset_description']) 1077 #code.interact(local=locals()) 1078 1079 # Time loop 1080 1081 1 0.7 0.7 0.0 time = tstart 1082 1 2.2 2.2 0.0 while time < tend: 1083 1 36.1 36.1 0.0 if verbose: print("JINTRAC_IMAS_DRIVER: time =", time, '\n') 1084 8 6.1 0.8 0.0 for icomponent in range(num_components): 1085 8 10.3 1.3 0.0 ids_bundle_work['workflow'].time[0] = time 1086 8 24.7 3.1 0.0 ids_bundle_work['workflow'].time_loop.workflow_cycle[0].component[icomponent].control_integer[0] = 0 #re-set action flag 1087 8 29.4 3.7 0.0 ids_bundle_work['workflow'].time_loop.workflow_cycle[0].component[icomponent].control_float = np.array([0.0]) 1088 1 1782.6 1782.6 0.0 ids_bundle_updated['workflow'].copyValues(ids_bundle_work['workflow']) #workflow IDS from ids_bundle_updated foreseen to be used by all actors 1089 1090 # Advance each component 1091 3 2.5 0.8 0.0 for item in component_list: 1092 3 70.6 23.5 0.0 if verbose: print("JINTRAC_IMAS_DRIVER: check trigger for item ",item,"...") 1093 3 16.6 5.5 0.0 item_index = imas_control.get_component_index(item) 1094 3 13.7 4.6 0.0 if ids_bundle_updated['workflow'].time_loop.workflow_cycle[0].component[item_index].execution_mode == 1: 1095 3 20.3 6.8 0.0 if verbose: print("JINTRAC_IMAS_DRIVER: wrapper called for item ",item,"...") 1096 3 0.9 0.3 0.0 args = ("(noprocessors, imas_control, ids_bundle_updated, ids_bundle_work, ids_bundle_prev[item])") 1097 1098 # Call component via its wrapper 1099 3 29669430.5 9889810.2 19.1 ids_bundle_updated_tmp = eval(imas_control.get_wrapper(item) + args) 1100 1101 # Workflow-component specific consideration of IDS updates, update ids_bundle_prev: 1102 14 55.7 4.0 0.0 for ids_struct in imas_control.get_ids_sublist_updates(item): 1103 14 10.7 0.8 0.0 if ids_struct in ids_bundle_updated_tmp: 1104 11 206.0 18.7 0.0 if is_populated(ids_bundle_updated_tmp[ids_struct],2): 1105 11 4863627.8 442148.0 3.1 ids_bundle_updated[ids_struct].copyValues(ids_bundle_updated_tmp[ids_struct]) 1106 11 3643527.1 331229.7 2.3 ids_bundle_prev[item][ids_struct].copyValues(ids_bundle_updated_tmp[ids_struct]) 1107 3 1.7 0.6 0.0 elif ids_struct == 'transport_solver_numerics': 1108 if is_populated(ids_bundle_updated_tmp[ids_struct],1): 1109 ids_bundle_updated[ids_struct].copyValues(ids_bundle_updated_tmp[ids_struct]) 1110 ids_bundle_prev[item][ids_struct].copyValues(ids_bundle_updated_tmp[ids_struct]) 1111 1112 # Copy newly updated IDS into input (work) IDS, 1113 # ready for next time step 1114 1 4798639.4 4798639.4 3.1 ids_bundle_work = bundle_copy(ids_bundle_updated) 1115 1116 # Update and increment time 1117 1 4.8 4.8 0.0 time = ids_bundle_work['workflow'].time[0] 1118 1 0.3 0.3 0.0 dtmax = 0.0 1119 3 1.9 0.6 0.0 for icomponent in component_list: 1120 3 7.5 2.5 0.0 icomponent_index = imas_control.get_component_index(icomponent) 1121 3 18.2 6.1 0.0 dtmax = max(dtmax, ids_bundle_work['workflow'].time_loop.workflow_cycle[0].component[icomponent_index].time_interval) 1122 1 4.4 4.4 0.0 time += dtmax 1123 1 37.7 37.7 0.0 if verbose: print("JINTRAC_IMAS_DRIVER: Calculated time interval = ", dtmax) 1124 1 1.2 1.2 0.0 dtmaxnew = tend-time 1125 3 1.0 0.3 0.0 for icomponent in component_list: 1126 3 2.9 1.0 0.0 icomponent_index = imas_control.get_component_index(icomponent) 1127 3 4.7 1.6 0.0 ids_bundle_work['workflow'].time_loop.workflow_cycle[0].component[icomponent_index].time_interval = dtmaxnew 1128 1 34.1 34.1 0.0 if verbose: print("JINTRAC_IMAS_DRIVER: Next target interval = ", dtmaxnew) 1129 1130 # end of time loop 1131 1132 1 7.5 7.5 0.0 if verbose: print("JINTRAC_IMAS_DRIVER: Finish time =", time) 1133 1134 1 2369.4 2369.4 0.0 alenv.close() 1135 1136 1 2.0 2.0 0.0 ids_in.close() 1137 1 2.9 2.9 0.0 if DBentry.API == 'NEW': 1138 1 8714.5 8714.5 0.0 DBentry.idsin.close() 1139 1140 1 1.8 1.8 0.0 if 'IDSOUT' in component_list: 1141 1 5201.2 5201.2 0.0 DBentry.idsout.close() 1142 1143 1 0.3 0.3 0.0 return 0