# Porosity Variation with Time

 Register Blogs Members List Search Today's Posts Mark Forums Read

June 6, 2016, 13:09
Porosity Variation with Time
#1
Member

Join Date: Jun 2016
Posts: 64
Rep Power: 10
Hello everyone,

I am a college student trying to model the flow of acid through a porous rock sample. After some research, I have come to the conclusion that I need to write a UDF for the change in porosity as a function of time due to the acid reacting with the rock.

From what I understand, I need to use the DEFINE_PROFILE macro. Inside the macro, I need to loop over each of the cells to define the new porosity at each new time. For the sake of simplicity, the porosity formula (of the solid) I will be using is as follows:

Quote:
 φ is the new porosity X is a constant Δt is the change in time φ_0 is the old porosity
I have two questions.
1. How do I define an initial porosity that isn't constant across all cells, since I want a random porosity distribution?
2. How do I store the "new" value of porosity for each cell so that it can be accessed and used as the "old" porosity for the next calculation? I know that a C_POR function exists, but will I assumed it only pulled the initial porosity.
Below I've included a skeleton of the what I have come up with so far. Any help would be greatly appreciated as I have scoured the internet and come up empty handed. I did find some useful information in this thread, but nothing that answers my questions.

Code:
```#include "udf.h"

DEFINE_PROFILE(porosity_variation,t,i)
{
real delta_t = CURRENT_TIMESTEP; /* not sure if this should be PREVIOUS_TIMESTEP instead */
real X = 1.0; /* this is an arbitrary value */
cell_t c;

begin_c_loop(c,t)
{
C_PROFILE(c,t,i) = 1 - (X * delta_t - phi_0 ^ 2 + phi_0) / (X * delta_t - phi_0 + 1);
}
end_c_loop(c,t)
}```

Last edited by Baden; June 8, 2016 at 12:47.

June 7, 2016, 05:52
#2
Senior Member

Join Date: May 2014
Posts: 271
Rep Power: 13
Quote:
 Originally Posted by Baden Hello everyone,How do I define an initial porosity that isn't constant across all cells, since I want a random porosity distribution?
you can add #include <stdlib.h> and use the function randomize() to generate a random number to you.
Quote:
 How do I store the "new" value of porosity for each cell so that it can be accessed and used as the "old" porosity for the next calculation? I know that a C_POR function exists, but will I assumed it only pulled the initial porosity.
you can storage the value of the porosity in a UDMI at the end of each iteration using the macro DEFINE_AT_THE_END.

June 7, 2016, 10:13
#3
Member

Join Date: Jun 2016
Posts: 64
Rep Power: 10
Thank you so much for the response.

Quote:
 Originally Posted by Bruno Machado you can add #include and use the function randomize() to generate a random number to you.
To expand on this, would I include the initial porosity generation inside the same UDF as my porosity variation with time? If not, where would be the appropriate place to hook these two UDFs?

Quote:
 Originally Posted by Bruno Machado you can storage the value of the porosity in a UDMI at the end of each iteration using the macro DEFINE_AT_THE_END.
Are you referring the the DEFINE_EXECUTE_AT_END macro? If so, would you mind explaining how you intended it to be used? I've read through this page and don't quite understand it's use in my application.

June 7, 2016, 11:17
#4
Senior Member

Join Date: May 2014
Posts: 271
Rep Power: 13
Quote:
 Originally Posted by Baden Thank you so much for the response. To expand on this, would I include the initial porosity generation inside the same UDF as my porosity variation with time? If not, where would be the appropriate place to hook these two UDFs? Are you referring the the DEFINE_EXECUTE_AT_END macro? If so, would you mind explaining how you intended it to be used? I've read through this page and don't quite understand it's use in my application.
1) you can use the function to generate a random number. multiply it to the porosity in the cell and it should give you a "non uniform" porosity. just be careful, because if it varies too much, lets say porosity between 0.1 and 0.9, it can lead to divergence problems.

2) yes, my mistake, typed it quickly and did not check the right macro. the DEFINE_EXECUTE_AT_END executes a command at the end of each iteration. what you can do is an if statement that storage the value of porosity in the UDMI with dependence in a relation of time and current time step.

June 7, 2016, 13:06
#5
Member

Join Date: Jun 2016
Posts: 64
Rep Power: 10
Quote:
 Originally Posted by Bruno Machado 2) yes, my mistake, typed it quickly and did not check the right macro. the DEFINE_EXECUTE_AT_END executes a command at the end of each iteration. what you can do is an if statement that storage the value of porosity in the UDMI with dependence in a relation of time and current time step.
I am still struggling to understand how to achieve the time variation. Since the variable I'm using is native to Fluent (porosity), is there not a way to call it without using UDM? The only example I could find of what you are describing is in this thread and it doesn't provide an example of the "if statement" one would have to use to only run at the end of a timestep for steady-state flow.

I'm relatively new to Fluent and there aren't many examples on the internet of what I'm trying to do so I'm having a hard time following. Is there a chance you could post a sample UDF code or a modification to the code I wrote to demonstrate how I would make the porosity dependent on time?

Again, I really appreciate you taking the time to answer my questions.

Last edited by Baden; June 7, 2016 at 17:17.

 June 7, 2016, 17:16 #6 Member   Join Date: Jun 2016 Posts: 64 Rep Power: 10 Here is an update of the code I have so far, which is based on this thread. Code: ```#include "udf.h" DEFINE_PROFILE(porosity_variation,t,i) { real X = 1; /* arbitrary constant */ real delta_t = CURRENT_TIMESTEP; cell_t c; begin_c_loop(c,t) { if (N_TIME == 1) { C_PROFILE(c,t,i) = 0.8; } else { real phi_0 = C_UDMI(c,t,0); C_PROFILE(c,t,i) = 1 - (-(phi_0 * phi_0) + phi_0 + X * delta_t) / (-phi_0 + X * delta_t + 1); } C_UDMI(c,t,0) = C_PROFILE(c,t,i); } end_c_loop(c,t) }``` I'm not quite sure if it will do what I want it to do, so any input is welcome. I've set the initial porosity to be a constant 0.8 for all cells (or at least that's what I intended it to do) so I could tackle one problem at a time. Last edited by Baden; June 8, 2016 at 12:47.

June 8, 2016, 04:40
#7
Senior Member

Join Date: May 2014
Posts: 271
Rep Power: 13
Quote:
 Originally Posted by Baden Here is an update of the code I have so far, which is based on this thread. I'm not quite sure if it will do what I want it to do, so any input is welcome. I've set the initial porosity to be a constant 0.8 for all cells (or at least that's what I intended it to do) so I could tackle one problem at a time.
did you try to compile and run?

just couple of things. instead of using "1", use "1.0". I spent over a month trying to find a bug in my code and it was that the compiler was messing with a number because of the decimal place.

and you have to initialize your UDMI, otherwise phi_0 has no value. You can initialize it in you initialization process as 0.8 and then use it like this.

Code:
```#include "udf.h"

DEFINE_PROFILE(porosity_variation,t,i)
{
real X = 1.0; /* arbitrary constant */
real delta_t = CURRENT_TIMESTEP;
cell_t c;

begin_c_loop(c,t)
{
if (N_TIME == 1)
{
C_PROFILE(c,t,i) = C_UDMI(c,t,0);
}
else
{
real phi_0 = C_UDMI(c,t,0);
C_PROFILE(c,t,i) = 1.0 - (-(phi_0 * phi_0) + phi_0 + X * delta_t) / (-phi_0 + X * delta_t + 1.0);
}
C_UDMI(c,t,0) = C_PROFILE(c,t,i);
}
end_c_loop(c,t)
}```

June 8, 2016, 12:45
#8
Member

Join Date: Jun 2016
Posts: 64
Rep Power: 10
Quote:
 Originally Posted by Bruno Machado did you try to compile and run? just couple of things. instead of using "1", use "1.0". I spent over a month trying to find a bug in my code and it was that the compiler was messing with a number because of the decimal place. and you have to initialize your UDMI, otherwise phi_0 has no value. You can initialize it in you initialization process as 0.8 and then use it like this.
I made the suggested changes as well as attempted to add a macro to initialize the UDMI:

Code:
```#include "udf.h"

DEFINE_PROFILE(porosity_variation,t,i)
{
real X = 1.0;
real delta_t = CURRENT_TIMESTEP;
cell_t c;

begin_c_loop(c,t)
{
if (N_TIME == 1)
{
C_PROFILE(c,t,i) = C_UDMI(c,t,0);
}
else
{
real phi_0 = C_UDMI(c,t,0);
C_PROFILE(c,t,i) = 1.0 - (-(phi_0 * phi_0) + phi_0 + X * delta_t) / (-phi_0 + X * delta_t + 1.0);
}
C_UDMI(c,t,0) = C_PROFILE(c,t,i);
}
end_c_loop(c,t)
}

DEFINE_INIT(UDMI0_init,d)
{
cell_t c;
Thread *t_fluid = Lookup_Thread(d,3); /* 3 is the ID of the fluid */

{
if (t == t_fluid)
{
begin_c_loop(c,t)
{
C_UDMI(c,t,0) = 0.8;
}
end_c_loop(c,t)
}
}
}```
I interpreted the code and ran it, however, either I did the setup incorrectly or the code is not correct seeing as the porosity values did not appear to change. I have a feeling that the initialization code is wildly incorrect, but it is the best I could figure out.

Also, earlier you said:

Quote:
 Originally Posted by Bruno Machado 2) yes, my mistake, typed it quickly and did not check the right macro. the DEFINE_EXECUTE_AT_END executes a command at the end of each iteration. what you can do is an if statement that storage the value of porosity in the UDMI with dependence in a relation of time and current time step.
Since my code is not doing this, could the lack of change in porosity be caused by storing the previous UDMI value for each iteration rather than each timestep? I attempted to use the DEFINE_EXECUTE_AT_END macro, but I couldn't figure out how to only run it at the end of each timestep since I'm doing steady-state.

Last edited by Baden; June 8, 2016 at 17:18.

June 9, 2016, 04:25
#9
Senior Member

Join Date: May 2014
Posts: 271
Rep Power: 13
Quote:
 Originally Posted by Baden I made the suggested changes as well as attempted to add a macro to initialize the UDMI: Code: ```#include "udf.h" DEFINE_PROFILE(porosity_variation,t,i) { real X = 1.0; real delta_t = CURRENT_TIMESTEP; cell_t c; begin_c_loop(c,t) { if (N_TIME == 1) { C_PROFILE(c,t,i) = C_UDMI(c,t,0); } else { real phi_0 = C_UDMI(c,t,0); C_PROFILE(c,t,i) = 1.0 - (-(phi_0 * phi_0) + phi_0 + X * delta_t) / (-phi_0 + X * delta_t + 1.0); } C_UDMI(c,t,0) = C_PROFILE(c,t,i); } end_c_loop(c,t) } DEFINE_INIT(UDMI0_init,d) { Thread *t; cell_t c; Thread *t_fluid = Lookup_Thread(d,3); /* 3 is the ID of the fluid */ thread_loop_c(t,d) { if (t == t_fluid) { begin_c_loop(c,t) { C_UDMI(c,t,0) = 0.8; } end_c_loop(c,t) } } }``` I interpreted the code and ran it, however, either I did the setup incorrectly or the code is not correct seeing as the porosity values did not appear to change. I have a feeling that the initialization code is wildly incorrect, but it is the best I could figure out. Also, earlier you said: Since my code is not doing this, could the lack of change in porosity be caused by storing the previous UDMI value for each iteration rather than each timestep? I attempted to use the DEFINE_EXECUTE_AT_END macro, but I couldn't figure out how to only run it at the end of each timestep since I'm doing steady-state.
I am not sure how the time step macros work, but instead of using (N_TIME == 1) try to do an if with an increment in a integer and see if it varies as you expect. then you can check rather the problem is in the loop or in the if statements.

"DEFINE_EXECUTE_AT_END is a general purpose macro that is executed at the end of an iteration in a steady state run, or at the end of a time step in a transient run.". It runs automatically at the end of each iteration/time step for stead-state/transient case. Did you hook it properly?

June 9, 2016, 14:19
#10
Member

Join Date: Jun 2016
Posts: 64
Rep Power: 10
Quote:
 Originally Posted by Bruno Machado I am not sure how the time step macros work, but instead of using (N_TIME == 1) try to do an if with an increment in a integer and see if it varies as you expect. then you can check rather the problem is in the loop or in the if statements. "DEFINE_EXECUTE_AT_END is a general purpose macro that is executed at the end of an iteration in a steady state run, or at the end of a time step in a transient run.". It runs automatically at the end of each iteration/time step for stead-state/transient case. Did you hook it properly?
Due to my lack of knowledge of UDFs, I don't quite understand. Please forgive my lack of knowledge as my understanding of UDFs is limited to the user manual and the information that you have provided.

Let me outline what I think I need to do. Please correct me if I'm wrong.
1. use a DEFINE_INIT macro to set the initial the values of porosity
2. use a DEFINE_PROFILE macro to change the porosity profile as a function of time and previous porosity
3. use UDMI to store the value of previous porosity for each cell so it can be called in the next iteration
4. use a DEFINE_EXECUTE_AT_END macro to store the calculated value of porosity in the UDMI at the end of each iteration
5. add an if statement to the DEFINE_EXECUTE_AT_END macro to make it only run per timestep rather than per iteration (I'm not sure about this step, but it seems to be what was suggested here)

June 10, 2016, 04:10
#11
Senior Member

Join Date: May 2014
Posts: 271
Rep Power: 13
Quote:
 Originally Posted by Baden Due to my lack of knowledge of UDFs, I don't quite understand. Please forgive my lack of knowledge as my understanding of UDFs is limited to the user manual and the information that you have provided. Let me outline what I think I need to do. Please correct me if I'm wrong. use a DEFINE_INIT macro to set the initial the values of porosity use a DEFINE_PROFILE macro to change the porosity profile as a function of time and previous porosity use UDMI to store the value of previous porosity for each cell so it can be called in the next iteration use a DEFINE_EXECUTE_AT_END macro to store the calculated value of porosity in the UDMI at the end of each iteration add an if statement to the DEFINE_EXECUTE_AT_END macro to make it only run per timestep rather than per iteration (I'm not sure about this step, but it seems to be what was suggested here)
you are mostly right. in the 5th step, looks like you don't need to add any if condition to run it to each time step, once it does like that automatically. have a look at its definition in the manual:

Quote:
 DEFINE_EXECUTE_AT_END is a general purpose macro that is executed at the end of an iteration in a steady state run, or at the end of a time step in a transient run.
http://jullio.pe.kr/fluent6.1/help/html/udf/node55.htm

In other words, it wont compute anything in the DEFINE_AT_THE_END unless at the end of the time step for transient cases.

June 10, 2016, 10:25
#12
Member

Join Date: Jun 2016
Posts: 64
Rep Power: 10
Quote:
 Originally Posted by Bruno Machado you are mostly right. in the 5th step, looks like you don't need to add any if condition to run it to each time step, once it does like that automatically. have a look at its definition in the manual: http://jullio.pe.kr/fluent6.1/help/html/udf/node55.htm In other words, it wont compute anything in the DEFINE_AT_THE_END unless at the end of the time step for transient cases.
Right, however, I am running my simulation as steady-state. So from what I understand, I need an if statement to make it only run at the end of a timestep?

June 10, 2016, 10:32
#13
Senior Member

Join Date: May 2014
Posts: 271
Rep Power: 13
Quote:
 Originally Posted by Baden Right, however, I am running my simulation as steady-state. So from what I understand, I need an if statement to make it only run at the end of a timestep?
but if you are running it stead-state, there is no time step...

June 10, 2016, 10:42
#14
Member

Join Date: Jun 2016
Posts: 64
Rep Power: 10
Quote:
 Originally Posted by Bruno Machado but if you are running it stead-state, there is no time step...
I feel like and idiot. I did not know this.

So how would I model a change in porosity as a function of time if there isn't a timestep? Is there another way to get change in time other than this?

Code:
`real dt = CURRENT_TIMESTEP;`

June 10, 2016, 10:50
#15
Senior Member

Join Date: May 2014
Posts: 271
Rep Power: 13
Quote:
 Originally Posted by Baden I feel like and idiot. I did not know this. So how would I model a change in porosity as a function of time if there isn't a timestep? Is there another way to get change in time other than this? Code: `real dt = CURRENT_TIMESTEP;`
the steady state solution is the one when time is equal to infinity, in other words, it wont change anymore. If you want it to vary on time, you need to run a transient solution.

This macro is for transient case, which is the way you gotta run your case if you want time variation on it. Have a look about the transient problem in the manual and you can also have a look in youtube, there are many videos of time dependent variation.

June 10, 2016, 10:52
#16
Member

Join Date: Jun 2016
Posts: 64
Rep Power: 10
Quote:
 Originally Posted by Bruno Machado the steady state solution is the one when time is equal to infinity, in other words, it wont change anymore. If you want it to vary on time, you need to run a transient solution. This macro is for transient case, which is the way you gotta run your case if you want time variation on it. Have a look about the transient problem in the manual and you can also have a look in youtube, there are many videos of time dependent variation.
Alright, I will. I didn't realize I would have to run it as transient since my flow rate is steady-state. Much appreciated.

I will report back if I encounter any more problems.

 June 10, 2016, 13:56 #17 Member   Join Date: Jun 2016 Posts: 64 Rep Power: 10 I do have one question about the DEFINE_EXECUTE_AT_END macro. I'm trying to store the calculated value of porosity in the UDMI using the DEFINE_EXECUTE_AT_END macro but I'm not quite sure how to reference the porosity since the C_PROFILE macro requires an index (i). Code: ```#define ID 3.0 /* ID of the fluid */ DEFINE_EXECUTE_AT_END(execute_at_end) { Domain *d; Thread *t; Thread *t_fluid = Lookup_Thread(d,ID); cell_t c; d = Get_Domain(1); /* mixture domain if multiphase */ thread_loop_c(t,d) { if (t == t_fluid) { begin_c_loop(c,t) { C_UDMI(c,t,0) = C_PROFILE(c,t,???) } end_c_loop(c,t) } } }``` I guess my question is how do I pull the index for the porosity variable so I can reference it?

June 10, 2016, 15:47
#18
Senior Member

Join Date: May 2014
Posts: 271
Rep Power: 13
Quote:
 Originally Posted by Baden I do have one question about the DEFINE_EXECUTE_AT_END macro. I'm trying to store the calculated value of porosity in the UDMI using the DEFINE_EXECUTE_AT_END macro but I'm not quite sure how to reference the porosity since the C_PROFILE macro requires an index (i). Code: ```#define ID 3.0 /* ID of the fluid */ DEFINE_EXECUTE_AT_END(execute_at_end) { Domain *d; Thread *t; Thread *t_fluid = Lookup_Thread(d,ID); cell_t c; d = Get_Domain(1); /* mixture domain if multiphase */ thread_loop_c(t,d) { if (t == t_fluid) { begin_c_loop(c,t) { C_UDMI(c,t,0) = C_PROFILE(c,t,???) } end_c_loop(c,t) } } }``` I guess my question is how do I pull the index for the porosity variable so I can reference it?
I wrote what I think will work for you. I did not compile, so might have some mistakes. The logic is explained in the code. Hope it clarifies things to you.

Code:
```#include "udf.h"

#define ID 3.0 /* ID of the fluid */

/* in this part, the value of the porosity is initialised as 0.8 */
DEFINE_INIT(UDMI0_init,d)
{
cell_t c;
Thread *t_fluid = Lookup_Thread(d,3); /* 3 is the ID of the fluid */

{
if (t == t_fluid)
{
begin_c_loop(c,t)
{
C_UDMI(c,t,0) = 0.8;
}
end_c_loop(c,t)
}
}
}

/* this macro will read the value of the UDMI_0. For the first time step, it will be 0.8,
after that, it will use the value of the UDMI_0 calculated in the DEFINE_EXECUTE_AT_END */

DEFINE_PROFILE(porosity_variation,t,i)
{

cell_t c;

begin_c_loop(c,t)
{
C_PROFILE(c,t,i) = C_UDMI(c,t,0);
}
end_c_loop(c,t)
}

/*Since this macro is only executed at the end of each time step, there is no need to an IF statement.
This command will define that phi_0 is the value of the old porosity, then the porosity_new can be solved and followed by the definition of the new value of the UDMI_0.
This value will be read by the DEFINE_PROFILE as the new value of the porosity at the end of each time step*/

DEFINE_EXECUTE_AT_END(execute_at_end)
{
Domain *d;
cell_t c;
d = Get_Domain(1);    /* mixture domain if multiphase */
real porosity;
real X = 1.0; /* arbitrary constant */
real delta_t = CURRENT_TIMESTEP;

{
if (t == t_fluid)
{
begin_c_loop(c,t)
{
real phi_0 = C_UDMI(c,t,0);
porosity_new = 1.0 - (-(phi_0 * phi_0) + phi_0 + X * delta_t) / (-phi_0 + X * delta_t + 1.0);
C_UDMI(c,t,0) = porosity_new;
}
}
end_c_loop(c,t)
}
}
}```

June 10, 2016, 17:06
#19
Member

Join Date: Jun 2016
Posts: 64
Rep Power: 10
Quote:
 Originally Posted by Bruno Machado I wrote what I think will work for you. I did not compile, so might have some mistakes. The logic is explained in the code. Hope it clarifies things to you.
Thank you very much. I never thought about calculating the new porosity value in the DEFINE_EXECUTE_AT_END macro as opposed to the DEFINE_PROFILE macro.

I did notice one oddity when interpreting the code (I don't compile it because I've read the manual and still have no idea how to). I received a parse error whenever the "d = Get_Domain(1);" was placed on any line above where it is now in the following code:

Code:
```DEFINE_EXECUTE_AT_END(execute_at_end)
{
Domain *d;
cell_t c;
real X = 1.0;
real dt = CURRENT_TIMESTEP;
d = Get_Domain(1);

{
if (t == t_fluid)
{
begin_c_loop(c,t)
{
real phi_0 = C_UDMI(c,t,0);
real phi = 1.0 - (-(phi_0 * phi_0) + phi_0 + X * dt) / (-phi_0 + X * dt + 1.0);
C_UDMI(c,t,0) = phi;
}
end_c_loop(c,t)
}
}
}```

 June 10, 2016, 17:55 #20 Senior Member   Join Date: Mar 2015 Posts: 892 Rep Power: 18 Fluent uses ANSI C which follows a number of strict rules including the requirement of declaring all variables at the beginning of a code block. However, you can declare and initialise the domain thread on one line with: Code: `Domain *d = Get_Domain(1);` Baden likes this.

 Tags acid, porosity, time, transient, udf

 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 OffTrackbacks are Off Pingbacks are On Refbacks are On Forum Rules

 Similar Threads Thread Thread Starter Forum Replies Last Post vaina74 OpenFOAM Pre-Processing 37 July 20, 2020 05:38 mbcx4jc2 OpenFOAM Running, Solving & CFD 12 August 4, 2015 02:20 shipman OpenFOAM Programming & Development 25 March 19, 2014 10:08 Heroic OpenFOAM Running, Solving & CFD 26 December 17, 2012 03:34 jonmec OpenFOAM Running, Solving & CFD 3 July 28, 2011 05:24

All times are GMT -4. The time now is 00:40.