Пример #1
0
void get_put_vars(int exo_file, ex_entity_type type, int num_blocks, int num_vars,
                  int num_time_steps, const std::vector<int> &num_per_block, const char* mname)

{
  /* truth table */
  if (debug) logger("\tTruth Table");
  std::vector<int> truth_table(num_vars*num_blocks);
  ex_get_truth_table(exo_file, type, num_blocks, num_vars,TOPTR(truth_table));

  size_t num_entity = std::accumulate(num_per_block.begin(), num_per_block.end(), 0);
  std::vector<double> scr(num_entity * num_time_steps);

  std::vector<int> ids(num_blocks);
  ex_get_ids(exo_file, type, TOPTR(ids));

  char str[32];
  for (int i=0; i < num_vars; i++) {
    if (debug) logger("\tReading");
    std::fill(scr.begin(), scr.end(), 0.0);
    size_t n=0;
    sprintf(str,mname,i+1);
    for (int j=0; j<num_time_steps; j++){
      for (int k=0; k<num_blocks; k++){
        if (truth_table[num_vars*k+i]==1) {
          ex_get_var(exo_file,j+1,type, i+1,ids[k],num_per_block[k],&scr[n]);
        }
        n=n+num_per_block[k];
      }
    }
    if (debug) logger("\tWriting");
    PutDbl(str,num_entity,num_time_steps,TOPTR(scr));
  }
}
Пример #2
0
int NemSpread<T,INT>::read_elem_vars(int exoid, int index, INT *eb_ids,
                                     INT *eb_cnts, INT ***eb_map_ptr,
                                     INT **eb_cnts_local)
{

    /* to speed up searches, keep track of element blocks offset on each proc */
    std::vector<INT> local_offset(Proc_Info[2]);

    /* loop over the number of element blocks */
    INT     eb_offset=0;
    for (int iblk = 0; iblk < globals.Num_Elem_Blk; iblk++) {
        read_elem_vars_1(exoid, index, eb_ids,
                         eb_cnts, eb_map_ptr, eb_cnts_local,
                         iblk, eb_offset, TOPTR(local_offset));

        /* need to keep track of this for the element number map */
        eb_offset += eb_cnts[iblk];

        /* need to set up local offsets for next block */
        for (int iproc = 0; iproc <Proc_Info[2]; iproc++)
            local_offset[iproc] += eb_cnts_local[iproc][iblk];

    } /* End "for (iblk = 0; iblk < globals.Num_Elem_Blk; iblk++)" */

    return 0;
}
Пример #3
0
int NemSpread<T,INT>::read_vars(int exoid, int index, INT *eb_ids,
                                INT *eb_cnts, INT ***eb_map_ptr, INT **eb_cnts_local,
                                INT *ss_ids, INT *ss_cnts, INT *ns_ids, INT *ns_cnts)
{
    const char  *yo="read_vars";

    /* first read the time */
    if (ex_get_time(exoid, index, &Restart_Info.Time) < 0) {
        fprintf(stderr, "%s: ERROR, unable to get time for restart index %d!\n",
                yo, index);
        return -1;
    }

    /***************** Global Variables ********************/
    /* allocate space for the global variables */
    if (Restart_Info.NVar_Glob > 0) {
        /* get the global variables */
        if (ex_get_glob_vars(exoid, index, Restart_Info.NVar_Glob, TOPTR(Restart_Info.Glob_Vals)) < 0) {
            fprintf(stderr, "%s: Could not get global variables from file\n", yo);
            return -1;
        }
    }

    if (Restart_Info.NVar_Elem > 0 ) {
        printf("Reading %d element variables...\n", Restart_Info.NVar_Elem);
        if (read_elem_vars(exoid, index, eb_ids, eb_cnts, eb_map_ptr,
                           eb_cnts_local) < 0) {
            fprintf(stderr, "%s: Error distributing elemental variables.\n", yo);
            return -1;
        }
    }

    if (Restart_Info.NVar_Node > 0 ) {
        printf("Reading %d nodal variables...\n", Restart_Info.NVar_Node);
        if (read_nodal_vars(exoid, index) < 0) {
            fprintf(stderr, "%s: Error distributing nodal variables.\n", yo);
            return -1;
        }
    }

    if (Restart_Info.NVar_Sset > 0 ) {
        printf("Reading %d sideset variables...\n", Restart_Info.NVar_Sset);
        if (read_sset_vars(exoid, index, ss_ids, ss_cnts) < 0) {
            fprintf(stderr, "%s: Error distributing sideset variables.\n", yo);
            return -1;
        }
    }


    if (Restart_Info.NVar_Nset > 0 ) {
        printf("Reading %d nodeset variables...\n", Restart_Info.NVar_Nset);
        if (read_nset_vars(exoid, index, ns_ids, ns_cnts) < 0) {
            fprintf(stderr, "%s: Error distributing nodeset variables.\n", yo);
            return -1;
        }
    }

    return 0;

}
Пример #4
0
static void
start_aps(void) {
	int			i;
	unsigned	count;

	for(i = 1; i < lsp.syspage.p->num_cpu; ++i) {
		cpu_starting = i + 1;

		if(board_smp_start(i, smp_start)) {
			count = 0;
			do {
				if(++count == 0) ap_fail(i);
			} while(cpu_starting != 0);
		} else {
			ap_fail(i);
		}
	}

	smp_hook_rtn = transfer_aps;

#if defined(__X86__)
	// For backwards compatability, remove later
	lsp.cpu.x86_smpinfo.p->lapic_addr = TOPTR(lsp.smp.p->cpu);
#endif
}
Пример #5
0
void Ioss::ParallelUtils::gather(std::vector<int64_t> &my_values, std::vector<int64_t> &result) const
{
  size_t count = my_values.size();
  if (parallel_rank() == 0) {
    result.resize(count * parallel_size());
  }
#ifdef HAVE_MPI
  if (parallel_size() > 1) {
    const int success = MPI_Gather((void*)TOPTR(my_values),  count, MPI_LONG_LONG_INT,
				   (void*)TOPTR(result), count, MPI_LONG_LONG_INT,
				   0, communicator_);
    if (success !=  MPI_SUCCESS) {
      std::ostringstream errmsg;
      errmsg << "Ioss::ParallelUtils::gather - MPI_Gather failed";
      IOSS_ERROR(errmsg);
    }
  } else {
    std::copy(my_values.begin(), my_values.end(), result.begin());
  }
#else
  std::copy(my_values.begin(), my_values.end(), result.begin());
#endif
}
Пример #6
0
int write_nemesis(std::string &nemI_out_file,
                  Machine_Description* machine,
                  Problem_Description* problem,
                  Mesh_Description<INT>* mesh,
                  LB_Description<INT>* lb,
                  Sphere_Info* sphere)
{
  int     exoid;
  char    title[MAX_LINE_LENGTH+1], method1[MAX_LINE_LENGTH+1];
  char    method2[MAX_LINE_LENGTH+1];

  int cpu_ws = sizeof(float);
  int io_ws  = sizeof(float);

  printf("Outputting load balance to file %s\n", nemI_out_file.c_str());

  /* Create the load balance file */
  /* Attempt to create a netcdf4-format file; if it fails, then assume
     that the netcdf library does not support that mode and fall back
     to classic netcdf3 format.  If that fails, issue an error and
     return failure.
  */
  int mode3 = EX_CLOBBER;
  int mode4 = mode3|EX_NETCDF4|EX_NOCLASSIC|problem->int64db|problem->int64api;

  ex_opts(EX_DEFAULT); // Eliminate misleading error if the first ex_create fails, but the second succeeds.
  if((exoid=ex_create(nemI_out_file.c_str(), mode4, &cpu_ws, &io_ws)) < 0) {
    /* If int64api or int64db non-zero, then netcdf-4 format is required, so
       fail now...
    */
    if (problem->int64db|problem->int64api) {
      Gen_Error(0, "fatal: failed to create Nemesis netcdf-4 file");
      return 0;
    }
    if((exoid=ex_create(nemI_out_file.c_str(), mode3, &cpu_ws, &io_ws)) < 0) {
      Gen_Error(0, "fatal: failed to create Nemesis file");
      return 0;
    }
  }
  ON_BLOCK_EXIT(ex_close, exoid);
  
  /* Set the error reporting value */
  if (error_lev > 1)
    ex_opts(EX_VERBOSE | EX_DEBUG);
  else
    ex_opts(EX_VERBOSE);

  /* Enable compression (if netcdf-4) */
  ex_set_option(exoid, EX_OPT_COMPRESSION_LEVEL, 1);
  ex_set_option(exoid, EX_OPT_COMPRESSION_SHUFFLE, 1);

  /* Create the title */
  if(problem->type == NODAL)
    strcpy(method1, "nodal");
  else
    strcpy(method1, "elemental");

  sprintf(title, "nem_slice %s load balance file", method1);

  strcpy(method1, "method1: ");
  strcpy(method2, "method2: ");

  switch(lb->type)
    {
    case MULTIKL:
      strcat(method1, "Multilevel-KL decomposition");
      strcat(method2, "With Kernighan-Lin refinement");
      break;
    case SPECTRAL:
      strcat(method1, "Spectral decomposition");
      break;
    case INERTIAL:
      strcat(method1, "Inertial decomposition");
      break;
    case ZPINCH:
      strcat(method1, "ZPINCH decomposition");
      break;
    case BRICK:
      strcat(method1, "BRICK decomposition");
      break;
    case ZOLTAN_RCB:
      strcat(method1, "RCB decomposition");
      break;
    case ZOLTAN_RIB:
      strcat(method1, "RIB decomposition");
      break;
    case ZOLTAN_HSFC:
      strcat(method1, "HSFC decomposition");
      break;
    case LINEAR:
      strcat(method1, "Linear decomposition");
      break;
    case RANDOM:
      strcat(method1, "Random decomposition");
      break;
    case SCATTERED:
      strcat(method1, "Scattered decomposition");
      break;
    }

  if(lb->refine == KL_REFINE && lb->type != MULTIKL)
    strcat(method2, "with Kernighan-Lin refinement");
  else if(lb->type != MULTIKL)
    strcat(method2, "no refinement");

  switch(lb->num_sects)
    {
    case 1:
      strcat(method1, " via bisection");
      break;
    case 2:
      strcat(method1, " via quadrasection");
      break;
    case 3:
      strcat(method1, " via octasection");
      break;
    }

  /* Do some sorting */
  for(int proc=0; proc < machine->num_procs; proc++) {

    /* Sort node maps */
    gds_qsort(TOPTR(lb->int_nodes[proc]), lb->int_nodes[proc].size());
    if(problem->type == NODAL) {
      sort2(lb->ext_nodes[proc].size(), TOPTR(lb->ext_nodes[proc]),
	    TOPTR(lb->ext_procs[proc]));
    }

    /* Sort element maps */
    gds_qsort(TOPTR(lb->int_elems[proc]), lb->int_elems[proc].size());
  }

  /* Output the info records */
  char *info[3];
  info[0] = title;
  info[1] = method1;
  info[2] = method2;

  if(ex_put_info(exoid, 3, info) < 0)
    Gen_Error(0, "warning: output of info records failed");

  /* Generate a QA record for the utility */
  time_t time_val = time(nullptr);
  char *ct_ptr   = asctime(localtime(&time_val));
  char tm_date[30];
  strcpy(tm_date, ct_ptr);

  /* Break string with null characters */
  tm_date[3]  = '\0';
  tm_date[7]  = '\0';
  tm_date[10] = '\0';
  tm_date[19] = '\0';

  char    qa_date[15], qa_time[10], qa_name[MAX_STR_LENGTH];
  char    qa_vers[10];

  sprintf(qa_date, "%s %s %s", &tm_date[8], &tm_date[4], &tm_date[20]);
  sprintf(qa_time, "%s", &tm_date[11]);
  strcpy(qa_name, UTIL_NAME);
  strcpy(qa_vers, ELB_VERSION);

  if(qa_date[strlen(qa_date)-1] == '\n')
    qa_date[strlen(qa_date)-1] = '\0';

  char **lqa_record = (char **)array_alloc(1, 4, sizeof(char *));
  for(int i2=0; i2 < 4; i2++)
    lqa_record[i2] = (char *)array_alloc(1, MAX_STR_LENGTH+1, sizeof(char));

  strcpy(lqa_record[0], qa_name);
  strcpy(lqa_record[1], qa_vers);
  strcpy(lqa_record[2], qa_date);
  strcpy(lqa_record[3], qa_time);

  printf("QA Record:\n");
  for(int i2=0; i2 < 4; i2++) {
    printf("\t%s\n", lqa_record[i2]);
  }

  if(ex_put_qa(exoid, 1, (char *(*)[4]) &lqa_record[0]) < 0) {
    Gen_Error(0, "fatal: unable to output QA records");
    return 0;
  }

  /* free up memory */
  for(int i2=0; i2 < 4; i2++)
    free(lqa_record[i2]);

  free(lqa_record);

  /* Output the the initial Nemesis global information */
  if(ex_put_init_global(exoid, mesh->num_nodes, mesh->num_elems,
                        mesh->num_el_blks, 0, 0) < 0) {
    Gen_Error(0, "fatal: failed to output initial Nemesis parameters");
    return 0;
  }
  
  /* Set up dummy arrays for ouput */
  std::vector<INT> num_nmap_cnts(machine->num_procs);
  std::vector<INT> num_emap_cnts(machine->num_procs);
  
  if(problem->type == NODAL) {
    /* need to check and make sure that there really are comm maps */
    for(int cnt=0; cnt < machine->num_procs; cnt++) {
      if (!lb->bor_nodes[cnt].empty())
	num_nmap_cnts[cnt] = 1;
    }
  }
  else {	/* Elemental load balance */
    if(((problem->num_vertices)-(sphere->num)) > 0) {
      /* need to check and make sure that there really are comm maps */
      for(int cnt=0; cnt < machine->num_procs; cnt++) {
        if (!lb->bor_nodes[cnt].empty()) num_nmap_cnts[cnt] = 1;
      }
      for(int cnt=0; cnt < machine->num_procs; cnt++) {
        if (!lb->bor_elems[cnt].empty()) num_emap_cnts[cnt] = 1;
      }
    }
  }

  if(ex_put_init_info(exoid, machine->num_procs, machine->num_procs, (char*)"s") < 0) {
    Gen_Error(0, "fatal: unable to output init info");
    return 0;
  }

  // Need to create 5 arrays with the sizes of lb->int_nodes[i].size()...
  {
    std::vector<INT> ins(machine->num_procs);
    std::vector<INT> bns(machine->num_procs);
    std::vector<INT> ens(machine->num_procs);
    std::vector<INT> ies(machine->num_procs);
    std::vector<INT> bes(machine->num_procs);

    for (int iproc = 0; iproc < machine->num_procs; iproc++) {
      ins[iproc] = lb->int_nodes[iproc].size();
      bns[iproc] = lb->bor_nodes[iproc].size();
      ens[iproc] = lb->ext_nodes[iproc].size();
      ies[iproc] = lb->int_elems[iproc].size();
      bes[iproc] = lb->bor_elems[iproc].size();
    }

    if(ex_put_loadbal_param_cc(exoid,
			       TOPTR(ins), TOPTR(bns), TOPTR(ens),
			       TOPTR(ies), TOPTR(bes), TOPTR(num_nmap_cnts),
			       TOPTR(num_emap_cnts)) < 0)
      {
	Gen_Error(0, "fatal: unable to output load-balance parameters");
	return 0;
      }
  }

  if(problem->type == NODAL)		/* Nodal load balance output */
    {
      /* Set up for the concatenated communication map parameters */
      std::vector<INT> node_proc_ptr(machine->num_procs+1);
      std::vector<INT> node_cmap_ids_cc(machine->num_procs);
      std::vector<INT> node_cmap_cnts_cc(machine->num_procs);

      node_proc_ptr[0] = 0;
      for(int proc=0; proc < machine->num_procs; proc++) {
	node_proc_ptr[proc+1]   = node_proc_ptr[proc] + 1;
	node_cmap_cnts_cc[proc] = lb->ext_nodes[proc].size();
	node_cmap_ids_cc[proc]  = 1;
      }

      /* Output the communication map parameters */
      if(ex_put_cmap_params_cc(exoid, TOPTR(node_cmap_ids_cc),
			       TOPTR(node_cmap_cnts_cc),
			       TOPTR(node_proc_ptr), nullptr, nullptr, nullptr) < 0)
	{
	  Gen_Error(0, "fatal: unable to output communication map parameters");
	  return 0;
	}

      /* Output the node and element maps */
      for(int proc=0; proc < machine->num_procs; proc++) {
	/* Output the nodal map */
	if(ex_put_processor_node_maps(exoid,
				      TOPTR(lb->int_nodes[proc]),
				      TOPTR(lb->bor_nodes[proc]),
				      TOPTR(lb->ext_nodes[proc]), proc) < 0)
	  {
	    Gen_Error(0, "fatal: failed to output node map");
	    return 0;
	  }

	/* Output the elemental map */
	if(ex_put_processor_elem_maps(exoid, TOPTR(lb->int_elems[proc]), nullptr, proc) < 0)
	  {
	    Gen_Error(0, "fatal: failed to output element map");
	    return 0;
	  }

	/*
	 * Reorder the nodal communication maps so that they are ordered
	 * by processor and then by global ID.
	 */

	/* This is a 2-key sort */
	qsort2(TOPTR(lb->ext_procs[proc]), TOPTR(lb->ext_nodes[proc]), lb->ext_nodes[proc].size());

	/* Output the nodal communication map */
	if(ex_put_node_cmap(exoid, 1,
			    TOPTR(lb->ext_nodes[proc]),
			    TOPTR(lb->ext_procs[proc]), proc) < 0)
	  {
	    Gen_Error(0, "fatal: failed to output nodal communication map");
	    return 0;
	  }

      } /* End "for(proc=0; proc < machine->num_procs; proc++)" */
    }
  else if(problem->type == ELEMENTAL)	/* Elemental load balance output */
    {
      std::vector<INT> node_proc_ptr(machine->num_procs+1);
      std::vector<INT> node_cmap_ids_cc(machine->num_procs);
      std::vector<INT> node_cmap_cnts_cc(machine->num_procs);

      node_proc_ptr[0] = 0;
      for(int proc=0; proc < machine->num_procs; proc++) {
	node_proc_ptr[proc+1]   = node_proc_ptr[proc] + 1;

	node_cmap_cnts_cc[proc] = 0;
	for(size_t cnt=0; cnt < lb->bor_nodes[proc].size(); cnt++)
	  node_cmap_cnts_cc[proc] += lb->born_procs[proc][cnt].size();

	node_cmap_ids_cc[proc]  = 1;
      }

      std::vector<INT> elem_proc_ptr(machine->num_procs+1);
      std::vector<INT> elem_cmap_ids_cc(machine->num_procs);
      std::vector<INT> elem_cmap_cnts_cc(machine->num_procs);

      elem_proc_ptr[0] = 0;
      for(int proc=0; proc < machine->num_procs; proc++) {
	elem_proc_ptr[proc+1]   = elem_proc_ptr[proc] + 1;
	elem_cmap_cnts_cc[proc] = lb->e_cmap_elems[proc].size();
	elem_cmap_ids_cc[proc]  = 1;
      }

      /* Output the communication map parameters */
      if(ex_put_cmap_params_cc(exoid, TOPTR(node_cmap_ids_cc), TOPTR(node_cmap_cnts_cc),
			       TOPTR(node_proc_ptr), TOPTR(elem_cmap_ids_cc),
			       TOPTR(elem_cmap_cnts_cc), TOPTR(elem_proc_ptr)) < 0)
	{
	  Gen_Error(0, "fatal: unable to output communication map parameters");
	  return 0;
	}

      /* Output the node and element maps */
      for(int proc=0; proc < machine->num_procs; proc++)
	{
	  /* Output the nodal map */
	  if(ex_put_processor_node_maps(exoid,
					TOPTR(lb->int_nodes[proc]),
					TOPTR(lb->bor_nodes[proc]),
					nullptr, proc) < 0)
	    {
	      Gen_Error(0, "fatal: failed to output node map");
	      return 0;
	    }

	  /* Output the elemental map */
	  if(ex_put_processor_elem_maps(exoid,
					TOPTR(lb->int_elems[proc]),
					TOPTR(lb->bor_elems[proc]),
					proc) < 0)
	    {
	      Gen_Error(0, "fatal: failed to output element map");
	      return 0;
	    }

	  /*
	   * Build a nodal communication map from the list of border nodes
	   * and their associated processors and side IDs.
	   */
	  size_t nsize = 0;
	  for(size_t cnt=0; cnt < lb->bor_nodes[proc].size(); cnt++)
	    nsize += lb->born_procs[proc][cnt].size();

	  if (nsize > 0) {
	    std::vector<INT> n_cmap_nodes(nsize);
	    std::vector<INT> n_cmap_procs(nsize);

	    size_t cnt3 = 0;
	    for(size_t cnt=0; cnt < lb->bor_nodes[proc].size(); cnt++) {
	      for(size_t cnt2=0; cnt2 < lb->born_procs[proc][cnt].size(); cnt2++) {
		n_cmap_nodes[cnt3]   = lb->bor_nodes[proc][cnt];
		n_cmap_procs[cnt3++] = lb->born_procs[proc][cnt][cnt2];
	      }
	    }

	    /*
	     * Reorder the nodal communication maps so that they are ordered
	     * by processor and then by global ID.
	     */
	    /* This is a 2-key sort */
	    qsort2(TOPTR(n_cmap_procs), TOPTR(n_cmap_nodes), cnt3);

	    /* Output the nodal communication map */
	    if(ex_put_node_cmap(exoid, 1, TOPTR(n_cmap_nodes), TOPTR(n_cmap_procs), proc) < 0) {
	      Gen_Error(0, "fatal: unable to output nodal communication map");
	      return 0;
	    }
	  } /* End "if (nsize > 0)" */

	    /* Output the elemental communication map */
	  if(!lb->e_cmap_elems[proc].empty()) {
	    if(ex_put_elem_cmap(exoid, 1,
				TOPTR(lb->e_cmap_elems[proc]),
				TOPTR(lb->e_cmap_sides[proc]),
				TOPTR(lb->e_cmap_procs[proc]), proc) < 0)
	      {
		Gen_Error(0, "fatal: unable to output elemental communication map");
		return 0;
	      }
	  }

	} /* End "for(proc=0; proc < machine->num_procs; proc++)" */

    }
  return 1;
} /*------------------------End write_nemesis()------------------------------*/
Пример #7
0
int write_vis(std::string &nemI_out_file,
	      std::string &exoII_inp_file,
	      Machine_Description* machine,
	      Problem_Description* prob,
	      Mesh_Description<INT>* mesh,
	      LB_Description<INT>* lb)
{
  int    exid_vis, exid_inp;

  char  title[MAX_LINE_LENGTH+1];
  const char   *coord_names[] = {"X", "Y", "Z"};

  /*-----------------------------Execution Begins------------------------------*/

  /* Generate the file name for the visualization file */
  std::string vis_file_name = remove_extension(nemI_out_file);
  vis_file_name += "-vis.exoII";

  /* Generate the title for the file */
  strcpy(title, UTIL_NAME);
  strcat(title, " ");
  strcat(title, ELB_VERSION);
  strcat(title, " load balance visualization file");

  /*
   * If the vis technique is to be by element block then calculate the
   * number of element blocks.
   */
  int    vis_nelem_blks;
  if(prob->type == ELEMENTAL)
    vis_nelem_blks = machine->num_procs;
  else
    vis_nelem_blks = machine->num_procs + 1;

  /* Create the ExodusII file */
  std::cout << "Outputting load balance visualization file " << vis_file_name.c_str() << "\n";
  int cpu_ws = 0;
  int io_ws = 0;
  int mode = EX_CLOBBER;
  if (prob->int64db|prob->int64api) {
    mode |= EX_NETCDF4|EX_NOCLASSIC|prob->int64db|prob->int64api;
  }
  if((exid_vis=ex_create(vis_file_name.c_str(), mode, &cpu_ws, &io_ws)) < 0) {
    Gen_Error(0, "fatal: unable to create visualization output file");
    return 0;
  }
  ON_BLOCK_EXIT(ex_close, exid_vis);

  /*
   * Open the original input ExodusII file, read the values for the
   * element blocks and output them to the visualization file.
   */
  int icpu_ws=0;
  int iio_ws=0;
  float vers=0.0;
  mode = EX_READ | prob->int64api;
  if((exid_inp=ex_open(exoII_inp_file.c_str(), mode, &icpu_ws, &iio_ws, &vers)) < 0) {
    Gen_Error(0, "fatal: unable to open input ExodusII file");
    return 0;
  }
  ON_BLOCK_EXIT(ex_close, exid_inp);
  
  char **elem_type  = (char**)array_alloc(2, mesh->num_el_blks, MAX_STR_LENGTH+1,
					  sizeof(char));
  if(!elem_type) {
    Gen_Error(0, "fatal: insufficient memory");
    return 0;
  }
  ON_BLOCK_EXIT(free, elem_type);

  std::vector<INT> el_blk_ids(mesh->num_el_blks);
  std::vector<INT> el_cnt_blk(mesh->num_el_blks);
  std::vector<INT> node_pel_blk(mesh->num_el_blks);
  std::vector<INT> nattr_el_blk(mesh->num_el_blks);

  if(ex_get_elem_blk_ids(exid_inp, TOPTR(el_blk_ids)) < 0) {
    Gen_Error(0, "fatal: unable to get element block IDs");
    return 0;
  }

  int acc_vis = ELB_TRUE; // Output a different element block per processor
  if (prob->vis_out == 2)
    acc_vis = ELB_FALSE; // Output a nodal/element variable showing processor

  size_t nsize = 0;

  /*
   * Find out if the mesh consists of mixed elements. If not then
   * element blocks will be used to visualize the partitioning. Otherwise
   * nodal/element results will be used.
   */
  for(size_t ecnt=0; ecnt < mesh->num_el_blks; ecnt++) {
    if(ex_get_elem_block(exid_inp, el_blk_ids[ecnt], elem_type[ecnt],
			 &el_cnt_blk[ecnt], &node_pel_blk[ecnt],
			 &nattr_el_blk[ecnt]) < 0) {
      Gen_Error(0, "fatal: unable to get element block parameters");
      return 0;
    }

    nsize += el_cnt_blk[ecnt]*node_pel_blk[ecnt];

    if(strcmp(elem_type[0], elem_type[ecnt]) == 0) {
      if(node_pel_blk[0] != node_pel_blk[ecnt])
	acc_vis = ELB_FALSE;
    }
    else
      acc_vis = ELB_FALSE;
  }

  if(acc_vis == ELB_TRUE) {
    /* Output the initial information */
    if(ex_put_init(exid_vis, title, mesh->num_dims, mesh->num_nodes,
		   mesh->num_elems, vis_nelem_blks, 0, 0) < 0) {
      Gen_Error(0, "fatal: unable to output initial params to vis file");
      return 0;
    }
	
    /* Output the nodal coordinates */
    float *xptr = nullptr;
    float *yptr = nullptr;
    float *zptr = nullptr;
    switch(mesh->num_dims) {
    case 3:
      zptr = (mesh->coords) + 2*mesh->num_nodes;
      /* FALLTHRU */
    case 2:
      yptr = (mesh->coords) + mesh->num_nodes;
      /* FALLTHRU */
    case 1:
      xptr = mesh->coords;
    }
    if(ex_put_coord(exid_vis, xptr, yptr, zptr) < 0) {
      Gen_Error(0, "fatal: unable to output coords to vis file");
      return 0;
    }
	
    if(ex_put_coord_names(exid_vis, (char**)coord_names) < 0) {
      Gen_Error(0, "fatal: unable to output coordinate names");
      return 0;
    }

    std::vector<INT> elem_block(mesh->num_elems);
    std::vector<INT> elem_map(mesh->num_elems);
    std::vector<INT> tmp_connect(nsize);
    for(size_t ecnt=0; ecnt < mesh->num_elems; ecnt++) {
      elem_map[ecnt] = ecnt+1;
      if(prob->type == ELEMENTAL)
	elem_block[ecnt] = lb->vertex2proc[ecnt];
      else {
	int proc   = lb->vertex2proc[mesh->connect[ecnt][0]];
	int nnodes = get_elem_info(NNODES, mesh->elem_type[ecnt]);
	elem_block[ecnt] = proc;
	for(int ncnt=1; ncnt < nnodes; ncnt++) {
	  if(lb->vertex2proc[mesh->connect[ecnt][ncnt]] != proc) {
	    elem_block[ecnt] = machine->num_procs;
	    break;
	  }
	}
      }
    }

    int ccnt = 0;
    std::vector<INT> vis_el_blk_ptr(vis_nelem_blks+1);
    for(INT bcnt=0; bcnt < vis_nelem_blks; bcnt++) {
      vis_el_blk_ptr[bcnt] = ccnt;
      int pos = 0;
      int old_pos = 0;
      INT* el_ptr = TOPTR(elem_block);
      size_t ecnt   = mesh->num_elems;
      while(pos != -1) {
	pos = in_list(bcnt, ecnt, el_ptr);
	if(pos != -1) {
	  old_pos += pos + 1;
	  ecnt     = mesh->num_elems - old_pos;
	  el_ptr   = TOPTR(elem_block) + old_pos;
	  int nnodes = get_elem_info(NNODES, mesh->elem_type[old_pos-1]);
	  for(int ncnt=0; ncnt < nnodes; ncnt++)
	    tmp_connect[ccnt++] = mesh->connect[old_pos-1][ncnt] + 1;
	}
      }
    }
    vis_el_blk_ptr[vis_nelem_blks] = ccnt;
	
    /* Output the element map */
    if(ex_put_map(exid_vis, TOPTR(elem_map)) < 0) {
      Gen_Error(0, "fatal: unable to output element number map");
      return 0;
    }
	
    /* Output the visualization element blocks */
    for(int bcnt=0; bcnt < vis_nelem_blks; bcnt++) {
      /*
       * Note this assumes all the blocks contain the same type
       * element.
       */
      int ecnt = (vis_el_blk_ptr[bcnt+1]-vis_el_blk_ptr[bcnt])/node_pel_blk[0];
      if(ex_put_elem_block(exid_vis, bcnt+1, elem_type[0],
			   ecnt, node_pel_blk[0], 0) < 0) {
	Gen_Error(0, "fatal: unable to output element block params");
	return 0;
      }
	  
      /* Output the connectivity */
      if(ex_put_elem_conn(exid_vis, bcnt+1,
			  &tmp_connect[vis_el_blk_ptr[bcnt]]) < 0) {
	Gen_Error(0, "fatal: unable to output element connectivity");
	return 0;
      }
    }
  }

  else {	/* For nodal/element results visualization of the partioning. */
    // Copy the mesh portion to the vis file.
    ex_copy(exid_inp, exid_vis);

    /* Set up the file for nodal/element results */
    float time_val = 0.0;
    if(ex_put_time(exid_vis, 1, &time_val) < 0) {
      Gen_Error(0, "fatal: unable to output time to vis file");
      return 0;
    }

    const char  *var_names[] = {"proc"};
    if(prob->type == NODAL) {
      /* Allocate memory for the nodal values */
      std::vector<float> proc_vals(mesh->num_nodes);

      if(ex_put_variable_param(exid_vis, EX_NODAL, 1) < 0) {
	Gen_Error(0, "fatal: unable to output var params to vis file");
	return 0;
      }

      if(ex_put_variable_names(exid_vis, EX_NODAL, 1, (char**)var_names) < 0) {
	Gen_Error(0, "fatal: unable to output variable name");
	return 0;
      }

      /* Do some problem specific assignment */
      for(size_t ncnt=0; ncnt < mesh->num_nodes; ncnt++)
	proc_vals[ncnt] = lb->vertex2proc[ncnt];

      for(int pcnt=0; pcnt < machine->num_procs; pcnt++) {
	for(auto & elem : lb->bor_nodes[pcnt])
	  proc_vals[elem] = machine->num_procs + 1;
      }

      /* Output the nodal variables */
      if(ex_put_nodal_var(exid_vis, 1, 1, mesh->num_nodes, TOPTR(proc_vals)) < 0) {
	Gen_Error(0, "fatal: unable to output nodal variables");
	return 0;
      }
    }
    else if(prob->type == ELEMENTAL) {
      /* Allocate memory for the element values */
      std::vector<float> proc_vals(mesh->num_elems);

      if(ex_put_variable_param(exid_vis, EX_ELEM_BLOCK, 1) < 0) {
	Gen_Error(0, "fatal: unable to output var params to vis file");
	return 0;
      }

      if(ex_put_variable_names(exid_vis, EX_ELEM_BLOCK, 1, (char**)var_names) < 0) {
	Gen_Error(0, "fatal: unable to output variable name");
	return 0;
      }

      /* Do some problem specific assignment */
      for(int proc=0; proc < machine->num_procs; proc++) {
	for (size_t e = 0; e < lb->int_elems[proc].size(); e++) {
	  size_t ecnt = lb->int_elems[proc][e];
	  proc_vals[ecnt] = proc;
	}

	for (size_t e = 0; e < lb->bor_elems[proc].size(); e++) {
	  size_t ecnt = lb->bor_elems[proc][e];
	  proc_vals[ecnt] = proc;
	}
      }

      /* Output the element variables */
      size_t offset = 0;
      for (size_t i=0; i < mesh->num_el_blks; i++) {
	if(ex_put_var(exid_vis, 1, EX_ELEM_BLOCK, 1, el_blk_ids[i],
		      el_cnt_blk[i], &proc_vals[offset]) < 0) {
	  Gen_Error(0, "fatal: unable to output nodal variables");
	  return 0;
	}
	offset += el_cnt_blk[i];
      }
    }
  }
  return 1;
} /*---------------------------End write_vis()-------------------------------*/
Пример #8
0
int read_exo_weights(Problem_Description* prob, Weight_Description<INT>* weight)
{
  int    exoid, cpu_ws=0, io_ws=0;
  int    neblks;
  float  version, minval = 1.0f;
  char elem_type[MAX_STR_LENGTH+1];
  char ctemp[1024];
/*---------------------------Execution Begins--------------------------------*/

  /* Open the ExodusII file containing the weights */
  int mode = EX_READ | prob->int64api;
  if((exoid=ex_open(weight->exo_filename.c_str(), mode, &cpu_ws, &io_ws,
                    &version)) < 0)
  {
    sprintf(ctemp, "fatal: could not open ExodusII file %s",
            weight->exo_filename.c_str());
    Gen_Error(0, ctemp);
    return 0;
  }

  std::vector<float> values(weight->nvals);
  if(prob->type == NODAL)
  {
    size_t tmp_nodes = ex_inquire_int(exoid, EX_INQ_NODES);
    /* check to make sure the sizes agree */
    if ((size_t)weight->nvals != tmp_nodes) {
      Gen_Error(0, "fatal: different number of nodes in mesh and weight files");
      ex_close(exoid);
      return 0;
    }

    weight->ow.resize(weight->nvals);
    /* Read in the nodal values */
    if(ex_get_nodal_var(exoid, weight->exo_tindx, weight->exo_vindx,
                        weight->nvals, TOPTR(values)) < 0)
    {
      Gen_Error(0, "fatal: unable to read nodal values");
      ex_close(exoid);
      return 0;
    }
  }
  else
  {
    size_t tmp_elem = ex_inquire_int(exoid, EX_INQ_ELEM);
    /* check to make sure the sizes agree */
    if ((size_t)weight->nvals != tmp_elem) {
      Gen_Error(0, "fatal: different number of elems in mesh and weight files");
      ex_close(exoid);
      return 0;
    }

    /* Get the number of element blocks */
    neblks = ex_inquire_int(exoid, EX_INQ_ELEM_BLK);
    std::vector<INT> eblk_ids(neblks);
    std::vector<INT> eblk_ecnts(neblks);

    if(ex_get_ids(exoid, EX_ELEM_BLOCK, &eblk_ids[0]) < 0)
    {
      Gen_Error(0, "fatal: unable to get element block IDs");
      ex_close(exoid);
      return 0;
    }

    /* Get the count of elements in each element block */
    for(int cnt=0; cnt < neblks; cnt++) {
      INT dum1, dum2;
      if(ex_get_elem_block(exoid, eblk_ids[cnt], elem_type,
                           &(eblk_ecnts[cnt]), &dum1, &dum2) < 0)
      {
        Gen_Error(0, "fatal: unable to get element block");
        ex_close(exoid);
        return 0;
      }
    }

    /* Get the element variables */
    size_t offset = 0;
    for(int cnt=0; cnt < neblks; cnt++)
    {
      if(ex_get_elem_var(exoid, weight->exo_tindx, weight->exo_vindx,
                         eblk_ids[cnt], eblk_ecnts[cnt], &(values[offset])) < 0)
      {
        Gen_Error(0, "fatal: unable to get element variable");
        ex_close(exoid);
        return 0;
      }
      offset += eblk_ecnts[cnt];
    }
  }

  /* Close the ExodusII weighting file */
  if(ex_close(exoid) < 0)
  {
    sprintf(ctemp, "warning: failed to close ExodusII file %s",
            weight->exo_filename.c_str());
    Gen_Error(0, ctemp);
  }

  /* now I need to translate the values to positive integers */

  /* first find the minimum value */
  minval = *std::min_element(values.begin(), values.end());

  /* now translate the values to be greater than 1 and convert to ints */
  for (int cnt=0; cnt < weight->nvals; cnt++) {
    values[cnt] += 1.0 - minval;
    weight->vertices[cnt] = roundfloat(values[cnt]);
  }
  return 1;
} /*------------------------End read_exo_weights()----------------------*/
Пример #9
0
int NemSpread<T,INT>::read_var_param (int exoid, int max_name_length)
{
    const char  *yo="read_var_param";

    /* Get the number of time indices contained in the file */
    int ret_int = ex_inquire_int(exoid, EX_INQ_TIME);

    /* see if the user want to get all of the time indices */
    if (Restart_Info.Num_Times == -1) {

        Restart_Info.Num_Times = ret_int;

        if (ret_int > 0) {
            /* allocate array space */
            Restart_Info.Time_Idx.resize(Restart_Info.Num_Times);

            for (int cnt = 0; cnt < Restart_Info.Num_Times; cnt++)
                Restart_Info.Time_Idx[cnt] = cnt + 1;
        }
    }
    else {
        /* Check to see if the requested indeces are valid */
        for (int cnt = 0; cnt < Restart_Info.Num_Times; cnt++) {

            /* if the user wants the last time, then set it */
            if (Restart_Info.Time_Idx[cnt] == 0)
                Restart_Info.Time_Idx[cnt] = ret_int;

            if (Restart_Info.Time_Idx[cnt] > ret_int) {
                fprintf(stderr, "%s: Requested time index, %d, out of range.\n",
                        yo, Restart_Info.Time_Idx[cnt]);
                fprintf(stderr, "%s: Valid time indices in %s are from 1 to %d.\n",
                        yo, Exo_Res_File, ret_int);
                return -1;
            }

        }
    }

    /* if there are not any time steps, then return here without an error */
    if (Restart_Info.Num_Times == 0) {
        Restart_Info.Flag = 0;
        Restart_Info.NVar_Glob = 0;
        Restart_Info.NVar_Node = 0;
        Restart_Info.NVar_Elem = 0;
        return 0;
    }


    /***************** Global Variables ********************/
    if (ex_get_variable_param(exoid, EX_GLOBAL, &(Restart_Info.NVar_Glob)) < 0) {
        fprintf(stderr, "%s: Could not get global variable parameter from file\n",
                yo);
        return -1;
    }

    /* allocate space for the global variable names */
    if (Restart_Info.NVar_Glob > 0) {
        Restart_Info.GV_Name = (char **) array_alloc(__FILE__, __LINE__, 2,
                               Restart_Info.NVar_Glob,
                               max_name_length+1,
                               sizeof(char));

        /* get the global variable names */
        if (ex_get_variable_names(exoid, EX_GLOBAL, Restart_Info.NVar_Glob,
                                  Restart_Info.GV_Name) < 0) {
            fprintf(stderr, "%s: Could not get global variable names from file\n",
                    yo);
            return -1;
        }
    }

    /***************** Elemental Variables ********************/
    if (ex_get_variable_param(exoid, EX_ELEM_BLOCK, &(Restart_Info.NVar_Elem)) < 0) {
        fprintf(stderr, "%s: Could not get elemental variable param from file\n",
                yo);
        return -1;
    }

    /* allocate space for the elemental variable names */
    if (Restart_Info.NVar_Elem > 0) {
        Restart_Info.EV_Name = (char **) array_alloc(__FILE__, __LINE__, 2,
                               Restart_Info.NVar_Elem,
                               max_name_length+1,
                               sizeof(char));

        /* get the elemental variable names */
        if (ex_get_variable_names(exoid, EX_ELEM_BLOCK, Restart_Info.NVar_Elem,
                                  Restart_Info.EV_Name) < 0) {
            fprintf(stderr, "%s: Could not get elemental variable names from file\n",
                    yo);
            return -1;
        }

        /* and get the truth table */
        Restart_Info.GElem_TT.resize(globals.Num_Elem_Blk * Restart_Info.NVar_Elem);

        check_exodus_error(ex_get_truth_table(exoid, EX_ELEM_BLOCK,
                                              globals.Num_Elem_Blk,
                                              Restart_Info.NVar_Elem,
                                              TOPTR(Restart_Info.GElem_TT)),
                           "ex_get_truth_table");
    }

    /******************* Nodal Variables **********************/
    if (ex_get_variable_param(exoid, EX_NODAL, &(Restart_Info.NVar_Node)) < 0) {
        fprintf(stderr, "%s: Could not get nodal variable param from file\n",
                yo);
        return -1;
    }

    /* allocate space for the nodal variable names */
    if (Restart_Info.NVar_Node > 0) {
        Restart_Info.NV_Name = (char **) array_alloc(__FILE__, __LINE__, 2,
                               Restart_Info.NVar_Node,
                               max_name_length+1,
                               sizeof(char));

        /* get the nodal variable names */
        if (ex_get_variable_names(exoid, EX_NODAL, Restart_Info.NVar_Node,
                                  Restart_Info.NV_Name) < 0) {
            fprintf(stderr, "%s: Could not get nodal variable names from file\n",
                    yo);
            return -1;
        }
    }

    /******************* Sideset Variables **********************/
    if (ex_get_variable_param(exoid, EX_SIDE_SET, &(Restart_Info.NVar_Sset)) < 0) {
        fprintf(stderr, "%s: Could not get sideset variable param from file\n",
                yo);
        return -1;
    }

    /* allocate space for the variable names */
    if (Restart_Info.NVar_Sset > 0) {
        Restart_Info.SSV_Name = (char **) array_alloc(__FILE__, __LINE__, 2,
                                Restart_Info.NVar_Sset,
                                max_name_length+1,
                                sizeof(char));

        /* get the variable names */
        if (ex_get_variable_names(exoid, EX_SIDE_SET, Restart_Info.NVar_Sset,
                                  Restart_Info.SSV_Name) < 0) {
            fprintf(stderr, "%s: Could not get sideset variable names from file\n",
                    yo);
            return -1;
        }

        /* and get the truth table */
        Restart_Info.GSset_TT.resize(globals.Num_Side_Set * Restart_Info.NVar_Sset);

        check_exodus_error(ex_get_truth_table(exoid, EX_SIDE_SET,
                                              globals.Num_Side_Set,
                                              Restart_Info.NVar_Sset,
                                              TOPTR(Restart_Info.GSset_TT)),
                           "ex_get_truth_table");
    }

    /******************* Nodeset Variables **********************/
    if (ex_get_variable_param(exoid, EX_NODE_SET, &(Restart_Info.NVar_Nset)) < 0) {
        fprintf(stderr, "%s: Could not get nodeset variable param from file\n",
                yo);
        return -1;
    }

    /* allocate space for the variable names */
    if (Restart_Info.NVar_Nset > 0) {
        Restart_Info.NSV_Name = (char **) array_alloc(__FILE__, __LINE__, 2,
                                Restart_Info.NVar_Nset,
                                max_name_length+1,
                                sizeof(char));

        /* get the variable names */
        if (ex_get_variable_names(exoid, EX_NODE_SET, Restart_Info.NVar_Nset,
                                  Restart_Info.NSV_Name) < 0) {
            fprintf(stderr, "%s: Could not get nodeset variable names from file\n",
                    yo);
            return -1;
        }

        /* and get the truth table */
        Restart_Info.GNset_TT.resize(globals.Num_Node_Set * Restart_Info.NVar_Nset);

        check_exodus_error(ex_get_truth_table(exoid, EX_NODE_SET,
                                              globals.Num_Node_Set,
                                              Restart_Info.NVar_Nset,
                                              TOPTR(Restart_Info.GNset_TT)),
                           "ex_get_var_tab");
    }


#ifdef DEBUG
    if (Debug_Flag >= 2) {
        printf("\n\nRestart Parameters:\n");
        printf("\tNumber of time indices: %d\n", Restart_Info.Num_Times);
        for (int cnt = 0; cnt < Restart_Info.Num_Times; cnt++)
            printf("\t\tTime index: %d\n", Restart_Info.Time_Idx[cnt]);
        printf("\tNumber of global variables: %d\n", Restart_Info.NVar_Glob);
        for (int cnt = 0; cnt < Restart_Info.NVar_Glob; cnt++)
            printf("\t\tGlobal variable %d: %s\n", (cnt+1),
                   Restart_Info.GV_Name[cnt]);
        printf("\tNumber of elental variables: %d\n", Restart_Info.NVar_Elem);
        for (int cnt = 0; cnt < Restart_Info.NVar_Elem; cnt++)
            printf("\t\tElemental variable %d: %s\n", (cnt+1),
                   Restart_Info.EV_Name[cnt]);
        printf("\tNumber of nodal variables: %d\n", Restart_Info.NVar_Node);
        for (int cnt = 0; cnt < Restart_Info.NVar_Node; cnt++)
            printf("\t\tNodal variable %d: %s\n", (cnt+1), Restart_Info.NV_Name[cnt]);
    }
#endif

    return 0;

}
Пример #10
0
void NemSpread<T,INT>::read_restart_data ()

/* Function which reads the restart variable data from the EXODUS II
 * database which contains the results information. Then distribute
 * it to the processors, and write it to the parallel exodus files.
 *
 *----------------------------------------------------------------------------
 *
 * Functions called:
 *
 * read_vars -- function which reads the variable values from the restart
 *              file, and then distributes them to the processors
 *
 * write_var_timestep -- function which writes out the variables for a
 *                       to a parallel ExodusII file.
 *
 *----------------------------------------------------------------------------
 */

{
    const char  *yo="read_restart_data";

    /* need to get the element block ids and counts */
    std::vector<INT> eb_ids_global(globals.Num_Elem_Blk);
    std::vector<INT> eb_cnts_global(globals.Num_Elem_Blk);
    std::vector<INT> ss_ids_global(globals.Num_Side_Set);
    std::vector<INT> ss_cnts_global(globals.Num_Side_Set);
    std::vector<INT> ns_ids_global(globals.Num_Node_Set);
    std::vector<INT> ns_cnts_global(globals.Num_Node_Set);

    INT ***eb_map_ptr = NULL, **eb_cnts_local = NULL;
    int    exoid=0, *par_exoid = NULL;

    float  vers;
    char   cTemp[512];

    /* computing precision should be the same as the database precision
     *
     * EXCEPTION: if the io_ws is smaller than the machine precision,
     * ie - database with io_ws == 4 on a Cray (sizeof(float) == 8),
     * then the cpu_ws must be the machine precision.
     */
    int cpu_ws;
    if (io_ws < (int)sizeof(float)) cpu_ws = sizeof(float);
    else                            cpu_ws = io_ws;

    /* Open the ExodusII file */
    {
        cpu_ws = io_ws;
        int mode = EX_READ | int64api;
        if ((exoid=ex_open(Exo_Res_File, mode, &cpu_ws, &io_ws, &vers)) < 0) {
            fprintf(stderr, "%s: Could not open file %s for restart info\n",
                    yo, Exo_Res_File);
            exit(1);
        }
    }

    /* allocate space for the global variables */
    Restart_Info.Glob_Vals.resize(Restart_Info.NVar_Glob);

    if (Restart_Info.NVar_Elem > 0 ) {

        /* allocate storage space */
        Restart_Info.Elem_Vals.resize(Proc_Info[2]);

        /* now allocate storage for the values */
        for (int iproc = 0; iproc <Proc_Info[2]; iproc++) {
            size_t array_size = Restart_Info.NVar_Elem *
                                (globals.Num_Internal_Elems[iproc] + globals.Num_Border_Elems[iproc]);
            Restart_Info.Elem_Vals[iproc].resize(array_size);
        }

        /*
         * at this point, I need to broadcast the global element block ids
         * and counts to the processors. I know that this is redundant data
         * since they will all receive this information in read_mesh, but
         * the variables which contain that information are static in
         * el_exoII_io.c, and cannot be used here. So, take a second and
         * broadcast all of this out.
         *
         * I want to do this here so that it is done only once no matter
         * how many time steps are retrieved
         */

        /* Get the Element Block IDs from the input file */
        if (ex_get_ids (exoid, EX_ELEM_BLOCK, TOPTR(eb_ids_global)) < 0)
        {
            fprintf(stderr, "%s: unable to get element block IDs", yo);
            exit(1);
        }

        /* Get the count of elements in each element block */
        for (int cnt = 0; cnt < globals.Num_Elem_Blk; cnt++) {
            if (ex_get_block(exoid, EX_ELEM_BLOCK, eb_ids_global[cnt], cTemp,
                             &(eb_cnts_global[cnt]), NULL, NULL, NULL, NULL) < 0) {
                fprintf(stderr, "%s: unable to get element count for block id "ST_ZU"",
                        yo, (size_t)eb_ids_global[cnt]);
                exit(1);
            }
        }

        /*
         * in order to speed up finding matches in the global element
         * number map, set up an array of pointers to the start of
         * each element block's global element number map. That way
         * only entries for the current element block have to be searched
         */
        eb_map_ptr = (INT ***) array_alloc (__FILE__, __LINE__, 2,Proc_Info[2],
                                            globals.Num_Elem_Blk, sizeof(INT *));
        if (!eb_map_ptr) {
            fprintf(stderr, "[%s]: ERROR, insufficient memory!\n", yo);
            exit(1);
        }
        eb_cnts_local = (INT **) array_alloc (__FILE__, __LINE__, 2,Proc_Info[2],
                                              globals.Num_Elem_Blk, sizeof(INT));
        if (!eb_cnts_local) {
            fprintf(stderr, "[%s]: ERROR, insufficient memory!\n", yo);
            exit(1);
        }

        /*
         * for now, assume that element blocks have been
         * stored in the same order as the global blocks
         */
        for (int iproc = 0; iproc <Proc_Info[2]; iproc++) {
            int    ifound = 0;
            size_t offset = 0;
            int    ilocal;
            for (int cnt = 0; cnt < globals.Num_Elem_Blk; cnt++) {
                for (ilocal = ifound; ilocal < globals.Proc_Num_Elem_Blk[iproc]; ilocal++) {
                    if (globals.Proc_Elem_Blk_Ids[iproc][ilocal] == eb_ids_global[cnt])
                        break;
                }

                if (ilocal < globals.Proc_Num_Elem_Blk[iproc]) {
                    eb_map_ptr[iproc][cnt] = &globals.GElems[iproc][offset];
                    eb_cnts_local[iproc][cnt] = globals.Proc_Num_Elem_In_Blk[iproc][ilocal];
                    offset += globals.Proc_Num_Elem_In_Blk[iproc][ilocal];
                    ifound = ilocal; /* don't search the same part of the list over */
                }
                else {
                    eb_map_ptr[iproc][cnt] = NULL;
                    eb_cnts_local[iproc][cnt] = 0;
                }
            }
        }

    } /* End: "if (Restart_Info.NVar_Elem > 0 )" */

    if (Restart_Info.NVar_Node > 0 ) {
        /* allocate storage space */
        Restart_Info.Node_Vals.resize(Proc_Info[2]);

        /* now allocate storage for the values */
        for (int iproc = 0; iproc <Proc_Info[2]; iproc++) {
            size_t array_size = Restart_Info.NVar_Node * (globals.Num_Internal_Nodes[iproc] +
                                globals.Num_Border_Nodes[iproc] + globals.Num_External_Nodes[iproc]);
            Restart_Info.Node_Vals[iproc].resize(array_size);
        }
    }

    if (Restart_Info.NVar_Sset > 0 ) {

        /* allocate storage space */
        Restart_Info.Sset_Vals.resize(Proc_Info[2]);

        /* now allocate storage for the values */
        for (int iproc = 0; iproc <Proc_Info[2]; iproc++) {
            size_t array_size = Restart_Info.NVar_Sset * globals.Proc_SS_Elem_List_Length[iproc];

            Restart_Info.Sset_Vals[iproc].resize(array_size);
        }

        /*
         * at this point, I need to broadcast the ids and counts to the
         * processors. I know that this is redundant data since they will
         * all receive this information in read_mesh, but the variables
         * which contain that information are static in el_exoII_io.c, and
         * cannot be used here. So, take a second and broadcast all of
         * this out.
         *
         * I want to do this here so that it is done only once no matter
         * how many time steps are retrieved
         */

        /* Get the Sideset IDs from the input file */
        if (ex_get_ids (exoid, EX_SIDE_SET, TOPTR(ss_ids_global)) < 0) {
            fprintf(stderr, "%s: unable to get sideset IDs", yo);
            exit(1);
        }

        /* Get the count of elements in each sideset */
        for (int cnt = 0; cnt < globals.Num_Side_Set; cnt++) {
            if (ex_get_set_param(exoid, EX_SIDE_SET,
                                 ss_ids_global[cnt],
                                 &(ss_cnts_global[cnt]), NULL) < 0) {
                fprintf(stderr, "%s: unable to get element count for sideset id "ST_ZU"",
                        yo, (size_t)ss_ids_global[cnt]);
                exit(1);
            }
        }
    } /* End: "if (Restart_Info.NVar_Sset > 0 )" */


    if (Restart_Info.NVar_Nset > 0 ) {

        /* allocate storage space */
        Restart_Info.Nset_Vals.resize(Proc_Info[2]);

        /* now allocate storage for the values */
        for (int iproc = 0; iproc <Proc_Info[2]; iproc++) {
            size_t array_size = Restart_Info.NVar_Nset * globals.Proc_NS_List_Length[iproc];
            Restart_Info.Nset_Vals[iproc].resize(array_size);
        }

        /*
         * at this point, I need to broadcast the ids and counts to the
         * processors. I know that this is redundant data since they will
         * all receive this information in read_mesh, but the variables
         * which contain that information are static in el_exoII_io.c, and
         * cannot be used here. So, take a second and broadcast all of
         * this out.
         *
         * I want to do this here so that it is done only once no matter
         * how many time steps are retrieved
         */

        /* Get the Nodeset IDs from the input file */
        if (ex_get_ids (exoid, EX_NODE_SET, TOPTR(ns_ids_global)) < 0) {
            fprintf(stderr, "%s: unable to get nodeset IDs", yo);
            exit(1);
        }

        /* Get the count of elements in each nodeset */
        for (int cnt = 0; cnt < globals.Num_Node_Set; cnt++) {
            if (ex_get_set_param(exoid, EX_NODE_SET,
                                 ns_ids_global[cnt],
                                 &(ns_cnts_global[cnt]), NULL) < 0) {
                fprintf(stderr, "%s: unable to get element count for nodeset id "ST_ZU"",
                        yo, (size_t)ns_ids_global[cnt]);
                exit(1);
            }
        }
    } /* End: "if (Restart_Info.NVar_Nset > 0 )" */


    /*
     * NOTE: A possible place to speed this up would be to
     * get the global node and element lists here, and broadcast
     * them out only once.
     */

    par_exoid = (int*)malloc(Proc_Info[2] * sizeof(int));
    if(!par_exoid) {
        fprintf(stderr, "[%s]: ERROR, insufficient memory!\n",
                yo);
        exit(1);
    }

    /* See if any '/' in the name.  IF present, isolate the basename of the file */
    if (strrchr(PIO_Info.Scalar_LB_File_Name, '/') != NULL) {
        /* There is a path separator.  Get the portion after the
         * separator
         */
        strcpy(cTemp, strrchr(PIO_Info.Scalar_LB_File_Name, '/')+1);
    } else {
        /* No separator; this is already just the basename... */
        strcpy(cTemp, PIO_Info.Scalar_LB_File_Name);
    }

    if (strlen(PIO_Info.Exo_Extension) == 0)
        add_fname_ext(cTemp, ".par");
    else
        add_fname_ext(cTemp, PIO_Info.Exo_Extension);

    int open_file_count = get_free_descriptor_count();
    if (open_file_count >Proc_Info[5]) {
        printf("All output files opened simultaneously.\n");
        for (int iproc=Proc_Info[4]; iproc <Proc_Info[4]+Proc_Info[5]; iproc++) {

            gen_par_filename(cTemp, Par_Nem_File_Name, Proc_Ids[iproc],
                             Proc_Info[0]);

            /* Open the parallel Exodus II file for writing */
            cpu_ws = io_ws;
            int mode = EX_WRITE | int64api | int64db;
            if ((par_exoid[iproc]=ex_open(Par_Nem_File_Name, mode, &cpu_ws,
                                          &io_ws, &vers)) < 0) {
                fprintf(stderr,"[%d] %s Could not open parallel Exodus II file: %s\n",
                        iproc, yo, Par_Nem_File_Name);
                exit(1);
            }
        }
    } else {
        printf("All output files opened one-at-a-time.\n");
    }

    /* Now loop over the number of time steps */
    for (int time_idx = 0; time_idx < Restart_Info.Num_Times; time_idx++) {

        double start_t = second ();

        /* read and distribute the variables for this time step */
        if (read_vars(exoid, Restart_Info.Time_Idx[time_idx],
                      TOPTR(eb_ids_global), TOPTR(eb_cnts_global), eb_map_ptr,
                      eb_cnts_local,
                      TOPTR(ss_ids_global), TOPTR(ss_cnts_global),
                      TOPTR(ns_ids_global), TOPTR(ns_cnts_global)) < 0) {
            fprintf(stderr, "%s: Error occured while reading variables\n",
                    yo);
            exit(1);
        }
        double end_t   = second () - start_t;
        printf ("\tTime to read  vars for timestep %d: %f (sec.)\n", (time_idx+1), end_t);

        start_t = second ();
        for (int iproc=Proc_Info[4]; iproc <Proc_Info[4]+Proc_Info[5]; iproc++) {

            if (open_file_count <Proc_Info[5]) {
                gen_par_filename(cTemp, Par_Nem_File_Name, Proc_Ids[iproc],
                                 Proc_Info[0]);

                /* Open the parallel Exodus II file for writing */
                cpu_ws = io_ws;
                int mode = EX_WRITE | int64api | int64db;
                if ((par_exoid[iproc]=ex_open(Par_Nem_File_Name, mode, &cpu_ws,
                                              &io_ws, &vers)) < 0) {
                    fprintf(stderr,"[%d] %s Could not open parallel Exodus II file: %s\n",
                            iproc, yo, Par_Nem_File_Name);
                    exit(1);
                }
            }

            /*
             * Write out the variable data for the time steps in this
             * block to each parallel file.
             */
            write_var_timestep(par_exoid[iproc], iproc, (time_idx+1),
                               TOPTR(eb_ids_global), TOPTR(ss_ids_global), TOPTR(ns_ids_global));

            if (iproc%10 == 0 || iproc ==Proc_Info[2]-1)
                printf("%d", iproc);
            else
                printf(".");

            if (open_file_count <Proc_Info[5]) {
                if (ex_close(par_exoid[iproc]) == -1) {
                    fprintf(stderr, "[%d] %s Could not close the parallel Exodus II file.\n",
                            iproc, yo);
                    exit(1);
                }
            }
        } /* End "for (iproc=0; iproc <Proc_Info[2]; iproc++)" */

        end_t   = second () - start_t;
        printf ("\n\tTime to write vars for timestep %d: %f (sec.)\n", (time_idx+1), end_t);

    }
    if (Restart_Info.NVar_Elem > 0 ) {
        safe_free((void **) &eb_map_ptr);
        safe_free((void **) &eb_cnts_local);
    }

    /* Close the restart exodus II file */
    if (ex_close(exoid) == -1) {
        fprintf(stderr, "%sCould not close the restart Exodus II file\n",
                yo);
        exit(1);
    }

    if (open_file_count >Proc_Info[5]) {
        for (int iproc=Proc_Info[4]; iproc <Proc_Info[4]+Proc_Info[5]; iproc++) {
            /* Close the parallel exodus II file */
            if (ex_close(par_exoid[iproc]) == -1) {
                fprintf(stderr, "[%d] %s Could not close the parallel Exodus II file.\n",
                        iproc, yo);
                exit(1);
            }
        }
    }
    if (par_exoid != NULL) {
        free(par_exoid);
        par_exoid = NULL;
    }
}
Пример #11
0
void Exo_Entity::internal_load_params()
{
  int name_size = ex_inquire_int(fileId, EX_INQ_MAX_READ_NAME_LENGTH);
  {
    std::vector<char> name(name_size + 1);
    ex_get_name(fileId, exodus_type(), id_, TOPTR(name));
    if (name[0] != '\0') {
      name_ = TOPTR(name);
      to_lower(name_);
    }
    else {
      name_ = short_label();
      name_ += "_";
      name_ += to_string(id_);
    }
  }
  numVars = get_num_variables(fileId, exodus_type(), label());
  if (numVars) {
    results_ = new double *[numVars];
    SMART_ASSERT(results_ != nullptr);
    for (int i    = 0; i < numVars; ++i)
      results_[i] = nullptr;
  }

  numAttr = get_num_attributes(fileId, exodus_type(), id_, label());
  if (numAttr) {
    attributes_.resize(numAttr);

    char **names = get_name_array(numAttr, name_size);
    int    err   = ex_get_attr_names(fileId, exodus_type(), id_, names);
    if (err < 0) {
      ERROR("ExoII_Read::Get_Init_Data(): Failed to get " << label()
                                                          << " attribute names!  Aborting...\n");
      exit(1);
    }

    for (int vg = 0; vg < numAttr; ++vg) {
      SMART_ASSERT(names[vg] != nullptr);
      if (std::strlen(names[vg]) == 0) {
        std::string name = "attribute_" + to_string(vg + 1);
        attributeNames.push_back(name);
      }
      else if ((int)std::strlen(names[vg]) > name_size) {
        std::cerr << trmclr::red << "exodiff: ERROR: " << label()
                  << " attribute names appear corrupt\n"
                  << "                A length is 0 or greater than "
                  << "name_size(" << name_size << ")\n"
                  << "                Here are the names that I received from"
                  << " a call to ex_get_attr_names(...):\n";
        for (int k = 1; k <= numAttr; ++k)
          std::cerr << "\t\t" << k << ") \"" << names[k - 1] << "\"\n";
        std::cerr << "                 Aborting...\n" << trmclr::normal;
        exit(1);
      }
      else {
        std::string n(names[vg]);
        to_lower(n);
        attributeNames.push_back(n);
      }
    }
    free_name_array(names, numAttr);
  }
}
Пример #12
0
template <typename INT> void ExoII_Read<INT>::Get_Init_Data()
{
  SMART_ASSERT(Check_State());
  SMART_ASSERT(file_id >= 0);

  // Determine max size of entity and variable names on the database
  int name_length = ex_inquire_int(file_id, EX_INQ_DB_MAX_USED_NAME_LENGTH);
  ex_set_max_name_length(file_id, name_length);

  ex_init_params info;
  info.title[0] = '\0';

  int err = ex_get_init_ext(file_id, &info);
  if (err < 0) {
    std::cout << "EXODIFF ERROR: Failed to get init data!"
              << " Error number = " << err << ".  Aborting..." << '\n';
    exit(1);
  }

  dimension       = info.num_dim;
  num_nodes       = info.num_nodes;
  num_elmts       = info.num_elem;
  num_elmt_blocks = info.num_elem_blk;
  num_node_sets   = info.num_node_sets;
  num_side_sets   = info.num_side_sets;
  title           = info.title;

  if (err > 0 && !interface.quiet_flag)
    std::cout << "EXODIFF WARNING: was issued, number = " << err << '\n';
  if (dimension < 1 || dimension > 3 || num_elmt_blocks < 0 || num_node_sets < 0 ||
      num_side_sets < 0) {
    std::cout << "EXODIFF ERROR: Init data appears corrupt:" << '\n'
              << "         dimension = " << dimension << '\n'
              << "         num_nodes = " << num_nodes << '\n'
              << "         num_elmts = " << num_elmts << '\n'
              << "         num_elmt_blocks = " << num_elmt_blocks << '\n'
              << "         num_node_sets = " << num_node_sets << '\n'
              << "         num_side_sets = " << num_side_sets << '\n'
              << " ... Aborting..." << '\n';
    exit(1);
  }

  int num_qa   = ex_inquire_int(file_id, EX_INQ_QA);
  int num_info = ex_inquire_int(file_id, EX_INQ_INFO);

  if (num_qa < 0 || num_info < 0) {
    std::cout << "EXODIFF ERROR: inquire data appears corrupt:" << '\n'
              << "         num_qa = " << num_qa << '\n'
              << "         num_info = " << num_info << '\n'
              << " ... Aborting..." << '\n';
    exit(1);
  }

  //                   Coordinate Names...

  char **coords = get_name_array(3, name_length);
  err           = ex_get_coord_names(file_id, coords);
  if (err < 0) {
    std::cout << "EXODIFF ERROR: Failed to get coordinate"
              << " names!  Aborting..." << '\n';
    exit(1);
  }

  coord_names.clear();
  for (size_t i = 0; i < dimension; ++i) {
    coord_names.push_back(coords[i]);
  }
  free_name_array(coords, 3);

  //                 Element Block Data...

  if (eblocks)
    delete[] eblocks;
  eblocks = nullptr;
  if (num_elmt_blocks > 0) {
    eblocks = new Exo_Block<INT>[num_elmt_blocks];
    SMART_ASSERT(eblocks != nullptr);
    std::vector<INT> ids(num_elmt_blocks);

    err = ex_get_ids(file_id, EX_ELEM_BLOCK, TOPTR(ids));

    if (err < 0) {
      std::cout << "EXODIFF ERROR: Failed to get element"
                << " block ids!  Aborting..." << '\n';
      exit(1);
    }

    size_t e_count = 0;
    for (size_t b = 0; b < num_elmt_blocks; ++b) {
      if (ids[b] <= EX_INVALID_ID) {
        std::cout << "EXODIFF  WARNING:  Element block Id "
                  << "for block index " << b << " is " << ids[b]
                  << " which is negative. This was returned by call to ex_get_elem_blk_ids()."
                  << '\n';
      }

      eblocks[b].initialize(file_id, ids[b]);
      e_count += eblocks[b].Size();
    }

    if (e_count != num_elmts && !interface.quiet_flag) {
      std::cout << "EXODIFF WARNING: Total number of elements " << num_elmts
                << " does not equal the sum of the number of elements "
                << "in each block " << e_count << '\n';
    }

    // Gather the attribute names (even though not all attributes are on all blocks)
    std::set<std::string> names;
    for (size_t b = 0; b < num_elmt_blocks; ++b) {
      for (int a = 0; a < eblocks[b].attr_count(); a++) {
        names.insert(eblocks[b].Get_Attribute_Name(a));
      }
    }
    elmt_atts.resize(names.size());
    std::copy(names.begin(), names.end(), elmt_atts.begin());
  }

  //                     Node & Side sets...

  if (nsets)
    delete[] nsets;
  nsets = nullptr;
  if (num_node_sets > 0) {
    nsets = new Node_Set<INT>[num_node_sets];
    SMART_ASSERT(nsets != nullptr);
    std::vector<INT> ids(num_node_sets);

    err = ex_get_ids(file_id, EX_NODE_SET, TOPTR(ids));

    if (err < 0) {
      std::cout << "EXODIFF ERROR: Failed to get "
                << "nodeset ids!  Aborting..." << '\n';
      exit(1);
    }

    for (size_t nset = 0; nset < num_node_sets; ++nset) {
      if (ids[nset] <= EX_INVALID_ID) {
        std::cout << "EXODIFF  WARNING: Nodeset Id "
                  << "for nodeset index " << nset << " is " << ids[nset]
                  << " which is negative.  This was returned by call to ex_get_ids()." << '\n';
      }

      nsets[nset].initialize(file_id, ids[nset]);
    }
  }

  if (ssets)
    delete[] ssets;
  ssets = nullptr;
  if (num_side_sets) {
    ssets = new Side_Set<INT>[num_side_sets];
    SMART_ASSERT(ssets != nullptr);
    std::vector<INT> ids(num_side_sets);

    err = ex_get_ids(file_id, EX_SIDE_SET, TOPTR(ids));

    if (err < 0) {
      std::cout << "EXODIFF ERROR: Failed to get "
                << "sideset ids!  Aborting..." << '\n';
      exit(1);
    }

    for (size_t sset = 0; sset < num_side_sets; ++sset) {
      if (ids[sset] <= EX_INVALID_ID) {
        std::cout << "EXODIFF  WARNING:  Sideset Id "
                  << "for sideset index " << sset << " is " << ids[sset]
                  << " which is negative. This was returned by call to ex_get_ids()." << '\n';
      }
      ssets[sset].initialize(file_id, ids[sset]);
    }
  }

  //  **************  RESULTS info  ***************  //

  int num_global_vars, num_nodal_vars, num_elmt_vars, num_ns_vars, num_ss_vars;

  err = ex_get_variable_param(file_id, EX_GLOBAL, &num_global_vars);
  if (err < 0) {
    std::cout << "EXODIFF ERROR: Failed to get number of"
              << " global variables!  Aborting..." << '\n';
    exit(1);
  }

  err = ex_get_variable_param(file_id, EX_NODAL, &num_nodal_vars);
  if (err < 0) {
    std::cout << "EXODIFF ERROR: Failed to get number of"
              << " nodal variables!  Aborting..." << '\n';
    exit(1);
  }

  err = ex_get_variable_param(file_id, EX_ELEM_BLOCK, &num_elmt_vars);
  if (err < 0) {
    std::cout << "EXODIFF ERROR: Failed to get number of"
              << " element variables!  Aborting..." << '\n';
    exit(1);
  }

  err = ex_get_variable_param(file_id, EX_NODE_SET, &num_ns_vars);
  if (err < 0) {
    std::cout << "EXODIFF ERROR: Failed to get number of"
              << " nodeset variables!  Aborting..." << '\n';
    exit(1);
  }

  err = ex_get_variable_param(file_id, EX_SIDE_SET, &num_ss_vars);
  if (err < 0) {
    std::cout << "EXODIFF ERROR: Failed to get number of"
              << " sideset variables!  Aborting..." << '\n';
    exit(1);
  }

  if (num_global_vars < 0 || num_nodal_vars < 0 || num_elmt_vars < 0 || num_ns_vars < 0 ||
      num_ss_vars < 0) {
    std::cout << "EXODIFF ERROR: Data appears corrupt for"
              << " number of variables !" << '\n'
              << "\tnum global vars  = " << num_global_vars << '\n'
              << "\tnum nodal vars   = " << num_nodal_vars << '\n'
              << "\tnum element vars = " << num_elmt_vars << '\n'
              << " ... Aborting..." << '\n';
    exit(1);
  }

  read_vars(file_id, EX_GLOBAL, "Global", num_global_vars, global_vars);
  read_vars(file_id, EX_NODAL, "Nodal", num_nodal_vars, nodal_vars);
  read_vars(file_id, EX_ELEM_BLOCK, "Element", num_elmt_vars, elmt_vars);
  read_vars(file_id, EX_NODE_SET, "Nodeset", num_ns_vars, ns_vars);
  read_vars(file_id, EX_SIDE_SET, "Sideset", num_ss_vars, ss_vars);

  // Times:
  num_times = ex_inquire_int(file_id, EX_INQ_TIME);
  if (num_times < 0) {
    std::cout << "EXODIFF ERROR: Number of time steps came"
              << " back negative (" << num_times << ")!  Aborting..." << '\n';
    exit(1);
  }

  if ((num_global_vars > 0 || num_nodal_vars > 0 || num_elmt_vars > 0 || num_ns_vars > 0 ||
       num_ss_vars > 0) &&
      num_times == 0) {
    std::cout << "EXODIFF Consistency error -- The database contains transient variables, but no "
                 "timesteps!"
              << '\n';
    exit(1);
  }

  if (num_times) {
    times = new double[num_times];
    SMART_ASSERT(times != nullptr);
    err = ex_get_all_times(file_id, times);
  }

  if (num_nodal_vars) {
    if (num_times == 0) {
      std::cout << "EXODIFF Consistency error--The database contains " << num_nodal_vars
                << " nodal variables, but there are no time steps defined." << '\n';
    }
    if (num_times) {
      results = new double *[num_nodal_vars];
      for (int i   = 0; i < num_nodal_vars; ++i)
        results[i] = nullptr;
    }
  }

} // End of EXODIFF
Пример #13
0
static inline fd_set *PTR(Handle<Value>v) {
    return (fd_set *)TOPTR(v);
}
Пример #14
0
int main (int argc, char *argv[])
{
  char *oname = nullptr, *dot = nullptr, *filename = nullptr;
  char str[32];

  const char* ext=EXT;

  int
    n, n1,n2,err,
    num_axes,num_blocks,
    num_side_sets,num_node_sets,num_time_steps,
    num_info_lines,num_global_vars,
    num_nodal_vars,num_element_vars,num_nodeset_vars, num_sideset_vars;

  size_t num_nodes = 0;
  size_t num_elements = 0;

  int mat_version = 73;

  /* process arguments */
  for (int j=1; j< argc; j++){
    if ( strcmp(argv[j],"-t")==0){    /* write text file (*.m) */
      del_arg(&argc,argv,j);
      textfile=1;
      j--;
      continue;
    }
    if ( strcmp(argv[j],"-h")==0){    /* write help info */
      del_arg(&argc,argv,j);
      usage();
      exit(1);
    }
    if ( strcmp(argv[j],"-d")==0){    /* write help info */
      del_arg(&argc,argv,j);
      j--;
      debug = 1;
      continue;
    }
    if ( strcmp(argv[j],"-v73")==0){    /* Version 7.3 */
      del_arg(&argc,argv,j);
      mat_version = 73;
      j--;
      continue;
    }
    // This matches the option used in matlab
    if ( (strcmp(argv[j],"-v7.3")==0) || (strcmp(argv[j],"-V7.3")==0)){    /* Version 7.3 */
      del_arg(&argc,argv,j);
      mat_version = 73;
      j--;
      continue;
    }
    if ( strcmp(argv[j],"-v5")==0){    /* Version 5 (default) */
      del_arg(&argc,argv,j);
      mat_version = 50;
      j--;
      continue;
    }
    if ( strcmp(argv[j],"-o")==0){    /* specify output file name */
      del_arg(&argc,argv,j);
      if ( argv[j] ){
        oname=(char*)calloc(strlen(argv[j])+10,sizeof(char));
        strcpy(oname,argv[j]);
        del_arg(&argc,argv,j);
        std::cout << "output file: " << oname << "\n";
      }
      else {
        std::cerr << "ERROR: Invalid output file specification.\n";
        return 2;
      }
      j--;

      continue;
    }
  }

  /* QA Info */
  printf("%s: %s, %s\n", qainfo[0], qainfo[2], qainfo[1]);

  /* usage message*/
  if (argc != 2){
    usage();
    exit(1);
  }

  /* open output file */
  if ( textfile )
    ext=".m";

  if ( !oname ){
    filename = (char*)malloc( strlen(argv[1])+10);
    strcpy(filename,argv[1]);
    dot=strrchr(filename,'.');
    if ( dot ) *dot='\0';
    strcat(filename,ext);
  }
  else {
    filename=oname;
  }

  if ( textfile ){
    m_file = fopen(filename,"w");
    if (!m_file ){
      std::cerr << "ERROR: Unable to open " << filename << "\n";
      exit(1);
    }
  }
  else {
    if (mat_version == 50) {
      mat_file = Mat_CreateVer(filename, nullptr, MAT_FT_MAT5);
    }
    else if (mat_version == 73) {
      mat_file = Mat_CreateVer(filename, nullptr, MAT_FT_MAT73);
    }

    if (mat_file == nullptr) {
      std::cerr << "ERROR: Unable to create matlab file " << filename << "\n";
      exit(1);
    }
  }

  /* word sizes */
  int cpu_word_size=sizeof(double);
  int io_word_size=0;

  /* open exodus file */
  float exo_version;
  int exo_file=ex_open(argv[1],EX_READ,&cpu_word_size,&io_word_size,&exo_version);
  if (exo_file < 0){
    std::cerr << "ERROR: Cannot open " << argv[1] << "\n";
    exit(1);
  }

  /* print */
  std::cout << "\ttranslating " << argv[1] << " to " << filename << "...\n";

  /* read database paramters */
  char *line=(char *) calloc ((MAX_LINE_LENGTH+1),sizeof(char));
  ex_get_init(exo_file,line,
              &num_axes,&num_nodes,&num_elements,&num_blocks,
              &num_node_sets,&num_side_sets);
  num_info_lines = ex_inquire_int(exo_file,EX_INQ_INFO);
  num_time_steps = ex_inquire_int(exo_file,EX_INQ_TIME);
  ex_get_variable_param(exo_file,EX_GLOBAL,&num_global_vars);
  ex_get_variable_param(exo_file,EX_NODAL,&num_nodal_vars);
  ex_get_variable_param(exo_file,EX_ELEM_BLOCK,&num_element_vars);
  ex_get_variable_param(exo_file,EX_NODE_SET,&num_nodeset_vars);
  ex_get_variable_param(exo_file,EX_SIDE_SET,&num_sideset_vars);


  /* export paramters */
  PutInt("naxes",  num_axes);
  PutInt("nnodes", num_nodes);
  PutInt("nelems", num_elements);
  PutInt("nblks",  num_blocks);
  PutInt("nnsets", num_node_sets);
  PutInt("nssets", num_side_sets);
  PutInt("nsteps", num_time_steps);
  PutInt("ngvars", num_global_vars);
  PutInt("nnvars", num_nodal_vars);
  PutInt("nevars", num_element_vars);
  PutInt("nnsvars",num_nodeset_vars);
  PutInt("nssvars",num_sideset_vars);

  /* allocate -char- scratch space*/
  int nstr2 = num_info_lines;
  nstr2 = std::max(nstr2, num_blocks);
  nstr2 = std::max(nstr2, num_node_sets);
  nstr2 = std::max(nstr2, num_side_sets);
  char **str2 = get_exodus_names(nstr2, 512);

  /* title */
  PutStr("Title",line);

  /* information records */
  if (num_info_lines > 0 ){
    ex_get_info(exo_file,str2);
    std::string ostr;
    for (int i=0;i<num_info_lines;i++) {
      if (strlen(str2[i]) > 0) {
        ostr += str2[i];
        ostr += "\n";
      }
    }
    PutStr("info",ostr.c_str());
    ostr = "";
    for (int i=0;i<num_info_lines;i++) {
      if (strlen(str2[i]) > 0 && strncmp(str2[i],"cavi",4)==0) {
        ostr += str2[i];
        ostr += "\n";
      }
    }
    PutStr("cvxp",ostr.c_str());
  }

  /* nodal coordinates */
  {
    if (debug) {logger("Coordinates");}
    std::vector<double> x, y, z;
    x.resize(num_nodes);
    if (num_axes >= 2) y.resize(num_nodes);
    if (num_axes == 3) z.resize(num_nodes);
    ex_get_coord(exo_file,TOPTR(x), TOPTR(y), TOPTR(z));
    PutDbl("x0", num_nodes, 1, TOPTR(x));
    if (num_axes >= 2) {
      PutDbl("y0", num_nodes, 1, TOPTR(y));
    }
    if (num_axes == 3){
      PutDbl("z0",num_nodes,1, TOPTR(z));
    }
  }

  /* side sets */
  std::vector<int> num_sideset_sides(num_side_sets);
  std::vector<int> ids;
  if (num_side_sets > 0) {
    if (debug) {logger("Side Sets");}
    ids.resize(num_side_sets);
    ex_get_ids(exo_file,EX_SIDE_SET,TOPTR(ids));
    PutInt( "ssids",num_side_sets, 1,TOPTR(ids));
    std::vector<int> nssdfac(num_side_sets);
    std::vector<int> iscr;
    std::vector<int> jscr;
    std::vector<double> scr;
    std::vector<int> elem_list;
    std::vector<int> side_list;
    std::vector<int> junk;
    for (int i=0;i<num_side_sets;i++) {
      ex_get_set_param(exo_file,EX_SIDE_SET, ids[i],&n1,&n2);
      num_sideset_sides[i]=n1;
      nssdfac[i]=n2;
      /*
       * the following provision is from Version 1.6 when there are no
       * distribution factors in exodus file
       */
      bool has_ss_dfac = (n2 != 0);
      if (n2==0 || n1==n2){

        std::cerr << "WARNING: Exodus II file does not contain distribution factors.\n";

        /* n1=number of faces, n2=number of df */
        /* using distribution factors to determine number of nodes in the sideset
           causes a lot grief since some codes do not output distribution factors
           if they are all equal to 1. mkbhard: I am using the function call below
           to figure out the total number of nodes in this sideset. Some redundancy
           exists, but it works for now */

        junk.resize(n1);
        ex_get_side_set_node_count(exo_file,ids[i],TOPTR(junk));
        n2=0; /* n2 will be equal to the total number of nodes in the sideset */
        for (int j=0; j<n1; j++)
          n2+=junk[j];
      }

      iscr.resize(n1);
      jscr.resize(n2);
      ex_get_side_set_node_list(exo_file,ids[i],TOPTR(iscr),TOPTR(jscr));
      /* number-of-nodes-per-side list */
      sprintf(str,"ssnum%02d",i+1);
      PutInt(str,n1,1,TOPTR(iscr));
      /* nodes list */
      sprintf(str,"ssnod%02d",i+1);
      PutInt(str,n2,1,TOPTR(jscr));

      /* distribution-factors list */
      scr.resize(n2);
      if (has_ss_dfac) {
        ex_get_side_set_dist_fact(exo_file,ids[i], TOPTR(scr));
      } else {
        for (int j=0; j<n2; j++) {
          scr[j] = 1.0;
        }
      }
      sprintf(str,"ssfac%02d",i+1);
      PutDbl(str,n2,1,TOPTR(scr));

      /* element and side list for side sets (dgriffi) */
      elem_list.resize(n1);
      side_list.resize(n1);
      ex_get_set(exo_file,EX_SIDE_SET,ids[i],TOPTR(elem_list),TOPTR(side_list));
      sprintf(str,"ssside%02d",i+1);
      PutInt(str,n1,1,TOPTR(side_list));
      sprintf(str,"sselem%02d",i+1);
      PutInt(str,n1,1,TOPTR(elem_list));
    }
    /* Store # sides and # dis. factors per side set (dgriffi) */
    PutInt("nsssides",num_side_sets,1,TOPTR(num_sideset_sides));
    PutInt("nssdfac",num_side_sets,1,TOPTR(nssdfac));
  }

  /* node sets (section by dgriffi) */
  std::vector<int> num_nodeset_nodes(num_node_sets);
  if (num_node_sets > 0){
    if (debug) {logger("Node Sets");}
    std::vector<int> iscr;
    std::vector<double> scr;
    ids.resize(num_node_sets);
    ex_get_ids(exo_file,EX_NODE_SET, TOPTR(ids));
    PutInt( "nsids",num_node_sets, 1,TOPTR(ids));

    std::vector<int> num_nodeset_df(num_node_sets);
    for (int i=0;i<num_node_sets;i++){
      ex_get_set_param(exo_file,EX_NODE_SET,ids[i],&n1,&n2);
      iscr.resize(n1);
      ex_get_node_set(exo_file,ids[i],TOPTR(iscr));
      /* nodes list */
      sprintf(str,"nsnod%02d",i+1);
      PutInt(str,n1,1,TOPTR(iscr));
      {
        /* distribution-factors list */
        scr.resize(n2);
        ex_get_node_set_dist_fact(exo_file,ids[i],TOPTR(scr));
        sprintf(str,"nsfac%02d",i+1);
        PutDbl(str,n2,1,TOPTR(scr));
      }
      num_nodeset_nodes[i]=n1;
      num_nodeset_df[i]=n2;
    }

    /* Store # nodes and # dis. factors per node set */
    PutInt("nnsnodes",num_node_sets,1,TOPTR(num_nodeset_nodes));
    PutInt("nnsdfac",num_node_sets,1,TOPTR(num_nodeset_df));
  }

  /* element blocks */
  if (debug) {logger("Element Blocks");}
  std::vector<int> num_elem_in_block(num_blocks);
  {
    ids.resize(num_blocks);
    std::vector<int> iscr;
    ex_get_ids(exo_file,EX_ELEM_BLOCK,TOPTR(ids));
    PutInt( "blkids",num_blocks, 1,TOPTR(ids));
    for (int i=0;i<num_blocks;i++) {
      ex_get_elem_block(exo_file,ids[i],str2[i],&n,&n1,&n2);
      num_elem_in_block[i]=n;
      iscr.resize(n*n1);
      ex_get_conn(exo_file,EX_ELEM_BLOCK,ids[i],TOPTR(iscr), nullptr, nullptr);
      sprintf(str,"blk%02d",i+1);
      PutInt(str,n1,n,TOPTR(iscr));
    }
    str[0]='\0';
    for (int i=0;i<num_blocks;i++) {
      strcat(str, str2[i]);
      strcat(str, "\n");
    }
    PutStr("blknames",str);
  }

  /* time values */
  if (num_time_steps > 0 ) {
    if (debug) {logger("Time Steps");}
    std::vector<double> scr(num_time_steps);
    ex_get_all_times (exo_file, TOPTR(scr));
    PutDbl( "time", num_time_steps, 1, TOPTR(scr));
  }

  /* global variables */
  if (num_global_vars > 0 ) {
    if (debug) {logger("Global Variables");}
    get_put_names(exo_file, EX_GLOBAL, num_global_vars, "gnames");

    std::vector<double> scr(num_time_steps);
    for (int i=0;i<num_global_vars;i++){
      sprintf(str,"gvar%02d",i+1);
      ex_get_glob_var_time(exo_file,i+1,1,num_time_steps,TOPTR(scr));
      PutDbl(str,num_time_steps,1,TOPTR(scr));
    }
  }

  /* nodal variables */
  if (num_nodal_vars > 0 ) {
    if (debug) {logger("Nodal Variables");}
    if (debug) {logger("\tNames");}
    get_put_names(exo_file, EX_NODAL, num_nodal_vars, "nnames");

    std::vector<double> scr(num_nodes*num_time_steps);
    for (int i=0; i<num_nodal_vars; i++){
      sprintf(str,"nvar%02d",i+1);
      if (debug) {logger("\tReading");}
      for (int j=0; j<num_time_steps; j++) {
        ex_get_nodal_var(exo_file,j+1,i+1,num_nodes,
                         &scr[num_nodes*j]);
      }
      if (debug) {logger("\tWriting");}
      PutDbl(str,num_nodes,num_time_steps,TOPTR(scr));
    }
  }

  /* element variables */
  if (num_element_vars > 0 ) {
    if (debug) {logger("Element Variables");}
    get_put_names(exo_file, EX_ELEM_BLOCK, num_element_vars, "enames");

    get_put_vars(exo_file, EX_ELEM_BLOCK,
                 num_blocks, num_element_vars, num_time_steps, num_elem_in_block, "evar%02d");
  }

  /* nodeset variables */
  if (num_nodeset_vars > 0 ) {
    if (debug) {logger("Nodeset Variables");}
    get_put_names(exo_file, EX_NODE_SET, num_nodeset_vars, "nsnames");

    get_put_vars(exo_file, EX_NODE_SET,
                 num_node_sets, num_nodeset_vars, num_time_steps, num_nodeset_nodes, "nsvar%02d");
  }

  /* sideset variables */
  if (num_sideset_vars > 0 ) {
    if (debug) {logger("Sideset Variables");}
    get_put_names(exo_file, EX_SIDE_SET, num_sideset_vars, "ssnames");

    get_put_vars(exo_file, EX_SIDE_SET,
                 num_side_sets, num_sideset_vars, num_time_steps, num_sideset_sides, "ssvar%02d");
  }

  /* node and element number maps */
  if (debug) {logger("Node and Element Number Maps");}
  ex_opts(0);  /* turn off error reporting. It is not an error to have no map*/
  ids.resize(num_nodes);
  err = ex_get_node_num_map(exo_file,TOPTR(ids));
  if ( err==0 ){
    PutInt("node_num_map",num_nodes,1,TOPTR(ids));
  }

  ids.resize(num_elements);
  err = ex_get_elem_num_map(exo_file,TOPTR(ids));
  if ( err==0 ){
    PutInt("elem_num_map",num_elements,1,TOPTR(ids));
  }

  if (debug) {logger("Closing file");}
  ex_close(exo_file);

  if ( textfile )
    fclose(m_file);
  else
    Mat_Close(mat_file);

  std::cout << "done...\n";

  free(filename);
  free(line);

  delete_exodus_names(str2, nstr2);

  /* exit status */
  add_to_log("exo2mat", 0);
  return(0);
}