当前位置: 首页 > 工具软件 > mom4j > 使用案例 >

MOM 学习二

景阳平
2023-12-01

UnifyGeoUnit()

internal :: is_infinite_gnd = false;
internal :: g_gause_mean = 0.0;
int gause_num = 0;
double gause_distance = 0;

GenerateBaisViaElement

定义一个 gnd_elem_idx_set 数组,并找到在 GND 上的 element将其压入gnd_elem_idx_set 数组,然后将属于 gnd_elem_idx_set 数组中的 element 从 element_list 中移除。

1:对 element_list 进行遍历,将 element 的标号与 count 进行比较,目的是为了保证 elemrnt 是按照编号 0~size-1 的顺序出现;

2:如果 element 是 infinite_gnd (无线地),首先 取得 element 的三个角,对该element 的三个角遍历,如果其中一个角的 Z 坐标在 GND 上,那么 num_vertex_on_gnd 加一,然后如果该 element 的三个角都在 gnd 上,则把 该element 的编号压入 gnd_elem_idx_set 数组中。

3:对 element_list 遍历,将即在 element_list 数组中,又在gnd_elem_idx_set数组中的 element 从element_list 数组中删除,(当在一个数组中找不到元素时,就会默认为 end() )。

4:清除 element_list 中多余的元素。

相邻 element 的边、拓扑结构

通过两个点重合,一个点不重合的方法

basis_list 生成,对 edge_map 遍历

1:半基函数 时:edge_map.second.size() ==  1,

2:完整基函数 时:(1)edge_map.second.size() ==  2,.。。。(2)edge_map.second.size() >=  3,

void RWGBasis::GenerateBaisViaElement(std::vector<Basis>*&basis_list, 
        std::vector<Element>*&element_list, const vector<FLayer>& metal_layer)
{
  //getchar()
  auto &elem_vec = *element_list;
  if (basis_list != nullptr){
    return ;
  }
  basis_list = new std::vector<Basis>();
  struct Edge {
    FPoint p1, p2;
    Edge(FPoint &p1, FPoint &p2)
    {
      if (p1 < p2){
        this->p1 = p1;
        this->p2 = p2;
      }else{
        this->p1 = p2;
        this->p2 = p1;
      }
    }

    bool operator < (const Edge &rhs) const
    {
      if (NotEqualTo(this->p1, rhs.p1))
        return this->p1 < rhs.p1;
      else
        return this->p2 < rhs.p2;
    }

    void print() const
    {
      cout << "Edge: " << endl;
      cout.precision(20);
      cout << p1.XYZ(0) << "," << p1.XYZ(1) << "," << p1.XYZ(2) << endl;
      cout << p2.XYZ(0) << "," << p2.XYZ(1) << "," << p2.XYZ(2) << endl;
      cout << endl;
    }
  };

  int count = 0;
  std::set<int> gnd_elem_idx_set;
  //
  Msg::Debug("before remove elem on gnd: %d", elem_vec.size());
  for (auto &elem : elem_vec){
    if (elem.GetIndex() != count){
      Msg::Debug("Mesh Error! Elem idx doesn't match!);
      theow 
    }

    //remove elem on the ground
  if(internal::is_infinite_gnd){
      int num_vertex_on_gnd = 0;
      auto &vertexes = elem,GetVertex();
      for (auto &vertex : vertexes){
        if (EqualTo(vertex.XYZ(2), internal::g_z_GND)){
          num_vertex_on_gnd++;
        }
      }
      if (num_vertex_on_gnd == vertexes.size()) {
	    Msg::Debug("remove elem[%d] on gnd", elem.GetIndex());
		if (elem.GetPort() != nullptr){
		  throw
		}
		gnd_elem_idx_set.insert(count);
	  }
    }
	count++;
  }
  int step = 0;
  for(int i = 0; i < elem.vec.size(); i++){
    if (gnd_elem_idx_set.find(i) != gnd_elem_idx_set.end()){
	  step++;
	}else{
	  elem_vec[i - step] = elem.vec[i];
	  elem_vec[i - step].SetIndex(i - step);
	}
  }
  for (int i = 0; i < gnd_elem_idx_set.size(); i++){
    elem.vec.pop_back();
  }
  cout << "after remove elem on gnd" << elem.vec.size() << endl;
  
  //edge to vector of adjacent element index
  //相邻元素索引向量的边
  std::map<Edge, std::vector<int>> edge_map;
  
  for (auto &elem : elem_vec){
    auto &vertexes = elem.GetVertex();
	
	for (int i = 0; i < vertexes.size(); i++){
	  for (int j = 1; j < vertexes.size(); j++){
	    Edge e(elem.GetVertex()[i], elem.GetVertex()[j]);
		if(!EqualTo(e.p1.XYZ(2), e.p2.XYZ(2)) && EqualTo(e.p1.XYZ(0),e.p2.XYZ(0)) && EqualTo(e.p1.XYZ(1), e.p2.XYZ(1)) && IsTDSElem(elem,metal_layers)){
		  continue;
		}
		if(edge_map.find(e) == edge_map.end())
			edge_map[e] = std::vector<int>();
		edge_map[e].push_back(elem.GetIndex());
	  }
	}
  }
  cout << "edge_map" << edge_map.size() << endl;
  
  struct BasisComp{
    bool operator() (const Basis &a, const Basis &b) const
	{
	  using namespace highwayhash;
	  
	  std::string sa = bitset<32>(a[0]).to_string() + bitset<32>(a[1]).to_string();
	  std::string sb = bitset<32>(b[0]).to_string() + bitset<32>(b[1]).to_string();
	  
	  const HH_U64 key2[2] HH_ALIGANS(16) = {'F','D'};
	  HH_U64 hash_a = SipHash(key2, sa.c_str(), sa.size());
	  HH_U64 hash_b = SipHash(key2, sb.c_str(), sb.size());
	  
	  return hash_a < hash_b;
	}
  };
  
  std::set<Basis, BasisComp> set_b;
  
  for (auto &p : edge_map){
    auto &vec = p.second;
	
	if(vec.size() == 1){
	  Basis b = Basis(vec[0]. -1);
	  auto iter = set_b.insert(b);
	  
	  if(iter.second == false){
	    cout << "caught same half basis:" << b[0] << ",-1" << endl;
	  }else{
	    basis_list->push_back(Basis(vec[0], -1));
	  }
	}
	
	else if(vec.size() == 2){
	  if(vc[0] < vec[1]){
	    Basis b(vec[0], vec[1]);
		auto iter = set_b.insert(b);
		if (iter.second == false){
		  cout << "caught same complete basis:" << b[0] << "," << b[1] <<endl;		  
		}else{
		  basis_list->push_back(b);
		}
	  }else{
	    Basis b(vec[1], vec[0]);
		auto iter = set_b.insert(b);
		if(iter.second == false){
		  cout << "caught same complete basis:" << b[0] << "," << b[1] << endl;
		}else{
		  basis_list->push_back(b);
		}
	  }
	}
	else if(vec.size() >= 3){
	  for (int i = 0; i < vec.size() - 1; i++){
	    if(elem_vec[vec[i].GetPort() != nullptr){
		  throw
		}
		if(vec[i] < vec[i + 1]) {
		  Basis b(vec[i], vec[i+1]);
		  auto iter = set_b.insert(b);
		  if(iter.second == false){
		    cout << "caught same junction basis:" << b[0] << "," << b[1] << endl;
		  }else{
		    basis_list->push_back(b);
		  }
		}else{
		  Basis b(vec[i+1], vec[i]);
		  auto iter = set_b.insert(b);
		  if(iter.second == false){
		    cout << "caught same junction basis:" << b[0] << "," << b[1] << endl;
		  }else{
		    basis_list->push_back(b);
		  }
		}
	  }
	}
  }
  Msg::Debug("basis num : %d", basis_list->size());
}

std::string RWGBasis::str() const
{
  stringstream ss;
  ss.precision(15);
  ss << "RWGBasis Begin >>>>>>" << endl;
  ss << "{Elements:" << endl;
  if (this->IsHalfbasis()){
    ss << "Element 0 :" << this->element[0]->GetIndex() << endl;
	ss << "Element 1 : -1" << endl;
  }else{
    ss << "Element 0 :" << this->element[0]->GetIndex() << endl;
	ss << "Element 1 :" << this->element[1]->GetIndex() << endl;
  }
  
  if (port){
    ss << "belongs to " << port->GetPortName() << endl;
  }else{
    ss << "belongs to no Port" << endl;
  }
  
  ss << "}" << endl;
  ss << "{Common Length:" << endl;
  ss << common_length << endl;
  ss << "}" << endl;
  ss << "{Origin Point: " << endl;
  ss << "original_point[0] << endl;
  ss << "original_point[1] << endl;
  ss << "}" << endl;
  
  ss << "{Current Direction:" << endl;
  ss << current_direction[0] << endl;
  ss << current_direction[1] << endl;
  ss << "}" << endl;
  ss << "{Rho Vec List:" << endl;
  ss << "Rho 0:" << endl;
  
  for (int i = 0; i < rho_vec_list[0].size(); i++){
    ss << rho_vec_list[0][i][0] << "  " << rho_vec_list[0][i][1] << " " << rho_vec_list[0][i][2] << endl;
  }
  ss << "Rho: " << endl;
  for (int i = 0; i < rho_vec_list[1].size(); i++){
    ss << rho_vec_list[1][i][0] << "  " << rho_vec_list[1][i][1] << " " << rho_vec_list[1][i][2] << endl;
  }
  ss << "}” << endl;
  ss << "{Diff Rho 0:" << endl;
  for (int i = 0; i < diff_rho_vec_list[0].size(); i++){
    ss << diff_rho_vec_list[0][i][0] << "  " << diff_rho_vec_list[0][i][1] << " " << diff_rho_vec_list[0][i][2] << endl;
  }
  ss << "Diff Rho 0 :" << endl;
  for (int i = 0; i < diff_rho_vec_list[1].size(); i++){
     ss << diff_rho_vec_list[1][i][0] << "  " << diff_rho_vec_list[1][i][1] << " " << diff_rho_vec_list[1][i][2] << endl;
  }
  ss << "{" << endl;
  
  ss << "RWGBasis End ======" << endl;
  return ss.str();
}

void RWGBasis::print() const
{
  cout << this->str() << endl;
}

}









 

 类似资料: