CFD Online Logo CFD Online URL
www.cfd-online.com
[Sponsors]
Home > Forums > Software User Forums > OpenFOAM > OpenFOAM Programming & Development

Append scalar to scalarField

Register Blogs Community New Posts Updated Threads Search

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   October 27, 2011, 08:34
Default Append scalar to scalarField
  #1
Senior Member
 
Hisham's Avatar
 
Hisham Elsafti
Join Date: Apr 2011
Location: Braunschweig, Germany
Posts: 257
Blog Entries: 10
Rep Power: 17
Hisham is on a distinguished road
Dear Foamers,

I need to expand a scalarField size by one for each time step. How can I append a scalar to a scalarField?

Regards
Hisham
Hisham is offline   Reply With Quote

Old   October 27, 2011, 09:36
Default
  #2
Senior Member
 
Sandeep Menon
Join Date: Mar 2009
Location: Amherst, MA
Posts: 403
Rep Power: 25
deepsterblue will become famous soon enough
You can use the setSize(const label, const T&) member function in the List class (where Field is derived from) to increment its size (by 1 or any other number). This automatically copies values from the old field, and fills the remaining space with a value that you specify.

Take a look at List.C / List.H.
__________________
Sandeep Menon
University of Massachusetts Amherst
https://github.com/smenon
deepsterblue is offline   Reply With Quote

Old   October 27, 2011, 10:08
Default
  #3
Senior Member
 
Hisham's Avatar
 
Hisham Elsafti
Join Date: Apr 2011
Location: Braunschweig, Germany
Posts: 257
Blog Entries: 10
Rep Power: 17
Hisham is on a distinguished road
Thanks a lot! There is also an append function for the list class

Regards
Hisham
Hisham is offline   Reply With Quote

Old   October 27, 2011, 11:31
Default
  #4
Senior Member
 
Tomislav Maric
Join Date: Mar 2009
Location: Darmstadt, Germany
Posts: 284
Blog Entries: 5
Rep Power: 21
tomislav_maric is on a distinguished road
Quote:
Originally Posted by Hisham View Post
Dear Foamers,

I need to expand a scalarField size by one for each time step. How can I append a scalar to a scalarField?

Regards
Hisham

Will this not be expensive because of the memory copying taking place?

Code:
T* nv = new T[label(newSize)];
From List.C:setSize... append will do the same becaues it is a wrapper for setSize. There is some memcpy option inside, which does the following:

Code:
void * memcpy ( void * destination, const void * source, size_t num );
  Copy block of memory
 Copies the values of num bytes from the location pointed by source directly to the memory block pointed by destination.
If you have a large set of data that doesn't require direct access, you can use DynamicList<T>...
tomislav_maric is offline   Reply With Quote

Old   October 27, 2011, 11:54
Default
  #5
Senior Member
 
Hisham's Avatar
 
Hisham Elsafti
Join Date: Apr 2011
Location: Braunschweig, Germany
Posts: 257
Blog Entries: 10
Rep Power: 17
Hisham is on a distinguished road
Thanks Tomislav,

This feels more professional

Regards
Hisham
Hisham is offline   Reply With Quote

Old   October 28, 2011, 11:02
Default
  #6
Senior Member
 
Tomislav Maric
Join Date: Mar 2009
Location: Darmstadt, Germany
Posts: 284
Blog Entries: 5
Rep Power: 21
tomislav_maric is on a distinguished road
Quote:
Originally Posted by Hisham View Post
Thanks Tomislav,

This feels more professional

Regards
Hisham
Hi Hisham:

that feeling was wrong for the both of us. It seems that the DynamicList is nothing more than a wrapper for List<T> when it comes to expanding the storage.

If you take a look at DynamicListI.H and inspect the append method:

Code:
00309 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::append
00310 (
00311     const T& t
00312 )
00313 {
00314     label elemI = List<T>::size();
00315     setSize(elemI + 1);
00316 
00317     this->operator[](elemI) = t;
00318 }
00319
The "setSize" seemed suspicious to me because I have already seen it in List<T>, and,
guess what the DynamicList::setSize does:


Code:
00173     if (nElem > capacity_)
00174     {
00175 // TODO: convince the compiler that division by zero does not occur
00176 //        if (SizeInc && (!SizeMult || !SizeDiv))
00177 //        {
00178 //            // resize with SizeInc as the granularity
00179 //            capacity_ = nElem;
00180 //            unsigned pad = SizeInc - (capacity_ % SizeInc);
00181 //            if (pad != SizeInc)
00182 //            {
00183 //                capacity_ += pad;
00184 //            }
00185 //        }
00186 //        else
00187         {
00188             capacity_ = max
00189             (
00190                 nElem,
00191                 label(SizeInc + capacity_ * SizeMult / SizeDiv)
00192             );
00193         }
00194 
00195         List<T>::setSize(capacity_);
00196     }
00197
It calls the List<T>::setSize. And this function copies the entire list using memcpy.

What I don't get is why would one wrap a List<T> into something called "DynamicList"
if the underlying engine is based on something like (from UList<T>):

Code:
 this->v_ = new T[this->size_];
and not a pointer... well, I have some work to do over the weekend, I think the actual pointer based
list that allows for appending without memcopy would be LList (Linked List),
but I need to check that out...

Of course it was wrong, why would it be right?

T.
tomislav_maric is offline   Reply With Quote

Old   October 28, 2011, 11:26
Default
  #7
Senior Member
 
Sandeep Menon
Join Date: Mar 2009
Location: Amherst, MA
Posts: 403
Rep Power: 25
deepsterblue will become famous soon enough
Quote:
Originally Posted by tomislav_maric View Post

What I don't get is why would one wrap a List<T> into something called "DynamicList"
if the underlying engine is based on something like (from UList<T>):
It's not a simple wrap around List<T>. It's true that the underlying memory-handling is done by List<T>, but allocations/deallocations and memcpy's are rare. The idea is to pre-allocate a region of memory (larger than the current list), and use that by operating DynamicList with the append() / remove() methods - which, if you look at sources, merely sets the UList::size_ value to change addressed memory.

If and when increased capacity is required, additional memory is allocated (typically twice current capacity), so appends / removes can continue happily.
__________________
Sandeep Menon
University of Massachusetts Amherst
https://github.com/smenon
deepsterblue is offline   Reply With Quote

Old   October 28, 2011, 16:38
Default
  #8
Senior Member
 
Tomislav Maric
Join Date: Mar 2009
Location: Darmstadt, Germany
Posts: 284
Blog Entries: 5
Rep Power: 21
tomislav_maric is on a distinguished road
Quote:
Originally Posted by deepsterblue View Post
It's not a simple wrap around List<T>. It's true that the underlying memory-handling is done by List<T>, but allocations/deallocations and memcpy's are rare. The idea is to pre-allocate a region of memory (larger than the current list), and use that by operating DynamicList with the append() / remove() methods - which, if you look at sources, merely sets the UList::size_ value to change addressed memory.

If and when increased capacity is required, additional memory is allocated (typically twice current capacity), so appends / removes can continue happily.
Hi Sandeep,

I didn't say it was "just a simple wrapper around List", I said:

"
DynamicList is nothing more than a wrapper for List<T> when it comes to expanding the storage."

and that's, well, true.

memcpy or not, it uses simple arrays on the low level. This means that it has to create a completely new list in one way or the other (for the sake of this argument, it makes absolutely no difference in which way the copying is taking place), in order to append something to the existing one, in a logical sense. From List::setSize:

Code:
00327     if (newSize != this->size_)
00328     {
00329         if (newSize > 0)
00330         {
00331             T* nv = new T[label(newSize)];
And then it goes either into memcpy or copies the data via pointer...

That's what's in the code anyway.... or am I reading it wrong?

T.
tomislav_maric is offline   Reply With Quote

Old   October 28, 2011, 16:45
Default
  #9
Senior Member
 
Sandeep Menon
Join Date: Mar 2009
Location: Amherst, MA
Posts: 403
Rep Power: 25
deepsterblue will become famous soon enough
The new list is created only when the underlying storage is filled to capacity. Anyhow, I can't think of a better way to do this, so I consider this optimal.
__________________
Sandeep Menon
University of Massachusetts Amherst
https://github.com/smenon
deepsterblue is offline   Reply With Quote

Old   October 28, 2011, 16:58
Default
  #10
Senior Member
 
Tomislav Maric
Join Date: Mar 2009
Location: Darmstadt, Germany
Posts: 284
Blog Entries: 5
Rep Power: 21
tomislav_maric is on a distinguished road
Quote:
Originally Posted by deepsterblue View Post
The new list is created only when the underlying storage is filled to capacity. Anyhow, I can't think of a better way to do this, so I consider this optimal.
If there is no way for me to guess the size of the list, which is happening actually in what I'm trying to code around every corner, then it will always re-create the list. If I do this for 10-20% of all the cells in the mesh, 10 times in average per time step, that will be a lot of copying.

If I want to use a linked list, it may save more time, but may not, because there will be a price to pay if I need to acces n-th element directly in the fact that it will take (textbook quote) "linear time" to get to it by using an iterator.

Now the real question is, for small lists that span from 10 to 100 elements, say hundred thousand of them within a time-step scope, do I use "dynamic" storage of DynamicList, or dynamic storage provided by a Linked List.

The only thing that comes to my mind is to benchmark this somehow, but what I read about benchmarking makes it seem evil.

The question I had was because I'm used to thinking about dynamical storage in the sense of lists that actually create memory space for an element, and use pointers to access that. This is why the name DynamicList threw me off.

I have no idea for the motivation behind this (I'm not the developer, nor had any of the guys/girls that wrote this explained the background to me), and I'm not saying its wrong or something, it's just that I find the name confusing (especially with the coment that says something about automatically resizing... ).
tomislav_maric is offline   Reply With Quote

Old   October 28, 2011, 17:07
Default
  #11
Senior Member
 
Sandeep Menon
Join Date: Mar 2009
Location: Amherst, MA
Posts: 403
Rep Power: 25
deepsterblue will become famous soon enough
Choosing a particular container depends on how you would like to use it. If you want random access into a linked list, then a hash table would be a good choice, but you'll take a hit with performance due to cache misses. If linear traversal is of priority, then nothing beats a regular array.

I've used the DynamicList / DynamicField functionality quite extensively, and I find that it strikes an optimal balance with speed and flexibility of storage. But again, something that works for me doesn't necessarily translate to general applicability.
__________________
Sandeep Menon
University of Massachusetts Amherst
https://github.com/smenon
deepsterblue is offline   Reply With Quote

Old   October 28, 2011, 17:17
Default
  #12
Senior Member
 
Tomislav Maric
Join Date: Mar 2009
Location: Darmstadt, Germany
Posts: 284
Blog Entries: 5
Rep Power: 21
tomislav_maric is on a distinguished road
Well, right now I've coded everything with DynamicList, and it seems to be working with O.K. speed. I don't think I'll touch this untill the coupling with the CFD solution... that's something that just came to my mind.... heaven knows how will all this compare to the governing system solution. If the total computational time is in order of few % of the governing system solution, it will make no sense to change it.

That is if I ever get to the point of solving the system. Wish me luck.. I'll need it.
tomislav_maric is offline   Reply With Quote

Old   October 28, 2011, 20:42
Default
  #13
Senior Member
 
Hisham's Avatar
 
Hisham Elsafti
Join Date: Apr 2011
Location: Braunschweig, Germany
Posts: 257
Blog Entries: 10
Rep Power: 17
Hisham is on a distinguished road
Hi Tomislav and Sandeep,

Thanks a lot for your posts. Much food for thought

My problem is about a dynamic container that is unique for the domain (actually they are two). Its size is a user input and after a little thought I need to trim the first element and append a new element at the end and renumber the elements for each time step (so the defined size is constant). Luckily, this is not for each cell. I started using a dynamic allocation of an array. I will look to your suggestions in more details.

Nevertheless, considering the new infos, how can one does this in the optimum Foam way?

Regards,
Hisham
Hisham is offline   Reply With Quote

Reply

Tags
append, scalarfield


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Solving for an additional species CO in coalChemistryFoam N. A. OpenFOAM Programming & Development 3 February 18, 2019 06:58
dieselFoam problem!! trying to introduce a new heat transfer model vivek070176 OpenFOAM Programming & Development 10 December 24, 2014 00:48
Specifying nonuniform boundary condition maka OpenFOAM Running, Solving & CFD 59 October 22, 2014 15:52
Climbing inlet pressure with simpleFoam and directMappedPatches chegdan OpenFOAM Running, Solving & CFD 1 January 2, 2012 20:35
CFX12 rif errors romance CFX 4 October 26, 2009 14:41


All times are GMT -4. The time now is 17:19.