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/)
-   -   method surfaceSum(...) of class fvc (https://www.cfd-online.com/Forums/openfoam-programming-development/127138-method-surfacesum-class-fvc.html)

maybee December 4, 2013 07:42

method surfaceSum(...) of class fvc
 
hi,

I' m having problems with understanding the method surfaceSum(...) below:

Code:

template<class Type>
  192 tmp<GeometricField<Type, fvPatchField, volMesh> > surfaceSum
  193 (
  194    const tmp<GeometricField<Type, fvsPatchField, surfaceMesh> >& tssf
  195 )
  196 {
  197    tmp<GeometricField<Type, fvPatchField, volMesh> > tvf = surfaceSum(tssf());  //QUESTION
  198    tssf.clear(); 
  199    return tvf;
  200 }

with the overloaded operator () called on tssf in line 197:

Code:


template<class T>
213*inline const T& Foam::tmp<T>::operator()() const     
214*{
215* if (isTmp_)  // bool isTmp_;  //- Flag for whether object is a temporary or a constant object
216* {
217* if (!ptr_)  //mutable T* ptr_;  //- Pointer to temporary object 
218* {
219* FatalErrorIn("const T& Foam::tmp<T>::operator()() const")
220* << "temporary deallocated"
221* << abort(FatalError);
222* }
223*
224* return *ptr_;
225* }
226* else
227* {
228* return ref_;  //const T& ref_  //- Const reference to constant object
229* }
230*}

Question (line 197 marked in code snippet 1) :

In method surfaceSum(...) the input parameter tssf is passed to "another" surfaceSum(...) method. Wouldn t that cause some kind of endless loop, because in the new called method surfaceSum(...) the method gets called again and so on?

akidess December 4, 2013 08:22

The ()-operator strips the object from it's tmp-"shell", so the following call to surfaceSum leads to a different method, namely one that is called when a GeometricField is passed: http://foam.sourceforge.net/docs/cpp...ce.html#l00138

maybee December 4, 2013 08:50

hi again,

Quote:

The ()-operator strips the object from it's tmp-"shell",...
What do you mean by this? How is tmp stripped from the object tssf?

All I can see in the method operator () is that in line 215 it is proved if the object is tmp (temporary) and in line 217 if the pointer ptr_ is not NULL. If both these conditions are fullfilled the pointer ptr_ is dereferenced and returned in line 224.

akidess December 5, 2013 03:35

Code:

224* return *ptr_;
* What does this line do?

It dereferences the pointer stored in the tmp<> object, and returns the dereferenced pointer.

* What happens if you dereference a pointer pointing to an object?

You get access to that object. Note that in our case, the object in question is a vol*Field.

Does that make things clear?


Recommended reading: http://openfoamwiki.net/index.php/OpenFOAM_guide/tmp

maybee December 5, 2013 04:12

Quote:

224* return *ptr_;

What does this line do?

It dereferences the pointer stored in the tmp<> object, and returns the dereferenced pointer.

* What happens if you dereference a pointer pointing to an object?

You get access to that object. Note that in our case, the object in question is a vol*Field.
1. I know about dereferencing a pointer :), but if the pointer ptr_ points to an object of class tmp and gets dereferenced how should this strip the tmp from the object?

2. Furthermore, how do you know it is a vol*Field?

I have the following source code:

Code:

scalarField sumPhi
(
fvc::surfaceSum(mag(phi))().internalField()
);

with

Code:

const surfaceScalarField& phi
and therefore

Code:

→ template<class Type, template<class> class PatchField, class GeoMesh>
323*tmp<GeometricField<scalar, PatchField, GeoMesh> > mag 
324*(                                                                                                 
325* const GeometricField<Type, PatchField, GeoMesh>& gf   
326*)
327*{
328* tmp<GeometricField<scalar, PatchField, GeoMesh> > tMag   
329* (
330* new GeometricField<scalar, PatchField, GeoMesh>   
331* (                                                                                     
332* IOobject
333* (
334* "mag(" + gf.name() + ')',
335* gf.instance(),                                     
336* gf.db(),                                   
337* IOobject::NO_READ,
338* IOobject::NO_WRITE
339* ),
340* gf.mesh(),                   
341* gf.dimensions()                                           
342* )
343* );
344*
345* mag(tMag(), gf);
346*
347* return tMag;
348*}

and since the overloaded operator () [see my first post] is called on the result of method mag which returns a "tmp<GeometricField<scalar, PatchField, GeoMesh> > tMag" the pointer ptr_ should point at a "tmp<scalar> field".

akidess December 5, 2013 04:21

Quote:

Originally Posted by maybee (Post 464943)
1. I know about dereferencing a pointer :), but if the pointer ptr_ points to an object of class tmp and gets dereferenced how should this strip the tmp from the object?

I figured you would after getting this far, but the next guy with the same question may not :)

tmp<GeometricField<scalar, PatchField, GeoMesh> > tMag stores a pointer to a GeometricField<scalar, PatchField, GeoMesh>, which is the same thing as a volScalarField. So when you call tMag() you will end up with the underlying volScalarField.

- Anton

maybee December 5, 2013 04:36

:D , now I got it. Just one more question:

How did you know that ptr_ points to the geometricfield and not to the tmp<"geometricfield">?

akidess December 5, 2013 05:34

On line 330 of the code you posted a new object of GeometricField<> is allocated and it's pointer is passed on to the constructor of tmp<>: http://foam.sourceforge.net/docs/cpp...bf3c32f4c76004

maybee December 5, 2013 05:42

Ok, thx alot. Question solved.


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