// Searchs all neighbors of a crystal with nontrivial energy deposit until all // neighbors are accounted for or have negligible energy deposition vector<pair<int, double> > DFS(pair<int, double> start, double energyThresh, vector<pair<int, double> > shower, double map[]) { shower.push_back(start); for (int x=-1; x<2; x++) { for (int y=-1; y<2; y++) { int ngbrID = CoordtoID(IDtoX(start.first)+x, IDtoY(start.first)+y); double ngbrEn = map[ngbrID]; pair<int, double> ngbr(ngbrID, ngbrEn); if (ngbrEn>energyThresh) { vector<int> showerID; //no method for searching pairs for (int f=0; f<shower.size(); f++) {showerID.push_back((shower[f]).first);} if (std::find(showerID.begin(), showerID.end(), ngbrID)!=showerID.end()) {continue;} // if it has enough energy and has not been counted else {shower = DFS(ngbr, energyThresh, shower, map);} } } } //put crystals in correct order to make other methods simpler std::sort(shower.begin(), shower.end()); return shower; }
void contourFromScratch(Grid* &cGrid, shared_ptr<Var> &a, double d) { double val[listVertex.size()]; // 00. construct values at vertex; not cell dependent for (auto i = 0; i < listVertex.size(); ++i) val[i] = listVertex[i]->evalPhi(a); // 01. check near vertices if contour appears for (auto ia = 0; ia < listVertex.size(); ++ia) { if (otherVertex[ia] >= 0) continue; // already assigned auto va = listVertex[ia]; for (auto di = 1; di <= 3; ++di) { if (di == 0) continue; // no such direction auto vb = va->ngbr(di); if (vb == nullptr) continue; auto ib = (*vb)->id; auto dp = d; if (abs(val[ia] - dp) < 1e-15) dp = d - 1e-14; if (abs(val[ib] - dp) < 1e-15) dp = d - 1e-14; if ((val[ia] - dp)*(val[ib] - dp) >= 0) continue; // create a new point along xia - xib if yet not assigned. if (otherVertex[ia] < 0) { auto y = (dp - val[ia])/(val[ib] - val[ia]); auto dr = *listVertex[ib] - *listVertex[ia]; auto x = *listVertex[ia] + y*dr; auto i0a = searchVertexbyCoords(x, ia); if (i0a >= 0 && i0a < listVertex.size() && otherVertex[i0a] < 0) { cGrid->addVertex(x); auto i1a = cGrid->listVertex.size()-1; // assign this node to a; cGrid->otherVertex[i1a] = i0a; otherVertex[i0a] = i1a; } } } } if (cGrid->listVertex.size() == 0) return; cout << " Vertex count: " << cGrid->listVertex.size() << " " ; // initial point to start tracing interface ! and ends here; auto i1a = 0; auto i0a = cGrid->otherVertex[i1a]; if (i0a < 0 || i0a > listVertex.size()) { cout << " Vertex cannot be placed on the grid" << endl; exit(1); } ofstream ot; ot.open("log"+std::to_string(filecnt)+".dat"); // now I have the vertices; auto v0 = listVertex[i0a]; int_8 i1b; shared_ptr<Vertex> *vn; // Calculate gradient first; int di; Vec3 gradv; auto i1ref = i1a; auto icnt = 0; vector<bool> color(listVertex.size(), false); while (icnt < listVertex.size()) { ++icnt; vector<pair<int, double> > pp; for (auto di = -3; di <= 3; di++) { if (di == 0) continue; vn = v0->ngbr(di); if (vn == nullptr) continue; if (color[(*vn)->id]) continue; pp.push_back(std::make_pair<int, double>(int(di), abs(val[(*vn)->id] - d))); gradv[abs(di)-1] = (val[(*vn)->id]-val[i0a])/((**vn)[abs(di)-1]-(*v0)[abs(di)-1]) ; } if (pp.size() == 0) break; // nothing to pursue; std::sort(pp.begin(), pp.end(), [](const std::pair<int,double> &left, const std::pair<int,double> &right) { return left.second < right.second; }); vn = nullptr; for (auto ii = pp.begin(); ii !=pp.end(); ++ii) { if (ii->first == 1 && gradv[1] <= 0) continue; if (ii->first == -1 && gradv[1] >= 0) continue; if (ii->first == 2 && gradv[0] >= 0) continue; if (ii->first == -2 && gradv[0] <= 0) continue; vn = v0->ngbr(ii->first); break; } if (vn == nullptr) { cout << endl << "Couldn't get the next vertex" << endl; exit(1); } ot << i0a << " " << (*vn)->id << endl; i0a = (*vn)->id; v0 = (*vn); color[i0a] = true; if (abs(val[i0a]) < 1e-5 && abs(val[i0a] - 1.0) < 1e-5) { cout << "trace is not successful! stopping"<< endl; cGrid->writeVTK("lag"); exit(1); } if (otherVertex[i0a] < 0) continue; cGrid->addCell({i1a, otherVertex[i0a]}); if (otherVertex[i0a] == i1ref) break; i1a = otherVertex[i0a]; } cout <<" Cell count: " << cGrid->listCell.size() <<endl; if ((*(cGrid->listCell.rbegin()))->node[1] != (*(cGrid->listCell.begin()))->node[0]) { cout << " curve is not closed" << endl; cGrid->listVar.clear(); writeVTK("euler"); cGrid->writeVTK("lag"); exit(1); } if (icnt >= listVertex.size()) { cout << "Trace is not successful! stopping " << endl; cGrid->listVar.clear(); writeVTK("euler"); cGrid->writeVTK("lag"); exit(1); } ot.close(); auto nv2 = cGrid->listVertex.size(); auto nc2 = cGrid->listVertex.size(); for (auto v : cGrid->listVar) { if (v->loc == 1) v->data.resize(cGrid->listVertex.size()); else if (v->loc == 0) v->data.resize(cGrid->listCell.size()); } cGrid->cleanGrid(); // if (nv2 != cGrid->listVertex.size()) { updateOtherVertex(cGrid); // // for (auto i1 = 0; i1 < cGrid->otherVertex.size(); ++i1) { // // if (i1 != cGrid->listVertex[i1]->id) { // // cout << " Complaint; ids have problems" << i1; // // cout << " " << cGrid->listVertex[i1]->id << endl; // // exit(1); // // } // // auto i0 = cGrid->otherVertex[i1]; // // auto is = searchVertexbyCoords(*cGrid->listVertex[i1], i0); // // otherVertex[i0] = i1; // // } // } return; }