CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   OpenFOAM Programming & Development (https://www.cfd-online.com/Forums/openfoam-programming-development/)
-   -   newbie question - simple pTraits (https://www.cfd-online.com/Forums/openfoam-programming-development/87576-newbie-question-simple-ptraits.html)

ans April 23, 2011 19:46

newbie question - simple pTraits
 
I want to compile the pTraits test routine using just command line e.g.

g++ pTraitsTest.C

I get:

gcc version 4.3.4 20090804 (release) 1 (GCC)

$ g++ pTraitsTest.C
pTraits.H: In instantiation of `Foam::pTraits<double>':
pTraitsTest.C:42: instantiated from here
pTraits.H:52: error: base type `double' fails to be a struct or class type
pTraitsTest.C: In function `int main()':
pTraitsTest.C:42: error: `typeName' is not a member of `Foam::pTraits<double>'
ansayre@ansayre2m4 /cygdrive/d/dev/OpenFOAM/OpenFOAM-1.7.1/gcc/pTraits

I defined WM_DP. What else do I need to do?

wyldckat April 24, 2011 10:19

Greetings Alan,

Newbie? You're using Cygwin! ;)

You need OpenFOAM to be already built under your development environment. If that has already been achieved, simply use this command:
Code:

wmake
It will place the binary in the folder outputted by the following command:
Code:

echo $FOAM_USER_APPBIN
It's not advisable to try and build these OpenFOAM things manually, since they have tons of dependencies!

Best regards,
Bruno

openfoammaofnepo February 5, 2014 11:00

Dear Bruno,

About the pTraits, can we view them as a special scalar or vector? Because now I have met two situations they are used:

1, used in the operations:

Code:

vector omg = 2*ranGen.vector01() - pTraits<vector>::one
2, used in the initialization of some objects

Code:

loc_(pTraits<vector>::zero)
I feel that they are equal to [1 1 1] and [0 0 0]. Right?

wyldckat February 5, 2014 15:20

Hi openfoammaofnepo,

Quote:

Originally Posted by openfoammaofnepo (Post 473584)
About the pTraits, can we view them as a special scalar or vector? Because now I have met two situations they are used:

Honestly, I've got no idea what "pTraits" is. I'll have to investigate about it.
I'll try to have a look into it this coming weekend.

Best regards,
Bruno

openfoammaofnepo February 5, 2014 16:53

Thank you in advance!

wyldckat February 9, 2014 15:38

Hi openfoammaofnepo,

I did a quick search and this is what I've figured out:
  1. pTraits is located in "$FOAM_SRC/OpenFOAM/primitives/pTraits/pTraits.H"
  2. It has this comment/description:
    Code:

    All primitives need a specialised version of this class. The specialised version will normally also require a conversion method.
  3. Template specialization is explained here: http://www.cplusplus.com/doc/tutoria...specialization
  4. In essence, this allows dynamic casting for whatever necessary.
  5. If you have a look into the file "$FOAM_SRC/OpenFOAM/primitives/VectorSpace/products.H", you'll see that this further extends functionality to the pTraits template class, by adding the ability to be able to handle products between 2 other items of the same pTraits template class.
Therefore, the pTraits template class is essential to how OpenFOAM handles mathematical data.


As for the question you asked:
Code:

pTraits<vector>::one
pTraits<vector>::zero

This accesses the global definitions defined at "$FOAM_SRC/OpenFOAM/primitives/Vector/vector/vector.C".

... and I'm a bit lost in the code. I'm not 100% certain, but it either it's for accessing the static definitions of one and zero for vector, or to have access to the mathematical operators wrapped up in pTraits.

Best regards,
Bruno

openfoammaofnepo February 9, 2014 16:00

Thank you very much for your so detailed explanantion. I think I have more understanding after I read your reply for me.

Thank you again!

ngj February 9, 2014 16:48

Good evening,

I will probably not be able to tell the full story, but let me share what I know:

As Bruno says, it is merely a matter of accessing ::zero, ::one, the size (e.g. number of elements) of a given type (etc).

pTraits was (allegedly) introduced in order to handle this smoothly for scalars, because they were previously derived directly from the std:: namespace, i.e. if-sentences were needed to distinguish between scalars and everything else. This caused loss of computational efficiency.

Therefore, pTraits is merely a wrapper class, which unifies access to certain properties for all primitive types.

It is used in the very core of everything, e.g. whenever you compute a gradient of a given field, the following function is called in the grad schemes:

Code:

virtual tmp
        <
            GeometricField
            <typename outerProduct<vector, Type>::type, fvPatchField, volMesh>
        > grad
        (
            const GeometricField<Type, fvPatchField, volMesh>&
        ) const = 0;

Here, the important part is "outerProduct", which is to be found in the file:

Code:

./primitives/VectorSpace/products.H
and the implementation reads:

Code:

template<class arg1, class arg2>
class outerProduct
{
public:

    typedef typename typeOfRank
    <
        typename pTraits<arg1>::cmptType,
        int(pTraits<arg1>::rank) + int(pTraits<arg2>::rank)
    >::type type;
};

This is a nice example, where the pTraits is handy. The gradient operator "simply" raises the rank by one, which is achieved by this, because one of the Type-arguments in the template of the gradient operator is of type vector (rank = 1).

Kind regards,

Niels

openfoammaofnepo August 17, 2015 15:09

Dear ngj,

Thank you so much. Today I met the pTraits in the turbulentInlet.C again. So I had a look at thread again. The codes are as follows:

Code:

        scalar rmsCorr = sqrt(12*(2*alpha_ - sqr(alpha_)))/alpha_;

        patchField =
            (1 - alpha_)*patchField
          + alpha_*
            (
                referenceField_
              + rmsCorr*cmptMultiply
                (
                    randomField - 0.5*pTraits<Type>::one,
                    fluctuationScale_
                )*mag(referenceField_)
            );

So here when patchField is vector (actually it is velocity becase it is a boundary type for velocity), is "pTraits<Type>::one" the vector [1 1 1]?

Thank you so much. OFFO

Quote:

Originally Posted by ngj (Post 474159)
Good evening,

I will probably not be able to tell the full story, but let me share what I know:

As Bruno says, it is merely a matter of accessing ::zero, ::one, the size (e.g. number of elements) of a given type (etc).

pTraits was (allegedly) introduced in order to handle this smoothly for scalars, because they were previously derived directly from the std:: namespace, i.e. if-sentences were needed to distinguish between scalars and everything else. This caused loss of computational efficiency.

Therefore, pTraits is merely a wrapper class, which unifies access to certain properties for all primitive types.

It is used in the very core of everything, e.g. whenever you compute a gradient of a given field, the following function is called in the grad schemes:

Code:

virtual tmp
        <
            GeometricField
            <typename outerProduct<vector, Type>::type, fvPatchField, volMesh>
        > grad
        (
            const GeometricField<Type, fvPatchField, volMesh>&
        ) const = 0;

Here, the important part is "outerProduct", which is to be found in the file:

Code:

./primitives/VectorSpace/products.H
and the implementation reads:

Code:

template<class arg1, class arg2>
class outerProduct
{
public:

    typedef typename typeOfRank
    <
        typename pTraits<arg1>::cmptType,
        int(pTraits<arg1>::rank) + int(pTraits<arg2>::rank)
    >::type type;
};

This is a nice example, where the pTraits is handy. The gradient operator "simply" raises the rank by one, which is achieved by this, because one of the Type-arguments in the template of the gradient operator is of type vector (rank = 1).

Kind regards,

Niels


wyldckat August 18, 2015 12:05

Quote:

Originally Posted by openfoammaofnepo (Post 559917)
is "pTraits<Type>::one" the vector [1 1 1]?

Quick answer: If the template implementation defined for "Type" is "vector", then yes, it should be the vector "(1 1 1)".

openfoammaofnepo August 18, 2015 12:26

Thank you!!

Quote:

Originally Posted by wyldckat (Post 560050)
Quick answer: If the template implementation defined for "Type" is "vector", the yes, it should be the vector "(1 1 1)".


EmadTandis December 15, 2016 09:23

Hi openfoammaofnepo
can you explain about below code:

template<class arg1, class arg2>
class outerProduct
{
public:
typedef typename typeOfRank
<
typename pTraits<arg1>::cmptType,
int(pTraits<arg1>::rank) + int(pTraits<arg2>::rank)
>::type type;
};


All times are GMT -4. The time now is 07:18.