Example #1
0
void Dump_Maps(const INT *node_map, const INT *elmt_map, ExoII_Read<INT>& file1)
{
  size_t ijk;
  std::cout << "\n=== node number map (file1 -> file2) local ids\n";
  bool one_to_one = true;
  for (ijk = 0; ijk < file1.Num_Nodes(); ++ijk) {
    if ((INT)ijk != node_map[ijk]) {
      one_to_one = false;
      break;
    }
  }
  if (!one_to_one) {
    for (ijk = 0; ijk < file1.Num_Nodes(); ++ijk)
      std::cout << (ijk+1) << " -> " << (node_map[ijk]+1) << "\n";
  } else {
    std::cout << " *** Node map is one-to-one\n";
  }
      
  std::cout << "\n=== element number map (file1 -> file2) local ids\n";
  one_to_one = true;
  for (ijk = 0; ijk < file1.Num_Elmts(); ++ijk) {
    if ((INT)ijk != elmt_map[ijk]) {
      one_to_one = false;
      break;
    }
  }
  if (!one_to_one) {
    for (ijk = 0; ijk < file1.Num_Elmts(); ++ijk)
      std::cout << (ijk+1) << " -> " << (elmt_map[ijk]+1) << "\n";
  } else {
    std::cout << " *** Element map is one-to-one\n";
  }
  std::cout << "===" << std::endl;
}
Example #2
0
bool Check_Maps(const INT *node_map, const INT *elmt_map, const ExoII_Read<INT>& file1, const ExoII_Read<INT>& file2)
{
  if (file1.Num_Nodes() != file2.Num_Nodes()) {
    return false;
  }
  
  if (file1.Num_Elmts() != file2.Num_Elmts()) {
    return false;
  }
  
  if (node_map != nullptr) {
    for (size_t ijk = 0; ijk < file1.Num_Nodes(); ++ijk) {
      if ((INT)ijk != node_map[ijk]) {
	return false;
      }
    }
  }

  if (elmt_map != nullptr) {
    for (size_t ijk = 0; ijk < file1.Num_Elmts(); ++ijk) {
      if ((INT)ijk != elmt_map[ijk]) {
	return false;
      }
    }
  }
  // All maps are one-to-one; Don't need to map nodes or elements...
  return true;
}
Example #3
0
double Find_Min_Coord_Sep(ExoII_Read<INT>& file)
{
  size_t num_nodes = file.Num_Nodes();
  if (num_nodes < 2) return 0.0;
  
  file.Load_Nodal_Coordinates();
  const double* x = (double*)file.X_Coords();
  const double* y = (double*)file.Y_Coords();
  const double* z = (double*)file.Z_Coords();
  
  auto indx = new INT[num_nodes];
  for (size_t i=0; i < num_nodes; i++) {
    indx[i] = i;
  }

  // Find coordinate with largest range...
  const double *r = x;
  double range = find_range(x, num_nodes);
  if (file.Dimension() > 1) {
    double yrange = find_range(y, num_nodes);
    if (yrange > range) {
      range = yrange;
      r = y;
    }
  }

  if (file.Dimension() > 2) {
    double zrange = find_range(z, num_nodes);
    if (zrange > range) {
      range = zrange;
      r = z;
    }
  }

  // Sort based on coordinate with largest range...
  index_qsort(r, indx, num_nodes);
  
  double min = DBL_MAX;;
  switch (file.Dimension()) {
  case 1: {
    for (size_t i=0; i < num_nodes; i++) {
      for (size_t j=i+1; j < num_nodes; j++) {
	double tmp = dist_sqrd(x[indx[i]], x[indx[j]]);
	if (tmp >= min) {
	  break;
	} else {
	  min = tmp;
	}
      }
    }
    break;
  }
  case 2: {
    for (size_t i=0; i < num_nodes; i++) {
      for (size_t j=i+1; j < num_nodes; j++) {
	double delr = dist_sqrd(r[indx[i]], r[indx[j]]);
	if (delr > min) {
	  break;
	} else {	  
	  double tmp = dist_sqrd(x[indx[i]], y[indx[i]], x[indx[j]], y[indx[j]]);
	  min = min < tmp ? min : tmp;
	}
      }
    }
    break;
  }
  case 3: {
    for (size_t i=0; i < num_nodes; i++) {
      for (size_t j=i+1; j < num_nodes; j++) {
	double delr = dist_sqrd(r[indx[i]], r[indx[j]]);
	if (delr > min) {
	  break;
	} else {	  
	  double tmp = dist_sqrd(x[indx[i]], y[indx[i]], z[indx[i]], x[indx[j]], y[indx[j]], z[indx[j]]);
	  min = min < tmp ? min : tmp;
	}
      }
    }
    break;
  }
  } 
  delete [] indx;
  return sqrt(min);
}
Example #4
0
void Compute_Maps(INT*& node_map, INT*& elmt_map,
                  ExoII_Read<INT>& file1, ExoII_Read<INT>& file2)
{
  SMART_ASSERT(file1.Open());
  SMART_ASSERT(file2.Open());
  
  size_t num_nodes = file1.Num_Nodes();
  size_t num_elmts = file1.Num_Elmts();
  int dim = file1.Dimension();
  
  //  ********************  elements  ********************  //

  // Load global ids (0-offset) into id array.
  auto  id = new INT[num_elmts];
  {for (size_t e = 0; e < num_elmts; ++e) id[e] = e;}
  
  // Get map storage.
  node_map = new INT[num_nodes];  SMART_ASSERT(node_map != nullptr);
  {for (size_t i = 0; i < num_nodes; ++i) node_map[i] = -1; }
  elmt_map = new INT[num_elmts];  SMART_ASSERT(elmt_map != nullptr);
  
  // Create storage for midpoints.
  double *x2 = nullptr, *y2 = nullptr, *z2 = nullptr;
  x2 = new double[num_elmts];  SMART_ASSERT(x2 != nullptr);
  if (dim > 1) { y2 = new double[num_elmts];  SMART_ASSERT(y2 != nullptr); }
  if (dim > 2) { z2 = new double[num_elmts];  SMART_ASSERT(z2 != nullptr); }
  
  // Load coordinates for file 2 and get pointers to them.
  file2.Load_Nodal_Coordinates();
  const double* x2_f = (double*)file2.X_Coords();
  const double* y2_f = (double*)file2.Y_Coords();
  const double* z2_f = (double*)file2.Z_Coords();
  
  // Load connectivities for all blocks in second file.
  file2.Load_Elmt_Block_Descriptions();
  
  {
    // Compute midpoints of each element and place into x,y,z arrays.
    size_t num_blocks = file2.Num_Elmt_Blocks(),
      num_elmts_in_block,
      num_nodes_per_elmt,
      e = 0;
    double sum_x, sum_y, sum_z;
    for (size_t b = 0; b < num_blocks; ++b)
      {
	const Exo_Block<INT>* block = file2.Get_Elmt_Block_by_Index(b);
	num_elmts_in_block = block->Size();
	num_nodes_per_elmt = block->Num_Nodes_per_Elmt();
	for (size_t i = 0; i < num_elmts_in_block; ++i)
	  {
	    const INT* conn = block->Connectivity(i);  // Connectivity for element i.
	    sum_x = 0.0; sum_y = 0.0; sum_z = 0.0;
	    for (size_t j = 0; j < num_nodes_per_elmt; ++j) {
	      sum_x += x2_f[ conn[j] - 1 ];
	      if (dim > 1) sum_y += y2_f[ conn[j] - 1 ];
	      if (dim > 2) sum_z += z2_f[ conn[j] - 1 ];
	    }
	    x2[e] = sum_x / (double)num_nodes_per_elmt;
	    if (dim > 1) y2[e] = sum_y / (double)num_nodes_per_elmt;
	    if (dim > 2) z2[e] = sum_z / (double)num_nodes_per_elmt;
      
	    ++e;
	  }
      }
  }
  
  // Sort by x value.
  index_qsort(x2, id, num_elmts);
  
#if 0
  std::cout << "******************  elmts  ******************** " << std::endl;
  {for (size_t i = 0; i < num_elmts; ++i)
      std::cout << i << ")\t"
		<< x2[id[i]] << "\t"
		<< y2[id[i]] << "\t"
		<< z2[id[i]] << "\t" << id[i] << std::endl;}
  std::cout << "******************  elmts  ******************** " << std::endl;
#endif  
  //  Load and get nodal coordinates for first file.
  file1.Load_Nodal_Coordinates();
  const double* x1_f = (double*)file1.X_Coords();
  const double* y1_f = (double*)file1.Y_Coords();
  const double* z1_f = (double*)file1.Z_Coords();
  
  // Cannot ignore the comparisons, so make sure the coord_tol_type
  // is not -1 which is "ignore"
  TOLERANCE_TYPE_enum save_tolerance_type = interface.coord_tol.type;
  if (save_tolerance_type == IGNORE)
    interface.coord_tol.type = ABSOLUTE;

  // Match elmts in first file to their corresponding elmts in second.
  size_t num_blocks = file1.Num_Elmt_Blocks();
  size_t num_elmts_in_block;
  size_t num_nodes_per_elmt;
  size_t e1 = 0;
  size_t e2 = 0;
  INT sort_idx;
  double mid_x, mid_y, mid_z;

  for (size_t b = 0; b < num_blocks; ++b)
    {
      const Exo_Block<INT>* block1 = file1.Get_Elmt_Block_by_Index(b);
      file1.Load_Elmt_Block_Description(b);
      num_elmts_in_block = block1->Size();
      num_nodes_per_elmt = block1->Num_Nodes_per_Elmt();
      for (size_t i = 0; i < num_elmts_in_block; ++i)
	{
	  // Connectivity for element i.
	  const INT* conn1 = block1->Connectivity(i);
      
	  // Compute midpoint.
	  mid_x = 0.0; mid_y = 0.0; mid_z = 0.0;

	  for (size_t j = 0; j < num_nodes_per_elmt; ++j) {
	    SMART_ASSERT(conn1[j] >= 1 && conn1[j] <= (INT)num_nodes);
	    mid_x += x1_f[conn1[j]-1];
	    if (dim > 1) mid_y += y1_f[conn1[j]-1];
	    if (dim > 2) mid_z += z1_f[conn1[j]-1];
	  }
	  mid_x /= (double)num_nodes_per_elmt;
	  if (dim > 1) mid_y /= (double)num_nodes_per_elmt;
	  if (dim > 2) mid_z /= (double)num_nodes_per_elmt;
      
	  // Locate midpoint in sorted array.
	  sort_idx = Find(mid_x, mid_y, mid_z, x2, y2, z2, id, num_elmts, dim,
			  file1.Block_Id(b), interface.ignore_dups);

	  if (sort_idx < 0) {
	    std::cout << "\nexodiff: ERROR: Files are different (couldn't match element "
		      << (i+1) << " from block " << file1.Block_Id(b)
		      << " from first file to second)" << std::endl;
	    exit(1);
	  }
	  e2 = id[sort_idx];
      
	  // Assign element map for this element.
	  elmt_map[e1] = e2;
      
	  {
	    // Determine the block and elmt index of matched element.
	    int b2;
	    size_t l2;
	    file2.Global_to_Block_Local(e2+1, b2, l2);
        
	    const Exo_Block<INT>* block2 = file2.Get_Elmt_Block_by_Index(b2);
	    SMART_ASSERT(block2 != nullptr);
        
	    // Check that the element types are the same.
	    if (num_nodes_per_elmt != block2->Num_Nodes_per_Elmt())
	      {
		std::cout << "\nexodiff: ERROR: Files are different.\n"
			  << " In File 1: Element " << (i+1)  << " in Block " << file1.Block_Id(b)
			  << " has " << num_nodes_per_elmt << " and\n"
			  << " In File 2: Element " << (l2+1) << " in Block " << file2.Block_Id(b2)
			  << " has " << block2->Num_Nodes_per_Elmt()
			  << std::endl;
		exit(1);
	      }
        
	    // Get connectivity for file2 element.
	    const INT* conn2 = block2->Connectivity(l2);
        
	    // Match each node in the first elmt with a node in the second
	    // and assign node_map.
	    for (size_t ln1 = 0; ln1 < num_nodes_per_elmt; ++ln1)
	      {
		// Grab coordinate of node in first file.
		double x1_val = x1_f[ conn1[ln1] - 1 ];
		double y1_val = dim > 1 ? y1_f[ conn1[ln1] - 1 ] : 0.0;
		double z1_val = dim > 2 ? z1_f[ conn1[ln1] - 1 ] : 0.0;
          
		size_t found = 0;
		for (size_t ln2 = 0; ln2 < num_nodes_per_elmt; ++ln2)
		  {
		    // Grab coordinate of node in second file.
		    double x2_val = x2_f[ conn2[ln2] - 1 ];
		    double y2_val = dim > 1 ? y2_f[ conn2[ln2] - 1 ] : 0.0;
		    double z2_val = dim > 2 ? z2_f[ conn2[ln2] - 1 ] : 0.0;
            
		    if (!interface.coord_tol.Diff(x1_val, x2_val) &&
			!interface.coord_tol.Diff(y1_val, y2_val) &&
			!interface.coord_tol.Diff(z1_val, z2_val) )
		      {
			// assert that if this node has been given a map
			// previously, that it agrees with the latest
			// assignment.
			if (node_map[conn1[ln1]-1] >= 0 && node_map[conn1[ln1]-1] != conn2[ln2]-1) {

			  if (!interface.ignore_dups) {
			    // Node in file 1.
			    INT node1 = conn1[ln1];
			    double x1a = x1_f[node1-1];
			    double y1a = dim >= 2 ? y1_f[node1-1] : 0.0;
			    double z1a = dim >= 3 ? z1_f[node1-1] : 0.0;
		
			    // Node in file 2 that was already mapped to node 1 in file 1
			    INT n1 = node_map[conn1[ln1]-1]+1;
			    double x2a = x2_f[n1-1];
			    double y2a = dim >= 2 ? y2_f[n1-1] : 0.0;
			    double z2a = dim >= 3 ? z2_f[n1-1] : 0.0;

			    // Node in file 2 that is now being mapped to node 1 in file 1
			    INT n2 = conn2[ln2];
			    double x2b = x2_f[n2-1];
			    double y2b = dim >= 2 ? y2_f[n2-1] : 0.0;
			    double z2b = dim >= 3 ? z2_f[n2-1] : 0.0;

			    SMART_ASSERT(!interface.coord_tol.Diff(x2a, x2b) &&
					 !interface.coord_tol.Diff(y2a, y2b) &&
					 !interface.coord_tol.Diff(z2a, z2b));
			    std::cout << "\nexodiff: ERROR - No unique node mapping possible.\n"
				      << "\tFile 1, Node " << node1
				      << " at (" << x1a << ", " << y1a << ", " << z1a << ") maps to both:\n"
				      << "\tFile 2, Node " << n1
				      << " at (" << x2a << ", " << y2a << ", " << z2a << ") and\n"
				      << "\tFile 2, Node " << n2
				      << " at (" << x2b << ", " << y2b << ", " << z2b << ")\n\n";
			    exit(1);
			  }
			  found = 1;
			  break;
			}
			node_map[ conn1[ln1] - 1 ] = conn2[ln2] - 1;
			found = 1;
			break;
		      }
		  }
		if (!found) {
		  std::cout << "\nexodiff: ERROR: Cannot find a match for node at position "
			    << ln1+1 << " in first element.\n"
			    << "\tFile 1: Element " << (i+1)  << " in Block " << file1.Block_Id(b) << " nodes:\n";
		  for (size_t l1 = 0; l1 < num_nodes_per_elmt; ++l1) {
		    double x_val = x1_f[ conn1[l1] - 1 ];
		    double y_val = dim > 1 ? y1_f[ conn1[l1] - 1 ] : 0.0;
		    double z_val = dim > 2 ? z1_f[ conn1[l1] - 1 ] : 0.0;
		    std::cout << "\t(" << l1+1 << ")\t" << conn1[l1] << "\t"
			      << std::setprecision(9) << x_val << "\t" << y_val << "\t" << z_val << "\n";
		  }
		  std::cout << "\tFile 2: Element " << (l2+1) << " in Block " << file1.Block_Id(b) << " nodes:\n";
		  for (size_t l3 = 0; l3 < num_nodes_per_elmt; ++l3) {
		    double x_val = x2_f[ conn2[l3] - 1 ];
		    double y_val = dim > 1 ? y2_f[ conn2[l3] - 1 ] : 0.0;
		    double z_val = dim > 2 ? z2_f[ conn2[l3] - 1 ] : 0.0;
		    std::cout << "\t(" << l3+1 << ")\t" << conn2[l3] << "\t"
			      << std::setprecision(9) << x_val << "\t" << y_val << "\t" << z_val << "\n";
		  }
		  std::cout << "Coordinates compared using tolerance: " << interface.coord_tol.value
			    << " (" << interface.coord_tol.typestr() << "), floor: "
			    <<  interface.coord_tol.floor << "\n";
		  exit(1);
		}
	      }  // End of local node loop on file1's element.
	  }  // End of local node search block.
      
	  ++e1;
      
	}  // End of loop on elements in file1 element block.
    
      file1.Free_Elmt_Block(b);
    
    }  // End of loop on file1 blocks.
  
  // Check that all nodes in the file have been matched...  If any
  // unmatched nodes are found, then perform a node-based matching
  // algorithm...
  for (size_t i=0; i < num_nodes; i++) {
    if (node_map[i] < 0) {
      Compute_Node_Map(node_map, file1, file2);
      break;
    }
  }

  file1.Free_Nodal_Coordinates();
  file2.Free_Nodal_Coordinates();
  file2.Free_Elmt_Blocks();
  
  if (x2 != nullptr) delete [] x2;
  if (y2 != nullptr) delete [] y2;
  if (z2 != nullptr) delete [] z2;
  if (id != nullptr) delete [] id;

  interface.coord_tol.type = save_tolerance_type;
}
Example #5
0
void Compute_FileId_Maps(INT*& node_map, INT*& elmt_map,
			 ExoII_Read<INT>& file1, ExoII_Read<INT>& file2)
{
  // Compute map of nodes and elements in file1 to nodes and elements in file2
  // Use the internal exodus node and element number maps in file1 and file2 to
  // do the matching.  Currently assume (and verify) that number of nodes and
  // elements match in the two files.
  
  SMART_ASSERT(file1.Open());
  SMART_ASSERT(file2.Open());

  {
    size_t num_nodes = file1.Num_Nodes();
    SMART_ASSERT(num_nodes == file2.Num_Nodes());

    node_map = new INT[num_nodes];  SMART_ASSERT(node_map != nullptr);
    file1.Load_Node_Map();
    file2.Load_Node_Map();
    const INT *node_id_map1 = file1.Get_Node_Map();
    const INT *node_id_map2 = file2.Get_Node_Map();
    
    if (!internal_compute_maps(node_map, node_id_map1, node_id_map2, num_nodes, "node")) {
      delete [] node_map;
      node_map = nullptr;
    }
  }
  
  {
    size_t num_elmts = file1.Num_Elmts();
    SMART_ASSERT(num_elmts == file2.Num_Elmts());
    elmt_map = new INT[num_elmts];  SMART_ASSERT(elmt_map != nullptr);
    file1.Load_Elmt_Map();
    file2.Load_Elmt_Map();
    const INT *elem_id_map1 = file1.Get_Elmt_Map();
    const INT *elem_id_map2 = file2.Get_Elmt_Map();

    if (!internal_compute_maps(elmt_map, elem_id_map1, elem_id_map2, num_elmts, "element")) {
      delete [] elmt_map;
      elmt_map = nullptr;
    }
  }
}
Example #6
0
bool Compare_Maps(ExoII_Read<INT>& file1, ExoII_Read<INT>& file2, const INT *node_map, const INT *elmt_map, bool partial_flag)
{
  // Check whether the node and element number maps from both file1
  // and file2 match which indicates that we are comparing the same
  // element and node in each file.

  size_t num_nodes1 = file1.Num_Nodes();
  size_t num_elmts1 = file1.Num_Elmts();

  //size_t num_nodes2 = file2.Num_Nodes();
  //size_t num_elmts2 = file2.Num_Elmts();
  
  // NOTE: file1 maps are already loaded...
  file2.Load_Node_Map();
  file2.Load_Elmt_Map();

  const INT *node_id_map1 = file1.Get_Node_Map();
  const INT *elem_id_map1 = file1.Get_Elmt_Map();

  const INT *node_id_map2 = file2.Get_Node_Map();
  const INT *elem_id_map2 = file2.Get_Elmt_Map();

  bool diff = false;
  size_t warn_count = 0;
  
  if (node_map != nullptr) {
    // There is a map between file1 and file2, but all nodes are
    // used in both files.
    for (size_t i=0; i < num_nodes1; i++) {
      if (node_id_map1[i] != node_id_map2[node_map[i]]) {
	if (!(node_id_map2[node_map[i]] == 0 && partial_flag)) { // Don't output diff if non-matched and partial
	  std::cout << "exodiff: WARNING .. The local node " << i+1 << " with global id " << node_id_map1[i]
		    << " in file1 has the global id " << node_id_map2[node_map[i]]
		    << " in file2.\n";
	  diff = true;
	  warn_count++;
	  if (warn_count > 100) {
	    std::cout << "exodiff: WARNING .. Too many warnings, skipping remainder...\n";
	    break;
	  }
	}
      }
    }
  } else {
    // No node mapping between file1 and file2 -- do a straight compare.
    for (size_t i=0; i < num_nodes1; i++) {
      if (node_id_map1[i] != node_id_map2[i]) {
	if (!(node_id_map2[i] == 0 && partial_flag)) { // Don't output diff if non-matched and partial
	  std::cout << "exodiff: WARNING .. The local node " << i+1 << " with global id " << node_id_map1[i]
		    << " in file1 has the global id " << node_id_map2[i]
		    << " in file2.\n";
	  diff = true;
	  warn_count++;
	  if (warn_count > 100) {
	    std::cout << "exodiff: WARNING .. Too many warnings, skipping remainder...\n";
	    break;
	  }
	}
      }
    }
  }

  warn_count = 0;
  if (elmt_map != nullptr) {
    // There is a map between file1 and file2, but all elements are
    // used in both files.
    for (size_t i=0; i < num_elmts1; i++) {
      if (elem_id_map1[i] != elem_id_map2[elmt_map[i]]) {
	if (!(elem_id_map2[elmt_map[i]] == 0 && partial_flag)) { // Don't output diff if non-matched and partial
	  std::cout << "exodiff: WARNING .. The local element " << i+1 << " with global id " << elem_id_map1[i]
		    << " in file1 has the global id " << elem_id_map2[elmt_map[i]]
		    << " in file2.\n";
	  diff = true;
	  warn_count++;
	  if (warn_count > 100) {
	    std::cout << "exodiff: WARNING .. Too many warnings, skipping remainder...\n";
	    break;
	  }
	}
      }
    }
  } else {
    // No element mapping between file1 and file2 -- do a straight compare.
    for (size_t i=0; i < num_elmts1; i++) {
      if (elem_id_map1[i] != elem_id_map2[i]) {
	if (!(elem_id_map2[i] == 0 && partial_flag)) { // Don't output diff if non-matched and partial
	  std::cout << "exodiff: WARNING .. The local element " << i+1 << " with global id " << elem_id_map1[i]
		    << " in file1 has the global id " << elem_id_map2[i]
		    << " in file2.\n";
	  diff = true;
	  warn_count++;
	  if (warn_count > 100) {
	    std::cout << "exodiff: WARNING .. Too many warnings, skipping remainder...\n";
	    break;
	  }
	}
      }
    }
  }
  file2.Free_Node_Map();
  file2.Free_Elmt_Map();

  if (diff) std::cout << std::endl;
  return diff;
}
Example #7
0
void Compute_Partial_Maps(INT*& node_map, INT*& elmt_map,
			  ExoII_Read<INT>& file1, ExoII_Read<INT>& file2)
{
  SMART_ASSERT(file1.Open());
  SMART_ASSERT(file2.Open());
  
  size_t num_nodes1 = file1.Num_Nodes();
  size_t num_elmts1 = file1.Num_Elmts();

  //size_t num_nodes2 = file2.Num_Nodes();
  size_t num_elmts2 = file2.Num_Elmts();
  int dim = file1.Dimension();
  SMART_ASSERT(dim == file2.Dimension());
  
//  ********************  elements  ********************  //

  // Load global ids (0-offset) into id array.
  auto  id2 = new INT[num_elmts2];
  {for (size_t e = 0; e < num_elmts2; ++e) id2[e] = e;}
  
  // Get map storage.
  node_map = new INT[num_nodes1];  SMART_ASSERT(node_map != nullptr);
  {for (size_t i = 0; i < num_nodes1; ++i) node_map[i] = -1; }
  elmt_map = new INT[num_elmts1];  SMART_ASSERT(elmt_map != nullptr);
  {for (size_t i = 0; i < num_elmts1; ++i) elmt_map[i] = -1; }

  // Create storage for midpoints.
  double *x2 = nullptr, *y2 = nullptr, *z2 = nullptr;
  x2 = new double[num_elmts2];  SMART_ASSERT(x2 != nullptr);
  if (dim > 1) { y2 = new double[num_elmts2];  SMART_ASSERT(y2 != nullptr); }
  if (dim > 2) { z2 = new double[num_elmts2];  SMART_ASSERT(z2 != nullptr); }
  
  // Load coordinates for file 2 and get pointers to them.
  file2.Load_Nodal_Coordinates();
  const double* x2_f = (double*)file2.X_Coords();
  const double* y2_f = (double*)file2.Y_Coords();
  const double* z2_f = (double*)file2.Z_Coords();
  
  // Load connectivities for all blocks in second file.
  file2.Load_Elmt_Block_Descriptions();
  
  {
  // Compute midpoints of each element and place into x,y,z arrays.
  size_t num_blocks2 = file2.Num_Elmt_Blocks(),
      num_elmts_in_block,
      num_nodes_per_elmt,
      e = 0;
  double sum_x, sum_y, sum_z;
  for (size_t b = 0; b < num_blocks2; ++b)
  {
    const Exo_Block<INT>* block = file2.Get_Elmt_Block_by_Index(b);
    num_elmts_in_block = block->Size();
    num_nodes_per_elmt = block->Num_Nodes_per_Elmt();
    for (size_t i = 0; i < num_elmts_in_block; ++i)
    {
      const INT* conn = block->Connectivity(i);  // Connectivity for element i.
      sum_x = 0.0; sum_y = 0.0; sum_z = 0.0;
      for (size_t j = 0; j < num_nodes_per_elmt; ++j) {
        sum_x += x2_f[ conn[j] - 1 ];
        if (dim > 1) sum_y += y2_f[ conn[j] - 1 ];
        if (dim > 2) sum_z += z2_f[ conn[j] - 1 ];
      }
      x2[e] = sum_x / (double)num_nodes_per_elmt;
      if (dim > 1) y2[e] = sum_y / (double)num_nodes_per_elmt;
      if (dim > 2) z2[e] = sum_z / (double)num_nodes_per_elmt;
      
      ++e;
    }
  }
  }
  
  // Sort by x value.
  index_qsort(x2, id2, num_elmts2);
  
#if 0
  std::cout << "******************  elmts  ******************** " << std::endl;
  {for (size_t i = 0; i < num_elmts; ++i)
    std::cout << i << ")\t"
	      << x2[id[i]] << "\t"
	      << y2[id[i]] << "\t"
	      << z2[id[i]] << "\t" << id[i] << std::endl;}
  std::cout << "******************  elmts  ******************** " << std::endl;
#endif  
  //  Load and get nodal coordinates for first file.
  file1.Load_Nodal_Coordinates();
  const double* x1_f = (double*)file1.X_Coords();
  const double* y1_f = (double*)file1.Y_Coords();
  const double* z1_f = (double*)file1.Z_Coords();
  
  // Cannot ignore the comparisons, so make sure the coord_tol_type
  // is not -1 which is "ignore"
  TOLERANCE_TYPE_enum save_tolerance_type = interface.coord_tol.type;
  if (save_tolerance_type == IGNORE)
    interface.coord_tol.type = ABSOLUTE;

  // Match elmts in first file to their corresponding elmts in second.
  size_t num_blocks1 = file1.Num_Elmt_Blocks();
  size_t num_elmts_in_block;
  size_t num_nodes_per_elmt;
  size_t e1 = 0;
  size_t e2 = 0;
  INT    sort_idx;
  double mid_x, mid_y, mid_z;

  bool first = true;
  size_t  unmatched = 0;
  for (size_t b = 0; b < num_blocks1; ++b)
  {
    const Exo_Block<INT>* block1 = file1.Get_Elmt_Block_by_Index(b);
    file1.Load_Elmt_Block_Description(b);
    num_elmts_in_block = block1->Size();
    num_nodes_per_elmt = block1->Num_Nodes_per_Elmt();
    for (size_t i = 0; i < num_elmts_in_block; ++i)
    {
      // Connectivity for element i.
      const INT* conn1 = block1->Connectivity(i);
      
      // Compute midpoint.
      mid_x = 0.0; mid_y = 0.0; mid_z = 0.0;

      for (size_t j = 0; j < num_nodes_per_elmt; ++j) {
        SMART_ASSERT(conn1[j] >= 1 && conn1[j] <= (INT)num_nodes1);
        mid_x += x1_f[conn1[j]-1];
        if (dim > 1) mid_y += y1_f[conn1[j]-1];
        if (dim > 2) mid_z += z1_f[conn1[j]-1];
      }
      mid_x /= (double)num_nodes_per_elmt;
      if (dim > 1) mid_y /= (double)num_nodes_per_elmt;
      if (dim > 2) mid_z /= (double)num_nodes_per_elmt;
      
      // Locate midpoint in sorted array.
      sort_idx = Find(mid_x, mid_y, mid_z, x2, y2, z2, id2, num_elmts2, dim,
		      file1.Block_Id(b), interface.ignore_dups);
      if (sort_idx < 0) {
	unmatched++;
	if (first && interface.show_unmatched) {
	  std::cout << "exodiff: Doing Partial Comparison: No Match for (b.e):\n";
	}
	first = false;
        if (interface.show_unmatched)
	  std::cout << file1.Block_Id(b) << "." << (i+1) << ", ";
      }
      else{
	e2 = id2[sort_idx];
	elmt_map[e1] = e2;
	
	// Assign element map for this element.
	
	
        // Determine the block and elmt index of matched element.
	int b2;
        size_t l2;
	file2.Global_to_Block_Local(e2+1, b2, l2);
        
        const Exo_Block<INT>* block2 = file2.Get_Elmt_Block_by_Index(b2);
        SMART_ASSERT(block2 != nullptr);
        
        // Check that the element types are the same.
        if (num_nodes_per_elmt != block2->Num_Nodes_per_Elmt())
        {
          std::cout << "\nexodiff: ERROR: Files are different.\n"
		    << " In File 1: Element " << (i+1)  << " in Block " << file1.Block_Id(b)
		    << " has " << num_nodes_per_elmt << " and\n"
		    << " In File 2: Element " << (l2+1) << " in Block " << file2.Block_Id(b2)
		    << " has " << block2->Num_Nodes_per_Elmt()
		    << std::endl;
          exit(1);
        }
        
        // Get connectivity for file2 element.
        const INT* conn2 = block2->Connectivity(l2);
        
        // Match each node in the first elmt with a node in the second
        // and assign node_map.
        for (size_t ln1 = 0; ln1 < num_nodes_per_elmt; ++ln1)
        {
          // Grab coordinate of node in first file.
          double x1_val = x1_f[ conn1[ln1] - 1 ];
          double y1_val = dim > 1 ? y1_f[ conn1[ln1] - 1 ] : 0.0;
          double z1_val = dim > 2 ? z1_f[ conn1[ln1] - 1 ] : 0.0;
          size_t found = 0;
          for (size_t ln2 = 0; ln2 < num_nodes_per_elmt; ++ln2)
          {
            // Grab coordinate of node in second file.
            double x2_val =           x2_f[ conn2[ln2] - 1 ];
            double y2_val = dim > 1 ? y2_f[ conn2[ln2] - 1 ] : 0.0;
            double z2_val = dim > 2 ? z2_f[ conn2[ln2] - 1 ] : 0.0;
            
            if (!interface.coord_tol.Diff(x1_val, x2_val) &&
		!interface.coord_tol.Diff(y1_val, y2_val) &&
		!interface.coord_tol.Diff(z1_val, z2_val) )
            {
              node_map[ conn1[ln1] - 1 ] = conn2[ln2] - 1;
              found = 1;
              break;
            }
          }
          if (!found) {
            std::cout << "\nexodiff: ERROR: Cannot find a match for node at position "
		      << ln1+1 << " in first element.\n"
		      << "\tFile 1: Element " << (i+1)  << " in Block " << file1.Block_Id(b) << " nodes:\n";
	    for (size_t l1 = 0; l1 < num_nodes_per_elmt; ++l1) {
	      double x_val = x1_f[ conn1[l1] - 1 ];
	      double y_val = dim > 1 ? y1_f[ conn1[l1] - 1 ] : 0.0;
	      double z_val = dim > 2 ? z1_f[ conn1[l1] - 1 ] : 0.0;
	      std::cout << "\t(" << l1+1 << ")\t" << conn1[l1] << "\t"
			<< std::setprecision(9) << x_val << "\t" << y_val << "\t" << z_val << "\n";
	    }
	    std::cout << "\tFile 2: Element " << (l2+1) << " in Block " << file1.Block_Id(b) << " nodes:\n";
	    for (size_t l3 = 0; l3 < num_nodes_per_elmt; ++l3) {
	      double x_val = x2_f[ conn2[l3] - 1 ];
	      double y_val = dim > 1 ? y2_f[ conn2[l3] - 1 ] : 0.0;
	      double z_val = dim > 2 ? z2_f[ conn2[l3] - 1 ] : 0.0;
	      std::cout << "\t(" << l3+1 << ")\t" << conn2[l3] << "\t"
			<< std::setprecision(9) << x_val << "\t" << y_val << "\t" << z_val << "\n";
	    }
	    std::cout << "Coordinates compared using tolerance: " << interface.coord_tol.value
		      << " (" << interface.coord_tol.typestr() << "), floor: "
		      <<  interface.coord_tol.floor << "\n";
            exit(1);
          }
        }  // End of local node loop on file1's element.
      }  // End of local node search block.
      
      ++e1;
      
    }  // End of loop on elements in file1 element block.
    file1.Free_Elmt_Block(b);
    
  }  // End of loop on file1 blocks.
  if (!first) {
    std::cout << "\nPartial Map selected -- " << unmatched << " elements unmatched\n";
  } else {
    if (num_elmts1 == num_elmts2)
      std::cout << "exodiff: INFO .. Partial Map was specfied, but not needed.  All elements matched.\n";
  }
    
  
  // Check that all nodes in the file have been matched...  If any
  // unmatched nodes are found, then perform a node-based matching
  // algorithm...
//   for (size_t i=0; i < num_nodes; i++) {
//     if (node_map[i] < 0) {
//       Compute_Node_Map(node_map, file1, file2);
//       break;
//     }
//   }

  file1.Free_Nodal_Coordinates();
  file2.Free_Nodal_Coordinates();
  file2.Free_Elmt_Blocks();
  
  if (x2 != nullptr) delete [] x2;
  if (y2 != nullptr) delete [] y2;
  if (z2 != nullptr) delete [] z2;
  if (id2 != nullptr) delete [] id2;

  interface.coord_tol.type = save_tolerance_type;
}
Example #8
0
template <typename INT> bool Check_Global(ExoII_Read<INT> &file1, ExoII_Read<INT> &file2)
{
  bool is_same = true;
  if (file1.Dimension() != file2.Dimension()) {
    ERROR(".. Dimension doesn't agree.\n");
    is_same = false;
  }
  if (file1.Num_Nodes() != file2.Num_Nodes()) {
    if (interface.map_flag != PARTIAL) {
      ERROR(".. Number of nodes doesn't agree.\n");
      is_same = false;
    }
  }
  if (file1.Num_Elmts() != file2.Num_Elmts()) {
    if (interface.map_flag != PARTIAL) {
      ERROR(".. Number of elements doesn't agree.\n");
      is_same = false;
    }
  }
  if (file1.Num_Elmt_Blocks() != file2.Num_Elmt_Blocks()) {
    if (interface.map_flag != PARTIAL) {
      ERROR(".. Number of element blocks doesn't agree.\n");
      is_same = false;
    }
  }
  if (file1.Num_Times() != file2.Num_Times() && !interface.quiet_flag) {
    ERROR(".. First file has " << file1.Num_Times()
	  << " result times while the second file has " << file2.Num_Times() << ".\n");
  }
  return is_same;
}
Example #9
0
bool Check_Global(ExoII_Read<INT>& file1, ExoII_Read<INT>& file2)
{
  bool is_same = true;
  if (file1.Dimension() != file2.Dimension()) {
    std::cout << "exodiff: ERROR .. Dimension doesn't agree." << std::endl;
    is_same = false;
  }
  if (file1.Num_Nodes() != file2.Num_Nodes()) {
    if(interface.map_flag != PARTIAL){
      std::cout << "exodiff: ERROR .. Number of nodes doesn't agree." << std::endl;
      is_same = false;
    }
  }
  if (file1.Num_Elmts() != file2.Num_Elmts()) {
    if(interface.map_flag != PARTIAL){
      std::cout << "exodiff: ERROR .. Number of elements doesn't agree." << std::endl;
      is_same = false;
    }
  }
  if (file1.Num_Elmt_Blocks() != file2.Num_Elmt_Blocks()) {
    if(interface.map_flag != PARTIAL){
      std::cout << "exodiff: ERROR .. Number of element blocks doesn't agree." << std::endl;
      is_same = false;
    }
  }
  if (file1.Num_Times() != file2.Num_Times() && !interface.quiet_flag) {
    std::cout << "exodiff: WARNING .. First file has " << file1.Num_Times()
	      << " result times while the second file has " << file2.Num_Times()
	      << ".\n";
  }
  return is_same;
}
Example #10
0
void Build_Variable_Names(ExoII_Read& file1, ExoII_Read& file2, bool *diff_found)
{
  // Build (and compare) global variable names.
  build_variable_names("global", specs.glob_var_names, specs.glob_var,
                       specs.glob_var_default, specs.glob_var_do_all_flag,
                       file1.Global_Var_Names(), file2.Global_Var_Names(),
		       diff_found);

  // Build (and compare) nodal variable names.
  build_variable_names("nodal", specs.node_var_names, specs.node_var,
                       specs.node_var_default, specs.node_var_do_all_flag,
                       file1.Nodal_Var_Names(),  file2.Nodal_Var_Names(),
		       diff_found);

  // Build (and compare) element variable names.
  build_variable_names("element", specs.elmt_var_names, specs.elmt_var,
                        specs.elmt_var_default, specs.elmt_var_do_all_flag,
                        file1.Elmt_Var_Names(),   file2.Elmt_Var_Names(),
			diff_found);

  // Build (and compare) element variable names.
  if (!specs.ignore_attributes) {
    build_variable_names("element attribute", specs.elmt_att_names, specs.elmt_att,
			 specs.elmt_att_default, specs.elmt_att_do_all_flag,
			 file1.Elmt_Att_Names(),   file2.Elmt_Att_Names(),
			 diff_found);
  }

  // Build (and compare) nodeset variable names.
  build_variable_names("nodeset", specs.ns_var_names, specs.ns_var,
                       specs.ns_var_default, specs.ns_var_do_all_flag,
                       file1.NS_Var_Names(), file2.NS_Var_Names(),
                       diff_found);

  // Build (and compare) sideset variable names.
  build_variable_names("sideset", specs.ss_var_names, specs.ss_var,
                       specs.ss_var_default, specs.ss_var_do_all_flag,
                       file1.SS_Var_Names(), file2.SS_Var_Names(),
                       diff_found);
}
Example #11
0
int Create_File(ExoII_Read& file1, ExoII_Read& file2,
                const string& diffile_name, bool *diff_found)
{
  // Multiple modes:
  // summary_flag == true   --> Single file, output summary and variable names, return
  // diffile_name == ""     --> Dual file, output summary, variable names, check compatability,
  // diffile_name != ""     --> Three files (2 in, 1 out)
  //                            create output file which is diff of input.
  //                            output summary, variable names, check compatability
  // quiet_flag == true     --> don't output summary information


  SMART_ASSERT(!specs.summary_flag);
  //========================================================================
  // From here on down, have two input files and possibly 1 output file...
  // Create output file.

  int out_file_id = -1;
  if (!diffile_name.empty()) {

    // Take minimum word size for output file.
    int iows = file1.IO_Word_Size() < file2.IO_Word_Size()
      ? file1.IO_Word_Size() : file2.IO_Word_Size();
    int compws = sizeof(double);

    out_file_id = ex_create(diffile_name.c_str(), EX_CLOBBER, &compws, &iows);
    SMART_ASSERT(out_file_id >= 0);
    ex_copy(file1.File_ID(), out_file_id);
  }

  if (!specs.quiet_flag) {
    if (out_file_id >= 0) {  // The files are to be differenced .. just list names.
      if (specs.coord_tol.type != IGNORE) {
	SMART_ASSERT(specs.coord_tol.type == RELATIVE ||
                     specs.coord_tol.type == ABSOLUTE ||
		     specs.coord_tol.type == COMBINED ||
		     specs.coord_tol.type == EIGEN_REL ||
                     specs.coord_tol.type == EIGEN_ABS ||
		     specs.coord_tol.type == EIGEN_COM);
	sprintf(buf, "Coordinates:  tol: %8g %s, floor: %8g",
		specs.coord_tol.value, specs.coord_tol.typestr(), specs.coord_tol.floor);
	std::cout << buf << std::endl;
      }
      else
	std::cout << "Locations of nodes will not be considered.\n";

      if (specs.time_tol.type != IGNORE) {
	SMART_ASSERT(specs.time_tol.type == RELATIVE ||
                     specs.time_tol.type == ABSOLUTE ||
		     specs.time_tol.type == COMBINED ||
		     specs.time_tol.type == EIGEN_REL ||
                     specs.time_tol.type == EIGEN_ABS ||
		     specs.time_tol.type == EIGEN_COM);
	sprintf(buf, "Time step values:  tol: %8g %s, floor: %8g",
		specs.time_tol.value,	specs.time_tol.typestr(), specs.time_tol.floor);
	std::cout << buf << std::endl;
      }
      else
	std::cout << "Time step time values will not be differenced.\n";

      output_diff_names("Global",  specs.glob_var_names);
      output_diff_names("Nodal",   specs.node_var_names);
      output_diff_names("Element", specs.elmt_var_names);
      output_diff_names("Element Attribute", specs.elmt_att_names);
      output_diff_names("Nodeset", specs.ns_var_names);
      output_diff_names("Sideset", specs.ss_var_names);
    }
    else {  // The files are to be compared .. echo additional info.
      if (Tolerance::use_old_floor) {
	std::cout << "WARNING: Using old definition of floor tolerance. |a-b|<floor.\n\n";
      }
      if (specs.coord_tol.type != IGNORE) {
	SMART_ASSERT(specs.coord_tol.type == RELATIVE ||
                     specs.coord_tol.type == ABSOLUTE ||
		     specs.coord_tol.type == COMBINED ||
		     specs.coord_tol.type == EIGEN_REL ||
                     specs.coord_tol.type == EIGEN_ABS ||
		     specs.coord_tol.type == EIGEN_COM);
	sprintf(buf, "Coordinates will be compared .. tol: %8g (%s), floor: %8g",
		specs.coord_tol.value, specs.coord_tol.typestr(), specs.coord_tol.floor);
	std::cout << buf << std::endl;
      } else {
	std::cout << "Locations of nodes will not be compared." << std::endl;
      }

      if (specs.time_tol.type != IGNORE) {
	SMART_ASSERT(specs.time_tol.type == RELATIVE ||
                     specs.time_tol.type == ABSOLUTE ||
		     specs.time_tol.type == COMBINED ||
		     specs.time_tol.type == EIGEN_REL ||
                     specs.time_tol.type == EIGEN_ABS ||
		     specs.time_tol.type == EIGEN_COM);
	sprintf(buf, "Time step values will be compared .. tol: %8g (%s), floor: %8g",
		specs.time_tol.value, specs.time_tol.typestr(), specs.time_tol.floor);
	std::cout << buf << std::endl;
      } else {
	std::cout << "Time step time values will not be compared." << std::endl;
      }

      output_compare_names("Global",  specs.glob_var_names, specs.glob_var,
			   file1.Num_Global_Vars(), file2.Num_Global_Vars());

      output_compare_names("Nodal",   specs.node_var_names, specs.node_var,
			   file1.Num_Nodal_Vars(), file2.Num_Nodal_Vars());

      output_compare_names("Element", specs.elmt_var_names, specs.elmt_var,
			   file1.Num_Elmt_Vars(), file2.Num_Elmt_Vars());

      output_compare_names("Element Attribute", specs.elmt_att_names, specs.elmt_att,
			   file1.Num_Elmt_Atts(), file2.Num_Elmt_Atts());

      output_compare_names("Nodeset", specs.ns_var_names, specs.ns_var,
			   file1.Num_NS_Vars(), file2.Num_NS_Vars());

      output_compare_names("Sideset", specs.ss_var_names, specs.ss_var,
			   file1.Num_SS_Vars(), file2.Num_SS_Vars());
    }
  }

  std::vector<int> truth_tab;
  build_truth_table(EX_ELEM_BLOCK, "Element Block", specs.elmt_var_names, file1.Num_Elmt_Blocks(),
		    file1, file2, file1.Elmt_Var_Names(), file2.Elmt_Var_Names(),
		    truth_tab, specs.quiet_flag, diff_found);

  std::vector<int> ns_truth_tab;
  build_truth_table(EX_NODE_SET, "Nodeset", specs.ns_var_names, file1.Num_Node_Sets(),
		    file1, file2, file1.NS_Var_Names(), file2.NS_Var_Names(),
		    ns_truth_tab, specs.quiet_flag, diff_found);

  std::vector<int> ss_truth_tab;
  build_truth_table(EX_SIDE_SET, "Sideset", specs.ss_var_names, file1.Num_Side_Sets(),
		    file1, file2, file1.SS_Var_Names(), file2.SS_Var_Names(),
		    ss_truth_tab, specs.quiet_flag, diff_found);


  // Put out the concatenated variable parameters here and then
  // put out the names....
  if (out_file_id >= 0) {
    ex_put_all_var_param(out_file_id,
			 specs.glob_var_names->size(),
			 specs.node_var_names->size(),
			 specs.elmt_var_names->size(), &truth_tab[0],
			 specs.ns_var_names->size(),   &ns_truth_tab[0],
			 specs.ss_var_names->size(),   &ss_truth_tab[0]);

    output_exodus_names(out_file_id, EX_GLOBAL,     specs.glob_var_names);
    output_exodus_names(out_file_id, EX_NODAL,      specs.node_var_names);
    output_exodus_names(out_file_id, EX_ELEM_BLOCK, specs.elmt_var_names);
    output_exodus_names(out_file_id, EX_NODE_SET,   specs.ns_var_names);
    output_exodus_names(out_file_id, EX_SIDE_SET,   specs.ss_var_names);
  }
  return out_file_id;
}
Example #12
0
bool Check_Global(ExoII_Read& file1, ExoII_Read& file2)
{
  bool is_same = true;
  if (file1.Dimension() != file2.Dimension()) {
    std::cout << "exodiff: ERROR .. Dimension doesn't agree." << std::endl;
    is_same = false;
  }
  if (file1.Num_Nodes() != file2.Num_Nodes()) {
    if(specs.map_flag != PARTIAL){
      std::cout << "exodiff: ERROR .. Number of nodes don't agree." << std::endl;
      is_same = false;
    }
  }
  if (file1.Num_Elmts() != file2.Num_Elmts()) {
    if(specs.map_flag != PARTIAL){
      std::cout << "exodiff: ERROR .. Number of elements don't agree." << std::endl;
      is_same = false;
    }
  }
  if (!specs.map_flag && file1.Num_Elmt_Blocks() != file2.Num_Elmt_Blocks()) {
    if(specs.map_flag != PARTIAL){
      std::cout << "exodiff: ERROR .. Number of blocks don't agree." << std::endl;
      is_same = false;
    }
  }
  if (!specs.map_flag && file1.Num_Times() != file2.Num_Times() && !specs.quiet_flag) {
    std::cout << "exodiff: WARNING First file has " << file1.Num_Times()
	      << " result times while the second file has " << file2.Num_Times()
	      << ".\n"
	      << "         Will consider only "
	      << (file1.Num_Times() < file2.Num_Times() ? file1.Num_Times()
		  : file2.Num_Times())
	      << " timesteps." << std::endl;
  }
  return is_same;
}