|
[Sponsors] |
May 12, 2016, 02:25 |
If statement in OpenFoam
|
#1 |
Member
Upuli
Join Date: Feb 2016
Posts: 68
Rep Power: 10 |
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>:perator= [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. |
|
May 12, 2016, 04:23 |
|
#2 |
Senior Member
Gerhard Holzinger
Join Date: Feb 2012
Location: Austria
Posts: 342
Rep Power: 28 |
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. |
|
May 12, 2016, 04:56 |
|
#3 |
Member
Upuli
Join Date: Feb 2016
Posts: 68
Rep Power: 10 |
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. |
|
May 12, 2016, 04:59 |
|
#4 |
Senior Member
anonymous
Join Date: Aug 2014
Posts: 205
Rep Power: 13 |
1) Initialize the volScalarField outside the if
2) if gastotalmass != 0 YCO = YCO-YCO This should work |
|
May 13, 2016, 09:20 |
|
#5 |
Member
Upuli
Join Date: Feb 2016
Posts: 68
Rep Power: 10 |
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 } } |
|
May 13, 2016, 14:55 |
|
#6 | |
Senior Member
Mahdi Hosseinali
Join Date: Apr 2009
Location: NB, Canada
Posts: 273
Rep Power: 18 |
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:
|
||
May 14, 2016, 06:29 |
|
#7 |
Member
Upuli
Join Date: Feb 2016
Posts: 68
Rep Power: 10 |
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. |
|
May 16, 2016, 08:27 |
|
#8 |
New Member
Erik Löfgren
Join Date: Feb 2015
Location: Umeå, Sweden
Posts: 9
Rep Power: 11 |
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 |
|
May 16, 2016, 16:44 |
|
#9 |
Senior Member
David Gaden
Join Date: Apr 2009
Location: Winnipeg, Canada
Posts: 437
Rep Power: 22 |
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.)
__________________
~~~ Follow me on twitter @DavidGaden |
|
May 17, 2016, 15:09 |
|
#10 |
Senior Member
Mahdi Hosseinali
Join Date: Apr 2009
Location: NB, Canada
Posts: 273
Rep Power: 18 |
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.
|
|
May 19, 2016, 02:55 |
|
#11 |
Member
Upuli
Join Date: Feb 2016
Posts: 68
Rep Power: 10 |
Hi
Thank you all for your answers I added a small value to the denominator and the problem was solved. rgds upuli |
|
June 15, 2016, 08:39 |
If statement problem
|
#12 |
New Member
Rimsha
Join Date: Jan 2016
Posts: 25
Rep Power: 10 |
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: currentcodewithforallloop.png 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 Last edited by block; June 15, 2016 at 13:26. |
|
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Frequently Asked Questions about Installing OpenFOAM | wyldckat | OpenFOAM Installation | 3 | November 14, 2023 12:58 |
OpenFOAM Training, London, Chicago, Munich, Sep-Oct 2015 | cfd.direct | OpenFOAM Announcements from Other Sources | 2 | August 31, 2015 14:36 |
How to use if statement in openFoam solver? | rapierrz | OpenFOAM Programming & Development | 7 | August 4, 2015 06:19 |
OpenFOAM Foundation Releases OpenFOAM v2.3.0 | opencfd | OpenFOAM Announcements from OpenFOAM Foundation | 3 | December 23, 2014 04:43 |
OpenFOAM Foundation releases OpenFOAM 2.2.2 | opencfd | OpenFOAM Announcements from ESI-OpenCFD | 0 | October 14, 2013 08:18 |