Example #1
0
bool TriangleMesherInterface :: meshPSLG(const Triangle_PSLG &pslg,
                                         const IntArray &outside, const IntArray &inside,
                                         std :: vector< FloatArray > &nodes, std :: vector< IntArray > &n_markers,
                                         std :: vector< IntArray > &triangles, IntArray &t_markers,
                                         std :: vector< IntArray > &segments, IntArray &s_markers) const
{
#ifdef __TRIANGLE_MODULE
    // 1. Fill the struct for triangle;
    struct triangulateio mesh;
    clearTriangulateIO(mesh);

    // 1.a. Copy over the node data.
    mesh.numberofpoints = pslg.nx.giveSize();
    mesh.pointlist = new REAL [ mesh.numberofpoints * 2 ];
    //mesh.pointmarkerlist = new REAL[mesh.numberofpoints];
    for ( int i = 0; i < mesh.numberofpoints; ++i ) {
        mesh.pointlist [ i * 2 ] = pslg.nx(i);
        mesh.pointlist [ i * 2 + 1 ] = pslg.ny(i);
        //mesh.pointmarkerlist[i] = pslg.n_marker(i);
    }

    // 1.b. Copy over the segment data
    printf("Copying segment data\n");
    mesh.numberofsegments = pslg.segment_a.giveSize();
    mesh.segmentlist = new int [ mesh.numberofsegments * 2 ];
    for ( int i = 0; i < mesh.numberofsegments; ++i ) {
        mesh.segmentlist [ i * 2 ] = pslg.segment_a(i);
        mesh.segmentlist [ i * 2 + 1 ] = pslg.segment_b(i);
    }

    if ( pslg.segment_marker.giveSize() > 0 ) {
        mesh.segmentmarkerlist = new int [ mesh.numberofsegments ];
        for ( int i = 0; i < mesh.numberofsegments; ++i ) {
            mesh.segmentmarkerlist [ i ] = pslg.segment_marker(i);
        }
    }

    // 2. Triangulate
    char options [ 100 ];
    // Note: Not sure if -A is necessary when using the library interface.
    sprintf(options, "-p -q %f -a%f %s -A", this->minAngle, this->maxArea, this->quadratic ? "-o2" : "");
    struct triangulateio output;
    clearTriangulateIO(output);
    custom_triangulate( options, & mesh, & output, NULL, outside.givePointer(), inside.givePointer() );

    // 3. Copy back
    nodes.resize(output.numberofpoints);
    //n_markers.resize(output.numberofpoints);
    for ( int i = 0; i < output.numberofpoints; ++i ) {
        nodes [ i ].resize(2);
        nodes [ i ].at(1) = output.pointlist [ i * 2 ];
        nodes [ i ].at(2) = output.pointlist [ i * 2 + 1 ];
        //n_markers(i) = output.pointmarkerlist[i]; // Not enough.
    }

    triangles.resize(output.numberoftriangles);
    t_markers.resize(output.numberoftriangles);
    for ( int i = 0; i < output.numberoftriangles; ++i ) {
        IntArray &triangle = triangles [ i ];
        triangle.resize(output.numberofcorners);
        for ( int j = 0; j < 3; j++ ) { // First three
            triangle(j) = output.trianglelist [ i * output.numberofcorners + j ];
        }
        // Rearrange the strange ordering of the edge nodes.
        if ( output.numberofcorners == 6 ) {
            triangle(3) = output.trianglelist [ i * output.numberofcorners + 5 ];
            triangle(4) = output.trianglelist [ i * output.numberofcorners + 3 ];
            triangle(5) = output.trianglelist [ i * output.numberofcorners + 4 ];
        }
        t_markers.at(i + 1) = ( int ) round(output.triangleattributelist [ i ]);
    }

    // A somewhat annoying missing feature of triangle, it won't make the segments quadratic.
    std :: set< std :: size_t > *node_triangle = NULL;
    if ( this->quadratic ) {
        node_triangle = new std :: set< std :: size_t > [ output.numberofpoints ];
        for ( std :: size_t i = 0; i < triangles.size(); ++i ) {
            IntArray &triangle = triangles [ i ];
            for ( int j = 1; j <= 3; ++j ) {
                node_triangle [ triangle.at(j) - 1 ].insert(i);
            }
        }
    }

    segments.resize(output.numberofsegments);
    s_markers.resize(output.numberofsegments);
    for ( int i = 0; i < output.numberofsegments; ++i ) {
        IntArray &segment = segments [ i ];
        segment.resize(this->quadratic ? 3 : 2);
        segment.at(1) = output.segmentlist [ i * 2 + 0 ];
        segment.at(2) = output.segmentlist [ i * 2 + 1 ];
        //segment->at(3) = output.segmentlist[i*3 + 2]; // Quadratic meshes only, not for segments.
        if ( this->quadratic ) {
            int a, b, c;
            std :: set< std :: size_t >tris = node_triangle [ segment.at(1) - 1 ];
            // Now look up any triangle with the other point included.
            for ( auto tri: tris ) {
                IntArray &triangle = triangles [ tri ];
                if ( ( b = triangle.findFirstIndexOf( segment.at(2) ) ) > 0 ) {
                    a = triangle.findFirstIndexOf( segment.at(1) );
                    if ( a + b == 3 ) {
                        c = 4;
                    } else if ( a + b == 5 ) {
                        c = 5;
                    } else {
                        c = 6;
                    }
                    segment.at(3) = triangle.at(c);
                    break;
                }
            }
        }
        s_markers.at(i + 1) = output.segmentmarkerlist [ i ];
    }
    if ( this->quadratic ) {
        delete[] node_triangle;
    }

    this->fixNodeMarkers(nodes, n_markers, triangles, t_markers, segments, s_markers);

    // Deleting old memory
    delete[] mesh.pointlist;
    //delete[] mesh.pointattributelist;
    //delete[] mesh.pointmarkerlist;
    //delete[] mesh.trianglelist;
    //delete[] mesh.triangleattributelist;
    //delete[] mesh.trianglearealist;
    delete[] mesh.segmentlist;
    delete[] mesh.segmentmarkerlist;
    //if (mesh.holelist) { delete[] mesh.holelist; }
    //if (mesh.regionlist) { delete[] mesh.regionlist; }

    // Holes and regions are referenced in both.
    free(output.pointlist);
    //free(output.pointattributelist);
    free(output.pointmarkerlist);
    free(output.trianglelist);
    free(output.triangleattributelist);
    //free(output.trianglearealist);
    free(output.segmentlist);
    free(output.segmentmarkerlist);
    //free(output.holelist);
    //free(output.regionlist);
#else
    OOFEM_ERROR("OOFEM is not compiled with support for triangle.");
#endif

    return true;
}
Example #2
0
void
NRSolver :: applyConstraintsToStiffness(SparseMtrx *k)
{
    if ( this->smConstraintVersion == k->giveVersion() ) {
        return;
    }

#if 0
 #ifdef __PETSC_MODULE
    if ( solverType == ST_Petsc ) {
        PetscScalar diagVal = 1.0;
        if ( k->giveType() != SMT_PetscMtrx ) {
            OOFEM_ERROR("NRSolver :: applyConstraintsToStiffness: PetscSparseMtrx Expected");
        }

        PetscSparseMtrx *lhs = ( PetscSparseMtrx * ) k;

        if ( !prescribedEgsIS_defined ) {
            IntArray eqs;
  #ifdef __PARALLEL_MODE
            Natural2GlobalOrdering *n2lpm = engngModel->givePetscContext(1)->giveN2Gmap();
            int s = prescribedEqs.giveSize();
            eqs.resize(s);
            for ( int i = 1; i <= s; i++ ) {
                eqs.at(i) = n2lpm->giveNewEq( prescribedEqs.at(i) );
            }

            ISCreateGeneral(PETSC_COMM_WORLD, s, eqs.givePointer(), & prescribedEgsIS);
            //ISView(prescribedEgsIS,PETSC_VIEWER_STDOUT_WORLD);
  #else
            eqs.resize(numberOfPrescribedDofs);
            for ( int i = 1; i <= numberOfPrescribedDofs; i++ ) {
                eqs.at(i) = prescribedEqs.at(i) - 1;
            }

            ISCreateGeneral(PETSC_COMM_SELF, numberOfPrescribedDofs, eqs.givePointer(), & prescribedEgsIS);
            //ISView(prescribedEgsIS,PETSC_VIEWER_STDOUT_SELF);
  #endif
            prescribedEgsIS_defined = true;
        }

        //MatView(*(lhs->giveMtrx()),PETSC_VIEWER_STDOUT_WORLD);
        MatZeroRows(* ( lhs->giveMtrx() ), prescribedEgsIS, & diagVal);
        //MatView(*(lhs->giveMtrx()),PETSC_VIEWER_STDOUT_WORLD);
        if ( numberOfPrescribedDofs ) {
            this->smConstraintVersion = k->giveVersion();
        }

        return;
    }

 #endif // __PETSC_MODULE
#else
 #ifdef __PETSC_MODULE
    if ( solverType == ST_Petsc ) {
        if ( k->giveType() != SMT_PetscMtrx ) {
            OOFEM_ERROR("NRSolver :: applyConstraintsToStiffness: PetscSparseMtrx Expected");
        }

        PetscSparseMtrx *lhs = ( PetscSparseMtrx * ) k;

        Vec diag;
        PetscScalar *ptr;
        int eq;

        PetscContext *parallel_context = engngModel->givePetscContext(this->domain->giveNumber());
        parallel_context->createVecGlobal(& diag);
        MatGetDiagonal(* lhs->giveMtrx(), diag);
        VecGetArray(diag, & ptr);
        for ( int i = 1; i <= numberOfPrescribedDofs; i++ ) {
            eq = prescribedEqs.at(i) - 1;
            MatSetValue(* ( lhs->giveMtrx() ), eq, eq, ptr [ eq ] * 1.e6, INSERT_VALUES);
        }

        MatAssemblyBegin(* lhs->giveMtrx(), MAT_FINAL_ASSEMBLY);
        MatAssemblyEnd(* lhs->giveMtrx(), MAT_FINAL_ASSEMBLY);
        VecRestoreArray(diag, & ptr);
        VecDestroy(&diag);
        if ( numberOfPrescribedDofs ) {
            this->smConstraintVersion = k->giveVersion();
        }

        return;
    }

 #endif // __PETSC_MODULE
#endif
    for ( int i = 1; i <= numberOfPrescribedDofs; i++ ) {
        k->at( prescribedEqs.at(i), prescribedEqs.at(i) ) *= 1.e6;
    }

    if ( numberOfPrescribedDofs ) {
        this->smConstraintVersion = k->giveVersion();
    }
}