CFD Online Logo CFD Online URL
www.cfd-online.com
[Sponsors]
Home > Forums > Software User Forums > ANSYS > FLUENT > Fluent UDF and Scheme Programming

Variable Surface Tension Modelling UDF (Modifications to CSF)

Register Blogs Community New Posts Updated Threads Search

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   March 8, 2021, 16:18
Question Variable Surface Tension Modelling UDF (Modifications to CSF)
  #1
Member
 
Venkat Ganesh
Join Date: May 2020
Location: Cincinnati, Ohio
Posts: 49
Rep Power: 6
Venky_94 is on a distinguished road
Hey,
I'm new to UDFs in FLUENT and am writing a UDF involving a modification in the interface curvature calculation part of the CSF model to smoothen it.

So far, I've understood that C_VOF_G(c,t) can calculate gradient of volume fraction and NV_MAG(C_VOF_G(c,t)) can calculate magnitude of volume fraction. For the divergence part, will I have to save the unit normal in a UDS (C_UDSI) using a cell loop, and assign C_USDI_G to the interface curvature "k" to directly access the gradient of the scalar?

I would also like to modify the property determination method for the VOF model as indicated in the picture. How would I be implementing this change on FLUENT?

Also where would I be hooking both these UDFs exactly?
Attached Images
File Type: jpg Modified VOF.JPG (56.6 KB, 80 views)
Venky_94 is offline   Reply With Quote

Old   March 23, 2021, 06:28
Default
  #2
Member
 
Venkat Ganesh
Join Date: May 2020
Location: Cincinnati, Ohio
Posts: 49
Rep Power: 6
Venky_94 is on a distinguished road
I've written a UDF for the surface tension force which I'm sharing below. I'm getting a bunch of errors that I've looked around for but am unable to resolve. Any help would be appreciated.

Code:
/***********************************************************************
UDF for defining surface tension source term and interface smoothening
************************************************************************/

#include "udf.h"

DEFINE_SOURCE(surface_tension_force,c,t,dS,eqn)
{

/* Note that t is the mixture thread passed by the solver in this case */

Domain *d;

real source;
real k;						/* interface curvature */
real ncap;					/* unit normal */
real n;						/* a function of the phase fraction */
real sigma = 0.072;				/* surface tension coefficient */
real alphacell = C_UDMI(c,t,1);			/* calculates the area averaged volume fraction of individual cell */
real rho1 = 1.225;				/* Density of air */
real rho2 = 1;					/* Density of non-Newtonian fluid */

C_UDSI(c,t,0) = alphacell;			/* Fill UDS with the alphacell values to get gradient value */

n = C_UDSI_G(c,t,0);				/* Get value of n as the gradient of alphacell (phase fraction) */
ncap = n/NV_MAG(n);				/* calculate unit vector */

C_UDSI(c,t,1) = ncap;				/* Fill another UDS with the variable ncap */

k = C_UDSI_G(c,t,1);				/* Get value of k as the gradient of ncap */

source = sigma*k*C_R(c,t)*n/(0.5*(rho1+rho2));	/* Calculate the surface tension force */
dS[eqn] = 0;
return source;
}
Quote:
Copied \clusterfsnew.ceas1.uc.edu\students\ganeshvt\deskt op\Ansys_Simulations\Bubble_Setup_files\dp0\FFF\Fl uent/\clusterfsnew.ceas1.uc.edu\students\ganeshvt\deskt op\Ansys_Simulations\Bubble_Setup_files\dp0\FFF\Fl uent\Surfacetension_Sourceterm.c to libudf\src
Creating user_nt.udf file for 2ddp_host ...
(system "copy "C:\PROGRA~1\ANSYSI~1\v202\fluent"\fluent20.2.0\sr c\udf\makefile_nt.udf "libudf\win64\2ddp_host\makefile" ")
1 file(s) copied.
(chdir "libudf")(chdir "win64\2ddp_host")# Generating ud_io1.h
Surfacetension_Sourceterm.c
..\..\src\Surfacetension_Sourceterm.c(25): error C2440: '=': cannot convert from 'real *' to 'real'
..\..\src\Surfacetension_Sourceterm.c(26): error C2109: subscript requires array or pointer type
..\..\src\Surfacetension_Sourceterm.c(26): error C2198: 'sqrt': too few arguments for call
..\..\src\Surfacetension_Sourceterm.c(30): error C2440: '=': cannot convert from 'real *' to 'real'
Creating user_nt.udf file for 2ddp_node ...
(system "copy "C:\PROGRA~1\ANSYSI~1\v202\fluent"\fluent20.2.0\sr c\udf\makefile_nt.udf "libudf\win64\2ddp_node\makefile" ")
1 file(s) copied.
(chdir "libudf")(chdir "win64\2ddp_node")# Generating ud_io1.h
Surfacetension_Sourceterm.c
..\..\src\Surfacetension_Sourceterm.c(25): error C2440: '=': cannot convert from 'real *' to 'real'
..\..\src\Surfacetension_Sourceterm.c(26): error C2109: subscript requires array or pointer type
..\..\src\Surfacetension_Sourceterm.c(26): error C2198: 'sqrt': too few arguments for call
..\..\src\Surfacetension_Sourceterm.c(30): error C2440: '=': cannot convert from 'real *' to 'real'

Done.
Venky_94 is offline   Reply With Quote

Old   March 23, 2021, 12:40
Default
  #3
Senior Member
 
Join Date: Nov 2013
Posts: 1,965
Rep Power: 27
pakk will become famous soon enough
Ignoring the errors: your concept can not work.

You fill UDS, and want to get the gradient at the same time. How should that work after the first cell? How can Fluent calculate a gradient if only one cell has a value?

I think you have to do this in three steps :
1. Fill UDS0 completely.
2.calculate UDS 1 completely as gradient.
3.calculate the source completely as gradient of UDS1.

Even then, I'm not sure if this is the right approach, but I don't have enough time to think a better one.
__________________
"The UDF library you are trying to load (libudf) is not compiled for parallel use on the current platform" is NOT the error after compiling. It is the error after loading. To see compiler errors, look at your screen after you click "build".
pakk is offline   Reply With Quote

Old   March 23, 2021, 14:35
Default
  #4
Member
 
Venkat Ganesh
Join Date: May 2020
Location: Cincinnati, Ohio
Posts: 49
Rep Power: 6
Venky_94 is on a distinguished road
Quote:
Originally Posted by pakk View Post
Ignoring the errors: your concept can not work.

You fill UDS, and want to get the gradient at the same time. How should that work after the first cell? How can Fluent calculate a gradient if only one cell has a value?

I think you have to do this in three steps :
1. Fill UDS0 completely.
2.calculate UDS 1 completely as gradient.
3.calculate the source completely as gradient of UDS1.

Even then, I'm not sure if this is the right approach, but I don't have enough time to think a better one.
Thanks. I understood the issue, and I have written loops to completely calculate the values for all the UDS, and calculate the source term on a per cell basis.

However I'm still receiving the same errors and I'm not sure what they mean. I thought maybe it meant I can't store my UDS and UDS_G values in 'real' variables and also tried storing them in UDMs and not real variables like "n, ncap and k" as I've used below, but my errors remain the same irrespective of the approach.

Below are my code and errors. All errors pertain to the lines involving calculation of n, ncap and k. Please suggest.

Code:
/***********************************************************************
UDF for defining surface tension source term and interface smoothening
************************************************************************/

#include "udf.h"

DEFINE_SOURCE(surface_tension_force,c,t,dS,eqn)
{

/* Note that t is the mixture thread passed by the solver in this case */

Domain *d = Get_Domain(1);			/* defines the mixture domain */

real source;
real k;						/* interface curvature */
real ncap;					/* unit normal */
real n;						/* a function of the phase fraction */
real sigma = 0.072;				/* surface tension coefficient */
real alphacell = C_UDMI(c,t,1);			/* calculates the area averaged volume fraction of individual cell */
real rho1 = 1.225;				/* Density of air */
real rho2 = 1;					/* Density of non-Newtonian fluid */

/* Fill UDS with the alphacell values to get gradient value */

thread_loop_c(t,d)
{
begin_c_loop(c,t)
{
C_UDSI(c,t,0) = alphacell;
}
end_c_loop(c,t)
}

/* Get value of n as the gradient of alphacell (phase fraction) */

thread_loop_c(t,d)
{
begin_c_loop(c,t)
{
n = C_UDSI_G(c,t,0);
}
end_c_loop(c,t)
}
				
ncap = n/NV_MAG(n);				/* calculate unit vector */

/* Fill another UDS with the variable ncap */

thread_loop_c(t,d)
{
begin_c_loop(c,t)
{
C_UDSI(c,t,1) = ncap;
}
end_c_loop(c,t)
}

thread_loop_c(t,d)
{
begin_c_loop(c,t)
{
k = C_UDSI_G(c,t,1);				/* Get value of k as the gradient of ncap */
}
end_c_loop(c,t)
}

source = sigma*k*C_R(c,t)*n/(0.5*(rho1+rho2));	/* Calculate the surface tension force */
dS[eqn] = 0;
return source;
}
Quote:
Surfacetension_Sourceterm_Trial.c
..\..\src\Surfacetension_Sourceterm_Trial.c(40): error C2440: '=': cannot convert from 'real *' to 'real'
..\..\src\Surfacetension_Sourceterm_Trial.c(45): error C2109: subscript requires array or pointer type
..\..\src\Surfacetension_Sourceterm_Trial.c(45): error C2198: 'sqrt': too few arguments for call
..\..\src\Surfacetension_Sourceterm_Trial.c(62): error C2440: '=': cannot convert from 'real *' to 'real'
Venky_94 is offline   Reply With Quote

Old   March 23, 2021, 15:15
Default
  #5
Senior Member
 
Join Date: Nov 2013
Posts: 1,965
Rep Power: 27
pakk will become famous soon enough
Your problem now is that gradient is a vector. You can not store that in a scalar.
__________________
"The UDF library you are trying to load (libudf) is not compiled for parallel use on the current platform" is NOT the error after compiling. It is the error after loading. To see compiler errors, look at your screen after you click "build".
pakk is offline   Reply With Quote

Old   March 23, 2021, 15:23
Default
  #6
Member
 
Venkat Ganesh
Join Date: May 2020
Location: Cincinnati, Ohio
Posts: 49
Rep Power: 6
Venky_94 is on a distinguished road
Quote:
Originally Posted by pakk View Post
Your problem now is that gradient is a vector. You can not store that in a scalar.
Thanks. I just realized that and made some modifications to the code. I was able to declare n as a vector using real n[ND_ND] and perform the corresponding operation using NV_V(n, =, C_UDSI_G(c,t,0)).

The below are the concepts I'm struggling with right now.

1. ncap is a vector that has the value ( n/NV_MAG(n) ), where n is also a vector. How would I perform the operation of dividing a vector by a scalar? As the command as it is gives me an error "error C2296: '/': illegal, left operand has type 'real [2]'" Is there a NV macro that can handle this?

2. I need to calculate the divergence of the vector ncap (or simply said - the Laplacian) and store it in k. How would I go about this?

Last edited by Venky_94; March 24, 2021 at 00:24.
Venky_94 is offline   Reply With Quote

Old   March 25, 2021, 12:08
Default
  #7
Member
 
Venkat Ganesh
Join Date: May 2020
Location: Cincinnati, Ohio
Posts: 49
Rep Power: 6
Venky_94 is on a distinguished road
Quote:
Originally Posted by Venky_94 View Post
Thanks. I just realized that and made some modifications to the code. I was able to declare n as a vector using real n[ND_ND] and perform the corresponding operation using NV_V(n, =, C_UDSI_G(c,t,0)).

The below are the concepts I'm struggling with right now.

1. ncap is a vector that has the value ( n/NV_MAG(n) ), where n is also a vector. How would I perform the operation of dividing a vector by a scalar? As the command as it is gives me an error "error C2296: '/': illegal, left operand has type 'real [2]'" Is there a NV macro that can handle this?

2. I need to calculate the divergence of the vector ncap (or simply said - the Laplacian) and store it in k. How would I go about this?
Update:
I was able to achieve the first part using the command NV_VS(ncap, =, n, /, NV_MAG(n)).

So now I have the unit vector ncap. All I need to do it figure out how to calculate the term ∇⋅ncap (divergence of the unit vector). Any suggestions would be great.
Venky_94 is offline   Reply With Quote

Old   May 28, 2024, 11:28
Default
  #8
New Member
 
Guilherme Luz
Join Date: Mar 2021
Posts: 2
Rep Power: 0
qwertyus is on a distinguished road
Deleted my own answer because coding was wrong. For anyone looking, this are two DEFINE_ADJUST functions to store and calculate the gradient of the VOF:


Of course, there are some things which need to be done in order for it to work (hooking the UDFs, defining the required UDSs in the GUI, enabling "keep shared memory", etc).





Code:
DEFINE_ADJUST(store_vof_liquid, domain)
{
    cell_t cell;
    face_t face;
    Thread **pt;
    Thread *cell_threads, *face_threads;
    
    
#if !RP_HOST
    if(! Data_Valid_P())
    {
        Message0("\n\n-------\nstore_vof_liquid: invalid data. Returning...\n-------\n\n");
        return;
    }
    
    mp_thread_loop_c(cell_threads,domain,pt)
    {
        if(FLUID_THREAD_P(cell_threads))
        {
            begin_c_loop(cell,cell_threads)
            {
                C_UDSI(cell,cell_threads,0) = C_VOF(cell,pt[1]);  
            }
            end_c_loop(cell,cell_threads)
        }
    }
    
    mp_thread_loop_f(face_threads,domain,pt)
    {
        if(THREAD_STORAGE(face_threads,SV_UDS_I(0)) != NULL)
        {
            begin_f_loop(face,face_threads)
            {
                F_UDSI(face,face_threads,0) = F_VOF(face,pt[1]);
            }
            end_f_loop(face,face_threads)
        }
    }
    
    // Message0("\n\n-------\nstore_vof_liquid: end call. Returning...\n-------\n\n");

#endif
}

DEFINE_ADJUST(store_grad_vof_liquid, domain)
{
    cell_t cell;
    Thread **pt;
    Thread *cell_threads;
    
#if !RP_HOST
    if(! Data_Valid_P())
    {
        Message0("\n\n-------\nstore_grad_vof_liquid: invalid data. Returning...\n-------\n\n");
        return;
    }
    
    mp_thread_loop_c(cell_threads,domain,pt)
    {
        if(FLUID_THREAD_P(cell_threads))
        {
            if(NULL != THREAD_STORAGE(cell_threads, SV_UDS_I(0)) && NULL != T_STORAGE_R_NV(cell_threads,SV_UDSI_G(0)))
            {
                begin_c_loop(cell,cell_threads)
                {
                    C_UDSI(cell,cell_threads,1) = C_UDSI_G(cell,cell_threads,0)[0];
                    C_UDSI(cell,cell_threads,2) = C_UDSI_G(cell,cell_threads,0)[1];
                    #if RP_3D
                        C_UDSI(cell,cell_threads,3) = C_UDSI_G(cell,cell_threads,0)[2];
                    #else
                        C_UDSI(cell,cell_threads,3) = 0;
                    #endif
                }
                end_c_loop(cell,cell_threads)
            }
        }
    }
    
    // Message0("\n\n-------\nstore_grad_vof_liquid: End call. Returning...\n-------\n\n");
    
#endif
}

Last edited by qwertyus; June 3, 2024 at 10:10.
qwertyus is offline   Reply With Quote

Reply

Tags
interface curvature, surface tension model, udf, vof multiphase, volume fraction


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 Off
Trackbacks are Off
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Surface tension UDF Diconico FLUENT 3 March 12, 2021 13:38
OpenFOAM error Vinay Kumar V Main CFD Forum 0 February 20, 2020 10:17
How to add Surface Tension in cavitatingFoam solver jamestangx OpenFOAM Programming & Development 1 April 6, 2016 17:39
Surface Tension Force Model Miguel CFX 7 October 2, 2006 06:30
UDF for surface tension gradient kiran FLUENT 2 July 15, 2003 13:00


All times are GMT -4. The time now is 23:54.