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/)
-   -   == operator (https://www.cfd-online.com/Forums/openfoam-programming-development/85013-operator.html)

linch February 15, 2011 06:57

== operator
 
Hi foamers,

I know the "==" operator as an equality operator in C, i.e. (a==b) suppose to return true or false.

But then I can't understand following lines of interFoam:
Code:

rho == alpha1*rho1 + (scalar(1) - alpha1)*rho2;
and
Code:

solve
        (
            UEqn
        ==
            fvc::reconstruct
            (
                (
                    fvc::interpolate(interface.sigmaK())*fvc::snGrad(alpha1)
                  - ghf*fvc::snGrad(rho)
                  - fvc::snGrad(p_rgh)
                ) * mesh.magSf()
            )
        );

Can you please explain me the meaning of the == operator is these cases? What would be the difference if I would use
Code:

rho = alpha1*rho1 + (scalar(1) - alpha1)*rho2;
instead of == for the first one?

Best regards,
Ilya

l_r_mcglashan February 15, 2011 07:43

I think...

= only does stuff to the internalField()
== does stuff to the internalField() AND the boundaryField()

linch February 15, 2011 07:56

And how OF knows, if it has to use the C/C++ standard boolean or the OF-redefined "==" operator?

santiagomarquezd February 15, 2011 23:32

Hi, '=' is the usual operator used to replace the content of LHS with RHS. '==' is overloaded in fvMatrix class in order to write equations. It's only dividing sides.

Regards.

linch February 16, 2011 07:11

Even in this case: rho == alpha1*rho1 + (scalar(1) - alpha1)*rho2; ?

I thought in this line the volScalar rho is being computed, but if I understand you correctly an equation for rho is being defined? :eek:

regards,
Ilya

akidess February 16, 2011 08:00

No Ilya, in your example it is an assignment just like Laurence already stated further up. Santiago was explaining the case when having an "==" within a solve().

santiagomarquezd February 16, 2011 08:22

Illya, from what source file did you take this line?:

Code:

rho = alpha1*rho1 + (scalar(1) - alpha1)*rho2;
Regards.

linch February 16, 2011 11:47

Quote:

Originally Posted by santiagomarquezd (Post 295511)
Illya, from what source file did you take this line?

interFoam : alphaEqnSubCycle.H

Quote:

Originally Posted by akidess (Post 295502)
No Ilya, in your example it is an assignment just like Laurence already stated further up. Santiago was explaining the case when having an "==" within a solve().

Thanks, so for volFields it makes more sense to use == instead of =, if no boundary condition is prescribed for the LHS-field?

santiagomarquezd February 16, 2011 13:33

Aha, it's true I never paid attention in this particular '==' operator. Checking GeometricField.C, operator== and operator= copies both internal and boundary fields. The difference seems to be in another characteristic, operator= uses transfer method and operator== does not. But I don't realize the necessity of this operator in this case.

Regards.

linch February 18, 2011 07:07

Quote:

Originally Posted by santiagomarquezd (Post 295585)
Aha, ... operator= uses transfer method and operator== does not

Sry, but what does it mean?

Regards.

hjasak February 19, 2011 06:55

Nope: operator== will FORCE assignment, even if patch field type says it should not be so. For example for a fixedValue patch, operator== will change its value and operator= will do nothing.

Hrv

santiagomarquezd February 19, 2011 11:27

Aha, that explains the part I couldn't understand at all (GeometricField.C:01103):

Code:

01090 template<class Type, template<class> class PatchField, class GeoMesh>
01091 void Foam::GeometricField<Type, PatchField, GeoMesh>::operator==
01092 (
01093    const tmp<GeometricField<Type, PatchField, GeoMesh> >& tgf
01094 )
01095 {
01096    const GeometricField<Type, PatchField, GeoMesh>& gf = tgf();
01097
01098    checkField(*this, gf, "==");
01099
01100    // only equate field contents not ID
01101
01102    dimensionedInternalField() = gf.dimensionedInternalField();
01103    boundaryField() == gf.boundaryField();
01104
01105    tgf.clear();
01106 }

i think it ends doing this (fvPatchField.C):

Code:

00437 // Force an assignment, overriding fixedValue status
00438 template<class Type>
00439 void Foam::fvPatchField<Type>::operator==
00440 (
00441    const fvPatchField<Type>& ptf
00442 )
00443 {
00444    Field<Type>::operator=(ptf);
00445 }

Thanks for the clarification!!

Regards.

P.S. fvPatchField class don't have a 'fixed value flag' to avoid overriding?

Hisham September 26, 2011 15:35

Greetings,

I am developing a timeVaryingMapped BC for tractionDisplacement based on the timeV..M..FixedValue and the tractionDisplacement BCs. In the first (timeV..M..FixedValues) I find that values are assigned by the "==" operator:
Quote:

00710 this->operator==((1-s)*startSampledValues_ + s*endSampledValues_);
According to the discussion here, this should mean that the value (for given patch and variable) is imposed for each time it is calculated.
However, in the tractionDisplacement BC, the gradient() is calculated via a "=" operator.
I would like to know:

1. What is the meaning of "this->operator==(someField);" for a fixedGradient BC?
2. To assign gradient() for the custom BC I seek, should I use "gradient() == someVectorField;" or "gradient() = someVectorField;"

I appreciate your help/answer! Thanks
Hisham

tomislav_maric September 27, 2011 03:12

Quote:

Originally Posted by linch (Post 295327)
And how OF knows, if it has to use the C/C++ standard boolean or the OF-redefined "==" operator?

Hi Illya,

operators are like other functions in C++. Although you don't see it, they look like, for example:

Code:

left operand == (right operand)
where "==" is the name of the function. Since they are overloaded (the final name of the function is defined by the arguments, return value, as well as by the "==" special character), the compiler recognizes by the types involved, which operator to call, in which class (type).

From fvMatrix.C:

Code:

template<class Type>
Foam::tmp<Foam::fvMatrix<Type> > Foam::operator==
(
    const fvMatrix<Type>& A,
    const fvMatrix<Type>& B
)
{
    checkMethod(A, B, "==");
    return (A - B);
}

"checkMethod" compares the "psi_" private data members (geometric fields) to see if they are compatible (mapped on the same mesh) and the dimensioned set to ensure compatible field dimensions.

Since it returns A - B (both coeff matrices), it seems to me that it just makes the entire algebraic system implicit (put B on the left side, or in your case, the field you get by fvc::reconstruct).

operator = ... from fvMatrix.C:
Code:

template<class Type>                                                     
void Foam::fvMatrix<Type>::operator=(const fvMatrix<Type>& fvmv)         
{
    if (this == &fvmv)                                                   
    {
        FatalErrorIn("fvMatrix<Type>::operator=(const fvMatrix<Type>&)") 
            << "attempted assignment to self"                           
            << abort(FatalError);                                       
    }                                                                   
       
    if (&psi_ != &(fvmv.psi_))
    {                                                                   
        FatalErrorIn("fvMatrix<Type>::operator=(const fvMatrix<Type>&)") 
            << "different fields"                                       
            << abort(FatalError);                                       
    } 
       
    lduMatrix::operator=(fvmv);                                         
    source_ = fvmv.source_;
    internalCoeffs_ = fvmv.internalCoeffs_;                             
    boundaryCoeffs_ = fvmv.boundaryCoeffs_;
                                                                         
    if (faceFluxCorrectionPtr_ && fvmv.faceFluxCorrectionPtr_)           
    { 
        *faceFluxCorrectionPtr_ = *fvmv.faceFluxCorrectionPtr_;         
    }                                                                   
    else if (fvmv.faceFluxCorrectionPtr_)                               
    { 
        faceFluxCorrectionPtr_ =
            new GeometricField<Type, fvsPatchField, surfaceMesh>         
        (*fvmv.faceFluxCorrectionPtr_);                                 
    }                                                                   
}

It has to call the lduMatrix::operator= because it inherits from it, this guy goes over lower, upper and diagonal part and executes the data copy. The other part copies the rest of the data that is stored in the fvMatrix.

There seems to be no difference between

rho = something

and

rho == something

If rho is a vol*Field, == will copy both the boundary and the internal field:

01154 template<class Type, template<class> class PatchField, class GeoMesh>
01155 void Foam::GeometricField<Type, PatchField, GeoMesh>::operator==
01156 (
01157 const tmp<GeometricField<Type, PatchField, GeoMesh> >& tgf
01158 )
01159 {
01160 const GeometricField<Type, PatchField, GeoMesh>& gf = tgf();
01161
01162 checkField(*this, gf, "==");
01163
01164 // only equate field contents not ID
01165
01166 dimensionedInternalField() = gf.dimensionedInternalField();
01167 boundaryField() == gf.boundaryField();
01168
01169 tgf.clear();
01170 }



and "=" seems to be doing the same thing:

01082 template<class Type, template<class> class PatchField, class GeoMesh>
01083 void Foam::GeometricField<Type, PatchField, GeoMesh>::operator=
01084 (
01085 const GeometricField<Type, PatchField, GeoMesh>& gf
01086 )
01087 {
01088 if (this == &gf)
01089 {
01090 FatalErrorIn
01091 (
01092 "GeometricField<Type, PatchField, GeoMesh>::operator="
01093 "(const GeometricField<Type, PatchField, GeoMesh>&)"
01094 ) << "attempted assignment to self"
01095 << abort(FatalError);
01096 }
01097
01098 checkField(*this, gf, "=");
01099
01100 // only equate field contents not ID
01101
01102 dimensionedInternalField() = gf.dimensionedInternalField();
01103 boundaryField() = gf.boundaryField();
01104 }

Both operators, work on GeometricField<Type, PatchField, GeoMesh> ( example: vol*Field) from both sides.

Hope this helps,
Tomislav

l_r_mcglashan September 27, 2011 04:31

Ah, but == will force an overwrite of all the boundary conditions, whereas = will not.

tomislav_maric September 27, 2011 05:06

Quote:

Originally Posted by l_r_mcglashan (Post 325740)
Ah, but == will force an overwrite of all the boundary conditions, whereas = will not.

I just checked it with an application, and you are completely right.... still,

Code:

01167    boundaryField() == gf.boundaryField();
I didn't notice that double "==" in the operator == of the GeometricField<blah ... and when I look in the BoundaryField, this operator is defined to do:

Code:

void operator==            (          const GeometricBoundaryField &           
          )           
                  Forced assignment to.
 BoundaryField<Type, PatchField, BoundaryMesh>

and the definition does exactly that:

Code:

// Forced assignments                                                     
template<class Type, template<class> class PatchField, class GeoMesh>     
void Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricBoundaryField::
operator== 
(         
    const typename GeometricField<Type, PatchField, GeoMesh>::           
    GeometricBoundaryField& bf
)         
{                                                                         
    forAll((*this), patchI)
    {     
        this->operator[](patchI) == bf[patchI];                           
    }                                                                     
}

:confused: It's all in the GeometricField.C and GeometricBoundaryField.C (GeometricBoundaryField is composited into GeometricField).

The only question is, what does this button do: "this->operator[](patchI) == bf[patchI]"


All times are GMT -4. The time now is 11:55.