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. |
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. |
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. |
1) Initialize the volScalarField outside the if
2) if gastotalmass != 0 YCO = YCO-YCO This should work |
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 } } |
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:
|
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. |
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 |
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.) |
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.
|
Hi
Thank you all for your answers I added a small value to the denominator and the problem was solved. rgds upuli |
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. |