Ejemplo n.º 1
0
Matrix_t *MatInverse(const Matrix_t *mat)
{
   PTR tmp = NULL;      // workspace
   Matrix_t *dest;

   if (!MatIsValid(mat)) {
      return NULL;
   }
   if (mat->Nor != mat->Noc) {
      MTX_ERROR1("%E",MTX_ERR_NOTSQUARE);
      return NULL;
   }
   dest = MatId(mat->Field,mat->Nor);
   if (dest == NULL) {
      return NULL;
   }

   // Copy matrix into workspace
   tmp = FfAlloc(mat->Nor);
   if (tmp == NULL) {
      return NULL;
   }
   memcpy(tmp,mat->Data,FfCurrentRowSize * mat->Nor);

   // Inversion
   if (zmatinv(tmp,dest->Data) != 0) {
      MatFree(dest);
      return NULL;
   }
   return dest;
}
Ejemplo n.º 2
0
Unstructured* Unstructured::getConnectivityMesh() const {
    Unstructured* res = new Unstructured;
    res->coords() = coords().cloneElems();
    Element::Group<const ElemR> elems = this->elems();
    elems.removeMatId(MatId(0));
    Graph::Vertices<ElemR, CoordR3> graphLayer;
    graphLayer.init(elems);
    std::vector<std::vector<const ElemR*>> comps =
        graphLayer.getConnectedComponents();
    for (std::size_t c = 0; c < comps.size(); c++) {
        std::stringstream layerName;
        layerName << "Component " << c+1;
        Layer::Layer* newLayer =
            res->layers().addId(new Layer::Layer(layerName.str()))(0);
        std::vector<ElemR*> newElemsLayer;
        newElemsLayer.resize(comps[c].size());
        for (std::size_t e = 0; e < comps[c].size(); e++) {
            newElemsLayer[e] = comps[c][e]->cloneTo<ElemR>();
            newElemsLayer[e]->setLayer(newLayer);
        }
        res->elems().add(newElemsLayer);
    }
    res->reassignPointers(res->coords());
    res->reassignPointers(res->layers());
    return res;
}
Ejemplo n.º 3
0
MatId Base::getMatId  () const {
    if (mat_ == NULL) {
        return MatId(0);
    }
    return mat_->getId();
}
Ejemplo n.º 4
0
vector<vector<Geometry::ElemId>> Volume::getPartitionsIds(
        const size_t nDivisions,
        const vector<pair<Geometry::ElemId,int>> idWgt,
        const Math::Real* taskPower) const {
    // Metis v5 manual:
    // [...] take as input the element-node array of the mesh and
    // compute a k-way partitioning for both its elements and its nodes
    // idWgt contains id and weight pairs.
    vector<vector<Geometry::ElemId>> res;
    res.resize(nDivisions, vector<Geometry::ElemId>());
    // Accounts for the one partition case.
    if (nDivisions == 1) {
        Geometry::ConstElemRGroup physVol = elems();
        physVol.removeMatId(MatId(0));
        const size_t nK = physVol.sizeOf<Geometry::VolR>();
        res[0].resize(nK, Geometry::ElemId(0));
        for (size_t i = 0; i < nK; i++) {
            res[0][i] = (elems())(i)->getId();
        }
        return res;
    }
#ifdef MESH_ALLOW_PARTITIONING
    // Prepares mesh info.
    cout << " - Preparing mesh info... " << flush;
    idx_t ne = elems().sizeOf<Geometry::VolR>();
    idx_t *eptr, *eind;
    eptr = new idx_t[ne+1];
    eind = new idx_t[ne*4];
    size_t counter = 0;
    eptr[0] = counter;
    for (idx_t i = 0; i < ne; i++) {
        const Geometry::VolR* vol = elem_.tet[i];
        for (size_t j = 0; j < vol->numberOfVertices(); j++) {
            eind[counter++] = vol->getVertex(j)->id - 1;
        }
        eptr[i+1] = counter;
    }
    cout << "OK" << endl;
    // Relabels ids, needed by quadratic or linearized meshes.
    cout << " - Relabeling... " << flush;
    DynMatrix<Math::Int> id(ne*4,3);
    for (Math::Int i = 0; i < ne*4; i++) {
        id(i,0) = i;
        id(i,1) = eind[i];
        id(i,2) = 0;
    }
    id.sortRows_omp(1,1);
    Math::Int label = 0;
    for (Math::Int i = 1; i < ne*4; i++) {
        if (id(i,1) == id(i-1,1)) {
            id(i,2) = label;
        } else {
            id(i,2) = ++label;
        }
    }
    id.sortRows_omp(0,0);
    for (Math::Int i = 0; i < ne*4; i++) {
        eind[i] = id(i,2);
    }
    idx_t nn = label+1; // Number of vertices.
    cout << "OK" << endl;
    // Copies weights.
    cout << " - Copying weights... " << flush;
    idx_t *vwgt;
    if (idWgt.size() == 0) {
        vwgt = NULL;
    } else {
        vwgt = new idx_t[ne];
        for (Math::Int e = 0; e < ne; e++) {
            vwgt[e] = idWgt[e].second;
        }
    }
    idx_t *vsize = NULL;
    idx_t nparts = nDivisions;
    idx_t objval;
    idx_t *epart;
    epart = new idx_t[ne];
    idx_t *npart;
    npart = new idx_t[nn];
    cout << "OK" << endl;
    // Computes task computational powers.
    real_t *tpwgts = NULL;
    if (taskPower != NULL) {
        tpwgts = new real_t[nDivisions];
        real_t sum = 0.0;
        for (size_t i = 0; i < nDivisions; i++) {
            tpwgts[i] = taskPower[i];
            sum += tpwgts[i];
        }
        assert(std::abs(sum) - 1.0e-16 < 1.0);
    }
    // METIS options.
    cout << " - Setting Options... " << flush;
    idx_t options[METIS_NOPTIONS];
    Math::Int status;
    status = METIS_SetDefaultOptions(options);
    options[METIS_OPTION_PTYPE] = METIS_PTYPE_KWAY;
    options[METIS_OPTION_OBJTYPE] = METIS_OBJTYPE_CUT;
    options[METIS_OPTION_SEED] = (idx_t) 0;
    //	options[METIS_OPTION_OBJTYPE] = METIS_OBJTYPE_VOL;
    // c numbering. Starts from 0.
    options[METIS_OPTION_NUMBERING] = 0;
    cout << "OK" << endl;
    // Calls METIS partition function for meshes.
    idx_t ncommon = 3; // Number of common vertices per element.
    cout << " - Calling Part Mesh Dual... " << flush;
    status = METIS_PartMeshDual(
            &ne, &nn, eptr, eind, vwgt, vsize, &ncommon, &nparts,
            tpwgts, options, &objval, epart, npart);
    if (status != METIS_OK) {
        throw Error("METIS_PartMeshDual fn failed with error: " + status);
    }
    cout << "OK" << endl;
    // Converts result.
    for (size_t i = 0; i < nDivisions; i++) {
        res[i].reserve(ne);
    }
    for (Math::Int i = 0; i < ne; i++) {
        size_t id = elem_.tet[i]->getId();
        res[epart[i]].push_back(id);
    }
    // Frees memory.
    delete vwgt;
    delete epart;
    delete npart;
    delete eptr;
    delete eind;
    // Returns result.
    return res;
#else
    throw logic_error("Mesh partitioning is not allowed.");
#endif
}