CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   FLUENT (https://www.cfd-online.com/Forums/fluent/)
-   -   User Defined Memory Problem (https://www.cfd-online.com/Forums/fluent/33784-user-defined-memory-problem.html)

Melih May 22, 2004 07:02

User Defined Memory Problem
 
Hi everbody,

I have a problem that may be a common problem for Fluent Users. I want to see pressure values of a wall by User Defined Memory at every iteration. The thing is that the pressure values are transfered to F_UDMI(t,f,0) in my UDF, but I can not see them in FLUENT. I mean, every values of F_UDMI(t,t,0) are zero in contour values windows in FLUENT. Here is the simple UDF that transfers pressure values to F_UDMI(t,f,0). Could you please tell me what is wrong with it?

#include "udf.h"

DEFINE_ADJUST(wall_pressure,domain)

{ face_t f;

int ID = 8;

/* Zone ID for wall zone */

Thread *t = Lookup_Thread(domain, ID);

begin_f_loop(f, t)

{

F_UDMI(f,t,0) = F_P(f,t);

Message("pressure %e\n",F_UDMI(f,t,0));

}

end_f_loop(f, t)

}

Andrew Garrard May 24, 2004 04:31

Re: User Defined Memory Problem
 
I have had exactly the same problem with the UDMI macro and the good people at the fluent USC couldn't help me much. I had to use a "dirty trick" to get around this one. If you assign the value of the F_UDMI to the adjcent cell you should then be able to see it in, say, a contour or XY plot with in fluent. If you need help doing this I can help you out with the source code, but you seem to know what you are doing, so I will leave it for the moment.

I hope this helps, happy coding.

ap May 25, 2004 04:20

Re: User Defined Memory Problem
 
I had the same problem too. Maybe it's a bug of FLUENT.

Hi :)

ap

dp May 25, 2004 21:39

Re: User Defined Memory Problem
 
Have had a similiar problem, and the bug seams to go away (if the same bug) by first viewing the udm with contours (should be all zeros), then run your udf and then replot. It appears that viewing the udm initializies it for use (atleast thats one interpretation).

s.m.saad jamil July 16, 2016 06:47

problem regarding user defined memory
 
i am trying to calculate source term for X-momentum equation by calculating first the average temperature in a mixed convection case.
I want to store the value of mean temperature using user defined memory and use this value to calculate source term in xmomentum equation.
i have written the UDF mentioned below:
#include "udf.h"
DEFINE_ON_DEMAND(on_demand_calc)
{
real tavg;
real temp,volume,vol_tot;
Domain*d;
Thread*t;
int i;
cell_t c;
tavg = 0.;
vol_tot = 0.;
d = Get_Domain(1);
thread_loop_c(t,d)
{
begin_c_loop(c,t)
{
volume = C_VOLUME(c,t);
temp = C_T(c,t)-273.5;
vol_tot += volume;
tavg += temp*volume;
}
end_c_loop(c,t)
tavg = tavg/vol_tot;
}
printf("Tavg = %g\n",tavg);
printf("volume = %g\n",volume);
printf("vol_tot = %g\n",vol_tot);
printf("temp = %g\n",temp);
thread_loop_c(t,d)
{
begin_c_loop(c,t)
{
C_UDMI(c,t,0) = tavg;
}
end_c_loop(c,t)
}
}
DEFINE_SOURCE(mom_source,c,t,dS,eqn)
{
real x[ND_ND];
real source;
C_CENTROID(x,c,t);
source= 1.-5.33*(C_T(c,t)-C_UDMI(c,t,0));
dS[eqn]=0.;
return source;
}

but i am getting zero value when i am trying to plot the user defined memory.

please help me regarding this.

Regards

saad

gouravjee March 18, 2018 08:36

UDM problem
 
Quote:

Originally Posted by s.m.saad jamil (Post 609766)
i am trying to calculate source term for X-momentum equation by calculating first the average temperature in a mixed convection case.
I want to store the value of mean temperature using user defined memory and use this value to calculate source term in xmomentum equation.
i have written the UDF mentioned below:
#include "udf.h"
DEFINE_ON_DEMAND(on_demand_calc)
{
real tavg;
real temp,volume,vol_tot;
Domain*d;
Thread*t;
int i;
cell_t c;
tavg = 0.;
vol_tot = 0.;
d = Get_Domain(1);
thread_loop_c(t,d)
{
begin_c_loop(c,t)
{
volume = C_VOLUME(c,t);
temp = C_T(c,t)-273.5;
vol_tot += volume;
tavg += temp*volume;
}
end_c_loop(c,t)
tavg = tavg/vol_tot;
}
printf("Tavg = %g\n",tavg);
printf("volume = %g\n",volume);
printf("vol_tot = %g\n",vol_tot);
printf("temp = %g\n",temp);
thread_loop_c(t,d)
{
begin_c_loop(c,t)
{
C_UDMI(c,t,0) = tavg;
}
end_c_loop(c,t)
}
}
DEFINE_SOURCE(mom_source,c,t,dS,eqn)
{
real x[ND_ND];
real source;
C_CENTROID(x,c,t);
source= 1.-5.33*(C_T(c,t)-C_UDMI(c,t,0));
dS[eqn]=0.;
return source;
}

but i am getting zero value when i am trying to plot the user defined memory.

please help me regarding this.

Regards

saad

If you have figured out the problem, then can you tell me what was it ?
I am also facing the same problem

Toufik KHATTARA February 16, 2020 03:20

I'm facing exactly the same problem, user defined memory contains just zero value !!
please help me regarding this.

vinerm February 16, 2020 04:14

UDM usage
 
The usage of the UDM in the code given is not its intentional usage. A simple C variables, tavg itself, could be used. UDM is required only if the variable varies over space, i.e., it may have different value corresponding to each cell.

Toufik KHATTARA February 16, 2020 05:44

Quote:

Originally Posted by vinerm (Post 758290)
The usage of the UDM in the code given is not its intentional usage. A simple C variables, tavg itself, could be used. UDM is required only if the variable varies over space, i.e., it may have different value corresponding to each cell.

Thanks for your reply,
I've changed my udm into this :
DEFINE_ON_DEMAND(essay)
{
real temp;
cell_t c;
Thread *t;
Domain* d;
d = Get_Domain(1);
thread_loop_c(t,d)
{
begin_c_loop(c,t)
{
C_UDMI(c,t,0) = C_U(c,t);
}
end_c_loop(c,t)
}
}
" as a small test just to know if i succeed to store the x_velocity or no "
once i execute , Fluent shuts down and close without showing any error !!
I don't know where is exactly the problem.
Thanks

2phase February 16, 2020 09:50

edit: I got a minimal example working, so I posted below.

Reducing unnecessary stuff and deleted my post here.

vinerm February 16, 2020 16:02

C_UDMI for C_U
 
Toufik, your code is alright. The issue could be that either the UDM does not exist or you did not initialize it.

First, check if the UDM exists, Go to User-Defined > Memory and ensure that at least one memory exists.

Second important part is its initialization. Using UDM without initialization gives error. There are two ways to initialize it. The easiest is to use Patch within Initialization Dialogue box. Use Patch, select UDM, select all cell zones, and patch with value of 0. Other option is to do initialization within the UDF. Once these two processes are done, the UDF should work fine assuming C_U exists, i.e., you have at least one fluid domain and the flow is initialized or solved.

vinerm February 16, 2020 16:09

Incomplete Code
 
Martin, the code is incomplete or at least not posted here in its complete form. adj_relhum and myHumdity functions are missing. Furthermore, min_mass, max_mass, min_heat, and max_heat variables are undefined. The enum section for UDMs is missing as well. Even if those functions exist, their output is not being used in this code. But enum section or equivalent is required. Values for UDMs are being set to 0, hence, numbers will remain 0. Message reported is as expected from the code since there are no values available for min_mass, etc.

2phase February 17, 2020 12:50

Dear Vinerm,

thanks for the thorough answer.
Yes, the Code was incomplete, because I wanted to Keep it short - though that's not helpful in the end, as it turns out.

I reduced the Code to an example, which is more easy to read, though it is still not minimal.

I compiled and loaded UDFs, have enough UDMs reserved through GUI.
And newly, I patched the UDMs before calculation - read that somewhere here, thanks for that hint.
Then I ran a few steps and turns out, the humidity is calculated correctly.


Code:

/******************************************************************
    UDF for
 *******************************************************************/
 
 #include "udf.h"
 
 #define UDM_RH  0          /* no. of UDM holding relative humidity */
 #define UDM_MASS 1          /* no. of UDM holding species mass source */
 #define UDM_HEAT 2          /* no. of UDM holding species heat source */
 #define NUM_UDM 3
 static int udm_offset = UDM_UNRESERVED;
 
 int h2o_index=0;          /* index of water vapor species in mixture material */
 int cell_count=0;                        /*counter to limit output messages*/

 
 real molwt_h2o=18.01528;  /* molecular weight of water g/mol */
 real molwt_air=28.949;
 real R_vap = 8.314 / 18.01528 *1000;        /*specific gas constant of water vapor J/kg/K */
 real R_air = 8.314 / 28.949 * 1000;        /*for dry air*/
 
 
  real H2O_Saturation_Pressure(real T)
 {
  real ratio, aTmTp;
  T = MAX(T, 273);
  T = MIN(T, 647.286);
  aTmTp = .01 * (T - 338.15);
  ratio = (647.286 / T - 1.) *
          (-7.419242 + aTmTp * (.29721 +
                        aTmTp * (-.1155286 +
                        aTmTp * (8.685635e-3 +
                        aTmTp * (1.094098e-3 +
                        aTmTp * (-4.39993e-3 +
                        aTmTp * (2.520658e-3 -
                        aTmTp * 5.218684e-4)))))));
  return (22.089e6 * exp(MIN(ratio, 35.)));
 }
 
 real myHumidity(cell_t c, Thread *t)
 {
  int i;
  Material *m = THREAD_MATERIAL(t), *sp;
  real yi_h2o = 0.;      /* water mass fraction */
  real r_mix = 0.0;    /* sum of [mass fraction / mol. weight] over all species */
  real humidity;

  if ((MATERIAL_TYPE(m) == MATERIAL_MIXTURE) && (FLUID_THREAD_P(t)))
    {
      yi_h2o = C_YI(c, t, h2o_index);    /* water vapor mass fraction */
      mixture_species_loop(m, sp, i)
        {
          r_mix += C_YI(c,t,i) / MATERIAL_PROP(sp, PROP_mwi);
        }
         
      humidity = op_pres * yi_h2o / (molwt_h2o * r_mix) / H2O_Saturation_Pressure(C_T(c,t));
          return humidity;
    }
  else
    return 0.;
 }
 
 DEFINE_SOURCE(demister_mass_source, cell, thread, dS, eqn)
 {
    real relHumi = C_UDMI(cell,thread,UDM_RH);
    real source_mass = 0.;
    dS[eqn]=0.; 
    C_UDMI(cell, thread, UDM_MASS) = source_mass;
       
    return source_mass;
 }
   

 DEFINE_SOURCE(demister_heat_source, cell, thread, dS, eqn)
 {
    real relHumi = C_UDMI(cell,thread,UDM_RH);
    real source_heat = 0.;
    dS[eqn]=0.;

    C_UDMI(cell, thread, UDM_HEAT) = source_heat;
    if (cell_count < 20)
          {
          Message("\n heat source gives thread %d\n\n", THREAD_ID(thread));
          Message("\n relative humidity is %f\n\n", relHumi);
          cell_count += 1;
          }
        return source_heat;
 }


 DEFINE_ADJUST(adj_relhum, domain)
 {
  cell_t cell;
  Thread *thread; 
  real humidity;

  thread_loop_c(thread, domain)
        {
                /* Check if thread is a Fluid thread and has UDMs set up on it */
                if (FLUID_THREAD_P(thread) && NNULLP(THREAD_STORAGE(thread, SV_UDM_I)))
                {
                  Material *m = THREAD_MATERIAL(thread), *sp;
                  int i;
                  /* Set the species index and molecular weight of water */
                  if (MATERIAL_TYPE(m) == MATERIAL_MIXTURE)
                        mixture_species_loop (m,sp,i)
                          {
                                if ((0 == strcmp(MIXTURE_SPECIE_NAME(m,i),"h2o")) ||
                                        (0 == strcmp(MIXTURE_SPECIE_NAME(m,i),"H2O")) )
                                  {
                                        h2o_index = i;
                                        molwt_h2o = MATERIAL_PROP(sp,PROP_mwi);
                                  }
                          }
               
                  begin_c_loop(cell,thread)
                        {
                          humidity = myHumidity(cell, thread);
              C_UDMI(cell, thread, UDM_RH) = humidity;
                        }
                  end_c_loop(cell, thread)
                }
        }

 }
 

 DEFINE_EXECUTE_ON_LOADING(on_loading, libname)
 {
    if (udm_offset == UDM_UNRESERVED) udm_offset =
      Reserve_User_Memory_Vars(NUM_UDM);
    if (udm_offset == UDM_UNRESERVED)
    Message("\nYou need to define up to %d extra UDMs in GUI and "
        "then reload current library %s\n", NUM_UDM, libname);
    else
    {
      Message("%d UDMs have been reserved by the current "
        "library %s\n", NUM_UDM, libname);
          Set_User_Memory_Name(udm_offset,"UDM-rel-humidity");
      Set_User_Memory_Name(udm_offset+1,"UDM-mass-source");
      Set_User_Memory_Name(udm_offset+2,"UDM-heat-source");
    }
    Message("\nUDM Offset for Current Loaded Library = %d",udm_offset);

 
 }
 
 DEFINE_ON_DEMAND(set_relhum)
 {
  adj_relhum(Get_Domain(1));
  Thread *thread;
  cell_t cell;
 
  thread_loop_c(thread, Get_Domain(1))
        {
                /* Check if thread is a Fluid thread and has UDMs set up on it */
                if (FLUID_THREAD_P(thread) && NNULLP(THREAD_STORAGE(thread, SV_UDM_I)))
                {
                  begin_c_loop(cell,thread)
                        {
                          C_UDMI(cell, thread, UDM_RH) = 0;
                          C_UDMI(cell, thread, UDM_MASS) = 0;
                          C_UDMI(cell, thread, UDM_HEAT) = 0;
                        }
                  end_c_loop(cell, thread)
                }
        }
 
  Message("\nrelHumi set in udm-%d", UDM_RH);
  Message("\nh2o mass source set in udm-%d", UDM_MASS);
  Message("\nh2o heat source set in udm-%d", UDM_HEAT);
  Message("\noperating pressure: %f", op_pres);
 }

One Thing I got wrong in the beginning was the denominaation of the Output variables as floats, not as integers.

So I'll Keep my example as a working one so far for others - if that is OK?!
When I manage to get the other UDMs working, I'll report the solution.

vinerm February 17, 2020 15:54

Caveats
 
There are a few caveats in the code. First, it assumes that you have water vapor in the gas mixture and second assumption is that it is first in the list of the names that show in the Species list.

demister_mass_source function fetches the relative humidity but does not use it. The value returned is always 0. So, your second UDM will always be 0. Same is true for demister_heat_source function and, consequently, the third UDM is 0 as well.

There are some useful checks for ensuring if there are other libraries loaded along with this one that also use UDMs. But those are overkill if this library is not to be used with other libraries.

Lastly, molwt_air is declared and defined but never used.

2phase February 18, 2020 17:30

Sorry again for leaving parts out in the code… well, not leaving out, but I cut it to simplify and search for Errors and had a few unnecessary leftovers in the code.

As far as I can reconstruct my work, it might most likely have been the fault of not patching the UDMs. Despite that I found mistakes here and there.

In the end, I want to provide a working example for everyone here.
If anyone has additional questions to the specific use or whatever, feel free to write a personal message, as I don't have notifications on the thread.

Hope this helps anyone and I didn't hijack this thread for Nothing.
Martin

Code:

/******************************************************************
/******************************************************************
    UDF for removing excessive water (relative humidity >1) from air
    flow during cooling/condensation process
   
    Inspired from examples from FLUENT customization manual
        DEFINE_DPM_SWITCH
        DEFINE_SOURCE
       
 *******************************************************************/
 
 #include "udf.h"
 
 #define UDM_RH  0          /* no. of UDM holding relative humidity */
 #define UDM_MASS 1          /* no. of UDM holding species mass source */
 #define UDM_HEAT 2          /* no. of UDM holding species heat source */
 
 static int last_ts    = -1;  /* Global variable. Time step is never <0 */
 
 int h2o_index=0;          /* index of water vapor species in mixture material */
 int cell_count=0;          /*counter to limit output messages*/
 
 real molwt_h2o=18.01528;  /* molecular weight of water g/mol */
 real molwt_air=28.949;
 real R_vap = UNIVERSAL_GAS_CONSTANT / 18.01528;    /*specific gas constant of water vapor J/kg/K */
 real R_air = UNIVERSAL_GAS_CONSTANT / 28.949  ;    /*for dry air*/
 
 
  real H2O_Saturation_Pressure(real T)
 {
  real ratio, aTmTp;
  T = MAX(T, 273);
  T = MIN(T, 647.286);
  aTmTp = .01 * (T - 338.15);
  ratio = (647.286 / T - 1.) *
          (-7.419242 + aTmTp * (.29721 +
                        aTmTp * (-.1155286 +
                        aTmTp * (8.685635e-3 +
                        aTmTp * (1.094098e-3 +
                        aTmTp * (-4.39993e-3 +
                        aTmTp * (2.520658e-3 -
                        aTmTp * 5.218684e-4)))))));
  return (22.089e6 * exp(MIN(ratio, 35.)));
 }
 
 real myHumidity(cell_t c, Thread *t)
 {
  int i;
  Material *m = THREAD_MATERIAL(t), *sp;
  real yi_h2o = 0.;      /* water mass fraction */
  real r_mix = 0.0;    /* sum of [mass fraction / mol. weight] over all species */
  real humidity;

  if ((MATERIAL_TYPE(m) == MATERIAL_MIXTURE) && (FLUID_THREAD_P(t)))
    {
      yi_h2o = C_YI(c, t, h2o_index);    /* water vapor mass fraction */
      mixture_species_loop(m, sp, i)
        {
          r_mix += C_YI(c,t,i) / MATERIAL_PROP(sp, PROP_mwi);
        }
     
      humidity = op_pres * yi_h2o / (molwt_h2o * r_mix) / H2O_Saturation_Pressure(C_T(c,t));
      return humidity;
    }
  else
    return 0.;
 }
 
 DEFINE_SOURCE(demister_mass_source, cell, thread, dS, eqn)
 {
    real relHumi = C_UDMI(cell,thread,UDM_RH);
    real rho_vap_excess=0.;
    real source_mass=0.;
    real subs=0.;
   
    if(relHumi > 1.0)
      {   
      rho_vap_excess = (relHumi-1.) * H2O_Saturation_Pressure(C_T(cell,thread)) / ( R_vap * C_T(cell, thread) );  /* kg/m3 */
      rho_vap_excess = rho_vap_excess;
      source_mass = -rho_vap_excess / CURRENT_TIMESTEP;
     
      /*derivative for improved convergence*/
      /*create substitutional term for derivative*/
      /*where rho_vap_excess is split up into every single flow variable it depends on und partly substituted by other variables*/
      subs = C_YI(cell, thread, h2o_index) * molwt_h2o * (R_air - R_vap)/ R_air + R_vap / R_air * molwt_h2o;
      /*dS[eqn] = (-C_P(cell, thread) * subs - C_P(cell,thread) * C_YI(cell, thread, h2o_index) * molwt_h2o * (R_air - R_vap)/R_air ) / pow(subs,2) / CURRENT_TIMESTEP;*/
      dS[eqn] = ((-C_P(cell, thread) * subs - C_P(cell,thread) * C_YI(cell, thread, h2o_index) * molwt_h2o * (R_air - R_vap)/R_air ) / pow(subs,2) * CURRENT_TIMESTEP + rho_vap_excess ) / pow(CURRENT_TIMESTEP, 2) ;
      }
    else
      {
      source_mass = 0.;
      dS[eqn]=0.;
      }

    C_UDMI(cell, thread, UDM_MASS) = source_mass;
    return source_mass;
 }
   

 DEFINE_SOURCE(demister_heat_source, cell, thread, dS, eqn)
 {
    real relHumi = C_UDMI(cell,thread,UDM_RH);
    real rho_vap_excess=0.;
    real source_mass=0.;
    real source_heat=0.;
    real subs=0.;
       
    if(relHumi > 1.0)
      {
      rho_vap_excess = (relHumi-1.) * H2O_Saturation_Pressure(C_T(cell,thread)) / ( R_vap * C_T(cell, thread) ); /*kg / m^3 */
      rho_vap_excess = rho_vap_excess;
      source_mass = -rho_vap_excess / CURRENT_TIMESTEP;
      source_heat = -source_mass * 2257e3; /* J/m^3/s  ; simplification: drops and gas phase are assumed to have equal temperature*/
   
      /*derivative for improved convergence*/
      /*create substitutional term for derivative*/
      /*where rho_vap_excess is split up into every single flow variable it depends on und partly substituted by other variables*/
      subs = C_YI(cell, thread, h2o_index) * molwt_h2o * (R_air - R_vap)/ R_air + R_vap / R_air * molwt_h2o;
      dS[eqn] = ((-C_P(cell, thread) * subs - C_P(cell,thread) * C_YI(cell, thread, h2o_index) * molwt_h2o * (R_air - R_vap)/R_air ) / pow(subs,2) * CURRENT_TIMESTEP + rho_vap_excess ) / pow(CURRENT_TIMESTEP, 2);
      }
    else
      {
      source_heat = 0.;
      dS[eqn]=0.;
      }

    C_UDMI(cell, thread, UDM_HEAT) = source_heat;
    return source_heat;
 }


 DEFINE_ADJUST(adj_relhum, domain)
 {
  cell_t cell;
  Thread *thread; 
  real humidity;
  real cum_mass_source = 0.;
  real cum_heat_source = 0.;
 
  cell_count = 0;

  thread_loop_c(thread, domain)
    {
        cum_mass_source = 0.;
        cum_heat_source = 0.;
        int curr_ts;
        curr_ts = N_TIME;
       
        /* Check if thread is a Fluid thread and has UDMs set up on it */
        if (FLUID_THREAD_P(thread) && NNULLP(THREAD_STORAGE(thread, SV_UDM_I)))
        {
          Material *m = THREAD_MATERIAL(thread), *sp;
          int i;
          /* Set the species index and molecular weight of water */
          if (MATERIAL_TYPE(m) == MATERIAL_MIXTURE)
            mixture_species_loop (m,sp,i)
              {
                if ((0 == strcmp(MIXTURE_SPECIE_NAME(m,i),"h2o")) ||
                    (0 == strcmp(MIXTURE_SPECIE_NAME(m,i),"H2O")) )
                  {
                    h2o_index = i;
                    molwt_h2o = MATERIAL_PROP(sp,PROP_mwi);
                  }
              }
       
          begin_c_loop(cell,thread)
            {
              humidity = myHumidity(cell, thread);
              C_UDMI(cell, thread, UDM_RH) = humidity;
            }
          end_c_loop(cell, thread)
        }

    }
 }
 
 DEFINE_EXECUTE_ON_LOADING(on_loading, libname)
 {
      Set_User_Memory_Name(0,"UDM-rel-humidity");
      Set_User_Memory_Name(1,"UDM-mass-source");
      Set_User_Memory_Name(2,"UDM-heat-source");
 }


vinerm February 19, 2020 05:10

Is it working
 
Is the code working properly now or do you face any issues?

2phase February 21, 2020 07:34

Yes,
it's working absolutely properly - as far as I could investigate. Should it not? Because I already stated that above.


Only issue: convergence is a bit slower, but generally working - I needed about 12-15 iterations per time step instead of less than 10.


Reducing time step might be another solution as well.

vinerm February 21, 2020 07:43

Good
 
Nice to know that it is working. 12-15 iterations per time-step is optimal.


All times are GMT -4. The time now is 13:59.