Beispiel #1
0
vector<int> maOrderingFast(const vector<SplitEdge> &g, int s)
{
	int addOne = cG(s, g) == 0 ? 1 : 0;
	int maxNodeInd = 0;
	for (unsigned i = 0; i < g.size(); i++)
		maxNodeInd = max(g[i].end0, max(g[i].end1, maxNodeInd));
	maxNodeInd++;
	vector<bool> usedNodes(maxNodeInd, false);
	for (unsigned i = 0; i < g.size(); i++)
	{
		usedNodes[g[i].end0] = true;
		usedNodes[g[i].end1] = true;
	}
	int numNodes = 0;
	for (unsigned i = 0; i < usedNodes.size(); i++)
		numNodes += usedNodes[i];
	vector<int> ordering;
	vector<bool> inOrdering;
	for (int i = 0; i < maxNodeInd; i++)
		inOrdering.push_back(false);
	ordering.push_back(s);
	inOrdering[s] = true;

	while (ordering.size() != numNodes + addOne)
	{
		vector<int> dels(maxNodeInd, 0);
		for (unsigned i = 0; i < g.size(); i++)
		{
			if (!inOrdering[g[i].end0] && inOrdering[g[i].end1])
				dels[g[i].end0] += g[i].weight;
			if (!inOrdering[g[i].end1] && inOrdering[g[i].end0])
				dels[g[i].end1] += g[i].weight;
		}
		for (int i = 0; i < maxNodeInd; i++)
		{
			if (!usedNodes[i])
				dels[i] = -1;
		}
		int loc = -1;
		int maxDel = -1;
		for (unsigned i = 0; i < dels.size(); i++)
		{
			if (dels[i] > maxDel)
			{
				maxDel = dels[i];
				loc = i;
			}
		}
		ordering.push_back(loc);
		inOrdering[loc] = true;
	}
	//verifyMAOrdering(g, ordering);
	return ordering;
}
Beispiel #2
0
vector<int> maOrdering(const vector<SplitEdge> &g, int s)
{
	int addOne = 0;
	if (cG(s, g) == 0)
		addOne = 1;
	int numNodes = getNumUsedNodes(g);
	int maxNodeInd = getMaxNodeInd(g);
	vector<bool> usedNodes = getUsedNodes(g);
	vector<int> ordering;
	vector<vector<pair<int, int>>> adjacency;
	adjacency.reserve(maxNodeInd);
	for (int i = 0; i < maxNodeInd; i++)
		adjacency.push_back(vector<pair<int, int>>());
	for (unsigned i = 0; i < g.size(); i++)
	{
		adjacency[g[i].end0].push_back(pair<int, int>(g[i].end1, g[i].weight));
		adjacency[g[i].end1].push_back(pair<int, int>(g[i].end0, g[i].weight));
	}
	//for each vertex in left, sum the weights of all the edges which end in ordering.
	//take the greatest of these, move from left to ordering; repeat while 
	//left isn't empty.
	vector<bool> inOrdering(maxNodeInd, false);
	ordering.push_back(s);
	inOrdering[s] = true;
	vector<int> dels(maxNodeInd, 0);
	while (ordering.size() != numNodes+addOne)
	{
		function<int(vector<pair<int,int>>)> f = [&inOrdering](vector<pair<int,int>> e)
		{
			int acc = 0;
			for (unsigned i = 0; i < e.size(); i++)
			{
				if (inOrdering[e[i].first])
					acc += e[i].second;
			}
			return acc;
		};
		transform(adjacency.begin(), adjacency.end(), dels.begin(), f);
		for (int i = 0; i < maxNodeInd; i++)
			dels[i] = inOrdering[i] || !usedNodes[i] ? -1 : dels[i];
		vector<int>::iterator maxLoc = max_element(dels.begin(), dels.end());
		int loc = std::distance(dels.begin(), maxLoc);
		ordering.push_back(loc);
		inOrdering[loc] = true;
	}
	//verifyMAOrdering(g, ordering);
	return ordering;
}
Beispiel #3
0
vector<SplitEdge> eulerCSplit(const vector<SplitEdge> &g, vector<SplitEdge> &B, int s, unsigned int k, vector<vector<int>> X, historyIndex &h)
{
	vector<SplitEdge> GHat = g;
	GHat = fixEquation4(GHat, s);
	if (cG(s, g) % 2 != 0)
	{
		cout << "ERROR: odd CG(s)" << endl;
		throw logic_error("");
	}
	vector<vector<int>> X1 = X;

	while (X1.size() >= 3)
	{
		X1 = sortByCG(GHat, s, X1);
		vector<int> cgsX1;
		for (unsigned i = 0; i < X1.size(); i++)
		{
			cgsX1.push_back(cG(s, X1[i], GHat));
		}
		int del1P = 0;
		int del2P = 0;
		if ((cG(s, X1[0], GHat) - cG(s, X1[1], GHat)) >= cG(s, X1[X1.size() - 1], GHat))
			del1P = cG(s, X1[X1.size() - 1], GHat);
		else
		{
			del2P = (int)ceil(double(cG(s, X1[X1.size() - 1], GHat) - cG(s, X1[0], GHat) + cG(s, X1[1], GHat)) * .5);
			del1P = cG(s, X1[X1.size() - 1], GHat) - del2P;
		}
		GHat = removeZeroWeighted(GHat);
		GHat = pairing(X1[0], X1[X1.size() - 1], del1P, B, GHat, s, h);
		GHat = removeZeroWeighted(GHat);
		GHat = pairing(X1[1], X1[X1.size() - 1], del2P, B, GHat, s, h);
		bool erase1 = cG(s, X1[0], GHat) == 0;
		bool erase2 = cG(s, X1[1], GHat) == 0;
		bool eraseLast = cG(s, X1.back(), GHat) == 0;
		vector<vector<int>> X11;
		if (!erase1)
			X11.push_back(X1[0]);
		if (!erase2)
			X11.push_back(X1[1]);
		for (unsigned i = 2; i < X1.size() - 1; i++)
			X11.push_back(X1[i]);
		if (!eraseLast)
			X11.push_back(X1.back());
		X1 = X11;
		if (X1.size() == 1)
		{
			cout << "ERROR: X1.size() == 1" << endl;
			throw logic_error("");
		}
	}
	int del12 = 0;
	if (X1.size() != 0)
	{
		if (cG(s, X1[0], GHat) != cG(s, X1[1], GHat))
		{
			cout << "eulerCSplit sanity check failure. Make sure cG(X1) != cG(X2)" << endl;
			throw logic_error("");
		}
		del12 = cG(s, X1[0], GHat);
		GHat = removeZeroWeighted(GHat);
		GHat = pairing(X1[0], X1[1], del12, B, GHat, s, h);
	}
	return GHat;
}
Beispiel #4
0
vector<SplitEdge> pairing(const vector<int> &Xi,const vector<int> &Xj, int delij, vector<SplitEdge> &B, const vector<SplitEdge> &g, int s, historyIndex &h)
{
	vector<SplitEdge> GHat = g;
	while (delij > 0)
	{
		int u = 0;
		int v = 0;
		vector<int> gamXi = setIntersection(Xi, neighbors(GHat, s));
		vector<int> gamXj = setIntersection(Xj, neighbors(GHat, s));
		if (gamXi.size() == 0 || gamXj.size() == 0)
		{
			cout << "Detected 0, dumping status" << endl;
			cout << "GHat:" << endl;
			output(GHat);
			cout << "B:" << endl;
			output(B);
			cout << "S: " << s << endl;
			cout << "delij: " << delij << endl;
			cout << "Xi:" << endl;
			output(Xi);
			cout << "neighbors of s in GHat:" << endl;
			output(neighbors(GHat, s));
			cout << "Xj:" << endl;
			output(Xj);
			cout << "gamXi:" << endl;
			output(gamXi);
			cout << "gamXj:" << endl;
			output(gamXj);
		}
		u = gamXi[0];
		v = gamXj[0];
		if (u == v)
		{
			cout << "U == V. Quitting" << endl;
			throw logic_error("");
		}
		int delta = min(min(cG(s, u, GHat), cG(s, v, GHat)),delij);
		GHat = split(GHat, u, v, s, delta, h);
		//Add weight delta to (u,v) in B
		bool found = false;
		for (unsigned i = 0; i < B.size(); i++)
		{
			if (connects(B[i], u, v))
			{
				B[i].weight += delta;
				found = true;
				break;
			}
		}
		if (!found)
		{
			for (unsigned i = 0; i < GHat.size(); i++)
			{
				if (connects(GHat[i], u, v))
				{
					SplitEdge e(GHat[i].end0, GHat[i].end1, delta, GHat[i].orig0, GHat[i].orig1);
					B.push_back(e);
					found = true;
					break;
				}
			}
		}
		if (!found)
		{
			SplitEdge e(u, v, delta, u, v);
			B.push_back(e);
		}
		delij -= delta;
	}
	return GHat;
}
Beispiel #5
0
huReturn hookUp(const vector<SplitEdge> &g, int s, vector<SplitEdge> &bIn, int k, vector<vector<int>> &Y, historyIndex &h)
{
	if (cG(s, g) != 0)
	{
		cout << "cG(s) problem in hookup" << endl;
		throw logic_error("");
	}
	vector<SplitEdge> H = g;
	vector<SplitEdge> G1 = g; 
	vector<SplitEdge> B = bIn;
	vector<SplitEdge> B1;
	vector<vector<int>> XS;
	int maxNodeInd = getMaxNodeInd(G1);
	for (int i = 0; i < maxNodeInd; i++)
		XS.push_back(vector<int>());
	for (int i = 0; i < maxNodeInd; i++)
		XS[i].push_back(i);
	//cout << "About to enter while loop" << endl;
	while (getNumUsedNodes(H) >= 4)
	{
		vector<int> ma = maOrderingHeap(H, s);
		int v = ma[ma.size() - 2];
		int w = ma[ma.size() - 1];
		if (v == s || w == s)
			throw logic_error("SET WAS V - S, S FOUND");
		vector<int> X1;
		H = combineVertices(H, v, w);
		H = compress(H);
		XS[v] = setUnion(XS[v], XS[w]);
		if (XS[w].size() == 0)
		{
			cout << "Error: W, " << w << " was merged twice. Quitting" << endl;
			throw logic_error("");
		}
		XS[w] = vector<int>();
		if (cG(v, H) < k)
		{
			int numToGet = (int)ceil(.5*(double(k) - double(cG(G1, XS[v]))));
			vector<SplitEdge> GX = inducedSubgraph(G1, XS[v]);
			vector<SplitEdge> delB;
			int added = 0;
			for (unsigned i = 0; i < GX.size(); i++)
			{
				SplitEdge e = SplitEdge(GX[i].end0, GX[i].end1, GX[i].weight, GX[i].orig0, GX[i].orig1);
				if (isMem(e, B))
				{
					int bW = B[indexOfEdge(B, e.end0, e.end1)].weight;
					if (bW < e.weight)
						e.weight = bW;
					if (e.weight > (numToGet - added))
					{
						e.weight = numToGet - added;
					}
					added += e.weight;
					delB.push_back(e);
				}
				if (added == numToGet)
					break;
			}
			if (added != numToGet)
			{
				cout << "Error: GX did not contain " << numToGet << " entries in B. Quitting." << endl;
				throw logic_error("");
			}
			if (!isSubset(delB, B))
			{
				cout << "ERROR: delB is not a subset of B." << endl;
				cout << "B:" << endl;
				output(B);
				cout << "delB:" << endl;
				output(delB);
				cout << "This was the GX to choose from:" << endl;
				output(GX);
				cout << "V: " << v << endl;
				cout << "W: " << w << endl;
				cout << "S: " << s << endl;
				throw logic_error("");
			}
			B = setRemove(delB, B);
			B = removeZeroWeighted(B);
			B1 = setUnion(delB, B1);
			H = removeZeroWeighted(H);
			G1 = hookUpHelper(s, G1, delB, h);
			G1 = removeZeroWeighted(G1);
			H = removeZeroWeighted(H);
			bool addedFromXSinH = false;
			numToGet *= 2;
			for (unsigned i = 0; i < H.size(); i++)
			{
				SplitEdge tester = SplitEdge(s, v, 0, 0, 0);
				if (equals(tester, H[i]))
				{
					//cout << "Increasing weight in hookUp in H between " << H[i].end0 << " and " << H[i].end1 << "from " << H[i].weight << " to " << H[i].weight + numToGet << endl;
					H[i].weight += numToGet;
					addedFromXSinH = true;
					break;
				}
			}
			if (!addedFromXSinH && numToGet != 0)
			{
				//cout << "Creating edge in hookUp in H between " << s << " and " << v << " with weight " << numToGet << endl;
				SplitEdge e(s, v, numToGet, s, v);
				H.push_back(e);
			}
			vector<vector<int>> newY;
			for (unsigned i = 0; i < Y.size(); i++)
			{
				if (!isProperSubset(Y[i], XS[v]))
					newY.push_back(Y[i]);
			}
			bool foundX1inY = false;
			for (unsigned i = 0; i < newY.size(); i++)
			{
				if (setsEqual(newY[i], XS[v]))
					foundX1inY = true;
			}
			if (!foundX1inY)
				newY.push_back(XS[v]);
			Y = newY;
		}
	}
	huReturn ret;
	ret.BP = B1;
	ret.G1 = G1;
	ret.Y = Y;
	return ret;
}
Beispiel #6
0
vector<int> maOrderingHeap(const vector<SplitEdge> &g, int s)
{
	vector<pair<int, int>> heap; //fst is key/incidence, snd is node ind (matched in MACompare)
	int addOne = cG(s, g) == 0 ? 1 : 0;
	int maxNodeInd = 0;
	for (unsigned i = 0; i < g.size(); i++)
		maxNodeInd = max(g[i].end0, max(g[i].end1, maxNodeInd));
	maxNodeInd++;
	vector<bool> usedNodes(maxNodeInd, false);
	for (unsigned i = 0; i < g.size(); i++)
	{
		usedNodes[g[i].end0] = true;
		usedNodes[g[i].end1] = true;
	}
	int numNodes = 0;
	for (unsigned i = 0; i < usedNodes.size(); i++)
		numNodes += usedNodes[i];
	vector<int> ordering;
	vector<bool> inOrdering(maxNodeInd, false);
	ordering.push_back(s);
	inOrdering[s] = true;

	vector<vector<pair<int, int>>> adjacency;
	adjacency.reserve(maxNodeInd);
	for (int i = 0; i < maxNodeInd; i++)
		adjacency.push_back(vector<pair<int, int>>());
	for (unsigned i = 0; i < g.size(); i++)
	{
		adjacency[g[i].end0].push_back(pair<int, int>(g[i].end1, g[i].weight));
		adjacency[g[i].end1].push_back(pair<int, int>(g[i].end0, g[i].weight));
	}

	heap.reserve(maxNodeInd);
	for (int i = 0; i < maxNodeInd; i++)
		heap.push_back(pair<int, int>(0, i));

	for (unsigned i = 0; i < g.size(); i++)
	{
		if (g[i].end0 == s)
			heap[g[i].end1].first += g[i].weight;
		else if (g[i].end1 == s)
			heap[g[i].end0].first += g[i].weight;
	}
	vector<int>realValue;
	for (unsigned i = 0; i < heap.size(); i++)
		realValue.push_back(heap[i].first);
	make_heap(heap.begin(), heap.end(), MACompare());
	while (ordering.size() != numNodes + addOne)
	{
		pair<int, int> next = heap.front();
		pop_heap(heap.begin(), heap.end());
		heap.pop_back();

		while (realValue[next.second] != next.first || inOrdering[next.second] || !usedNodes[next.second]) //i.e. this value was changed.
		{
			next = heap.front();
			pop_heap(heap.begin(), heap.end());
			heap.pop_back();
		}

		ordering.push_back(next.second);
		inOrdering[next.second] = true;

		for (unsigned i = 0; i < adjacency[next.second].size(); i++)
		{
			int n = adjacency[next.second][i].first;
			if (!inOrdering[n])
			{
				realValue[n] += adjacency[next.second][i].second;
				pair<int, int> p(realValue[n], n);
				heap.push_back(p);
				push_heap(heap.begin(), heap.end());
			}
		}
	}
	//verifyMAOrdering(g, ordering);
	return ordering;
}
void EinsplineSetBuilder::ReadBands_ESHDF(int spin, EinsplineSetExtended<complex<double > >* orbitalSet)
{
  update_token(__FILE__,__LINE__,"ReadBands_ESHDF:complex");
  ReportEngine PRE("EinsplineSetBuilder","ReadBands_ESHDF(EinsplineSetExtended<complex<double > >*");
  Timer c_prep, c_unpack,c_fft, c_phase, c_spline, c_newphase, c_h5, c_init;
  double t_prep=0.0, t_unpack=0.0, t_fft=0.0, t_phase=0.0, t_spline=0.0, t_newphase=0.0, t_h5=0.0, t_init=0.0;
  c_prep.restart();
  bool root = myComm->rank()==0;
  vector<BandInfo>& SortBands(*FullBands[spin]);
  // bcast other stuff
  myComm->bcast (NumDistinctOrbitals);
  myComm->bcast (NumValenceOrbs);
  myComm->bcast (NumCoreOrbs);
  int N = NumDistinctOrbitals;
  orbitalSet->kPoints.resize(N);
  orbitalSet->MakeTwoCopies.resize(N);
  orbitalSet->StorageValueVector.resize(N);
  orbitalSet->BlendValueVector.resize(N);
  orbitalSet->StorageLaplVector.resize(N);
  orbitalSet->BlendLaplVector.resize(N);
  orbitalSet->StorageGradVector.resize(N);
  orbitalSet->BlendGradVector.resize(N);
  orbitalSet->StorageHessVector.resize(N);
  orbitalSet->StorageGradHessVector.resize(N);
  orbitalSet->phase.resize(N);
  orbitalSet->eikr.resize(N);
  orbitalSet->NumValenceOrbs = NumValenceOrbs;
  orbitalSet->NumCoreOrbs    = NumCoreOrbs;
  // Read in k-points
  int numOrbs = orbitalSet->getOrbitalSetSize();
  int num = 0;
  if (root)
  {
    for (int iorb=0; iorb<N; iorb++)
    {
      int ti = SortBands[iorb].TwistIndex;
      PosType twist  = TwistAngles[ti];
      orbitalSet->kPoints[iorb] = orbitalSet->PrimLattice.k_cart(twist);
      orbitalSet->MakeTwoCopies[iorb] =
        (num < (numOrbs-1)) && SortBands[iorb].MakeTwoCopies;
      num += orbitalSet->MakeTwoCopies[iorb] ? 2 : 1;
    }
  }
  myComm->bcast(orbitalSet->kPoints);
  myComm->bcast(orbitalSet->MakeTwoCopies);
  // First, check to see if we have already read this in
  H5OrbSet set(H5FileName, spin, N);
  ///check mesh or ready for FFT grid
  bool havePsig=ReadGvectors_ESHDF();
  app_log() << "MeshSize = (" << MeshSize[0] << ", " << MeshSize[1] << ", " << MeshSize[2] << ")\n";
  int nx, ny, nz, bi, ti;
  nx=MeshSize[0];
  ny=MeshSize[1];
  nz=MeshSize[2];
  Ugrid x_grid, y_grid, z_grid;
  BCtype_z xBC, yBC, zBC;
  xBC.lCode = PERIODIC;
  xBC.rCode = PERIODIC;
  yBC.lCode = PERIODIC;
  yBC.rCode = PERIODIC;
  zBC.lCode = PERIODIC;
  zBC.rCode = PERIODIC;
  x_grid.start = 0.0;
  x_grid.end = 1.0;
  x_grid.num = nx;
  y_grid.start = 0.0;
  y_grid.end = 1.0;
  y_grid.num = ny;
  z_grid.start = 0.0;
  z_grid.end = 1.0;
  z_grid.num = nz;
  // Create the multiUBspline object
  orbitalSet->MultiSpline =
    create_multi_UBspline_3d_z (x_grid, y_grid, z_grid, xBC, yBC, zBC, NumValenceOrbs);
  //////////////////////////////////////
  // Create the MuffinTin APW splines //
  //////////////////////////////////////
  orbitalSet->MuffinTins.resize(NumMuffinTins);
  for (int tin=0; tin<NumMuffinTins; tin++)
  {
    orbitalSet->MuffinTins[tin].Atom = tin;
    orbitalSet->MuffinTins[tin].set_center (MT_centers[tin]);
    orbitalSet->MuffinTins[tin].set_lattice(Lattice);
    orbitalSet->MuffinTins[tin].init_APW
    (MT_APW_rgrids[tin], MT_APW_lmax[tin],
     NumValenceOrbs);
  }
  for (int iat=0; iat<AtomicOrbitals.size(); iat++)
  {
    AtomicOrbitals[iat].set_num_bands(NumValenceOrbs);
    AtomicOrbitals[iat].allocate();
  }
  int isComplex=1;
  if (root)
  {
    HDFAttribIO<int> h_isComplex(isComplex);
    h_isComplex.read(H5FileID, "/electrons/psi_r_is_complex");
  }
  myComm->bcast(isComplex);
  if (!isComplex)
  {
    APP_ABORT("Expected complex orbitals in ES-HDF file, but found real ones.");
  }
  EinsplineSetBuilder::RotateBands_ESHDF(spin, orbitalSet);
  bool isCore = bcastSortBands(spin,N,root);
  if(isCore)
  {
    APP_ABORT("Core states not supported by ES-HDF yet.");
  }
  t_prep += c_prep.elapsed();
  /** For valence orbitals,
   * - extended orbitals either in G or in R
   * - localized orbitals
   */
  //this can potentially break
  Array<ComplexType,3> splineData(nx,ny,nz);
  if(havePsig)//perform FFT using FFTW
  {
    c_init.restart();
    Array<ComplexType,3> FFTbox;
    FFTbox.resize(MeshSize[0], MeshSize[1], MeshSize[2]);
    fftw_plan FFTplan = fftw_plan_dft_3d
                        (MeshSize[0], MeshSize[1], MeshSize[2],
                         reinterpret_cast<fftw_complex*>(FFTbox.data()),
                         reinterpret_cast<fftw_complex*>(FFTbox.data()),
                         +1, FFTW_ESTIMATE);
    Vector<complex<double> > cG(MaxNumGvecs);
    //this will be parallelized with OpenMP
    for(int iorb=0,ival=0; iorb<N; ++iorb, ++ival)
    {
      //Vector<complex<double> > cG;
      int ncg=0;
      int ti=SortBands[iorb].TwistIndex;
      c_h5.restart();
      if(root)
      {
        ostringstream path;
        path << "/electrons/kpoint_" << SortBands[iorb].TwistIndex
             << "/spin_" << spin << "/state_" << SortBands[iorb].BandIndex << "/psi_g";
        HDFAttribIO<Vector<complex<double> > >  h_cG(cG);
        h_cG.read (H5FileID, path.str().c_str());
        ncg=cG.size();
      }
      myComm->bcast(ncg);
      if(ncg != Gvecs[0].size())
      {
        APP_ABORT("Failed : ncg != Gvecs[0].size()");
      }
      if(!root)
        cG.resize(ncg);
      myComm->bcast(cG);
      t_h5 += c_h5.elapsed();
      c_unpack.restart();
      unpack4fftw(cG,Gvecs[0],MeshSize,FFTbox);
      t_unpack+= c_unpack.elapsed();
      c_fft.restart();
      fftw_execute (FFTplan);
      t_fft+= c_fft.elapsed();
      c_phase.restart();
      fix_phase_rotate_c2c(FFTbox,splineData,TwistAngles[ti]);
      t_phase+= c_phase.elapsed();
      c_spline.restart();
      set_multi_UBspline_3d_z(orbitalSet->MultiSpline, ival, splineData.data());
      t_spline+= c_spline.elapsed();
    }
    fftw_destroy_plan(FFTplan);
    t_init+=c_init.elapsed();
  }
  else
  {
    //this will be parallelized with OpenMP
    for(int iorb=0,ival=0; iorb<N; ++iorb, ++ival)
    {
      //check dimension
      if(root)
      {
        ostringstream path;
        path << "/electrons/kpoint_" << SortBands[iorb].TwistIndex
             << "/spin_" << spin << "/state_" << SortBands[iorb].BandIndex << "/psi_r";
        HDFAttribIO<Array<complex<double>,3> >  h_splineData(splineData);
        h_splineData.read(H5FileID, path.str().c_str());
      }
      myComm->bcast(splineData);
      set_multi_UBspline_3d_z(orbitalSet->MultiSpline, ival, splineData.data());
    }
    //return true;
  }
  app_log() << "    READBANDS::PREP   = " << t_prep << endl;
  app_log() << "    READBANDS::H5     = " << t_h5 << endl;
  app_log() << "    READBANDS::UNPACK = " << t_unpack << endl;
  app_log() << "    READBANDS::FFT    = " << t_fft << endl;
  app_log() << "    READBANDS::PHASE  = " << t_phase << endl;
  app_log() << "    READBANDS::SPLINE = " << t_spline << endl;
  app_log() << "    READBANDS::SUM    = " << t_init << endl;
  //now localized orbitals
  for(int iorb=0,ival=0; iorb<N; ++iorb, ++ival)
  {
    PosType twist=TwistAngles[SortBands[iorb].TwistIndex];
    // Read atomic orbital information
    for (int iat=0; iat<AtomicOrbitals.size(); iat++)
    {
      app_log() << "Reading orbital " << iat << " for band " << ival << endl;
      AtomicOrbital<complex<double> > &orb = AtomicOrbitals[iat];
      Array<complex<double>,2> radial_spline(orb.SplinePoints,orb.Numlm),
            poly_coefs(orb.PolyOrder+1,orb.Numlm);
      if (root)
      {
        int ti   = SortBands[iorb].TwistIndex;
        int bi   = SortBands[iorb].BandIndex;
        ostringstream path;
        path << "/electrons/kpoint_" << ti << "/spin_" << spin << "/state_" << bi << "/";
        AtomicOrbital<complex<double> > &orb = AtomicOrbitals[iat];
        ostringstream spline_path, poly_path;
        spline_path << path.str() << "radial_spline_" << iat;
        poly_path   << path.str() << "poly_coefs_"    << iat;
        HDFAttribIO<Array<complex<double>,2> > h_radial_spline(radial_spline);
        HDFAttribIO<Array<complex<double>,2> > h_poly_coefs(poly_coefs);
        h_radial_spline.read(H5FileID, spline_path.str().c_str());
        h_poly_coefs.read   (H5FileID, poly_path.str().c_str());
        // cerr << "radial_spline.size = (" << radial_spline.size(0)
        // 	 << ", " << radial_spline.size(1) << ")\n";
        // cerr << "poly_coefs.size = (" << poly_coefs.size(0)
        // 	 << ", " << poly_coefs.size(1) << ")\n";
      }
      myComm->bcast(radial_spline);
      myComm->bcast(poly_coefs);
      AtomicOrbitals[iat].set_band (ival, radial_spline, poly_coefs, twist);
    }
    // Now read muffin tin data
    for (int tin=0; tin<NumMuffinTins; tin++)
    {
      // app_log() << "Reading data for muffin tin " << tin << endl;
      PosType twist, k;
      int lmax = MT_APW_lmax[tin];
      int numYlm = (lmax+1)*(lmax+1);
      Array<complex<double>,2>
      u_lm_r(numYlm, MT_APW_num_radial_points[tin]);
      Array<complex<double>,1> du_lm_dr (numYlm);
      if (root)
      {
        int ti   = SortBands[iorb].TwistIndex;
        int bi   = SortBands[iorb].BandIndex;
        twist = TwistAngles[ti];
        k = orbitalSet->PrimLattice.k_cart(twist);
        string uName  = MuffinTinPath (ti, bi,tin) + "u_lm_r";
        string duName = MuffinTinPath (ti, bi,tin) + "du_lm_dr";
        HDFAttribIO<Array<complex<double>,2> > h_u_lm_r(u_lm_r);
        HDFAttribIO<Array<complex<double>,1> > h_du_lm_dr(du_lm_dr);
        h_u_lm_r.read(H5FileID, uName.c_str());
        h_du_lm_dr.read(H5FileID, duName.c_str());
      }
      myComm->bcast(u_lm_r);
      myComm->bcast(du_lm_dr);
      myComm->bcast(k);
      double Z = (double)IonTypes(tin);
      OrbitalSet->MuffinTins[tin].set_APW (ival, k, u_lm_r, du_lm_dr, Z);
    }
  }
  orbitalSet->AtomicOrbitals = AtomicOrbitals;
  for (int i=0; i<orbitalSet->AtomicOrbitals.size(); i++)
    orbitalSet->AtomicOrbitals[i].registerTimers();
  //ExtendedMap_z[set] = orbitalSet->MultiSpline;
}