Example #1
0
void fixVolumes ( RegionMesh& mesh,
                  const std::vector<bool>& elSign,
                  Switch& sw )
{

    for ( ID i = 0; i < mesh.numVolumes(); i++ )
    {
        if ( ! elSign[ i ] )
        {
            mesh.volume (i).reversePoints();
        }
    }
    sw.create ("HAS_VOLUMES", true);
}
Example #2
0
Real checkVolumes ( RegionMesh const& mesh,
                    std::vector<bool>& elSign,
                    Switch& sw )
{
    Real meas = 0.0;
    Real lmeas = 0.0;
    elSign.clear();
    elSign.reserve ( mesh.numVolumes() );
    typedef typename RegionMesh::elementShape_Type GeoShape;

    switch ( GeoShape::S_shape )
    {
        case TETRA:
        {
            CurrentFE fe ( feTetraP1, geoLinearTetra, quadRuleTetra1pt );
            for ( ID i = 0; i < mesh.numVolumes(); i++ )
            {
                fe.updateJac ( mesh.volume ( i ) );
                lmeas = fe.measure();
                meas += lmeas;
                elSign.push_back ( lmeas > 0.0 );
            }
        }
        break;
        case HEXA:
        {
            CurrentFE fe ( feHexaQ1, geoBilinearHexa, quadRuleHexa1pt );
            for ( ID i = 0; i < mesh.numVolumes(); i++ )
            {
                fe.updateJac ( mesh.volume ( i ) );
                lmeas = fe.measure();
                meas += lmeas;
                elSign.push_back ( lmeas > 0.0 );
            }
        }
        break;
        default:
            sw.create ( "SKIP_ORIENTATION_TEST", true );

            return 0;
    }

    if ( std::find ( elSign.begin(), elSign.end(), false ) != elSign.end() )
    {
        sw.create ( "HAS_NEGATIVE_VOLUMES", true );
    }

    return meas;
}
Example #3
0
void getVolumeFromFaces ( RegionMesh const& mesh,
                          Real vols[ 3 ],
                          std::ostream& err = std::cerr )
{
    MeshUtility::GetCoordComponent getx ( 0 );
    MeshUtility::GetCoordComponent gety ( 1 );
    MeshUtility::GetCoordComponent getz ( 2 );
    vols[ 0 ] = 0.0;
    vols[ 1 ] = 0.0;
    vols[ 2 ] = 0.0;
    typedef typename RegionMesh::facetShape_Type GeoBShape;
    typedef typename RegionMesh::facet_Type facet_Type;
    typedef boost::shared_ptr<CurrentFEManifold> current_fe_type;

    current_fe_type bdfe;

    switch ( GeoBShape::S_shape )
    {
        case TRIANGLE:
            bdfe = current_fe_type ( new CurrentFEManifold ( feTriaP1, geoLinearTria,
                                                             quadRuleTria1pt ) );
            for ( ID i = 0; i < mesh.numBFaces(); i++ )
            {
                bdfe->update ( mesh.face ( i ), UPDATE_W_ROOT_DET_METRIC | UPDATE_NORMALS | UPDATE_QUAD_NODES );
                vols[ 0 ] += bdfe->normalIntegral ( getx );
                vols[ 1 ] += bdfe->normalIntegral ( gety );
                vols[ 2 ] += bdfe->normalIntegral ( getz );
            }
            break;
        case QUAD:
            bdfe = current_fe_type ( new CurrentFEManifold ( feQuadQ1, geoBilinearQuad,
                                                             quadRuleQuad1pt ) );
            for ( ID i = 0; i < mesh.numBFaces(); i++ )
            {
                bdfe->update ( mesh.face ( i ), UPDATE_W_ROOT_DET_METRIC | UPDATE_NORMALS | UPDATE_QUAD_NODES );
                vols[ 0 ] += bdfe->normalIntegral ( getx );
                vols[ 1 ] += bdfe->normalIntegral ( gety );
                vols[ 2 ] += bdfe->normalIntegral ( getz );
            }
            break;
        default:
            err << "Only tria and quad surface elements  may be checked for volume orientation at the moment" << std::endl;
            ASSERT0 ( false, "ABORT CONDITION OCCURRED" );
    }
}
Example #4
0
Real testClosedDomain ( RegionMesh const& mesh,
                        std::ostream& err = std::cerr )
{
    typedef typename RegionMesh::facet_Type facet_Type;

    typedef boost::shared_ptr<CurrentFEManifold> current_fe_type;
    current_fe_type bdfe;

    MeshUtility::GetOnes ones;
    Real test ( 0.0 );

    switch ( RegionMesh::facetShape_Type::S_shape )
    {
        case TRIANGLE:
            bdfe = current_fe_type ( new CurrentFEManifold ( feTriaP1, geoLinearTria,
                                                             quadRuleTria1pt ) );
            for ( ID i = 0; i < mesh.numBFaces(); i++ )
            {
                bdfe->update ( mesh.face ( i ), UPDATE_W_ROOT_DET_METRIC | UPDATE_NORMALS | UPDATE_QUAD_NODES );
                test += bdfe->normalIntegral ( ones );
            }
            break;
        case QUAD:
            bdfe = current_fe_type ( new CurrentFEManifold ( feQuadQ1, geoBilinearQuad,
                                                             quadRuleQuad1pt ) );
            for ( ID i = 0; i < mesh.numBFaces(); i++ )
            {
                bdfe->update ( mesh.face ( i ), UPDATE_W_ROOT_DET_METRIC | UPDATE_NORMALS | UPDATE_QUAD_NODES );
                test += bdfe->normalIntegral ( ones );
            }

            break;

        default:
            err << "Only tria and quad surface elements  may be checked for volume orientation at the moment" << std::endl;
            ASSERT0 ( false, "ABORT CONDITION OCCURRED" );
    }

    return test;

}
Example #5
0
bool
readFreeFemFile( RegionMesh<LinearTriangle, MC> & mesh,
                 const std::string          & fileName,
                 markerID_Type              regionFlag, bool /*useless*/ = false)
{
    MeshElementBareHandler<BareEdge> _be;
    std::pair<BareEdge, bool> _edge;

    typedef LinearTriangle GeoShape;

    typename RegionMesh<GeoShape, MC>::point_Type * pp = 0;
    typename RegionMesh<GeoShape, MC>::edge_Type * pe = 0;
    typename RegionMesh<GeoShape, MC>::face_Type * pf = 0;

    std::ifstream __is ( fileName.c_str() );
    if( __is.fail() )
    {
        std::cerr << " Error in readFreeFemFile: File " << fileName
                  << " not found or locked"
                  << std::endl;
        abort();
    }

    // first row: how many vertices, triangles, edges
    UInt __nv, __nt, __ne, i1, i2, i3;
    __is >> __nv >> __nt >> __ne;

#ifdef DEBUG
    debugStream ( 8000 ) << "number of vertices: "<< __nv << "\n";
    debugStream ( 8000 ) << "number of triangles: "<< __nt << "\n";
    debugStream ( 8000 ) << "number of edges: "<< __ne << "\n";
#endif

    // first section: read the list of vertices
    // on each row find the two coordinates and the label for each node
    std::vector<Real> __x(2*__nv);
    std::vector<bool> __isonboundary(__nv);
    std::vector<UInt> __whichboundary(__nv);

#ifdef DEBUG
    debugStream ( 8000 ) << "reading "<< __nv << " nodes\n";
#endif

    // count the number of nodes on the boundary
    UInt __nbv( 0 );

    // reading vertices
    for ( UInt __i = 0; __i < __nv; ++ __i )
    {
        __is >> __x[ 2 * __i ] >> __x[ 2 * __i + 1 ] >> __whichboundary[ __i ];
        __isonboundary[ __i ] = __whichboundary[ __i ];
        __nbv                += __isonboundary[ __i ];
    }

    // second section: read the list of triangles
    // on each row find the three nodes and the label for each triangle
    std::vector<int> __triangle_nodes( 3 * __nt );
    std::vector<int> __triangle_label( __nt );

#ifdef DEBUG
    debugStream ( 8000 ) << "reading "<< __nt << " triangles\n";
#endif

    std::map<UInt,UInt> edge_to_firstAdjacentElementIdentity, edge_to_firstAdjacentElementPosition;

    // reading vertices
    for ( UInt __i = 0; __i < __nt; ++__i )
    {
        __is >> __triangle_nodes[ 3 * __i ]
        >> __triangle_nodes[ 3 * __i + 1 ]
        >> __triangle_nodes[ 3 * __i + 2 ]
        >> __triangle_label[ __i ];

        //from 1-based numbering to 0-based numbering
		__triangle_nodes[3 * __i]--;
		__triangle_nodes[3 * __i+1]--;
		__triangle_nodes[3 * __i+2]--;

		// dump first the existing edges, to maintain the correct numbering
        // if everything is correct the numbering in the bareedge
        // structure will reflect the actual edge numbering

        std::pair<UInt, bool> _check;

        i1 = __triangle_nodes[ 3 * __i ];
        i2 = __triangle_nodes[ 3 * __i + 1 ];
        i3 = __triangle_nodes[ 3 * __i + 2 ];

        _edge                             = makeBareEdge( i1, i2 );
        _check                            = _be.addIfNotThere( _edge.first );
        edge_to_firstAdjacentElementIdentity[ _check.first ]  = __i;
        edge_to_firstAdjacentElementPosition[ _check.first ] = 0;

        _edge                             = makeBareEdge( i2, i3 );
        _check                            = _be.addIfNotThere( _edge.first );
        edge_to_firstAdjacentElementIdentity[ _check.first ]  = __i;
        edge_to_firstAdjacentElementPosition[ _check.first ] = 1;

        _edge                             = makeBareEdge( i3, i1 );
        _check                            = _be.addIfNotThere( _edge.first );
        edge_to_firstAdjacentElementIdentity[ _check.first ]  = __i;
        edge_to_firstAdjacentElementPosition[ _check.first ] = 2;
    }

    //    ( __triangle[ 3 * i + 2] > __triangle[ 3 * i + 1 ] )

    // third section: read the list of edges
    // NOTE: only boundary edges are stored
    // on each row find the two nodes and the label for each edge
    std::vector<int> __edge_nodes( 2 * __ne );
    std::vector<int> __edge_label( __ne );

    // reading edges

    for ( UInt __i = 0; __i < __ne; ++__i )
    {
        __is >> __edge_nodes[ 2 * __i ] >> __edge_nodes[ 2 * __i + 1 ] >> __edge_label[ __i ];
    }

    //from 1-based numbering to 0-based numbering
    for(UInt i(0); i<__edge_nodes.size(); i++)
    	__edge_nodes[i]--;

    // Set mesh properties
    // Add Marker to list of Markers
    mesh.setMarkerID( regionFlag );

    // Till now I only have information about boundary edges - I don't know the MAX num of edges
    // Euler formula: ne = nv + nt - 1
    mesh.setMaxNumEdges      ( _be.size() );
    mesh.setMaxNumGlobalEdges( _be.size() );

    // Here the REAL number of edges (all of them)
    mesh.setNumEdges         ( _be.size() );

    mesh.setNumBEdges        ( __ne );
    mesh.setMaxNumFaces      ( __nt );
    mesh.setMaxNumGlobalFaces( __nt );

    // Here the REAL number of edges (all of them)
    mesh.setNumFaces          ( __nt);

    mesh.setMaxNumPoints      ( __nv, true );
    mesh.setMaxNumGlobalPoints( __nv );

    mesh.setNumVertices       ( __nv );
    mesh.setNumGlobalVertices ( __nv );

    mesh.numBVertices()      = __nbv;
    mesh.setNumBPoints( mesh.numBVertices() );

#ifdef DEBUG
    debugStream ( 8000 ) << "number of points : " << mesh.numPoints() << "\n";
    debugStream ( 8000 ) << "number of boundary points : " << mesh.numBPoints() << "\n";
    debugStream ( 8000 ) << "number of vertices : " << mesh.numVertices() << "\n";
    debugStream ( 8000 ) << "number of boundary vertices : " << mesh.numBVertices() << "\n";
#endif

    for ( UInt __i = 0; __i < __nv; ++__i )
    {
        pp = &mesh.addPoint( __isonboundary[ __i ], true );
        pp->setMarkerID( __whichboundary[ __i ] );
        pp->x() = __x[ 2 * __i ];
        pp->y() = __x[ 2 * __i + 1 ];
        pp->z() = 0;
        pp->setId( __i );
    }

    // add the edges to the mesh
    for ( UInt __i = 0; __i < __ne; ++__i )
    {
        pe = &( mesh.addEdge( true ) );
        pe->setMarkerID( markerID_Type( __edge_label[ __i ] ) );
        pe->setPoint( 0, mesh.point( __edge_nodes[ 2 * __i ] ) );
        pe->setPoint( 1, mesh.point( __edge_nodes[ 2 * __i + 1 ] ) );
        pe->setId( __i );
        _edge = makeBareEdge( __edge_nodes[ 2 * __i ], __edge_nodes[ 2 * __i + 1 ] );
        UInt map_it( _be.id( _edge.first ) );
        pe->firstAdjacentElementIdentity() = edge_to_firstAdjacentElementIdentity[ map_it ];
        pe->firstAdjacentElementPosition() = edge_to_firstAdjacentElementPosition[ map_it ];
    }

    // add the triangles to the mesh
    for ( UInt __i = 0; __i < __nt; ++__i )
    {
        pf = &( mesh.addFace(true) );
        pf->setId( __i );
        pf->setMarkerID( markerID_Type( __triangle_label[ __i ] ) );
        pf->setPoint( 0, mesh.point( __triangle_nodes[ 3 * __i ] ) );
        pf->setPoint( 1, mesh.point( __triangle_nodes[ 3 * __i + 1 ] ) );
        pf->setPoint( 2, mesh.point( __triangle_nodes[ 3 * __i + 2 ] ) );
    }

    return true;
} // Function readFreeFemFile
Example #6
0
int main (int argc, char** argv)
{
#ifdef HAVE_MPI
    MPI_Init (&argc, &argv);
    std::cout << "MPI Initialization" << std::endl;
    boost::shared_ptr<Epetra_Comm> comm ( new Epetra_MpiComm ( MPI_COMM_WORLD ) );
#else
    boost::shared_ptr<Epetra_Comm> comm ( new Epetra_SerialComm );
#endif


    using namespace LifeV;
    using namespace LifeV::MeshUtility;
    using namespace std;

    GetPot datafile ( "data" );
    string dirname = datafile ( "mesh_dir", "." ); //"../data/mesh/mesh++/";
    if (*dirname.rbegin() != '/');
        dirname += "/";
    string fname = dirname + datafile ( "mesh_file", "cube_47785.m++" ); //dirname+"cube_47785.m++";
    string outfile = "testBuilders.dat";
    ofstream ofile (outfile.c_str() );
    if (ofile.fail() )
    {
        cerr << " Error: Cannot creat output file" << endl;
        abort();
    }

    RegionMesh<LinearTetra> aMesh ( comm );
    typedef RegionMesh<LinearTetra> mesh_Type;
    //    aMesh.test3DBuilder();
    //    aMesh.readMppFile(mystream, id, m);
    ID m = 1;
    readMppFile (aMesh, fname, m);

    cout << " **********************************************************" << endl;

    cout << "  ****************** CHECKING MESH WITH INTERNAL CHECKER" << endl;

    aMesh.check (0, true, true);
    Switch sw;


    cout << " **********************************************************" << endl;

    cout << "  ****************** CLEANING edges and faces " << endl;

    aMesh.edgeList.clear();
    aMesh.faceList.clear();

    checkMesh3D (aMesh, sw,
                 true, true,
                 cerr, cout, ofile);


    aMesh.showMe();


    cout << " Now building local Edges/faces Stuff" << endl << endl;
    aMesh.updateElementEdges();
    aMesh.updateElementFaces();
    aMesh.showMe();
    cout << " Now cleaning local Edges/faces Stuff" << endl << endl;
    aMesh.cleanElementRidges();
    aMesh.cleanElementFacets();
    aMesh.showMe();
    cout << " **********************************************************" << endl;

    cout << "  ****************** BUILDING ALL EDGES" << endl;
    UInt bedges_found, iedges_found;
    buildEdges (aMesh, ofile, cerr, bedges_found,
                iedges_found, true, true, true);
    cout << " **********************************************************" << endl;

    cout << "  ****************** BUILDING ALL FACES" << endl;
    UInt bfaces_found, ifaces_found;
    buildFaces (aMesh, ofile, cerr, bfaces_found,
                ifaces_found, true, true, true);

    aMesh.showMe();

    cout << " Now building again local Edges/faces Stuff" << endl << endl;
    aMesh.updateElementEdges();
    aMesh.updateElementFaces();
    aMesh.showMe();
    checkMesh3D (aMesh, sw,
                 true, true,
                 cerr, cout, ofile);
    ofile.close();

    ///THIS PART IS ONLY TO VERIFY IF THESE ROUTINES COMPILE PROPERLY
    cerr << "Fixing bpoints" << endl;

    fixBoundaryPoints (aMesh, ofile, cerr, true);
    cerr << "Fixing edge markers" << endl;
    setBoundaryEdgesMarker (aMesh, ofile, cerr, true);
    cerr << "Fixing faces marker" << endl;
    setBoundaryFacesMarker (aMesh, ofile, cerr, true);
    cerr << "Fixing points marker" << endl;
    setBoundaryPointsMarker (aMesh, ofile, cerr, true);
    cerr << endl;
    dummyVect disp (3 * aMesh.numPoints() );
    MeshUtility::MeshTransformer<mesh_Type> transformer (aMesh);
    transformer.moveMesh (disp, 3);
    MeshUtility::MeshStatistics::meshSize sizes = MeshUtility::MeshStatistics::computeSize (aMesh);
    cerr << "Hmin =" << sizes.minH << " Hmax=" << sizes.maxH << std::endl;
    mesh_Type::points_Type newPointList = aMesh.pointList;
    mesh_Type::faces_Type newFaceList = aMesh.faceList;
    Utilities::fixAfterShallowCopy (newFaceList, newPointList);
    for (mesh_Type::faces_Type::iterator i = newFaceList.begin(); i < newFaceList.end(); ++i)
    {
        ID theId = i->point (0).id();
        if (& (i->point (0) ) != & (newPointList[theId]) )
        {
            cerr << "ERROR: Error after renumbering Faces" << std::endl;
            break;
        }
    }
    aMesh.faceList[2].replaceFlag (EntityFlags::CUTTED);
    aMesh.faceList.reorderAccordingToFlag (EntityFlags::CUTTED, &Flag::testOneSet);
    if (aMesh.faceList[0].flag() != EntityFlags::CUTTED)
    {
        cerr << "ERROR: Reordering is not working" << std::endl;
    }
    cout << "Number of cutted faces (should be 1) " <<
         aMesh.faceList.countElementsWithFlag (EntityFlags::CUTTED, &Flag::testOneSet) << std::endl;
    // Reset all flags to default
    aMesh.edgeList.changeAccordingToFunctor (ResetFlag<mesh_Type::edge_Type>() );
    aMesh.edge (0).setMarkerID (10);
    aMesh.edge (5).setMarkerID (10);
    aMesh.edge (10).setMarkerID (15);
    vector<ID> watermarks (2);
    watermarks[0] = 10;
    watermarks[1] = 15;
    // change flags according to marker iD
    SetFlagAccordingToWatermarks changeFlags (EntityFlags::CUTTED, watermarks);
    aMesh.edgeList.changeAccordingToFunctor (changeFlags);
    std::cout << "Number of cutted edges (should be 3) "
              << aMesh.edgeList.countElementsWithFlag (EntityFlags::CUTTED, &Flag::testOneSet) << std::endl;
    aMesh.edgeList.changeAccordingToFunctor ( ResetFlag<mesh_Type::edge_Type>() );
    aMesh.edge (0).setMarkerID (10);
    aMesh.edge (5).setMarkerID (12);
    aMesh.edge (10).setMarkerID (15);
    SetFlagAccordingToMarkerRanges changer ( &Flag::turnOn ); //I may use the default constructor
    changer.insert (std::make_pair (10, 12), EntityFlags::INTERNAL_INTERFACE);
    changer.insert (std::make_pair (15, 18), EntityFlags::CUTTED);
    aMesh.edgeList.changeAccordingToFunctor (changer);
    cout << "Number of cutted edges (should be 1) " <<
         aMesh.edgeList.countElementsWithFlag (EntityFlags::CUTTED, &Flag::testOneSet) << std::endl;
    cout << "Number of internal interface edges (should be 2) " <<
         aMesh.edgeList.countElementsWithFlag (EntityFlags::INTERNAL_INTERFACE, &Flag::testOneSet) << std::endl;

    SetFlagAccordingToWatermark<std::equal_to<markerID_Type> > changer2 (EntityFlags::INTERNAL_INTERFACE, 12000, Flag::turnOn);
    aMesh.faceList.changeAccordingToFunctor (changer2);

#ifdef HAVE_MPI
    MPI_Finalize();
#endif

    return ( EXIT_SUCCESS );
}
Example #7
0
bool checkMesh3D ( RegionMesh& mesh,
                   Switch& sw,
                   bool fix = true,
                   bool verbose = false,
                   std::ostream& out = std::cerr,
                   std::ostream& err = std::cerr,
                   std::ostream& clog = std::clog )
{
    verbose = verbose && ( mesh.comm()->MyPID() == 0 );
    typedef typename RegionMesh::point_Type point_Type;

    if ( mesh.storedPoints() == 0 )
    {
        err << "FATAL: mesh does not store points: I cannot do anything"
            << std::endl;
        sw.create ( "ABORT_CONDITION", true );
        sw.create ( "NOT_HAS_POINTS", true );
        return false;
    }

    if (verbose)
    {
        out << " Check point marker ids" << std::endl;
    }
    if ( !MeshUtility::checkIsMarkerSet ( mesh.pointList ) )
    {
        if (verbose)
        {
            err << "WARNING: Not all points have marker id set" << std::endl;
        }

        sw.create ( "POINTS_MARKER_UNSET", true );
    }


    //-------------------------------------------------------------------------
    //                                    VOLUMES
    //-------------------------------------------------------------------------


    if ( mesh.storedVolumes() == 0 )
    {
        if (verbose) err << "FATAL: mesh does not store volumes: I cannot do anything"
                             << std::endl;
        sw.create ( "ABORT_CONDITION", true );
        sw.create ( "NOT_HAS_VOLUMES", true );
        return false;
    }


    if ( !MeshUtility::checkId ( mesh.volumeList ) )
    {
        if (verbose)
        {
            err << "ERROR: volume ids were wrongly set" << std::endl;
            err << "FIXED" << std::endl;
        }
        if ( fix )
        {
            sw.create ( "FIXED_VOLUMES_ID", true );
        }
        if ( fix )
        {
            MeshUtility::fixId ( mesh.volumeList );
        }
    }

    if (verbose)
    {
        out << " Check volum marker ids" << std::endl;
    }
    if ( !MeshUtility::checkIsMarkerSet ( mesh.volumeList ) )
    {
        if (verbose)
        {
            err << "WARNING: Not all volumes have marker flag set" << std::endl;
        }

        sw.create ( "VOLUMES_MARKER_UNSET", true );

        if ( fix )
        {
            if (verbose)
            {
                out << "Fixing volume marker ids" << std::endl;
            }
            for ( typename RegionMesh::volumes_Type::iterator iv = mesh.volumeList.begin();
                    iv != mesh.volumeList.end(); ++iv )
            {
                if ( iv->isMarkerUnset() )
                {
                    iv->setMarkerID ( mesh.markerID() );
                }
            }
        }
    }

    if ( mesh.numElements() < mesh.storedVolumes() )
    {
        if (verbose)
            err << "WARNING: Mesh Volumes must be at least "
                << mesh.storedVolumes() << std::endl;
        if ( fix )
        {
            mesh.setNumVolumes ( mesh.storedVolumes() );
        }
        if ( fix )
        {
            sw.create ( "FIXED_VOLUME_COUNTER", true );
        }
    }

    // test now orientation

    boost::shared_ptr<std::vector<bool> > elSign ( new std::vector<bool> );

    Real meshMeasure = checkVolumes ( mesh, *elSign, sw );
    UInt positive;

    if ( sw.test ( "SKIP_ORIENTATION_TEST" ) )
    {
        if (verbose)
        {
            clog << "W: ELEMENT ORIENTATION NOT IMPLEMENTED YET FOR THIS TYPE OF ELEMENTS, SKIP" << std::endl;
            err << "W: ELEMENT ORIENTATION NOT IMPLEMENTED YET FOR THIS TYPE OF ELEMENTS, SKIP" << std::endl;
        }
    }
    else if ( sw.test ( "HAS_NEGATIVE_VOLUMES" ) )
    {
        if (verbose)
        {
            out << "Checking volume orientation" << std::endl;
        }
        positive = count ( elSign->begin(), elSign->end(), true );
        if ( verbose ) clog << positive << "W: positive elements out of"
                                << mesh.storedVolumes() << std::endl;
        if ( fix )
        {
            if ( verbose )
            {
                clog << "Fixing negative elements" << std::endl;
            }
            fixVolumes ( mesh, *elSign, sw );
        }

        if ( sw.test ( "ABORT_CONDITION" ) )
        {
            if (verbose) err << "ABORT: Cannot fix volumes, this element is not supported"
                                 << std::endl;
            return false;
        }
        else
        {
            sw.unset ( "HAS_NEGATIVE_VOLUMES" );
            meshMeasure = checkVolumes ( mesh, *elSign, sw );
            if ( sw.test ( "HAS_NEGATIVE_VOLUMES" ) )
            {
                if ( fix )
                {
                    if ( verbose )
                    {
                        err << "ABORT: Cannot fix volumes: something wrong with this mesh" << std::endl;
                    }
                    sw.create ( "ABORT_CONDITION", true );
                }
                return false;
            }
        }
    }

    if ( verbose ) clog << "Volume enclosed by the mesh= " << meshMeasure << std::endl
                            << "(Computed by integrating mesh elements measures)" << std::endl
                            << "(Using 1 point Quadrature rule)" << std::endl;

    //-----------------------------------------------------
    //                                    BOUNDARY FACES
    //-----------------------------------------------------

    boost::shared_ptr<MeshUtility::temporaryFaceContainer_Type> bfaces (
        new MeshUtility::temporaryFaceContainer_Type );
    UInt numInternalFaces, numFaces;

    if (verbose)
    {
        out << "Finding boundary faces from mesh topology" << std::endl;
    }

    UInt bFacesFound = MeshUtility::findBoundaryFaces ( mesh, *bfaces, numInternalFaces );

    numFaces = bFacesFound + numInternalFaces;

    MeshUtility::EnquireBFace<RegionMesh> enquireBFace (*bfaces );

    UInt meshNumBoundaryFaces ( mesh.numBFaces() + mesh.faceList.countElementsWithFlag ( EntityFlags::SUBDOMAIN_INTERFACE, &Flag::testOneSet ) );

    if ( mesh.storedFaces() == 0 ||
            meshNumBoundaryFaces > mesh.storedFaces() ||
            bFacesFound > mesh.storedFaces() || bFacesFound > meshNumBoundaryFaces )
    {
        // Something strange with boundary faces
        if (verbose)
        {
            err << "ERROR: Not all boundary faces stored" << std::endl;
            err << "Found " << bFacesFound << " stored " << mesh.storedFaces() <<
                "B faces declared in mesh " << meshNumBoundaryFaces << std::endl;
        }
        if ( fix )
        {
            sw.create ( "BUILD_BFACES", true );
            if (verbose)
            {
                out << "Building boundary faces from topology data" << std::endl;
            }
            MeshUtility::buildFaces ( mesh, clog, err, bFacesFound, numInternalFaces,
                                      true, false, false, bfaces.get() );
        }
        if (verbose)
        {
            err << "After buildFaces" << std::endl;
            err << "Found " << bFacesFound << " stored " << mesh.storedFaces()
                << "B faces declared in mesh " << meshNumBoundaryFaces << std::endl;
        }
    }
    else
    {
        if ( mesh.storedFaces() == 0 )
        {
            if ( verbose )
            {
                err << "ABORT CONDITION: cannot find boundary faces" << std::endl;
            }
            sw.create ( "NOT_HAS_FACES", true );
            sw.create ( "ABORT_CONDITION", true );
        }
        // The mesh declares to have the correct boundary faces. Yet, are we sure that the flag has been properly set
        // and that they are stored first? If fix is set we don't trust anybody!
        //
        // Make sure that flags are set using the info in bfaces, which depends ONLY on the mesh topology. No messing bout with markers
        // Make sure BFaces are stored first

        if (fix)
        {
            if (verbose)
            {
                out << "Rearranging faces so that boundary faces are first" << std::endl;
            }
            MeshUtility::rearrangeFaces ( mesh, clog, err, sw, numFaces, bFacesFound,
                                          verbose, bfaces.get() );
        }
        if ( meshNumBoundaryFaces !=  bFacesFound)
        {
            if ( verbose )
            {
                err << " ERROR: Number of B faces does not correspond to real one" << std::endl;
            }
            if (fix)
            {
                if ( verbose )
                {
                    err << "FIXED Number of B faces has been fixed to:" << bFacesFound << std::endl;
                }
                mesh.setNumBFaces ( bFacesFound);
            }
        }

        if ( !MeshUtility::checkId ( mesh.faceList ) )
        {
            if ( verbose )
            {
                err << "ERROR: face ids were wrongly set" << std::endl;
                err << "FIXED" << std::endl;
            }
            if ( fix )
            {
                sw.create ( "FIXED_FACES_ID", true );
                MeshUtility::fixId ( mesh.faceList );
            }
        }

        // Check Consistency with the mesh.

        if ( fix )
        {
            if (verbose)
            {
                out << "Make sure that adjacent elements of boundary faces are correct" << std::endl;
            }
            MeshUtility::fixBoundaryFaces ( mesh, clog, err, sw, numFaces, bFacesFound,
                                            false, verbose, bfaces.get() );
        }



        if ( mesh.numBFaces() == 0 )
        {
            if ( verbose )
            {
                err << " MeshBFaces counter is unset" << std::endl;
            }
            if ( fix )
            {
                mesh.setNumBFaces ( mesh.storedFaces() );
                sw.create ( "FIXED_BFACE_COUNTER", true );
                mesh.setLinkSwitch ( "HAS_BOUNDARY_FACETS" );
            }
        }


        if ( !MeshUtility::checkIsMarkerSet ( mesh.faceList ) )
        {
            if (verbose)
            {
                out << "Fix markers id for faces" << std::endl;
            }
            if ( verbose )
            {
                err << "WARNING: Not all faces have marker flag set" << std::endl;
            }
            sw.create ( "FACE_MARKER_UNSET", true );
            if ( fix )
            {
                MeshUtility::setBoundaryFacesMarker ( mesh, clog, err, verbose );
            }
            if ( fix && MeshUtility::checkIsMarkerSet ( mesh.faceList ) )
            {
                sw.create ( "FACE_MARKER_UNSET", false );
                sw.create ( "FACE_MARKER_FIXED", true );
            }
        }
    }


    if ( mesh.numFaces() != bFacesFound + numInternalFaces )
    {
        if ( verbose )
        {
            err << "WARNING Number of faces incorrectly set" << std::endl;
            err << "        It was       " << mesh.numFaces() << std::endl;
            err << "        It should be " << bFacesFound + numInternalFaces
                << std::endl;
        }
        if ( fix )
        {
            if ( verbose )
            {
                err << "        Fixing" << std::endl;
            }
            mesh.setNumFaces ( bFacesFound + numInternalFaces );
            sw.create ( "FIXED_FACE_COUNTER", true );
        }
    }

    if ( fix && mesh.storedFaces() == bFacesFound + numInternalFaces)
    {
        mesh.setLinkSwitch ( "HAS_ALL_FACETS" );
    }

    if (verbose)
    {
        out << std::endl;
        out << " Boundary faces found        :" << bFacesFound << std::endl;
        out << " Num Faces Stored stored     :" << mesh.storedFaces() << std::endl;
        out << " Num faces in mesh           :" << mesh.numFaces() << std::endl;
        out << " Boundary faces counter gives:" << mesh.numBFaces() << std::endl;
        out << std::endl;
    }
    //-----------------------------------------------------
    //                                    BOUNDARY EDGES
    //-----------------------------------------------------

    boost::shared_ptr<MeshUtility::temporaryEdgeContainer_Type> bedges (
        new MeshUtility::temporaryEdgeContainer_Type );

    UInt bEdgesFound = MeshUtility::findBoundaryEdges ( mesh, *bedges );
    MeshUtility::EnquireBEdge<RegionMesh> enquireBEdge (*bedges );

    UInt intedge (0);
    UInt Ned (0);
    MeshUtility::temporaryEdgeContainer_Type iedges;

    if ( mesh.storedEdges() == 0 ||
            mesh.numBEdges() > mesh.storedEdges() ||
            bEdgesFound > mesh.storedEdges() )
    {
        if (verbose)
        {
            err << "WARNING: mesh does not store (all) boundary edges" << std::endl;
        }
        sw.create ( "NOT_HAS_EDGES", true );
        if ( fix )
        {
            if (verbose)
            {
                out << "Build boundary edges" << std::endl;
            }
            MeshUtility::buildEdges ( mesh, clog, err, bEdgesFound, intedge, true, false,
                                      false, bedges.get() );
        }
        Ned = bEdgesFound + intedge;
        if ( fix )
        {
            sw.create ( "BUILD_BEDGES", true );
        }
    }
    else
    {

        // Make sure BEdges are first
        // Here I need to use a method that does not require the proper
        // setting of boundary Points!
        // With the edges I am being a bit sloppy. I am trusting the given mesh
        // todo do the same it was done for faces!
        if ( mesh.numBEdges() !=  bEdgesFound)
        {
            if ( verbose )
            {
                err << " ERROR: Number of BEdges does not correspond to real one" << std::endl;
            }
            if (fix)
            {
                if ( verbose )
                {
                    err << "FIXED Number of BEdges has been fixed to:" << bEdgesFound << std::endl;
                }
                mesh.setNumBEdges ( bEdgesFound);
            }
        }

        if ( fix )
        {
            if (verbose)
            {
                out << "Reorder edges so that boundary are first" << std::endl;
            }
            mesh.edgeList.reorderAccordingToFlag (EntityFlags::PHYSICAL_BOUNDARY, &Flag::testOneSet);

            sw.create ( "FIXED_BEDGES_FIRST" );
        }
        if ( !MeshUtility::checkId ( mesh.edgeList ) )
        {
            if ( verbose )
            {
                err << "ERROR: edge ids were wrongly set" << std::endl;
            }
            if (fix)
            {
                if ( verbose )
                {
                    err << "FIXED" << std::endl;
                }
                sw.create ( "FIXED_EDGES_ID", true );
                MeshUtility::fixId ( mesh.edgeList );
            }
        }


        if ( !MeshUtility::checkIsMarkerSet ( mesh.edgeList ) )
        {
            if ( verbose )
            {
                err << "WARNING: Not all edges have marker flag set" << std::endl;
            }
            sw.create ( "EDGE_MARKER_UNSET", true );
            if ( fix )
            {
                if (verbose)
                {
                    out << "Fix boundary edges marker" << std::endl;
                }
                MeshUtility::setBoundaryEdgesMarker ( mesh, clog, err, verbose );
            }
            if ( fix && MeshUtility::checkIsMarkerSet ( mesh.edgeList ) )
            {
                sw.unset ( "EDGE_MARKER_UNSET" );
                sw.create ( "EDGE_MARKER_FIXED", true );
            }
        }
        if (verbose)
        {
            out << "Computing number of internal edges";
        }
        if ( fix )
        {
            Ned = bEdgesFound + MeshUtility::findInternalEdges ( mesh, *bedges, iedges );
        }
    }
    iedges.clear();
    MeshUtility::temporaryEdgeContainer_Type tmp;
    iedges.swap (tmp);

    if ( mesh.numBEdges() != bEdgesFound )
    {
        if ( verbose ) err << "WARNING: number of found boundary edges:" << bEdgesFound
                               << std::endl
                               << " does not match that declared in mesh, i.e. "
                               << mesh.numBEdges() << std::endl;
        if ( mesh.numBEdges() == 0 )
        {
            if ( fix )
            {
                if ( verbose )
                {
                    err << "FIXING" << std::endl;
                }
                sw.create ( "FIXED_BEDGES_COUNTER", true );
                mesh.setNumBEdges ( bEdgesFound );
            }
        }
    }

    if ( Ned != mesh.numEdges() )
    {
        if ( fix )
        {
            if ( verbose ) err << "WARNING: Counter of number of edges badly set: Should be (actual number)" << Ned << std::endl
                                   << "It is instead equal to " << mesh.numEdges() << std::endl;
            err << " **FIXED" << std::endl;
            mesh.setNumEdges ( Ned );
        }
    }
    UInt nbed;
    UInt counte = MeshUtility::testDomainTopology ( mesh, nbed );
    if ( counte == 0 )
    {
        if ( verbose )
        {
            out << "**DOMAIN SURFACE IS (TOPOLOGICALLY) CLOSED" << std::endl;
        }
    }
    else
    {
        sw.create ( "DOMAIN_NOT_CLOSED", true );
        if ( verbose ) err << "WARNING: DOMAIN APPEARS TO HAVE AN OPEN BOUNDARY (TOPOLOGY CHECK)" << std::endl
                               << "Number of inconsistent edges:" << counte << std::endl;
    }



    //-----------------------------------------------------
    //                                    POINTS
    //-----------------------------------------------------

    if (verbose)
    {
        out << "Checking vertexes" << std::endl;
    }
    UInt numVerticesFound = mesh.pointList.countElementsWithFlag (EntityFlags::VERTEX, &Flag::testOneSet);
    if (numVerticesFound != mesh.numVertices() )
    {
        if ( verbose )
        {
            err << "warning: The number of Points with vertex flag on does not coincide with the declared one." << std::endl;
        }
        if (fix)
        {
            if ( verbose )
            {
                err << "It will be fixed now" << std::endl;
            }
            // unset the flag. It will be remade
            for (UInt i = 0; i < mesh.numPoints(); ++i)
            {
                mesh.point (i).unSetFlag (EntityFlags::VERTEX);
            }
            // Find the real vertices and set the flag
            for (UInt i = 0; i < mesh.numElements(); ++i)
                for (UInt j = 0; j < mesh.numLocalVertices(); ++j)
                {
                    ID k = mesh.element (i).point (j).localId();
                    mesh.pointList (k).setFlag (EntityFlags::VERTEX);
                }
            numVerticesFound = mesh.pointList.countElementsWithFlag (
                                   EntityFlags::VERTEX, &Flag::testOneSet);
            mesh.setNumVertices (numVerticesFound);
            UInt numBVerticesFound = mesh.pointList.countElementsWithFlag (
                                         EntityFlags::VERTEX | EntityFlags::PHYSICAL_BOUNDARY, &Flag::testAllSet);
            mesh.setNumBVertices (numBVerticesFound);
            sw.create ( "FIXED_VERTICES_COUNTER", true );
        }
    }

    // Now that boundary faces have been correctly set we may work out
    // boundaty points

    if (fix)
    {
        if (verbose)
        {
            out << "Fix boundary points using boundary faces info" << std::endl;
        }
        MeshUtility::fixBoundaryPoints (mesh, clog, err, verbose);
    }

    MeshUtility::EnquireBPoint<RegionMesh> enquirebpoint ( mesh );

    UInt foundBPoints = mesh.pointList.countElementsWithFlag (EntityFlags::PHYSICAL_BOUNDARY,
                                                              &Flag::testOneSet);
    if (verbose)
    {
        out << "B Points Found " << foundBPoints << std::endl;
    }
    if ( foundBPoints == 0 || foundBPoints < mesh.storedBPoints() )
    {
        if ( verbose )
        {
            err << "ERROR Bpoints indicator not correctly set" << std::endl;
        }
    }
    else
    {
        if ( fix )
        {
            sw.create ( "FIXED_BOUNDARY_POINTS", true );
        }
    }

    // Now that we are sure that (jus) boundary points are flagged as such we check if the marker id is set
    if (verbose)
    {
        out << "Chsck point marker Ids" << std::endl;
    }
    if ( ! MeshUtility::checkIsMarkerSet ( mesh.pointList ) )
    {
        if (verbose)
        {
            err << "Points MARKER id incorrectly set" << std::endl;
        }

        if ( fix )
        {
            if ( verbose )
            {
                err << " Fixing Points Marker ID" << std::endl << "If unset the boundary will inherit the strongest among faces" << std::endl;
            }
            if ( verbose )
            {
                err << " The internal will be set to the domain flag" << std::endl;
            }
            MeshUtility::setBoundaryPointsMarker ( mesh, clog, err, false );
            // fix marker at interior points. It takes
            if ( ! MeshUtility::checkIsMarkerSet ( mesh.pointList ) )
            {
                // Maybe boundary points marker is fine, this is enough
                bool boundaryIsOk (true);
                std::vector<point_Type const*>
                listOfPt = mesh.pointList.extractElementsWithFlag (
                               EntityFlags::PHYSICAL_BOUNDARY, &Flag::testOneSet);
                for (typename std::vector<point_Type const*>::const_iterator
                        it = listOfPt.begin();
                        it < listOfPt.end();
                        ++it)
                {
                    boundaryIsOk = boundaryIsOk | (*it)->isMarkerSet();
                }
                std::vector<point_Type const*>().swap (listOfPt); // save memory
                if ( verbose )
                {
                    clog << " Marker ID on boundary points is fine. Internal points may have marker unset" << std::endl;
                }
                if (verbose)
                {
                    err << "Cannot Fix Points MARKER" << std::endl;
                }
                if ( verbose && boundaryIsOk )
                {
                    err << "But boundary points are fine" << std::endl;
                }
                sw.create ( "POINT_MARKER_UNSET", true );
            }
            else
            {
                if (verbose)
                {
                    err << "FIXED" << std::endl;
                }
                sw.create ( "FIXED_POINT_MARKER", true );
            }
        }
    }


    if ( mesh.storedBPoints() == 0 )
    {
        if ( verbose )
        {
            err << "WARNING B. Points COUNTER incorrectly set" << std::endl;
        }
        if ( fix )
        {
            MeshUtility::setBoundaryPointsCounters ( mesh ) ;
            if ( verbose )
            {
                err << " FIXED" << std::endl;
            }
            sw.create ( "FIXED_BPOINTS_COUNTER", true );
        }
    }

    if ( mesh.numPoints() == 0 )
    {
        if ( verbose )
        {
            err << "WARNING Points Counter unset" << std::endl;
        }
        if ( fix )
        {
            mesh.numPoints() = mesh.storedPoints();
            sw.create ( "FIXED_POINTS_COUNTER", true );
        }
    }

    //-----------------------------------------------------
    //                                   FINAL CHECKS
    //-----------------------------------------------------
    if ( verbose ) out << " ********     COUNTERS CONTENT **********************************" << std::endl

                           << " Num Volumes    : " << mesh.numVolumes() << std::endl
                           << " Num Vertices   : " << mesh.numVertices() << std::endl
                           << " Num B. Vertices: " << mesh.numBVertices() << std::endl
                           << " Num Points     : " << mesh.numPoints() << std::endl
                           << " Num B. Points  : " << mesh.numBPoints() << std::endl
                           << " Num Edges      : " << mesh.numEdges() << std::endl
                           << " Num B. Edges   : " << mesh.numBEdges() << std::endl
                           << " Num Faces      : " << mesh.numFaces() << std::endl
                           << " Num B. Faces   : " << mesh.numBFaces() << std::endl
                           << " ********     END COUNTERS **********************************"
                           << std::endl;

    bool eulok1 = ( 2 * mesh.numFaces() -
                    mesh.numLocalFaces() * mesh.numVolumes() -
                    mesh.numBFaces() ) == 0;

    bool eulok2 ( true );

    if ( RegionMesh::elementShape_Type::S_shape == TETRA )
    {
        if ( verbose )
        {
            out << std::endl << "Checking Euler formulae: ";
        }
        eulok2 = ( mesh.numEdges() -
                   mesh.numVolumes() -
                   mesh.numVertices() -
                   ( 3 * mesh.numBFaces() -
                     2 * mesh.numBVertices() ) / 4 ) == 0;
    }

    if ( ! ( eulok1 && eulok2 ) )
    {
        if ( verbose ) err << "WARNING: The following Euler formula(s) are not satisfied"
                               << std::endl;
        sw.create ( "NOT_EULER_OK" );
    }
    else
    {
        if ( verbose )
        {
            out << std::endl << " ok." << std::endl;
        }
    }

    if ( !eulok1 )
    {
        if ( verbose ) err << "  2*nFaces = nFacesPerVolume*nVolumes + nBoundaryFaces"
                               << std::endl
                               << "  2*" << mesh.numFaces() << " != " << mesh.numLocalFaces()
                               << " * " << mesh.numVolumes() << " + " << mesh.numBFaces()
                               << std::endl;
    }

    if ( !eulok2 )
    {
        if ( verbose ) err << "  nEdges = nVolumes + nVertices + (3*nBoundaryFaces - 2*nBoundaryVertices)/4" << std::endl
                               << "  " << mesh.numEdges() << " != " << mesh.numVolumes() << " + "
                               << mesh.numVertices() << " + (3*" << mesh.numBFaces() << " - 2*"
                               << mesh.numBVertices() << ")/4" << std::endl;
    }

    mesh.setLinkSwitch ( "HAS_BEEN_CHECKED" );

    return true;
}
Example #8
0
static void
check_face (RegionMesh<LinearTetra>& mesh, ID i, ID j)
{
  ID faceId = mesh.localFaceId (i, j);

  if ( (ID) faceId != NotAnId)
  {
    RegionMesh<LinearTetra>::face_Type& face
    = mesh.face (faceId);

    if (0)
    fprintf (stdout, "  face: %5d %5d, ",
        faceId, face.id() );

    ID v0, v1, v2, gv0, gv1, gv2;
    v0 = LinearTetra::faceToPoint (j, 0);
    v1 = LinearTetra::faceToPoint (j, 1);
    v2 = LinearTetra::faceToPoint (j, 2);
    // fprintf(stdout, "[%5d %5d %5d], ", v0, v1, v2);

    gv0 = mesh.element (i).point (v0).id();
    gv1 = mesh.element (i).point (v1).id();
    gv2 = mesh.element (i).point (v2).id();
    fprintf (stdout, "[ %7d %7d %7d ], ", gv0, gv1, gv2);

    int mark = 0;
    if (face.flag() &
        EntityFlags::PHYSICAL_BOUNDARY)
    {
      mark = 1;
    }
    if (face.flag() &
        EntityFlags::SUBDOMAIN_INTERFACE)
    {
      mark += 2;
    }
    fprintf (stdout, "mark: %d, ", mark);

    ID vol0, vol1;
    ID pos0, pos1;
    vol0 = face.firstAdjacentElementIdentity();
    pos0 = face.firstAdjacentElementPosition();
    vol1 = face.secondAdjacentElementIdentity();
    pos1 = face.secondAdjacentElementPosition();

    if (vol0 == NotAnId)
    {
      vol0 = -1;
    }
    if (vol1 == NotAnId)
    {
      vol1 = -1;
    }
    if (pos0 == NotAnId)
    {
      pos0 = -1;
    }
    if (pos1 == NotAnId)
    {
      pos1 = -1;
    }

    fprintf (stdout, "first: %5d %d, second: %5d %d",
        vol0, pos0, vol1, pos1);

    fprintf (stdout, "\n");
  }
  else
  {
    fprintf (stdout, "Invalid face!!!\n");
  }
}