コード例 #1
0
    grid::grid(unsigned int idp,int leftp,int topp,unsigned int hcellsp,unsigned int vcellsp,unsigned int cellwidthp,unsigned int cellheightp,unsigned thresholdp,double speed_modifierp):
        id(idp), left(leftp), top(topp), hcells(hcellsp), vcells(vcellsp), cellwidth(cellwidthp), cellheight(cellheightp), threshold(thresholdp), speed_modifier(speed_modifierp), nodearray()
    {
        gridstructarray[id] = this;
        gridstructarray[id]->nodearray.reserve(hcells*vcells);
        for (unsigned int i = 0; i < hcells*vcells; i++)
        {
            node nnode(floor(i / vcells),i % vcells,0,0,0,1);
            gridstructarray[id]->nodearray.push_back(nnode);
        }

        grid *gr = gridstructarray[id];

        for (unsigned int i = 0; i < hcells; i++){
            for (unsigned int c = 0; c < vcells; c++){
            if (i>0){
                gr->nodearray[i*vcells+c].neighbor_nodes.push_back(&gr->nodearray[(i-1)*vcells+c]); //left
                if (c>0)
                    gr->nodearray[i*vcells+c].neighbor_nodes.push_back(&gr->nodearray[(i-1)*vcells+c-1]); //top-left
                if (c<vcells-1)
                    gr->nodearray[i*vcells+c].neighbor_nodes.push_back(&gr->nodearray[(i-1)*vcells+c+1]); //bottom-left
            }
            if (c>0)
                gr->nodearray[i*vcells+c].neighbor_nodes.push_back(&gr->nodearray[i*vcells+c-1]); //top
            if (i<hcells-1){
                gr->nodearray[i*vcells+c].neighbor_nodes.push_back(&gr->nodearray[(i+1)*vcells+c]); //right
                if (c>0)
                    gr->nodearray[i*vcells+c].neighbor_nodes.push_back(&gr->nodearray[(i+1)*vcells+c-1]); //top-right
                if (c<vcells-1)
                    gr->nodearray[i*vcells+c].neighbor_nodes.push_back(&gr->nodearray[(i+1)*vcells+c+1]); //bottom-bottom
            }
            if (c<vcells-1)
                gr->nodearray[i*vcells+c].neighbor_nodes.push_back(&gr->nodearray[i*vcells+c+1]); //bottom

            }
        }

        if (enigma::grid_idmax < id+1)
          enigma::grid_idmax = id+1;
    }
コード例 #2
0
void UnstructuredBlock< NDIM >::build_faces_from_cells() {
    // pointers.
    int *pcltpn, *pclnds, *pclfcs, *pfctpn, *pfcnds, *pfccls;
    int *pifctpn, *pjfctpn, *pifcnds, *pjfcnds;
    int *pndfcs;
    // buffers.
    int *ndnfc, *ndfcs, *map, *map2;
    // scalars.
    int tpnicl, ndmfc, cond;
    // iterator.
    int icl, ifc, jfc, inf, jnf, ind, nd1, ifl;
    int it;

    const index_type mface = calc_max_nface(cltpn());
    index_type computed_nface = -1;

    // create temporary tables.
    LookupTable<index_type, MAX_CLNFC+1> tclfcs(0, ncell());
    LookupTable<index_type,           0> tfctpn(0, mface);
    LookupTable<index_type, MAX_FCNND+1> tfcnds(0, mface);
    LookupTable<index_type,     FCNCL  > tfccls(0, mface);
    tclfcs.fill(-1); tfcnds.fill(-1); tfccls.fill(-1);
    index_type * lclfcs = reinterpret_cast<index_type *>(tclfcs.row(0));
    index_type * lfctpn = reinterpret_cast<shape_type *>(tfctpn.row(0));
    index_type * lfcnds = reinterpret_cast<index_type *>(tfcnds.row(0));
    index_type * lfccls = reinterpret_cast<index_type *>(tfccls.row(0));

    // extract face definition from the node list of cells.
    pcltpn = reinterpret_cast<index_type *>(cltpn().row(0));
    pclnds = reinterpret_cast<index_type *>(clnds().row(0));
    pclfcs = lclfcs;
    pfctpn = lfctpn;
    pfcnds = lfcnds;
    ifc = 0;
    for (icl=0; icl<ncell(); icl++) {
        tpnicl = pcltpn[0];
        // parse each type of cell.
        if (tpnicl == 0) {
        } else if (tpnicl == 1) {   // line.
            // extract 2 points from a line.
            pclfcs[0] = 2;
            for (it=0; it<pclfcs[0]; it++) {
                pfctpn[it] = 0; // face type is point.
                pfcnds[it*(FCMND+1)] = 1;   // number of nodes per face.
            };
            pfctpn += pclfcs[0];
            // face 1.
            pclfcs[1] = ifc;
            pfcnds[1] = pclnds[1];
            pfcnds += FCMND+1;
            ifc += 1;
            // face 2.
            pclfcs[2] = ifc;
            pfcnds[1] = pclnds[2];
            pfcnds += FCMND+1;
            ifc += 1;
        } else if (tpnicl == 2) {   // quadrilateral.
            // extract 4 lines from a quadrilateral.
            pclfcs[0] = 4;
            for (it=0; it<pclfcs[0]; it++) {
                pfctpn[it] = 1; // face type is line.
                pfcnds[it*(FCMND+1)] = 2;   // number of nodes per face.
            };
            pfctpn += pclfcs[0];
            // face 1.
            pclfcs[1] = ifc;
            pfcnds[1] = pclnds[1];
            pfcnds[2] = pclnds[2];
            pfcnds += FCMND+1;
            ifc += 1;
            // face 2.
            pclfcs[2] = ifc;
            pfcnds[1] = pclnds[2];
            pfcnds[2] = pclnds[3];
            pfcnds += FCMND+1;
            ifc += 1;
            // face 3.
            pclfcs[3] = ifc;
            pfcnds[1] = pclnds[3];
            pfcnds[2] = pclnds[4];
            pfcnds += FCMND+1;
            ifc += 1;
            // face 4.
            pclfcs[4] = ifc;
            pfcnds[1] = pclnds[4];
            pfcnds[2] = pclnds[1];
            pfcnds += FCMND+1;
            ifc += 1;
        } else if (tpnicl == 3) {   // triangle.
            // extract 3 lines from a triangle.
            pclfcs[0] = 3;
            for (it=0; it<pclfcs[0]; it++) {
                pfctpn[it] = 1; // face type is line.
                pfcnds[it*(FCMND+1)] = 2;   // number of nodes per face.
            };
            pfctpn += pclfcs[0];
            // face 1.
            pclfcs[1] = ifc;
            pfcnds[1] = pclnds[1];
            pfcnds[2] = pclnds[2];
            pfcnds += FCMND+1;
            ifc += 1;
            // face 2.
            pclfcs[2] = ifc;
            pfcnds[1] = pclnds[2];
            pfcnds[2] = pclnds[3];
            pfcnds += FCMND+1;
            ifc += 1;
            // face 3.
            pclfcs[3] = ifc;
            pfcnds[1] = pclnds[3];
            pfcnds[2] = pclnds[1];
            pfcnds += FCMND+1;
            ifc += 1;
        } else if (tpnicl == 4) {   // hexahedron.
            // extract 6 quadrilaterals from a hexahedron.
            pclfcs[0] = 6;
            for (it=0; it<pclfcs[0]; it++) {
                pfctpn[it] = 2; // face type is quadrilateral.
                pfcnds[it*(FCMND+1)] = 4;   // number of nodes per face.
            };
            pfctpn += pclfcs[0];
            // face 1.
            pclfcs[1] = ifc;
            pfcnds[1] = pclnds[1];
            pfcnds[2] = pclnds[4];
            pfcnds[3] = pclnds[3];
            pfcnds[4] = pclnds[2];
            pfcnds += FCMND+1;
            ifc += 1;
            // face 2.
            pclfcs[2] = ifc;
            pfcnds[1] = pclnds[2];
            pfcnds[2] = pclnds[3];
            pfcnds[3] = pclnds[7];
            pfcnds[4] = pclnds[6];
            pfcnds += FCMND+1;
            ifc += 1;
            // face 3.
            pclfcs[3] = ifc;
            pfcnds[1] = pclnds[5];
            pfcnds[2] = pclnds[6];
            pfcnds[3] = pclnds[7];
            pfcnds[4] = pclnds[8];
            pfcnds += FCMND+1;
            ifc += 1;
            // face 4.
            pclfcs[4] = ifc;
            pfcnds[1] = pclnds[1];
            pfcnds[2] = pclnds[5];
            pfcnds[3] = pclnds[8];
            pfcnds[4] = pclnds[4];
            pfcnds += FCMND+1;
            ifc += 1;
            // face 5.
            pclfcs[5] = ifc;
            pfcnds[1] = pclnds[1];
            pfcnds[2] = pclnds[2];
            pfcnds[3] = pclnds[6];
            pfcnds[4] = pclnds[5];
            pfcnds += FCMND+1;
            ifc += 1;
            // face 6.
            pclfcs[6] = ifc;
            pfcnds[1] = pclnds[3];
            pfcnds[2] = pclnds[4];
            pfcnds[3] = pclnds[8];
            pfcnds[4] = pclnds[7];
            pfcnds += FCMND+1;
            ifc += 1;
        } else if (tpnicl == 5) {   // tetrahedron.
            // extract 4 triangles from a tetrahedron.
            pclfcs[0] = 4;
            for (it=0; it<pclfcs[0]; it++) {
                pfctpn[it] = 3; // face type is triangle.
                pfcnds[it*(FCMND+1)] = 3;   // number of nodes per face.
            };
            pfctpn += pclfcs[0];
            // face 1.
            pclfcs[1] = ifc;
            pfcnds[1] = pclnds[1];
            pfcnds[2] = pclnds[3];
            pfcnds[3] = pclnds[2];
            pfcnds += FCMND+1;
            ifc += 1;
            // face 2.
            pclfcs[2] = ifc;
            pfcnds[1] = pclnds[1];
            pfcnds[2] = pclnds[2];
            pfcnds[3] = pclnds[4];
            pfcnds += FCMND+1;
            ifc += 1;
            // face 3.
            pclfcs[3] = ifc;
            pfcnds[1] = pclnds[1];
            pfcnds[2] = pclnds[4];
            pfcnds[3] = pclnds[3];
            pfcnds += FCMND+1;
            ifc += 1;
            // face 4.
            pclfcs[4] = ifc;
            pfcnds[1] = pclnds[2];
            pfcnds[2] = pclnds[3];
            pfcnds[3] = pclnds[4];
            pfcnds += FCMND+1;
            ifc += 1;
        } else if (tpnicl == 6) {   // prism.
            // extract 2 triangles and 3 quadrilaterals from a prism.
            pclfcs[0] = 5;
            for (it=0; it<2; it++) {
                pfctpn[it] = 3; // face type is triangle.
                pfcnds[it*(FCMND+1)] = 3;   // number of nodes per face.
            };
            for (it=2; it<pclfcs[0]; it++) {
                pfctpn[it] = 2; // face type is quadrilateral.
                pfcnds[it*(FCMND+1)] = 4;   // number of nodes per face.
            };
            pfctpn += pclfcs[0];
            // face 1.
            pclfcs[1] = ifc;
            pfcnds[1] = pclnds[1];
            pfcnds[2] = pclnds[2];
            pfcnds[3] = pclnds[3];
            pfcnds += FCMND+1;
            ifc += 1;
            // face 2.
            pclfcs[2] = ifc;
            pfcnds[1] = pclnds[4];
            pfcnds[2] = pclnds[6];
            pfcnds[3] = pclnds[5];
            pfcnds += FCMND+1;
            ifc += 1;
            // face 3.
            pclfcs[3] = ifc;
            pfcnds[1] = pclnds[1];
            pfcnds[2] = pclnds[4];
            pfcnds[3] = pclnds[5];
            pfcnds[4] = pclnds[2];
            pfcnds += FCMND+1;
            ifc += 1;
            // face 4.
            pclfcs[4] = ifc;
            pfcnds[1] = pclnds[1];
            pfcnds[2] = pclnds[3];
            pfcnds[3] = pclnds[6];
            pfcnds[4] = pclnds[4];
            pfcnds += FCMND+1;
            ifc += 1;
            // face 5.
            pclfcs[5] = ifc;
            pfcnds[1] = pclnds[2];
            pfcnds[2] = pclnds[5];
            pfcnds[3] = pclnds[6];
            pfcnds[4] = pclnds[3];
            pfcnds += FCMND+1;
            ifc += 1;
        } else if (tpnicl == 7) {   // pyramid.
            // extract 4 triangles and 1 quadrilaterals from a pyramid.
            pclfcs[0] = 5;
            for (it=0; it<4; it++) {
                pfctpn[it] = 3; // face type is triangle.
                pfcnds[it*(FCMND+1)] = 3;   // number of nodes per face.
            };
            for (it=4; it<pclfcs[0]; it++) {
                pfctpn[it] = 2; // face type is quadrilateral.
                pfcnds[it*(FCMND+1)] = 4;   // number of nodes per face.
            };
            pfctpn += pclfcs[0];
            // face 1.
            pclfcs[1] = ifc;
            pfcnds[1] = pclnds[1];
            pfcnds[2] = pclnds[5];
            pfcnds[3] = pclnds[4];
            pfcnds += FCMND+1;
            ifc += 1;
            // face 2.
            pclfcs[2] = ifc;
            pfcnds[1] = pclnds[2];
            pfcnds[2] = pclnds[5];
            pfcnds[3] = pclnds[1];
            pfcnds += FCMND+1;
            ifc += 1;
            // face 3.
            pclfcs[3] = ifc;
            pfcnds[1] = pclnds[3];
            pfcnds[2] = pclnds[5];
            pfcnds[3] = pclnds[2];
            pfcnds += FCMND+1;
            ifc += 1;
            // face 4.
            pclfcs[4] = ifc;
            pfcnds[1] = pclnds[4];
            pfcnds[2] = pclnds[5];
            pfcnds[3] = pclnds[3];
            pfcnds += FCMND+1;
            ifc += 1;
            // face 5.
            pclfcs[5] = ifc;
            pfcnds[1] = pclnds[1];
            pfcnds[2] = pclnds[4];
            pfcnds[3] = pclnds[3];
            pfcnds[4] = pclnds[2];
            pfcnds += FCMND+1;
            ifc += 1;
        };
        // advance pointers.
        pcltpn += 1;
        pclnds += CLMND+1;
        pclfcs += CLMFC+1;
    };

    // build the hash table, to know what faces connect to each node.
    /// first pass: get the maximum number of faces.
    ndnfc = (int *)malloc((size_t)nnode()*sizeof(int));
    for (ind=0; ind<nnode(); ind++) {    // initialize.
        ndnfc[ind] = 0;
    };
    pfcnds = lfcnds; // count.
    for (ifc=0; ifc<mface; ifc++) {
        for (inf=1; inf<=pfcnds[0]; inf++) {
            ind = pfcnds[inf];  // node of interest.
            ndnfc[ind] += 1;    // increment counting.
        };
        // advance pointers.
        pfcnds += FCMND+1;
    };
    ndmfc = 0;  // get maximum.
    for (ind=0; ind<nnode(); ind++) {
        if (ndnfc[ind] > ndmfc) {
            ndmfc = ndnfc[ind];
        };
    };
    free(ndnfc);
    /// second pass: scan again to build hash table.
    ndfcs = (int *)malloc((size_t)nnode()*(ndmfc+1)*sizeof(int));
    pndfcs = ndfcs; // initialize.
    for (ind=0; ind<nnode(); ind++) {
        pndfcs[0] = 0;
        for (it=1; it<=ndmfc; it++) { // <= or < ??
            pndfcs[it] = -1;
        };
        // advance pointers;
        pndfcs += ndmfc+1;
    };
    pfcnds = lfcnds; // build hash table mapping from node to face.
    for (ifc=0; ifc<mface; ifc++) {
        for (inf=1; inf<=pfcnds[0]; inf++) {
            ind = pfcnds[inf];  // node of interest.
            pndfcs = ndfcs + ind*(ndmfc+1);
            pndfcs[0] += 1; // increment face count for the node.
            pndfcs[pndfcs[0]] = ifc;
        };
        // advance pointers.
        pfcnds += FCMND+1;
    };

    // scan for duplicated faces and build duplication map.
    map = (int *)malloc((size_t)mface*sizeof(int));
    for (ifc=0; ifc<mface; ifc++) { // initialize.
        map[ifc] = ifc;
    };
    for (ifc=0; ifc<mface; ifc++) {
        if (map[ifc] == ifc) {
            pifcnds = lfcnds + ifc*(FCMND+1);
            nd1 = pifcnds[1];    // take only the FIRST node of a face.
            pndfcs = ndfcs + nd1*(ndmfc+1);
            for (it=1; it<=pndfcs[0]; it++) {
                jfc = pndfcs[it];
                // test for duplication.
                if ((jfc != ifc) && (lfctpn[jfc] == lfctpn[ifc])) {
                    pjfcnds = lfcnds + jfc*(FCMND+1);
                    cond = pjfcnds[0];
                    // scan all nodes in ifc and jfc to see if all the same.
                    for (jnf=1; jnf<=pjfcnds[0]; jnf++) {
                        for (inf=1; inf<=pifcnds[0]; inf++) {
                            if (pjfcnds[jnf] == pifcnds[inf]) {
                                cond -= 1;
                                break;
                            };
                        };
                    };
                    if (cond == 0) {
                        map[jfc] = ifc;  // record duplication.
                    };
                };
            };
        };
    };

    // use the duplication map to remap nodes in faces, and build renewed map.
    map2 = (int *)malloc((size_t)mface*sizeof(int));
    pifcnds = lfcnds;
    pjfcnds = lfcnds;
    pifctpn = lfctpn;
    pjfctpn = lfctpn;
    jfc = 0;
    for (ifc=0; ifc<mface; ifc++) {
        if (map[ifc] == ifc) {
            for (inf=0; inf<=FCMND; inf++) {
                pjfcnds[inf] = pifcnds[inf];
            };
            pjfctpn[0] = pifctpn[0];
            map2[ifc] = jfc;
            // increment j-face.
            jfc += 1;
            pjfcnds += FCMND+1;
            pjfctpn += 1;
        } else {
            map2[ifc] = map2[map[ifc]];
        };
        // advance pointers;
        pifcnds += FCMND+1;
        pifctpn += 1;
    };
    computed_nface = jfc;    // record deduplicated number of face.

    // rebuild faces in cells and build face neighboring, according to the
    // renewed face map.
    pfccls = lfccls; // initialize.
    for (ifc=0; ifc<mface; ifc++) {
        for (it=0; it<FCREL; it++) {
            pfccls[it] = -1;
        };
        // advance pointers;
        pfccls += FCREL;
    };
    pclfcs = lclfcs;
    for (icl=0; icl<ncell(); icl++) {
        for (ifl=1; ifl<=pclfcs[0]; ifl++) {
            ifc = pclfcs[ifl];
            jfc = map2[ifc];
            // rebuild faces in cells.
            pclfcs[ifl] = jfc;
            // build face neighboring.
            pfccls = lfccls + jfc*FCREL;
            if (pfccls[0] == -1) {
                pfccls[0] = icl;
            } else if (pfccls[1] == -1) {
                pfccls[1] = icl;
            };
        };
        // advance pointers;
        pclfcs += CLMFC+1;
    };

    free(map2);
    free(map);
    free(ndfcs);

    // recreate member tables.
    set_nface(computed_nface);
    create_fctpn(0, nface());
    create_fcnds(0, nface());
    create_fccls(0, nface());
    for (icl=0; icl < ncell(); ++icl) {
        clfcs().set(icl, tclfcs[icl]);
    }
    for (ifc=0; ifc < nface(); ++ifc) {
        fctpn().set(ifc, tfctpn[ifc]);
        fcnds().set(ifc, tfcnds[ifc]);
        fccls().set(ifc, tfccls[ifc]);
    }
    create_fccnd(0, nface());
    create_fcnml(0, nface());
    create_fcara(0, nface());
}