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/)
-   -   If statement in OpenFoam (https://www.cfd-online.com/Forums/openfoam-programming-development/171611-if-statement-openfoam.html)

upuli May 12, 2016 01:25

If statement in OpenFoam
 
dear members
I want to add an if statement to an OpenFOAM solver. There's a variable gastotalmass. If this variable(gastotalmass) is not equal to 0.0 the other variables will be calculated.It is written in the programme as below.

{
if (gastotalmass=0.0)
{

volScalarField YCO
(
"YCO",
mCO/(mCO+mCO2+mCH4+mH2+mH2O+mN2+mO2)
);

}
else
{
volScalarField YCO = 0.0
}
}
but I get the following error

variables.H:31:21: error: could not convert ‘gastotalmass.Foam::GeometricField<Type, PatchField, GeoMesh>::operator= [with Type = double, PatchField = Foam::fvPatchField, GeoMesh = Foam::volMesh]((* & Foam::dimensioned<double>((* &0.0))))’ from ‘void’ to ‘bool’
variables.H:72:22: error: conversion from ‘double’ to non-scalar type ‘Foam::volScalarField {aka Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh>}’ requested
variables.H:74:22: error: conversion from ‘double’ to non-scalar type ‘Foam::volScalarField {aka Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh>}’ requested
variables.H:76:23: error: conversion from ‘double’ to non-scalar type ‘Foam::volScalarField {aka Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh>}’ requested
variables.H:78:22: error: conversion from ‘double’ to non-scalar type ‘Foam::volScalarField {aka Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh>}’ requested
variables.H:80:23: error: conversion from ‘double’ to non-scalar type ‘Foam::volScalarField {aka Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh>}’ requested
variables.H:82:22: error: conversion from ‘double’ to non-scalar type ‘Foam::volScalarField {aka Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh>}’ requested
variables.H:84:21: error: conversion from ‘double’ to non-scalar type ‘Foam::volScalarField {aka Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh>}’ requested



can someone please help me to solve this.

GerhardHolzinger May 12, 2016 03:23

You understand the difference between the assignment (=) and comparison (==) operators?

This is not strictly limited to C++, however, in this case (OpenFOAM is written in C++) there is a strong difference between assignment and comparison.

The first error message gives a very strong hint at the reason of the error in your listed code.

Even if the compiler error messages seem messy, one needs to be able to interpret them in order to get an idea what is wrong with the code.

upuli May 12, 2016 03:56

HI
Thanks for the comment
There I want to continue my calculation when the gastotalmass(a volume Scalar Field ) not equal to zero. Since zero is a scalar ,OpenFOAM cannot do the operation. So how can I use the unequal operator to manipulate a volume scalar field with a scalar.

ssss May 12, 2016 03:59

1) Initialize the volScalarField outside the if

2) if gastotalmass != 0

YCO = YCO-YCO

This should work

upuli May 13, 2016 08:20

Hi
Can I initialize a function outside a forAll loop like below

volScalarField YCO(gastotalmass, mCO);

for All (gastotalmass,cellI)
{
if(gastotalmass[cellI] !=0)
{

YCO=mCO/gastotalmass
}
else
{
YCO=0

}
}

anishtain4 May 13, 2016 13:55

It's really hard to give you any feedback based on the limited information you have provided. For example I have no idea what is the type of mCO, I know gastotalmass is volScalarField.

Looking at your error there are more than one occasion that you have type inconsistency.
Working on the YCO right now, you can initialize it inside your if too, but since you have a forAll there would be multiple calls to the constructor and you want to avoid it unless it'd be necessary.
There are many ways to construct a volScalarField which you can check at http://openfoam.com/documentation/cp...ml/a00966.html

check constructors under "Public Member Functions".
I couldn't see any constructors with two copy input (I assumed mCo is also a volScalarField).

I am not sure what you are trying to achieve by YCO=mCO/gastotalmass but it is not going to work. Take a look at page P-22 of programmer's user guide and you'll see / operator is usable only when you have numerator as a field and denominator is a scalar. gastotalmass is a volScalarField so this throws an error. I think you are trying to divide two volScalarField elementwise, if that's the case then you are looking for
Quote:

YCO = cmptDivide(mCO.internalField(),gastotalmass.intern alField())

upuli May 14, 2016 05:29

Hi
Actually mCO is a volScalarField. By using the If statement I want to avoid the error of dividing by zero when the value of the volScalarfield gastotalmass equals to zero.

erlofg May 16, 2016 07:27

Like GerhardHolzinger said, the problem is that (=) is a variable assignment. Instead, write (==) in the condition in your if statement and see if that works.

/ Erik

marupio May 16, 2016 15:44

In OpenFOAM == can also be assignment on GeometricFieldBoundaries.

You want to avoid division by zero with a full field operation?

if (condition) { do this } else {do this }

In an if/else structure, the condition is evaluated as a single true/false. You can't compare a full field (with thousands of values) against zero.

volScalarField& T(thermo.T());
if (T == 0)
{ do something }
else { do something else }

This doesn't work. The compiler would have to branch to multiple execution paths. You have to break it down by cell / face, or use a function that does that for you. If you're sure that your total mass field is always going to be positive, it is much faster just to add a small value to the divisor always, regardless of whether it is zero or not. If there are some values less than zero, stabilise is convenient. I think that is defined for a GeometricField.

When using floating point math, you shouldn't use ==:

if (T == 0)

will exclude T=1e-200, which is essentially zero. When dividing by something this small, it will still blow-up anyway. Best to use greater-than / less-than. 1e-30 is a good near-zero value in general, but trial and error is always useful.

When inserting hard-coded constants, such as 1 and 0 into a program, add a '.' after them so the compiler knows they are meant to be floating point numbers, rather than integers, and saves it from casting to integer. E.g. max(T, 0) should be max(T, 0.)

anishtain4 May 17, 2016 14:09

He was trying to do the comparison in a loop, which is not the most efficient way as you mentioned. But there was still a lot of type missmatches that he needs to work on before getting there.

upuli May 19, 2016 01:55

Hi

Thank you all for your answers

I added a small value to the denominator and the problem was solved.

rgds

upuli

block June 15, 2016 07:39

If statement problem
 
1 Attachment(s)
Hi guys,

I have a similar issue. I am trying to add the simple if statement in a surfaceScalar constructor. where Kappaf is depend on the alpha1f and DI (a scalar defined in transport properties)

here is the code:

Attachment 48332

Foam::tmp<Foam::surfaceScalarField>
Foam::alphaincompressibleTwoPhaseMixture::kappaf() const
{
const surfaceScalarField alpha1f
(
min(max(fvc::interpolate(alpha1_), scalar(0)), scalar(1))
);

return tmp<surfaceScalarField>
(
new surfaceScalarField
(
"kappaf",
(
{
forAll(alpha1f,faceI)
{
if (alpha1f[faceI] > scalar(0.5))
{
(alpha1f[faceI]*DI_);
}
else
{
(scalar(0)*alpha1f[faceI]*DI_);
}
}
}
)
)
);
}

However i get all these errors:

alphaconditionincompressibleTwoPhaseMixture/alphaconditionincompressibleTwoPhaseMixture.C: In member function ‘Foam::tmp<Foam::GeometricField<double, Foam::fvsPatchField, Foam::surfaceMesh> > Foam::alphaincompressibleTwoPhaseMixture::kappaf() const’:
alphaconditionincompressibleTwoPhaseMixture/alphaconditionincompressibleTwoPhaseMixture.C:208: 10: error: invalid use of void expression
)
^
alphaconditionincompressibleTwoPhaseMixture/alphaconditionincompressibleTwoPhaseMixture.C:210: 1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
make: *** [Make/linux64GccDPInt32Opt/alphaconditionincompressibleTwoPhaseMixture/alphaconditionincompressibleTwoPhaseMixture.o] Error 1


I am new to openFoam therefore i am not sure how to fix this.

Kind regards

Rimsha


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