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/)
-   -   call of overloaded ‘exp(double)’ is ambiguous (https://www.cfd-online.com/Forums/openfoam-programming-development/176702-call-overloaded-exp-double-ambiguous.html)

babakflame August 24, 2016 15:56

call of overloaded ‘exp(double)’ is ambiguous
 
Dear Fellows

I am trying to add a variable called rhoE into my createFields.H file and assign a value to it based on location in the grid.

I have added the following lines into my createFields.H file:

Code:

volScalarField yPos = mesh.C().component(vector::Y);
    volScalarField xPos = mesh.C().component(vector::X);

    Info<< "Reading field electric density rhoE\n" << endl;
    volScalarField rhoE
    (
        IOobject
        (
            "rhoE",
            runTime.timeName(),
            mesh,
            IOobject::MUST_READ,
            IOobject::AUTO_WRITE
        ),
        mesh
    );

    forAll(rhoE.internalField(), patchi)
    {
        if (xPos [patchi] < 10)
    {
        rhoE.internalField()[patchi]=exp(-yPos[patchi]);
    }
    else
    {
        rhoE.internalField()[patchi]= 0;
    }
    }

However, after compiling my code, it gives the following error:

Code:

createFields.H: In function ‘int main(int, char**)’:
createFields.H:183:49: error: call of overloaded ‘exp(double)’ is ambiguous
createFields.H:183:49: note: candidates are:
In file included from /usr/include/math.h:69:0,
                from /usr/include/c++/4.7/cmath:46,

Would somebody hint me how can I remove this error?

chegdan August 24, 2016 16:06

Have you tried ?

Code:

        rhoE.internalField()[patchi]=Foam::exp(-yPos[patchi]);
or

Code:

        rhoE.internalField()[patchi]=std::exp(-yPos[patchi]);
if you don't want to use the Foam version.

babakflame August 24, 2016 17:28

Thanks Daniel. It worked.:)

I am trying to do sth similar with a volVectorField in my createFields.H file.

Code:

volVectorField E
    (
        IOobject
        (
            "E",
            runTime.timeName(),
            mesh,
            IOobject::MUST_READ,
            IOobject::AUTO_WRITE
        ),
        mesh
    );
 forAll(E.internalField(), i)
    {
        E.internalField()[i]=(2.e06 0 0);
    }

The product of this volVectorField and previous volScalarField is needed to be added to Momentum equation as a bodyForce.

OF gives me the following error during the compilation of the code:

Code:

createFields.H:248:34: error: expected ‘)’ before numeric constant
createFields.H:248:37: error: no match for ‘operator=’ in ‘(& E.Foam::GeometricField<Type, PatchField, GeoMesh>::internalField<Foam::Vector<double>, Foam::fvPatchField, Foam::volMesh>())->Foam::Field<Foam::Vector<double> >::<anonymous>.Foam::List<Foam::Vector<double> >::<anonymous>.Foam::UList<T>::operator[]<Foam::Vector<double> >(i) = 2.0e+6’
createFields.H:248:37: note: candidate is:
In file included from /home/babak/OpenFOAM/OpenFOAM-2.1.x/src/OpenFOAM/lnInclude/vector.H:39:0,

Would you hint me on this too?

babakflame August 24, 2016 18:13

Dear All

I coded my second problem as follows:

By defining the volVectorField and its volScalarFields components separately and using four loops.
Code:

volVectorField E
    (
        IOobject
        (
            "E",
            runTime.timeName(),
            mesh,
            IOobject::MUST_READ,
            IOobject::AUTO_WRITE
        ),
        mesh
    );

   

        volScalarField Ex
        (
            IOobject
            (
                "Ex",
                runTime.timeName(),
                mesh,
                IOobject::NO_READ,
                IOobject::NO_WRITE
            ),
            mesh
        );

        volScalarField Ey
        (
            IOobject
            (
                "Ey",
                runTime.timeName(),
                mesh,
                IOobject::NO_READ,
                IOobject::NO_WRITE
            ),
            mesh
        );

        volScalarField Ez
        (
            IOobject
            (
                "Ez",
                runTime.timeName(),
                mesh,
                IOobject::NO_READ,
                IOobject::NO_WRITE
            ),
            mesh
        );

    forAll(Ex.internalField(), i)
    {
        Ex.internalField()[i]= 2.0e06;
    }
    forAll(Ey.internalField(), i)
    {
        Ex.internalField()[i]= 0;
    }
    forAll(Ez.internalField(), i)
    {
        Ex.internalField()[i]= 0;
    }

        forAll( E.internalField(), i)
    {
        E.internalField()[i].component(vector::X) = Ex.internalField()[i];
        E.internalField()[i].component(vector::Y) = Ey.internalField()[i];
        E.internalField()[i].component(vector::Z) = Ez.internalField()[i];
    }

Now, the code compiles. However, is there any way to write these lines compactly?

I am not interested in lengthy codes.:D

chegdan August 24, 2016 18:24

try

Code:

volVectorField E
(
    IOobject
    (
        "E",
        runTime.timeName(),
        mesh,
        IOobject::MUST_READ,
        IOobject::AUTO_WRITE
    ),
    mesh,
    dimensionedVector("E", dimless, vector(2.e06, 0, 0))
);

you can change dimless to something else if it has dimensions, like
Code:

    dimensionedVector("E", dimensionSet(0, 1, 0, 0, 0, 0, 0), vector(2.e06, 0, 0))

babakflame August 24, 2016 18:31

Thanks Daniel.:)

I prefer shortened versions every time.

Just another short question:

Since these two volVectorField "E" and volScalarField "rhoE" are initialized from createFields.H and act on internal field (they are not present in Boundary conditions); I don't want to put them in 0 Folder.

So they should be

Code:

runTime.timeName(),
 mesh,
IOobject::NO_READ,
 IOobject::AUTO_WRITE

Am I correct? Because I just want OF to write them down to be checked.

chegdan August 24, 2016 18:51

try it out and see. But with those settings it will not read anything form the zero directory.

babakflame August 24, 2016 19:33

Thanks Daniel for your fast and correct responses.

babakflame August 25, 2016 17:26

Dear Daniel

These fields I introduced in my createFields.H file are internally active fields, so I don't want to define a Boundary condition file in my $Foam_case/0 folder.
I had these lines in my createFields.H file:
Code:

volScalarField rhoE
    (
        IOobject
        (
            "rhoE",
            runTime.timeName(),
            mesh,
            IOobject::NO_READ,
            IOobject::AUTO_WRITE
        ),
        mesh,
    );

    forAll(rhoE.internalField(), i)
    {
        if (xPos [i] > 10.e-06  && xPos [i] < 20.e-06)
    {
        rhoE.internalField()[i]=1e-04*Foam::exp(-yPos[i]);
    }
    else
    {
        rhoE.internalField()[i]= 0;
    }
    }
   
 

    volVectorField E
    (
        IOobject
        (
            "E",
            runTime.timeName(),
            mesh,
            IOobject::NO_READ,
            IOobject::AUTO_WRITE
        ),
        mesh,
    dimensionedVector("E", dimensionSet(1, 1, -3, 0, 0, -1, 0), vector(2.e06, 0, 0))
    );

During running the case, I encountered this error:
rhoE file cannot be found in 0 folder.
So what I did was initializing the rhoE as follows:

Code:

volScalarField rhoE
    (
        IOobject
        (
            "rhoE",
            runTime.timeName(),
            mesh,
            IOobject::NO_READ,
            IOobject::AUTO_WRITE
        ),
        mesh,
    dimensionedScalar("rhoE", dimensionSet(0, -3, 1, 0, 0, 1, 0), scalar(0.0))
    )

Is it correct?

since after Initializing I have introduced a for loop for setting internal values for rhoE?

Right now, this part in my createFields.H file is as follows.


Code:

volScalarField rhoE
    (
        IOobject
        (
            "rhoE",
            runTime.timeName(),
            mesh,
            IOobject::NO_READ,
            IOobject::AUTO_WRITE
        ),
        mesh,
    dimensionedScalar("rhoE", dimensionSet(0, -3, 1, 0, 0, 1, 0), scalar(0.0))
    );

    forAll(rhoE.internalField(), i)
    {
        if (xPos [i] > 10.e-06  && xPos [i] < 20.e-06)
    {
        rhoE.internalField()[i]=1e-04*Foam::exp(-yPos[i]);
    }
    else
    {
        rhoE.internalField()[i]= 0;
    }
    }
    volVectorField E
    (
        IOobject
        (
            "E",
            runTime.timeName(),
            mesh,
            IOobject::NO_READ,
            IOobject::AUTO_WRITE
        ),
        mesh,
    dimensionedVector("E", dimensionSet(1, 1, -3, 0, 0, -1, 0), vector(2.e06, 0, 0))
    );


chegdan August 25, 2016 17:32

Why not take your field you created and output the result and look at the values in ParaView? This will tell you if you are correct or not.

babakflame August 26, 2016 23:55

1 Attachment(s)
Daniel

Many thanks for your hints. Actually, right now I am capable of defining the internalField of two variables "rhoE" and "E" correctly. However, since the rhoE distribution very close to the one of my boundaries are important, I want to extrapolate from internalField to that boundary location and give a value for rhoE on that boundary.
Because If I don't do that, my distribution of rhoE starts form 0 (at the boundary) and then reaches to the internalField value.

In the appended picture, it is evident that the distribution starts from zero and reaches to the internal value.

I have thought sth like this:
Code:


    forAll(rhoE.boundaryField(), i)
    {
        if (xPos [i] > 9.3e-06  && xPos [i] < 18.6e-06 && yPos [i] == 0.0)
    {
        rhoE.boundaryField()[i]= rhoE.boundaryField()[i].internalField();
    }
    else
    {
        rhoE.boundaryField()[i]= 0;
    }
    }

But, gave me the same distribution as appended.
Is there any way to extrapolate the internal field and put it on related boundary inside createFields.H file?

Even , I tried sth like this:

Code:


  forAll(rhoE.boundaryField(), i)
    {
        if (xPos [i] > 9.3e-06  && xPos [i] < 18.6e-06 && yPos [i] == 0.0)
    {
        rhoE.boundaryField()[i]= 21.79  //the value expected on boundary
    }
    else
    {
        rhoE.boundaryField()[i]= 0;
    }
    }

But still at that location OpenFoam sets the boundary value equal to zero. :confused::confused:

babakflame August 27, 2016 00:34

PS: Here I have specified the location of boundary by xPos and yPos as:

Code:

  if (xPos [i] > 9.3e-06  && xPos [i] < 18.6e-06 && yPos [i] == 0.0)
Even I tried this:

Code:

forAll(rhoE.boundaryField(),boundaryI)
    {
      forAll(rhoE.boundaryField()[boundaryI],i)
        {
            if (xPos [i] > 9.3e-06  && xPos [i] < 18.6e-06 && yPos [i] == 0.0)
        {
            rhoE.boundaryField()[boundaryI][i]= 21.79;
        }
        else
        {
            rhoE.boundaryField()[boundaryI][i]= 0;
        }
        }
    }

But still the rhoE at the boundary position where
Code:

xPos [i] > 9.3e-06  && xPos [i] < 18.6e-06 && yPos [i] == 0.0
is equal to zero. (look the picture appended at previous post)

Please somebody tell me why this happens?:confused::confused::confused::confused:


All times are GMT -4. The time now is 20:39.