diff --git a/Mesh/yamakawa.cpp b/Mesh/yamakawa.cpp
index b305a491efc3ef63947c7950d6bf31be24343ba7..692ae31b78a78036dfd4ef650aa78214c0518f4e 100755
--- a/Mesh/yamakawa.cpp
+++ b/Mesh/yamakawa.cpp
@@ -86,6 +86,60 @@ bool Hex::operator<(const Hex& hex) const{
   return quality>hex.get_quality();
 }
 
+/****************class Facet****************/
+
+Facet::Facet(){}
+
+Facet::Facet(MVertex* a2,MVertex* b2,MVertex* c2){
+  a = a2;
+  b = b2;
+  c = c2;
+  compute_hash();
+}
+
+Facet::~Facet(){}
+
+MVertex* Facet::get_a(){
+  return a;
+}
+
+MVertex* Facet::get_b(){
+  return b;
+}
+
+MVertex* Facet::get_c(){
+  return c;
+}
+
+void Facet::set_vertices(MVertex* a2,MVertex* b2,MVertex* c2){
+  a = a2;
+  b = b2;
+  c = c2;
+  compute_hash();
+}
+
+bool Facet::same_vertices(Facet facet){
+  bool c1,c2,c3;
+	
+  c1 = (a==facet.get_a()) || (a==facet.get_b()) || (a==facet.get_c());
+  c2 = (b==facet.get_a()) || (b==facet.get_b()) || (b==facet.get_c());
+  c3 = (c==facet.get_a()) || (c==facet.get_b()) || (c==facet.get_c());
+	
+  return c1 && c2 && c3;
+}
+
+void Facet::compute_hash(){
+  hash = (unsigned long long)a + (unsigned long long)b + (unsigned long long)c;
+}
+
+unsigned long long Facet::get_hash() const{
+  return hash;
+}
+
+bool Facet::operator<(const Facet& facet) const{
+  return hash<facet.get_hash();
+}
+
 /****************class Recombinator****************/
 
 Recombinator::Recombinator(){}
@@ -111,14 +165,19 @@ void Recombinator::execute(GRegion* gr){
 
   build_vertex_to_vertices(gr);
   build_vertex_to_elements(gr);
+  printf("connectivity\n");
 
   potential.clear();
   patern1(gr);
+  printf("patern no. 1\n");
   patern2(gr);
+  printf("patern no. 2\n");
   patern3(gr);
-
+  printf("patern no. 3\n");
+	
   std::sort(potential.begin(),potential.end());
 
+  hash_table.clear();	
   merge(gr);
 
   rearrange(gr);
@@ -145,10 +204,7 @@ void Recombinator::patern1(GRegion* gr){
   MElement* element;
   MVertex *a,*b,*c,*d;
   MVertex *p,*q,*r,*s;
-  std::vector<MVertex*> already1;
-  std::vector<MVertex*> already2;
-  std::vector<MVertex*> already3;
-  std::vector<MVertex*> already4;
+  std::vector<MVertex*> already;
   std::set<MVertex*> bin1;
   std::set<MVertex*> bin2;
   std::set<MVertex*> bin3;
@@ -168,54 +224,44 @@ void Recombinator::patern1(GRegion* gr){
 	c = element->getVertex((index+2)%4);
 	d = element->getVertex((index+3)%4);
 
-	already1.clear();
-	already1.push_back(a);
-	already1.push_back(b);
-	already1.push_back(c);
-	already1.push_back(d);
+	already.clear();
+	already.push_back(a);
+	already.push_back(b);
+	already.push_back(c);
+	already.push_back(d);
 	bin1.clear();
-	find(b,d,already1,bin1);
+	bin2.clear();
+	bin3.clear();
+	find(b,d,already,bin1);
+	find(b,c,already,bin2);
+	find(c,d,already,bin3);
+
 	for(it1=bin1.begin();it1!=bin1.end();it1++){
 	  p = *it1;
-	  already2.clear();
-	  already2.push_back(a);
-	  already2.push_back(b);
-	  already2.push_back(c);
-	  already2.push_back(d);
-	  already2.push_back(p);
-	  bin2.clear();
-	  find(b,c,already2,bin2);
 	  for(it2=bin2.begin();it2!=bin2.end();it2++){
 	    q = *it2;
-		already3.clear();
-		already3.push_back(a);
-		already3.push_back(b);
-		already3.push_back(c);
-		already3.push_back(d);
-		already3.push_back(p);
-		already3.push_back(q);
-		bin3.clear();
-		find(c,d,already3,bin3);
 	    for(it3=bin3.begin();it3!=bin3.end();it3++){
 		  r = *it3;
-		  already4.clear();
-		  already4.push_back(a);
-		  already4.push_back(b);
-		  already4.push_back(c);
-		  already4.push_back(d);
-		  already4.push_back(p);
-		  already4.push_back(q);
-		  already4.push_back(r);
-		  bin4.clear();
-		  find(p,q,r,already4,bin4);
-		  for(it4=bin4.begin();it4!=bin4.end();it4++){
-			s = *it4;
-			hex = Hex(a,b,q,c,d,p,s,r);
-			quality = min_scaled_jacobian(hex);
-			hex.set_quality(quality);
-			if(valid(hex)){
-			  potential.push_back(hex);
-			}
+		  if(p!=q && p!=r && q!=r){
+		    already.clear();
+		    already.push_back(a);
+		    already.push_back(b);
+		    already.push_back(c);
+		    already.push_back(d);
+		    already.push_back(p);
+		    already.push_back(q);
+		    already.push_back(r);
+		    bin4.clear();
+		    find(p,q,r,already,bin4);
+		    for(it4=bin4.begin();it4!=bin4.end();it4++){
+			  s = *it4;
+			  hex = Hex(a,b,q,c,d,p,s,r);
+			  quality = min_scaled_jacobian(hex);
+			  hex.set_quality(quality);
+			  if(valid(hex)){
+			    potential.push_back(hex);
+			  }
+		    }
 		  }
 		}
 	  }
@@ -395,9 +441,11 @@ void Recombinator::patern3(GRegion* gr){
 void Recombinator::merge(GRegion* gr){
   unsigned int i;
   int count;
+  int idle;
   bool flag;
   double threshold;
   double quality;
+  double coeff;
   MVertex *a,*b,*c,*d;
   MVertex *e,*f,*g,*h;
   MElement* element;
@@ -408,6 +456,7 @@ void Recombinator::merge(GRegion* gr){
   Hex hex;
 
   count = 1;
+  idle = 0;
   quality = 0.0;
 
   for(i=0;i<potential.size();i++){
@@ -452,6 +501,10 @@ void Recombinator::merge(GRegion* gr){
 	  flag = 0;
 	}
 
+	if(!conformity(hex)){
+	  flag = 0;
+	}
+
 	if(flag){
 	  printf("%d - %d/%d - %f\n",count,i,(int)potential.size(),hex.get_quality());
 	  quality = quality + hex.get_quality();
@@ -461,8 +514,18 @@ void Recombinator::merge(GRegion* gr){
 		it2->second = 1;
 	  }
 	  gr->addHexahedron(new MHexahedron(a,b,c,d,e,f,g,h));
+	  build_hash_table(hex);
+	  idle = 0;
 	  count++;
 	}
+	else{
+	  idle++;
+	}
+	  
+	coeff = 0.1;  
+	if((double)idle>coeff*(double)potential.size() && potential.size()>2000){
+	  break;
+	}
   }
 
   it3 = gr->tetrahedra.begin();
@@ -1018,6 +1081,64 @@ bool Recombinator::inclusion(MVertex* v1,MVertex* v2,MVertex* v3,const std::set<
   return ok;
 }
 
+bool Recombinator::inclusion(Facet facet){
+  bool flag;
+  std::multiset<Facet>::iterator it;
+	
+  it = hash_table.find(facet);
+  flag = 0;
+	
+  while(it!=hash_table.end()){
+    if(facet.get_hash()!=it->get_hash()){
+	  break;
+	}
+		
+	if(facet.same_vertices(*it)){
+	  flag = 1;
+	  break;
+	}
+		
+	it++;
+  }
+	
+  return flag;
+}
+
+bool Recombinator::conformity(Hex hex){
+  bool c1,c2,c3,c4,c5,c6;
+  MVertex *a,*b,*c,*d;
+  MVertex *e,*f,*g,*h;
+	
+  a = hex.get_a();
+  b = hex.get_b();
+  c = hex.get_c();
+  d = hex.get_d();
+  e = hex.get_e();
+  f = hex.get_f();
+  g = hex.get_g();
+  h = hex.get_h();
+	
+  c1 = conformity(a,b,c,d);
+  c2 = conformity(e,f,g,h);
+  c3 = conformity(a,b,f,e);
+  c4 = conformity(b,c,g,f);
+  c5 = conformity(d,c,g,h);
+  c6 = conformity(d,a,e,h);
+	
+  return c1 && c2 && c3 && c4 && c5 && c6;
+}
+
+bool Recombinator::conformity(MVertex* a,MVertex* b,MVertex* c,MVertex* d){
+  bool c1,c2,c3,c4;
+	
+  c1 = inclusion(Facet(a,b,c));
+  c2 = inclusion(Facet(a,c,d));
+  c3 = inclusion(Facet(a,b,d));
+  c4 = inclusion(Facet(b,c,d));
+	
+  return (c1 && c2 && c3 && c4) || (!c1 && !c2 && !c3 && !c4);
+}
+
 void Recombinator::build_vertex_to_vertices(GRegion* gr){
   size_t i;
   int j;
@@ -1081,6 +1202,59 @@ void Recombinator::build_vertex_to_elements(GRegion* gr){
   }
 }
 
+void Recombinator::build_hash_table(Hex hex){
+  MVertex *a,*b,*c,*d;
+  MVertex *e,*f,*g,*h;
+	
+  a = hex.get_a();
+  b = hex.get_b();
+  c = hex.get_c();
+  d = hex.get_d();
+  e = hex.get_e();
+  f = hex.get_f();
+  g = hex.get_g();
+  h = hex.get_h();
+	
+  build_hash_table(a,b,c,d);
+  build_hash_table(e,f,g,h);
+  build_hash_table(a,b,f,e);
+  build_hash_table(b,c,g,f);
+  build_hash_table(d,c,g,h);
+  build_hash_table(d,a,e,h);
+}
+
+void Recombinator::build_hash_table(MVertex* a,MVertex* b,MVertex* c,MVertex* d){
+  build_hash_table(Facet(a,b,c));
+  build_hash_table(Facet(a,c,d));
+  build_hash_table(Facet(a,b,d));
+  build_hash_table(Facet(b,d,c));
+}
+
+void Recombinator::build_hash_table(Facet facet){
+  bool flag;
+  std::multiset<Facet>::iterator it;
+	
+  it = hash_table.find(facet);
+  flag = 1;
+	
+  while(it!=hash_table.end()){
+    if(facet.get_hash()!=it->get_hash()){
+	  break;
+	}
+		
+	if(facet.same_vertices(*it)){
+	  flag = 0;
+	  break;
+	}
+		
+	it++;
+  }
+	
+  if(flag){
+    hash_table.insert(facet);
+  }	
+}
+
 void Recombinator::print_vertex_to_vertices(GRegion* gr){
   size_t i;
   int j;
@@ -1127,6 +1301,14 @@ void Recombinator::print_vertex_to_elements(GRegion* gr){
   }
 }
 
+void Recombinator::print_hash_table(){
+  std::multiset<Facet>::iterator it;
+	
+  for(it=hash_table.begin();it!=hash_table.end();it++){
+    printf("%lld\n",it->get_hash());
+  }
+}
+
 void Recombinator::print_segment(SPoint3 p1,SPoint3 p2,std::ofstream& file){
   file << "SL ("
   << p1.x() << ", " << p1.y() << ", " << p1.z() << ", "
diff --git a/Mesh/yamakawa.h b/Mesh/yamakawa.h
index 930190209a04d9075655ab3699095956dcc4d7b0..9dbce321968d964a5fcf990098652d21b0656b71 100755
--- a/Mesh/yamakawa.h
+++ b/Mesh/yamakawa.h
@@ -31,12 +31,31 @@ class Hex{
   bool operator<(const Hex&) const;
 };
 
+class Facet{
+ private:
+  MVertex *a,*b,*c;
+  unsigned long long hash;
+ public:
+  Facet();
+  Facet(MVertex*,MVertex*,MVertex*);
+  ~Facet();
+  MVertex* get_a();
+  MVertex* get_b();
+  MVertex* get_c();
+  void set_vertices(MVertex*,MVertex*,MVertex*);
+  bool same_vertices(Facet);
+  void compute_hash();
+  unsigned long long get_hash() const;
+  bool operator<(const Facet&) const;
+};
+
 class Recombinator{
  private:
   std::vector<Hex> potential;
   std::map<MElement*,bool> markings;
   std::map<MVertex*,std::set<MVertex*> > vertex_to_vertices;
   std::map<MVertex*,std::set<MElement*> > vertex_to_elements;
+  std::multiset<Facet> hash_table;
  public:
   Recombinator();
   ~Recombinator();
@@ -76,11 +95,20 @@ class Recombinator{
   bool inclusion(MVertex*,Hex);
   bool inclusion(MVertex*,MVertex*,MVertex*,MVertex*,MVertex*);
   bool inclusion(MVertex*,MVertex*,MVertex*,const std::set<MElement*>&);
+  bool inclusion(Facet);
   
+  bool conformity(Hex);
+  bool conformity(MVertex*,MVertex*,MVertex*,MVertex*);
+	
   void build_vertex_to_vertices(GRegion*);
   void build_vertex_to_elements(GRegion*);
+  void build_hash_table(Hex);
+  void build_hash_table(MVertex*,MVertex*,MVertex*,MVertex*);
+  void build_hash_table(Facet);
+  
   void print_vertex_to_vertices(GRegion*);
   void print_vertex_to_elements(GRegion*);
+  void print_hash_table();
   void print_segment(SPoint3,SPoint3,std::ofstream&);
 	
   double scaled_jacobian(MVertex*,MVertex*,MVertex*,MVertex*);