Esempio n. 1
0
/* addLoop:
 * Add two temporary nodes to sgraph corresponding to two ends of a loop at cell cp, i
 * represented by dp and sp.
 */
static void
addLoop (sgraph* sg, cell* cp, snode* dp, snode* sp)
{
    int i;
    int onTop;
    pointf midp = midPt (cp);

    for (i = 0; i < cp->nsides; i++) {
	cell* ocp;
	pointf p;
	double wt;
	snode* onp = cp->sides[i];

	if (onp->isVert) continue;
	if (onp->cells[0] == cp) {
	    onTop = 1;
	    ocp = onp->cells[1];
	}
	else {
	    onTop = 0;
	    ocp = onp->cells[0];
	}
	p = sidePt (onp, ocp);
	wt = abs(p.x - midp.x) +  abs(p.y - midp.y);
	if (onTop)
	    createSEdge (sg, sp, onp, 0);  /* FIX weight */
	else
	    createSEdge (sg, dp, onp, 0);  /* FIX weight */
    }
    sg->nnodes += 2;
}
Esempio n. 2
0
/* addNodeEdges:
 * Add temporary node to sgraph corresponding to cell cp, represented
 * by np.
 */
static void
addNodeEdges (sgraph* sg, cell* cp, snode* np)
{
    int i;
    pointf midp = midPt (cp);

    for (i = 0; i < cp->nsides; i++) {
	snode* onp = cp->sides[i];
	cell* ocp;
	pointf p;
	double wt;

	if (onp->cells[0] == cp)
	    ocp = onp->cells[1];
	else
	    ocp = onp->cells[0];
	p = sidePt (onp, ocp);
	wt = abs(p.x - midp.x) +  abs(p.y - midp.y);
	createSEdge (sg, np, onp, 0);  /* FIX weight */
    }
    sg->nnodes++;
#ifdef DEBUG
    np->cells[0] = np->cells[1] = cp;
#endif
}
void normalizeLineSet(lineSet & lineSet, ofPolyline & input){
    
    ofPolyline output = input;
    vector< float > x;
    vector< float > y;
    for (int i = 0; i < output.getVertices().size(); i++){
        x.push_back(output[i].x);
        y.push_back(output[i].y);
    }
    float sumx, meanx, varx, devx, skewx, kurtx;
    float sumy, meany, vary, devy, skewy, kurty;
    computeStats(x.begin( ), x.end( ), sumx, meanx, varx, devx, skewx, kurtx);
    computeStats(y.begin( ), y.end( ), sumy, meany, vary, devy, skewy, kurty);
    float stdDev = sqrt(devx*devx + devy*devy);
    ofPoint midPt (meanx, meany);
    ofPoint dev (stdDev, stdDev);
    
    ofMatrix4x4 mat;
    mat.makeTranslationMatrix(-midPt.x, -midPt.y, 0);
    
    ofMatrix4x4 mat2;
    mat2.makeScaleMatrix(100.0/dev.x, 100.0/dev.y, 1.0);
    
    
    lineSet.normalizeLines = lineSet.lines;
    
    for (int i = 0; i < lineSet.normalizeLines.size(); i++){
        for (int j = 0; j < lineSet.normalizeLines[i].size(); j++){
            lineSet.normalizeLines[i][j] = lineSet.normalizeLines[i][j]  * mat * mat2;
        }
    }
}
Esempio n. 4
0
static void
emitSearchGraph (FILE* fp, sgraph* sg)
{
    cell* cp;
    snode* np;
    sedge* ep;
    point p;
    int i;
    fputs ("graph G {\n", fp);
    fputs (" node[shape=point]\n", fp);
    for (i = 0; i < sg->nnodes; i++) {
	np = sg->nodes+i;
	cp = np->cells[0];
	if (cp == np->cells[1]) {
	    pointf pf = midPt (cp);
	    p.x = pf.x;
	    p.y = pf.y;
	}
	else {
	    if (IsNode(cp)) cp = np->cells[1];
	    p = coordOf (cp, np);
	}
	fprintf (fp, "  %d [pos=\"%d,%d\"]\n", i, p.x, p.y);
    }
    for (i = 0; i < sg->nedges; i++) {
	ep = sg->edges+i;
	fprintf (fp, "  %d -- %d[len=\"%f\"]\n", ep->v1, ep->v2, ep->weight);
    }
    fputs ("}\n", fp);
}
transformation normalizeLineSetGetTrans (ofPolyline & input){
    
    transformation t;
    ofPolyline output = input;
    vector< float > x;
    vector< float > y;
    for (int i = 0; i < output.getVertices().size(); i++){
        x.push_back(output[i].x);
        y.push_back(output[i].y);
    }
    float sumx, meanx, varx, devx, skewx, kurtx;
    float sumy, meany, vary, devy, skewy, kurty;
    computeStats(x.begin( ), x.end( ), sumx, meanx, varx, devx, skewx, kurtx);
    computeStats(y.begin( ), y.end( ), sumy, meany, vary, devy, skewy, kurty);
    float stdDev = sqrt(devx*devx + devy*devy);
    ofPoint midPt (meanx, meany);
    ofPoint dev (stdDev, stdDev);
    
    //ofMatrix4x4 mat;
    t.mat.makeTranslationMatrix(-midPt.x, -midPt.y, 0);
    
    //ofMatrix4x4 mat2;
    t.mat2.makeScaleMatrix(100.0/dev.x, 100.0/dev.y, 1.0);
    return t;
}
ofPolyline returnNormalizedLine (ofPolyline & input){
    ofPolyline output = input;
    vector< float > x;
    vector< float > y;
    for (int i = 0; i < output.getVertices().size(); i++){
        x.push_back(output[i].x);
        y.push_back(output[i].y);
    }
    float sumx, meanx, varx, devx, skewx, kurtx;
    float sumy, meany, vary, devy, skewy, kurty;
    computeStats(x.begin( ), x.end( ), sumx, meanx, varx, devx, skewx, kurtx);
    computeStats(y.begin( ), y.end( ), sumy, meany, vary, devy, skewy, kurty);
    float stdDev = sqrt(devx*devx + devy*devy);
    ofPoint midPt (meanx, meany);
    ofPoint dev (stdDev, stdDev);
    
    
    ofMatrix4x4 mat;
    mat.makeTranslationMatrix(-midPt.x, -midPt.y, 0);
    
    ofMatrix4x4 mat2;
    mat2.makeScaleMatrix(100.0/dev.x, 100.0/dev.y, 1.0);
    // mat.scale(100,100,1.0);
    
    //mat *= mat2;
    
    
    for (int i = 0; i < output.getVertices().size(); i++){
        
        ofPoint input = output[i];
        
        output[i] -= midPt;
        output[i] /= dev;
        output[i]*= 100.0;
        
        //        cout << output[i] << endl;
        //        cout << "--> " << input << endl;
        //        cout << input * mat * mat2 << endl;
        //        cout << "--> " << (input * mat * mat2) * mat2.getInverse() * mat.getInverse() << endl;
        
    }
    //    ofRectangle boxOrig = input.getBoundingBox();
    //    ofRectangle box = boxOrig;
    //    ofRectangle outputBox(-100,-100,200,200);
    //    box.scaleTo(outputBox);
    //
    //    for (int i = 0; i < output.getVertices().size(); i++){
    //        output.getVertices()[i].x = ofMap( output.getVertices()[i].x, boxOrig.position.x, boxOrig.position.x + boxOrig.width,
    //                                           box.position.x, box.x + box.width);
    //        output.getVertices()[i].y = ofMap( output.getVertices()[i].y, boxOrig.position.y, boxOrig.position.y + boxOrig.height,
    //                                          box.position.x, box.y + box.height);
    //
    //    }
    
    return output;
    
}
Esempio n. 7
0
//      quadApprox - makes an approximation, which we hope is faster
static void quadApprox(SkPath &fPath, const SkPoint &p0, const SkPoint &p1, const SkPoint &p2)
{
    //divide the cubic up into two cubics, then convert them into quadratics
    //define our points
    SkPoint c,j,k,l,m,n,o,p,q, mid;
    fPath.getLastPt(&c);
    midPt(j, p0, c);
    midPt(k, p0, p1);
    midPt(l, p1, p2);
    midPt(o, j, k);
    midPt(p, k, l);
    midPt(q, o, p);
    //compute the first half
    m.set(SkScalarHalf(3*j.fX - c.fX), SkScalarHalf(3*j.fY - c.fY));
    n.set(SkScalarHalf(3*o.fX -q.fX), SkScalarHalf(3*o.fY - q.fY));
    midPt(mid,m,n);
    fPath.quadTo(mid,q);
    c = q;
    //compute the second half
    m.set(SkScalarHalf(3*p.fX - c.fX), SkScalarHalf(3*p.fY - c.fY));
    n.set(SkScalarHalf(3*l.fX -p2.fX),SkScalarHalf(3*l.fY -p2.fY));
    midPt(mid,m,n);
    fPath.quadTo(mid,p2);
}
Esempio n. 8
0
static route
convertSPtoRoute (sgraph* g, snode* fst, snode* lst)
{
    route rte;
    snode* ptr;
    snode* next;
    snode* prev;  /* node in shortest path just previous to next */
    int i, sz = 0;
    cell* cp;
    cell* ncp;
    segment seg;
    double fix, b1, b2;
    int l1, l2;
    pointf bp1, bp2, prevbp;  /* bend points */

	/* count no. of nodes in shortest path */
    for (ptr = fst; ptr; ptr = N_DAD(ptr)) sz++;
    rte.n = 0;
    rte.segs = N_NEW(sz-2, segment);  /* at most sz-2 segments */

    seg.prev = seg.next = 0;
    ptr = prev = N_DAD(fst);
    next = N_DAD(ptr);
    if (IsNode(ptr->cells[0]))
	cp = ptr->cells[1];
    else
	cp = ptr->cells[0];
    bp1 = sidePt (ptr, cp);
    while (N_DAD(next)!=NULL) {
	ncp = cellOf (prev, next);
	updateWts (g, ncp, N_EDGE(ptr));

        /* add seg if path bends or at end */
	if ((ptr->isVert != next->isVert) || (N_DAD(next) == lst)) {
	    if (ptr->isVert != next->isVert)
		bp2 = midPt (ncp);
	    else
		bp2 = sidePt(next, ncp);
	    if (ptr->isVert) {   /* horizontal segment */
		if (ptr == N_DAD(fst)) l1 = B_NODE;
		else if (prevbp.y > bp1.y) l1 = B_UP;
		else l1 = B_DOWN; 
		if (ptr->isVert != next->isVert) {
		    if (next->cells[0] == ncp) l2 = B_UP;
		    else l2 = B_DOWN;
		}
		else l2 = B_NODE;
		fix = cp->bb.LL.y;
		b1 = cp->bb.LL.x;
		b2 = ncp->bb.LL.x;
	    }
	    else {   /* vertical segment */
		if (ptr == N_DAD(fst)) l1 = B_NODE;
		else if (prevbp.x > bp1.x) l1 = B_RIGHT;
		else l1 = B_LEFT; 
		if (ptr->isVert != next->isVert) {
		    if (next->cells[0] == ncp) l2 = B_RIGHT;
		    else l2 = B_LEFT;
		}
		else l2 = B_NODE;
		fix = cp->bb.LL.x;
		b1 = cp->bb.LL.y;
		b2 = ncp->bb.LL.y;
	    }
	    setSeg (&seg, !ptr->isVert, fix, b1, b2, l1, l2);
	    rte.segs[rte.n++] = seg;
	    cp = ncp;
	    prevbp = bp1;
	    bp1 = bp2;
	    if ((ptr->isVert != next->isVert) && (N_DAD(next) == lst)) {
		bp2 = sidePt(next, ncp);
		l2 = B_NODE;
		if (next->isVert) {   /* horizontal segment */
		    if (prevbp.y > bp1.y) l1 = B_UP;
		    else l1 = B_DOWN; 
		    fix = cp->bb.LL.y;
		    b1 = cp->bb.LL.x;
		    b2 = ncp->bb.LL.x;
		}
		else {
		    if (prevbp.x > bp1.x) l1 = B_RIGHT;
		    else l1 = B_LEFT; 
		    fix = cp->bb.LL.x;
		    b1 = cp->bb.LL.y;
		    b2 = ncp->bb.LL.y;
		}
		setSeg (&seg, !next->isVert, fix, b1, b2, l1, l2);
		rte.segs[rte.n++] = seg;
	    }
	    ptr = next;
	}
	prev = next;
	next = N_DAD(next);
    }

    rte.segs = realloc (rte.segs, rte.n*sizeof(segment));
    for (i=0; i<rte.n; i++) {
	if (i > 0)
	    rte.segs[i].prev = rte.segs + (i-1);
	if (i < rte.n-1)
	    rte.segs[i].next = rte.segs + (i+1);
    }

    return rte;
}
Esempio n. 9
0
/**
 * Recursively subdivision of a parcel using OBB technique
 * @param parcel			parcel
 * @param areaMean			mean parcel area
 * @param areaStd			StdDev of parcel area
 * @param splitIrregularity	A normalized value 0-1 indicating how far from the middle point the split line should be.
 * @param outParcels		the resulting subdivision
 **/
bool PmParcels::subdivideParcel(Parcel& parcel, float areaMean, float areaStd, float splitIrregularity, std::vector<Parcel> &outParcels) {
	float thresholdArea = std::max(0.0f, Util::genRandNormal(areaMean, areaStd));
	
	if (parcel.parcelContour.area() <= thresholdArea * 1.5f) {
		outParcels.push_back(parcel);
		return true;
	}

	// compute OBB
	QVector3D obbSize;
	QMatrix4x4 obbMat;
	parcel.parcelContour.getMyOBB(obbSize, obbMat);

	// compute split line passing through center of OBB TODO (+/- irregularity)
	//		and with direction parallel/perpendicular to OBB main axis
	QVector3D slEndPoint;
	QVector3D dirVectorInit, dirVector, dirVectorOrthogonal;
	QVector3D midPt(0.0f, 0.0f, 0.0f);
	QVector3D auxPt(1.0f, 0.0f, 0.0f);
	QVector3D midPtNoise(0.0f, 0.0f, 0.0f);
	std::vector<QVector3D> splitLine;	

	midPt = midPt*obbMat;

	dirVectorInit = (auxPt*obbMat - midPt);
	dirVectorInit.normalize();
	if (obbSize.x() > obbSize.y()) {
		dirVector.setX(-dirVectorInit.y());
		dirVector.setY(dirVectorInit.x());
	} else {
		dirVector = dirVectorInit;
	}

	midPtNoise.setX(splitIrregularity * Util::genRand(-10, 10));
	midPtNoise.setY(splitIrregularity * Util::genRand(-10, 10));
	midPt = midPt + midPtNoise;

	slEndPoint = midPt + 10000.0f*dirVector;
	splitLine.push_back(slEndPoint);
	slEndPoint = midPt - 10000.0f*dirVector;
	splitLine.push_back(slEndPoint);

	// split parcel with line and obtain two new parcels
	Polygon3D pgon1, pgon2;

	float kDistTol = 0.01f;

	std::vector<Polygon3D> pgons;

	// Use the simple splitting because this is fast
	if (parcel.parcelContour.splitMeWithPolyline(splitLine, pgon1.contour, pgon2.contour)) {
		Parcel parcel1;
		Parcel parcel2;

		parcel1.parcelContour = pgon1;
		parcel2.parcelContour = pgon2;

		// call recursive function for both parcels
		subdivideParcel(parcel1, areaMean, areaStd, splitIrregularity, outParcels);
		subdivideParcel(parcel2, areaMean, areaStd, splitIrregularity, outParcels);
	} else {
		// If the simple splitting fails, try CGAL version which is slow
		if (parcel.parcelContour.split(splitLine, pgons)) {
			for (int i = 0; i < pgons.size(); ++i) {
				Parcel parcel;
				parcel.parcelContour = pgons[i];

				subdivideParcel(parcel, areaMean, areaStd, splitIrregularity, outParcels);
			}
		} else {
			parcel.isPark = true;
			outParcels.push_back(parcel);
		}
	}

	return true;
}
Esempio n. 10
0
int main(int argc, char* argv[]) {

#ifdef HAVE_MPI
  MPI::Init(argc, argv);
#endif
  RCP<MxComm> myComm = rcp(new MxComm());

#if 0
#ifdef HAVE_MPI
  MPI::Init(argc, argv);
  //MPI_Init(argc, argv);
  Epetra_MpiComm myComm(MPI_COMM_WORLD);
#else
  Epetra_SerialComm myComm;
#endif
#endif

// input file method
#if 1

  std::string inFile;

  Teuchos::CommandLineProcessor cmdp(false, true);
  cmdp.setOption("infile", &inFile, "XML format input file.");
  if (cmdp.parse(argc,argv) != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL) {
    return -1;
  }

  if (inFile == "") {
    std::cout << "Please specify an input file using --infile=your_file.mx\n";
    exit(0);
  }

  // now read the input file with trilinos XML reader
  Teuchos::XMLObject xmlObj(Teuchos::FileInputSource(inFile).getObject());

  // get simulation dimension
  int dim = atoi(MxUtil::XML::getAttr("dim", xmlObj).c_str());
  if (dim < 1 or dim > 3) {
    std::cout << "Simulation dimension invalid or not given, using 3D.\n";
    dim = 3;
  }

  // get simulation type
  std::string domain = MxUtil::XML::getAttr("domain", xmlObj).c_str();
  if (domain != "frequency" and domain != "time") {
    std::cout << "Simulation domain invalid or not given, using frequency-domain.\n";
    domain = "frequency";
  }

  // create problem
  
  MxProblem<1> * prob1d;
  MxProblem<2> * prob2d;
  MxProblem<3> * prob3d;
  switch (dim) {
    case 1:
      prob1d = new MxProblem<1>(xmlObj, myComm);
      prob1d->solve();
      delete prob1d;
      break;
    case 2:
      prob2d = new MxProblem<2>(xmlObj, myComm);
      prob2d->solve();
      delete prob2d;
      break;
    case 3:
      prob3d = new MxProblem<3>(xmlObj, myComm);
      prob3d->solve();
      delete prob3d;
      break;
  }
#endif


#if 0

  // epetra stuff test
  MxMap map(10, 0, myComm);
  Epetra_CrsMatrix mat(Copy, map, 0);
  int ind = 2;
  double val = 0;
  mat.InsertGlobalValues(1, 1, &val, &ind);
  ind = 3;
  val = 4;
  mat.InsertGlobalValues(1, 1, &val, &ind);
  mat.FillComplete(map, map);

  Epetra_Vector myvec(map);
  myvec.Random();

  std::cout << myvec;
  mat.Apply(myvec, myvec);
  std::cout << myvec;

  Epetra_CrsMatrix copy(mat);

  std::cout << mat;
  MxUtil::Epetra::stripZeros(mat);
  std::cout << mat;

  //throw 1;
#endif

  typedef MxDimVector<double, 3> vecd3;
  typedef MxDimVector<int, 3> veci3;

  vecd3 midPt(0);

#if 0
  //std::cout << "Crab cavity setup:\n";

  int crabNumCells = 4;
  double crabCellLen = 2.0 * 0.0192; //meters
  double crabCavRad = 0.04719;
  double crabIrisRad = 0.015;
  double crabCavRho = 0.0136;
  double crabIrisRho = 0.00331;

  int crabCellRes = 40;
  int padCells = 2;
  int cnx, cny, cnz;
  double clx, cly, clz;
  double cox, coy, coz;

  double crabDelta = crabCellLen / double(crabCellRes);

  cnz = crabNumCells * crabCellRes + 2 * padCells;
  clz = double(cnz) * crabDelta;
  coz = -0.5 * clz;

  cny = cnx = 2 * (int(ceil(crabCavRad / crabDelta)) + padCells);
  cly = clx = double(cnx) * crabDelta;
  coy = cox = -0.5 * clx;
  
  veci3 crabN; crabN[0] = cnx; crabN[1] = cny; crabN[2] = cnz;
  vecd3 crabL; crabL[0] = clx; crabL[1] = cly; crabL[2] = clz;
  vecd3 crabO; crabO[0] = cox; crabO[1] = coy; crabO[2] = coz;
  //crabN.print();
  //crabL.print();
  //crabO.print();
  
  MxGrid<3> crabGrid(crabO, crabN, crabL, &myComm);
  crabGrid.print();

  MxCrabCav crabCav(midPt, crabNumCells, crabCellLen, crabIrisRad, crabCavRad, crabIrisRho, crabCavRho);

  crabCav.save(crabGrid);

  Teuchos::ParameterList crabList;
  crabList.set("geo-mg : levels", 1);
  crabList.set("geo-mg : smoothers : sweeps", 5);
  crabList.set("amg : smoothers : sweeps", 1);
  crabList.set("amg : smoothers : type", "Chebyshev");
  crabList.set("eigensolver : output", 2);
  crabList.set("eigensolver : nev", 15);
  crabList.set("eigensolver : tol", 1.e-8);
  crabList.set("eigensolver : block size", 2);
  crabList.set("eigensolver : num blocks", 30);
  crabList.set("eigensolver : spectrum", "LM");
  crabList.set("wave operator : invert", true);
  crabList.set("wave operator : invert : tol", 1.e-10);
  //crabList.set("wave operator : invert : shift", 1000.0);
  crabList.set("wave operator : invert : max basis size", 40);

  MxEMSim<dim> crabSim;
  crabSim.setGrid(&crabGrid);
  crabSim.setPEC(&crabCav);
  //crabSim.setGrid(&sphGrid);
  //crabSim.setPEC(&ell);
  crabSim.setParameters(crabList);
  crabSim.setup();

  MxSolver<dim> * solver;
  solver = new MxSolver<dim>(&crabSim, crabList);
  solver->solve();

  delete solver;

  //return 1;
#endif

// optimized phc cavity
#if 0
  double rodRad = 0.003175; // meters
  const int numRods = 24;
  double rodx[numRods] = {0.0158406582694, 0.0551748491968, 0.0209567636489, 
                          0.0384658321918, 0.00792032913471, 0.0338604938991,
                          0.00477355412058, 0.00485955186622, -0.00792032913471,
                          -0.0213143552977, -0.0161832095283, -0.0336062803256,
                          -0.0158406582694, -0.0551748491968, -0.0209567636489,
                          -0.0384658321918, -0.00792032913471, -0.0338604938991,
                          -0.00477355412058, -0.00485955186622, 0.00792032913471,
                          0.0213143552977, 0.0161832095283, 0.0336062803256};
  double rody[numRods] = {0.0, -0.00724351649877, 0.006587367621, 
                    0.0165969314144, 0.013718412474, 0.044161062805,
                    0.0214427735115, 0.041610853563, 0.013718412474,
                    0.0514045793038, 0.0148554058905, 0.0250139221487,
                    1.9399211446e-18, 0.00724351649877, -0.006587367621,
                    -0.0165969314144, -0.013718412474, -0.044161062805,
                    -0.0214427735115, -0.041610853563, -0.013718412474,
                    -0.0514045793038, -0.0148554058905, -0.0250139221487};

  std::vector<MxShape<3> *> rods;
  MxShapeUnion<3> rodsShape;
  vecd3 rodPos;
  vecd3 zhat(0); zhat[2] = 1.0;
  for (int i = 0; i < numRods; i++) {
    rodPos[0] = rodx[i];
    rodPos[1] = rody[i];
    rodPos[2] = 0.0;
    rods.push_back(new MxCylinder(rodPos, zhat, rodRad));
    rodsShape.add(rods[i]);
  }

  MxDimMatrix<double, 3> sapphEps(0);
  sapphEps(0, 0) = 9.3;
  sapphEps(1, 1) = 9.3;
  sapphEps(2, 2) = 11.5;

  MxDielectric<3> phcDiel;
  phcDiel.add(&rodsShape, sapphEps);

  // conducting cavity
  double cavLen = 0.019624116824498831;
  double cavRad = 0.1;
  MxCylinder cavCyl(0, zhat, cavRad);
  MxSlab<3> cavCaps(0, zhat, cavLen);
  MxShapeIntersection<3> phcCav;
  phcCav.add(&cavCyl);
  phcCav.add(&cavCaps);

  // setup grid
  int rodDiaCells = 6;
  int pad = 2;
  double delta = 2.0 * rodRad / double(rodDiaCells);

  veci3 phcN;
  phcN[0] = phcN[1] = int(2.0 * cavRad / delta) + 2 * pad;
  phcN[2] = int(cavLen / delta) + 2 * pad;

  vecd3 phcL;
  phcL[0] = phcL[1] = delta * double(phcN[0]);
  phcL[2] = delta * double(phcN[2]);

  vecd3 phcO;
  phcO[0] = phcO[1] = -0.5 * phcL[0];
  phcO[2] = -0.5 * phcL[2];

  MxGrid<3> phcGrid(phcO, phcN, phcL, &myComm);
  phcGrid.print();

  Teuchos::ParameterList phcList;
  phcList.set("geo-mg : levels", 1);
  phcList.set("geo-mg : smoothers : sweeps", 5);
  phcList.set("eigensolver : output", 2);
  phcList.set("eigensolver : nev", 15);
  phcList.set("eigensolver : tol", 1.e-8);
  phcList.set("eigensolver : block size", 1);
  phcList.set("eigensolver : num blocks", 30);
  phcList.set("eigensolver : spectrum", "LM");
  phcList.set("wave operator : invert", true);
  phcList.set("wave operator : invert : tol", 1.e-8);
  //phcList.set("wave operator : invert : shift", 1000.0);
  phcList.set("wave operator : invert : max basis size", 40);

  MxEMSim<dim> phcSim;
  phcSim.setGrid(&phcGrid);
  //phcSim.setPEC(&phcCav);
  phcSim.setDielectric(&phcDiel);
  phcSim.setParameters(phcList);
  phcSim.setup();

  MxSolver<dim> * solver;
  solver = new MxSolver<dim>(&phcSim, phcList);
  solver->solve();

  delete solver;

  for (int i = 0; i < numRods; i++)
    delete rods[i];

#endif

#if 0
  double sphR = 0.37;
  int sphN = 64;
  MxEllipsoid ell(0.0, sphR);

  MxGrid<3> sphGrid(-0.5, sphN, 1.0, &myComm);
  sphGrid.print();

  MxDimMatrix<double, 3> rotSapphEps(0);
  rotSapphEps(0, 0) = 10.225;
  rotSapphEps(1, 1) = 10.225;
  rotSapphEps(2, 2) = 9.95;
  rotSapphEps(0, 1) = rotSapphEps(1, 0) = -0.825;
  rotSapphEps(0, 2) = rotSapphEps(2, 0) = -0.67360967926537398;
  rotSapphEps(1, 2) = rotSapphEps(2, 1) = 0.67360967926537398;

  MxDielectric<3> phcDiel;
  phcDiel.add(&ell, rotSapphEps);

  vecd3 ell2Loc(0); ell2Loc[0] = 0.6;
  vecd3 ell3Loc(0); ell3Loc[0] = 0.3; ell3Loc[2] = 0.3;
  MxEllipsoid ell2(ell2Loc, sphR);
  MxEllipsoid ell3(ell3Loc, sphR);

  MxShapeUnion<3> shUnion;
  shUnion.add(&ell);
  shUnion.add(&ell2);
  shUnion.add(&ell3);
  //shUnion.save(sphGrid);

  MxShapeIntersection<3> shInt;
  shInt.add(&ell);
  shInt.add(&ell2);
  shInt.add(&ell3);
  //shInt.save(sphGrid);

  MxShapeSubtract<3> shSub;
  shSub.setBaseShape(&ell);
  shSub.subtractShape(&ell2);
  shSub.subtractShape(&ell3);
  //shSub.save(sphGrid);

  MxDielectric<3> dielEll;
  MxDimMatrix<double, 3> epsEll(vecd3(10.0)); // isotropic eps = 10
  dielEll.add(&ell, epsEll);

  Teuchos::ParameterList sphList;
  sphList.set("geo-mg : levels", 1);
  sphList.set("geo-mg : smoothers : sweeps", 4);
  sphList.set("eigensolver : output", 2);
  sphList.set("eigensolver : nev", 12);
  sphList.set("eigensolver : tol", 1.e-8);
  sphList.set("eigensolver : block size", 1);
  sphList.set("eigensolver : num blocks", 30);
  sphList.set("eigensolver : spectrum", "LM");
  sphList.set("wave operator : invert", true);
  sphList.set("wave operator : invert : tol", 1.e-8);
  //sphList.set("wave operator : invert : shift", -0.1);
  sphList.set("wave operator : invert : shift", 1.0);
  sphList.set("wave operator : invert : max basis size", 40);

  MxEMSim<dim> sphSim;
  sphSim.setGrid(&sphGrid);
  //sphSim.setDielectric(&dielEll);
  sphSim.setDielectric(&phcDiel);
  //sphSim.setPEC(&sphCav);
  //sphSim.setPEC(&ell);
  sphSim.setParameters(sphList);
  sphSim.setup();

  MxSolver<dim> * solver;
  solver = new MxSolver<dim>(&sphSim, sphList);
  solver->solve();

  delete solver;

#endif


#ifdef HAVE_MPI
  MPI::Finalize();
  //MPI_Finalize();
#endif

  return 0;

}