CFD Online Discussion Forums

CFD Online Discussion Forums (http://www.cfd-online.com/Forums/)
-   OpenFOAM Programming & Development (http://www.cfd-online.com/Forums/openfoam-programming-development/)
-   -   Implementation of a new volField (http://www.cfd-online.com/Forums/openfoam-programming-development/77677-implementation-new-volfield.html)

andrea June 30, 2010 09:53

Implementation of a new volField
 
Dear all,
I'm trying to implement a new volField of a new type of VectorField, for example a vector of n elements. This is my workplan:
first of all I should define a new template class of my new type, copying from Vector.H
Code:

class Vector :
    public VectorSpace<Vector<Cmpt>, Cmpt, 3>

and changing 3 in to n.
Then adapting from VectorI.H I define the operations I need.
Next I typedef for scalar (for example) version of the new templated n-Vector, copying from vector.H. Included here there is contiguous.H, can somebody explain what it does, please?
Now I have a primitive type, and I can instantiate a Field, as
Code:

typedef GeometricField<nVector, fvPatchField, volMesh> volNVectorField;
At this point I can add a volNVectorField in the createField.H in the usual way, or am I still missing something?

Hope somebody can help me,
best regards

Andrea

andrea July 2, 2010 04:37

error, undefined reference to ...
 
Ok, when I construct a volNVectorField as usual

Code:

volNVectorField myVolNVectorField
    (
        IOobject
        (
        "goofy",
        runTime.timeName(),
        mesh,
        IOobject::NO_READ,
        IOobject::AUTO_WRITE
        ),
        mesh
    );

this error appears first:

Code:

undefined reference to `Foam::calculatedFvPatchField<Foam::NVector<double> >::typeName'                       
Make/linuxGccDPOpt/mySolver.o: In function `Foam::fvPatchField<Foam::NVector<double> >::type() const':                                   
mySolver.C:(.text._ZNK4Foam12fvPatchFieldINS_7NVectorIdEEE4typeEv[Foam::fvPatchField<Foam::NVector<double> >::type() const]+0x11): undefined reference to `Foam::fvPatchField<Foam::NVector<double> >::typeName''

Does anybody have any clue?

Best regards
Andrea

deepsterblue July 2, 2010 08:09

You're probably getting the error because the default patch type for a GeometricField is the calculated type. During template instantiation, the compiler looks for a calculated patchField type which (in your case) should be a templated patchField for 'nVector'.

Take a look at the makeFvPatchField() macros, and that should give you some direction. It does seem a little odd that you would want to customize a vectorSpace definition - do the current ones not fit your needs?

andrea July 5, 2010 11:44

It compiles but solver crashes
 
Hi,
thanks deepsterblue, yes the vector spaces already defined in OF are barely all we need. But in my calculation I need to store a n number of data on the patch surface that are function of other fields, I would like to access these data and manipulate them as an ordinary volField (read and write them for example). I thought that a volNVectorField could fit my needs. If anybody as a clever idea, please share.

Now I'm able to define a nvector now, plus a volNVectorField as

Code:

volNVectorField myNVectorField
    (
        IOobject
        (
        "myNVectorField",
        runTime.timeName(),
        mesh,
        IOobject::NO_READ,
        IOobject::NO_WRITE
        ),
        mesh,
        dimensionSet(0,0,0,0,0,0,0),
        "fixedValue"
    );

the two lines at the bottom is my way around the problem I still got about the calculatedFvPatchField. Now the code compiles, but when I run the case I get a segmentation fault I cannot understand:


Code:

#0  Foam::error::printStack(Foam::Ostream&) in "/home/andrea/OpenFOAM/OpenFOAM-1.6/lib/linuxGccDPOpt/libOpenFOAM.so"
#1  Foam::sigSegv::sigSegvHandler(int) in "/home/andrea/OpenFOAM/OpenFOAM-1.6/lib/linuxGccDPOpt/libOpenFOAM.so"
#2  Uninterpreted:
#3  Foam::fvPatchField<Foam::NVector<double> >::New(Foam::word const&, Foam::fvPatch const&, Foam::DimensionedField<Foam::NVector<double>, Foam::volMesh> const&) in "/home/andrea/OpenFOAM/OpenFOAM-1.6/applications/bin/linuxGccDPOpt/mySolver"
#4  Foam::GeometricField<Foam::NVector<double>, Foam::fvPatchField, Foam::volMesh>::GeometricBoundaryField::GeometricBoundaryField(Foam::fvBoundaryMesh const&, Foam::DimensionedField<Foam::NVector<double>, Foam::volMesh> const&, Foam::word const&) in "/home/andrea/OpenFOAM/OpenFOAM-1.6/applications/bin/linuxGccDPOpt/mySolver"
#5  Foam::GeometricField<Foam::NVector<double>, Foam::fvPatchField, Foam::volMesh>::GeometricField(Foam::IOobject const&, Foam::fvMesh const&, Foam::dimensionSet const&, Foam::word const&) in "/home/andrea/OpenFOAM/OpenFOAM-1.6/applications/bin/linuxGccDPOpt/mySolver"
#6  main in "/home/andrea/OpenFOAM/OpenFOAM-1.6/applications/bin/linuxGccDPOpt/mySolver"
#7  __libc_start_main in "/lib/tls/i686/cmov/libc.so.6"
#8  _start in "/home/andrea/OpenFOAM/OpenFOAM-1.6/applications/bin/linuxGccDPOpt/mySolver.C"
Segmentation fault

do you have any hint about this, please?
Andrea

deepsterblue July 6, 2010 09:38

Not a very useful stack trace... Compile your libraries in debug, and set FOAM_ABORT to true. This should give you the exact line where the seg-fault occurs..

andrea July 7, 2010 09:18

Some improvements but stopped again
 
Thanks for the hint,
I added these lines to my solver
Code:

typedef fvPatchField<nvector> fvPatchNVectorField;
makeFvPatchField(fvPatchNVectorField)

typedef calculatedFvPatchField<nvector> calculatedFvPatchNVectorField;
defineTemplateTypeNameAndDebug(calculatedFvPatchNVectorField, 0);

typedef  DimensionedField<nvector, volMesh> DimensionedNVectorField;
typedef  GeometricField<nvector, fvPatchField, volMesh> volNVectorField;

defineTemplateTypeNameAndDebug(volNVectorField::DimensionedInternalField, 0);
defineTemplateTypeNameAndDebug(volNVectorField, 0);

I can create this object

Code:

DimensionedNVectorField myDimNVectorField(
        IOobject
        (
        "myDimNVectorField",
        runTime.timeName(),
        mesh,
        IOobject::NO_READ,
        IOobject::NO_WRITE
        ),
        mesh,
        dimensionSet(0,0,1,0,0,0,0)     
        );

But I cannot create the volNVectorField.
If I leave the default "calculated", the debug mode gives me a printStack

Code:

#0  Foam::error::printStack(Foam::Ostream&) in "/home/andrea/OpenFOAM/OpenFOAM-1.6/lib/linuxGccDPOpt/libOpenFOAM.so"
#1  Foam::sigSegv::sigSegvHandler(int) in "/home/andrea/OpenFOAM/OpenFOAM-1.6/lib/linuxGccDPOpt/libOpenFOAM.so"
#2  Uninterpreted:
#3  Foam::HashTable<Foam::tmp<Foam::fvPatchField<Foam::NVector<double> > > (*)(Foam::fvPatch const&, Foam::DimensionedField<Foam::NVector<double>,Foam::volMesh> const&), Foam::word, Foam::string::hash>::find(Foam::word const&) at ~/OpenFOAM/OpenFOAM-1.6/src/OpenFOAM/lnInclude/HashTable.C:177
#4  Foam::fvPatchField<Foam::NVector<double> >::New(Foam::word const&, Foam::fvPatch const&, Foam::DimensionedField<Foam::NVector<double>, Foam::volMesh> const&) at ~/OpenFOAM/OpenFOAM-1.6/src/finiteVolume/lnInclude/newFvPatchField.C:46
#5  GeometricBoundaryField at ~/OpenFOAM/OpenFOAM-1.6/src/OpenFOAM/lnInclude/GeometricBoundaryField.C:56
#6  GeometricField at ~/OpenFOAM/OpenFOAM-1.6/src/OpenFOAM/lnInclude/GeometricField.C:201
#7  main at ~/OpenFOAM/andrea-1.6/Myapplications/solvers/mySolver/AndreaMassFlowBC/mySolver.C:97
#8  __libc_start_main in "/lib/tls/i686/cmov/libc.so.6"
#9  _start in "/home/andrea/OpenFOAM/OpenFOAM-1.6/applications/bin/linuxGccDPOpt/mySolver"
Segmentation fault

Of course something is wrong about the fvPatchField, but I cannot understand how I should define the calculatedFvPatchNVectorField, below I show the where the code breakes:

Code:

// GeometricField.C:201
  boundaryField_(mesh.boundary(), *this, patchFieldType)
{
    if (debug) // error
    {
        Info<< "GeometricField<Type, PatchField, GeoMesh>::GeometricField : "
              "creating temporary"
            << endl << this->info() << endl;
    }

    readIfPresent();
}
// GeometricBoundaryField.C 56
forAll(bmesh_, patchi)
    {
        set  // error
        (
            patchi,
            PatchField<Type>::New
            (
                patchFieldType,
                bmesh_[patchi],
                field
            )
        );

// newFvPatchField.C:46
typename patchConstructorTable::iterator cstrIter =
        patchConstructorTablePtr_->find(patchFieldType); // error

// HashTable.C:177

 if (nElmts_) // error
    {
        const label hashIdx = hashKeyIndex(key);

        for (hashedEntry* ep = table_[hashIdx]; ep; ep = ep->next_)
        {
            if (key == ep->key_)
            {
                return iterator(*this, ep, hashIdx);
            }
        }
    }

I'm really dizzy about this now, hope for your suggestions
Andrea

deepsterblue July 7, 2010 10:30

You might want to check whether the calculated type is added to the run-time selection tables during the run. If I'm not mistaken, initializing the volField with a wrong patchField type (like bananaFvPatchNVectorField, for instance :P) should give you the list of possible types.

andrea July 8, 2010 11:03

Thanks again,
I really appreciate your help.
I've checked, I initiated the volField to be MUST_READ than I try different type in the first boundaryField patch. For any type of patch, banana, fixedValue and even if I leave it blank as "patchName {type ; }", I get the same error message.
If I drop also "type" it complains about that is missing.
I'm running out of ideas but for the following:
what would you think of implementing the same stuff into the OF libraries? This sounds as a sort of last call to me...

Andrea

andrea July 9, 2010 05:17

Let's cross fingers, knock on wood etc.
maybe I found a way out, stay tuned!

Andrea

andrea July 9, 2010 08:45

calculatedFvPatchNVectorField ok but...
 
Hi,
good new first. Adding these lines

Code:

typedef calculatedFvPatchField<nvector> calculatedFvPatchNVectorField;
makePatchTypeField
(
    fvPatchNVectorField,
    calculatedFvPatchNVectorField
);

finally I can initialise the volNVectorField.
Bad new now. At the moment I get only one patchField Type available

Code:

Unknown patchField type fixedValue for patch type patch

Valid patchField types are :

1
(
calculated
)

Now I'm trying to addToRunTimeSelectionTable also a fixedValue patch. Following the same procedure I get

Code:

/home/andrea/OpenFOAM/OpenFOAM-1.6/src/finiteVolume/lnInclude/fixedValueFvPatchField.C: In member function ‘Foam::tmp<Foam::Field<Type> > Foam::fixedValueFvPatchField<Type>::gradientInternalCoeffs() const [with Type = Foam::NVector<double>]’:
andreaMassFlowBC.C:293:  instantiated from here
/home/andrea/OpenFOAM/OpenFOAM-1.6/src/finiteVolume/lnInclude/fixedValueFvPatchField.C:121: error: conversion from ‘Foam::tmp<Foam::Field<Foam::Vector<double> > >’ to non-scalar type ‘Foam::tmp<Foam::Field<Foam::NVector<double> > >’ requested
/home/andrea/OpenFOAM/OpenFOAM-1.6/src/OpenFOAM/lnInclude/FieldFunctions.C: In function ‘void Foam::outer(Foam::Field<typename Foam::outerProduct<Form, Type>::type>&, const Foam::VectorSpace<Form, Cmpt, nCmpt>&, const Foam::UList<Type>&) [with Form = Foam::NVector<double>, Cmpt = double, int nCmpt = 10, Type = double]’:
/home/andrea/OpenFOAM/OpenFOAM-1.6/src/OpenFOAM/lnInclude/FieldFunctions.C:693:  instantiated from ‘Foam::tmp<Foam::Field<typename Foam::outerProduct<Form, Type>::type> > Foam::operator*(const Foam::VectorSpace<Form, Cmpt, nCmpt>&, const Foam::UList<Type>&) [with Form = Foam::NVector<double>, Cmpt = double, int nCmpt = 10, Type = double]’
/home/andrea/OpenFOAM/OpenFOAM-1.6/src/finiteVolume/lnInclude/fixedValueFvPatchField.C:121:  instantiated from ‘Foam::tmp<Foam::Field<Type> > Foam::fixedValueFvPatchField<Type>::gradientInternalCoeffs() const [with Type = Foam::NVector<double>]’
andreaMassFlowBC.C:293:  instantiated from here
/home/andrea/OpenFOAM/OpenFOAM-1.6/src/OpenFOAM/lnInclude/FieldFunctions.C:693: error: no match for ‘operator=’ in ‘*(Foam::outer(Foam::Field<typename Foam::outerProduct<Form, Type>::type>&, const Foam::VectorSpace<Form, Cmpt, nCmpt>&, const Foam::UList<Type>&) [with Form = Foam::NVector<double>, Cmpt = double, int nCmpt = 10, Type = double]::productType*)(f1P ++) = Foam::operator*(const Foam::VectorSpace<Form, Cmpt, nCmpt>&, Foam::scalar) [with Form = Foam::NVector<double>, Cmpt = double, int nCmpt = 10]((*(const double*)(f2P ++)))’
/home/andrea/OpenFOAM/OpenFOAM-1.6/src/OpenFOAM/lnInclude/Vector.H:62: note: candidates are: Foam::Vector<double>& Foam::Vector<double>::operator=(const Foam::Vector<double>&)
make: *** [Make/linuxGccDPOpt/andreaMassFlowBC.o] Error 1

Seems to me that some operator needs to be specialized for nvector types, am I right?
But, since I don't need to add this volNVectorField to any fvMatrix should I better re-implement a fixedValueNVecor patch re-defining
- valueInternalCoeffs
- valueBoundaryCoeffs
- gradientInternalCoeffs
- gradientBoundaryCoeffs
?
I just need a calculated type, and a type that let me to modify runtime through updateCoeffs() the values of my volField, maybe can I derive it from calculated, is it a good idea?
Andrea

deepsterblue July 12, 2010 17:18

Looks like you're running into vector-space issues involving tensorial products. Why use updateCoeffs to update boundary patch values? Couldn't you just use (pseudocode):

field.boundaryField()[patch] = Field<nVector>(patch.size());

I think a calculated type should be just fine, particularly if you're not looking to solve anything on it.

andrea July 14, 2010 10:26

succeed
 
Ok,
my last post on this just to thanks Deepsterblue for the precious help.

I succeed in developing also a boundary condition-like (it does not update any coefficients) but implementing the code I need in the updateCoeffs() I take advantage of all the OF machinery in order to manage data.

:)

Bye
Andrea


All times are GMT -4. The time now is 16:42.