Example #1
0
void MazeRouter::routePowerNet(oaInt4 nid) {
    //We assume that each contact that needs to connect to VDD can route directly up in Metal1.
    //We assume that each contact that needs to connect to VSS can route directly down in Metal1.
    //This appears reasonable with the given test cases, and the knowledge of P/N diffusion regions and normal CMOS logic.
    oaUInt4 dim_m, dim_n, dim_k = 0;
    __grid->getDims(&dim_m, &dim_n, &dim_k);
	
	//Metal 1 cannot be used to route vertically to VDD/VSS if it's direction is not V or B
	//Use metal 2 instead if that's the case
	//oaUInt4 layer = 0;
	//if(__rules->getMetal1Direction() == 'H') {
	//	layer = 1;
	//}

    //cout << "In routePowerNet! dim_m = " << dim_m << " dim_n = " << dim_n << endl; //Weiche
    //Let's loop through all contacts that are on the net, and generate their routes one-by-one.
    for (oaInt4 i = 0; i < __contactCells[nid].size(); i++) {
        Cell* contact = __contactCells[nid][i];
        oaUInt4 m,n,k = 0;
        contact->getPosition(&m, &n, &k);
        oaInt4 j = n;
        bool done = false;
		
		//if(layer == 1) {
		//	contact->setNeedsVia();
		//}
		
		//int nCellsInRail=11; //Weiche
		//int nCellsInRail=0; //Weiche	
			while (!done) { //Iterate through cells until we hit a rail
            //cout<<"before at m="<<m<<" j="<<j<<" k="<<k<<endl; //Weiche
			Cell* curr = __grid->at(m,j,k);
			//Cell* curr = __grid->at(m,j,layer);
			//Cell* vdd_vss = __grid->at(m,j,k);
            //cout<<"after at m="<<m<<" j="<<j<<" k="<<k; //Weiche
			CellStatus status = curr->getStatus();
			//CellStatus status2 = vdd_vss->getStatus();
            oaUInt4 net_id = curr->getNetID();
            //oaUInt4 net_id2 = vdd_vss->getNetID();
			
			//Check cell underneath to see it it's vdd or vss
			/*if(layer == 1) {
				if(status2 == CellVDDRail && nid == VDD_NET_ID) {
					done = true;
					/*__grid->at(m,j+1,layer)->setBacktrace(__grid->at(m,j,layer));
					__grid->at(m,j+2,layer)->setBacktrace(__grid->at(m,j+1,layer));
					__grid->at(m,j+3,layer)->setBacktrace(__grid->at(m,j+2,layer));
					__grid->at(m,j+4,layer)->setBacktrace(__grid->at(m,j+3,layer));
					__grid->at(m,j+5,layer)->setBacktrace(__grid->at(m,j+4,layer));
					__grid->at(m,j+5,0)->setBacktrace(__grid->at(m,j+5,layer));
					__grid->at(m,j+5,0)->setNeedsVia();
					vdd_vss->setNeedsVia();
					vdd_vss->setBacktrace(curr);
				}
				else if(status2 == CellVSSRail && nid == VSS_NET_ID) {
					done = true;
					/*__grid->at(m,j-1,layer)->setBacktrace(__grid->at(m,j,layer));
					__grid->at(m,j-2,layer)->setBacktrace(__grid->at(m,j-1,layer));
					__grid->at(m,j-3,layer)->setBacktrace(__grid->at(m,j-2,layer));
					__grid->at(m,j-4,layer)->setBacktrace(__grid->at(m,j-3,layer));
					__grid->at(m,j-5,layer)->setBacktrace(__grid->at(m,j-4,layer));
					__grid->at(m,j-5,0)->setBacktrace(__grid->at(m,j-5,layer));
					__grid->at(m,j-5,0)->setNeedsVia();
					vdd_vss->setNeedsVia();
					vdd_vss->setBacktrace(curr);
				}
			}*/

            switch (status) {
                case CellVDDRail:
				//cout<<"  case CellVDDRail"<<endl; //Weiche
                    if (nid == VDD_NET_ID)
					{
						/*if(nCellsInRail>0) //Weiche
						{
							curr->setStatus(CellFilled);
			                curr->setNetType(contact->getNetType());
				            curr->setNetID(nid);
							nCellsInRail--;
							if(nCellsInRail==5)
								curr->setNeedsVia();
						}*/
						/*if(nCellsInRail==0){ //Weiche
							curr->setStatus(CellFilled);
			                curr->setNetType(contact->getNetType());
				            curr->setNetID(nid);
							curr->setNeedsVia();
							done = true;
						}*/
                        done = true;
					}
                    else {
                        cout << "Somehow hit the VDD rail while routing VSS!" << endl;
						__foundRoute = false;
                        //__grid->print();
                        exit(1);
                    }
                    break;
                case CellVSSRail:
                    //cout<<"  case CellVSSRail"<<endl; //Weiche
                    if (nid == VSS_NET_ID){
						/*if(nCellsInRail>0) //Weiche
						{
							curr->setStatus(CellFilled);
			                curr->setNetType(contact->getNetType());
				            curr->setNetID(nid);
							nCellsInRail--;
							if(nCellsInRail==5)
								curr->setNeedsVia();
						}*/
						/* if(nCellsInRail==0){ //Weiche
							curr->setStatus(CellFilled);
			                curr->setNetType(contact->getNetType());
				            curr->setNetID(nid);
							curr->setNeedsVia();
							done = true;
						}*/
                        done = true;
					}
                    else {
                        cout << "Somehow hit the VSS rail while routing VDD!" << endl;
						__foundRoute = false;
                        //__grid->print();
                        exit(1);
                    }
                    break;
                case CellFilled:
                    //cout<<"  case CellFilled"<<endl; //Weiche
                case CellContact:
				    //cout<<"  case CellContact"<<endl; //Weiche
                    if (net_id != nid) {
						//cout << "net_id = " << net_id << " nid = " << nid << endl; //Weiche
                        cout << "We have a problem routing power net " << contact->getNetType() << "! We hit an occupied cell that wasn't ours. Here's the Grid." << endl;
						__foundRoute = false;
                        //cout<<"m: "<<m<<", j: "<<j<<", k: "<<k<<endl; //Weiche
						//__grid->print();
                        exit(1);
                    }
                    break;
                case CellKeepout:
				    //cout<<"  case CellKeepout"<<endl; //Weiche
                    cout << "We have a problem routing power net " << contact->getNetType() << "! We hit a keepout region. Here's the Grid." << endl;
                    __foundRoute = false;
                    __grid->print();
                    exit(1);
                    break;
                case CellFree:
				    //cout<<"  case CellFree"<<endl; //Weiche
                    curr->setStatus(CellFilled);
                    curr->setNetType(contact->getNetType());
                    curr->setNetID(nid);
                    break;
            }
                       
            if (nid == VDD_NET_ID) {
                //create backtrace
				//if(i == 1)
				//	curr->setBacktrace(__grid->at(m,j-1,k));
                if (i > 0)
                    curr->setBacktrace(__grid->at(m,j-1,k));
                j++;
            } else {
                //create backtrace
				//if(i == 1)
				//	curr->setBacktrace(__grid->at(m,j+1,k));
                if (i > 0)
                    curr->setBacktrace(__grid->at(m,j+1,k));
                j--;
            }
        }       
    }
} 
Example #2
0
void Margolus::PareEnergyFull(Cell& cellIn, Cell& cellOut, double& energy) {
    // modifier & active in one cell
    for (pSub & subA : cellIn.GetSubs()) {
        if (subA->GetType() == ACTIVE) {
            for (pSub & subM : cellIn.GetSubs()) {
                if (subM->GetType() == MODIFIER) {
                    energy += GetEnergyCell(subA->GetName(), subM->GetName());
                }
            }
        }
    }
    // other
    if (cellOut.HaveSolid()) {
        if (cellIn.HaveModifier()) {
            for (pSub & subIn : cellIn.GetSubs()) {
                if (subIn->GetType() != ACTIVE) {
                    energy += GetEnergy(subIn->GetName(), cellOut.GetSub(0)->GetName());
                }
            }
        } else {
            for (pSub & subIn : cellIn.GetSubs()) {
                energy += GetEnergy(subIn->GetName(), cellOut.GetSub(0)->GetName());
            }
        }
    } else {
        if (cellIn.HaveSolid()) {
            if (cellOut.HaveModifier()) {
                for (pSub & subOut : cellOut.GetSubs()) {
                    if (subOut->GetType() != ACTIVE) {
                        energy += GetEnergy(subOut->GetName(), cellIn.GetSub(0)->GetName());
                    }
                }
            } else {
                for (pSub & subOut : cellOut.GetSubs()) {
                    energy += GetEnergy(subOut->GetName(), cellIn.GetSub(0)->GetName());
                }
            }
        } else {
            for (pSub & subIn : cellIn.GetSubs()) {
                for (pSub & subOut : cellOut.GetSubs()) {
                    energy += GetEnergy(subIn->GetName(), subOut->GetName());
                }
            }
        }
    }
}
Example #3
0
//The core function which summarizes the data and forms the pivot table.
void PivotMain::Summarize()
{
  
    
    Map* myMap = d->selection->lastSheet()->map();
    const QRect range3=d->selection->lastRange();
    Sheet* sheet=myMap->createSheet("Filtered Sheet");
    
    sheet=filter();
    if(sheet==d->selection->lastSheet())
    {
      d->filtersize=range3.bottom();
    }
    const QRect range(1,1,d->selection->lastRange().right(),d->filtersize);
    
    QColor color,color2("lightGray");
    color.setBlue(50);
    QPen pen(color);
    

    Style st,st2,st3,str,stl,stb,stt;
    st.setFontUnderline(true);
    st3.setBackgroundColor("lightGray");
    st.setRightBorderPen(pen);
    st.setLeftBorderPen(pen);
    st.setTopBorderPen(pen);
    st.setBottomBorderPen(pen);
    str.setRightBorderPen(pen);
    stl.setLeftBorderPen(pen);
    stt.setTopBorderPen(pen);
    stb.setBottomBorderPen(pen);
    
    
    static int z=1;
    
    Sheet* mySheet=myMap->createSheet("Pivot Sheet"+QString::number(z++));
    
    int r = range.right();
    int row=range.top();
    int bottom=range.bottom();
    Cell cell;
    
    ValueConverter *c;
    
    Value res(0);
    ValueCalc *calc= new ValueCalc(c);
    
    QVector<Value> vect;    
    for (int i = 1; i <= r; ++i) {
	cell= Cell(sheet,i,row);
	vect.append(Value(cell.value()));
    }

  d->func=d->mainWidget.selectOption->currentText();//check for the function to be performed
  
  //For Creating QLists for Rows,Columns,Values and PageField
  int counter;
  QListWidgetItem *item1;
  QList<QListWidgetItem *> rowList,columnList,valueList,pageList;
  
  counter= d->mainWidget.Rows->count();
  for(int i=0;i<counter;i++)
  {
	
        item1=d->mainWidget.Rows->item(i);
        rowList.append(item1);
    
  }
  counter= d->mainWidget.Columns->count();
  for(int i=0;i<counter;i++)
  {
	
        item1=d->mainWidget.Columns->item(i);
        columnList.append(item1); 
  }
  /*counter= d->mainWidget.PageFields->count();
  for(int i=0;i<counter;i++)
  {
        item1=d->mainWidget.PageFields->item(i);
        pageList.append(item1);
  }*/
  counter= d->mainWidget.Values->count();
  for(int i=0;i<counter;i++)
  {
        item1=d->mainWidget.Values->item(i);
        valueList.append(item1); 
  }
  
  //Summarization using vectors
  int rowpos=-1,colpos=-1,valpos=-1;
  QVector<Value> rowVector;
  QVector<QVector<Value> > rowVectorArr(rowList.size());
  QVector<QVector<Value> > columnVectorArr(columnList.size());
  QVector<Value> columnVector,valueVector;
  QVector<int> rowposVect,colposVect,valposVect;
  
  for(int i=0;i<rowList.size();i++)
  {
      rowpos=vect.indexOf(Value(rowList.at(i)->text()));
      for(int j=row+1;j<=bottom;j++)
      {
	cell =Cell(sheet,rowpos+1,j);
	if(rowVector.contains(Value(cell.value()))==0)
	{
	  rowVector.append(Value(cell.value()));
	  rowVectorArr[i].append(Value(cell.value()));
      
	}  
      }
      rowposVect.append(rowpos);
  }
    
  for(int i=0;i<columnList.size();i++)
  {
      colpos=vect.indexOf(Value(columnList.at(i)->text()));
      for(int j=row+1;j<=bottom;j++)
      {
	cell =Cell(sheet,colpos+1,j);
	if(columnVector.contains(Value(cell.value()))==0)
	{
 	columnVector.append(Value(cell.value()));
	columnVectorArr[i].append(Value(cell.value()));
	}
      }
      colposVect.append(colpos);
  }
  
  int count=1,count2=0,prevcount=1;
  QVector<QVector<Value> > rowVect(rowposVect.count());
  for(int i=0;i<rowposVect.count();i++)
  {
    for(int j=i+1;j<rowposVect.count();j++)
    {
      count*=rowVectorArr[j].count();
    }
    for(int k=0;k<(rowVectorArr[i].count())*prevcount;k++)
    {
      Cell(mySheet,((k)*count)+1+colposVect.count(),i+1).setValue(rowVectorArr[i].at(k%rowVectorArr[i].count()));
     
      for(int l=0;l<count;l++)
	rowVect[i].append(rowVectorArr[i].at(k%rowVectorArr[i].count()));
      
      count2++;
    }
    prevcount=count2;
    count=1;
    count2=0;
  }

  count=1,count2=0,prevcount=1;
  QVector<QVector<Value> > colVect(colposVect.count());
  for(int i=0;i<colposVect.count();i++)
  {
    for(int j=i+1;j<colposVect.count();j++)
    {
      count*=columnVectorArr[j].count();
    }
    for(int k=0;k<(columnVectorArr[i].count())*prevcount;k++)
    {
       
      Cell(mySheet,i+1,((k)*count)+1+rowposVect.count()).setValue(columnVectorArr[i].at(k%columnVectorArr[i].count()));
//     Cell(mySheet,i+1,((k)*count)+1+rowposVect.count()).setStyle(st2);
      for(int l=0;l<count;l++)
	colVect[i].append(columnVectorArr[i].at(k%columnVectorArr[i].count()));
      
      count2++;
    }
    
    
    prevcount=count2;
    count=1;
    count2=0;
  } 
  
  // Styling
  
  for(int m=0;m<colVect[0].count();m++)
    {
      Cell(mySheet,1,m+1+rowList.count()).setStyle(stl);
      Cell(mySheet,columnList.count(),m+1+rowList.count()).setStyle(str);
      Cell(mySheet,columnList.count()+rowVect[0].count(),m+1+rowList.count()).setStyle(str);
      
    }
  
  
  for(int m=0;m<rowVect[0].count();m++)
    {
      Cell(mySheet,m+1+columnList.count(),1).setStyle(stt);
      Cell(mySheet,m+1+columnList.count(),rowList.count()).setStyle(stb);
      Cell(mySheet,m+1+columnList.count(),rowList.count()+colVect[0].count()).setStyle(stb);
      
    }
    
   for(int m=0;m<rowList.count();m++)
    {
      Cell(mySheet,columnList.count()+1,m+1).setStyle(stl);
      Cell(mySheet,columnList.count()+rowVect[0].count(),m+1).setStyle(str);
    }
  
  
  for(int m=0;m<columnList.count();m++)
    {
      Cell(mySheet,m+1,rowList.count()+1).setStyle(stt);
      Cell(mySheet,m+1,rowList.count()+colVect[0].count()).setStyle(stb);
    } 
      
    
    
    
   //Styling Done
  
  for(int i=0;i<valueList.size();i++)
  {
     valpos=vect.indexOf(Value(valueList.at(i)->text()));
     valposVect.append(valpos);    
  }
  
  
  QString title=d->func + "-" + valueList.at(0)->text();
  Cell(mySheet,1,1).setValue(Value(title));
  Cell(mySheet,1,1).setStyle(st);
  for(int l=0;l<rowVect[0].count();l++)
  {
    for(int m=0;m<colVect[0].count();m++)
      {

	      QVector<Value> aggregate;
	      for(int k=row+1;k<=bottom;k++)
	      {
		int flag=0;
		for(int i=0;i<rowposVect.count();i++)
		{
		  for(int j=0;j<colposVect.count();j++)
		    {
 
		      if(!(Cell(sheet,rowposVect.at(i)+1,k).value()==rowVect[i].at(l) && Cell(sheet,colposVect.at(j)+1,k).value()==colVect[j].at(m)))
			flag=1;
		      
		    }
		  }
		if(flag==0)
		aggregate.append(Cell(sheet,valpos+1,k).value());
	      }
		if(d->func!="average")
		calc->arrayWalk(aggregate,res,calc->awFunc(d->func),Value(0));
 		
		else
		{
		  calc->arrayWalk(aggregate,res,calc->awFunc("sum"),Value(0));
		  if(aggregate.count()!=0)
		  res=calc->div(res,aggregate.count());
		  
		}
		Cell(mySheet,l+colposVect.count()+1,m+rowposVect.count()+1).setValue(res);
		if(m%2==0)
		  Cell(mySheet,l+colposVect.count()+1,m+rowposVect.count()+1).setStyle(st3);
		
		aggregate.clear();
		res=Value(0);
	    
      }
    }
  
  
  //For Adding the functions: Total Rows & Total Columns
  int colmult=1,rowmult=1;
  
  for(int x=0;x<columnList.size();x++)
  colmult*=columnVectorArr[x].count();
  
  for(int x=0;x<rowList.size();x++)
  rowmult*=rowVectorArr[x].count();
  
  
  
  
  //Totalling Columns
  
  if(d->mainWidget.TotalColumns->isChecked())
  {
    
  Cell(mySheet,1,rowList.size()+colmult+1).setValue(Value("Total Column"));
  
  for(int z=columnList.size()+1;z<=rowmult+columnList.size();z++)
  {
    QVector<Value> vector;
    for(int y=rowList.size()+1;y<=colmult+rowList.size();y++)
    {
      vector.append(Cell(mySheet,z,y).value());
      
    }
    if(d->func!="average")
      calc->arrayWalk(vector,res,calc->awFunc(d->func),Value(0));
    else
    {
      calc->arrayWalk(vector,res,calc->awFunc("sum"),Value(0));
      if(vector.count()!=0)
	  res=calc->div(res,vector.count());
    }
    
    
    Cell(mySheet,z,rowList.size()+colmult+1).setValue(res);
    res=Value(0);
    
  }
  }
  
  
  //Totalling Rows
  if(d->mainWidget.TotalRows->isChecked())
  {
    
  Cell(mySheet,columnList.size()+rowmult+1,1).setValue(Value("Total Row"));
    
  for(int z=rowList.size()+1;z<=colmult+rowList.size();z++)
  {
    QVector<Value> vector;
    for(int y=columnList.size()+1;y<=rowmult+columnList.size();y++)
    {
      vector.append(Cell(mySheet,y,z).value());
      
    }
    
    if(d->func!="average")
      calc->arrayWalk(vector,res,calc->awFunc(d->func),Value(0));
    else
    {
      calc->arrayWalk(vector,res,calc->awFunc("sum"),Value(0));
      if(vector.count()!=0)
	  res=calc->div(res,vector.count());
    }
    
    Cell(mySheet,columnList.size()+rowmult+1,z).setValue(res);
    res=Value(0);
     
  }
  }
  
  //Clearing Vectors
  rowVector.clear();
  columnVector.clear();
  valueVector.clear();
  rowposVect.clear();
  colposVect.clear();
  valposVect.clear();
  
  //Adding built sheet to myMap for viewing
  myMap->addSheet(mySheet);
  
}//Summarize
double GlobalPlanner::getRisk(Cell & cell) {
  double risk = explorePenalty;
  if (occProb.find(cell) != occProb.end()) {
    risk = octomap::probability(occProb[cell]);
  }
  Cell front = Cell(cell.x()+1, cell.y(), cell.z());
  Cell back = Cell(cell.x()-1, cell.y(), cell.z());
  Cell right = Cell(cell.x(), cell.y()+1, cell.z());
  Cell left = Cell(cell.x(), cell.y()-1, cell.z());
  Cell up = Cell(cell.x(), cell.y(), cell.z()+1);
  Cell down = Cell(cell.x(), cell.y(), cell.z()-1);
  if (occProb.find(front) != occProb.end()) {
    risk += octomap::probability(occProb[front]);
  }
  if (occProb.find(back) != occProb.end()) {
    risk += octomap::probability(occProb[back]);
  }
  if (occProb.find(right) != occProb.end()) {
    risk += octomap::probability(occProb[right]);
  }
  if (occProb.find(left) != occProb.end()) {
    risk += octomap::probability(occProb[left]);
  }
  if (occProb.find(up) != occProb.end()) {
    risk += octomap::probability(occProb[up]);
  }
  if (occProb.find(down) != occProb.end()) {
    risk += octomap::probability(occProb[down]);
  }
  double prior = heightPrior[floor(cell.z())];
  // ROS_INFO("risk: %f \t prior: %f \n", risk, prior);
  return risk * prior;
}
double distance2D(const Cell & a, const Cell & b) {
  return sqrt(squared(a.x() - b.x()) + squared(a.y() - b.y()));
}
Example #6
0
bool MainWindow::updateConnections()
{
  bool newconnection[BoardSize * BoardSize];
  for(int i = 0; i < BoardSize * BoardSize; i++)
    newconnection[i] = false;

  CellList list;
  if(!root->isRotated())
  {
    newconnection[root->index()] = true;
    list.append(root);
  }
  while(!list.isEmpty())
  {
    Cell* cell = list.first();
    Cell* ucell = uCell(cell);
    Cell* rcell = rCell(cell);
    Cell* dcell = dCell(cell);
    Cell* lcell = lCell(cell);

    if((cell->dirs() & Cell::U) && ucell && (ucell->dirs() & Cell::D) && !newconnection[ucell->index()] && !ucell->isRotated())
    {
      newconnection[ucell->index()] = true;
      list.append(ucell);
    }
    if((cell->dirs() & Cell::R) && rcell && (rcell->dirs() & Cell::L) && !newconnection[rcell->index()] && !rcell->isRotated())
    {
      newconnection[rcell->index()] = true;
      list.append(rcell);
    }
    if((cell->dirs() & Cell::D) && dcell && (dcell->dirs() & Cell::U) && !newconnection[dcell->index()] && !dcell->isRotated())
    {
      newconnection[dcell->index()] = true;
      list.append(dcell);
    }
    if((cell->dirs() & Cell::L) && lcell && (lcell->dirs() & Cell::R) && !newconnection[lcell->index()] && !lcell->isRotated())
    {
      newconnection[lcell->index()] = true;
      list.append(lcell);
    }
    list.removeFirst();
  }

  bool isnewconnection = false;
  for(int i = 0; i < BoardSize * BoardSize; i++)
  {
    if(!board[i]->isConnected() && newconnection[i])
      isnewconnection = true;
    board[i]->setConnected(newconnection[i]);
  }

  return isnewconnection;
}
Example #7
0
//-----------------------------------------------------------------------------
std::size_t QuadrilateralCell::orientation(const Cell& cell) const
{
  const Point up(0.0, 0.0, 1.0);
  return cell.orientation(up);
}
Example #8
0
Cell* Parser::Parse_Define(Cell* cell, bool topLevel)
{
    UNUSED(topLevel);
    THROW_ERROR_IF(cell->Length() < 3, cell, "'define' does not take " << cell->Length() << " arguments");

    // Example: (define (add a b) (+ a b))
    // (define add (lambda (a b) (+ a b)))
    Cell* pParams = cell->Cdr()->Car();
    Cell* pBody = cell->Cdr()->Cdr();
               
    // (define (f args..) body)
    // Parse the arguments, if necessary, and call back into the Parse
    if (pParams->GetType() & Cell::PairType)
    {
        // f
        Cell* f = pParams->Car();

        // (Args)
        Cell* args = pParams->Cdr();

        // (define)
        Cell* pDefine = Cell::Pair(Cell::Symbol(Sym::Symbol("_define")), nullptr);
        
        // (lambda)
        Cell* pLambda = Cell::Pair(Cell::Symbol(Sym::Symbol("_lambda")), nullptr);
        
        // (lambda (args)
        pLambda = pLambda->Append(args);

        // (lambda (args) (body)
        // Body is a list of expressions. ((+ a a) ...)
        while (pBody && pBody->Car())
        {
            pLambda = pLambda->Append(pBody->Car());
            pBody = pBody->Cdr();
        }
        
        // (define f)
        pDefine = pDefine->Append(f);

        // (define f (lamda ...))
        pDefine = pDefine->Append(pLambda);

        return Parse_Cell(pDefine);
    }
    // A parsed define, ready to store
    else
    {
        THROW_ERROR_IF(cell->Length()!= 3, cell, "'define' does not take " << cell->Length() << " arguments");
        THROW_ERROR_IF(!(pParams->GetType() & Cell::SymbolType), cell, "Expected Symbol in define");
        
        pBody = Parse_Cell(pBody->Car());

        // (define)
        Cell* pDefine = Cell::Pair(Cell::Symbol(Sym::Symbol("_define")), nullptr);

        // (define (params)
        pDefine = pDefine->Append(pParams);

        // (define (params) (pBody))
        pDefine = pDefine->Append(pBody);

        return pDefine;
    }
}
Example #9
0
void Random::doorCell(Cell &cell) {
	cell.dungeonFloorA();
}
Example #10
0
bool MazeRouter::route() {
	 __foundRoute = true; //assume true until we find an issue

    cout << "Special routing power nets..." << endl;
    //cout << "Special routing power nets: " << VDD_NET_ID << " for VDD and " << VSS_NET_ID << " for VSS." << endl; //Weiche
    routePowerNet(VDD_NET_ID);
    routePowerNet(VSS_NET_ID);
    
    //Single-contact IO nets: special case. No routing, only pin needed, but it gets high priority.
    cout << "Generating pins for single-contact IO nets..." << endl;
    __grid->reset();
    for (oaInt4 net = 2; net < __contactCells.size(); net++) {
        if (__contactCells[net][0]->getNetType() == "IO" && __contactCells[net].size() == 1) { 
            oaUInt4 m,n,k = 0;
            Cell* c = __contactCells[net][0];
            c->getPosition(&m,&n,&k);
            
            //We want to do this at the contact M1, since M2 pins are not required.
            //Propagate pin name (used later in creating text label))
            __grid->at(m,n,k)->setPin(true);
            __grid->at(m,n,k)->setPinName(c->getPinName());
        }
    }
    
    //Multi-contact IO nets. Need routing. Choose pin location after routing is done
    cout << "Maze routing multi-contact IO nets..." << endl;
    for (oaInt4 net = 2; net < __contactCells.size(); net++) {
        if (__contactCells[net][0]->getNetType() == "IO" && __contactCells[net].size() > 1) {
            //Clean reset for each net
            __grid->reset();
            generateKeepouts(net);
            
            //Basic approach: route from contact to contact in order of appearance.
            for (oaInt4 contactIndex = 0; contactIndex < __contactCells[net].size()-1; contactIndex++) {
                __grid->softReset(); //Preserve keepouts during soft reset so we don't waste time recomputing them
                if (contactIndex == 0) //set pin during first segment
                    mazeRoute(net, contactIndex+1, contactIndex, true);
                else   
                    mazeRoute(net, contactIndex+1, contactIndex, false);
            }

            /*
            //Yasmine's "better" approach: route between closest pairs of contacts first. You are welcome to try this. Disabled by default.
            //Get closest pairs
            vector<ClosestPairIndices> closestPairs;
            closestPairs=ClosestPairIndices::getClosestPairs(__contactCells[net]);
            int nPairs=closestPairs.size();
            for (oaInt4 pairIndex = 0; pairIndex <nPairs; pairIndex++) {
                __grid->softReset(); //Preserve keepouts during soft reset so we don't waste time recomputing them
                if (pairIndex == 0) //set pin during first segment
                    mazeRoute(net, closestPairs[pairIndex].getIndex1(),
                                   closestPairs[pairIndex].getIndex2(), true);
                else   
                   mazeRoute(net, closestPairs[pairIndex].getIndex1(),
                                   closestPairs[pairIndex].getIndex2(), false);
            }
            */
        }
    }
    
    //Multi-contact S nets, no pins needed.
    cout << "Maze routing S nets..." << endl;
    for (oaInt4 net = 2; net < __contactCells.size(); net++) { //Mark: perhaps change this to order by HPWL bounding box of nets? Smallest first?
          //Reset the grid weights, distances, sources, and sinks. Clear any keepout cells that were leftover from a previous maze route.    
        if (__contactCells[net][0]->getNetType() == "S") {
            //Clean reset for each net
            __grid->reset();
            generateKeepouts(net); //Generate keepouts for all nets OTHER than this one!
           
            for (oaInt4 contactIndex = 0; contactIndex < __contactCells[net].size()-1; contactIndex++) {
                __grid->softReset();
                mazeRoute(net, contactIndex+1, contactIndex, false); //Assume we always have >=2 pins for this net type, otherwise it wouldn't even make sense.
            }

            /*
            //Yasmine's "better" approach: route between closest pairs of contacts first. You are welcome to try this. Disabled by default.
            vector<ClosestPairIndices> closestPairs;
            closestPairs=ClosestPairIndices::getClosestPairs(__contactCells[net]);
            int nPairs=closestPairs.size();
            for (oaInt4 pairIndex = 0; pairIndex <nPairs; pairIndex++) {
                __grid->softReset(); //Preserve keepouts during soft reset so we don't waste time recomputing them
                mazeRoute(net, closestPairs[pairIndex].getIndex1(),
                                   closestPairs[pairIndex].getIndex2(), false);
            }
            */
        }
    }
   
    __grid->reset();
    //__grid->print();
	
	 return __foundRoute;
}
	bool Cell::operator==(const Cell& other) const    
	{
	    return ((coordinateX == other.getX()) && (coordinateY == other.getY()));
	}
Example #12
0
void MazeRouter::generateKeepout(Cell* c) {
    oaUInt4 mtmp,ntmp,ktmp = 0;
    oaInt4 m,n,k = 0;
    oaUInt4 dim_m, dim_n, dim_k = 0;
    c->getPosition(&mtmp,&ntmp,&ktmp);
    m = mtmp;
    n = ntmp;
    k = ktmp;
    __grid->getDims(&dim_m, &dim_n, &dim_k);
    
    oaInt4 leftBound = 0;
    oaInt4 rightBound = 0;
    oaInt4 topBound = 0;
    oaInt4 bottomBound = 0;
    
    Cell* tmp = NULL;
    CellStatus tmpStatus;
    CellStatus cStatus = c->getStatus();
    
    
       //SET LATERAL AND LONGITUDINAL BOUNDS DEPENDING ON LAYER AND LINE END STATUS
    if (k == 0) { //metal1
		if(__rules->getMetal1Direction() == 'V') { //vertical only
			
			leftBound = m-__keepoutRadius_lateral;
			if (leftBound < 0)
				leftBound = 0;
			
			rightBound = m+__keepoutRadius_lateral;
			if (rightBound > dim_m-1)
				rightBound = dim_m-1;
			
			//check line end top condition
			if (n+1 < dim_n) {
				tmp = __grid->at(m,n+1,k); //get cell above
				tmpStatus = tmp->getStatus();
				if (tmpStatus == CellFilled || tmpStatus == CellContact) //not line end
					topBound = n;
				else { //line end
					if (cStatus == CellVDDRail || cStatus == CellVSSRail) //cell of interest is power rail
						 topBound = n+__keepoutRadius_powerRail;
					else //cell of interest is regular net
						 topBound = n+__keepoutRadius_longitudinal;
				}
				if (topBound > dim_n-1)
					topBound = dim_n-1;
			}
			
			//check line end bottom condition
			if (n-1 >= 0) {
				tmp = __grid->at(m,n-1,k); //get cell below
				tmpStatus = tmp->getStatus();
				if (tmpStatus == CellFilled || tmpStatus == CellContact) //not line end
					bottomBound = n;
				else { //line end
					if (cStatus == CellVDDRail || cStatus == CellVSSRail) //cell of interest is power rail
							bottomBound = n-__keepoutRadius_powerRail;
					else //cell of interest is regular net
							bottomBound = n-__keepoutRadius_longitudinal;
				}
				if (bottomBound < 0)
					bottomBound = 0;
			}
		}
		else if(__rules->getMetal1Direction() == 'H') { //horizontal only
			bottomBound = n-__keepoutRadius_lateral;
			if (bottomBound < 0)
				bottomBound = 0;
			
			topBound = n+__keepoutRadius_lateral;
			if (topBound > dim_n-1)
				topBound = dim_n-1;
			
			//check line end right condition
			if (m+1 < dim_m) {
				tmp = __grid->at(m+1,n,k); //get cell to right
				tmpStatus = tmp->getStatus();
				if (tmpStatus == CellFilled || tmpStatus == CellContact) //not line end
					rightBound = m;
				else //line end
					rightBound = m+__keepoutRadius_longitudinal;
				
				if (rightBound > dim_m-1)
					rightBound = dim_m-1;
			}
			
			//check line end left condition
			if (m-1 >= 0) {
				tmp = __grid->at(m-1,n,k); //get cell to left
				tmpStatus = tmp->getStatus();
				if (tmpStatus == CellFilled || tmpStatus == CellContact) //not line end
					leftBound = m;
				else //line end
					leftBound = m-__keepoutRadius_longitudinal;
				
				if (leftBound < 0)
					leftBound = 0;
			}
		}
		else { //bidirectional 
			Cell* tmptop;
			Cell* tmpbottom;
			Cell* tmpleft;
			Cell* tmpright;
			CellStatus tmptops;
			CellStatus tmpbottoms;
			CellStatus tmplefts;
			CellStatus tmprights;
			bool isVertical = false;
			
			//check cell above
			if (n + 1 < dim_n) {
				tmptop = __grid->at(m, n + 1, k);
				tmptops = tmptop->getStatus();
				if (tmptops == CellFilled || tmptops == CellContact){ //not line end
					topBound = n;
					isVertical = true;
				}
				else { //line end
					if (cStatus == CellVDDRail || cStatus == CellVSSRail) //cell of interest is power rail
						topBound = n + __keepoutRadius_powerRail;
					else //regular cell
						topBound = n + __keepoutRadius_longitudinal;
				}
				if (topBound > dim_n - 1)
					topBound = dim_n - 1;
			}
			//check cell below
			if (n - 1 >= 0) {
				tmpbottom = __grid->at(m, n - 1, k);
				tmpbottoms = tmpbottom->getStatus();
				if (tmpbottoms == CellFilled || tmpbottoms == CellContact){ //not line end
					bottomBound = n;
					isVertical = true;
				}
				else { //line end
					if (cStatus == CellVDDRail || cStatus == CellVSSRail) //cell of interest is power rail
						bottomBound = n - __keepoutRadius_powerRail;
					else
						bottomBound = n - __keepoutRadius_longitudinal;
				}
				if (bottomBound < 0)
					bottomBound = 0;
			}

			//Vertical segment - bounds on left and right sides
			if (isVertical) {
				//left side
				if (m - 1 >= 0) {
					tmpleft = __grid->at(m - 1, n, k);
					tmplefts = tmpleft->getStatus();
					if (tmplefts == CellFilled || tmplefts == CellContact) { //right corner connecting vertical and horizontal segments
						leftBound = m;
					}
					else { //left side is empty
						leftBound = m - __keepoutRadius_lateral;
						if (leftBound < 0)
							leftBound = 0;
					}
				}

				//right side
				if (m + 1 < dim_m) {
					tmpright = __grid->at(m + 1, n, k);
					tmprights = tmpright->getStatus();
					if (tmprights == CellFilled || tmprights == CellContact) { //left corner connecting vertical and horizontal segments
						rightBound = m;
					}
					else { //right side is empty
						rightBound = m + __keepoutRadius_lateral;
						if (rightBound > dim_m - 1)
							rightBound = dim_m - 1;
					}
				}
			}

			//if not verical then it's horizontal
			if (!isVertical) {
				if (m - 1 >= 0) {
					tmpleft = __grid->at(m - 1, n, k);
					tmplefts = tmpleft->getStatus();
					if (tmplefts == CellFilled || tmplefts == CellContact) //not line end
						leftBound = m;
					else //line end
						leftBound = m - __keepoutRadius_longitudinal;
					if (leftBound < 0)
						leftBound = 0;
				}

				if (m + 1 < dim_m) {
					tmpright = __grid->at(m + 1, n, k);
					tmprights = tmpright->getStatus();
					if (tmprights == CellFilled || tmprights == CellContact) //not line end
						rightBound = m;
					else //line end
						rightBound = m + __keepoutRadius_longitudinal;
					if (rightBound > dim_m - 1)
						rightBound = dim_m - 1;
				}
				topBound = n + __keepoutRadius_lateral;
				if (topBound > dim_n - 1)
					topBound = dim_n - 1;
				bottomBound = n - __keepoutRadius_lateral;
				if (bottomBound < 0)
					bottomBound = 0;
			}
		}
	}
	if (k == 1) { //metal2
		if(__rules->getMetal2Direction() == 'V') { //vertical only
			
			leftBound = m-__keepoutRadius_lateral;
			if (leftBound < 0)
				leftBound = 0;
			
			rightBound = m+__keepoutRadius_lateral;
			if (rightBound > dim_m-1)
				rightBound = dim_m-1;
			
			//check line end top condition
			if (n+1 < dim_n) {
				tmp = __grid->at(m,n+1,k); //get cell above
				tmpStatus = tmp->getStatus();
				if (tmpStatus == CellFilled || tmpStatus == CellContact) //not line end
					topBound = n;
				else { //line end
					if (cStatus == CellVDDRail || cStatus == CellVSSRail) //cell of interest is power rail
						 topBound = n+__keepoutRadius_powerRail;
					else //cell of interest is regular net
						 topBound = n+__keepoutRadius_longitudinal;
				}
				if (topBound > dim_n-1)
					topBound = dim_n-1;
			}
			
			//check line end bottom condition
			if (n-1 >= 0) {
				tmp = __grid->at(m,n-1,k); //get cell below
				tmpStatus = tmp->getStatus();
				if (tmpStatus == CellFilled || tmpStatus == CellContact) //not line end
					bottomBound = n;
				else { //line end
					if (cStatus == CellVDDRail || cStatus == CellVSSRail) //cell of interest is power rail
							bottomBound = n-__keepoutRadius_powerRail;
					else //cell of interest is regular net
							bottomBound = n-__keepoutRadius_longitudinal;
				}
				if (bottomBound < 0)
					bottomBound = 0;
			}
		}
		else if(__rules->getMetal2Direction() == 'H') { //horizontal only
			bottomBound = n-__keepoutRadius_lateral;
			if (bottomBound < 0)
				bottomBound = 0;
			
			topBound = n+__keepoutRadius_lateral;
			if (topBound > dim_n-1)
				topBound = dim_n-1;
			
			//check line end right condition
			if (m+1 < dim_m) {
				tmp = __grid->at(m+1,n,k); //get cell to right
				tmpStatus = tmp->getStatus();
				if (tmpStatus == CellFilled || tmpStatus == CellContact) //not line end
					rightBound = m;
				else //line end
					rightBound = m+__keepoutRadius_longitudinal;
				
				if (rightBound > dim_m-1)
					rightBound = dim_m-1;
			}
			
			//check line end left condition
			if (m-1 >= 0) {
				tmp = __grid->at(m-1,n,k); //get cell to left
				tmpStatus = tmp->getStatus();
				if (tmpStatus == CellFilled || tmpStatus == CellContact) //not line end
					leftBound = m;
				else //line end
					leftBound = m-__keepoutRadius_longitudinal;
				
				if (leftBound < 0)
					leftBound = 0;
			}
		}
		else if(__rules->getMetal2Direction() == 'B') { //bidirectional 
			Cell* tmptop;
			Cell* tmpbottom;
			Cell* tmpleft;
			Cell* tmpright;
			CellStatus tmptops;
			CellStatus tmpbottoms;
			CellStatus tmplefts;
			CellStatus tmprights;
			bool isVertical = false;
			
			//top
			if (n + 1 < dim_n) {
				tmptop = __grid->at(m, n + 1, k);
				tmptops = tmptop->getStatus();
				if (tmptops == CellFilled || tmptops == CellContact){ //not line end
					topBound = n;
					isVertical = true;
				}
				else { //line end
					if (cStatus == CellVDDRail || cStatus == CellVSSRail) //cell of interest is power rail
						topBound = n + __keepoutRadius_powerRail;
					else //regular cell
						topBound = n + __keepoutRadius_longitudinal;
				}
				if (topBound > dim_n - 1)
					topBound = dim_n - 1;
			}
			//bottom
			if (n - 1 >= 0) {
				tmpbottom = __grid->at(m, n - 1, k);
				tmpbottoms = tmpbottom->getStatus();
				if (tmpbottoms == CellFilled || tmpbottoms == CellContact){ //not line end
					bottomBound = n;
					isVertical = true;
				}
				else { //line end
					if (cStatus == CellVDDRail || cStatus == CellVSSRail) //cell of interest is power rail
						bottomBound = n - __keepoutRadius_powerRail;
					else
						bottomBound = n - __keepoutRadius_longitudinal;
				}
				if (bottomBound < 0)
					bottomBound = 0;
			}

			//Vertical segment - bounds on left and right sides
			if (isVertical) {
				//left side
				if (m - 1 >= 0) {
					tmpleft = __grid->at(m - 1, n, k);
					tmplefts = tmpleft->getStatus();
					if (tmplefts == CellFilled || tmplefts == CellContact) { //right corner connecting vertical and horizontal segments
						leftBound = m;
					}
					else { //left side is empty
						leftBound = m - __keepoutRadius_lateral;
						if (leftBound < 0)
							leftBound = 0;
					}
				}

				//right side
				if (m + 1 < dim_m) {
					tmpright = __grid->at(m + 1, n, k);
					tmprights = tmpright->getStatus();
					if (tmprights == CellFilled || tmprights == CellContact) { //left corner connecting vertical and horizontal segments
						rightBound = m;
					}
					else { //right side is empty
						rightBound = m + __keepoutRadius_lateral;
						if (rightBound > dim_m - 1)
							rightBound = dim_m - 1;
					}
				}
			}

			//if not verical then it's horizontal
			if (!isVertical) {
				if (m - 1 >= 0) {
					tmpleft = __grid->at(m - 1, n, k);
					tmplefts = tmpleft->getStatus();
					if (tmplefts == CellFilled || tmplefts == CellContact) //not line end
						leftBound = m;
					else //line end
						leftBound = m - __keepoutRadius_longitudinal;
					if (leftBound < 0)
						leftBound = 0;
				}

				if (m + 1 < dim_m) {
					tmpright = __grid->at(m + 1, n, k);
					tmprights = tmpright->getStatus();
					if (tmprights == CellFilled || tmprights == CellContact) //not line end
						rightBound = m;
					else //line end
						rightBound = m + __keepoutRadius_longitudinal;
					if (rightBound > dim_m - 1)
						rightBound = dim_m - 1;
				}
				topBound = n + __keepoutRadius_lateral;
				if (topBound > dim_n - 1)
					topBound = dim_n - 1;
				bottomBound = n - __keepoutRadius_lateral;
				if (bottomBound < 0)
					bottomBound = 0;
			}
		}
	}
	if (k == 2) { //metal3
		if(__rules->getMetal3Direction() == 'V') { //vertical only
			
			leftBound = m-__keepoutRadius_lateral;
			if (leftBound < 0)
				leftBound = 0;
			
			rightBound = m+__keepoutRadius_lateral;
			if (rightBound > dim_m-1)
				rightBound = dim_m-1;
			
			//check line end top condition
			if (n+1 < dim_n) {
				tmp = __grid->at(m,n+1,k); //get cell above
				tmpStatus = tmp->getStatus();
				if (tmpStatus == CellFilled || tmpStatus == CellContact) //not line end
					topBound = n;
				else { //line end
					if (cStatus == CellVDDRail || cStatus == CellVSSRail) //cell of interest is power rail
						 topBound = n+__keepoutRadius_powerRail;
					else //cell of interest is regular net
						 topBound = n+__keepoutRadius_longitudinal;
				}
				if (topBound > dim_n-1)
					topBound = dim_n-1;
			}
			
			//check line end bottom condition
			if (n-1 >= 0) {
				tmp = __grid->at(m,n-1,k); //get cell below
				tmpStatus = tmp->getStatus();
				if (tmpStatus == CellFilled || tmpStatus == CellContact) //not line end
					bottomBound = n;
				else { //line end
					if (cStatus == CellVDDRail || cStatus == CellVSSRail) //cell of interest is power rail
							bottomBound = n-__keepoutRadius_powerRail;
					else //cell of interest is regular net
							bottomBound = n-__keepoutRadius_longitudinal;
				}
				if (bottomBound < 0)
					bottomBound = 0;
			}
		}
		else if(__rules->getMetal3Direction() == 'H') { //horizontal only
			bottomBound = n-__keepoutRadius_lateral;
			if (bottomBound < 0)
				bottomBound = 0;
			
			topBound = n+__keepoutRadius_lateral;
			if (topBound > dim_n-1)
				topBound = dim_n-1;
			
			//check line end right condition
			if (m+1 < dim_m) {
				tmp = __grid->at(m+1,n,k); //get cell to right
				tmpStatus = tmp->getStatus();
				if (tmpStatus == CellFilled || tmpStatus == CellContact) //not line end
					rightBound = m;
				else //line end
					rightBound = m+__keepoutRadius_longitudinal;
				
				if (rightBound > dim_m-1)
					rightBound = dim_m-1;
			}
			
			//check line end left condition
			if (m-1 >= 0) {
				tmp = __grid->at(m-1,n,k); //get cell to left
				tmpStatus = tmp->getStatus();
				if (tmpStatus == CellFilled || tmpStatus == CellContact) //not line end
					leftBound = m;
				else //line end
					leftBound = m-__keepoutRadius_longitudinal;
				
				if (leftBound < 0)
					leftBound = 0;
			}
		}
		else if(__rules->getMetal3Direction() == 'B') { //bidirectional 
			leftBound = m-__keepoutRadius_lateral;
			if (leftBound < 0)
				leftBound = 0;
			
			rightBound = m+__keepoutRadius_lateral;
			if (rightBound > dim_m-1)
				rightBound = dim_m-1;
			
			//check line end top condition
			if (n+1 < dim_n) {
				tmp = __grid->at(m,n+1,k); //get cell above
				tmpStatus = tmp->getStatus();
				if (tmpStatus == CellFilled || tmpStatus == CellContact) //not line end
					topBound = n;
				else { //line end
					if (cStatus == CellVDDRail || cStatus == CellVSSRail) //cell of interest is power rail
						 topBound = n+__keepoutRadius_powerRail;
					else //cell of interest is regular net
						 topBound = n+__keepoutRadius_longitudinal;
				}
				if (topBound > dim_n-1)
					topBound = dim_n-1;
			}
			
			//check line end bottom condition
			if (n-1 >= 0) {
				tmp = __grid->at(m,n-1,k); //get cell below
				tmpStatus = tmp->getStatus();
				if (tmpStatus == CellFilled || tmpStatus == CellContact) //not line end
					bottomBound = n;
				else { //line end
					if (cStatus == CellVDDRail || cStatus == CellVSSRail) //cell of interest is power rail
							bottomBound = n-__keepoutRadius_powerRail;
					else //cell of interest is regular net
							bottomBound = n-__keepoutRadius_longitudinal;
				}
				if (bottomBound < 0)
					bottomBound = 0;
			}
			
			bottomBound = n-__keepoutRadius_lateral;
			if (bottomBound < 0)
				bottomBound = 0;
			
			topBound = n+__keepoutRadius_lateral;
			if (topBound > dim_n-1)
				topBound = dim_n-1;
			
			//check line end right condition
			if (m+1 < dim_m) {
				tmp = __grid->at(m+1,n,k); //get cell to right
				tmpStatus = tmp->getStatus();
				if (tmpStatus == CellFilled || tmpStatus == CellContact) //not line end
					rightBound = m;
				else //line end
					rightBound = m+__keepoutRadius_longitudinal;
				
				if (rightBound > dim_m-1)
					rightBound = dim_m-1;
			}
			
			//check line end left condition
			if (m-1 >= 0) {
				tmp = __grid->at(m-1,n,k); //get cell to left
				tmpStatus = tmp->getStatus();
				if (tmpStatus == CellFilled || tmpStatus == CellContact) //not line end
					leftBound = m;
				else //line end
					leftBound = m-__keepoutRadius_longitudinal;
				
				if (leftBound < 0)
					leftBound = 0;
			}
		}
	}
    
	oaInt4 newBottom = bottomBound;
	oaInt4 newRight = rightBound;
	oaInt4 newLeft = leftBound;
	oaInt4 newTop = topBound;
	oaInt4 increase = 10;
	oaInt4 decrease = 10;
	if(k == 0 && __rules->getMetal1Direction() == 'B') {
		newBottom -= decrease;
		newRight += increase;
		newLeft -= decrease;
		newTop += increase;
	}
	else if(k == 1 && __rules->getMetal2Direction() == 'B') {
		newBottom -= decrease;
		newRight += increase;
		newLeft -= decrease;
		newTop += increase;
	}
	else if(k == 2 && __rules->getMetal3Direction() == 'B') {
		newBottom -= decrease;
		newRight += increase;
		newLeft -= decrease;
		newTop += increase;
	}
	
	if (newTop > dim_n-1)
		newTop = dim_n-1;
	if (newRight > dim_m-1)
		newRight = dim_m-1;
	if (newBottom < 0)
		newBottom = 0;
	if (newLeft < 0)
		newLeft = 0;

    /*for (oaInt4 j = topBound; j >= bottomBound; j--) {
        for (oaInt4 i = leftBound; i <= rightBound; i++) {
            tmp = __grid->at(i,j,k);
            if (tmp->getStatus() == CellFree) {      
                tmp->setStatus(CellKeepout);
            }
        }
    }*/
	 for (oaInt4 j = newTop; j >= newBottom; j--) {
        for (oaInt4 i = newLeft; i <= newRight; i++) {
            tmp = __grid->at(i,j,k);
            if (tmp->getStatus() == CellFree) {      
                tmp->setStatus(CellKeepout);
            }
        }
    }
}
Example #13
0
void MazeRouter::doBacktrace(Cell* source, Cell* sink, bool setPin) {
    Cell* curr = sink;
    Cell* tmp = NULL;
    oaUInt4 currm,currn,currk = 0;
    oaUInt4 tmpm,tmpn,tmpk = 0;
    
    //Handle pin
    if (setPin) {
        curr->getPosition(&currm,&currn,&currk);
        tmp = curr->getBacktrace();
        tmp->getPosition(&tmpm,&tmpn,&tmpk);
        
        if (currm == tmpm && currn == tmpn && currk == (tmpk+1)%2) { //backtrace is above the contact, set pin on M2 (the backtraced cell).
            tmp->setPin(true);
            tmp->setPinName(source->getPinName());
        }
        else { //set pin on the contact (sink)
            curr->setPin(true);
        }
    }
    
    // backtrace sink to source
    curr = sink;
    tmp = curr;
    while (tmp != source) {       
        if (curr->getStatus() == CellFree) {
            curr->setStatus(CellFilled);
            curr->setNetID(source->getNetID());
            curr->setNetType(source->getNetType());
        }
        
        //check if we need a via.
		  oaInt4 currm_dbu, currn_dbu = 0;
		  oaInt4 tmpm_dbu, tmpn_dbu = 0;

        curr->getPosition(&currm, &currn, &currk);
		  curr->getAbsolutePosition(&currm_dbu,&currn_dbu);
        tmp->getPosition(&tmpm,&tmpn,&tmpk);
		  tmp->getAbsolutePosition(&tmpm_dbu,&tmpn_dbu);

        if (currk == 0 && tmpk == 1) { //change from layer 1 to layer 0
            //set via on curr, which is M1.
            curr->setNeedsVia();
            cout << "Via needed at cell (" << currm << "," << currn << "," << currk << ") ---> (" << currm_dbu << "," << currn_dbu << ")" << endl;
        }
        else if (currk == 1 && tmpk == 0) { //change from layer 0 to layer 1
            //set via on tmp, which is M1.
            tmp->setNeedsVia();
            cout << "Via needed at cell (" << tmpm << "," << tmpn << "," << tmpk << ") ---> (" << tmpm_dbu << "," << tmpn_dbu << ")" << endl;
        }
		else if (currk == 1 && tmpk == 2) { //change from layer 2 to layer 1
            //set via on curr, which is M2.
            curr->setNeedsVia();
            cout << "Via needed at cell (" << currm << "," << currn << "," << currk << ") ---> (" << currm_dbu << "," << currn_dbu << ")" << endl;
        }
		else if (currk == 2 && tmpk == 1) { //change from layer 1 to layer 2
            //set via on tmp, which is M2.
            tmp->setNeedsVia();
            cout << "Via needed at cell (" << tmpm << "," << tmpn << "," << tmpk << ") ---> (" << tmpm_dbu << "," << tmpn_dbu << ")" << endl;
        }
		else if (currk == 0 && tmpk == 2) { //change from layer 2 to layer 0
            //set via on curr, which is M1.
            curr->setNeedsVia();
			Cell * temp = __grid->at(currm, currn, (currk+1));
			CellStatus tempStatus = temp->getStatus();
			//if(tempStatus == CellFree)
				temp->setStatus(CellFilled);
			temp->setNeedsVia();
            cout << "Via needed at cell (" << currm << "," << currn << "," << currk << ") ---> (" << currm_dbu << "," << currn_dbu << ")" << endl;
            cout << "Via needed at cell (" << currm << "," << currn << "," << currk+1 << ") ---> (" << currm_dbu << "," << currn_dbu << ")" << endl;
			cout << "temp->needsVia(): " << temp->needsVia() << endl;
        }
		else if (currk == 2 && tmpk == 0) { //change from layer 0 to layer 2
            //set via on tmp, which is M1.
            tmp->setNeedsVia();
			Cell * temp = __grid->at(currm, currn, (currk-1));
			CellStatus tempStatus = temp->getStatus();
			//if(tempStatus == CellFree)
				temp->setStatus(CellFilled);
			temp->setNeedsVia();
            cout << "Via needed at cell (" << tmpm << "," << tmpn << "," << tmpk << ") ---> (" << tmpm_dbu << "," << tmpn_dbu << ")" << endl;
			cout << "Via needed at cell (" << currm << "," << currn << "," << currk-1 << ") ---> (" << currm_dbu << "," << currn_dbu << ")" << endl;
			cout << "temp->needsVia(): " << temp->needsVia() << endl;
        }
        
        tmp = curr;
        curr = curr->getBacktrace();
    }
}
Example #14
0
void MazeRouter::mazeRoute(oaUInt4 netID, oaInt4 contactIndex0, oaInt4 contactIndex1, bool setPin) { //Lee's algorithm
    //First, choose two endpoints to connect, and set them as source and sink.
    Cell* source = __contactCells[netID][contactIndex0]; 
    Cell* sink = __contactCells[netID][contactIndex1];
 
    source->setIsRouted();
    
    source->setSource(true);
    sink->setSink(true);
    
    oaUInt4 sourcem, sourcen, sourcek = 0;
    oaInt4 sourceNetID = source->getNetID();
    oaUInt4 sinkm, sinkn, sinkk = 0;
    source->getPosition(&sourcem,&sourcen,&sourcek);
    sink->getPosition(&sinkm,&sinkn,&sinkk);
    //cout<<"source m: "<<(int)sourcem<<" sourcen "<<(int)sourcen<<endl;  //Weiche
    //Next, initialize our plist and nlist (two adjacent BFS wavefronts)
    vector<Cell*> plist;
    vector<Cell*> nlist;
    vector<Cell*> neighbors;
    bool path_exists = false;
    oaUInt4 dist = 0;
    Cell* curr = NULL;
    oaUInt4 m,n,k = 0;    
    oaUInt4 dim_m, dim_n, dim_k = 0;
    __grid->getDims(&dim_m,&dim_n,&dim_k);
   
    plist.push_back(source); //we start with the source only.
    while (plist.size() > 0 && !path_exists) {
        //One wave
        for (int p = 0; p < plist.size(); p++) {
            curr = plist[p];
            //Iterate over neighbors of curr
            curr->getPosition(&m,&n,&k);
            neighbors.clear();

           if (k == 0) { //bottom layer, M1, route vertically only
                if(__rules->getMetal1Direction() == 'V') { //vertical only
					if (n-1 >= 0)
						neighbors.push_back(__grid->at(m,n-1,k));
					if (n+1 < dim_n)
						neighbors.push_back(__grid->at(m,n+1,k));
				}
                else if(__rules->getMetal1Direction() == 'H') { //horizontal only
					if (m-1 >= 0)
						neighbors.push_back(__grid->at(m-1,n,k));
					if (m+1 < dim_m)
						neighbors.push_back(__grid->at(m+1,n,k));
				}
				else if(__rules->getMetal1Direction() == 'B') { //bidirectional
					if (m-1 >= 0)
						neighbors.push_back(__grid->at(m-1,n,k));
					if (m+1 < dim_m)
						neighbors.push_back(__grid->at(m+1,n,k));
					if (n-1 >= 0)
						neighbors.push_back(__grid->at(m,n-1,k));
					if (n+1 < dim_n)
						neighbors.push_back(__grid->at(m,n+1,k));
				}
				neighbors.push_back(__grid->at(m,n,1));
				if(num_of_layers == 3)
					neighbors.push_back(__grid->at(m,n,2));
            }
            else if(k == 1){ //M2
				if(__rules->getMetal2Direction() == 'V') { //vertial only
					if (n-1 >= 0)
						neighbors.push_back(__grid->at(m,n-1,k));
					if (n+1 < dim_n)
						neighbors.push_back(__grid->at(m,n+1,k));
				}
                else if(__rules->getMetal2Direction() == 'H') { //horizontal only
					if (m-1 >= 0)
						neighbors.push_back(__grid->at(m-1,n,k));
					if (m+1 < dim_m)
						neighbors.push_back(__grid->at(m+1,n,k));
				}
				else if(__rules->getMetal2Direction() == 'B') { //bidirectional
					if (n-1 >= 0)
						neighbors.push_back(__grid->at(m,n-1,k));
					if (n+1 < dim_n)
						neighbors.push_back(__grid->at(m,n+1,k));
					if (m-1 >= 0)
						neighbors.push_back(__grid->at(m-1,n,k));
					if (m+1 < dim_m)
						neighbors.push_back(__grid->at(m+1,n,k));
				}
				neighbors.push_back(__grid->at(m,n,0));
				if(num_of_layers == 3)
					neighbors.push_back(__grid->at(m,n,2));
            }
			else if(k == 2){ //M3
				if(__rules->getMetal3Direction() == 'V') { //vertial only
					if (n-1 >= 0)
						neighbors.push_back(__grid->at(m,n-1,k));
					if (n+1 < dim_n)
						neighbors.push_back(__grid->at(m,n+1,k));
				}
                else if(__rules->getMetal3Direction() == 'H') { //horizontal only
					if (m-1 >= 0)
						neighbors.push_back(__grid->at(m-1,n,k));
					if (m+1 < dim_m)
						neighbors.push_back(__grid->at(m+1,n,k));
				}
				else if(__rules->getMetal3Direction() == 'B') { //bidirectional
					if (n-1 >= 0)
						neighbors.push_back(__grid->at(m,n-1,k));
					if (n+1 < dim_n)
						neighbors.push_back(__grid->at(m,n+1,k));
					if (m-1 >= 0)
						neighbors.push_back(__grid->at(m-1,n,k));
					if (m+1 < dim_m)
						neighbors.push_back(__grid->at(m+1,n,k));
				}
				 neighbors.push_back(__grid->at(m,n,1)); 
				 neighbors.push_back(__grid->at(m,n,0)); 
			}
    
            Cell* next = NULL;
            CellStatus nextstatus;
            oaInt4 netID = -1;
            for (int d = 0; d < neighbors.size(); d++) {
                next = neighbors[d];   
                nextstatus = next->getStatus();
                netID = next->getNetID();
                if (!next->touched() && //cell must NOT be touched and...
                        (nextstatus == CellFree || //free, or
                                ((nextstatus == CellFilled || nextstatus == CellContact) && //filled or contact, and...
                                        netID == sourceNetID))) { //same net ID as source.
                    next->touch();
                    
                    next->setDistance(dist+1);
                    next->setBacktrace(curr);
                    nlist.push_back(next);
                    if (next->isSink()) { //HURRAY WE FOUND IT
                        path_exists = true;
                    }
                    
                    /*
                    //test by Yasmine: enough to touch any of cells of this net
                    unsigned int hSrc,vSrc,lSrc, hNext,vNext,lNext, hCurr,vCurr,lCurr;
                    source->getPosition(&hSrc,&vSrc,&lSrc);
                    curr->getPosition(&hCurr,&vCurr,&lCurr);
                    next->getPosition(&hNext,&vNext, &lNext);
                    if(hNext==hSrc//vertically aligned
                    && lNext==lSrc//same layer
                    && lSrc==lCurr//same layer (no via just before the reached cell)
                       && lNext==0)//heuristic to try to favor keeping on M1 layer
                    {
                        if(((nextstatus==CellFilled)//filled or contact but already routed
                            ||(nextstatus==CellContact && (next->isRouted())))                             
                            && netID==sourceNetID && next!=source)
                        {
                            path_exists=true;
                            sink=next;
                        }
                    }
                    //end test
                    */
                }
            }
        }
        dist++;
        plist = nlist;
        nlist.clear();
    }
    
    if (path_exists) {
#ifdef DEBUG
        cout << "Found a path from Cell (" << sourcem << "," << sourcen << "," << sourcek << ") to (" << sinkm << "," << sinkn << "," << sinkk << ")" << endl;
#endif
        doBacktrace(source, sink, setPin);
    } else {
        cout << "DID NOT find a path from Cell (" << sourcem << "," << sourcen << "," << sourcek << ") to (" << sinkm << "," << sinkn << "," << sinkk << ")" << endl;
		  __foundRoute = false;
    }   
}
Example #15
0
bool MergeCommand::preProcessing()
{
    if (isColumnOrRowSelected()) {
        KMessageBox::information(0, i18n("Merging of columns or rows is not supported."));
        return false;
    }

    if (m_firstrun) {
        setText(name());

        // reduce the region to the region occupied by merged cells
        Region mergedCells;
        ConstIterator endOfList = constEnd();
        for (ConstIterator it = constBegin(); it != endOfList; ++it) {
            Element* element = *it;
            QRect range = element->rect();
            int right = range.right();
            int bottom = range.bottom();
            for (int row = range.top(); row <= bottom; ++row) {
                for (int col = range.left(); col <= right; ++col) {
                    Cell cell = Cell(m_sheet, col, row);
                    if (cell.doesMergeCells()) {
                        QRect rect(col, row, cell.mergedXCells() + 1, cell.mergedYCells() + 1);
                        mergedCells.add(rect);
                    }
                }
            }
        }

        if (m_merge) { // MergeCommand
            // we're in the manipulator's first execution
            // initialize the undo manipulator
            m_unmerger = new MergeCommand();
            if (!m_mergeHorizontal && !m_mergeVertical) {
                m_unmerger->setReverse(true);
            }
            m_unmerger->setSheet(m_sheet);
            m_unmerger->setRegisterUndo(false);
            m_unmerger->add(mergedCells);
        } else { // DissociateManipulator
            clear();
            add(mergedCells);
        }
    }

    if (m_merge) { // MergeCommand
        if (m_reverse) { // dissociate
        } else { // merge
            // Dissociate cells before merging the whole region.
            // For horizontal/vertical merging the cells stay
            // as they are. E.g. the region contains a merged cell
            // occupying two rows. Then the horizontal merge should
            // keep the height of two rows and extend the merging to the
            // region's width. In this case the unmerging is done while
            // processing each region element.
            if (!m_mergeHorizontal && !m_mergeVertical) {
                m_unmerger->redo();
            }
        }
    }
    // Clear the associated selection, if any. The merge/dissociate process will restore
    // selections. This ensures that the selection isn't broken after merging.
    if (m_selection) m_selection->Region::clear();

    return AbstractRegionCommand::preProcessing();
}
Example #16
0
void Random::wallItemCell(Cell &cell) {
	cell.dungeonWallA();
}
Example #17
0
bool MergeCommand::process(Element* element)
{
    if (element->type() != Element::Range || element->isRow() || element->isColumn()) {
        // TODO Stefan: remove these elements?!
        return true;
    }

    // sanity check
    if (m_sheet->isProtected() || m_sheet->map()->isProtected()) {
        return false;
    }

    QRect range = element->rect();
    int left   = range.left();
    int right  = range.right();
    int top    = range.top();
    int bottom = range.bottom();
    int height = range.height();
    int width  = range.width();

    bool doMerge = m_reverse ? (!m_merge) : m_merge;

    if (doMerge) {
        if (m_mergeHorizontal) {
            for (int row = top; row <= bottom; ++row) {
                int rows = 0;
                for (int col = left; col <= right; ++col) {
                    Cell cell = Cell(m_sheet, col, row);
                    if (cell.doesMergeCells()) {
                        rows = qMax(rows, cell.mergedYCells());
                        cell.mergeCells(col, row, 0, 0);
                    }
                }
                Cell cell = Cell(m_sheet,  left, row);
                if (!cell.isPartOfMerged()) {
                    cell.mergeCells(left, row, width - 1, rows);
                }
            }
        } else if (m_mergeVertical) {
            for (int col = left; col <= right; ++col) {
                int cols = 0;
                for (int row = top; row <= bottom; ++row) {
                    Cell cell = Cell(m_sheet, col, row);
                    if (cell.doesMergeCells()) {
                        cols = qMax(cols, cell.mergedXCells());
                        cell.mergeCells(col, row, 0, 0);
                    }
                }
                Cell cell = Cell(m_sheet, col, top);
                if (!cell.isPartOfMerged()) {
                    cell.mergeCells(col, top, cols, height - 1);
                }
            }
        } else {
            Cell cell = Cell(m_sheet,  left, top);
            cell.mergeCells(left, top, width - 1, height - 1);
        }
    } else { // dissociate
        for (int col = left; col <= right; ++col) {
            for (int row = top; row <= bottom; ++row) {
                Cell cell = Cell(m_sheet, col, row);
                if (!cell.doesMergeCells()) {
                    continue;
                }
                cell.mergeCells(col, row, 0, 0);
            }
        }
    }

    // adjust selection
    if (m_selection)
        m_selection->isEmpty() ? m_selection->initialize(range, m_sheet) : m_selection->extend(range, m_sheet);

    return true;
}
Example #18
0
//-----------------------------------------------------------------------------
void MultiMesh::_build_quadrature_rules_overlap()
{
  begin(PROGRESS, "Building quadrature rules of cut cells' overlap.");

  // Get quadrature order
  const std::size_t quadrature_order = parameters["quadrature_order"];

  // Clear quadrature rules
  _quadrature_rules_overlap.clear();
  _quadrature_rules_interface.clear();

  // Resize quadrature rules
  _quadrature_rules_overlap.resize(num_parts());
  _quadrature_rules_interface.resize(num_parts());

  // Clear and resize facet normals
  _facet_normals.clear();
  _facet_normals.resize(num_parts());

  // FIXME: test prebuild map from boundary facets to full mesh cells
  // for all meshes: Loop over all boundary mesh facets to find the
  // full mesh cell which contains the facet. This is done in two
  // steps: Since the facet is on the boundary mesh, we first map this
  // facet to a facet in the full mesh using the
  // boundary_cell_map. Then we use the full_facet_cell_map to find
  // the corresponding cell in the full mesh. This cell is to match
  // the cutting_cell_no.

  // Build map from boundary facets to full mesh
  std::vector<std::vector<std::vector<std::pair<std::size_t, std::size_t>>>>
    full_to_bdry(num_parts());
  for (std::size_t part = 0; part < num_parts(); ++part)
  {
    full_to_bdry[part].resize(_meshes[part]->num_cells());

    // Get map from boundary mesh to facets of full mesh
    const std::size_t tdim_boundary
      = _boundary_meshes[part]->topology().dim();
    const auto& boundary_cell_map
      = _boundary_meshes[part]->entity_map(tdim_boundary);

    // Generate facet to cell connectivity for full mesh
    const std::size_t tdim = _meshes[part]->topology().dim();
    _meshes[part]->init(tdim_boundary, tdim);
    const MeshConnectivity& full_facet_cell_map
      = _meshes[part]->topology()(tdim_boundary, tdim);

    for (std::size_t boundary_facet = 0;
         boundary_facet < boundary_cell_map.size(); ++boundary_facet)
    {
      // Find the facet in the full mesh
      const std::size_t full_mesh_facet = boundary_cell_map[boundary_facet];

      // Find the cells in the full mesh (for interior facets we
      // can have 2 facets, but here we should only have 1)
      dolfin_assert(full_facet_cell_map.size(full_mesh_facet) == 1);
      const auto& full_cells = full_facet_cell_map(full_mesh_facet);
      full_to_bdry[part][full_cells[0]].push_back(std::make_pair(boundary_facet,
                                                                 full_mesh_facet));
    }
  }

  // Iterate over all parts
  for (std::size_t cut_part = 0; cut_part < num_parts(); cut_part++)
  {
    // Iterate over cut cells for current part
    const auto& cmap = collision_map_cut_cells(cut_part);
    for (auto it = cmap.begin(); it != cmap.end(); ++it)
    {
      // Get cut cell
      const unsigned int cut_cell_index = it->first;
      const Cell cut_cell(*(_meshes[cut_part]), cut_cell_index);

      // Get dimensions
      const std::size_t tdim = cut_cell.mesh().topology().dim();
      const std::size_t gdim = cut_cell.mesh().geometry().dim();

      // Data structure for the volume triangulation of the cut_cell
      std::vector<double> volume_triangulation;

      // Data structure for the overlap quadrature rule
      std::vector<quadrature_rule> overlap_qr;

      // Data structure for the interface quadrature rule
      std::vector<quadrature_rule> interface_qr;

      // Data structure for the facet normals of the interface. The
      // numbering matches the numbering of interface_qr. This means
      // we have one normal for each quadrature point, since this is
      // how the data are grouped during assembly: for each pair of
      // colliding cells, we build a list of quadrature points and a
      // corresponding list of facet normals.
      std::vector<std::vector<double>> interface_n;

      // Data structure for the interface triangulation
      std::vector<double> interface_triangulation;

      // Data structure for normals to the interface. The numbering
      // should match the numbering of interface_triangulation.
      std::vector<Point> triangulation_normals;

      // Iterate over cutting cells
      const auto& cutting_cells = it->second;
      for (auto jt = cutting_cells.begin(); jt != cutting_cells.end(); jt++)
      {
        // Get cutting part and cutting cell
        const std::size_t cutting_part = jt->first;
        const std::size_t cutting_cell_index = jt->second;
        const Cell cutting_cell(*(_meshes[cutting_part]), cutting_cell_index);

        // Topology of this cut part
        const std::size_t tdim_boundary = _boundary_meshes[cutting_part]->topology().dim();

        // Must have the same topology at the moment (FIXME)
        dolfin_assert(cutting_cell.mesh().topology().dim() == tdim);

        // Data structure for local interface triangulation
        std::vector<double> local_interface_triangulation;

        // Data structure for the local interface normals. The
        // numbering should match the numbering of
        // local_interface_triangulation.
        std::vector<Point> local_triangulation_normals;

        // Data structure for the overlap part quadrature rule
        quadrature_rule overlap_part_qr;

        // Data structure for the interface part quadrature rule
        quadrature_rule interface_part_qr;

        // Data structure for the interface part facet normals. The
        // numbering matches the numbering of interface_part_qr.
        std::vector<double> interface_part_n;

        // Iterate over boundary cells
        for (auto boundary_cell_index : full_to_bdry[cutting_part][cutting_cell_index])
        {
          // Get the boundary facet as a cell in the boundary mesh
          const Cell boundary_cell(*_boundary_meshes[cutting_part],
                                   boundary_cell_index.first);

          // Get the boundary facet as a facet in the full mesh
          const Facet boundary_facet(*_meshes[cutting_part],
                                     boundary_cell_index.second);

          // Triangulate intersection of cut cell and boundary cell
          const auto triangulation_cut_boundary
            = cut_cell.triangulate_intersection(boundary_cell);

          // The normals to triangulation_cut_boundary
          std::vector<Point> normals_cut_boundary;

          // Add quadrature rule and normals for triangulation
          if (triangulation_cut_boundary.size())
          {
            dolfin_assert(interface_part_n.size() == interface_part_qr.first.size());

            const auto num_qr_points
              = _add_quadrature_rule(interface_part_qr,
                                     triangulation_cut_boundary,
                                     tdim_boundary, gdim,
                                     quadrature_order, 1);

            const std::size_t local_facet_index = cutting_cell.index(boundary_facet);
            const Point n = -cutting_cell.normal(local_facet_index);
            for (std::size_t i = 0; i < num_qr_points.size(); ++i)
            {
              _add_normal(interface_part_n,
                          n,
                          num_qr_points[i],
                          gdim);
              normals_cut_boundary.push_back(n);
            }

            dolfin_assert(interface_part_n.size() == interface_part_qr.first.size());
          }

          // Triangulate intersection of boundary cell and previous volume triangulation
          const auto triangulation_boundary_prev_volume
            = IntersectionTriangulation::triangulate_intersection(boundary_cell,
                                                                  volume_triangulation,
                                                                  tdim);

          // Add quadrature rule and normals for triangulation
          if (triangulation_boundary_prev_volume.size())
          {
            dolfin_assert(interface_part_n.size() == interface_part_qr.first.size());

            const auto num_qr_points
              = _add_quadrature_rule(interface_part_qr,
                                     triangulation_boundary_prev_volume,
                                     tdim_boundary, gdim,
                                     quadrature_order, -1);

            const std::size_t local_facet_index = cutting_cell.index(boundary_facet);
            const Point n = -cutting_cell.normal(local_facet_index);
            for (std::size_t i = 0; i < num_qr_points.size(); ++i)
              _add_normal(interface_part_n,
                          n,
                          num_qr_points[i],
                          gdim);

            dolfin_assert(interface_part_n.size() == interface_part_qr.first.size());
          }

          // Update triangulation
          local_interface_triangulation.insert(local_interface_triangulation.end(),
                                               triangulation_cut_boundary.begin(),
                                               triangulation_cut_boundary.end());

          // Update interface facet normals
          local_triangulation_normals.insert(local_triangulation_normals.end(),
                                             normals_cut_boundary.begin(),
                                             normals_cut_boundary.end());
        }

        // Triangulate the intersection of the previous interface
        // triangulation and the cutting cell (to remove)
        std::vector<double> triangulation_prev_cutting;
        std::vector<Point> normals_prev_cutting;
        IntersectionTriangulation::triangulate_intersection(cutting_cell,
                                                            interface_triangulation,
                                                            triangulation_normals,
                                                            triangulation_prev_cutting,
                                                            normals_prev_cutting,
                                                            tdim_boundary);

        // Add quadrature rule for triangulation
        if (triangulation_prev_cutting.size())
        {
          dolfin_assert(interface_part_n.size() == interface_part_qr.first.size());

          const auto num_qr_points
            = _add_quadrature_rule(interface_part_qr,
                                   triangulation_prev_cutting,
                                   tdim_boundary, gdim,
                                   quadrature_order, -1);

          for (std::size_t i = 0; i < num_qr_points.size(); ++i)
            _add_normal(interface_part_n,
                        normals_prev_cutting[i],
                        num_qr_points[i],
                        gdim);

          dolfin_assert(interface_part_n.size() == interface_part_qr.first.size());
        }

        // Update triangulation
        interface_triangulation.insert(interface_triangulation.end(),
                                       local_interface_triangulation.begin(),
                                       local_interface_triangulation.end());

        // Update normals
        triangulation_normals.insert(triangulation_normals.end(),
                                     local_triangulation_normals.begin(),
                                     local_triangulation_normals.end());

        // Do the volume segmentation

        // Compute volume triangulation of intersection of cut and cutting cells
        const auto triangulation_cut_cutting
          = cut_cell.triangulate_intersection(cutting_cell);

        // Compute triangulation of intersection of cutting cell and
        // the (previous) volume triangulation
        const auto triangulation_cutting_prev
          = IntersectionTriangulation::triangulate_intersection(cutting_cell,
                                                                volume_triangulation,
                                                                tdim);

        // Add these new triangulations
        volume_triangulation.insert(volume_triangulation.end(),
                                    triangulation_cut_cutting.begin(),
                                    triangulation_cut_cutting.end());

        // Add quadrature rule with weights corresponding to the two
        // triangulations
        _add_quadrature_rule(overlap_part_qr,
                             triangulation_cut_cutting,
                             tdim, gdim, quadrature_order, 1);
        _add_quadrature_rule(overlap_part_qr,
                             triangulation_cutting_prev,
                             tdim, gdim, quadrature_order, -1);

        // Add quadrature rule for overlap part
        overlap_qr.push_back(overlap_part_qr);

        // Add quadrature rule for interface part
        interface_qr.push_back(interface_part_qr);

        // Add facet normal for interface part
        interface_n.push_back(interface_part_n);
      }

      // Store quadrature rules for cut cell
      _quadrature_rules_overlap[cut_part][cut_cell_index] = overlap_qr;
      _quadrature_rules_interface[cut_part][cut_cell_index] = interface_qr;

      // Store facet normals for cut cell
      _facet_normals[cut_part][cut_cell_index] = interface_n;
    }
  }

  end();
}
Example #19
0
void MainWindow::addRandomDir(CellList& list)
{
  Cell* cell = list.first();
  Cell* ucell = uCell(cell);
  Cell* rcell = rCell(cell);
  Cell* dcell = dCell(cell);
  Cell* lcell = lCell(cell);

  typedef QMap<Cell::Dirs, Cell*> CellMap;
  CellMap freecells;

  if(ucell && ucell->dirs() == Cell::Free)
    freecells[Cell::U] = ucell;
  if(rcell && rcell->dirs() == Cell::Free)
    freecells[Cell::R] = rcell;
  if(dcell && dcell->dirs() == Cell::Free)
    freecells[Cell::D] = dcell;
  if(lcell && lcell->dirs() == Cell::Free)
    freecells[Cell::L] = lcell;
  if(freecells.isEmpty())
    return;

  CellMap::ConstIterator it = freecells.constBegin();
  for(int i = rand() % freecells.count(); i > 0; --i)
    ++it;

  cell->setDirs(Cell::Dirs(cell->dirs() | it.key()));
  it.value()->setDirs(contrdirs[it.key()]);
  list.append(it.value());
}
Example #20
0
QVariant GridModel::data(const QModelIndex& index, int role) const
{
	Cell* subject = _grid.cellAt(index.row(), index.column());
	switch(role)
	{
		// sets the actual content of the cell
		case Qt::EditRole:
		case Qt::DisplayRole:
		{
			if( subject->value() == Cell::UNKNOWN )
				return QVariant("");
			else {
				QChar value = _grid.alphabet().at(subject->value());
				return QVariant(value);
			}
			break;
		}

		// sets the cell alignment
		case Qt::TextAlignmentRole:
		{
			return QVariant(Qt::AlignCenter);
			break;
		}
		case Qt::ToolTipRole:
		case Qt::StatusTipRole:
		{
			QList<char> d = subject->domain().toList();
			QString ret = "";
			qSort(d);

			if( d.isEmpty() ){
				if( subject->value() != Cell::UNKNOWN ){
					return QVariant();
				}
				else {
					return QVariant("No domain!");
				}
			}
			else {
				ret += _grid.alphabet().at(d.takeFirst());
				for( auto i=d.begin(); i!=d.end(); ++i ){
					ret += "/";
					ret += _grid.alphabet().at(*i);
				}
				return QVariant(ret);
			}
			break;
		}

		case Qt::FontRole:
		{
			if( subject->isGiven() ){
				return QVariant(givenFont);
			}
			else {
				return QVariant();
			}
			break;
		}
		case Qt::BackgroundRole:
		{
			if( showDomainColor && subject->value() == Cell::UNKNOWN ){
				double restrictionRatio = (double)subject->domain().size()/subject->fullDomain.size();
				//QColor bgColor(55+200*restrictionRatio, 255, 55+200*restrictionRatio);
				QColor bgColor = QColor::fromHsv(255*restrictionRatio, 100, 255);
				return QVariant(bgColor);
			}
			break;
		}
		case Qt::ForegroundRole:
			break;
		default:
			return QVariant();
			break;
	}
	return QVariant();
}
Example #21
0
//Saves the map.  Good for editing maps, not good for saving a game in mid-play because unit statuses are not saved. 
void InformationStorage::saveMap(string filename, Map *level)
{
	TiXmlDocument doc;
	string s;
	TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "", "");
	doc.LinkEndChild(decl);

	//Set up the root of the XML document
	TiXmlElement *root = new TiXmlElement("TileInfo");
	doc.LinkEndChild(root);

	//Set up the Units, Buildings, and Tiles blocks
	TiXmlElement *units = new TiXmlElement("Units");
	TiXmlElement *buildings = new TiXmlElement("Buildings");
	TiXmlElement *tiles = new TiXmlElement("Tiles");

	//Set up pointers to be used throughout saving the map
	TiXmlElement *elem;
	GameObject *gObj = 0;
	Unit *unit = 0;
	Building *building = 0;
	Terrain *tile = 0;

	//Set the width, height, and player count in the XML based on the level
	tiles->SetAttribute("width", level->width);
	tiles->SetAttribute("height", level->height);
	tiles->SetAttribute("playercount", level->playerCount());

	//Add the units, buildings, and tiles blocks to the root
	root->LinkEndChild(units);
	root->LinkEndChild(buildings);
	root->LinkEndChild(tiles);

	Cell* cell;
	
	//Go through every cell of the map, and check what the terrain, unit(if any), and building(if any)
	//there is, and store it in the xml
	for(int i=0; i<level->width; i++)
	{
		for(int j=0; j<level->height; j++)
		{
			cell = level->getCell(i, j);
			gObj = cell->objectAtLayer(CellLayers::Unit);
			if(gObj)
			{
				//Add the unit to the units tag
				unit = (Unit*)gObj;
				elem = new TiXmlElement("Unit");
				elem->SetAttribute("id", unit->id);
				elem->SetAttribute("pId", unit->getOwner()->id);
				elem->SetAttribute("x", i);
				elem->SetAttribute("y", j);
				units->LinkEndChild(elem);
			}

			gObj = cell->objectAtLayer(CellLayers::Building);
			if(gObj)
			{
				//Add the building to the buildings tag
				building = (Building*)gObj;
				elem = new TiXmlElement("Building");
				elem->SetAttribute("id", building->id);
				elem->SetAttribute("pId", building->getOwner()->id);
				elem->SetAttribute("x", i);
				elem->SetAttribute("y", j);
				buildings->LinkEndChild(elem);
			}
			//Don't bother checking for terrain, there should always be one there.

			gObj = cell->objectAtLayer(CellLayers::Terrain);
			tile = (Terrain*)gObj;
			elem = new TiXmlElement("Tile");
			elem->SetAttribute("shorthand", tile->id);
			elem->SetAttribute("x", i);
			elem->SetAttribute("y", j);
			tiles->LinkEndChild(elem);
		}
	}
	doc.SaveFile(filename.c_str());
	
}
/*
Subrender routing for filling the Layer image object with
thumbnails view scene
*/
void Thumblay::subrender()
{
	Graphics *gfx = Graphics::FromImage(this->image);
	gfx->Clear(CLR_WHITE);

	Cacher *cacher = this->cacher;
	if( cacher != NULL ){
		Image *thumb = NULL;
		Cell *cell = NULL;
		int i, x, y, mx, my, count;
		bool top, bot, left, right;

		right = false;
		left = false;
		top = false;
		bot = false;

		mx = OVL_MARGIN + 2 * (THB_SMSIZE + THB_SPACE);
		my = mx;

		x = y = OVL_MARGIN;
		count = 0;

		for( i = -THB_COUNT - this->picker; i <= THB_COUNT - this->picker; i++ ){
			cacher->lockCache();

			if( cacher->getCache() != NULL ){
				cell = cacher->getCache()->gettoThat(i);
				if( cell != NULL ){
					thumb = cell->getImageThumb();
					if( thumb != NULL ){
						if( i != 0 ){
							gfx->DrawImage(thumb,x,y,THB_SMSIZE,THB_SMSIZE);
							gfx->DrawRectangle(this->Pen_Border,
											   x,
											   y,
											   THB_SMSIZE,
											   THB_SMSIZE);
						}	
						else {
							mx = x + (int)((THB_SIZE - THB_SMSIZE)/4);
							my = y + (int)((THB_SIZE - THB_SMSIZE)/4);
						}
					}
					if( i == -THB_ROW )
						top = true;
					if( i == THB_ROW )
						bot = true;
					if( i == -1 && cacher->getCache()->isThatHead() == false )
						left = true;
					if( i == 1 && cacher->getCache()->isThatTail() == false )
						right = true;
				}
			}
			count++;
			x += THB_SMSIZE + THB_SPACE;
			if( count >= THB_ROW ){
				x = OVL_MARGIN;
				y += THB_SMSIZE + THB_SPACE;
				count = 0;
			}
			cacher->unlockCache();
		}
		int frame = 2;
		cacher->lockCache();
		if( cacher->getCache() != NULL ){
			cell = cacher->getThat();
			if( cell != NULL ){
				thumb = cell->getImageThumb();
				if( thumb != NULL ){
					gfx->FillRectangle(this->Brush_Back,
									   mx - THB_SIZE/4,
									   my - THB_SIZE/4,
									   THB_SIZE,
									   THB_SIZE);
					gfx->DrawImage(thumb,
								   mx - THB_SIZE/4,
								   my - THB_SIZE/4,
								   THB_SIZE,
								   THB_SIZE);
					gfx->DrawRectangle(this->Pen_Border,
									   mx - THB_SIZE/4,
									   my - THB_SIZE/4,
									   THB_SIZE,
									   THB_SIZE);
					gfx->DrawRectangle( this->Pen_DarkBorder,
										mx - frame - THB_SIZE/4,
										my - frame - THB_SIZE/4,
										THB_SIZE + 2*frame,
										THB_SIZE + 2*frame );
				}
			}
		}
		cacher->unlockCache();

		int size = 3;
		int width = 10;
		int ax = (int)(mx - frame - THB_SIZE/4);
		int ay = (int)(my - frame - THB_SIZE/4);
		int asize = THB_SIZE + 2*frame;
		Point arrow[3];

		if( top == true ){
			arrow[0].X = (int)(ax + (THB_SIZE/2) - width);
			arrow[0].Y = ay;
			arrow[1].X = (int)(ax + (THB_SIZE/2));
			arrow[1].Y = ay - width;
			arrow[2].X = (int)(ax + (THB_SIZE/2) + width);
			arrow[2].Y = ay;
			gfx->FillPolygon(this->Brush_DarkBack,arrow,size);
		}
		if( bot == true ){
			arrow[0].X = (int)(ax + (THB_SIZE/2) - width);
			arrow[0].Y = ay + asize;
			arrow[1].X = (int)(ax + (THB_SIZE/2));
			arrow[1].Y = ay + asize + width;
			arrow[2].X = (int)(ax + (THB_SIZE/2) + width);
			arrow[2].Y = ay + asize;
			gfx->FillPolygon(this->Brush_DarkBack,arrow,size);
		}
		if( left == true ){
			arrow[0].X = ax;
			arrow[0].Y = (int)(ay + (THB_SIZE/2) - width);
			arrow[1].X = ax - width;
			arrow[1].Y = (int)(ay + (THB_SIZE/2));
			arrow[2].X = ax;
			arrow[2].Y = (int)(ay + (THB_SIZE/2) + width);
			gfx->FillPolygon(this->Brush_DarkBack,arrow,size);
		}
		if( right == true ){
			arrow[0].X = ax + asize;
			arrow[0].Y = (int)(ay + (THB_SIZE/2) - width);
			arrow[1].X = ax + asize + width;
			arrow[1].Y = (int)(ay + (THB_SIZE/2));
			arrow[2].X = ax + asize;
			arrow[2].Y = (int)(ay + (THB_SIZE/2) + width);
			gfx->FillPolygon(this->Brush_DarkBack,arrow,size);
		}
	}
	if( this->ticker > TICKER_OFF ){
		int tsize = TICKER_SIZE;
		int tx,ty;
		if( this->ticker == 0 ){
			tx = OVL_SIZE - 2*TICKER_INDENT;
			ty = OVL_SIZE - 2*TICKER_INDENT;
		}
		if( this->ticker == 1 ){
			tx = OVL_SIZE - TICKER_INDENT;
			ty = OVL_SIZE - 2*TICKER_INDENT;
		}
		if( this->ticker == 2 ){
			tx = OVL_SIZE - TICKER_INDENT;
			ty = OVL_SIZE - TICKER_INDENT;
		}
		if( this->ticker == 3 ){
			tx = OVL_SIZE - 2*TICKER_INDENT;
			ty = OVL_SIZE - TICKER_INDENT;
		}
		gfx->FillRectangle(this->Brush_DarkBack,tx,ty,tsize,tsize);
	}
	delete gfx;
}
bool GlobalPlanner::FindPath(std::vector<Cell> & path) {

  Cell s = Cell(currPos);
  Cell t = Cell(goalPos.x(), goalPos.y(), 2);

  if (occupied.find(s) != occupied.end()) {
    goingBack = true;
    for (int i=pathBack.size()-1; i >= 0; i -= 2){
      path.push_back(pathBack[i]);
    }
    ROS_INFO("Current position is occupied, going back. Path size is %d", path.size());
    return true;
  }
  if (occupied.find(t) != occupied.end()) {
    ROS_INFO("Goal position is occupied");
    return false;
  }

  ROS_INFO("Trying to find path from %d,%d to %d,%d", s.x(), s.y(), t.x(), t.y());
  std::map<Cell, Cell> parent;
  std::map<Cell, double> distance;
  std::set<Cell> seen;
  std::priority_queue< std::pair<Cell,double>, 
                       std::vector< std::pair<Cell,double> >,
                       CompareDist> pq;

  pq.push(std::make_pair(s, 0.0));
  distance[s] = 0.0;
  int numIter = 0;
  while (!pq.empty() && numIter++ < maxIterations) {
    auto cellDistU = pq.top(); pq.pop();
    Cell u = cellDistU.first;
    double d = distance[u];
    if (seen.find(u) != seen.end()) {
      continue;
    }
    seen.insert(u);
    if (u == t) {
      break;
    }
    std::vector< std::pair<Cell, double> > neighbors;
    getNeighbors(u, neighbors);

    for (auto cellDistV : neighbors) {
      Cell v = cellDistV.first;
      double risk = getRisk(v);
      double newDist = d + cellDistV.second + riskFactor * risk;
      double oldDist = inf;
      if (distance.find(v) != distance.end()) {
        oldDist = distance[v];
      }
      if (occupied.find(v) == occupied.end() && seen.find(v) == seen.end()
          && newDist < oldDist) {
        parent[v] = u;
        distance[v] = newDist;
        double heuristic = newDist + overEstimateFactor*distance2D(v, t);
        pq.push(std::make_pair(v, heuristic));
      }
    }
  }

  if (seen.find(t) == seen.end()) {
    ROS_INFO("  Failed to find a path");
    return false;
  }

  Cell walker = t;
  pathCells.clear();
  while (!(walker == s)) {
    path.push_back(walker);
    pathCells.insert(walker);
    walker = parent[walker];
  }
  std::reverse(path.begin(),path.end());

  ROS_INFO("Found path with %d iterations, iterations / distance squared: %f", numIter, numIter / squared(path.size()));
  
  return true;
}  
Example #24
0
int main(int argc,char ** argv)
{
	Solver::Initialize(&argc,&argv,""); // Initialize the solver and MPI activity
#if defined(USE_PARTITIONER)
	Partitioner::Initialize(&argc,&argv); // Initialize the partitioner activity
#endif
	if( argc > 1 )
	{
		TagReal phi;
		TagReal tag_F;
		TagRealArray tag_K;
		TagRealArray tag_BC;
		TagReal phi_ref;
		Mesh * m = new Mesh(); // Create an empty mesh
		double ttt = Timer();
		bool repartition = false;
		m->SetCommunicator(INMOST_MPI_COMM_WORLD); // Set the MPI communicator for the mesh
		if( m->GetProcessorRank() == 0 ) // If the current process is the master one
			std::cout << argv[0] << std::endl;

		if( m->isParallelFileFormat(argv[1]) )
		{
			m->Load(argv[1]); // Load mesh from the parallel file format
			repartition = true;
		}
		else
		{
			if( m->GetProcessorRank() == 0 )
				m->Load(argv[1]); // Load mesh from the serial file format
		}
		BARRIER;
		if( m->GetProcessorRank() == 0 ) std::cout << "Processors: " << m->GetProcessorsNumber() << std::endl;
		if( m->GetProcessorRank() == 0 ) std::cout << "Load(MPI_File): " << Timer()-ttt << std::endl;

		//~ double ttt2 = Timer();
		//~ Mesh t;
		//~ t.SetCommunicator(INMOST_MPI_COMM_WORLD);
		//~ t.SetParallelFileStrategy(0);
		//~ t.Load(argv[1]);
		//~ BARRIER
		//~ if( m->GetProcessorRank() == 0 ) std::cout << "Load(MPI_Scatter): " << Timer()-ttt2 << std::endl;

#if defined(USE_PARTITIONER)
		if (m->GetProcessorsNumber() > 1)
		{ // currently only non-distributed meshes are supported by Inner_RCM partitioner
			ttt = Timer();
			Partitioner * p = new Partitioner(m);
			p->SetMethod(Partitioner::INNER_KMEANS,Partitioner::Partition); // Specify the partitioner
			p->Evaluate(); // Compute the partitioner and store new processor ID in the mesh
			delete p;
			BARRIER;

			if( m->GetProcessorRank() == 0 ) std::cout << "Evaluate: " << Timer()-ttt << std::endl;

			ttt = Timer();
			m->Redistribute(); // Redistribute the mesh data
			m->ReorderEmpty(CELL|FACE|EDGE|NODE); // Clean the data after reordring
			BARRIER;

			if( m->GetProcessorRank() == 0 ) std::cout << "Redistribute: " << Timer()-ttt << std::endl;
		}
#endif

		ttt = Timer();
		phi = m->CreateTag("Solution",DATA_REAL,CELL,NONE,1); // Create a new tag for the solution phi
		
		bool makerefsol = true;
		
		if( m->HaveTag("PERM" ) )
		{
			tag_K = m->GetTag("PERM");
			makerefsol = false;
			std::cout << "Permeability from grid" << std::endl;
		}
		else
		{
			std::cout << "Set perm" << std::endl;
			tag_K = m->CreateTag("PERM",DATA_REAL,CELL,NONE,1); // Create a new tag for K tensor
			for( Mesh::iteratorCell cell = m->BeginCell(); cell != m->EndCell(); ++cell ) // Loop over mesh cells
				tag_K[*cell][0] = 1.0; // Store the tensor K value into the tag
		}
		
		
		
		if( m->HaveTag("BOUNDARY_CONDITION") )
		{
			tag_BC = m->GetTag("BOUNDARY_CONDITION");
			makerefsol = false;
			std::cout << "Boundary conditions from grid" << std::endl;
		}
		else
		{
			std::cout << "Set boundary conditions" << std::endl;
			double x[3];
			tag_BC = m->CreateTag("BOUNDARY_CONDITION",DATA_REAL,FACE,FACE,3);
			for( Mesh::iteratorFace face = m->BeginFace(); face != m->EndFace(); ++face )
				if( face->Boundary() && !(face->GetStatus() == Element::Ghost) )
				{
					face->Centroid(x);
					tag_BC[*face][0] = 1; //dirichlet
					tag_BC[*face][1] = 0; //neumann
					tag_BC[*face][2] = func(x,0);//face->Mean(func, 0);
				}
		}
		
		if( m->HaveTag("FORCE") )
		{
			tag_F = m->GetTag("FORCE");
			makerefsol = false;
			std::cout << "Force from grid" << std::endl;
		}
		else if( makerefsol )
		{
			std::cout << "Set rhs" << std::endl;
			tag_F = m->CreateTag("FORCE",DATA_REAL,CELL,NONE,1); // Create a new tag for external force
			double x[3];
			for( Mesh::iteratorCell cell = m->BeginCell(); cell != m->EndCell(); ++cell ) // Loop over mesh cells
			{
				cell->Centroid(x);
				tag_F[*cell] = -func_rhs(x,1);
				//tag_F[*cell] = -cell->Mean(func_rhs,1);
			}
		}
		
		if(m->HaveTag("REFERENCE_SOLUTION") )
			phi_ref = m->GetTag("REFERENCE_SOLUTION");
		else if( makerefsol )
		{
			phi_ref = m->CreateTag("REFRENCE_SOLUTION",DATA_REAL,CELL,NONE,1);
			double x[3];
			for( Mesh::iteratorCell cell = m->BeginCell(); cell != m->EndCell(); ++cell )
			{
				cell->Centroid(x);
				phi_ref[*cell] = func(x,0);//cell->Mean(func, 0);
			}
		}

		ttt = Timer();
		m->ExchangeGhost(1,FACE);
		m->ExchangeData(tag_K,CELL,0); // Exchange the tag_K data over processors
		BARRIER;
		if( m->GetProcessorRank() == 0 ) std::cout << "Exchange ghost: " << Timer()-ttt << std::endl;



		ttt = Timer();
		Solver S("inner_ilu2"); // Specify the linear solver to ASM+ILU2+BiCGStab one
		S.SetParameter("absolute_tolerance", "1e-8");
		S.SetParameter("schwartz_overlap", "2");
    	Residual R; // Residual vector
    	Sparse::LockService Locks;
		Sparse::Vector Update; // Declare the solution and the right-hand side vectors

		{
			Mesh::GeomParam table;
			table[CENTROID] = CELL | FACE;
			table[NORMAL] = FACE;
			table[ORIENTATION] = FACE;
			table[MEASURE] = CELL | FACE;
			table[BARYCENTER] = CELL | FACE;
			m->PrepareGeometricData(table);
		}
		BARRIER
		if( m->GetProcessorRank() == 0 ) std::cout << "Prepare geometric data: " << Timer()-ttt << std::endl;
		
		{
			Automatizator aut;
			Automatizator::MakeCurrent(&aut);
			INMOST_DATA_ENUM_TYPE iphi = aut.RegisterTag(phi,CELL);
			aut.EnumerateEntries();

			// Set the indeces intervals for the matrix and vectors
			R.SetInterval(aut.GetFirstIndex(),aut.GetLastIndex());
			R.InitLocks();
			Update.SetInterval(aut.GetFirstIndex(),aut.GetLastIndex());
			
			dynamic_variable Phi(aut,iphi);
			// Solve \nabla \cdot \nabla phi = f equation
			//for( Mesh::iteratorFace face = m->BeginFace(); face != m->EndFace(); ++face )
#if defined(USE_OMP)
#pragma omp parallel
#endif
			{
				variable flux; //should be more efficient to define here to avoid multiple memory allocations if storage for variations should be expanded
				rMatrix x1(3,1), x2(3,1), xf(3,1), n(3,1);
				double d1, d2, k1, k2, area, T, a, b, c;
#if defined(USE_OMP)
#pragma omp for
#endif
				for(Storage::integer iface = 0; iface < m->FaceLastLocalID(); ++iface ) if( m->isValidFace(iface) )
				{
					Face face = Face(m,ComposeFaceHandle(iface));
					Element::Status s1,s2;
					Cell r1 = face->BackCell();
					Cell r2 = face->FrontCell();
					if( ((!r1->isValid() || (s1 = r1->GetStatus()) == Element::Ghost)?0:1) +
						((!r2->isValid() || (s2 = r2->GetStatus()) == Element::Ghost)?0:1) == 0) continue;
					
					
					area = face->Area(); // Get the face area
					face->UnitNormal(n.data()); // Get the face normal
					face->Centroid(xf.data()); // Get the barycenter of the face
					r1->Centroid(x1.data());  // Get the barycenter of the cell
					k1 = n.DotProduct(rMatrix::FromTensor(tag_K[r1].data(),
														  tag_K[r1].size(),3)*n);
					d1 = fabs(n.DotProduct(xf-x1));
					if( !r2->isValid() ) // boundary condition
					{
						// bnd_pnt is a projection of the cell center to the face
						// a*pb + bT(pb-p1) = c
						// F = T(pb-p1)
						// pb = (c + bTp1)/(a+bT)
						// F = T/(a+bT)(c - ap1)
						T = k1/d1;
						a = 0;
						b = 1;
						c = 0;
						if( tag_BC.isValid() && face.HaveData(tag_BC) )
						{
							a = tag_BC[face][0];
							b = tag_BC[face][1];
							c = tag_BC[face][2];
							//std::cout << "a " << a << " b " << b << " c " << c << std::endl;
						}
						R.Lock(Phi.Index(r1));
						R[Phi.Index(r1)] -=  T/(a + b*T) * area * (c - a*Phi(r1));
						R.UnLock(Phi.Index(r1));
					}
					else
					{
						r2->Centroid(x2.data());
						k2 = n.DotProduct(rMatrix::FromTensor(tag_K[r2].data(),
															  tag_K[r2].size(),3)*n);
						d2 = fabs(n.DotProduct(x2-xf));
						T = 1.0/(d1/k1 + d2/k2);
						flux = T* area * (Phi(r2) - Phi(r1));
						if( s1 != Element::Ghost )
						{
							R.Lock(Phi.Index(r1));
							R[Phi.Index(r1)] -= flux;
							R.UnLock(Phi.Index(r1));
						}
						if( s2 != Element::Ghost )
						{
							R.Lock(Phi.Index(r2));
							R[Phi.Index(r2)] += flux;
							R.UnLock(Phi.Index(r2));
						}
					}
				}
			}
			if( tag_F.isValid() )
			{
#if defined(USE_OMP)
#pragma omp parallel for
#endif
				for( Storage::integer icell = 0; icell < m->CellLastLocalID(); ++icell ) if( m->isValidCell(icell) )
				{
					Cell cell = Cell(m,ComposeCellHandle(icell));
					if( cell->GetStatus() != Element::Ghost )
						R[Phi.Index(cell)] -= tag_F[cell] * cell->Volume();
				}
			}
			BARRIER;
			if( m->GetProcessorRank() == 0 ) std::cout << "Matrix assemble: " << Timer()-ttt << std::endl;

			//m->RemoveGeometricData(table); // Clean the computed geometric data

			if( argc > 3 ) // Save the matrix and RHS if required
			{
				ttt = Timer();
				R.GetJacobian().Save(std::string(argv[2])); // "A.mtx"
				R.GetResidual().Save(std::string(argv[3])); // "b.rhs"
				BARRIER;
				if( m->GetProcessorRank() == 0 ) std::cout << "Save matrix \"" << argv[2] << "\" and RHS \"" << argv[3] << "\": " << Timer()-ttt << std::endl;
			}

			ttt = Timer();

			S.SetMatrix(R.GetJacobian()); // Compute the preconditioner for the original matrix
			S.Solve(R.GetResidual(),Update);   // Solve the linear system with the previously computted preconditioner

			BARRIER;
			if( m->GetProcessorRank() == 0 ) 
			{
				std::cout << S.Residual() << " " << S.Iterations() << " " << S.ReturnReason() << std::endl;
				std::cout << "Solve system: " << Timer()-ttt << std::endl;
			}

			ttt = Timer();

			
			if( phi_ref.isValid() )
			{
				Tag error = m->CreateTag("error",DATA_REAL,CELL,NONE,1);
				double err_C = 0.0, err_L2 = 0.0, vol = 0.0;
#if defined(USE_OMP)
#pragma omp parallel
#endif
				{
					double local_err_C = 0;
#if defined(USE_OMP)
#pragma omp for reduction(+:err_L2) reduction(+:vol)
#endif
					for( Storage::integer icell = 0; icell < m->CellLastLocalID(); ++icell ) if( m->isValidCell(icell) )
					{
						Cell cell = Cell(m,ComposeCellHandle(icell));
						if( cell->GetStatus() != Element::Ghost )
						{
							double old = phi[cell];
							double exact = phi_ref[cell];
							double res = Update[Phi.Index(cell)];
							double sol = old-res;
							double err = fabs (sol - exact);
							if (err > local_err_C) local_err_C = err;
							err_L2 += err * err * cell->Volume();
							vol += cell->Volume();
							cell->Real(error) = err;
							phi[cell] = sol;
						}
					}
#if defined(USE_OMP)
#pragma omp critical
#endif
					{
						if( local_err_C > err_C ) err_C = local_err_C;
					}
				}
				err_C = m->AggregateMax(err_C); // Compute the maximal C norm for the error
				err_L2 = sqrt(m->Integrate(err_L2)/m->Integrate(vol)); // Compute the global L2 norm for the error
				if( m->GetProcessorRank() == 0 ) std::cout << "err_C  = " << err_C << std::endl;
				if( m->GetProcessorRank() == 0 ) std::cout << "err_L2 = " << err_L2 << std::endl;
			}
		}
		BARRIER;
		if( m->GetProcessorRank() == 0 ) std::cout << "Compute true residual: " << Timer()-ttt << std::endl;

		ttt = Timer();
		m->ExchangeData(phi,CELL,0); // Data exchange over processors
		BARRIER;
		if( m->GetProcessorRank() == 0 ) std::cout << "Exchange phi: " << Timer()-ttt << std::endl;

		std::string filename = "result";
		if( m->GetProcessorsNumber() == 1 )
			filename += ".vtk";
		else
			filename += ".pvtk";
		ttt = Timer();
		m->Save(filename);
		m->Save("result.pmf");
		BARRIER;
		if( m->GetProcessorRank() == 0 ) std::cout << "Save \"" << filename << "\": " << Timer()-ttt << std::endl;


		delete m;
	}
Example #25
0
void Listlay::subrender()
{
	Graphics *gfx = Graphics::FromImage(this->image);
	gfx->Clear(CLR_WHITE);

	Cacher *cacher = this->core->getCacher();
	if( cacher != NULL ){
		FwCHAR *string = NULL;
		FwCHAR *name = NULL;
		Cell *cell = NULL;
		int i, x, y;
		bool top, bot, archived = false;

		top = false;
		bot = false;

		x = LST_X;
		y = LST_Y;

		for( i = -CACHE_SIZE; i < CACHE_SIZE; i++ ){
			cacher->lockCache();

			if( cacher->getCache() != NULL ){
				cell = cacher->getCache()->gettoThat(i);
				if( cell != NULL ){
					if( cell->getFile() != NULL ){
						name = cell->getFile()->getFileName();
					}
					if( name != NULL ){
						if( i == 0 )
							gfx->FillRectangle(this->Brush_LiteBack,0,y+1,OVL_SIZE,FONTSIZE+2);
						
						string = name;
						if( cell->getFile()->isArchived() == true ){
							if( archived == false )
								archived = true;

							string = new FwCHAR(L"~");
							string->mergeWith(name);

							x = 3*LST_X;
						}
						else if( archived == true ){
							archived = false;
							x = LST_X;
						}
						gfx->DrawString(string->toWCHAR(),
										string->toLength(),
										this->Font_Default,
										PointF((REAL)x,(REAL)y),
										this->Brush_DarkBack);

						if( archived == true )
							delete string;
					}
					if( i == -1 && cacher->getCache()->isThatHead() == false )
						top = true;
					if( i == 1 && cacher->getCache()->isThatTail() == false )
						bot = true;
				}
			}
			cacher->unlockCache();

			y += (FONTSIZE + 2);
		}
		int size = 3;
		int width = 20;
		int ax = (int)(OVL_SIZE/2);
		int ay = LST_Y;
		int asize = OVL_SIZE - 2*LST_Y;
		Point arrow[3];

		if( top == true ){
			arrow[0].X = ax - width;
			arrow[0].Y = ay;
			arrow[1].X = ax;
			arrow[1].Y = ay - width;
			arrow[2].X = ax + width;
			arrow[2].Y = ay;
			gfx->FillPolygon(this->Brush_LiteBack,arrow,size);
		}
		if( bot == true ){
			arrow[0].X = ax - width;
			arrow[0].Y = ay + asize;
			arrow[1].X = ax;
			arrow[1].Y = ay + asize + width;
			arrow[2].X = ax + width;
			arrow[2].Y = ay + asize;
			gfx->FillPolygon(this->Brush_LiteBack,arrow,size);
		}
	}
	if( this->ticker > TICKER_OFF ){
		int tsize = TICKER_SIZE;
		int tx,ty;
		if( this->ticker == 0 ){
			tx = OVL_SIZE - 2*TICKER_INDENT;
			ty = OVL_SIZE - 2*TICKER_INDENT;
		}
		if( this->ticker == 1 ){
			tx = OVL_SIZE - TICKER_INDENT;
			ty = OVL_SIZE - 2*TICKER_INDENT;
		}
		if( this->ticker == 2 ){
			tx = OVL_SIZE - TICKER_INDENT;
			ty = OVL_SIZE - TICKER_INDENT;
		}
		if( this->ticker == 3 ){
			tx = OVL_SIZE - 2*TICKER_INDENT;
			ty = OVL_SIZE - TICKER_INDENT;
		}
		gfx->FillRectangle(this->Brush_DarkBack,tx,ty,tsize,tsize);
	}
	delete gfx;
}
Example #26
0
void BinnedCorr2<D1,D2>::process11(const Cell<D1,C>& c1, const Cell<D2,C>& c2)
{
    if (c1.getW() == 0. || c2.getW() == 0.) return;

    const double dsq = MetricHelper<M>::DistSq(c1.getPos(),c2.getPos());
    const double s1ps2 = c1.getAllSize()+c2.getAllSize();

    if (MetricHelper<M>::TooSmallDist(c1.getPos(), c2.getPos(), s1ps2, dsq, _minsep, _minsepsq))
        return;
    if (MetricHelper<M>::TooLargeDist(c1.getPos(), c2.getPos(), s1ps2, dsq, _maxsep, _maxsepsq))
        return;

    // See if need to split:
    bool split1=false, split2=false;
    CalcSplitSq(split1,split2,c1,c2,dsq,s1ps2,_bsq);

    if (split1) {
        if (split2) {
            if (!c1.getLeft()) {
                std::cerr<<"minsep = "<<_minsep<<", maxsep = "<<_maxsep<<std::endl;
                std::cerr<<"minsepsq = "<<_minsepsq<<", maxsepsq = "<<_maxsepsq<<std::endl;
                std::cerr<<"c1.Size = "<<c1.getSize()<<", c2.Size = "<<c2.getSize()<<std::endl;
                std::cerr<<"c1.SizeSq = "<<c1.getSizeSq()<<
                    ", c2.SizeSq = "<<c2.getSizeSq()<<std::endl;
                std::cerr<<"c1.N = "<<c1.getN()<<", c2.N = "<<c2.getN()<<std::endl;
                std::cerr<<"c1.Pos = "<<c1.getPos();
                std::cerr<<", c2.Pos = "<<c2.getPos()<<std::endl;
                std::cerr<<"dsq = "<<dsq<<", s1ps2 = "<<s1ps2<<std::endl;
            }
            Assert(c1.getLeft());
            Assert(c1.getRight());
            Assert(c2.getLeft());
            Assert(c2.getRight());
            process11<C,M>(*c1.getLeft(),*c2.getLeft());
            process11<C,M>(*c1.getLeft(),*c2.getRight());
            process11<C,M>(*c1.getRight(),*c2.getLeft());
            process11<C,M>(*c1.getRight(),*c2.getRight());
        } else {
            Assert(c1.getLeft());
            Assert(c1.getRight());
            process11<C,M>(*c1.getLeft(),c2);
            process11<C,M>(*c1.getRight(),c2);
        }
    } else {
        if (split2) {
            Assert(c2.getLeft());
            Assert(c2.getRight());
            process11<C,M>(c1,*c2.getLeft());
            process11<C,M>(c1,*c2.getRight());
        } else if (dsq >= _minsepsq && dsq < _maxsepsq) {
            XAssert(NoSplit(c1,c2,sqrt(dsq),_b));
            directProcess11<C,M>(c1,c2,dsq);
        }
    }
}
Example #27
0
void Margolus::CreateRotateBlock3D(Block3D & block, Rotate3D rotate, cuint& ix,
        cuint& iy, cuint& iz, bool act, bool mod) {
    block.rotate = rotate;
    memset(block.move, 0, sizeof(block.move));
    // front
    for (uint x = 0; x < 2; ++x) {
        for (uint y = 0; y < 2; ++y) {
            for (uint z = 0; z < 2; ++z) {
                block.cells[x][y][z].Clear();
                for (pSub & sub : cells[ix + x][iy + y][iz + z].GetSubs()) {
                    if (sub->GetType() == ACTIVE || sub->GetType() == MODIFIER) {
                        x == 0 ? --block.move[1] : --block.move[2];
                        y == 0 ? --block.move[3] : --block.move[4];
                        z == 0 ? --block.move[5] : --block.move[6];
                    }
                }
            }
        }
    }
    
    switch (rotate) {
        case ClockWiceX:
            for (uint x = 0; x < 2; ++x) {
                for (uint i = 0; i < 4; ++i) {
                    Cell cell = cells[ix + x][iy + indexF[i][0]][iz + indexF[i][1]];

                    if (cell.HaveSolid()) {
                        block.cells[x][indexF[i][0]][indexF[i][1]] = cell;
                    } else {
                        if (cell.HaveActive()) {
                            uint q = act ? 1 : 0;
                            for (pSub & sub : cell.GetSubs()) {
                                if (sub->GetType() == ACTIVE) {
                                    block.cells[x][indexF[i + q][0]][indexF[i + q][1]].AddSub(sub);
                                }
                            }
                        }

                        if (cell.HaveModifier()) {
                            if (mod) {
                                for (pSub & sub : cell.GetSubs()) {
                                    if (sub->GetType() == MODIFIER) {
                                        int u = 1;
                                        while (true) {
                                            if (cells[ix + x][iy + indexF[i + u][0]][iz + indexF[i + u][1]].HaveSolid()) {
                                                ++u;
                                            } else {
                                                block.cells[x][indexF[i + u][0]][indexF[i + u][1]].AddSub(sub);
                                                break;
                                            }
                                        }
                                    }
                                }
                            } else {
                                for (pSub & sub : cell.GetSubs()) {
                                    if (sub->GetType() == MODIFIER) {
                                        block.cells[x][indexF[i][0]][indexF[i][1]].AddSub(sub);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            break;
        case CounterClockWiceX:
            for (uint x = 0; x < 2; ++x) {
                for (uint i = 0; i < 4; ++i) {
                    Cell cell = cells[ix + x][iy + indexB[i][0]][iz + indexB[i][1]];

                    if (cell.HaveSolid()) {
                        block.cells[x][indexB[i][0]][indexB[i][1]] = cell;
                    } else {
                        if (cell.HaveActive()) {
                            uint q = act ? 1 : 0;
                            for (pSub & sub : cell.GetSubs()) {
                                if (sub->GetType() == ACTIVE) {
                                    block.cells[x][indexB[i + q][0]][indexB[i + q][1]].AddSub(sub);
                                }
                            }
                        }

                        if (cell.HaveModifier()) {
                            if (mod) {
                                for (pSub & sub : cell.GetSubs()) {
                                    if (sub->GetType() == MODIFIER) {
                                        int u = 1;
                                        while (true) {
                                            if (cells[ix+ x][iy + indexB[i + u][0]][iz + indexB[i + u][1]].HaveSolid()) {
                                                ++u;
                                            } else {
                                                block.cells[x][indexB[i + u][0]][indexB[i + u][1]].AddSub(sub);
                                                break;
                                            }
                                        }
                                    }
                                }
                            } else {
                                for (pSub & sub : cell.GetSubs()) {
                                    if (sub->GetType() == MODIFIER) {
                                        block.cells[x][indexB[i][0]][indexB[i][1]].AddSub(sub);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            break;
        case ClockWiceY:
            for (uint y = 0; y < 2; ++y) {
                for (uint i = 0; i < 4; ++i) {
                    Cell cell = cells[ix + indexF[i][1]][iy + y][iz + indexF[i][0]];

                    if (cell.HaveSolid()) {
                        block.cells[indexF[i][1]][y][indexF[i][0]] = cell;
                    } else {
                        if (cell.HaveActive()) {
                            uint q = act ? 1 : 0;
                            for (pSub & sub : cell.GetSubs()) {
                                if (sub->GetType() == ACTIVE) {
                                    block.cells[indexF[i + q][1]][y][indexF[i + q][0]].AddSub(sub);
                                }
                            }
                        }

                        if (cell.HaveModifier()) {
                            if (mod) {
                                for (pSub & sub : cell.GetSubs()) {
                                    if (sub->GetType() == MODIFIER) {
                                        int u = 1;
                                        while (true) {
                                            if (cells[ix + indexF[i + u][1]][iy + y][iz + indexF[i + u][0]].HaveSolid()) {
                                                ++u;
                                            } else {
                                                block.cells[indexF[i + u][1]][y][indexF[i + u][0]].AddSub(sub);
                                                break;
                                            }
                                        }
                                    }
                                }
                            } else {
                                for (pSub & sub : cell.GetSubs()) {
                                    if (sub->GetType() == MODIFIER) {
                                        block.cells[indexF[i][1]][y][indexF[i][0]].AddSub(sub);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            break;
        case CounterClockWiceY:
            for (uint y = 0; y < 2; ++y) {
                for (uint i = 0; i < 4; ++i) {
                    Cell cell = cells[ix + indexB[i][1]][iy + y][iz + indexB[i][0]];

                    if (cell.HaveSolid()) {
                        block.cells[indexB[i][1]][y][indexB[i][0]] = cell;
                    } else {
                        if (cell.HaveActive()) {
                            uint q = act ? 1 : 0;
                            for (pSub & sub : cell.GetSubs()) {
                                if (sub->GetType() == ACTIVE) {
                                    block.cells[indexB[i + q][1]][y][indexB[i + q][0]].AddSub(sub);
                                }
                            }
                        }

                        if (cell.HaveModifier()) {
                            if (mod) {
                                for (pSub & sub : cell.GetSubs()) {
                                    if (sub->GetType() == MODIFIER) {
                                        int u = 1;
                                        while (true) {
                                            if (cells[ix + indexB[i + u][1]][iy + y][iz + indexB[i + u][0]].HaveSolid()) {
                                                ++u;
                                            } else {
                                                block.cells[indexB[i + u][1]][y][indexB[i + u][0]].AddSub(sub);
                                                break;
                                            }
                                        }
                                    }
                                }
                            } else {
                                for (pSub & sub : cell.GetSubs()) {
                                    if (sub->GetType() == MODIFIER) {
                                        block.cells[indexB[i][1]][y][indexB[i][0]].AddSub(sub);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            break;
        case ClockWiceZ:
            for (uint z = 0; z < 2; ++z) {
                for (uint i = 0; i < 4; ++i) {
                    Cell cell = cells[ix + indexF[i][0]][iy + indexF[i][1]][iz + z];

                    if (cell.HaveSolid()) {
                        block.cells[indexF[i][0]][indexF[i][1]][z] = cell;
                    } else {
                        if (cell.HaveActive()) {
                            uint q = act ? 1 : 0;
                            for (pSub & sub : cell.GetSubs()) {
                                if (sub->GetType() == ACTIVE) {
                                    block.cells[indexF[i + q][0]][indexF[i + q][1]][z].AddSub(sub);
                                }
                            }
                        }

                        if (cell.HaveModifier()) {
                            if (mod) {
                                for (pSub & sub : cell.GetSubs()) {
                                    if (sub->GetType() == MODIFIER) {
                                        int u = 1;
                                        while (true) {
                                            if (cells[ix + indexF[i + u][0]][iy + indexF[i + u][1]][z].HaveSolid()) {
                                                ++u;
                                            } else {
                                                block.cells[indexF[i + u][0]][indexF[i + u][1]][z].AddSub(sub);
                                                break;
                                            }
                                        }
                                    }
                                }
                            } else {
                                for (pSub & sub : cell.GetSubs()) {
                                    if (sub->GetType() == MODIFIER) {
                                        block.cells[indexF[i][0]][indexF[i][1]][z].AddSub(sub);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            break;
        case CounterClockWiceZ:
            for (uint z = 0; z < 2; ++z) {
                for (uint i = 0; i < 4; ++i) {
                    Cell cell = cells[ix + indexB[i][0]][iy + indexB[i][1]][iz + z];

                    if (cell.HaveSolid()) {
                        block.cells[indexB[i][0]][indexB[i][1]][z] = cell;
                    } else {
                        if (cell.HaveActive()) {
                            uint q = act ? 1 : 0;
                            for (pSub & sub : cell.GetSubs()) {
                                if (sub->GetType() == ACTIVE) {
                                    block.cells[indexB[i + q][0]][indexB[i + q][1]][z].AddSub(sub);
                                }
                            }
                        }

                        if (cell.HaveModifier()) {
                            if (mod) {
                                for (pSub & sub : cell.GetSubs()) {
                                    if (sub->GetType() == MODIFIER) {
                                        int u = 1;
                                        while (true) {
                                            if (cells[ix + indexB[i + u][0]][iy + indexB[i + u][1]][iz + z].HaveSolid()) {
                                                ++u;
                                            } else {
                                                block.cells[indexB[i + u][0]][indexB[i + u][1]][z].AddSub(sub);
                                                break;
                                            }
                                        }
                                    }
                                }
                            } else {
                                for (pSub & sub : cell.GetSubs()) {
                                    if (sub->GetType() == MODIFIER) {
                                        block.cells[indexB[i][0]][indexB[i][1]][z].AddSub(sub);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            break;
    }
    
    for (uint x = 0; x < 2; ++x) {
        for (uint y = 0; y < 2; ++y) {
            for (uint z = 0; z < 2; ++z) {
                for (pSub & sub : block.cells[x][y][z].GetSubs()) {
                    if (sub->GetType() == ACTIVE || sub->GetType() == MODIFIER) {
                        x == 0 ? ++block.move[1] : ++block.move[2];
                        y == 0 ? ++block.move[3] : ++block.move[4];
                        z == 0 ? ++block.move[5] : ++block.move[6];
                    }
                }
            }
        }
    }
}
Example #28
0
 static void ProcessXi(
     const Cell<KData,C>& c1, const Cell<KData,C>& c2, const double ,
     XiData<KData,KData>& xi, int k)
 { xi.xi[k] += c1.getData().getWK() * c2.getData().getWK(); }
Example #29
0
// era: encode references absolutely
QDomDocument CopyCommand::saveAsXml(const Region& region, bool era)
{
    QDomDocument xmlDoc("spreadsheet-snippet");
    xmlDoc.appendChild(xmlDoc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\""));
    QDomElement root = xmlDoc.createElement("spreadsheet-snippet");
    xmlDoc.appendChild(root);

    // find the upper left corner of the selection
    const QRect boundingRect = region.boundingRect();
    int left = boundingRect.left();
    int top = boundingRect.top();

    // for tiling the clipboard content in the selection
    root.setAttribute("rows", QString::number(boundingRect.height()));
    root.setAttribute("columns", QString::number(boundingRect.width()));

    const Region::ConstIterator end(region.constEnd());
    for (Region::ConstIterator it = region.constBegin(); it != end; ++it) {
        Sheet *const sheet = (*it)->sheet();
        const QRect range = (*it)->rect();
        CellStorage *const storage = sheet->cellStorage();

        //
        // Entire rows selected?
        //
        if ((*it)->isRow()) {
            QDomElement rows = xmlDoc.createElement("rows");
            rows.setAttribute("count", QString::number(range.height()));
            rows.setAttribute("row", QString::number(range.top() - top + 1));
            root.appendChild(rows);

            // Save all cells.
            for (int row = range.top(); row <= range.bottom(); ++row) {
                Cell cell = storage->firstInRow(row);
                for (; !cell.isNull(); cell = storage->nextInRow(cell.column(), cell.row())) {
                    if (!cell.isPartOfMerged()) {
                        root.appendChild(cell.save(xmlDoc, 0, top - 1, era));
                    }
                }
            }

            // TODO Stefan: Inefficient, use cluster functionality
            // Save the row formats if there are any
            //const RowFormat* format;
            for (int row = range.top(); row <= range.bottom(); ++row) {
                if (!sheet->rowFormats()->isDefaultRow(row)) {
                    QDomElement e = RowFormat(sheet->rowFormats(), row).save(xmlDoc, top - 1);
                    if (!e.isNull()) {
                        rows.appendChild(e);
                    }
                }
            }
            continue;
        }

        //
        // Entire columns selected?
        //
        if ((*it)->isColumn()) {
            QDomElement columns = xmlDoc.createElement("columns");
            columns.setAttribute("count", QString::number(range.width()));
            columns.setAttribute("column", QString::number(range.left() - left + 1));
            root.appendChild(columns);

            // Save all cells.
            for (int col = range.left(); col <= range.right(); ++col) {
                Cell cell = storage->firstInColumn(col);
                for (; !cell.isNull(); cell = storage->nextInColumn(cell.column(), cell.row())) {
                    if (!cell.isPartOfMerged()) {
                        root.appendChild(cell.save(xmlDoc, left - 1, 0, era));
                    }
                }
            }

            // TODO Stefan: Inefficient, use the cluster functionality
            // Save the column formats if there are any
            const ColumnFormat* format;
            for (int col = range.left(); col <= range.right(); ++col) {
                format = sheet->columnFormat(col);
                if (format && !format->isDefault()) {
                    QDomElement e = format->save(xmlDoc, left - 1);
                    if (!e.isNull()) {
                        columns.appendChild(e);
                    }
                }
            }
            continue;
        }

        // Save all cells.
        Cell cell;
        for (int row = range.top(); row <= range.bottom(); ++row) {
            if (range.left() == 1) {
                cell = storage->firstInRow(row);
            } else {
                cell = storage->nextInRow(range.left() - 1, row);
            }
            while (!cell.isNull() && cell.column() >= range.left() && cell.column() <= range.right()) {
                if (!cell.isPartOfMerged()) {
                    root.appendChild(cell.save(xmlDoc, left - 1, top - 1, era));
                }
                cell = storage->nextInRow(cell.column(), cell.row());
            }
        }
    }
    return xmlDoc;
}
Example #30
0
//lĂ­nea recta horitzontal cap a l'est
void Path::addCell(double x, double y) {
	Cell c;
	c.setTypeEnd(_NONE);
	setPositionXY(&c,x,y);
	cellsPath.push_back(c);
}