Exemplo n.º 1
0
// select min weight edge
Graph SccGraph(const Graph &g) {
  vector<vector<int> > scc = Scc(g);
  const int n = g.size();
  const int m = scc.size();
  vector<int> mapto(n);
  for (int i = 0; i < (int)scc.size(); i++) {
    for (int j = 0; j < (int)scc[i].size(); j++) {
      mapto[scc[i][j]] = i;
    }
  }
  Graph ret(m);
  vector<int> indexs(m, -1);
  for (int from = 0; from < m; from++) {
    int e = 0;
    for (int i = 0; i < (int)scc[from].size(); i++) {
      for (Edges::const_iterator it = g[scc[from][i]].begin(); it != g[scc[from][i]].end(); it++) {
        int to = mapto[it->dest];
        if (from == to) { continue; } // loopback
        if (indexs[to] == -1) {
          ret[from].push_back(Edge(from, to, it->weight));
          indexs[to] = e++;
        } else {
          // select edge
          ret[from][indexs[to]].weight = min(ret[from][indexs[to]].weight, it->weight);
        }
      }
    }
    for (Edges::const_iterator it = ret[from].begin(); it != ret[from].end(); it++) {
      indexs[it->dest] = -1;
    }
  }
  return ret;
}
Exemplo n.º 2
0
    bool processArgs(int argc, char** argv, const std::string&) {
        std::vector<std::string> args = mapto(argc, argv);
        if(argc < 3 || args[1] != "-c") {
            Log::log() << "Not a command: " << argc << args[1] 
                << std::endl;
            return false;
        }

        std::vector<std::string> cmd = unescapeCmd(args[2]);        

        if(cmd[0] != kScpCommand && cmd[0] != kSftpCommand) {
            Log::log() << "Not an ssh command: " << args[2] << std::endl;
            return false;
        }

        const char** newargv = tocarray(cmd);

        Log::log() << "Switching to " << cmd[0] << " with arguments " <<
            cmd << std::endl;

        execvp(cmd[0].c_str(), const_cast<char**>(newargv));

        // Should not be reached.
        return true;
    }
Exemplo n.º 3
0
int TMOGUIToneSlider::UpdateValues(bool bGamma)
{
	if (pValues)
	{
		switch (iMode)
		{
		case 0:
			pValues->dRMinimum = pValues->dGMinimum = pValues->dBMinimum = mapto((double)iBlack / (s.width() - 1));
			pValues->dRMaximum = pValues->dGMaximum = pValues->dBMaximum = mapto((double)iWhite / (s.width() - 1));
			if (bGamma)
			{
				pValues->dRGamma = pValues->dGGamma = pValues->dBGamma = (double)(iGamma - iBlack) / (iWhite - iBlack);
				if ((pValues->dRGamma > .49) && (pValues->dRGamma < .51)) pValues->dRGamma = pValues->dGGamma = pValues->dBGamma = .5;
				pValues->dRGamma = pValues->dGGamma = pValues->dBGamma = log(0.5) / log(pValues->dRGamma);
			}
			break;
		case 1:
			pValues->dRMinimum = mapto((double)iBlack / (s.width() - 1));
			pValues->dRMaximum = mapto((double)iWhite / (s.width() - 1));
			if (bGamma)
			{
				pValues->dRGamma = (double)(iGamma - iBlack) / (iWhite - iBlack);
				if ((pValues->dRGamma > .49) && (pValues->dRGamma < .51)) pValues->dRGamma = .5;
				pValues->dRGamma = log(0.5) / log(pValues->dRGamma);
			}
			break;
		case 2:
			pValues->dGMinimum = mapto((double)iBlack / (s.width() - 1));
			pValues->dGMaximum = mapto((double)iWhite / (s.width() - 1));
			if (bGamma)
			{
				pValues->dGGamma = (double)(iGamma - iBlack) / (iWhite - iBlack);
				if ((pValues->dGGamma > .49) && (pValues->dGGamma < .51)) pValues->dGGamma = .5;
				pValues->dGGamma = log(0.5) / log(pValues->dGGamma);
			}
			break;
		case 3:
			pValues->dBMinimum = mapto((double)iBlack / (s.width() - 1));
			pValues->dBMaximum = mapto((double)iWhite / (s.width() - 1));
			if (bGamma)
			{
				pValues->dBGamma = (double)(iGamma - iBlack) / (iWhite - iBlack);
				if ((pValues->dBGamma > .49) && (pValues->dBGamma < .51)) pValues->dBGamma = .5;
				pValues->dBGamma = log(0.5) / log(pValues->dBGamma);
			}
			break;
		}
	}
	update();
	pValues->UpdateValues();
	return 0;
}
void FlowBasedGlobalConstraint::augmentStructure(Graph &graph, StoreCost &cost, int varindex, map<Value, Cost> &delta) {

	for (map<Value, Cost>::iterator i = delta.begin(); i != delta.end();i++) {
		pair<int,int> edge = mapto(varindex, i->first);
		if (!graph.increaseCost(edge.first, edge.second, -i->second)) {
			graph.increaseCost(edge.second, edge.first, i->second);
			cost -= i->second;
		}
	}

}
Exemplo n.º 5
0
trieNode childRevTrie (revtrie T, trieNode i, uint depth, byte c, 
			trieNode *lzl, trieNode *lzr)

   { trieNode j;
     trieNode jlz;
     uint d,pos,jid;
     byte tc;
#ifdef QUERYREPORT
     BCALLS++;
#endif
     j = i+1;
#ifdef QUERYREPORT
		DEPTH1 += depth;
#endif
     while (!bitget1(T->data,j)) // there is a child here
	{ pos = leftrankRevTrie(T,j); 
	  jid = rthRevTrie(T,pos); // leftmost id in subtree
	  jlz = mapto(T->map,jid);
	  for (d=depth;d;d--) jlz = parentLZTrie(T->trie,jlz);
#ifdef QUERYREPORT
		RJUMPS++;
		DEPTH += depth;
#endif
	  tc = letterLZTrie(T->trie,jlz);
	  if (tc > c) break;
	  if (tc == c)
	     { *lzl = jlz; 
	       if ((pos < T->n-1) && (rthRevTrie(T,pos+1) == jid)) // empty
	          { pos = rightrankRevTrie(T,j); 
	            jlz = mapto(T->map,rthRevTrie(T,pos)); // rightmost
	            for (d=depth;d;d--) jlz = parentLZTrie(T->trie,jlz);
	            *lzr = jlz;
		  }
	       else *lzr = NULLT;
	       return j; 
	     }
	  j = findclose(T->pdata,j)+1;
	}
     *lzl = *lzr = NULLT;
     return NULLT; // no child to go down by c
   }
Exemplo n.º 6
0
void TMOGUIToneSlider::paintEvent ( QPaintEvent * pe)
{
	QPainter p(pBackBuffer);
	int col;
//	double val;

	p.setClipRect(pe->rect());

	for (int i = 0; i < s.width(); i++)
	{
		/*val = 256.0 * exp(5 * ((double)i / s.width() - 1));
		if (bLog) col = (int)val;
		else col = i * 256 / s.width();
		*/
		col = 256 * mapto((double)i / (s.width() - 1));
		if (col > 255) col = 255;
		switch(iMode)
		{
		case 1:
			p.setPen(QColor(col, 0, 0));
			break;
		case 2:
			p.setPen(QColor(0, col, 0));
			break;
		case 3:
			p.setPen(QColor(0, 0, col));
			break;
		default:
			p.setPen(QColor(col, col, col));
			break;
		}
		p.drawLine(i,0,i,9);
	}
	p.fillRect(0,10,s.width(),10,QBrush(QColor(255,255,255)));
	DrawMarker(&p, iBlack, QColor(0,0,0));
	DrawMarker(&p, iGamma, QColor(128,128,128));
	DrawMarker(&p, iWhite, QColor(255,255,255));
	p.drawLine(iBlack, 9, iBlack, 7);
	p.drawLine(iWhite, 9, iWhite, 7);
	p.fillRect(iBlack + 1, 3, iWhite - iBlack, 4, QBrush(QColor(255,255,255)));
	p.drawRect(iBlack, 2, iWhite - iBlack + 1, 5);
	bitBlt(this, 0, 0, pBackBuffer, 0, 0, s.width(), s. height(), CopyROP);	
}
void FlowBasedGlobalConstraint::findProjection(Graph &graph, StoreCost &cost, int varindex, map<Value, Cost> &delta) {

	//if (ToulBar2::GCLevel == LC_NC) return;

	pair<Cost, bool> result;
	delta.clear();
	EnumeratedVariable* x = (EnumeratedVariable*)getVar(varindex);
	for (EnumeratedVariable::iterator j = x->begin(); j != x->end(); ++j) {
		pair<int,int> edge = mapto(varindex, *j);
		Cost tmp = cost;
		//vector<Cost> weight = graph.getWeight(edge.first, edge.second);
		//if (!weight.empty()) {
		if (graph.edgeExist(edge.first, edge.second)) {
			if (zeroEdges[edge.first][edge.second]) {
				//cout << "good\n";
				tmp = cost;
			} else {
				vector<pair<int, int> > edges;
				result = graph.augment(edge.second, edge.first, false, edges);
				/*if (!result.second) {
				  printf("error! no shortest path\n");
				  exit(0);
				  }*/
				//tmp = cost+result.first+weight[0];
				tmp = cost+result.first + graph.getMinWeight(edge.first, edge.second);
				zeroEdges[edge.first][edge.second] = true;
				for (vector<pair<int,int> >::iterator i = edges.begin();i !=
						edges.end();i++) {
					zeroEdges[i->first][i->second] = true;
				}
			}
		}
		assert(tmp >= 0);
		delta[*j] = tmp;
	}

}
Exemplo n.º 8
0
inline uint Rev(lzindex I, uint rpos)
 {
    return mapto(I.Rev,rpos);
 }
Exemplo n.º 9
0
inline uint RNODE(lzindex I, uint id)
 {
    return mapto(I.rmap,id);
 }
Exemplo n.º 10
0
void FlowBasedGlobalConstraint::checkRemoved(Graph &graph, StoreCost &cost, vector<int> &rmv) {

	//if (ToulBar2::GCLevel == LC_NC) return;
		
	pair<Cost, bool> result;
	vector<int> cDomain, cDomain2;
	bool deleted = false;
	for (int i=0;i<arity_;i++) {
		cDomain.clear();
		getDomainFromGraph(graph, i, cDomain);
		sort(cDomain.begin(), cDomain.end());
		EnumeratedVariable* y = (EnumeratedVariable*)getVar(i);
		for (EnumeratedVariable::iterator v = y->begin(); v != y->end();++v) {
			vector<int>::iterator it = find(cDomain.begin(), cDomain.end(), *v);
			if (it == cDomain.end()) {
				cout << "non exist a value ?" << endl;
				for (vector<int>::iterator v=cDomain.begin();v != cDomain.end();v++) {
					cout << *v << " ";
				} cout << endl;
				for (EnumeratedVariable::iterator v = y->begin(); v != y->end();++v) {
					cout << *v << " ";
				} cout << endl;
				graph.print();
				exit(0);
			}
			cDomain.erase(it);
			deleted = true;
		}
		if (!cDomain.empty()) {
			//bool flag = false;
			cDomain2.clear();
			rmv.push_back(i);
			for (vector<int>::iterator v=cDomain.begin();v != cDomain.end();v++) {
				pair<int, int> edge = mapto(i, *v);
				if (!graph.removeEdge(edge.first, edge.second)) {
					cDomain2.push_back(*v);
				}
			}
			for (vector<int>::iterator v=cDomain2.begin();v != cDomain2.end();v++) {
				pair<int, int> edge = mapto(i, *v);
				vector<Cost> weight = graph.getWeight(edge.second, edge.first);
				if (weight.size() == 0) {				
					cout << "error for non-existence of egde (" << edge.second << "," << edge.first << ")\n";
					graph.print();
					exit(0);
				}
				result = graph.augment(edge.first, edge.second, true);
				if (result.second) {
					//flag = true;
					cost += weight[0]+result.first;
					result.second = graph.removeEdge(edge.first, edge.second);
				}
				if (!result.second) {
					cout << "ERROR cannot delete egde (" << edge.second << "," << edge.first << ")\n";
					graph.print();
					exit(0);
				}
			}
			if (cost > 0) graph.removeNegativeCycles(cost);
			deleted = true;
		}
	}
	if (deleted) {
		for (int i=0;i<graph.size() && (zeroEdges != NULL);i++) {
			for (int j=0;j<graph.size();j++) {	
				zeroEdges[i][j] = false;
			}
		}
	}	

}
Exemplo n.º 11
0
uint rthRevTrie(revtrie T, uint pos)
 { 
    return rthLZTrie(T->trie, leftrankLZTrie(T->trie,mapto(T->Rev,getposRevTrie(T,pos))));
 }
Exemplo n.º 12
0
/*
    Philippose Rajan - 11 June 2009
    
    Added an initial experimental function for 
    generating prismatic boundary layers on 
    a given set of surfaces.
    
    The number of layers, height of the first layer 
    and the growth / shrink factor can be specified 
    by the user

    Currently, the layer height is calculated using:
    height = h_first_layer * (growth_factor^(num_layers - 1))
*/
   void GenerateBoundaryLayer (Mesh & mesh, MeshingParameters & mp)
   {
      int i, j;

      ofstream dbg("BndLayerDebug.log");

      // Angle between a surface element and a growth-vector below which 
      // a prism is project onto that surface as a quad
      // (in degrees)
      double angleThreshold = 5.0;
      
      cout << "Generate Prismatic Boundary Layers (Experimental)...." << endl;

      // Use an array to support creation of boundary 
      // layers for multiple surfaces in the future...
      Array<int> surfid;
      int surfinp = 0;
      int prismlayers = 1;
      double hfirst = 0.01;
      double growthfactor = 1.0;

      // Monitor and print out the number of prism and quad elements 
      // added to the mesh
      int numprisms = 0;
      int numquads = 0;

      while(surfinp >= 0)
      {
         cout << "Enter Surface ID (-1 to end list): ";
         cin >> surfinp;
         if(surfinp >= 0) surfid.Append(surfinp);
      }

      cout << "Number of surfaces entered = " << surfid.Size() << endl; 
      cout << "Selected surfaces are:" << endl;

      for(i = 1; i <= surfid.Size(); i++)
      {
         cout << "Surface " << i << ": " << surfid.Elem(i) << endl;
      }
      
      cout << endl << "Enter number of prism layers: ";
      cin >> prismlayers;
      if(prismlayers < 1) prismlayers = 1;

      cout << "Enter height of first layer: ";
      cin >> hfirst;
      if(hfirst <= 0.0) hfirst = 0.01;

      cout << "Enter layer growth / shrink factor: ";
      cin >> growthfactor;
      if(growthfactor <= 0.0) growthfactor = 0.5;

      cout << "Old NP: " << mesh.GetNP() << endl;
      cout << "Old NSE: " << mesh.GetNSE() << endl;
      
      for(int layer = prismlayers; layer >= 1; layer--)
      {
         cout << "Generating layer: " << layer << endl;

         const MeshTopology& meshtopo = mesh.GetTopology();
         const_cast<MeshTopology &> (meshtopo).SetBuildEdges(true);
         const_cast<MeshTopology &> (meshtopo).SetBuildFaces(true);
         const_cast<MeshTopology &> (meshtopo).Update();

         double layerht = hfirst;

         if(growthfactor == 1)
         {
            layerht = layer * hfirst;
         }
         else
         {
            layerht = hfirst*(pow(growthfactor,(layer+1)) - 1)/(growthfactor - 1);
         }

         cout << "Layer Height = " << layerht << endl;

         // Need to store the old number of points and 
         // surface elements because there are new points and 
         // surface elements being added during the process
         int np = mesh.GetNP();
         int nse = mesh.GetNSE();

         // Safety measure to ensure no issues with mesh 
         // consistency
         int nseg = mesh.GetNSeg();

         // Indicate which points need to be remapped
         BitArray bndnodes(np);

         // Map of the old points to the new points
         Array<int> mapto(np);

         // Growth vectors for the prismatic layer based on 
         // the effective surface normal at a given point
         Array<Vec3d> growthvectors(np);

         // Bit array to identify all the points belonging 
         // to the surface of interest
         bndnodes.Clear();

         // Run through all the surface elements and mark the points 
         // belonging to those where a boundary layer has to be created.
         // In addition, also calculate the effective surface normal 
         // vectors at each of those points to determine the mesh motion 
         // direction
         cout << "Marking points for remapping...." << endl;

         for (i = 1; i <= nse; i++)
         {
            int snr = mesh.SurfaceElement(i).GetIndex();
            // cout << "snr = " << snr << endl;
            if (surfid.Contains(snr))
            {
               Element2d & sel = mesh.SurfaceElement(i);
               int selNP = sel.GetNP();
               for(j = 1; j <= selNP; j++)
               {
                  // Set the bitarray to indicate that the 
                  // point is part of the required set
                  bndnodes.Set(sel.PNum(j));
		  
                  // Vec3d& surfacenormal = Vec3d();   ????
                  Vec3d surfacenormal;

                  // Calculate the surface normal at the current point 
                  // with respect to the current surface element
                  GetSurfaceNormal(mesh,sel,j,surfacenormal);
                  
                  // Add the surface normal to the already existent one 
                  // (This gives the effective normal direction at corners 
                  //  and curved areas)
                  growthvectors.Elem(sel.PNum(j)) = growthvectors.Elem(sel.PNum(j)) 
                                                    + surfacenormal;
               }
            }
         }

         // Add additional points into the mesh structure in order to 
         // clone the surface elements.
         // Also invert the growth vectors so that they point inwards, 
         // and normalize them
         cout << "Cloning points and calculating growth vectors...." << endl;

         for (i = 1; i <= np; i++)
         {
            if (bndnodes.Test(i))
            {
               mapto.Elem(i) = mesh.AddPoint (mesh.Point (i));

               growthvectors.Elem(i).Normalize();
               growthvectors.Elem(i) *= -1.0;
            }
            else
            {
               mapto.Elem(i) = 0;
               growthvectors.Elem(i) = Vec3d(0,0,0);
            }
         }


         // Add quad surface elements at edges for surfaces which 
         // dont have boundary layers

         // Bit array to keep track of segments already processed
         BitArray segsel(nseg);

         // Set them all to "1" to initially activate all segments
         segsel.Set();

         cout << "Adding 2D Quad elements on required surfaces...." << endl;

         for (i = 1; i <= nseg; i++)
         {
            int seg_p1 = mesh.LineSegment(i)[0];
            int seg_p2 = mesh.LineSegment(i)[1];

            // Only go in if the segment is still active, and if both its 
            // surface index is part of the "hit-list"
            if(segsel.Test(i) && surfid.Contains(mesh.LineSegment(i).si))
            {
               // clear the bit to indicate that this segment has been processed
               segsel.Clear(i);

               // Find matching segment pair on other surface
               for(j = 1; j <= nseg; j++)
               {
                  int segpair_p1 = mesh.LineSegment(j)[1];
                  int segpair_p2 = mesh.LineSegment(j)[0];

                  // Find the segment pair on the neighbouring surface element
                  // Identified by: seg1[0] = seg_pair[1] and seg1[1] = seg_pair[0]
                  if(segsel.Test(j) && ((segpair_p1 == seg_p1) && (segpair_p2 == seg_p2)))
                  {
                     // clear bit to indicate that processing of this segment is done
                     segsel.Clear(j);

                     // Only worry about those surfaces which are not in the 
                     // boundary layer list
                     if(!surfid.Contains(mesh.LineSegment(j).si))
                     {
		        int pnt_commelem = 0;
			int pnum_commelem = 0;
                        Array<int> pnt1_elems;
                        Array<int> pnt2_elems;
                       
                            
                        meshtopo.GetVertexSurfaceElements(segpair_p1,pnt1_elems);
                        meshtopo.GetVertexSurfaceElements(segpair_p2,pnt2_elems);
                        for(int k = 1; k <= pnt1_elems.Size(); k++)
                        {
                           Element2d pnt1_sel = mesh.SurfaceElement(pnt1_elems.Elem(k));
                           for(int l = 1; l <= pnt2_elems.Size(); l++)
                           {
                              Element2d pnt2_sel = mesh.SurfaceElement(pnt2_elems.Elem(l));
                              if((pnt1_sel.GetIndex() == mesh.LineSegment(j).si) 
                                 && (pnt2_sel.GetIndex() == mesh.LineSegment(j).si)
                                 && (pnt1_elems.Elem(k) == pnt2_elems.Elem(l)))
                              {
                                 pnt_commelem = pnt1_elems.Elem(k);
                              }
                           }
                        }

                        for(int k = 1; k <= mesh.SurfaceElement(pnt_commelem).GetNP(); k++)
                        {
                           if((mesh.SurfaceElement(pnt_commelem).PNum(k) != segpair_p1)
                              && (mesh.SurfaceElement(pnt_commelem).PNum(k) != segpair_p2))
                           {
                              pnum_commelem = mesh.SurfaceElement(pnt_commelem).PNum(k);
                           }
                        }

                        Vec3d surfelem_vect, surfelem_vect1;
                        
                        Element2d & commsel = mesh.SurfaceElement(pnt_commelem);

                        dbg << "NP= " << commsel.GetNP() << " : ";

                        for(int k = 1; k <= commsel.GetNP(); k++)
                        {
                           GetSurfaceNormal(mesh,commsel,k,surfelem_vect1);
                           surfelem_vect += surfelem_vect1;
                        }

                        surfelem_vect.Normalize();

                        double surfangle = Angle(growthvectors.Elem(segpair_p1),surfelem_vect);

                        dbg << "V1= " << surfelem_vect1 
                            << " : V2= " << surfelem_vect1
                            << " : V= " << surfelem_vect
                            << " : GV= " << growthvectors.Elem(segpair_p1)
                            << " : Angle= " << surfangle * 180 / 3.141592;

                  
                        // remap the segments to the new points
                        mesh.LineSegment(i)[0] = mapto.Get(seg_p1);
                        mesh.LineSegment(i)[1] = mapto.Get(seg_p2);
                        mesh.LineSegment(j)[1] = mapto.Get(seg_p1);
                        mesh.LineSegment(j)[0] = mapto.Get(seg_p2);

                        if((surfangle < (90 + angleThreshold) * 3.141592 / 180.0)
                           && (surfangle > (90 - angleThreshold) * 3.141592 / 180.0))
                        {
                           dbg << " : quad\n";
                           // Since the surface is lower than the threshold, change the effective 
                           // prism growth vector to match with the surface vector, so that 
                           // the Quad which is created lies on the original surface
                           //growthvectors.Elem(segpair_p1) = surfelem_vect;

                           // Add a quad element to account for the prism volume
                           // element which is going to be added 
                           Element2d sel(QUAD);
                           sel.PNum(4) = mapto.Get(seg_p1);
                           sel.PNum(3) = mapto.Get(seg_p2);
                           sel.PNum(2) = segpair_p2;
                           sel.PNum(1) = segpair_p1;
                           sel.SetIndex(mesh.LineSegment(j).si);
                           mesh.AddSurfaceElement(sel);
                           numquads++;
                        }
                        else
                        {
                           dbg << "\n";
                           for (int k = 1; k <= pnt1_elems.Size(); k++)
                           {
                              Element2d & pnt_sel = mesh.SurfaceElement(pnt1_elems.Elem(k));
                              if(pnt_sel.GetIndex() == mesh.LineSegment(j).si)
                              {
                                 for(int l = 1; l <= pnt_sel.GetNP(); l++)
                                 {
                                    if(pnt_sel.PNum(l) == segpair_p1)
                                    {
                                       pnt_sel.PNum(l) = mapto.Get(seg_p1);
                                    }
                                    else if(pnt_sel.PNum(l) == segpair_p2)
                                    {
                                       pnt_sel.PNum(l) = mapto.Get(seg_p2);
                                    }
                                 }
                              }
                           }

                           for (int k = 1; k <= pnt2_elems.Size(); k++)
                           {
                              Element2d & pnt_sel = mesh.SurfaceElement(pnt2_elems.Elem(k));
                              if(pnt_sel.GetIndex() == mesh.LineSegment(j).si)
                              {
                                 for(int l = 1; l <= pnt_sel.GetNP(); l++)
                                 {
                                    if(pnt_sel.PNum(l) == segpair_p1)
                                    {
                                       pnt_sel.PNum(l) = mapto.Get(seg_p1);
                                    }
                                    else if(pnt_sel.PNum(l) == segpair_p2)
                                    {
                                       pnt_sel.PNum(l) = mapto.Get(seg_p2);
                                    }
                                 }
                              }
                           }
                        }
                     }
                     else
                     {
                        // If the code comes here, it indicates that we are at 
                        // a line segment pair which is at the intersection 
                        // of two surfaces, both of which have to grow boundary 
                        // layers.... here too, remapping the segments to the 
                        // new points is required
                        mesh.LineSegment(i)[0] = mapto.Get(seg_p1);
                        mesh.LineSegment(i)[1] = mapto.Get(seg_p2);
                        mesh.LineSegment(j)[1] = mapto.Get(seg_p1);
                        mesh.LineSegment(j)[0] = mapto.Get(seg_p2);
                     }
                  }
               }
            }
         }

         // Add prismatic cells at the boundaries
         cout << "Generating prism boundary layer volume elements...." << endl;

         for (i = 1; i <= nse; i++)
         {
            Element2d & sel = mesh.SurfaceElement(i);
            if(surfid.Contains(sel.GetIndex()))
            {
               Element el(PRISM);
               for (j = 1; j <= sel.GetNP(); j++)
               {
                  // Check (Doublecheck) if the corresponding point has a 
                  // copy available for remapping
                  if (mapto.Get(sel.PNum(j)))
                  {
                     // Define the points of the newly added Prism cell
                     el.PNum(j+3) = mapto.Get(sel.PNum(j));
                     el.PNum(j) = sel.PNum(j);
                  }
               }

               el.SetIndex(1);
               el.Invert();
               mesh.AddVolumeElement(el);
               numprisms++;
            }
         }

         // Finally switch the point indices of the surface elements 
         // to the newly added ones
         cout << "Transferring boundary layer surface elements to new vertex references...." << endl;

         for (i = 1; i <= nse; i++)
         {
            Element2d & sel = mesh.SurfaceElement(i);
            if(surfid.Contains(sel.GetIndex()))
            {
               for (j = 1; j <= sel.GetNP(); j++)
               {
                  // Check (Doublecheck) if the corresponding point has a 
                  // copy available for remapping
                  if (mapto.Get(sel.PNum(j)))
                  {
                     // Map the surface elements to the new points
                     sel.PNum(j) = mapto.Get(sel.PNum(j));
                  }
               }
            }
         }

         // Lock all the prism points so that the rest of the mesh can be 
         // optimised without invalidating the entire mesh
         for (PointIndex pi = mesh.Points().Begin(); pi < mesh.Points().End(); pi++)
         {
           if(bndnodes.Test(i)) mesh.AddLockedPoint(pi);
         }

         // Now, actually pull back the old surface points to create 
         // the actual boundary layers
         cout << "Moving and optimising boundary layer points...." << endl;
         
         for (i = 1; i <= np; i++)
         {
            Array<ElementIndex> vertelems;

            if(bndnodes.Test(i))
            {
               MeshPoint pointtomove;

               pointtomove = mesh.Point(i);

               if(layer == prismlayers)
               {
                  mesh.Point(i).SetPoint(pointtomove + layerht * growthvectors.Elem(i));

                  meshtopo.GetVertexElements(i,vertelems);

                  for(j = 1; j <= vertelems.Size(); j++)
                  {
		    // double sfact = 0.9;
                     Element volel = mesh.VolumeElement(vertelems.Elem(j));
                     if(((volel.GetType() == TET) || (volel.GetType() == TET10)) && (!volel.IsDeleted()))
                     {
                        //while((volel.Volume(mesh.Points()) <= 0.0) && (sfact >= 0.0))
                        //{
                        //   mesh.Point(i).SetPoint(pointtomove + (sfact * layerht * growthvectors.Elem(i)));
                        //   mesh.ImproveMesh();

                        //   // Try to move the point back by one step but 
                        //   // if the volume drops to below zero, double back
                        //   mesh.Point(i).SetPoint(pointtomove + ((sfact + 0.1) * layerht * growthvectors.Elem(i)));
                        //   if(volel.Volume(mesh.Points()) <= 0.0)
                        //   {
                        //      mesh.Point(i).SetPoint(pointtomove + (sfact * layerht * growthvectors.Elem(i)));
                        //   }
                        //   sfact -= 0.1;
                        //}
                        volel.Delete();
                     }
                  }

                  mesh.Compress();
               }
               else
               {
                  mesh.Point(i).SetPoint(pointtomove + layerht * growthvectors.Elem(i));
               }
            }
         }
      }

      // Optimise the tet part of the volume mesh after all the modifications 
      // to the system are completed
      //OptimizeVolume(mparam,mesh);

      cout << "New NP: " << mesh.GetNP() << endl;
      cout << "Num of Quads: " << numquads << endl;
      cout << "Num of Prisms: " << numprisms << endl;
      cout << "Boundary Layer Generation....Done!" << endl;

      dbg.close();
   }