|
[Sponsors] |
June 30, 2021, 15:33 |
Need some support for UDF (my first time)
|
#1 |
Super Moderator
Tobias Holzmann
Join Date: Oct 2010
Location: Bad Wörishofen
Posts: 2,711
Blog Entries: 6
Rep Power: 52 |
ey everybody, I was in contact with the FLUENT support today regarding the evaporation of H2O2/H2O droplets. As stated in the theory guide, the liquid droplets/phase are assumed to be ideal which means that the activity coefficient is set to one. However, based on the customer, we know that the equilibrium to an ideal assumption is far away and hence, we need to incorporate the activity coefficient in the DPM model. We can use an already defined UDF for manipulating the concentration / partial pressure of each phase. The makro is given here: https://ansyshelp.ansys.com/account/...p_equilib.html
So, I just want to discuss the part I need to modify: Code:
/*********************************************************************** UDF for defining the vapor particle equilibrium for multicomponent particles ***********************************************************************/ #include <udf.h> DEFINE_DPM_VP_EQUILIB(raoult_vpe,tp,Tp,cvap_surf,Z) { int is; real molwt[MAX_SPE_EQNS]; Thread *t0 = TP_CELL_THREAD(tp); /* cell thread of particle location */ Material *gas_mix = THREAD_MATERIAL(t0); /* gas mixture material */ Material *cond_mix = TP_MATERIAL(tp); /* particle mixture material */ int nc = TP_N_COMPONENTS(tp); /* number of particle components */ real molwt_cond = 0.; /* reciprocal molecular weight of the particle */ for (is = 0; is < nc; is++) { int gas_index = TP_COMPONENT_INDEX_I(tp,is); /* index of vaporizing component in the gas phase */ if (gas_index >= 0) { /* the molecular weight of particle material */ molwt[gas_index] = MATERIAL_PROP(MIXTURE_COMPONENT(gas_mix,gas_index),PROP_mwi); molwt_cond += TP_COMPONENT_I(tp,is) / molwt[gas_index]; } } /* prevent division by zero */ molwt_cond = MAX(molwt_cond,DPM_SMALL); for (is = 0; is < nc; is++) { /* gas species index of vaporization */ int gas_index = TP_COMPONENT_INDEX_I(tp,is); if(gas_index >= 0) { /* condensed material */ Material * cond_c = MIXTURE_COMPONENT(cond_mix, is); /* condensed component molefraction */ real xi_cond = TP_COMPONENT_I(tp,is)/(molwt[gas_index]*molwt_cond); /* particle saturation pressure */ real p_saturation = DPM_vapor_pressure(tp, cond_c, Tp); if (p_saturation < 0.0) p_saturation = 0.0; /* vapor pressure over the surface, this is the actual Raoult law */ cvap_surf[is] = activity * xi_cond * p_saturation / UNIVERSAL_GAS_CONSTANT / Tp; } } /* compressibility for ideal gas */ *Z = 1.0; } Code:
if (species[i] == "h2o") { activity = activityH2O(temperature, mole-fraction-h2o) } else if (species[i] == "h2o2") { activity = activityH2O2(temperature, mole-fraction-h2o) } Code:
double activityH2O(const class temperature, const class mole-fraction) { double temp = 1; temp = exp(232*temperature) * moleFraction * some other things } Code:
DEFINE_FUNCTION(activityH2O, ....)
Code:
double activityH2O(double Tp, double xi_cond) { double tmp; // Calc tmp based on the droplet temperature Tp and h2o molefraction xi_cond return tmp; } Material * cond_c = MIXTURE_COMPONENT(cond_mix, is); Gives me the idea that I could use the cond_c pointer to call (maybe) the name of the species such das: string nameOfSpecies = cond_c->name(); Finally the last question. How can I be sure that this UDF is used later on? Thank you very much for your support. Tobi PS: After re-reading and thinking about the stuff I guess I am close to the guy: Code:
/* condensed material */ Material * cond_c = MIXTURE_COMPONENT(cond_mix, is); /* condensed component molefraction */ real xi_cond = TP_COMPONENT_I(tp,is)/(molwt[gas_index]*molwt_cond); /* particle saturation pressure */ real p_saturation = DPM_vapor_pressure(tp, cond_c, Tp); if (p_saturation < 0.0) p_saturation = 0.0; /* Activity coefficient */ real activity = activity(tp, Tp, xi_cond); /* vapor pressure over the surface, this is the actual Raoult law */ cvap_surf[is] = activity * xi_cond * p_saturation / UNIVERSAL_GAS_CONSTANT / Tp; } } /* compressibility for ideal gas */ *Z = 1.0; } real activity(Thread* tp, real Tp, real x) { real RT = 1.986 * Tp; real B0 = -752 + 0.97 * Tp real B1 = 85; real B2 = 13 /* if H2O */ return exp(pow(1-x, 2)/RT * (B0 + B1 * (1 - 4*x) + B2 * (1 -2*x) * (1 - 6*x))); /* if H2O2 */ /* return exp(pow(x, 2)/RT * (B0 + B1 * (3 - 4*x) + B2 * (1 - 2*x) * (5 - 6*x))); */ }
__________________
Keep foaming, Tobias Holzmann |
|
June 30, 2021, 21:54 |
|
#2 |
Senior Member
Alexander
Join Date: Apr 2013
Posts: 2,363
Rep Power: 34 |
as far as I understand you've almost done with the issue.
you may try to use following code for activity function Code:
real activity(Thread* t0, real Tp, real x) { real RT = 1.986 * Tp; real B0 = -752 + 0.97 * Tp real B1 = 85; real B2 = 13 if (FLUID_THREAD_P(t0) && NNULLP(THREAD_STORAGE(t0, SV_UDM_I))) { Material *m = THREAD_MATERIAL(t0), *sp; int i; 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")) ) { return exp(pow(1-x, 2)/RT * (B0 + B1 * (1 - 4*x) + B2 * (1 -2*x) * (1 - 6*x))); } else return exp(pow(x, 2)/RT * (B0 + B1 * (3 - 4*x) + B2 * (1 - 2*x) * (5 - 6*x))); } } }
__________________
best regards ****************************** press LIKE if this message was helpful |
|
July 1, 2021, 04:42 |
|
#3 |
Super Moderator
Tobias Holzmann
Join Date: Oct 2010
Location: Bad Wörishofen
Posts: 2,711
Blog Entries: 6
Rep Power: 52 |
Hey Alexander,
thank you for your reply. You got everything right. However, I will understand the code you posted. So can you give me some insights into the following lines: Code:
if (FLUID_THREAD_P(t0) && NNULLP(THREAD_STORAGE(t0, SV_UDM_I))) Code:
Material *m = THREAD_MATERIAL(t0), *sp; Code:
Material *m = TP_MATERIAL(t0); As both activity coefficients are based on the mole fraction of h2o in the droplet phase I would do it like that (not the best but okay-level): Code:
for (is = 0; is < nc; is++) { /* gas species index of vaporization */ int gas_index = TP_COMPONENT_INDEX_I(tp,is); if(gas_index >= 0) { /* condensed material */ Material * cond_c = MIXTURE_COMPONENT(cond_mix, is); /* condensed component molefraction */ real xi_cond = TP_COMPONENT_I(tp,is)/(molwt[gas_index]*molwt_cond); /* particle saturation pressure */ real p_saturation = DPM_vapor_pressure(tp, cond_c, Tp); if (p_saturation < 0.0) p_saturation = 0.0; /* ================ ADDED ================== */ /* Get h2o mole fraction */ real h2oMole = 0; int indexh2o = -1; int gasIndexh2o = -1; int ns = 0; Material *sp; /* Get the species index and gas index of h2o */ mixture_species_loop(cond_c, sp, ns) { if ((0 == strcmp(MIXTURE_SPECIE_NAME(cond_c,ns),"h2o") || (0 == strcmp(MIXTURE_SPECIE_NAME(cond_c,ns),"H2O")) { indexh2o = ns; gas_index_h2o = TP_COMPONENT_INDEX_I(tp,ns); break; } } /* Check if index is larger than zero - otherwise error */ if ((indexh2o >= 0) && (gas_index_h2o >= 0)) { /* stop fluent --> show message but how ??? */ } /* get mole fraction of h2o in droplet phase */ h2oMole = TP_COMPONENT_I(tp,indexh2o)/(molwt[gas_index_h2o]*molwt_cond) /* Activity coefficient */ real activity = activity(tp, Tp, h2oMole); /* vapor pressure over the surface, this is the actual Raoult law */ cvap_surf[is] = activity * xi_cond * p_saturation / UNIVERSAL_GAS_CONSTANT / Tp; } } /* compressibility for ideal gas */ *Z = 1.0; } real activity(Thread* tp, real Tp, real x) { real RT = 1.986 * Tp; real B0 = -752 + 0.97 * Tp real B1 = 85; real B2 = 13 if (FLUID_THREAD_P(t0) && NNULLP(THREAD_STORAGE(t0, SV_UDM_I))) { Material *m = TP_MATERIAL(t0), *sp; int i; 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")) ) { return exp(pow(1-x, 2)/RT * (B0 + B1 * (1 - 4*x) + B2 * (1 -2*x) * (1 - 6*x))); } else if (0 == strcmp(MIXTURE_SPECIE_NAME(m,i),"h2o2")) || (0 == strcmp(MIXTURE_SPECIE_NAME(m,i),"H2O2")) ) { return exp(pow(x, 2)/RT * (B0 + B1 * (3 - 4*x) + B2 * (1 - 2*x) * (5 - 6*x))); } else { // Stop simulation and show some info that it can only be used for h2o/h2o2 parcels - but how (similar to the indexes) } } } } Thank you in advance.
__________________
Keep foaming, Tobias Holzmann |
|
July 1, 2021, 21:52 |
|
#4 |
Senior Member
Alexander
Join Date: Apr 2013
Posts: 2,363
Rep Power: 34 |
you are right, you need
Code:
Material *m = TP_MATERIAL(t0); Code:
if (FLUID_THREAD_P(t0) && NNULLP(THREAD_STORAGE(t0, SV_UDM_I))) Unfortunately, I don't know about the list of available UDF function similar to Doxygen. Some documentations could be found in Ansys Fluent Customization manual. To stop the fluent you may use macro Code:
Error("text"); But I'm not sure if you can rerun simulation after this error, which is not convenient
__________________
best regards ****************************** press LIKE if this message was helpful |
|
July 3, 2021, 08:34 |
|
#5 |
Super Moderator
Tobias Holzmann
Join Date: Oct 2010
Location: Bad Wörishofen
Posts: 2,711
Blog Entries: 6
Rep Power: 52 |
Hi, thank you for your hint regarding the ERROR function. Do you know if I can throw a message to the console somehow. E.g.,
Code:
msg("Calculate activity"); EDIT: Regarding the message, I guess that I will try this one printing values from udf!!!
__________________
Keep foaming, Tobias Holzmann |
|
July 8, 2021, 20:21 |
|
#6 |
Senior Member
Alexander
Join Date: Apr 2013
Posts: 2,363
Rep Power: 34 |
from Ansys FLuent Customizatiion manual
Code:
After the UDF that you have defined using DEFINE_DPM_VP_EQUILIB is interpreted (Interpreting UDFs (p. 313)) or compiled (Compiling UDFs (p. 319)), the name of the argument that you supplied as the first DEFINE macro argument will become visible and selectable in the Create/Edit Materials dialog box in ANSYS Fluent. Note that before you hook the UDF, you’ll need to create particle injections in the Injections dialog box with the type Multicomponent chosen. As you've mentioned it is possible to write information to console using Message("text"); macro (works same as printf in C)
__________________
best regards ****************************** press LIKE if this message was helpful |
|
July 9, 2021, 14:57 |
|
#7 |
Super Moderator
Tobias Holzmann
Join Date: Oct 2010
Location: Bad Wörishofen
Posts: 2,711
Blog Entries: 6
Rep Power: 52 |
Hey Alex,
thank you very much for your support. The library is ready and works as expected. The last week I was using the manuals of fluent intensively and hence, I could solve a lot of problems. In addition, your feedback is highly valuable and hence, I want to thank you for taking your private time for your replys.
__________________
Keep foaming, Tobias Holzmann |
|
August 2, 2021, 07:14 |
|
#8 |
Super Moderator
Tobias Holzmann
Join Date: Oct 2010
Location: Bad Wörishofen
Posts: 2,711
Blog Entries: 6
Rep Power: 52 |
Hey everybody,
I just want to give all of you (who are doing similar things) the procedure you need to make a correct H2O/H2O2 evaporation analysis:
Done. The main challange was the iterative process of the H2O and H2O2 saturation pressure as these guys are not a function of temperature only as they are a function of the other species as well. Doing so, you will have a very accurate analysis. Some speedup possibilities:
This will save a lot of computational power as the vapor equilibrium calculation is called several times. However, the simplification lead to less accuracy as the saturation pressures are (a) not based on the parcel temperature (b) not updated during the DPM iteration.
__________________
Keep foaming, Tobias Holzmann |
|
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Elastic or Plastic Deformations in OpenFOAM | NickolasPl | OpenFOAM Pre-Processing | 36 | September 23, 2023 09:22 |
[solidMechanics] Support thread for "Solid Mechanics Solvers added to OpenFOAM Extend" | bigphil | OpenFOAM CC Toolkits for Fluid-Structure Interaction | 686 | December 22, 2022 10:10 |
Extrusion with OpenFoam problem No. Iterations 0 | Lord Kelvin | OpenFOAM Running, Solving & CFD | 8 | March 28, 2016 12:08 |
simpleFoam error - "Floating point exception" | mbcx4jc2 | OpenFOAM Running, Solving & CFD | 12 | August 4, 2015 03:20 |
dynamic Mesh is faster than MRF???? | sharonyue | OpenFOAM Running, Solving & CFD | 14 | August 26, 2013 08:47 |