CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   Fluent UDF and Scheme Programming (https://www.cfd-online.com/Forums/fluent-udf/)
-   -   Cleaning UDM (https://www.cfd-online.com/Forums/fluent-udf/140013-cleaning-udm.html)

CeesH August 6, 2014 04:49

Cleaning UDM
 
Hi all,

I wrote a small DPM_SCALAR_UPDATE script which stores some stuff in a UDM(c,t,0). These UDM variables are needed in the next timestep, but they should be reset to 0 before the next particle update. Since not every cell contains a particle at every timestep, I do this in a loop inside the DPM_SCALAR_UPDATE script. Furthermore I use a secondary UDM(c,t,1) as a boolean to indicate if a cell has been reset or not. This happens in another UDF during a downstream processing step. In practice, this looks like:

Code:

if (C_UDMI(c,t,1) > 0)
{

domain=Get_Domain(1);

  thread_loop_c (tr,domain)
    {
      begin_c_loop (cell,tr)
        {

C_UDMI(cell,tr,0) = 0;
C_UDMI(cell,tr,1) = 0;

        }
      end_c_loop (cell,tr)
    }
}

In serial mode, this works fine; the complete UDM field gets cleaned as soon as DPM iterations start and afterwards the UDM can be filled again without problems.

If I run in parallel however, the routine only resets the UDM in the partitions that contain a particle. Although in practice there are nearly always particles in every partition, this could theoretically lead to improper memory cleaning and thereby mass imbalances in other UDFs linked to this UDM.

Does anyone have a suggestion to properly clean the memory, by not just looping over all cells in this partition, but by all cells in the entire mesh?

Thanks!
Cees

pakk August 6, 2014 06:01

I used something like this (I removed some lines from my code that you don't need, I did not test this version but I think it should still work).

I used it in serial mode, but probably it should work in parallel too.

Code:

DEFINE_ON_DEMAND(cleanUDM)
  {
        Domain *domain = Get_Domain(ROOT_DOMAIN_ID);
        Thread *t;
        cell_t c;

        Alloc_Storage_Vars(domain, SV_RTMP_0, SV_NULL);

        thread_loop_c(t,domain) {
                if (THREAD_ID(t)!=0) {
                        begin_c_loop(c,t) {
                                C_UDMI(c,t,0)=0
                        }
                }
        end_c_loop(c,t)
        }
  }


CeesH August 6, 2014 06:07

Thanks Pakk, I'll give it a try.

CeesH August 6, 2014 10:32

I implemented the piece of code in my DPM_SCALAR_UPDATE UDF (can't use execute at end or define on demand as I need the values in the next timestep).

Unfortunately, it didn't work. Like before only the cells in the partition that contained a particle got cleaned out, while the others were not..

EDIT:
Also using both a c_loop_int and c_loop_ext in the routine did not work..

pakk August 7, 2014 04:33

I think that is because the DPM_SCALAR_UPDATE UDf is only called if DPM particles are found. You might have better luck with a DEFINE_ADJUST UDF.

CeesH August 7, 2014 05:28

That might be the case indeed; problem is that the define_adjust routine is called before species and energy equation update, and I need the UDM values during those updates.

If I'm correct, the DPM routine is called after the scalar fields have been treated, and at that point the memory is to be erased. So far this approach has been working well, provided indeed there is a particle in the partition domain.

pakk August 7, 2014 06:11

One problem with your original code is that it is evaluated for every cell where there is a particle.
If there are 10000 particles, the domain will be 'cleaned' 10000 times. This is not necessarily wrong, but inefficient.
More ideally, you need one flag per domain. You can do that be defining a global variable (assuming there is one domain, otherwise make it an array):
Code:

int domainisclean=1;
Every time you change the UDM, update this variable:
Code:

domainisclean=-1;
Then you can change your code to
Code:

if (domainisclean < 0)
{

domain=Get_Domain(1);

  thread_loop_c (tr,domain)
    {
      begin_c_loop (cell,tr)
        {
            C_UDMI(cell,tr,0) = 0;
        }
      end_c_loop (cell,tr)
    }
domainisclean=1;
}

But this does not answer your question... I don't know the answer to that question. Maybe this is a good time to involve the Ansys support!

CeesH August 7, 2014 06:38

Hi Pakk,

The loop is only executed if there the boolean UDM is 1; so once per partition. But in terms of memory it is indeed not efficient, 1 boolean per partition would be sufficient, rather than 1 per cell..

Indeed, time to contact ansys support. Thanks for your help anyway!

Best
cees

pakk August 7, 2014 07:17

Quote:

Originally Posted by CeesH (Post 504803)
The loop is only executed if there the boolean UDM is 1; so once per partition. But in terms of memory it is indeed not efficient, 1 boolean per partition would be sufficient, rather than 1 per cell..

You are right, I forgot about that.


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