View Issue Details

IDProjectCategoryView StatusLast Update
0002041OpenFOAMBugpublic2016-04-04 12:53
Reporterwyldckat Assigned Tohenry  
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
PlatformGNU/LinuxOSUbuntuOS Version16.04
Product Versiondev 
Summary0002041: Problems with "isnan" in "src/conversion/ensight/part": C99 vs C++11
DescriptionI was testing building OpenFOAM-dev (commit ac71f86574) with Ubuntu 16.04 and I tripped on this compiler error message:

  ensight/part/ensightPart.C:54:54: error: ‘isnan’ was not declared in this scope
               if (id >= field.size() || isnan(field[id]))

Even though I'm using Ubuntu 16.04 beta, it is using GCC 5.3.1, so I expect that something changed permanently in the build pattern when using "-std=c++0x", given that I don't get this issue with GCC 5.2.1 on Ubuntu 15.10.

Attached is the file "ensightPart.H", to update "src/conversion/ensight/part/ensightPart.H" in OpenFOAM-dev. It adds an "inline isnan" method that will use either the C99 or C++11 definition at build time.

For easier inspection, the patch is shown in the "Additional Information" section below.
Additional Informationdiff --git a/src/conversion/ensight/part/ensightPart.H b/src/conversion/ensight/part/ensightPart.H
index feb6d37..d6e4cd5 100644
--- a/src/conversion/ensight/part/ensightPart.H
+++ b/src/conversion/ensight/part/ensightPart.H
@@ -62,6 +62,16 @@ class ensightPart
         // Static data members
         static const List<word> elemTypes_;
 
+ // wrapper for isnan, namely C99 or C++11
+ inline bool isnan(const scalar value) const
+ {
+ #ifndef isnan
+ return std::isnan(value);
+ #else
+ return ::isnan(value);
+ #endif
+ }
+
 
 protected:
 
TagsNo tags attached.

Activities

wyldckat

2016-04-03 18:14

updater  

ensightPart.H (9,345 bytes)   
/*---------------------------------------------------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     |
    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
     \\/     M anipulation  |
-------------------------------------------------------------------------------
License
    This file is part of OpenFOAM.

    OpenFOAM is free software: you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    for more details.

    You should have received a copy of the GNU General Public License
    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.

Class
    Foam::ensightPart

Description
    Base class for ensightPartCells and ensightPartFaces

SourceFiles
    ensightPart.C
    ensightPartIO.C
    ensightPartTemplates.C

\*---------------------------------------------------------------------------*/

#ifndef ensightPart_H
#define ensightPart_H

#include "ensightFile.H"
#include "ensightGeoFile.H"
#include "typeInfo.H"
#include "labelList.H"
#include "polyMesh.H"
#include "Field.H"
#include "IOPtrList.H"
#include "IOstream.H"

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

namespace Foam
{

/*---------------------------------------------------------------------------*\
                         Class ensightPart Declaration
\*---------------------------------------------------------------------------*/

class ensightPart
{
    // Private data

        // Static data members
        static const List<word> elemTypes_;

        // wrapper for isnan, namely C99 or C++11
        inline bool isnan(const scalar value) const
        {
            #ifndef isnan
            return std::isnan(value);
            #else
            return ::isnan(value);
            #endif
        }


protected:

    // Protected data

        //- Part number
        label number_;

        //- Part name (or description)
        string name_;

        //- Simple labelList with a name
        labelListList elemLists_;

        //- Start offset for elemLists_
        label offset_;

        //- Number of elements in this part
        label size_;

        //- Cell or face data
        bool isCellData_;

        //- Material id (numeric)
        label matId_;

        //- pointField referenced
        const pointField& points_;


    // Protected Classes

        //- Track the points used by the part and map global to local indices
        class localPoints
        {
        public:
            //- Number of points used
            label nPoints;

            //- Map global to local indices
            labelList list;

            //- Null constructor
            localPoints()
            :
                nPoints(0),
                list(0)
            {}

            //- Construct for mesh points
            localPoints(const pointField& pts)
            :
                nPoints(0),
                list(pts.size(), -1)
            {}
        };


    // Protected Member Functions

        //- Reconstruct part characteristics (eg, element types) from Istream
        //  A part reconstructed in this manner can be used when writing fields,
        //  but cannot be used to write a new geometry
        void reconstruct(Istream&);

        //- Check for fully defined fields
        bool isFieldDefined(const List<scalar>&) const;

        //- Write the part header
        void writeHeader(ensightFile&, bool withDescription=false) const;

        //- Write a scalar field for idList
        //  A null reference for idList writes the perNode values
        void writeFieldList
        (
            ensightFile& os,
            const List<scalar>& field,
            const labelUList& idList
        ) const;

        //- Track points used
        virtual localPoints calcLocalPoints() const
        {
            return localPoints();
        }

        //- Write connectivities
        virtual void writeConnectivity
        (
            ensightGeoFile&,
            const word& key,
            const labelUList& idList,
            const labelUList& pointMap
        ) const
        {}


public:

    //- Runtime type information
    TypeName("ensightPart");


    // Constructors

        //- Construct null
        ensightPart();

        //- Construct empty part with number and description
        ensightPart(label partNumber, const string& partDescription);

        //- Construct part with number, description and points reference
        ensightPart
        (
            label partNumber,
            const string& partDescription,
            const pointField& points
        );

        //- Construct as copy
        ensightPart(const ensightPart&);


    // Selectors

        // Declare run-time constructor selection table
        declareRunTimeSelectionTable
        (
            autoPtr,
            ensightPart,
            istream,
            (
                Istream& is
            ),
            (is)
        );

        //- Construct and return clone
        autoPtr<ensightPart> clone() const
        {
            return autoPtr<ensightPart>(new ensightPart(*this));
        };

        //- Reconstruct part characteristics on freestore from Istream
        //  \sa reconstruct
        static autoPtr<ensightPart> New(Istream&);


    //- Destructor
    virtual ~ensightPart();


    // Static members

        virtual const List<word>& elementTypes() const
        {
            return elemTypes_;
        }


    // Access

        //- Number of elements in this part
        label size() const
        {
            return size_;
        }

        //- Represents cell data
        bool isCellData() const
        {
            return isCellData_;
        }

        //- Represents face data
        bool isFaceData() const
        {
            return !isCellData_;
        }

        //- Part number
        label number() const
        {
            return number_;
        }

        //- Part name or description
        const string& name() const
        {
            return name_;
        }

        //- Material id
        label materialId() const
        {
            return matId_;
        }

        //- non-const access to part name or description
        void name(const string& value)
        {
            name_ = value;
        }

        //- non-const access to material id
        void materialId(const label value)
        {
            matId_ = value;
        }

        //- Simple labelList with a name
        const labelListList& elemLists() const
        {
            return elemLists_;
        }

        //- Offset for element ids
        label offset() const
        {
            return offset_;
        }


    // Edit

        //- Renumber elements
        void renumber(const labelUList&);

        //- Write summary information about the object
        bool writeSummary(Ostream&) const;

        //- Write reconstruction information for the object
        bool writeData(Ostream&) const;

        //- Write geometry
        virtual void writeGeometry(ensightGeoFile&) const
        {}

        //- Helper: write geometry given the pointField
        void writeGeometry(ensightGeoFile&, const pointField&) const;

        //- Write scalar field
        //  optionally write data per node
        void writeScalarField
        (
            ensightFile&,
            const List<scalar>& field,
            const bool perNode = false
        ) const;

        //- Write vector field components
        //  optionally write data per node
        void writeVectorField
        (
            ensightFile&,
            const List<scalar>& field0,
            const List<scalar>& field1,
            const List<scalar>& field2,
            const bool perNode = false
        ) const;


        //- Write generalized field components
        //  optionally write data per node
        template<class Type>
        void writeField
        (
            ensightFile&,
            const Field<Type>&,
            const bool perNode = false
        ) const;


    // Member Operators

        //- Disallow default bitwise assignment
        void operator=(const ensightPart&)
        {
            NotImplemented;
        }


    // IOstream Operators

        //- Write data (reconstruction information)
        friend Ostream& operator<<(Ostream&, const ensightPart&);

        //- Write geometry
        friend ensightGeoFile& operator<<(ensightGeoFile&, const ensightPart&);

};


// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

} // End namespace Foam

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

#ifdef NoRepository
    #include "ensightPartTemplates.C"
#endif

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

#endif

// ************************************************************************* //
ensightPart.H (9,345 bytes)   

henry

2016-04-04 08:22

manager   ~0006078

I am using gcc-5.3.1 and not seen this issue so it is something to do with the header files on Ubuntu 16.04. Why is it necessary to create this inline wrapper? Why not simply use

            if (id >= field.size() || std::isnan(field[id]))

wyldckat

2016-04-04 12:25

updater   ~0006080

As far as I can figure out (although I haven't fully tested this yet), the "std::isnan" solution will not work when GCC is not set to use C++11 or similar (namely the "tr1"). This is because "isnan()" was only introduced as a function part of the "std" namespace in the C++11 standard.

When not using the C++11 standard, it will default to the C99 standard which relies on a macro named "isnan". This is the option I suspect is being used by default in your build of GCC 5.3.1. This was why I proposed the wrapper, so that it would cover both scenarios... although the wrapper is assuming that the correct "isnan" is predefined by default.


If you prefer to simply deprecate the reliance on the C99 standard, there are 2 more occurrences of "isnan" in the "ensightPartIO.C" file:

  - Line 66: https://github.com/OpenFOAM/OpenFOAM-dev/blob/master/src/conversion/ensight/part/ensightPartIO.C#L66

  - Line 83: https://github.com/OpenFOAM/OpenFOAM-dev/blob/master/src/conversion/ensight/part/ensightPartIO.C#L83

And that's it. There are no other needs for "isnan" at this moment.

henry

2016-04-04 12:45

manager   ~0006081

I have tested std::isnan with gcc-5.3.1, gcc-4.5.4, clang-3.7.0 and icpc-15.0.3 without any problems so I don't think there is a need for the inline wrapper.
I will make the same change to ensightPartIO.C and close this report; please reopen if further issues with isnan occur.

henry

2016-04-04 12:52

manager   ~0006082

Resolved in OpenFOAM-3.0.x by
commit 9716f15f665cf0579e97b23703183b3db95afaf2
commit ea3490b533b444dd42292c6dec940b03b3313ddc

Resolved in OpenFOAM-dev by
commit 1c97ed7098cc579168d7e58ddefe47af282de0fd
commit 1fbd362faa9a14c99ec13c88ea6863cac68976d9

Issue History

Date Modified Username Field Change
2016-04-03 18:14 wyldckat New Issue
2016-04-03 18:14 wyldckat Status new => assigned
2016-04-03 18:14 wyldckat Assigned To => henry
2016-04-03 18:14 wyldckat File Added: ensightPart.H
2016-04-04 08:22 henry Note Added: 0006078
2016-04-04 12:25 wyldckat Note Added: 0006080
2016-04-04 12:45 henry Note Added: 0006081
2016-04-04 12:52 henry Note Added: 0006082
2016-04-04 12:52 henry Status assigned => resolved
2016-04-04 12:52 henry Fixed in Version => 3.0.x
2016-04-04 12:52 henry Resolution open => fixed