DPM Water Spray Model Customizing for 'Condensation' with DPM_SWITCH UDF
Dear ANSYS Community,
I hope you are all doing well.
I am trying to simulate a spray system to replicate a wind-tunnel + spray cooling experiment. Although, the DPM module is perfect and gives me good results, when I have to run some specific cooling conditions, I receive more than 100% RH at the outlet. After some research, I have come across the DPM_SWITCH code in the manual.
Nonetheless, I am having some trouble running the code. Even though it compiles fine under Fluent.
Here is some background information about my model:
Inlet air mass flow: 0.5 kg/s - RH: 51% @25 Deg C.
Water Injection: 0.27 kg/s @5 Deg C.
Geometry:
To mitigate the over-saturation problem at the outlet, wanted to customize the Fluent with a UDF and for that the custom law is checked and looks like this:
I have found the DPM_SWITCH UDF in the manual (p. 184, 2013, Release 15.0) and compiled in the Fluent with no problem.
However, when I run the simulation and when the DPM_SWITCH custom law is engaged, I am receiving several errors.
The errors change based on parallel and serial running. I am not super knowledgeable with UDF coding but I understand that the code may not be compatible with parallel running. As I have observed, the errors received during parallel run is mostly related to either MPI or Node # receiving a signal and 'fl' process not being able to start.
However, when I run on the host node only (i.e. either Serial or Parallel with '0' node), I receive the following message.
I am running this on my local machine.
---------------------------------------------------------------------------
Error: received a fatal signal (Segmentation fault).
Error: received a fatal signal (Segmentation fault).
Error Object: #f
---------------------------------------------------------------------------
I am a little lost here guys and would really appreciate some back up!
Let me know if you need to know more.
Thank you!
Cheers,
Ali
Best Answer
-
Rob UKForum Coordinator Posts: 8,371
In User Defined you need to switch on the memory locations before loading the UDF. We assume zero by default as it saves memory/file size. You need a memory (and/or scalar) available for the above UDF.
Answers
Also, here is the code:
/**********************************************************************
Concatenated UDFs for the Discrete Phase Model including
an implementation of a condensation model
an example for the use of DPM_SWITCH
***********************************************************************/
#include "udf.h"
#include "dpm.h"
#define UDM_RH 0 /* no. of UDM holding relative humidity */
#define N_REQ_UDM 1 /* 1 more than UDM_RH */
#define CONDENS 1.0e-4 /* a condensation rate constant */
int h2o_index=0; /* index of water vapor species in mixture material */
real mw_h2o=18.; /* molecular weight of water */
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 / (mw_h2o * r_mix) /
H2O_Saturation_Pressure(C_T(c,t));
return humidity;
}
else
return 0.;
}
DEFINE_DPM_LAW(condenshumidlaw, p, coupled)
{
real area;
real mp_dot;
/* Get Cell and Thread from Particle Structure */
cell_t c = P_CELL(p);
Thread *t = P_CELL_THREAD(p);
area = 4.0 * M_PI * (P_DIAM(p) * P_DIAM(p));
/* Note This law only used if Humidity > 1.0 so mp_dot always positive*/
mp_dot = CONDENS * sqrt(area) * (myHumidity(c, t) - 1.0);
if (mp_dot > 0.0)
{
P_MASS(p) += mp_dot * P_DT(p);
P_DIAM(p) = pow(6.0 * P_MASS(p) / (P_RHO(p) * M_PI), 1./3.);
}
/* Assume condensing particle is in thermal equilibrium with fluid in cell */
P_T(p) = C_T(c,t);
}
DEFINE_DPM_SOURCE(dpm_source, c, t, S, strength, p)
{
real mp_dot;
/* mp_dot is the mass source to the continuous phase
* (Difference in mass between entry and exit from cell)
* multiplied by strength (Number of particles/s in stream)
*/
mp_dot = (P_MASS0(p) - P_MASS(p)) * strength;
if (P_CURRENT_LAW(p) == DPM_LAW_USER_1)
{
/* Sources relevant to the user law 1:
* add the source to the condensing species
* equation and adjust the energy source by
* adding the latent heat at reference temperature
*/
S->species[h2o_index] += mp_dot;
S->energy -= mp_dot * P_INJECTION(p)->latent_heat_ref;
}
}
DEFINE_DPM_SWITCH(dpm_switch, p, coupled)
{
cell_t c = P_CELL(p);
Thread *t = P_CELL_THREAD(p);
Material *m = P_MATERIAL(p);
/* If the relative humidity is higher than 1
* and the particle temperature below the boiling temperature
* switch to condensation law
*/
if ((C_UDMI(c,t,UDM_RH) > 1.0) && (P_T(p) < DPM_BOILING_TEMPERATURE(p, m)))
P_CURRENT_LAW(p) = DPM_LAW_USER_1;
else
P_CURRENT_LAW(p) = DPM_LAW_INITIAL_INERT_HEATING;
}
DEFINE_ADJUST(adj_relhum, domain)
{
cell_t cell;
Thread *thread;
if(sg_udm < N_REQ_UDM)
Message("\nNot enough user defined memory allocated. %d required.\n",
N_REQ_UDM);
else
{
real humidity, min, max;
min = 1e10;
max = 0.0;
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;
mw_h2o = MATERIAL_PROP(sp,PROP_mwi);
}
}
begin_c_loop(cell,thread)
{
humidity = myHumidity(cell, thread);
min = MIN(min, humidity);
max = MAX(max, humidity);
C_UDMI(cell, thread, UDM_RH) = humidity;
}
end_c_loop(cell, thread)
}
}
Message("\nRelative Humidity set in udm-%d", UDM_RH);
Message(" range:(%f,%f)\n", min, max);
}/* end if for enough UDSs and UDMs */
}
DEFINE_ON_DEMAND(set_relhum)
{
adj_relhum(Get_Domain(1));
}
I assume that you assigned enough UDM in the solver? I've not read, and am not going to, the rest of the code.
Hey Rob,
Thanks for the reply. Now that you are saying that, I think that might be my problem. Could you please help me on how to fix that one?
Cheers,
In User Defined you need to switch on the memory locations before loading the UDF. We assume zero by default as it saves memory/file size. You need a memory (and/or scalar) available for the above UDF.
You should in addition hook the dpm law. And update to a supported release.