예제 #1
0
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;
    }
}
예제 #2
0
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;
}
예제 #3
0
Coord ScrollListShape::AddSat(Coord a,Coord b)
 {
  MCoord ret=MCoord(a)+b;

  if( ret>MaxCoord ) return MaxCoord;

  return (Coord)ret;
 }
예제 #4
0
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;
}
예제 #5
0
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;
}
예제 #6
0
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;
    }
}
예제 #7
0
MCoord DrawLab::toMilli(Coord x) const
 {
  return MCoord( IntLShift<MCoord>(x,MPoint::Precision-cfg.zoom_deg)-MPoint::Half );
 }