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/)
-   -   volScalarField to volVectorField (https://www.cfd-online.com/Forums/openfoam-programming-development/157266-volscalarfield-volvectorfield.html)

syavash July 24, 2015 06:23

volScalarField to volVectorField
 
Dear Foamers,

I have three volScalarField namely: avgUx, avgUy, and avgUz as follows in the code:

Code:

volScalarField avgUx
    (
    IOobject
    (
        "avgUx",
        runTime.timeName(),
        mesh,
        IOobject::NO_READ,
        IOobject::AUTO_WRITE
    ),
        mesh,
        dimensionedScalar("avgUx", dimVelocity, 0.0)
    );
 
    volScalarField avgUy
    (
    IOobject
    (
        "avgUy",
        runTime.timeName(),
        mesh,
        IOobject::NO_READ,
        IOobject::AUTO_WRITE
    ),
        mesh,
        dimensionedScalar("avgUy", dimVelocity, 0.0)
    );

    volScalarField avgUz
    (
    IOobject
    (
        "avgUz",
        runTime.timeName(),
        mesh,
        IOobject::NO_READ,
        IOobject::AUTO_WRITE
    ),
        mesh,
        dimensionedScalar("avgUz", dimVelocity, 0.0)
    );

Each of these volScalarField variables takes value, e.g. avgUx something like this:


Code:

scalarField spanavgUMeanX
    (
        meshIndexing.collapse(UMean.component(vector::X)())
    );
   
    avgUx.internalField() = spanavgUMeanX;
    avgUx.write();

Now, I need to construct a volVectorField from these scalars, but I do not know the right syntax. I am beginner in OF, so please help me to write this code.

Thanks,
Syavash

syavash July 26, 2015 02:55

Well, I have tried to construct a volVectorField from aforementioned volScalarField using the following block:

Code:

volVectorField Uvec
    (
    IOobject
    (
        "Uvec",
        runTime.timeName(),
        mesh,
        IOobject::NO_READ,
        IOobject::AUTO_WRITE
    ),
        mesh,
        dimensionedVector("Uvec",dimVelocity,vector(avgUx,avgUy,avgUz))
    );

but when compiling the code, the following error message appears:

Code:

In file included from postSpanwiseAverage.C:82:0:
collapse.H: In function ‘int main(int, char**)’:
collapse.H:128:70: error: no matching function for call to ‘Foam::Vector<double>::Vector(Foam::volScalarField&, Foam::volScalarField&, Foam::volScalarField&)’
        dimensionedVector("Uvec",dimVelocity,vector(avgUx,avgUy,avgUz))
                                                                      ^
collapse.H:128:70: note: candidates are:
In file included from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/Vector.H:153:0,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/vector.H:39,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/point.H:35,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/pointField.H:35,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/edge.H:40,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/edgeList.H:32,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/primitiveMesh.H:54,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/polyMesh.H:45,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/finiteVolume/lnInclude/fvMesh.H:50,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/finiteVolume/lnInclude/fvCFD.H:7,
                from postSpanwiseAverage.C:33:
/home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/VectorI.H:56:8: note: Foam::Vector<Cmpt>::Vector(Foam::Istream&) [with Cmpt = double]
 inline Vector<Cmpt>::Vector(Istream& is)
        ^
/home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/VectorI.H:56:8: note:  candidate expects 1 argument, 3 provided
/home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/VectorI.H:47:8: note: Foam::Vector<Cmpt>::Vector(const Cmpt&, const Cmpt&, const Cmpt&) [with Cmpt = double]
 inline Vector<Cmpt>::Vector(const Cmpt& vx, const Cmpt& vy, const Cmpt& vz)
        ^
/home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/VectorI.H:47:8: note:  no known conversion for argument 1 from ‘Foam::volScalarField {aka Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh>}’ to ‘const double&’
In file included from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/vector.H:39:0,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/point.H:35,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/pointField.H:35,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/edge.H:40,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/edgeList.H:32,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/primitiveMesh.H:54,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/polyMesh.H:45,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/finiteVolume/lnInclude/fvMesh.H:50,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/finiteVolume/lnInclude/fvCFD.H:7,
                from postSpanwiseAverage.C:33:
/home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/Vector.H:100:16: note: template<class Cmpt2> Foam::Vector<Cmpt>::Vector(const Foam::VectorSpace<Foam::Vector<Cmpt2>, Cmpt2, 3>&)
        inline Vector(const VectorSpace<Vector<Cmpt2>, Cmpt2, 3>&);
                ^
/home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/Vector.H:100:16: note:  template argument deduction/substitution failed:
In file included from postSpanwiseAverage.C:82:0:
collapse.H:128:70: note:  ‘Foam::volScalarField {aka Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh>}’ is not derived from ‘const Foam::VectorSpace<Foam::Vector<Cmpt>, Cmpt, 3>’
        dimensionedVector("Uvec",dimVelocity,vector(avgUx,avgUy,avgUz))
                                                                      ^
In file included from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/Vector.H:153:0,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/vector.H:39,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/point.H:35,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/pointField.H:35,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/edge.H:40,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/edgeList.H:32,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/primitiveMesh.H:54,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/polyMesh.H:45,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/finiteVolume/lnInclude/fvMesh.H:50,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/finiteVolume/lnInclude/fvCFD.H:7,
                from postSpanwiseAverage.C:33:
/home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/VectorI.H:34:8: note: Foam::Vector<Cmpt>::Vector() [with Cmpt = double]
 inline Vector<Cmpt>::Vector()
        ^
/home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/VectorI.H:34:8: note:  candidate expects 0 arguments, 3 provided
In file included from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/vector.H:39:0,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/point.H:35,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/pointField.H:35,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/edge.H:40,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/edgeList.H:32,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/primitiveMesh.H:54,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/polyMesh.H:45,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/finiteVolume/lnInclude/fvMesh.H:50,
                from /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/finiteVolume/lnInclude/fvCFD.H:7,
                from postSpanwiseAverage.C:33:
/home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/Vector.H:58:7: note: Foam::Vector<double>::Vector(const Foam::Vector<double>&)
 class Vector
      ^
/home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/Vector.H:58:7: note:  candidate expects 1 argument, 3 provided
make: *** [Make/linux64GccDPOpt/postSpanwiseAverage.o] Error 1

I have also tried different combinations but with no success.
Any kind of help is highly appreciated

Syavash

syavash July 28, 2015 08:03

Anyone willing to help??!

Thanks.

klilla July 28, 2015 11:49

See this tread:

http://www.cfd-online.com/Forums/ope...ctorfield.html

Best,
Lilla

danny123 July 29, 2015 04:13

You can access the individual carthesian coordinates of a volume vector field directly. I think it is something like U[cellI].x or something similar. Just try it out. Then you formulate a ForAll loop and overwrite them. The access of individual memeber of your volume scalar field is even more simple, just avgUx[cellI] is the value of cellI member of avgUx.

Regards,

Daniel

Henning86 July 29, 2015 04:17

tmp< GeometricField< cmptType,
PatchField, GeoMesh > > component (const direction) const Return a component of the field. More...

try:

volVectorField FieldName.component (const direction) const

syavash July 30, 2015 08:58

@ Lilla
I tried something like this:

Code:

volVectorField Uvec
    (
    IOobject
    (
        "Uvec",
        runTime.timeName(),
        mesh,
        IOobject::NO_READ,
        IOobject::AUTO_WRITE
    ),
        mesh,
        dimensionedVector
        (
                "Uvec",
                dimVelocity,
                vector::zero         
        )       
    );
   
        Uvec.internalField().component(vector::X)=avgUx.internalField();
        Uvec.internalField().component(vector::Y)=avgUy.internalField();
        Uvec.internalField().component(vector::Z)=avgUz.internalField();

It compiled properly but I get a runtime error:

Code:

FOAM FATAL ERROR:
attempted to assign to a const reference to constant object of type N4Foam5FieldIdEE

    From function Foam::tmp<T>::operator=(const tmp<T>&)
    in file /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/tmpI.H at line 306.

FOAM aborting

#0  Foam::error::printStack(Foam::Ostream&) at ??:?
#1  Foam::error::abort() at ??:?
#2 
 at ??:?
#3  __libc_start_main in "/lib/x86_64-linux-gnu/libc.so.6"
#4 
 at ??:?
Aborted (core dumped)

Any Idea??!

@Henning86:

Thanks for your reply. I know the difference between sclalarfield, volScalarField, and volVectorField but I am not really an OF programmer!
Could you be more specific regarding my case?!!
What syntax should I use? A simple example is highly appreciated.

Henning86 July 30, 2015 09:09

This function only allows only to get the compoenents in each direction.

attempted to assign to a const reference to constant object of type

Hadn't seen this:


The function you are looking for is:

http://foam.sourceforge.net/docs/cpp/a00911.html

void replace (const direction, const GeometricField< cmptType, PatchField, GeoMesh > &)

void replace (const direction, const dimensioned< cmptType > &)

kmou December 2, 2016 11:29

Quote:

Originally Posted by syavash (Post 557664)
@ Lilla
I tried something like this:

Code:

volVectorField Uvec
    (
    IOobject
    (
        "Uvec",
        runTime.timeName(),
        mesh,
        IOobject::NO_READ,
        IOobject::AUTO_WRITE
    ),
        mesh,
        dimensionedVector
        (
                "Uvec",
                dimVelocity,
                vector::zero         
        )       
    );
   
        Uvec.internalField().component(vector::X)=avgUx.internalField();
        Uvec.internalField().component(vector::Y)=avgUy.internalField();
        Uvec.internalField().component(vector::Z)=avgUz.internalField();

It compiled properly but I get a runtime error:

Code:

FOAM FATAL ERROR:
attempted to assign to a const reference to constant object of type N4Foam5FieldIdEE

    From function Foam::tmp<T>::operator=(const tmp<T>&)
    in file /home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude/tmpI.H at line 306.

FOAM aborting

#0  Foam::error::printStack(Foam::Ostream&) at ??:?
#1  Foam::error::abort() at ??:?
#2 
 at ??:?
#3  __libc_start_main in "/lib/x86_64-linux-gnu/libc.so.6"
#4 
 at ??:?
Aborted (core dumped)

Any Idea??!
.

Hi Syavash, I am doing exactly this, but I was wondering if you know how to solve this problem, given the answer below (the link does not work anymore), you used the function void replace?
Thank you for any help. :)

Henning86 December 2, 2016 11:59

The component function is not meant to set the internalfield. Try:

Code:

Uvec.internalField().replace(vector::X,avgUx.internalField());
Sry cant test it written with the phone

kmou December 2, 2016 12:20

Quote:

Originally Posted by Henning86 (Post 627989)
The component function is not meant to set the internalfield. Try:

Code:

Uvec.internalField().replace(vector::X,avgUx.internalField());
Sry cant test it written with the phone

Thank you very much for your prompt reply, which did the trick! :D


And if I understood correctly, OpenFOAM cannot store surfaceVectorFields in the time folders? It has to be a mesh-element value of voLVectorField

shanvach September 27, 2018 16:05

Can't convert volScalar Field to volScalarField
 
Hi all,

I am trying to edit twoPhaseEulerFoam solver by introducing another force in the momentum equation.Below is the UEqns.H file that I am editing.The bold part is what I am introducing in the code. However the third bolded line where I introduce volVectorField it gives me an error saying

"error: conversion from ‘Foam::volScalarField {aka Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh>}’ to non-scalar type ‘Foam::volVectorField {aka Foam::GeometricField<Foam::Vector<double>, Foam::fvPatchField, Foam::volMesh>}’ requested
volVectorField FV = (KA,KA,KA);
"

How do I introduce the scalar in the volScalarField into volVectorField?

Your help in this matter is greatly appreciated.

Thanks and Regards,


Code:

Info<< "Constructing momentum equations" << endl;

MRF.correctBoundaryVelocity(U1);
MRF.correctBoundaryVelocity(U2);
MRF.correctBoundaryVelocity(U);

fvVectorMatrix U1Eqn(U1, rho1.dimensions()*U1.dimensions()*dimVol/dimTime);
fvVectorMatrix U2Eqn(U2, rho2.dimensions()*U2.dimensions()*dimVol/dimTime);


volTensorField grU_1 = fvc::grad(U1);
volScalarField KA = grU_1 && (grU_1 + grU_1.T());
volVectorField FV = (KA,KA,KA);


volScalarField Kd(fluid.Kd());

{
    volScalarField Vm(fluid.Vm());

    {
        U1Eqn =
        (
            fvm::ddt(alpha1, rho1, U1) + fvm::div(alphaRhoPhi1, U1)
          - fvm::Sp(contErr1, U1)
          + MRF.DDt(alpha1*rho1 + Vm, U1)
          + phase1.turbulence().divDevRhoReff(U1)
        ==
          - Vm
          *(
                fvm::ddt(U1)
              + fvm::div(phi1, U1)
              - fvm::Sp(fvc::div(phi1), U1)
              - DDtU2
            )
          + fvOptions(alpha1, rho1, U1)
        );
        U1Eqn.relax();
        U1Eqn += fvm::Sp(Kd, U1);
        fvOptions.constrain(U1Eqn);
        U1.correctBoundaryConditions();
        fvOptions.correct(U1);
    }


Tobi September 28, 2018 02:44

Hi,

what you are trying to do is not possible.
The easiest way is to do it somehow like that:

Code:

volVectorField yourField
(
    IOobject
    (
        "tmp",
        ...,
        mesh,
        IOobject::NO_READ,
        IOobject::AUTO_READ
    ),
    mesh,
    dimensionedVector("tmp", dimensionSet(...), vector(0,0,0)),
    "zeroGradient" // what you need; you can use a wordList too
);

forAll(yourField, cellI)
{
    yourField[cellI][0] = KA[cellI][0];
    yourField[cellI][1] = KA[cellI][1];
    ...
}

Of course, there are other possibilities, but this one is the one coming into my mind first. I guess there should be faster ways. To give some feedback to your code:

Code:

volVectorField FV = (KA,KA,KA);
You try to assign a non-defined field - in the sense of c++ - (KA, KA, KA) to a volVectorField. The problem is that the volVectorField operator== cannot handle such assignments and it does not make sense to implement it. Another possibility would be to do it like that:

Code:

volVectorField yourField = U; // copy of the field

forAll(yourField, cellI)
{
    yourField[cellI][0] = KA[cellI][0];
    yourField[cellI][1] = KA[cellI][1];
    ...
}

By the way. Please use code tags for keeping the text clear.

danny123 September 28, 2018 05:22

Hi shanvach,

In OF, the fvVectorMatrix is a special object, which describes a linear equation system consisting of a scalar matrix, an unknown vector field and a source term. You cannot just multiply the terms by something.

The structure of that operation is that each of those terms (fvm:... etc) does a specific operation to add or assign values to the matrix coefficients or the source term. So, you have to include your mutiplier to each of those component by respecting what kind of field term is asked for. For a scalar field multiplied to the temporal derivative, you somewhat have already have the syntax in the upper part of your code:

Code:

fvm::ddt(alpha1, U1)
alpha1 is a scalar field and you can replace to any other volScalarField to your liking.
For the source term, the code is:

Code:

fvm::Sp(fvc::div(phi1), U1)
You can replace fvc::div(phi1) by any volScalarField.

The tricky part is:

Code:

fvm::div(phi1, U1)
phi1 is a surfaceScalarField. Basically U1 is interpolated to the faces and the contributions are added to the diagonal and off-diagonal parts of the matrix equation using weight factors. If you mutiply by a volScalarField, the multiplier is not face symmetric anymore. This is out of the scope of OF, I think. What you can do is to build your own fvm object. You just copy one the existing ones that seems close, modify it and define it in fvm.H. Then you compile the work in src/finitVolume. You then can call the object in your application solver.

Just be aware: this is a little work to do and you have to spend some time understanding the structure of fvm objects.

Regards,

Daniel

Tobi September 28, 2018 08:21

Quote:

Originally Posted by danny123 (Post 708067)
Hi shanvach,

In OF, the fvVectorMatrix is a special object, which describes a linear equation system consisting of a scalar matrix, an unknown vector field and a source term. You cannot just multiply the terms by something.

The structure of that operation is that each of those terms (fvm:... etc) does a specific operation to add or assign values to the matrix coefficients or the source term. So, you have to include your mutiplier to each of those component by respecting what kind of field term is asked for. For a scalar field multiplied to the temporal derivative, you somewhat have already have the syntax in the upper part of your code:

Code:

fvm::ddt(alpha1, U1)
alpha1 is a scalar field and you can replace to any other volScalarField to your liking.
For the source term, the code is:

Code:

fvm::Sp(fvc::div(phi1), U1)
You can replace fvc::div(phi1) by any volScalarField.

The tricky part is:

Code:

fvm::div(phi1, U1)
phi1 is a surfaceScalarField. Basically U1 is interpolated to the faces and the contributions are added to the diagonal and off-diagonal parts of the matrix equation using weight factors. If you mutiply by a volScalarField, the multiplier is not face symmetric anymore. This is out of the scope of OF, I think. What you can do is to build your own fvm object. You just copy one the existing ones that seems close, modify it and define it in fvm.H. Then you compile the work in src/finitVolume. You then can call the object in your application solver.

Just be aware: this is a little work to do and you have to spend some time understanding the structure of fvm objects.

Regards,

Daniel

Dear Daniel,

maybe I missed the point when one was starting to talk about fvMatrix class, but shanvach was actually asking for the bold lines in his code?

danny123 September 28, 2018 10:13

Dear Tobi,

You are correct. I should read the question more carefully. But the code further below will not work, I think. This popped up immediately when I read it.

Regards,

Daniel

Tobi September 28, 2018 13:23

Hi,


you are right too. I stopped reading the code after I reached the bolded lines; its a matter of available time I have. However, your answer is of benefit too based on the missing matrix definition. :)


All times are GMT -4. The time now is 13:37.