Example #1
0
void enkf_tui_ranking_menu(void * arg) {
    
  enkf_main_type  * enkf_main  = enkf_main_safe_cast( arg );  
  {
    menu_type * menu = menu_alloc("Ranking of results" , "Back" , "bB");
    menu_item_type * obs_item;
    {
      arg_pack_type * arg_pack = arg_pack_alloc();
      arg_pack_append_ptr( arg_pack , enkf_main );
      menu_add_item(menu , "Create/update misfit table" , "cC"  , enkf_tui_ranking_make_misfit_ensemble   , arg_pack , arg_pack_free__);
      menu_add_separator( menu );
      obs_item = menu_add_item(menu , "New observation based ranking" , "nN" , enkf_tui_ranking_create_obs  , enkf_main , NULL);
      arg_pack_append_ptr( arg_pack , obs_item );
    }
    menu_add_item(menu , "New data based ranking (Sort: increasing)" , "iI" , enkf_tui_ranking_create_data_increasing , enkf_main , NULL);
    menu_add_item(menu , "New data based ranking (Sort: decreasing)" , "dD" , enkf_tui_ranking_create_data_decreasing , enkf_main , NULL);
    menu_add_item(menu , "Show ranking" , "sS" , enkf_tui_ranking_display , enkf_main , NULL);
    {
      enkf_fs_type * fs = enkf_main_get_fs( enkf_main );
      misfit_ensemble_type * misfit_ensemble = enkf_fs_get_misfit_ensemble( fs );
      if (!misfit_ensemble_initialized( misfit_ensemble ))
        menu_item_disable( obs_item );
    }
    menu_add_item(menu , "Help" , "hH" , enkf_tui_help_menu_rank , enkf_main , NULL);
    menu_run(menu);
    menu_free(menu);
  }
  
}
int test_load_manually_to_new_case(enkf_main_type * enkf_main) {
  int result = 0;
  int iens = 0;
  int iter = 0;
  const char * casename = "new_case";
  enkf_main_select_fs( enkf_main , casename );
  
  
  enkf_fs_type * fs = enkf_main_get_fs( enkf_main );
  run_arg_type * run_arg = run_arg_alloc_ENSEMBLE_EXPERIMENT(fs , iens , iter , "simulations/run0");
  {
    arg_pack_type * arg_pack = arg_pack_alloc();
    arg_pack_append_ptr( arg_pack , enkf_main_iget_state(enkf_main, 0));                
    arg_pack_append_ptr( arg_pack , run_arg );
    arg_pack_append_bool( arg_pack , true );                                            
    arg_pack_append_owned_ptr( arg_pack , stringlist_alloc_new() , stringlist_free__);  
    arg_pack_append_bool( arg_pack, true );                                             
    arg_pack_append_ptr( arg_pack, &result );                                           
    
    enkf_state_load_from_forward_model_mt(arg_pack);
    arg_pack_free(arg_pack);
  }
  
  return result;
}
Example #3
0
void enkf_main_initialize_from_scratch(enkf_main_type * enkf_main , enkf_fs_type * init_fs , const stringlist_type * param_list ,const bool_vector_type * iens_mask , init_mode_type init_mode) {
  int num_cpu = 4;
  int ens_size               = enkf_main_get_ensemble_size( enkf_main );
  thread_pool_type * tp     = thread_pool_alloc( num_cpu , true );
  arg_pack_type ** arg_list = util_calloc( ens_size , sizeof * arg_list );
  int i;
  int iens;

  for (iens = 0; iens < ens_size; iens++) {
    arg_list[iens] = arg_pack_alloc();
    if (bool_vector_safe_iget(iens_mask , iens)) {
      arg_pack_append_ptr( arg_list[iens] , enkf_main );
      arg_pack_append_ptr( arg_list[iens] , init_fs );
      arg_pack_append_const_ptr( arg_list[iens] , param_list );
      arg_pack_append_int( arg_list[iens] , iens );
      arg_pack_append_int( arg_list[iens] , init_mode );
      
      thread_pool_add_job( tp , enkf_main_initialize_from_scratch_mt , arg_list[iens]);
    }
  }
  thread_pool_join( tp );
  for (i = 0; i < ens_size; i++){
    arg_pack_free( arg_list[i] );
  }
  free( arg_list );
  thread_pool_free( tp );
}
Example #4
0
void enkf_tui_analysis_menu(void * arg) {
  enkf_main_type  * enkf_main  = enkf_main_safe_cast( arg );
  menu_type       * menu = menu_alloc( "Analysis menu" , "Back" , "bB");

  arg_pack_type * arg_pack = arg_pack_alloc();
  arg_pack_append_ptr( arg_pack , enkf_main );
  arg_pack_append_ptr( arg_pack , menu );

  {
    enkf_tui_analysis_update_title(enkf_main, menu);

    if (enkf_main_have_obs(enkf_main)) {
      menu_add_item(menu, "Global scaling of uncertainty", "gG", enkf_tui_analysis_scale_observation_std__, enkf_main, NULL);
      menu_add_separator(menu);
    }

    menu_add_item(menu, "Select analysis module", "sS", enkf_tui_analysis_select_module__, arg_pack, NULL);
    menu_add_item(menu, "List available modules", "lL", enkf_tui_analysis_list_modules__, enkf_main, NULL);
    menu_add_item(menu, "Modify analysis module parameters", "mM", enkf_tui_analysis_update_module__, enkf_main, NULL);
    menu_add_item(menu, "Reload current module (external only)", "rR", enkf_tui_analysis_reload_module__, enkf_main, NULL);
  }
  menu_run(menu);
  menu_free(menu);
  arg_pack_free(arg_pack);
}
void submit_jobs( job_queue_type * queue , int num_jobs , job_type ** jobs , thread_pool_type * tp) {
  for (int i=0; i < num_jobs; i++) {
    job_type * job = jobs[i];
    arg_pack_type * arg = arg_pack_alloc();
    arg_pack_append_ptr( arg , job );
    arg_pack_append_ptr( arg , queue );
    thread_pool_add_job(tp , submit_job__ , arg );
  }
}
Example #6
0
void matrix_inplace_matmul_mt2(matrix_type * A, const matrix_type * B , thread_pool_type * thread_pool){
  int num_threads  = thread_pool_get_max_running( thread_pool );
  arg_pack_type    ** arglist = util_malloc( num_threads * sizeof * arglist );
  int it;
  thread_pool_restart( thread_pool );
  {
    int rows       = matrix_get_rows( A ) / num_threads;
    int rows_mod   = matrix_get_rows( A ) % num_threads;
    int row_offset = 0;

    for (it = 0; it < num_threads; it++) {
      int row_size;
      arglist[it] = arg_pack_alloc();
      row_size = rows;
      if (it < rows_mod)
        row_size += 1;

      arg_pack_append_int(arglist[it] , row_offset );
      arg_pack_append_int(arglist[it] , row_size   );
      arg_pack_append_ptr(arglist[it] , A );
      arg_pack_append_const_ptr(arglist[it] , B );

      thread_pool_add_job( thread_pool , matrix_inplace_matmul_mt__ , arglist[it]);
      row_offset += row_size;
    }
  }
  thread_pool_join( thread_pool );

  for (it = 0; it < num_threads; it++)
    arg_pack_free( arglist[it] );
  free( arglist );
}
Example #7
0
static void job_queue_handle_EXIT( job_queue_type * queue , job_queue_node_type * node) {
  job_queue_change_node_status(queue , node , JOB_QUEUE_RUNNING_CALLBACK );
  {
    arg_pack_type * arg_pack = arg_pack_alloc();
    arg_pack_append_ptr( arg_pack , queue );
    arg_pack_append_int( arg_pack , job_queue_node_get_queue_index(node));
    thread_pool_add_job( queue->work_pool , job_queue_run_EXIT_callback , arg_pack );
  }
}
Example #8
0
void job_queue_start_manager_thread( job_queue_type * job_queue , pthread_t * queue_thread , int job_size , bool verbose) {

  arg_pack_type  * queue_args = arg_pack_alloc(); /* This arg_pack will be freed() in the job_que_run_jobs__() */
  arg_pack_append_ptr(queue_args  , job_queue);
  arg_pack_append_int(queue_args  , job_size);
  arg_pack_append_bool(queue_args , verbose);

  job_queue->running = true;
  pthread_create( queue_thread , NULL , job_queue_run_jobs__ , queue_args);
}
Example #9
0
void test_add_job() {
  job_list_type * list = job_list_alloc();
  job_queue_node_type * node = job_queue_node_alloc_simple("name" , "/tmp" , "/bin/ls" , 0 , NULL);
  job_list_add_job( list , node );
  test_assert_int_equal( job_list_get_size( list ) , 1 );
  test_assert_int_equal( job_queue_node_get_queue_index(node) ,  0 );
  test_assert_ptr_equal( node , job_list_iget_job(list , 0));
  {
    arg_pack_type * arg_pack = arg_pack_alloc( );
    arg_pack_append_ptr( arg_pack , list );
    arg_pack_append_ptr( arg_pack , node );
    test_assert_util_abort("job_queue_node_set_queue_index", call_add_job, arg_pack );
    arg_pack_free( arg_pack );
  }
  test_assert_util_abort("job_list_iget_job", call_iget_job, list);
  job_list_reset( list );
  test_assert_int_equal( 0 , job_list_get_size( list ));
  job_list_free( list );
}
Example #10
0
void ensemble_load_from_glob( ensemble_type * ensemble , const char * pattern , thread_pool_type * tp) {
  glob_t pglob;
  int    i;
  glob( pattern , GLOB_NOSORT , NULL , &pglob );

  for (i=0; i < pglob.gl_pathc; i++) {
    arg_pack_type * arg_pack = arg_pack_alloc( );
    arg_pack_append_ptr( arg_pack , ensemble );
    arg_pack_append_owned_ptr( arg_pack , util_alloc_string_copy( pglob.gl_pathv[i] ) , free );
    thread_pool_add_job( tp , ensemble_add_case__ , arg_pack );
  }

  globfree( &pglob );
}
Example #11
0
void enkf_tui_fs_menu(void * arg) {
  
   enkf_main_type  * enkf_main  = enkf_main_safe_cast( arg );  

   const char * menu_title = util_alloc_sprintf("Manage cases - current: %s", enkf_main_get_current_fs( enkf_main ));
   menu_type * menu = menu_alloc(menu_title , "Back" , "bB");

   menu_add_item(menu , "List available cases" , "lL" , enkf_tui_fs_ls_case , enkf_main , NULL);
   
   {
     arg_pack_type * arg_pack = arg_pack_alloc();
     arg_pack_append_ptr(arg_pack  , enkf_main);
     arg_pack_append_ptr(arg_pack  , menu);
     menu_add_item(menu , "Create and select new case" , "cC" , enkf_tui_fs_create_case, arg_pack , arg_pack_free__);
   }

   {
     arg_pack_type * arg_pack = arg_pack_alloc();
     arg_pack_append_ptr(arg_pack  , enkf_main);
     arg_pack_append_ptr(arg_pack  , menu);
     menu_add_item(menu , "Select case" , "sS" , enkf_tui_fs_select_case, arg_pack , arg_pack_free__);
   }

   menu_add_separator(menu);
   menu_add_item(menu, "Initialize case from scratch"                      , "iI" , enkf_tui_init_menu                          , enkf_main , NULL); 
   menu_add_item(menu, "Initialize case from existing case"                , "aA" , enkf_tui_fs_initialize_case_from_copy       , enkf_main , NULL); 
   menu_add_item(menu, "Initialize case FOR PREDICTIONS from existing case", "pP" , enkf_tui_fs_initialize_case_for_predictions , enkf_main , NULL); 

   menu_add_separator(menu);
   /* Are these two in use??? */
   menu_add_item(menu, "Copy full ensemble to another case", "eE", enkf_tui_fs_copy_ensemble, enkf_main, NULL); 
   menu_add_item(menu, "Copy ensemble of parameters to another case", "oO", enkf_tui_fs_copy_ensemble_of_parameters, enkf_main, NULL); 
   menu_add_item(menu , "Help"                                  , "hH" , enkf_tui_help_menu_cases   , enkf_main , NULL); 

   menu_run(menu);
   menu_free(menu);
}
Example #12
0
void enkf_main_initialize_from_scratch(enkf_main_type * enkf_main , const stringlist_type * param_list , int iens1 , int iens2, init_mode_enum init_mode) {
  int num_cpu               = 4;
  thread_pool_type * tp     = thread_pool_alloc( num_cpu , true );
  int ens_sub_size          = (iens2 - iens1 + 1) / num_cpu;
  arg_pack_type ** arg_list = util_calloc( num_cpu , sizeof * arg_list );
  int i;

  printf("Setting up ensemble members from %d to %d", iens1, iens2);
  if (init_mode == INIT_CONDITIONAL) {
    printf(" using conditional initialization (keep existing parameter values).\n");
  }
  else if (init_mode == INIT_FORCE) {
    printf(" using forced initialization (initialize from scratch).\n");
  }
  else if (init_mode == INIT_NONE) {
    printf(" not initializing at all.\n");
  }
  fflush( stdout );

  for (i = 0; i < num_cpu;  i++) {
    arg_list[i] = arg_pack_alloc();
    arg_pack_append_ptr( arg_list[i] , enkf_main );
    arg_pack_append_const_ptr( arg_list[i] , param_list );
    {
      int start_iens = i * ens_sub_size;
      int end_iens   = start_iens + ens_sub_size;

      if (i == (num_cpu - 1)){
        end_iens = iens2 + 1;  /* Input is upper limit inclusive. */
        if(ens_sub_size == 0)
          start_iens = iens1;  /* Don't necessarily want to start from zero when ens_sub_size = 0*/
      }
      arg_pack_append_int( arg_list[i] , start_iens );
      arg_pack_append_int( arg_list[i] , end_iens );
    }
    arg_pack_append_int( arg_list[i] , init_mode );
    thread_pool_add_job( tp , enkf_main_initialize_from_scratch_mt , arg_list[i]);
  }
  thread_pool_join( tp );
  for (i = 0; i < num_cpu; i++)
    arg_pack_free( arg_list[i] );
  free( arg_list );
  thread_pool_free( tp );
  printf("Done setting up ensemble.\n");
}
Example #13
0
void test_runpath_list() {
  runpath_list_type * list = runpath_list_alloc();

  test_assert_int_equal( runpath_list_size( list ) , 0 );

  runpath_list_add( list , 3 , 0, "path" , "base");
  runpath_list_add( list , 2 , 0, "path" , "base");
  runpath_list_add( list , 1 , 0, "path" , "base");

  runpath_list_add( list , 3 , 1, "path" , "base");
  runpath_list_add( list , 2 , 1, "path" , "base");
  runpath_list_add( list , 1 , 1, "path" , "base");
  
  test_assert_int_equal( runpath_list_size( list ) , 6 );
  test_assert_int_equal( runpath_list_iget_iens( list , 0 ) , 3 );
  test_assert_int_equal( runpath_list_iget_iens( list , 2 ) , 1 );
  test_assert_int_equal( runpath_list_iget_iter( list , 3 ) , 1 );
  runpath_list_sort( list );

  test_assert_int_equal( runpath_list_iget_iens( list , 0 ) , 1 );
  test_assert_int_equal( runpath_list_iget_iens( list , 4 ) , 3 );
  runpath_list_clear( list );
  test_assert_int_equal( runpath_list_size( list ) , 0 );

  test_assert_string_equal( runpath_list_get_line_fmt( list ) , RUNPATH_LIST_DEFAULT_LINE_FMT );
  {
    const char * other_line = "%d %s %s";
    runpath_list_set_line_fmt( list , other_line );
    test_assert_string_equal( runpath_list_get_line_fmt( list ) , other_line );
  }
  runpath_list_set_line_fmt( list , NULL );
  test_assert_string_equal( runpath_list_get_line_fmt( list ) , RUNPATH_LIST_DEFAULT_LINE_FMT );

  {
    const int block_size = 100;
    const int threads = 100;
    thread_pool_type * tp = thread_pool_alloc( threads , true );
    int it;
    
    for (it = 0; it < threads; it++) {
      int iens_offset = it * block_size;
      arg_pack_type * arg_pack = arg_pack_alloc();

      arg_pack_append_ptr( arg_pack , list );
      arg_pack_append_int( arg_pack , iens_offset );
      arg_pack_append_int( arg_pack , block_size );
      
      thread_pool_add_job( tp , add_pathlist , arg_pack );
    }
    thread_pool_join( tp );
    test_assert_int_equal( runpath_list_size( list ) , block_size * threads );
    runpath_list_sort( list );
    {
      int iens;
      for (iens = 0; iens < block_size * threads; iens++)
        test_assert_int_equal( runpath_list_iget_iens( list , iens ) , iens );
    }
    
    {
      test_work_area_type * work_area = test_work_area_alloc("enkf_runpath_list" );
      const char *filename = "runpath_list.txt";
      {
        FILE * stream = util_fopen( filename, "w");
        runpath_list_fprintf( list , stream );
        fclose( stream );
      }

      {
        int file_iens;
        int file_iter;
        char file_path[256];
        char file_base[256];
        int iens;
        FILE * stream = util_fopen( filename, "r");
        for (iens = 0; iens < threads * block_size; iens++) {
          int fscanf_return = fscanf( stream , "%d %s %s %d" , &file_iens , file_path , file_base, &file_iter);
          test_assert_int_equal(fscanf_return, 4 );
          test_assert_int_equal( file_iens , iens );
          test_assert_int_equal( file_iter , 0 );
        }
        fclose( stream );
      }
      test_work_area_free( work_area );
    }
  }
  runpath_list_free( list );
}
Example #14
0
void enkf_tui_run_manual_load__( void * arg ) {
  enkf_main_type * enkf_main                   = enkf_main_safe_cast( arg );
  enkf_fs_type * fs                            = enkf_main_get_fs( enkf_main ); 
  const int last_report                        = -1;
  const int ens_size                           = enkf_main_get_ensemble_size( enkf_main );
  int step1,step2;
  bool_vector_type * iactive = bool_vector_alloc( 0 , false );
  run_mode_type run_mode = ENSEMBLE_EXPERIMENT; 
  
  enkf_main_init_run(enkf_main , run_mode);     /* This is ugly */
  
  step1 = 0;
  step2 = last_report;  /** Observe that for the summary data it will load all the available data anyway. */
  {
    char * prompt = util_alloc_sprintf("Which realizations to load  (Ex: 1,3-5) <Enter for all> [M to return to menu] : [ensemble size:%d] : " , ens_size);
    char * select_string;
    util_printf_prompt(prompt , PROMPT_LEN , '=' , "=> ");
    select_string = util_alloc_stdin_line();

    enkf_tui_util_sscanf_active_list( iactive , select_string , ens_size );
    util_safe_free( select_string );
    
    free( prompt );
  }



  if (bool_vector_count_equal( iactive , true )) {
    int iens;
    arg_pack_type ** arg_list = util_calloc( ens_size , sizeof * arg_list );
    thread_pool_type * tp = thread_pool_alloc( 4 , true );  /* num_cpu - HARD coded. */

    for (iens = 0; iens < ens_size; iens++) {
      arg_pack_type * arg_pack = arg_pack_alloc();
      arg_list[iens] = arg_pack;
      
      if (bool_vector_iget(iactive , iens)) {
        enkf_state_type * enkf_state = enkf_main_iget_state( enkf_main , iens );

        arg_pack_append_ptr( arg_pack , enkf_state);                                        /* 0: */
        arg_pack_append_ptr( arg_pack , fs );                                               /* 1: */
        arg_pack_append_int( arg_pack , step1 );                                            /* 2: This will be the load start parameter for the run_info struct. */
        arg_pack_append_int( arg_pack , step1 );                                            /* 3: Step1 */ 
        arg_pack_append_int( arg_pack , step2 );                                            /* 4: Step2 For summary data it will load the whole goddamn thing anyway.*/
        arg_pack_append_bool( arg_pack , true );                                            /* 5: Interactive */                  
        arg_pack_append_owned_ptr( arg_pack , stringlist_alloc_new() , stringlist_free__);  /* 6: List of interactive mode messages. */
        thread_pool_add_job( tp , enkf_state_load_from_forward_model_mt , arg_pack);
        
      }
    }
    
    thread_pool_join( tp );
    thread_pool_free( tp );
    printf("\n");

    {
      qc_module_type * qc_module = enkf_main_get_qc_module( enkf_main );
      runpath_list_type * runpath_list = qc_module_get_runpath_list( qc_module );

      for (iens = 0; iens < ens_size; iens++) {
        if (bool_vector_iget(iactive , iens)) {
          const enkf_state_type * state = enkf_main_iget_state( enkf_main , iens );
          runpath_list_add( runpath_list , iens , enkf_state_get_run_path( state ) , enkf_state_get_eclbase( state ));
        }
      }

      qc_module_export_runpath_list( qc_module );
    }

    for (iens = 0; iens < ens_size; iens++) {
      if (bool_vector_iget(iactive , iens)) {
        stringlist_type * msg_list = arg_pack_iget_ptr( arg_list[iens] , 6 );
        if (stringlist_get_size( msg_list ))
          enkf_tui_display_load_msg( iens , msg_list );
      }
    }
    
    
    for (iens = 0; iens < ens_size; iens++) 
      arg_pack_free( arg_list[iens]);
    free( arg_list );      
  }
  bool_vector_free( iactive );
}
Example #15
0
int main(int argc , char ** argv) {
  install_SIGNALS();
  
  if(argc > 1) {
    if(strcmp(argv[1], "-h") == 0)
      print_usage(__LINE__);
  }


  if(argc < 2)
    print_usage(__LINE__);

  else{
    char ** input        = &argv[1];   /* Skipping the name of the executable */
    int     input_length = argc - 1;   
    int     input_offset = 0;
    bool    use_eclbase, fmt_file; 
    
    const char * report_filen  = "RUN_GRAVITY.out"; 
    
    ecl_file_type ** restart_files;
    ecl_file_type  * init_file;
    ecl_grid_type  * ecl_grid;
    
    int model_phases;
    int file_phases;
    vector_type * grav_stations = vector_alloc_new();
    
    
    /* Restart info */
    restart_files = load_restart_info( (const char **) input , input_length , &input_offset , &use_eclbase , &fmt_file);
    
    /* INIT and GRID/EGRID files */
    {
      char           * grid_filename = NULL;
      char           * init_filename = NULL;
      if (use_eclbase) {
        /* 
           The first command line argument is interpreted as ECLBASE, and we
           search for grid and init files in cwd.
        */
        init_filename = ecl_util_alloc_exfilename_anyfmt( NULL , input[0] , ECL_INIT_FILE  , fmt_file , -1);
        grid_filename = ecl_util_alloc_exfilename_anyfmt( NULL , input[0] , ECL_EGRID_FILE , fmt_file , -1);
        if (grid_filename == NULL)
          grid_filename = ecl_util_alloc_exfilename_anyfmt( NULL , input[0] , ECL_GRID_FILE , fmt_file , -1);
        
        if ((init_filename == NULL) || (grid_filename == NULL))  /* Means we could not find them. */
          util_exit("Could not find INIT or GRID|EGRID file \n");
      } else {
        /* */
        if ((input_length - input_offset) > 1) {
          init_filename = util_alloc_string_copy(input[input_offset]);
          grid_filename = util_alloc_string_copy(input[input_offset + 1]);
          input_offset += 2;
        } else print_usage(__LINE__);
      }
      
      init_file     = ecl_file_open(init_filename );
      ecl_grid      = ecl_grid_alloc(grid_filename );
      free( init_filename );
      free( grid_filename );
    }
    
    // Load the station_file
    if (input_length > input_offset) {
      char * station_file = input[input_offset];
      if (util_file_exists(station_file))
        load_stations( grav_stations , station_file);
      else 
        util_exit("Can not find file:%s \n",station_file);
    } else 
      print_usage(__LINE__);



    /** 
        OK - now everything is loaded - check that all required
        keywords+++ are present.
    */
    gravity_check_input(ecl_grid , init_file , restart_files[0] , restart_files[1] , &model_phases , &file_phases);
    
    /* 
       OK - now it seems the provided files have all the information
       we need. Let us start using it. The main loop is run in
       parallell on four threads - most people have four cores these
       days.
    */
    {
      int i;
      int num_threads = 4;
      thread_pool_type * tp = thread_pool_alloc( num_threads , true);
      arg_pack_type ** arg_list = util_calloc( num_threads , sizeof * arg_list);
      {
        int station_delta = vector_get_size( grav_stations ) / num_threads;
        for (i = 0; i < num_threads; i++) {
          int station1 = i * station_delta;
          int station2 = station1 + station_delta;
          if (i == num_threads)
            station2 = vector_get_size( grav_stations );
          
          arg_list[i] = arg_pack_alloc( );

          arg_pack_append_ptr( arg_list[i] , grav_stations );
          arg_pack_append_ptr( arg_list[i] , ecl_grid);
          arg_pack_append_ptr( arg_list[i] , init_file );
          arg_pack_append_ptr( arg_list[i] , restart_files);
          arg_pack_append_int( arg_list[i] , station1 );
          arg_pack_append_int( arg_list[i] , station2 );
          arg_pack_append_int( arg_list[i] , model_phases );
          arg_pack_append_int( arg_list[i] , file_phases );

          thread_pool_add_job( tp , gravity_response_mt , arg_list[i]);
        }
      }
      thread_pool_join( tp );
      for (i = 0; i < num_threads; i++) 
        arg_pack_free( arg_list[i] );
      free( arg_list );
        
    }
    
    {
      FILE * stream = util_fopen(report_filen , "w");
      int station_nr;
      double total_chisq = 0;
      for(station_nr = 0; station_nr < vector_get_size( grav_stations ); station_nr++){
        const grav_station_type * g_s = vector_iget_const(grav_stations, station_nr);
        fprintf(stream, "%f",g_s->grav_diff);
        printf ("DELTA_G %4s[%02d]: %12.6f %12.6f %12.6f %12.6f", g_s->name , station_nr, g_s->grav_diff, g_s->utm_x, g_s->utm_y, g_s->depth);

        if ( g_s->has_obs ) {
          double y = (g_s->grav_diff - g_s->obs_gdiff) / g_s->std_gdiff;
          double chi_sq = y * y;
          total_chisq += chi_sq;
          fprintf(stream , " %g",chi_sq);
          printf(" %g",chi_sq);
        }

        fprintf(stream , " \n");
        printf("\n");
      }
      if (total_chisq > 0) {
        printf("Total chisq misfit: %g \n", total_chisq);
      }
      fclose(stream);
    }
    

    vector_free( grav_stations );
    ecl_grid_free(ecl_grid);
    ecl_file_close(restart_files[0]);
    ecl_file_close(restart_files[1]);
    free( restart_files );
    ecl_file_close(init_file);
  }             

}