void MultiDLA::density(double density, double& denAero, double& porosity) const { if (m_finished) { // calc double volume = 0.0; int32_t sx = m_fld->size().coord(0); int32_t sy = m_fld->size().coord(1); int32_t sz = m_fld->size().coord(2); MCoord::setDefDims(3); MCoord sc; for (size_t i = 0; i < 3; ++i) { sc.setCoord(i, m_fld->size().coord(i)); } CellsField* cf = new CellsField(sc, MCoord(), 2 * m_fld->radius()); for (int32_t ix = 0; ix < sx; ++ix) { for (int32_t iy = 0; iy < sy; ++iy) { for (int32_t iz = 0; iz < sz; ++iz) { if (m_fld->element(MCoord(ix, iy, iz)) == OCUPIED_CELL) { MCoord currCoord(ix, iy, iz); cf->setElement(currCoord); volume += vAdd(cf, currCoord); } } } } delete cf; double aeroVolume = volume / (sx * sy * sz); porosity = 1.0 - aeroVolume; denAero = density * aeroVolume; } }
MCoordVec* MultiDLA::createDirections() { size_t dims = MCoord::defDims(); MCoordVec* result = new MCoordVec(2 * dims); for (size_t i = 0; i < dims; ++i) { result[0][i] = MCoord(); result[0][i + dims] = MCoord(); result->at(i).setCoord(i, -1); result->at(i + dims).setCoord(i, 1); } return result; }
Coord ScrollListShape::AddSat(Coord a,Coord b) { MCoord ret=MCoord(a)+b; if( ret>MaxCoord ) return MaxCoord; return (Coord)ret; }
void MultiDLA::generate(const Sizes& sizes, const RunParams& params) { double r = 0.5385; MCoord::setDefDims(3); MCoord sz; double scale = params.cellSize;// * std::sqrt(1 - 0.4 * 0.4); sz.setCoord(0, Coordinate(sizes.x * 2.0 * r / scale)); sz.setCoord(1, Coordinate(sizes.y * 2.0 * r / scale)); sz.setCoord(2, Coordinate(sizes.z * 2.0 * r / scale)); std::vector<double> composition; double porosity = 0.0; composition.push_back(params.porosity); porosity += params.porosity; if (porosity <= 0 || porosity >= 1) { std::cout << "Wrong porosity!" << std::endl; return; } m_finished = false; // clean up if (m_fld) { delete m_fld; } #ifndef _WIN32 uint32_t t0 = uint32_t(clock()); #endif m_fld = new CellsField(sz, MCoord(), params.cellSize); std::cout << "DLA" << std::endl; cMultiDLA(m_fld, params.porosity, params.init, params.step, params.hit); std::cout << "Aggregation" << std::endl; clusterAggregation(m_fld, params.cluster); for (FieldElement i = 1; i < composition.size(); ++i) { std::cout << "Change labels " << composition[i] << std::endl; changeLabels(m_fld, composition[i], i); } #ifndef _WIN32 std::cout << "Прошло: " << double(clock() - t0) / CLOCKS_PER_SEC << " сек." << std::endl; #endif if (m_cancel) { QMetaObject::invokeMethod(m_mainwindow, "setProgress", Qt::QueuedConnection, Q_ARG(int, 0)); std::cout << "Canceled!" << std::endl; m_cancel = false; return; } //PrintField(fld); // save field to file //fld->tofile(fileName.c_str()); m_finished = true; QMetaObject::invokeMethod(m_mainwindow, "restructGL", Qt::QueuedConnection); std::cout << "Done" << std::endl; }
double MultiDLA::surfaceArea(double density, uint32_t steps) const { double result = 0.0; if (m_finished) { #ifndef _WIN32 uint32_t t0 = uint32_t(clock()); #endif // calc double volume = 0.0; double square = 0.0; int32_t sx = m_fld->size().coord(0); int32_t sy = m_fld->size().coord(1); int32_t sz = m_fld->size().coord(2); MCoord::setDefDims(3); MCoord sc; for (size_t i = 0; i < 3; ++i) { sc.setCoord(i, m_fld->size().coord(i)); } CellsField* cf = new CellsField(sc, MCoord(), 2 * m_fld->radius()); double cellRadius = cf->radius(); for (int32_t ix = 0; ix < sx; ++ix) { for (int32_t iy = 0; iy < sy; ++iy) { for (int32_t iz = 0; iz < sz; ++iz) { if (m_fld->element(MCoord(ix, iy, iz)) == OCUPIED_CELL) { MCoord currCoord(ix, iy, iz); cf->setElement(currCoord); volume += vAdd(cf, currCoord) * cube(cf->side()); square += SfromR(cellRadius); } } } } delete cf; // -> Monte-Carlo uint32_t positive = m_fld->monteCarlo(steps); result = 1000000 * square * positive / (steps * density * volume); #ifndef _WIN32 std::cout << "Прошло: " << double(clock() - t0) / CLOCKS_PER_SEC << " сек." << std::endl; #endif } return result; }
void MultiDLA::cMultiDLA(CellsField* fld, double targetPorosity, uint32_t initN, uint32_t step, uint32_t hitCnt) { fld->clear(); double currVol = 0.0; double needVol = fld->cellsCnt() * (1 - targetPorosity); bool needHit = (hitCnt != 1); size_t dimensions = MCoord::defDims(); MCoordVec* mapNeigh = createNeighborsMap(dimensions); MCoordVec* mapSteps = createStepMap(dimensions, step); uint32_t currCnt = 0; MCoord currCoord; while (currCnt != initN) { currCoord = freeRandomPntInField(fld); fld->setElement(currCoord); currVol += vAdd(fld, currCoord); ++currCnt; } CellsField* hitField; if (needHit) { hitField = new CellsField(fld->size(), MCoord(), fld->radius() * 2); } while (currVol < needVol) { currCoord = freeRandomPntInField(fld); if (needHit) { hitField->clear(); } while (true) { if (!fld->isSet(currCoord) && cntNeighbors(fld, mapNeigh, currCoord) != 0) { FieldElement newHitCnt = 1; if (needHit) { newHitCnt = hitField->elementVal(currCoord) + 1; hitField->setElementVal(currCoord, newHitCnt); } if (newHitCnt >= hitCnt) { fld->setElement(currCoord); currVol += vAdd(fld, currCoord); ++currCnt; break; } } MCoord tmpCoord = makeStep(currCoord, mapSteps); tmpCoord = toroidizeCoords(tmpCoord, fld->size()); while (fld->isSet(tmpCoord)) { tmpCoord = makeStep(currCoord, mapSteps); tmpCoord = toroidizeCoords(tmpCoord, fld->size()); } currCoord = tmpCoord; } } delete mapNeigh; mapNeigh = nullptr; delete mapSteps; mapSteps = nullptr; if (needHit) { delete hitField; hitField = nullptr; } }
MCoord DrawLab::toMilli(Coord x) const { return MCoord( IntLShift<MCoord>(x,MPoint::Precision-cfg.zoom_deg)-MPoint::Half ); }