Timer unit: 1e-06 s Total time: 12.4592 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.7 9.7 0.0 if verbose: print("JINTRAC_IMAS_DRIVER: jetto wrapper called...", mpicfg.myrank) 309 310 1 0.6 0.6 0.0 in_prof = in_ids_bundle_work['core_profiles'] 311 1 0.6 0.6 0.0 in_src = in_ids_bundle_work['core_sources'] 312 1 0.7 0.7 0.0 in_trans = in_ids_bundle_work['core_transport'] 313 1 0.4 0.4 0.0 in_equil = in_ids_bundle_work['equilibrium'] 314 1 0.6 0.6 0.0 in_nbi = in_ids_bundle_work['nbi'] 315 1 0.4 0.4 0.0 in_pel = in_ids_bundle_work['pellets'] 316 1 0.6 0.6 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.3 0.3 0.0 in_summ = in_ids_bundle_work['summary'] 319 1 0.4 0.4 0.0 in_num = in_ids_bundle_updated['transport_solver_numerics'] 320 1 0.2 0.2 0.0 in_work = in_ids_bundle_updated['workflow'] 321 322 1 5.6 5.6 0.0 if verbose: print("JINTRAC_IMAS_DRIVER: Calling jetto_actor...", mpicfg.myrank) 323 1 1.3 1.3 0.0 out_prof, out_src, out_trans, out_equil, out_summ, out_num, out_work \ 324 1 8958798.8 8958798.8 71.9 = jetto(in_prof, in_src, in_trans, in_equil, in_nbi, 325 1 0.2 0.2 0.0 in_pel, in_pulse, in_contr, in_summ, in_num, in_work) 326 1 29.5 29.5 0.0 if verbose: print("JINTRAC_IMAS_DRIVER: ...jetto_actor done!", mpicfg.myrank) 327 328 1 1.9 1.9 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 12.4 1.5 0.0 for ii in range(len(out_work.time_loop.component)): 338 7 9.1 1.3 0.0 if out_work.time_loop.component[ii].name == 'jetto': 339 1 0.3 0.3 0.0 jetto_index = ii 340 1 7.7 7.7 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.8 1.8 0.0 out_work.ids_properties.homogeneous_time = imas.imasdef.IDS_TIME_MODE_HOMOGENEOUS 351 1 2.3 2.3 0.0 out_work.time[0] = time 352 353 1 3.3 3.3 0.0 timereached = out_work.time[0] + out_work.time_loop.workflow_cycle[0].component[jetto_index].time_interval 354 1 1.6 1.6 0.0 if out_prof.ids_properties.homogeneous_time == imas.imasdef.IDS_TIME_MODE_HOMOGENEOUS: 355 1 0.9 0.9 0.0 out_prof.time[0] = timereached 356 1 1.6 1.6 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 1.5 1.5 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.4 1.4 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.0 1.0 0.0 if out_summ.ids_properties.homogeneous_time == imas.imasdef.IDS_TIME_MODE_HOMOGENEOUS: 363 1 0.6 0.6 0.0 out_summ.time[0] = timereached 364 1 0.7 0.7 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 3459717.4 3459717.4 27.8 out_ids_bundle = bundle_copy(in_ids_bundle_work) 368 1 357.0 357.0 0.0 out_ids_bundle['core_profiles'] = out_prof 369 1 742.6 742.6 0.0 out_ids_bundle['core_sources'] = out_src 370 1 7.6 7.6 0.0 out_ids_bundle['core_transport'] = out_trans 371 1 38898.2 38898.2 0.3 out_ids_bundle['equilibrium'] = out_equil 372 1 533.7 533.7 0.0 out_ids_bundle['summary'] = out_summ 373 1 18.8 18.8 0.0 out_ids_bundle['transport_solver_numerics'] = out_num 374 1 25.6 25.6 0.0 out_ids_bundle['workflow'] = out_work 375 376 1 0.4 0.4 0.0 return out_ids_bundle Total time: 155.743 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.4 0.4 0.0 verbose = True # 'master' switch 748 749 1 0.4 0.4 0.0 if debug: print("JINTRAC_IMAS_DRIVER: Python Driver started") 750 751 # Workflow configuration parameters 752 753 1 0.6 0.6 0.0 user_in = params["Input IDS user"] 754 1 0.4 0.4 0.0 machine_in = params["Input IDS machine"] 755 1 0.9 0.9 0.0 shot_in = params["Input IDS shot"] 756 1 0.7 0.7 0.0 run_in = params["Input IDS run"] 757 1 0.4 0.4 0.0 user_out = params["Output IDS user"] 758 1 0.3 0.3 0.0 machine_out = params["Output IDS machine"] 759 1 0.3 0.3 0.0 shot_out = params["Output IDS shot"] 760 1 0.5 0.5 0.0 run_out = params["Output IDS run"] 761 1 15.1 15.1 0.0 user_tmp = os.environ['HOME']+'/public/tempdb' 762 763 1 0.6 0.6 0.0 tstart = params["Start time"] 764 1 0.5 0.5 0.0 tend = params["End time"] 765 1 0.8 0.8 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.5 0.5 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.5 0.5 0.0 if mpi == 'yes': 773 1 0.2 0.2 0.0 if debug: print("JINTRAC_IMAS_DRIVER: MPI starting...") 774 1 173541.6 173541.6 0.1 from mpi4py import MPI # This import performs an implicit MPI_INIT 775 1 1.0 1.0 0.0 if debug: print("JINTRAC_IMAS_DRIVER: MPI started okay") 776 1 2.5 2.5 0.0 mpicfg.init = True 777 1 2.8 2.8 0.0 mpicfg.comm = MPI.COMM_WORLD 778 1 7.4 7.4 0.0 mpicfg.size = mpicfg.comm.Get_size() 779 1 4.1 4.1 0.0 mpicfg.rank = mpicfg.comm.Get_rank() 780 1 5.7 5.7 0.0 mpicfg.myrank = "(MPI process "+str(mpicfg.rank)+")" 781 1 1.7 1.7 0.0 mpi_root = (mpicfg.rank == 0) 782 1 1.0 1.0 0.0 verbose = verbose and mpi_root 783 1 0.7 0.7 0.0 if mpicfg.size == 1: 784 1 22.1 22.1 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 1.0 1.0 0.0 if verbose: 792 1 6.7 6.7 0.0 print("") 793 1 2.7 2.7 0.0 print("JINTRAC_IMAS_DRIVER: Workflow configuration parameters") 794 1 13.7 13.7 0.0 print("JINTRAC_IMAS_DRIVER: tstart =", tstart) 795 1 5.8 5.8 0.0 print("JINTRAC_IMAS_DRIVER: tend =", tend) 796 1 7.0 7.0 0.0 print("JINTRAC_IMAS_DRIVER: shot,run(in) =", shot_in, run_in) 797 1 5.7 5.7 0.0 print("JINTRAC_IMAS_DRIVER: machine(in) =", machine_in) 798 1 4.8 4.8 0.0 print("JINTRAC_IMAS_DRIVER: user(in) =", user_in) 799 1 7.9 7.9 0.0 print("JINTRAC_IMAS_DRIVER: shot,run(out) =", shot_out, run_out) 800 1 4.2 4.2 0.0 print("JINTRAC_IMAS_DRIVER: machine(out) =", machine_out) 801 1 6.0 6.0 0.0 print("JINTRAC_IMAS_DRIVER: user(out) =", user_out) 802 1 4.5 4.5 0.0 print("JINTRAC_IMAS_DRIVER: no. processors =", noprocessors) 803 1 7.6 7.6 0.0 print("JINTRAC_IMAS_DRIVER: replace IDS =", lreplace) 804 805 1 11.2 11.2 0.0 print("\nJINTRAC_IMAS_DRIVER: Active Components:", components) 806 807 1 0.4 0.4 0.0 comment_file = 'ids_comment' 808 809 1 39.9 39.9 0.0 imas_control = WorkflowControl() 810 1 4.1 4.1 0.0 num_components = imas_control.get_num_components() 811 812 # Build list of components to be used 813 1 0.7 0.7 0.0 component_list = [] # component_list is identical to components but with upper case enforcement 814 3 1.4 0.5 0.0 for item in components: 815 3 4.6 1.5 0.0 component_list.append(item.upper()) 816 817 # Reference Python actors as global functions 818 1 1.0 1.0 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.7 0.7 0.0 if debug: print("JINTRAC_IMAS_DRIVER: Trying to import "+name+" actor...") 821 1 0.7 0.7 0.0 try: 822 1 66338.8 66338.8 0.0 ierr = import_actor(name) 823 1 0.7 0.7 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.6 0.6 0.0 if debug: print("JINTRAC_IMAS_DRIVER: Successful import of "+name+" actor") 828 829 1 0.9 0.9 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.2 0.2 0.0 ids_list = [] 839 3 0.9 0.3 0.0 for elem in component_list: 840 3 6.3 2.1 0.0 ids_list.extend(imas_control.get_ids_list_required(elem)) 841 1 4.1 4.1 0.0 ids_list = list(set(ids_list)) # Remove duplicates 842 843 # Determine IMAS backend -> wrap into a function 844 1 12.8 12.8 0.0 backendtype = os.environ['JINTRAC_IMAS_BACKEND'] 845 1 0.6 0.6 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.7 0.7 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 1 1.6 1.6 0.0 backend = imas.imasdef.MDSPLUS_BACKEND 852 elif backendtype == 'HDF5': 853 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 3.5 3.5 0.0 version = os.environ['IMAS_VERSION'][:1] 860 1 0.8 0.8 0.0 if mpi_root: 861 1 12.7 12.7 0.0 if verbose: print("JINTRAC_IMAS_DRIVER: Creating local database "+user_out+'/'+machine_out+'/'+version) 862 1 0.5 0.5 0.0 if user_out[0] != '/': 863 user_out_root = os.environ['HOME']+'/public/imasdb' 864 else: 865 1 0.2 0.2 0.0 user_out_root = user_out 866 1 13.1 13.1 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.3 0.3 0.0 if backendtype == 'MDSPLUS': 869 1 0.4 0.4 0.0 if user_out[0] != '/': 870 os.popen("imasdb "+machine_out).read() 871 else: 872 1 90376.8 90376.8 0.1 os.popen("imasdb "+user_out_root+'/'+machine_out+'/'+version).read() 873 elif backendtype == 'HDF5': 874 hdf5_outdir = user_out_root+'/'+machine_out+'/'+version+'/'+str(shot_out) 875 if not os.path.exists(hdf5_outdir): 876 os.mkdir(hdf5_outdir) 877 878 1 2.9 2.9 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.9 0.9 0.0 idx_out = -9999 882 1 1.6 1.6 0.0 if 'IDSOUT' in component_list: 883 1 14.8 14.8 0.0 if verbose: print("JINTRAC_IMAS_DRIVER: Initialising output IDS...") 884 1 37.6 37.6 0.0 DBentry.idsout = imas.DBEntry(backend, machine_out, shot_out, run_out, user_name=user_out) 885 886 1 0.8 0.8 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.6 0.6 0.0 if create_ids: 895 1 0.9 0.9 0.0 if mpi_root: 896 1 19.0 19.0 0.0 if verbose: print("JINTRAC_IMAS_DRIVER: ...Creating output IDS environment...", user_out, machine_out, version) 897 1 1638364.1 1638364.1 1.1 status, idx_out = DBentry.idsout.create() # idx_out points to output IDS file index 898 1 9.9 9.9 0.0 if status != 0: 899 error_exit("IDS output file creation has failed... Aborting with status = "+str(status)) 900 901 1 21.6 21.6 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 27199.6 27199.6 0.0 ids_in = imas.ids(0, 0, 0, 0) 907 1 0.5 0.5 0.0 idx_in = -9999 908 1 1.8 1.8 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 37.8 37.8 0.0 if verbose: print("JINTRAC_IMAS_DRIVER: Opening input IDS...") 919 1 13.5 13.5 0.0 print(backend, machine_in, shot_in, run_in, user_in) 920 1 1.6 1.6 0.0 if DBentry.API == 'OLD': 921 ids_in = imas.ids(shot_in, run_in) 922 ids_in.open_env(user_in, machine_in, version) 923 idx_in = ids_in.core_profiles.getPulseCtx() # idx_in points to input IDS file index 924 else: 925 1 50.7 50.7 0.0 DBentry.idsin = imas.DBEntry(backend, machine_in, shot_in, run_in, user_name=user_in) 926 1 869.7 869.7 0.0 status, idx_in = DBentry.idsin.open() # idx_in points to input IDS file index 927 1 1.1 1.1 0.0 if status != 0: 928 error_exit("Failure to open input IDS file... Aborting with status = "+str(status)) 929 930 # Initialise temporary IDS file 931 # Required by all workflows calling physics actors - see JIRA issue IMAS-2921 932 1 433495.2 433495.2 0.3 alenv = ALEnv(user_temp=user_tmp) 933 1 12.8 12.8 0.0 tmp_db = alenv.ids_tmp 934 935 # Set up IDS bundles, to make it easier to pass the IDSs between actors 936 # ids_bundle_input: IDS time slice from input database file, used i.a. for initialisation 937 # ids_bundle_work: input IDSs of the current timestep, only one timeslice 938 # ids_bundle_prev: collection of component-specific output IDSs from the previous component call 939 # (initialised by subset of ids_bundle_work), only one timeslice 940 # ids_bundle_updated: output IDSs of the current timestep, only one timeslice 941 942 # Initial IDS bundle (must contain all IDSs likely to be used) 943 # Unused IDSs are removed from this list below 944 1 10.1 10.1 0.0 ids_list_complete = imas_control.get_complete_ids_list() 945 1 2.2 2.2 0.0 ids_bundle_input = {} 946 947 # Read IDS input data -> move into a wrapper 948 1 1.7 1.7 0.0 if mpi_root: 949 # Check which subset of IDS from the complete list are present in the data entry 950 22 16.9 0.8 0.0 for ids_struct in ids_list_complete: 951 22 37.6 1.7 0.0 if DBentry.API == 'OLD': 952 ids_bundle_input[ids_struct] = eval('ids_in.'+ids_struct) 953 else: 954 22 6.7 0.3 0.0 try: 955 # Next line currently causes problems if: 956 # - no IDSIN is required (i.e. shot_in==0), AND 957 # - IDSOUT datafile does not yet exist 958 22 50742304.5 2306468.4 32.6 ids_bundle_input[ids_struct] = eval('DBentry.idsin.get("'+ids_struct+'")') 959 except: 960 # Fall-back to using old-style API call to define structure 961 ids_bundle_input[ids_struct] = eval('ids_in.'+ids_struct) 962 963 1 45878227.2 45878227.2 29.5 tmpdict = bundle_copy(ids_bundle_input) 964 22 8.9 0.4 0.0 for elem in tmpdict: 965 12 8.4 0.7 0.0 if elem not in ids_list: 966 10 76.1 7.6 0.0 del ids_bundle_input[elem] 967 else: 968 12 6.3 0.5 0.0 if shot_in != 0 and mpi_root: 969 12 8.6 0.7 0.0 if DBentry.API == 'OLD': 970 ids_bundle_input[elem].ids_properties.homogeneous_time = ids_bundle_input[elem].getField('ids_properties/homogeneous_time') 971 else: 972 12 9166.1 763.8 0.0 ids_bundle_input[elem].ids_properties.homogeneous_time = DBentry.idsin.get_node(elem, 'ids_properties/homogeneous_time') 973 974 # Read in input IDS data, if present 975 1 0.4 0.4 0.0 if shot_in != 0 and mpi_root: 976 1 18.3 18.3 0.0 print("Reading input IDS...") 977 12 8.4 0.7 0.0 for elem in ids_bundle_input: 978 9 60.5 6.7 0.0 if is_populated(ids_bundle_input[elem],1): 979 3 68.3 22.8 0.0 if verbose: print("Getting first slice from ", elem, "...") 980 2 2.8 1.4 0.0 if elem != 'equilibrium' and elem != 'summary' and elem != 'core_sources' and elem != 'workflow' and elem != 'pulse_schedule': 981 1 0.5 0.5 0.0 if DBentry.API == 'OLD': 982 ids_bundle_input[elem].getSlice(tstart, interp_value) 983 else: 984 1 327381.7 327381.7 0.2 ids_bundle_input[elem] = DBentry.idsin.get_slice(elem, tstart, interp_value) 985 2 2.7 1.3 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 986 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 987 ids_bundle_input[elem].time = np.array([-9999.0]) 988 2 1.6 0.8 0.0 elif elem == 'pulse_schedule': 989 if DBentry.API == 'OLD': 990 ids_bundle_input[elem].get() 991 else: 992 ids_bundle_input[elem] = DBentry.idsin.get(elem) 993 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 994 2 4.2 2.1 0.0 if DBentry.API == 'OLD': 995 ids_bundle_input[elem].getSlice(tstart, interp_value) 996 else: 997 2 3193050.2 1596525.1 2.1 ids_bundle_input[elem] = DBentry.idsin.get_slice(elem, tstart, interp_value) 998 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 999 9 9.0 1.0 0.0 ids_bundle_input[elem].ids_properties.homogeneous_time = imas.imasdef.IDS_TIME_MODE_HOMOGENEOUS 1000 9 39.0 4.3 0.0 ids_bundle_input[elem].time = np.array([-9999.0]) 1001 else: 1002 for elem in ids_bundle_input: 1003 ids_bundle_input[elem].ids_properties.homogeneous_time = imas.imasdef.IDS_TIME_MODE_HOMOGENEOUS 1004 ids_bundle_input[elem].time = np.array([-9999.0]) 1005 1006 1 1.9 1.9 0.0 if mpicfg.init and mpicfg.size > 1: 1007 if verbose: print('bcast ids_bundle_input...') 1008 ids_bundle_input = mpicfg.comm.bcast(ids_bundle_input, root=0) 1009 if verbose: print('...done') 1010 1011 # Copy slice from ids_bundle_input to ids_bundle_work and ids_bundle_updated 1012 1 3399663.8 3399663.8 2.2 ids_bundle_work = bundle_copy(ids_bundle_input) 1013 1 4340984.3 4340984.3 2.8 ids_bundle_updated = bundle_copy(ids_bundle_input) 1014 1015 # Set up initial workflow IDS, turn on required components and set initial time intervals 1016 # Trigger first component only 1017 1 12.7 12.7 0.0 ids_bundle_work['workflow'].time = np.array([tstart]) 1018 1 60.7 60.7 0.0 ids_bundle_work['workflow'].time_loop.component.resize(num_components) 1019 1 23.3 23.3 0.0 ids_bundle_work['workflow'].time_loop.workflow_cycle.resize(1) 1020 1 94.8 94.8 0.0 ids_bundle_work['workflow'].time_loop.workflow_cycle[0].component.resize(num_components) 1021 1 11.3 11.3 0.0 names = imas_control.get_array_order() 1022 8 2.4 0.3 0.0 for icomponent in range(num_components): 1023 8 8.1 1.0 0.0 ids_bundle_work['workflow'].time_loop.component[icomponent].name = names[icomponent] 1024 8 10.4 1.3 0.0 ids_bundle_work['workflow'].time_loop.workflow_cycle[0].component[icomponent].index = icomponent + 1 #index in Fortran notation 1025 8 8.7 1.1 0.0 ids_bundle_work['workflow'].time_loop.workflow_cycle[0].component[icomponent].execution_mode = 0 1026 8 10.0 1.3 0.0 ids_bundle_work['workflow'].time_loop.workflow_cycle[0].component[icomponent].time_interval = 0.0 1027 8 20.5 2.6 0.0 ids_bundle_work['workflow'].time_loop.workflow_cycle[0].component[icomponent].control_integer = np.array([0, 0, 0, 0]) 1028 8 16.3 2.0 0.0 ids_bundle_work['workflow'].time_loop.workflow_cycle[0].component[icomponent].control_float = np.array([0.0]) 1029 3 1.3 0.4 0.0 for icomponent in component_list: 1030 3 4.2 1.4 0.0 icomponent_index = imas_control.get_component_index(icomponent) 1031 3 4.2 1.4 0.0 ids_bundle_work['workflow'].time_loop.workflow_cycle[0].component[icomponent_index].time_interval = tend-tstart 1032 1 0.8 0.8 0.0 ids_bundle_work['workflow'].time_loop.time_end = tend 1033 1 1.2 1.2 0.0 first_component_index = imas_control.get_component_index(component_list[0]) 1034 1 1.4 1.4 0.0 ids_bundle_work['workflow'].time_loop.workflow_cycle[0].component[first_component_index].execution_mode = 1 1035 # Always set JETTO trigger, required for decomposed COCONUT runs: 1036 1 0.7 0.7 0.0 if 'JETTO' in component_list: 1037 1 0.9 0.9 0.0 jetto_component_index = imas_control.get_component_index('JETTO') 1038 1 1.3 1.3 0.0 ids_bundle_work['workflow'].time_loop.workflow_cycle[0].component[jetto_component_index].execution_mode = 1 1039 1 0.6 0.6 0.0 if 'IDSIN' in component_list: 1040 1 0.8 0.8 0.0 idsin_component_index = imas_control.get_component_index('IDSIN') 1041 1 2.7 2.7 0.0 ids_bundle_work['workflow'].time_loop.workflow_cycle[0].component[idsin_component_index].control_integer[2] = idx_in 1042 1 0.3 0.3 0.0 if 'IDSOUT' in component_list: 1043 1 0.8 0.8 0.0 idsout_component_index = imas_control.get_component_index('IDSOUT') 1044 1 1.3 1.3 0.0 ids_bundle_work['workflow'].time_loop.workflow_cycle[0].component[idsout_component_index].control_integer[2] = idx_out 1045 1 0.7 0.7 0.0 if create_ids == False: 1046 # Do not recreate IDS datafile if it exists already in case of restart from IMAS case; 1047 # instead, append to the existing IDS datafile, assuming that put() procedure has already been run 1048 # for each IDS structure in the preceding run. This assumption may need to be revised later on! 1049 for elem in ids_list: 1050 elemidx = imas_control.get_idsname_index(elem) 1051 ids_bundle_work['workflow'].time_loop.workflow_cycle[0].component[idsout_component_index].control_integer[3] += 2**(elemidx) 1052 1053 # Zero HCD sources as they may be supposed to be provided from external actor that has not yet been called 1054 # (this part can be removed pending adaptations in JINTRAC for non-consideration of external source input 1055 # at (non-restart) initialisation step if HCD workflow is active and sources are not supposed to come from input IDS files): 1056 # TEMPORARILY(?) COMMENTED-OUT, BECAUSE IF THIS IS EXECUTED WITH AN EDGE2D-ONLY RUN WE GET A 1057 # KeyError('core_sources') EXCEPTION FOR REASONS NOT CLEAR TO ME (PJK) - IF ANYONE CAN EXPLAIN, PLEASE... 1058 #for isource in range(len(ids_bundle_work['core_sources'].source)): 1059 # ids_bundle_work['core_sources'].source[isource].profiles_1d[0].electrons.energy[:] = 0.0 1060 # ids_bundle_work['core_sources'].source[isource].profiles_1d[0].total_ion_energy[:] = 0.0 1061 # ids_bundle_work['core_sources'].source[isource].profiles_1d[0].j_parallel[:] = 0.0 1062 # for iion in range(len(ids_bundle_work['core_sources'].source[isource].profiles_1d[0].ion)): 1063 # ids_bundle_work['core_sources'].source[isource].profiles_1d[0].ion[iion].particles[:] = 0.0 1064 # ids_bundle_work['core_sources'].source[isource].profiles_1d[0].momentum_tor[:] = 0.0 1065 1066 1 0.4 0.4 0.0 ids_bundle_prev = {} 1067 3 2.8 0.9 0.0 for item in component_list: 1068 3 6779104.9 2259701.6 4.4 ids_bundle_prev[item] = bundle_copy(ids_bundle_work,imas_control.get_ids_sublist_updates(item)) 1069 1070 1 1.3 1.3 0.0 if 'IDSOUT' in component_list: 1071 1 21.1 21.1 0.0 if verbose: print("JINTRAC_IMAS_DRIVER: Writing dataset_description") 1072 1 7.8 7.8 0.0 ids_bundle_updated['dataset_description'] \ 1073 1 824.8 824.8 0.0 = dd.init(ids_bundle_work['dataset_description'], 0, 1074 1 0.2 0.2 0.0 comment_file) 1075 1 22.1 22.1 0.0 ids_bundle_updated['dataset_description'].setPulseCtx(idx_out) 1076 1 0.5 0.5 0.0 if mpi_root: 1077 1 3751.0 3751.0 0.0 DBentry.idsout.put(ids_bundle_updated['dataset_description']) 1078 #code.interact(local=locals()) 1079 1080 # Time loop 1081 1082 1 0.9 0.9 0.0 time = tstart 1083 1 2.1 2.1 0.0 while time < tend: 1084 1 22.0 22.0 0.0 if verbose: print("JINTRAC_IMAS_DRIVER: time =", time, '\n') 1085 8 5.4 0.7 0.0 for icomponent in range(num_components): 1086 8 9.6 1.2 0.0 ids_bundle_work['workflow'].time[0] = time 1087 8 21.7 2.7 0.0 ids_bundle_work['workflow'].time_loop.workflow_cycle[0].component[icomponent].control_integer[0] = 0 #re-set action flag 1088 8 25.4 3.2 0.0 ids_bundle_work['workflow'].time_loop.workflow_cycle[0].component[icomponent].control_float = np.array([0.0]) 1089 1 1764.3 1764.3 0.0 ids_bundle_updated['workflow'].copyValues(ids_bundle_work['workflow']) #workflow IDS from ids_bundle_updated foreseen to be used by all actors 1090 1091 # Advance each component 1092 3 1.7 0.6 0.0 for item in component_list: 1093 3 51.2 17.1 0.0 if verbose: print("JINTRAC_IMAS_DRIVER: check trigger for item ",item,"...") 1094 3 21.9 7.3 0.0 item_index = imas_control.get_component_index(item) 1095 3 9.3 3.1 0.0 if ids_bundle_updated['workflow'].time_loop.workflow_cycle[0].component[item_index].execution_mode == 1: 1096 3 19.8 6.6 0.0 if verbose: print("JINTRAC_IMAS_DRIVER: wrapper called for item ",item,"...") 1097 3 0.8 0.3 0.0 args = ("(noprocessors, imas_control, ids_bundle_updated, ids_bundle_work, ids_bundle_prev[item])") 1098 1099 # Call component via its wrapper 1100 3 25454536.5 8484845.5 16.3 ids_bundle_updated_tmp = eval(imas_control.get_wrapper(item) + args) 1101 1102 # Workflow-component specific consideration of IDS updates, update ids_bundle_prev: 1103 14 44.9 3.2 0.0 for ids_struct in imas_control.get_ids_sublist_updates(item): 1104 14 11.3 0.8 0.0 if ids_struct in ids_bundle_updated_tmp: 1105 11 157.6 14.3 0.0 if is_populated(ids_bundle_updated_tmp[ids_struct],2): 1106 11 4817487.6 437953.4 3.1 ids_bundle_updated[ids_struct].copyValues(ids_bundle_updated_tmp[ids_struct]) 1107 11 3587909.3 326173.6 2.3 ids_bundle_prev[item][ids_struct].copyValues(ids_bundle_updated_tmp[ids_struct]) 1108 3 1.7 0.6 0.0 elif ids_struct == 'transport_solver_numerics': 1109 if is_populated(ids_bundle_updated_tmp[ids_struct],1): 1110 ids_bundle_updated[ids_struct].copyValues(ids_bundle_updated_tmp[ids_struct]) 1111 ids_bundle_prev[item][ids_struct].copyValues(ids_bundle_updated_tmp[ids_struct]) 1112 1113 # Copy newly updated IDS into input (work) IDS, 1114 # ready for next time step 1115 1 4769085.3 4769085.3 3.1 ids_bundle_work = bundle_copy(ids_bundle_updated) 1116 1117 # Update and increment time 1118 1 4.1 4.1 0.0 time = ids_bundle_work['workflow'].time[0] 1119 1 1.1 1.1 0.0 dtmax = 0.0 1120 3 1.8 0.6 0.0 for icomponent in component_list: 1121 3 6.7 2.2 0.0 icomponent_index = imas_control.get_component_index(icomponent) 1122 3 16.0 5.3 0.0 dtmax = max(dtmax, ids_bundle_work['workflow'].time_loop.workflow_cycle[0].component[icomponent_index].time_interval) 1123 1 3.8 3.8 0.0 time += dtmax 1124 1 37.1 37.1 0.0 if verbose: print("JINTRAC_IMAS_DRIVER: Calculated time interval = ", dtmax) 1125 1 1.5 1.5 0.0 dtmaxnew = tend-time 1126 3 1.0 0.3 0.0 for icomponent in component_list: 1127 3 3.1 1.0 0.0 icomponent_index = imas_control.get_component_index(icomponent) 1128 3 4.3 1.4 0.0 ids_bundle_work['workflow'].time_loop.workflow_cycle[0].component[icomponent_index].time_interval = dtmaxnew 1129 1 19.5 19.5 0.0 if verbose: print("JINTRAC_IMAS_DRIVER: Next target interval = ", dtmaxnew) 1130 1131 # end of time loop 1132 1133 1 8.0 8.0 0.0 if verbose: print("JINTRAC_IMAS_DRIVER: Finish time =", time) 1134 1135 1 2166.3 2166.3 0.0 alenv.close() 1136 1137 1 5.2 5.2 0.0 ids_in.close() 1138 1 3.4 3.4 0.0 if DBentry.API == 'NEW': 1139 1 1367.3 1367.3 0.0 DBentry.idsin.close() 1140 1141 1 2.5 2.5 0.0 if 'IDSOUT' in component_list: 1142 1 2230.6 2230.6 0.0 DBentry.idsout.close() 1143 1144 1 0.4 0.4 0.0 return 0