Esempio n. 1
0
CUInt128 CKademlia::MakeCloseTarget(int *pDistance)
{
	if(!m_pKadHandler)
	{
		if(pDistance)
			*pDistance = -1;
		return 0;
	}

	CUInt128 uMyID = m_pRootZone->GetID();
	NodeMap Nodes;
	m_pRootZone->GetClosestNodes(uMyID, Nodes, Cfg()->GetInt("BucketSize"));
	if(Nodes.size() < 2)
	{
		if(pDistance)
			*pDistance = -1;
		return 0;
	}
	
	// Find Median distance difference between nodes closest to us
	vector<CUInt128> Diff;
	for(NodeMap::iterator np = Nodes.begin(), n = np++; np != Nodes.end(); n = np++)
		Diff.push_back(np->first - n->first);
	CUInt128 Sep = Median(Diff);

	// generate ID that is closer to us than the closest node by a few difference
	CUInt128 uDistance = Nodes.begin()->first;
	for(int i=0; i < 3 && uDistance > Sep; i++)
		uDistance = uDistance - Sep;
	CUInt128 uCloser = uMyID ^ uDistance;

	// count the matchign bits
	UINT uLevel=0;
	for(; uLevel < uMyID.GetBitSize(); uLevel++)
	{
		if(uCloser.GetBit(uLevel) != uMyID.GetBit(uLevel))
			break;
	}

	// add a few more matching bytes
	for(UINT i=0; i < 4 && uLevel < uMyID.GetBitSize() - 1; i++)
	{
		uCloser.SetBit(uLevel, uMyID.GetBit(uLevel));
		uLevel++;
	}

	if(pDistance)
		*pDistance = (int)uMyID.GetBitSize() - uLevel;

	// create a random ID that we are closest to
	CUInt128 uRandom(uCloser, uLevel);
	//wstring sTest = (uMyID ^ uRandom).ToBin();
	return uRandom;
}
Esempio n. 2
0
void CKadHandler::HandleNodeReq(const CVariant& NodeReq, CKadNode* pNode, CComChannel* pChannel)
{
	if(GetParent<CKademlia>()->Cfg()->GetBool("DebugRT"))
		LogLine(LOG_DEBUG, L"Recived 'Node Resuest' to %s", pNode->GetID().ToHex().c_str());

	CVariant NodeRes;

	uint32 uDesiredCount = NodeReq["RCT"];
	if(uDesiredCount == 0)
		throw CException(LOG_ERROR, L"node requested 0 nodes");

	int iMaxState = NodeReq.Get("MNC", NODE_2ND_CLASS);

	NodeMap Nodes;
	if(!NodeReq.Has("TID"))
		GetParent<CKademlia>()->Root()->GetBootstrapNodes(GetParent<CKademlia>()->Root()->GetID(), Nodes, uDesiredCount, pChannel->GetAddress().GetProtocol(), iMaxState);
	else
		GetParent<CKademlia>()->Root()->GetClosestNodes(NodeReq["TID"], Nodes, uDesiredCount, pChannel->GetAddress().GetProtocol(), iMaxState);
	
	CVariant List;
	for(NodeMap::iterator I = Nodes.begin(); I != Nodes.end(); I++)
		List.Append(I->second->Store());
	NodeRes["LIST"] = List;

	if(GetParent<CKademlia>()->Cfg()->GetBool("DebugRT"))
		LogLine(LOG_DEBUG, L"Sending 'Node Response' to %s", pNode->GetID().ToHex().c_str());
	pChannel->QueuePacket(KAD_NODE_RESPONSE, NodeRes);
}
Esempio n. 3
0
    static void prepForTree() {
#ifndef VL_LEAK_CHECKS
	s_nodes.clear();
#endif
	for (NodeMap::iterator it = s_nodes.begin(); it != s_nodes.end(); ++it) {
	    it->second &= ~FLAG_IN_TREE;
	    it->second &= ~FLAG_LINKABLE;
	}
    }
Esempio n. 4
0
void CLookupHistory::AddNodes(const NodeMap& Nodes, const CUInt128& ByID)
{
	for(NodeMap::const_iterator I = Nodes.begin(); I != Nodes.end(); I++)
	{
		LookupNodeMap::iterator J = m_Nodes.find(I->second->GetID());
		if(J == m_Nodes.end())
			J = m_Nodes.insert(LookupNodeMap::value_type(I->second->GetID(), SLookupNode())).first;
		J->second.FoundByIDs.push_back(ByID == 0 ? SELF_NODE : ByID);
	}
}
Esempio n. 5
0
 void PMap(const NodeMap& m)
 {
   // print out map
   NodeMap::const_iterator it;
   pout() << "Node map has " << m.size() << " nodes\n";
   for (it=m.begin(); it!=m.end(); it++)
   {
     pout() << "node "; PIV(it->first); pout() << ": " << it->second << "\n";
   }
 }
Esempio n. 6
0
void ScriptInterpreter::markDOMNodesForDocument(Document* doc)
{
    NodePerDocMap::iterator dictIt = domNodesPerDocument().find(doc);
    if (dictIt != domNodesPerDocument().end()) {
        NodeMap* nodeDict = dictIt->second;
        NodeMap::iterator nodeEnd = nodeDict->end();
        for (NodeMap::iterator nodeIt = nodeDict->begin(); nodeIt != nodeEnd; ++nodeIt) {
            DOMNode* node = nodeIt->second;
            // don't mark wrappers for nodes that are no longer in the
            // document - they should not be saved if the node is not
            // otherwise reachable from JS.
            if (node->impl()->inDocument() && !node->marked())
                node->mark();
        }
    }
}
Esempio n. 7
0
  // recursively delete the stmts and subtrees
  ~TreeNode()
  {
    for (StmtMap::iterator sit = stmtMap.begin(); sit != stmtMap.end(); ++sit) {
      delete sit->second;
    }
    stmtMap.clear();

    for (LoopList::iterator lit = loopList.begin(); lit != loopList.end(); ++lit) {
      delete (*lit)->node;
    }
    loopList.clear();

    for (NodeMap::iterator nit = nodeMap.begin(); nit != nodeMap.end(); ++nit) {
      delete nit->second;
    }
    nodeMap.clear();
  }
Esempio n. 8
0
    static void doneWithTree() {
	for (int backs=0; backs<2; backs++) {  // Those with backp() are probably under one leaking without
	    for (NodeMap::iterator it = s_nodes.begin(); it != s_nodes.end(); ++it) {
		if ((it->second & FLAG_ALLOCATED)
		    && !(it->second & FLAG_IN_TREE)
		    && !(it->second & FLAG_LEAKED)
		    && (it->first->backp() ? backs==1 : backs==0)) {
		    // Use only AstNode::dump instead of the virtual one, as there
		    // may be varp() and other cross links that are bad.
		    if (v3Global.opt.debugCheck()) {
			cerr<<"%Error: LeakedNode"<<(it->first->backp()?"Back: ":": ");
			((AstNode*)(it->first))->AstNode::dump(cerr);
			cerr<<endl;
			V3Error::incErrors();
		    }
		    it->second |= FLAG_LEAKED;
		}
	    }
	}
    }
Esempio n. 9
0
void PertyDuplicatePoiOp::apply(shared_ptr<OsmMap>& map)
{
  MapProjector::projectToPlanar(map);
  boost::uniform_real<> uni(0.0, 1.0);
  boost::normal_distribution<> nd;
  boost::variate_generator<boost::minstd_rand&, boost::normal_distribution<> > N(*_rng, nd);

  // make a copy since we'll be modifying the map as we go.
  NodeMap nm = map->getNodeMap();
  for (NodeMap::const_iterator it = nm.begin(); it != nm.end(); ++it)
  {
    if (uni(*_rng) < _p)
    {
      const NodePtr& n = it->second;
      int copies = round(fabs(N() * _duplicateSigma)) + 1;

      for (int i = 0; i < copies; i++)
      {
        duplicateNode(n, map);
      }
    }
  }
}
void FileProjections::readProjectionsInfo()
{
    // Prepare nodes
    NodeMap* nodeList = graph->getNodeMap();
    unsigned count = nodeList->size();

    if (!count)
        return;

    unsigned oldSize = projectionsList->size();
    bool isProjectionsWasEmpty = !oldSize;

    projectionsList->resize(count, nullptr);
    projectionsList->shrink_to_fit();

    auto oldStart = projectionsList->begin();
    auto oldEnd = projectionsList->begin() + oldSize;
    auto it = nodeList->begin();
    Projection* pr;

    ProjectionsReader reader(*this);
    std::string saveName(graphFileName);
    unsigned nameSize = saveName.size();
    bool someMissing = false, someReaded = false;

    startProcess(0u, count - 1);

    unsigned currentId;
    unsigned pos = oldSize;

    for(unsigned i = 0u; i < count; ++i, ++it)
    {
        if (isInterrupted())
        {
            projectionStatus = Status::PARTIAL;
            return;
        }

        updateProgress(i);

        currentId = it->first;
        pr = nullptr;
        // Projection exist - skip
        if (!isProjectionsWasEmpty)
        {
            auto e = std::lower_bound(oldStart, oldEnd, currentId,
                                      Projection::lessById);
            if (e != oldEnd && (*e)->getId() == currentId)
            {
                pr = *e;
            }
        }
        if (!pr)
        {
            pr = new Projection(currentId);
            (*projectionsList)[pos] = pr;
            ++pos;
        }

        ProjectionsReader::projectionFileName(saveName, nameSize, currentId);

        bool result = reader.readProjectionInfo(saveName.data(), pr);
        if (result)
        {
            someReaded = true;
        }
        else
        {
            someMissing = true;
            if (reader.getLastError() == ProjectionsReader::Error::TYPE)
            {
                lastError = Error::TYPE;
            }
        }
    }
    if (someReaded)
    {
        projectionStatus = someMissing ? Status::PARTIAL : Status::ALL;
    }
    else
    {
        projectionStatus = Status::EMPTY;
    }

    // check that list was not empty and some new projections added
    if (oldSize && oldSize != count)
    {
        auto end = projectionsList->end();
        std::sort(oldStart, end, Projection::less);
    }
    completeProcess();
}
void FileProjections::createAllProjections()
{
    if (graph->isEmpty())
    {
        return;
    }

    if(isMemoryUsed())
    {
        Projections::createAllProjections();
        return;
    }

    // Prepare nodes
    NodeMap* nodeList = graph->getNodeMap();
    unsigned count = nodeList->size();

    if (!count)
        return;

    ProjectionsWriter writer(*this);
    setWorker(&writer, true);
    startProcess(0u, count - 1);

    unsigned oldSize = projectionsList->size();
    bool isWasEmpty = !oldSize;

    projectionsList->resize(count, nullptr);
    projectionsList->shrink_to_fit();

    auto oldStart = projectionsList->begin();
    auto oldEnd = projectionsList->begin() + oldSize;
    auto it = nodeList->begin();
    Projection* pr;

    std::string saveName(graphFileName);
    unsigned nameSize = saveName.size();

    unsigned currentId;
    unsigned pos = oldSize;

    for(unsigned i = 0u; i < count; ++i, ++it)
    {
        if (isInterrupted())
        {
            projectionStatus = Status::PARTIAL;
            // if interrupted on null filled projections, shrink list
            projectionsList->resize(pos);
            break;
        }

        updateProgress(i);

        currentId = it->first;
        pr = nullptr;
        // Projection exist - skip
        if (!isWasEmpty)
        {
            auto e = std::lower_bound(oldStart, oldEnd, currentId,
                                      Projection::lessById);
            if (e != oldEnd && (*e)->getId() == currentId)
            {
                pr = *e;
                if (pr->fileExist())
                    continue;
            }
        }
        if (!pr)
        {
            pr = new Projection(currentId);
            (*projectionsList)[pos] = pr;
            ++pos;
        }
        pr->createProjection(*graph);
        if (pr->isInterrupted())
        {
            continue;
        }

        ProjectionsReader::projectionFileName(saveName, nameSize, currentId);

        bool result = writer.saveProjection(saveName.data(), pr);

        if (result)
        {
            pr->setFileExist(true);
        }
        // stay loaded last projection
        if (count - i > 1)
        {
            pr->clear();
        }
        else
        {
            loadedProjection = pr;
        }
    }

    if (!isWasEmpty)
    {
        auto end = projectionsList->end();
        std::sort(oldStart, end, Projection::less);
    }
    if (!isInterrupted())
        projectionStatus = Status::ALL;
    completeProcess();
}
Esempio n. 12
0
/*
 * DeleteCFG()
 *  Remove one CFG.
 */
void DeleteCFG(NodeMap &CFGMap)
{
    for (NodeMap::iterator I = CFGMap.begin(), E = CFGMap.end(); I != E; I++)
        delete I->first;
}
Esempio n. 13
0
static void removeWrappers(const NodeMap& wrappers)
{
    for (NodeMap::const_iterator it = wrappers.begin(); it != wrappers.end(); ++it)
        removeWrapper(it->second);
}
Esempio n. 14
0
int
main (int   argc,
      char* argv[])
{
    BoxLib::Initialize(argc,argv);

    if (argc < 2)
        print_usage(argc,argv);

    ParmParse pp;

    if (pp.contains("help"))
        print_usage(argc,argv);

    bool verbose = false;
    pp.query("verbose",verbose);

    if (verbose>1)
        AmrData::SetVerbose(true);

    std::string infile; pp.get("infile",infile);
    std::string outfile_DEF;

    std::string outType = "tec";
#ifdef USE_TEC_BIN_IO
    bool doBin = true;
    pp.query("doBin",doBin);
    outfile_DEF = infile+(doBin ? ".plt" : ".dat" );
#else
    bool doBin=false;
    outfile_DEF = infile+".dat";
#endif

    // 
    bool connect_cc = true; pp.query("connect_cc",connect_cc);

    std::string outfile(outfile_DEF); pp.query("outfile",outfile);
    DataServices::SetBatchMode();
    Amrvis::FileType fileType(Amrvis::NEWPLT);
    DataServices dataServices(infile, fileType);

    if (!dataServices.AmrDataOk())
        DataServices::Dispatch(DataServices::ExitRequest, NULL);

    AmrData& amrData = dataServices.AmrDataRef();

    const Array<std::string>& names = amrData.PlotVarNames();

    Array<int> comps;
    if (int nc = pp.countval("comps"))
    {
        comps.resize(nc);
        pp.getarr("comps",comps,0,nc);
    }
    else
    {
        int sComp = 0;
        pp.query("sComp",sComp);
        int nComp = amrData.NComp();
        pp.query("nComp",nComp);
        BL_ASSERT(sComp+nComp <= amrData.NComp());
        comps.resize(nComp);
        for (int i=0; i<nComp; ++i)
            comps[i] = sComp + i;
    }

    Box subbox;
    if (int nx=pp.countval("box"))
    {
        Array<int> barr;
        pp.getarr("box",barr,0,nx);
        int d=BL_SPACEDIM;
        BL_ASSERT(barr.size()==2*d);
        subbox=Box(IntVect(D_DECL(barr[0],barr[1],barr[2])),
                   IntVect(D_DECL(barr[d],barr[d+1],barr[d+2]))) & amrData.ProbDomain()[0];

    } else {

        subbox = amrData.ProbDomain()[0];
    }

    int finestLevel = amrData.FinestLevel(); pp.query("finestLevel",finestLevel);
    int Nlev = finestLevel + 1;
    Array<BoxArray> gridArray(Nlev);
    Array<Box> subboxArray(Nlev);

    int nGrowPer = 0; pp.query("nGrowPer",nGrowPer);
    PArray<Geometry> geom(Nlev);

    Array<Real> LO(BL_SPACEDIM,0);
    Array<Real> HI(BL_SPACEDIM,1);
    RealBox rb(LO.dataPtr(),HI.dataPtr());
    int coordSys = 0;
    Array<int> isPer(BL_SPACEDIM,0);

    for (int lev=0; lev<Nlev; ++lev)
    {
        subboxArray[lev]
            = (lev==0 ? subbox
               : Box(subboxArray[lev-1]).refine(amrData.RefRatio()[lev-1]));

        geom.set(lev,new Geometry(amrData.ProbDomain()[lev],&rb,coordSys,const_cast<int*>(isPer.dataPtr())));

        if (nGrowPer>0 && lev==0)
        {
            for (int i=0; i<BL_SPACEDIM; ++i)
            {
                if (geom[lev].isPeriodic(i))
                {
                    if (subboxArray[lev].smallEnd()[i] == amrData.ProbDomain()[lev].smallEnd()[i])
                        subboxArray[lev].growLo(i,nGrowPer);
                    if (subboxArray[lev].bigEnd()[i] == amrData.ProbDomain()[lev].bigEnd()[i])
                        subboxArray[lev].growHi(i,nGrowPer);
                }
            }
        }

        gridArray[lev] = BoxLib::intersect(amrData.boxArray(lev), subboxArray[lev]);

        if (nGrowPer>0 && geom[lev].isAnyPeriodic() && gridArray[lev].size()>0)
        {
	  //const Box& probDomain = amrData.ProbDomain()[lev];
            const BoxArray& ba = amrData.boxArray(lev);
            BoxList bladd;
            Array<IntVect> shifts;
            for (int i=0; i<ba.size(); ++i)
            {
                geom[lev].periodicShift(subboxArray[lev],ba[i],shifts);
                for (int j=0; j<shifts.size(); ++j)
                {
                    Box ovlp = Box(ba[i]).shift(shifts[j]) & subboxArray[lev];
                    if (ovlp.ok())
                        bladd.push_back(ovlp);
                }
            }
            bladd.simplify();
            BoxList blnew(gridArray[lev]);
            blnew.join(bladd);
            gridArray[lev] = BoxArray(blnew);
        }

        if (!gridArray[lev].size())
        {
            Nlev = lev;
            finestLevel = Nlev-1;
            gridArray.resize(Nlev);
            subboxArray.resize(Nlev);
        }
    }

    const int nGrow = 1;
    typedef BaseFab<Node> NodeFab;
    typedef FabArray<NodeFab> MultiNodeFab; 
    PArray<MultiNodeFab> nodes(Nlev,PArrayManage);

    std::cerr << "Before nodes allocated" << endl;
    for (int lev=0; lev<Nlev; ++lev)
        nodes.set(lev,new MultiNodeFab(gridArray[lev],1,nGrow));
    std::cerr << "After nodes allocated" << endl;

    int cnt = 0;
    typedef std::map<Node,int> NodeMap;
    NodeMap nodeMap;
    for (int lev=0; lev<Nlev; ++lev)
    {
        for (MFIter fai(nodes[lev]); fai.isValid(); ++fai)
        {
            NodeFab& ifab = nodes[lev][fai];
            const Box& box = ifab.box() & subboxArray[lev];
            for (IntVect iv=box.smallEnd(); iv<=box.bigEnd(); box.next(iv))
                ifab(iv,0) = Node(iv,lev,fai.index(),Node::VALID);
        }
            
        if (lev != 0)
        {
            const int ref = amrData.RefRatio()[lev-1];
            const Box& rangeBox = Box(IntVect::TheZeroVector(),
                                     (ref-1)*IntVect::TheUnitVector());

            BoxArray bndryCells = GetBndryCells(nodes[lev].boxArray(),ref,geom[lev]);

            for (MFIter fai(nodes[lev]); fai.isValid(); ++fai)
            {
                const Box& box = BoxLib::grow(fai.validbox(),ref) & subboxArray[lev];
                NodeFab& ifab = nodes[lev][fai];
                std::vector< std::pair<int,Box> > isects = bndryCells.intersections(box);
                for (int i = 0; i < isects.size(); i++)
                {
                    Box co = isects[i].second & fai.validbox();
                    if (co.ok())
                        std::cout << "BAD ISECTS: " << co << std::endl;

                    const Box& dstBox = isects[i].second;
                    const Box& srcBox = BoxLib::coarsen(dstBox,ref);

                    NodeFab dst(dstBox,1);
                    for (IntVect iv(srcBox.smallEnd());
                         iv<=srcBox.bigEnd();
                         srcBox.next(iv))
                    {
                        const IntVect& baseIV = ref*iv;
                        for (IntVect ivt(rangeBox.smallEnd());ivt<=rangeBox.bigEnd();rangeBox.next(ivt))
                            dst(baseIV + ivt,0) = Node(iv,lev-1,-1,Node::VALID);
                    }
                    const Box& ovlp = dstBox & ifab.box();

                    Box mo = ovlp & fai.validbox();
                    if (mo.ok())
                    {
                        std::cout << "BAD OVERLAP: " << mo << std::endl;
                        std::cout << "         vb: " << fai.validbox() << std::endl;
                    }
                    if (ovlp.ok())
                        ifab.copy(dst,ovlp,0,ovlp,0,1);
                }
            }
        }

        // Block out cells covered by finer grid
        if (lev < finestLevel)
        {
            const BoxArray coarsenedFineBoxes =
                BoxArray(gridArray[lev+1]).coarsen(amrData.RefRatio()[lev]);
                
            for (MFIter fai(nodes[lev]); fai.isValid(); ++fai)
            {
                NodeFab& ifab = nodes[lev][fai];
                const Box& box = ifab.box();
                std::vector< std::pair<int,Box> > isects = coarsenedFineBoxes.intersections(box);
                for (int i = 0; i < isects.size(); i++)
                {
                    const Box& ovlp = isects[i].second;
                    for (IntVect iv=ovlp.smallEnd(); iv<=ovlp.bigEnd(); ovlp.next(iv))
                        ifab(iv,0) = Node(iv,lev,fai.index(),Node::COVERED);
                }
            }
        }

        // Add the unique nodes from this level to the list
        for (MFIter fai(nodes[lev]); fai.isValid(); ++fai)
        {
            NodeFab& ifab = nodes[lev][fai];
            const Box& box = fai.validbox() & subboxArray[lev];
            for (IntVect iv(box.smallEnd()); iv<=box.bigEnd(); box.next(iv))
            {
                if (ifab(iv,0).type == Node::VALID)
                {
                    if (ifab(iv,0).level != lev) 
                        std::cout << "bad level: " << ifab(iv,0) << std::endl;
                    nodeMap[ifab(iv,0)] = cnt++;
                }
            }
        }
    }

    std::cerr << "After nodeMap built, size=" << nodeMap.size() << endl;

    typedef std::set<Element> EltSet;
    EltSet elements;
    for (int lev=0; lev<Nlev; ++lev)
    {
        for (MFIter fai(nodes[lev]); fai.isValid(); ++fai)
        {
            NodeFab& ifab = nodes[lev][fai];                        
            Box box = ifab.box() & subboxArray[lev];

            for (int dir=0; dir<BL_SPACEDIM; ++dir)
                box.growHi(dir,-1);

            for (IntVect iv(box.smallEnd()); iv<=box.bigEnd(); box.next(iv))
            {
#if (BL_SPACEDIM == 2)
                const Node& n1 = ifab(iv,0);
                const Node& n2 = ifab(IntVect(iv).shift(BoxLib::BASISV(0)),0);
                const Node& n3 = ifab(IntVect(iv).shift(IntVect::TheUnitVector()),0);
                const Node& n4 = ifab(IntVect(iv).shift(BoxLib::BASISV(1)),0);
                if (n1.type==Node::VALID && n2.type==Node::VALID &&
                    n3.type==Node::VALID && n4.type==Node::VALID )
                    elements.insert(Element(n1,n2,n3,n4));
#else
                const IntVect& ivu = IntVect(iv).shift(BoxLib::BASISV(2));
                const Node& n1 = ifab(iv ,0);
                const Node& n2 = ifab(IntVect(iv ).shift(BoxLib::BASISV(0)),0);
                const Node& n3 = ifab(IntVect(iv ).shift(BoxLib::BASISV(0)).shift(BoxLib::BASISV(1)),0);
                const Node& n4 = ifab(IntVect(iv ).shift(BoxLib::BASISV(1)),0);
                const Node& n5 = ifab(ivu,0);
                const Node& n6 = ifab(IntVect(ivu).shift(BoxLib::BASISV(0)),0);
                const Node& n7 = ifab(IntVect(ivu).shift(BoxLib::BASISV(0)).shift(BoxLib::BASISV(1)),0);
                const Node& n8 = ifab(IntVect(ivu).shift(BoxLib::BASISV(1)),0);
                if (n1.type==Node::VALID && n2.type==Node::VALID &&
                    n3.type==Node::VALID && n4.type==Node::VALID &&
                    n5.type==Node::VALID && n6.type==Node::VALID &&
                    n7.type==Node::VALID && n8.type==Node::VALID )
                    elements.insert(Element(n1,n2,n3,n4,n5,n6,n7,n8));
#endif
            }
        }
    }

    int nElts = (connect_cc ? elements.size() : nodeMap.size());
    std::cerr << "Before connData allocated " << elements.size() << " elements"  << endl;
    Array<int> connData(MYLEN*nElts);
    std::cerr << "After connData allocated " << elements.size() << " elements" << endl;

    if (connect_cc) {
        cnt = 0;
        for (EltSet::const_iterator it = elements.begin(); it!=elements.end(); ++it)
        {
            for (int j=0; j<MYLEN; ++j)
            {
                const NodeMap::const_iterator noit = nodeMap.find(*((*it).n[j]));
                if (noit == nodeMap.end())
                {
                    std::cout << "Node not found in node map" << std::endl;
                    std::cout << *((*it).n[j]) << std::endl;
                }
                else
                {
                    connData[cnt++] = noit->second+1;
                }
            }
        }
    } else {
        cnt = 1;
        for (int i=0; i<nElts; ++i) {
            for (int j=0; j<MYLEN; ++j) {
                connData[i*MYLEN+j] = cnt++;
            }
        }
    }

    std::cerr << "Final elements built" << endl;

    // Invert the map
    std::vector<Node> nodeVect(nodeMap.size());
    for (NodeMap::const_iterator it=nodeMap.begin(); it!=nodeMap.end(); ++it)
    {
        if (it->second>=nodeVect.size() || it->second<0)
            std::cout << "Bad id: " << it->second << "  bad node: " << it->first << std::endl;
        BL_ASSERT(it->second>=0);
        BL_ASSERT(it->second<nodeVect.size());
        nodeVect[it->second] = (*it).first;
    }
    std::cerr << "Final nodeVect built (" << nodeVect.size() << " nodes)" << endl;
		
    nodeMap.clear();
    elements.clear();
    nodes.clear();

    std::cerr << "Temp nodes, elements cleared" << endl;

    PArray<MultiFab> fileData(Nlev);
    int ng = nGrowPer;
    for (int lev=0; lev<Nlev; ++lev)
    {
        if (lev!=0)
            ng *= amrData.RefRatio()[lev-1];
        const BoxArray& ba = gridArray[lev];
        fileData.set(lev,new MultiFab(ba,comps.size(),0));
        fileData[lev].setVal(1.e30);
        std::cerr << "My data set alloc'd at lev=" << lev << endl;

        MultiFab pData, pDataNG;
        if (ng>0 && geom[lev].isAnyPeriodic())
        {
            const Box& pd = amrData.ProbDomain()[lev];
            //const BoxArray& vba = amrData.boxArray(lev);
            Box shrunkenDomain = pd;
            for (int i=0; i<BL_SPACEDIM; ++i)
                if (geom[lev].isPeriodic(i))
                    shrunkenDomain.grow(i,-ng);

            const BoxArray edgeVBoxes = BoxLib::boxComplement(pd,shrunkenDomain);
            pData.define(edgeVBoxes,1,ng,Fab_allocate);
            pDataNG.define(BoxArray(edgeVBoxes).grow(ng),1,0,Fab_allocate);
        }

        for (int i=0; i<comps.size(); ++i)
        {
            BoxArray tmpBA = BoxLib::intersect(fileData[lev].boxArray(),amrData.ProbDomain()[lev]);
            MultiFab tmpMF(tmpBA,1,0);
            tmpMF.setVal(2.e30);
            amrData.FillVar(tmpMF,lev,names[comps[i]],0);
            fileData[lev].copy(tmpMF,0,i,1);
            if (ng>0 && geom[lev].isAnyPeriodic())
            {
                pData.setVal(3.e30);
                pDataNG.copy(tmpMF);
                for (MFIter mfi(pData); mfi.isValid(); ++mfi)
                    pData[mfi].copy(pDataNG[mfi]);
                amrData.FillVar(pData,lev,names[comps[i]],0);
                geom[lev].FillPeriodicBoundary(pData);
                for (MFIter mfi(pData); mfi.isValid(); ++mfi)
                    pDataNG[mfi].copy(pData[mfi]);
                fileData[lev].copy(pDataNG,0,i,1);
            }            
        }

        if (fileData[lev].max(0) > 1.e29)
        {
            std::cerr << "Bad mf data" << std::endl;
            VisMF::Write(fileData[lev],"out.mfab");
            BoxLib::Abort();
        }
    }
    std::cerr << "File data loaded" << endl;

    int nNodesFINAL = (connect_cc  ?  nodeVect.size() : nElts*MYLEN );
    int nCompsFINAL = BL_SPACEDIM+comps.size();
    FABdata tmpData(nNodesFINAL,nCompsFINAL);
    int tmpDatLen = nCompsFINAL*nNodesFINAL;
    std::cerr << "Final node data allocated (size=" << tmpDatLen << ")" << endl;

    //const Array<Array<Real> >& dxLevel = amrData.DxLevel();  // Do not trust dx from file...compute our own
    Array<Array<Real> > dxLevel(Nlev);
    for (int i=0; i<Nlev; ++i)
    {
        dxLevel[i].resize(BL_SPACEDIM);
        for (int j=0; j<BL_SPACEDIM; ++j)
            dxLevel[i][j] = amrData.ProbSize()[j]/amrData.ProbDomain()[i].length(j);
    }
    const Array<Real>& plo = amrData.ProbLo();

    // Handy structures for loading data in usual fab ordering (transpose of mef/flt ordering)
#define BIN_POINT
#undef BIN_POINT
#ifdef BIN_POINT
    Real* data = tmpData.dataPtr();
#else /* BLOCK ordering */
    Array<Real*> fdat(comps.size()+BL_SPACEDIM);
    for (int i=0; i<fdat.size(); ++i)
        fdat[i] = tmpData.dataPtr(i);
#endif

    cnt = 0;
    int Nnodes = nodeVect.size();
    int jGridPrev = 0;
    int levPrev = -1;
    for (int i=0; i<Nnodes; ++i)
    {
        const Node& node = nodeVect[i];

        const Array<Real>& dx = dxLevel[node.level];
        const IntVect& iv = node.iv;

        const BoxArray& grids = fileData[node.level].boxArray();
        int jGrid = node.grid;
        if (jGrid<0)
        {
            bool found_it = false;
            
            // Try same grid as last time, otherwise search list
            if (node.level==levPrev && grids[jGridPrev].contains(iv))
            {
                found_it = true;
                jGrid = jGridPrev;
            }
            for (int j=0; j<grids.size() && !found_it; ++j)
            {
                if (grids[j].contains(iv))
                {
                    found_it = true;
                    jGrid = j;
                }
            }
            BL_ASSERT(found_it);
        }
	// Remember these for next time
	levPrev = node.level;
	jGridPrev = jGrid;

	Array<IntVect> ivt;
        if (connect_cc) {
            ivt.resize(1,iv);
        } else {
            ivt.resize(D_PICK(1,4,8),iv);
            ivt[1] += BoxLib::BASISV(0);
            ivt[2] = ivt[1] + BoxLib::BASISV(1);
            ivt[3] += BoxLib::BASISV(1);
#if BLSPACEDIM==3
            for (int n=0; n<4; ++n) {
                ivt[4+n] = iv[n] + BoxLib::BASISV(2);
            }
#endif
        }

	for (int j=0; j<ivt.size(); ++j) {

            Real offset = (connect_cc ? 0.5 : 0);

#ifdef BIN_POINT
	  for (int dir=0; dir<BL_SPACEDIM; ++dir)
            data[cnt++] = plo[dir] + (ivt[j][dir] + offset) * dx[dir];
#else /* BLOCK ordering */
	  for (int dir=0; dir<BL_SPACEDIM; ++dir)
            fdat[dir][cnt] = plo[dir] + (ivt[j][dir] + offset) * dx[dir];
#endif /* BIN_POINT */


#ifdef BIN_POINT
	  for (int n=0; n<comps.size(); ++n) {
            data[cnt++] = fileData[node.level][jGrid](iv,n);
          }
#else /* BLOCK ordering */
	  for (int n=0; n<comps.size(); ++n) {
              fdat[n+BL_SPACEDIM][cnt] = fileData[node.level][jGrid](iv,n);
          }
	  cnt++;
#endif /* BIN_POINT */
	}
    }

    //Collate(tmpData,connData,MYLEN);

    //
    // Write output
    //
    const int nState = BL_SPACEDIM + comps.size();
    std::string vars = D_TERM("X"," Y"," Z");
    for (int j=0; j<comps.size(); ++j)
        vars += " " + amrData.PlotVarNames()[comps[j]];

    if (outType == "tec")
    {

#ifdef BIN_POINT
        string block_or_point = "FEPOINT";
#else /* BLOCK ordering */
        string block_or_point = "FEBLOCK";
#endif


        if (doBin)
        {
#ifdef USE_TEC_BIN_IO
            INTEGER4 Debug = 0;
            INTEGER4 VIsDouble = 1;
            INTEGER4 EltID = D_PICK(0,1,3);
            TECINI((char*)"Pltfile data", (char*)vars.c_str(), (char*)outfile.c_str(), (char*)".", &Debug, &VIsDouble);
            INTEGER4 nPts = nNodesFINAL;
            TECZNE((char*)infile.c_str(), &nPts, &nElts, &EltID, (char*)block_or_point.c_str(), NULL);
            TECDAT(&tmpDatLen,tmpData.fab.dataPtr(),&VIsDouble);
            TECNOD(connData.dataPtr());
            TECEND();
#else
            BoxLib::Abort("Need to recompile with USE_TEC_BIN_IO defined");
#endif
        }
        else
        {
            std::ofstream osf(outfile.c_str(),std::ios::out);
            osf << D_TERM("VARIABLES= \"X\"", " \"Y\"", " \"Z\"");
            for (int j=0; j<comps.size(); ++j)
                osf << " \""  << amrData.PlotVarNames()[comps[j]] << "\"";
            char buf[100];
            sprintf(buf,"%g",amrData.Time());
            osf << endl << "ZONE T=\"" << infile << " time = " << buf
                << "\", N=" << nNodesFINAL << ", E=" << nElts << ", F=" << "FEPOINT" << " ET="
                //<< "\", N=" << nPts << ", E=" << nElts << ", F=" << block_or_point << " ET="
                << D_PICK("POINT","QUADRILATERAL","BRICK") << endl;
            
            for (int i=0; i<nNodesFINAL; ++i)
            {
                for (int j=0; j<nState; ++j)
                    osf << tmpData.dataPtr(j)[i] << " ";
                osf << endl;
            }
            for (int i=0; i<nElts; ++i)
            {
                for (int j=0; j<MYLEN; ++j)
                    osf << connData[i*MYLEN+j] << " ";
                osf << endl;
            }
            osf << endl;
            osf.close();
        }
    }
    else
    {
        std::ofstream ofs;
        std::ostream* os =
            (outfile=="-" ? (std::ostream*)(&std::cout) : (std::ostream*)(&ofs) );
        if (outfile!="-")
            ofs.open(outfile.c_str(),std::ios::out|std::ios::trunc|std::ios::binary);
        (*os) << infile << " time = " << amrData.Time() << endl;
        (*os) << vars << endl;
        (*os) << nElts << " " << MYLEN << endl;
        tmpData.fab.writeOn(*os);
        (*os).write((char*)connData.dataPtr(),sizeof(int)*connData.size());
        if (outfile!="-")
            ofs.close();
    }

    BoxLib::Finalize();
    return 0;
}