From 370a3c7669a4d175884aed13b096bf842e145e04 Mon Sep 17 00:00:00 2001 From: Dmytro Sashko Date: Fri, 4 Aug 2023 16:12:32 +1000 Subject: [PATCH 01/26] Add fixes for building on macOS --- src/makefile.main.Rt | 2 +- src/models.R | 2 +- tools/dep.R | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) mode change 100644 => 100755 tools/dep.R diff --git a/src/makefile.main.Rt b/src/makefile.main.Rt index b0af2d3e4..aa7297e52 100644 --- a/src/makefile.main.Rt +++ b/src/makefile.main.Rt @@ -293,7 +293,7 @@ wiki/schema/.xsd:$(SRC)/schema.xsd.Rt $(SRC)/conf.R / %_sp.c:%.c @echo " SP-CONST $@" @$(MKPATH) $@ - @cat $< | sed -r 's/([^a-zA-Z0-9][0-9]+\.[0-9]*([eE][-+]?[0-9]+)?)[fL]+/\1f/g' > $@ + @cat $< | sed -E 's/([^a-zA-Z0-9][0-9]+\.[0-9]*([eE][-+]?[0-9]+)?)[fL]+/\1f/g' > $@ diff --git a/src/models.R b/src/models.R index a9a1add46..b4db6571f 100644 --- a/src/models.R +++ b/src/models.R @@ -19,7 +19,7 @@ get.model.names = function(path) { get.models = function() { M1 = get.model.dirs("git ls-files | grep 'conf.mk$'") - M2 = get.model.dirs("find models/ -name 'conf.mk'") + M2 = get.model.dirs("find models -name 'conf.mk'") M3 = union(M1,M2) Models = do.call(rbind, lapply(M3,function (m) { ret = get.model.names(m) diff --git a/tools/dep.R b/tools/dep.R old mode 100644 new mode 100755 index 7492616b8..9fc102c0e --- a/tools/dep.R +++ b/tools/dep.R @@ -9,7 +9,7 @@ opt <- parse_args(OptionParser(usage="Usage: ADmod -f inputfile [-o outputfile]" if (opt$path != "") setwd(opt$path) # 'grep' all the includes -f = pipe("grep '# *include' `find -regex '.*[.]\\(c\\|cu\\|cpp\\|h\\|hpp\\)'` | sed -n 's/^\\([^:]*\\):[ \\t]*#[ \\t]*include[ \\t]*[\"<]\\(.*\\)[>\"]/\\1,\\2/gp'") +f = pipe("grep '# *include' `find . -type f \\( -name '*.c' -o -name '*.cu' -o -name '*.cpp' -o -name '*.h' -o -name '*.hpp' \\)` | sed -n -e 's/^\\([^:]*\\):[ \\t]*#include[ \\t]*[\"<]\\(.*\\)[>\"]/\\1,\\2/gp'") w = read.csv(f,col.names=c("file","dep"), stringsAsFactor=F, header=FALSE); # make the relative paths in include statement relative to *here* From c3ac8f416a2760449612007773d61284425cfa7a Mon Sep 17 00:00:00 2001 From: Dmytro Sashko Date: Thu, 8 Feb 2024 14:48:15 +1000 Subject: [PATCH 02/26] Adjust boundary computation for angle 90 (or other similar cases) Compute pf_f in the normal direction as soon as possible, because we probably want to use it later in the computations --- .../d3q27_pf_velocity/Boundary.c.Rt | 55 +++++++++---------- 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt index 024f94c20..0ceb6b12b 100644 --- a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt +++ b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt @@ -689,37 +689,17 @@ CudaDeviceFunction void calcWallPhase(){ PhaseF = PhaseF(0,0,0); //For fluid nodes. if ( IamWall || IamSolid ) { real_t a, h, pf_f; - - // This is needed, because otherwise geometric_staircaseimp performance will drop + // First compute pf_f without staircase improvement + // + // Weird selection here is needed, because otherwise geometric_staircaseimp performance will drop // (presumably because of the dynamic access that it has) - pf_f = _dyn(nw_x, nw_y, nw_z); - h = 0.5 * sqrt(nw_x*nw_x + nw_y*nw_y + nw_z*nw_z); - // handling special cases - if (h < 0.001) { - // If I am a wall/solid node and I am surrounded by solid nodes - PhaseF = 1; - } else if (fabs(radAngle - PI/2.0) < 1e-4) { - // If I am not surrounded, but contact angle is pi/2 (90d) - PhaseF = pf_f; - } else if (IsSpecialBoundaryPoint == ) { - // Pass for now. Dont calculate anything, just set it to some huge number, purely to make sure - // that the value is corrected in calcWall_correction, and otherwise the error would be visible - // and hopefulyl break the simulation - PhaseF = ; - } else if (IsSpecialBoundaryPoint == ) { - // Eventhough I am geometric boundary condition, still apply surface energy - // here because otherwise we cant really apply anything else - a = -h * (4.0/IntWidth) * cos( radAngle ); - PhaseF = (1 + a - sqrt( (1+a)*(1+a) - 4*a*pf_f))/(a+1e-12) - pf_f; - } else { - // normal calculation with picking correct form depending on the boundary condition - + // if enabled compute staircase improved version of pf_f, + // and wallback to pf_f #ifdef OPTIONS_staircaseimp - int face_index = int(triangle_index) / 8; int face_triangle_index = int(triangle_index) % 8; int vertex_coords[3] = {0,0,0}; @@ -729,9 +709,6 @@ CudaDeviceFunction void calcWallPhase(){ int v_x = vertex_coords[0], v_y = vertex_coords[1], v_z = vertex_coords[2]; - - - real_t pf_v = _dyn(v_x, v_y, v_z); @@ -744,7 +721,27 @@ CudaDeviceFunction void calcWallPhase(){ pf_f = pf_interpolated; } #endif - + + // handling special cases + if (h < 0.001) { + // If I am a wall/solid node and I am surrounded by solid nodes + PhaseF = 1; + } else if (fabs(radAngle - PI/2.0) < 1e-4) { + // If I am not surrounded, but contact angle is pi/2 (90d) + PhaseF = pf_f; + } else if (IsSpecialBoundaryPoint == ) { + // Pass for now. Dont calculate anything, just set it to some huge number, purely to make sure + // that the value is corrected in calcWall_correction, and otherwise the error would be visible + // and hopefulyl break the simulation + PhaseF = ; + } else if (IsSpecialBoundaryPoint == ) { + // Eventhough I am geometric boundary condition, still apply surface energy + // here because otherwise we cant really apply anything else + a = -h * (4.0/IntWidth) * cos( radAngle ); + PhaseF = (1 + a - sqrt( (1+a)*(1+a) - 4*a*pf_f))/(a+1e-12) - pf_f; + } else { + // normal calculation with picking correct form depending on the boundary condition + #ifndef OPTIONS_geometric // Case 1: Apply surface energy BC (with calculated pf_f with standard or staircase improvement) a = -h * (4.0/IntWidth) * cos( radAngle ); From c3b563f01b00cc6de6d645c41b9220909ed38af7 Mon Sep 17 00:00:00 2001 From: Dmytro Sashko Date: Tue, 13 Feb 2024 10:43:50 +1000 Subject: [PATCH 03/26] Split normal initialisation in two part This way we can both initialise external and internally based on some approximations --- .../d3q27_pf_velocity/Boundary.c.Rt | 125 +++++++++++++----- .../multiphase/d3q27_pf_velocity/Dynamics.R | 26 +++- .../d3q27_pf_velocity/Dynamics.c.Rt | 16 +++ 3 files changed, 125 insertions(+), 42 deletions(-) diff --git a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt index 0ceb6b12b..1db215670 100644 --- a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt +++ b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt @@ -673,11 +673,32 @@ CudaDeviceFunction void calcPhaseGradCloseToBoundary(){ */ CudaDeviceFunction void calcWallPhase_correction() { PhaseF = PhaseF(0,0,0); - if (IsSpecialBoundaryPoint == ) { // take the phase field calculated already from the node in front. // Might as well calculate using the neighbors, e.g. averaging - PhaseF = PhaseF_dyn(nw_x, nw_y, nw_z); + real_t point_in_the_normal_direction = PhaseF_dyn(nw_x, nw_y, nw_z); + // in some cases we might (TODO: investigate) still point into the solid node + // that has normal pointing into another, we need to avoid this + if (point_in_the_normal_direction == ) { + // ignore first node + int count = 0; + real_t fluid_average = 0.0; + real_t x, y, z; + + for (int i=1; i<27 ; i++){ + x = d3q27_ex[i]; + y = d3q27_ey[i]; + z = d3q27_ez[i]; + if (!IsBoundary_dyn(int(x), int(y), int(z)) && PhaseF_dyn(int(x), int(y), int(z)) > -0.5) { + fluid_average += PhaseF_dyn(int(x), int(y), int(z)); + count++; + } + } + // print sum and average and count + PhaseF = count == 0 ? 1 : fluid_average / count; + } else { + PhaseF = point_in_the_normal_direction; + } } } @@ -848,6 +869,57 @@ CudaDeviceFunction real_t getSpecialBoundaryPoint() { return IsSpecialBoundaryPoint; } +/* Calculate the actual wall norm based on the solid + *field */ +CudaDeviceFunction real_t Init_real_wallNorm() +{ + // set initial values + nw_x = 0.0; + nw_y = 0.0; + nw_z = 0.0; + if ( IamWall || IamSolid ) { + + int i,j,k; + real_t tmp = 0.0; + for (i=-1;i<2;i++){for (j=-1;j<2;j++){for (k=-1;k<2;k++){ + tmp += PhaseF_dyn(i,j,k); + }}} + + if (abs(tmp) > 26000) { + // I am surrounded by all solid nodes (sum(pf) = 27*-999 = -26973 if surrounded): + nw_x = 0.0; nw_y = 0.0; nw_z = 0.0; + } else { + // no I am not surrounded, so calc normal: + int solidFlag[27]; + // Calculate the normal direction based converting + // negative PhaseF into actual solid flags + + for (i=0;i<27;i++){ + nw_x += wg[i] * solidFlag[i] * d3q27_ex[i]; + nw_y += wg[i] * solidFlag[i] * d3q27_ey[i]; + nw_z += wg[i] * solidFlag[i] * d3q27_ez[i]; + } + nw_x *= -1.0/3.0; nw_y *= -1.0/3.0; nw_z *= -1.0/3.0; + tmp = nw_x*nw_x + nw_y*nw_y + nw_z*nw_z; + + nw_x = nw_x / sqrt(tmp); + nw_y = nw_y / sqrt(tmp); + nw_z = nw_z / sqrt(tmp); + + } + } + else { + // I am a fluid node, I dont need no solid normal, + // should be set to zero before. Branch kept + // for clarity + } +} /* * Initialise and set: wall normals, get interpolating triangles and their coefficients, @@ -863,7 +935,8 @@ CudaDeviceFunction void Init_wallNorm(){ coeff_v2 = 0; coeff_v3 = 0; #endif - if ( IamWall || IamSolid ) { + //printf("PhaseF value is %f\n", PhaseF); + if ( IamWall || IamSolid ) { IsBoundary = 1.0; int i,j,k; real_t tmp = 0.0; @@ -880,42 +953,29 @@ CudaDeviceFunction void Init_wallNorm(){ nw_actual_z = 0.0; #endif } else { - // no I am not surrounded, so calc normal: - int solidFlag[27]; + // Calculate the closest discrete direction for normal: + real_t tmp = 0.0; int maxi = 0; - real_t myNorm[3] = {0.0,0.0,0.0}; real_t maxn=0.0, dot; - // Calculate the normal direction based converting - // negative PhaseF into actual solid flags - - for (i=0;i<27;i++){ - myNorm[0] += wg[i] * solidFlag[i] * d3q27_ex[i]; - myNorm[1] += wg[i] * solidFlag[i] * d3q27_ey[i]; - myNorm[2] += wg[i] * solidFlag[i] * d3q27_ez[i]; - - } - myNorm[0] *= -1.0/3.0;myNorm[1] *= -1.0/3.0;myNorm[2] *= -1.0/3.0; - tmp = myNorm[0]*myNorm[0] + myNorm[1]*myNorm[1] + myNorm[2]*myNorm[2]; - - // Calculate the closest discrete direction for normal: for (i = 0; i<27; i++) { - dot = (myNorm[0]*d3q27_ex[i] + myNorm[1]*d3q27_ey[i] + myNorm[2]*d3q27_ez[i]) / - sqrt( tmp*(d3q27_ex[i]*d3q27_ex[i] + d3q27_ey[i]*d3q27_ey[i] + - d3q27_ez[i]*d3q27_ez[i]) + 1e-12); + tmp = nw_x*nw_x + nw_y*nw_y + nw_z*nw_z; + dot = (nw_x*d3q27_ex[i] + nw_y*d3q27_ey[i] + nw_z*d3q27_ez[i]) / + sqrt( tmp*(d3q27_ex[i]*d3q27_ex[i] + d3q27_ey[i]*d3q27_ey[i] + + d3q27_ez[i]*d3q27_ez[i]) + 1e-12); if (dot > maxn) { maxn = dot; maxi = i; } } +#ifdef OPTIONS_staircaseimp + // save original values before they get truncated + real_t original_normal[3] = {nw_x, nw_y, nw_z}; +#endif if (maxi < 0) { // This should not happen ? - nw_x = 0.0;nw_y = 0.0;nw_z = 0.0; + nw_x = 0.0; + nw_y = 0.0; + nw_z = 0.0; } else { nw_x = d3q27_ex[maxi]; nw_y = d3q27_ey[maxi]; @@ -930,7 +990,6 @@ CudaDeviceFunction void Init_wallNorm(){ } #ifdef OPTIONS_staircaseimp - real_t truncated_normals[3] = {nw_x, nw_y, nw_z}; real_t intersection_point[3]; int face_index; real_t coeff[3]; @@ -938,7 +997,7 @@ CudaDeviceFunction void Init_wallNorm(){ int t_index; int t_index2; - calcIntersectionTriangleId(myNorm, t_index, face_index, coeff, intersection_point, t_index2, coeff2); + calcIntersectionTriangleId(original_normal, t_index, face_index, coeff, intersection_point, t_index2, coeff2); // make sure normal vector is extended to the surface (to use it during interpolation) nw_actual_x = intersection_point[0]; @@ -1027,10 +1086,6 @@ CudaDeviceFunction void Init_wallNorm(){ } } else { - // I am a fluid node, I dont need no solid normal. - nw_x = 0.0; - nw_y = 0.0; - nw_z = 0.0; #ifdef OPTIONS_staircaseimp nw_actual_x = 0.0; nw_actual_y = 0.0; diff --git a/models/multiphase/d3q27_pf_velocity/Dynamics.R b/models/multiphase/d3q27_pf_velocity/Dynamics.R index 2023981b4..5118c085e 100644 --- a/models/multiphase/d3q27_pf_velocity/Dynamics.R +++ b/models/multiphase/d3q27_pf_velocity/Dynamics.R @@ -14,6 +14,11 @@ AddDensity(name="Init_UY_External", group="init", comment="free stream velocity" AddDensity(name="Init_UZ_External", group="init", comment="free stream velocity", parameter=TRUE) AddDensity(name="Init_PhaseField_External", group="init", dx=0,dy=0,dz=0, parameter=TRUE) +# for initialising the normals +AddDensity(name="Init_nwx_external", group="init_normals", dx=0,dy=0,dz=0, parameter=TRUE) +AddDensity(name="Init_nwy_external", group="init_normals", dx=0,dy=0,dz=0, parameter=TRUE) +AddDensity(name="Init_nwz_external", group="init_normals", dx=0,dy=0,dz=0, parameter=TRUE) + # macroscopic params # - consider migrating to fields AddDensity(name="pnorm", dx=0, dy=0, dz=0, group="Vel") @@ -125,16 +130,21 @@ if (Options$thermo){ AddStage("calcPhase", "calcPhaseF", save=Fields$name=="PhaseF", load=DensityAll$group %in% load_phase) AddStage("BaseIter" , "Run", save=Fields$group %in% save_iteration, load=DensityAll$group %in% load_iteration ) AddStage(name="InitFromFieldsStage", load=DensityAll$group %in% "init",read=FALSE, save=Fields$group %in% save_initial_PF) + AddStage(name="InitFromFieldsStageWithNormals", load=DensityAll$group %in% c("init_normals", "init"),read=FALSE, save=Fields$group %in% c("nw", save_initial_PF)) + # STAGES FOR VARIOUS OPTIONS if (Options$geometric){ - AddStage("WallInit_CA" , "Init_wallNorm", save=Fields$group %in% c("nw", "solid_boundary", extra_fields_to_load_for_bc)) + + AddStage("WallInit_Real" , "Init_real_wallNorm", save=Fields$group %in% c("nw")) + AddStage("WallInit_CA" , "Init_wallNorm", load=DensityAll$group %in% c("nw"), save=Fields$group %in% c("nw", "solid_boundary", extra_fields_to_load_for_bc)) AddStage("calcWall_CA" , "calcWallPhase", save=Fields$name %in% c("PhaseF"), load=DensityAll$group %in% c("nw", "gradPhi", "PF", "solid_boundary", extra_fields_to_load_for_bc)) AddStage('calcPhaseGrad', "calcPhaseGrad", load=DensityAll$group %in% c("nw", "PF", "solid_boundary"), save=Fields$group=="gradPhi") AddStage('calcPhaseGrad_init', "calcPhaseGrad_init", load=DensityAll$group %in% c("nw", "PF", "solid_boundary"), save=Fields$group=="gradPhi") AddStage("calcWallPhase_correction", "calcWallPhase_correction", save=Fields$name=="PhaseF", load=DensityAll$group %in% c("nw", "solid_boundary")) } else { - AddStage("WallInit" , "Init_wallNorm", save=Fields$group %in% c("nw", "solid_boundary", extra_fields_to_load_for_bc)) + AddStage("WallInit_Real" , "Init_real_wallNorm", save=Fields$group %in% c("nw")) + AddStage("WallInit" , "Init_wallNorm", load=DensityAll$group %in% c("nw"), save=Fields$group %in% c("nw", "solid_boundary", extra_fields_to_load_for_bc)) AddStage("calcWall" , "calcWallPhase", save=Fields$name=="PhaseF", load=DensityAll$group %in% c("nw", "solid_boundary", extra_fields_to_load_for_bc)) AddStage("calcWallPhase_correction", "calcWallPhase_correction", save=Fields$name=="PhaseF", load=DensityAll$group %in% c("nw", "solid_boundary")) } @@ -156,16 +166,18 @@ if (Options$thermo){ AddAction("TempToSteadyState", c("CopyDistributions","RK_1", "RK_2", "RK_3", "RK_4","NonLocalTemp")) AddAction("Iteration", c("BaseIter", "calcPhase", "calcWall","RK_1", "RK_2", "RK_3", "RK_4","NonLocalTemp")) AddAction("IterationConstantTemp", c("BaseIter", "calcPhase", "calcWall","CopyThermal")) - AddAction("Init" , c("PhaseInit","WallInit" , "calcWall","BaseInit")) + AddAction("Init" , c("PhaseInit","WallInit_Real","WallInit" , "calcWall","BaseInit")) } else if (Options$geometric) { calcGrad <- if (Options$isograd) "calcPhaseGrad" else "calcPhaseGrad_init" AddAction("Iteration", c("BaseIter", "calcPhase", calcGrad, "calcWall_CA", "calcWallPhase_correction")) - AddAction("Init" , c("PhaseInit","WallInit_CA" , "calcPhaseGrad_init" , "calcWall_CA", "calcWallPhase_correction", "BaseInit")) - AddAction("InitFields" , c("InitFromFieldsStage","WallInit_CA" , "calcPhaseGrad_init", "calcWall_CA", "calcWallPhase_correction", "BaseInit")) + AddAction("Init" , c("PhaseInit","WallInit_Real","WallInit_CA" , "calcPhaseGrad_init" , "calcWall_CA", "calcWallPhase_correction", "BaseInit")) + AddAction("InitFields" , c("InitFromFieldsStage","WallInit_Real","WallInit_CA" , "calcPhaseGrad_init", "calcWall_CA", "calcWallPhase_correction", "BaseInit")) + AddAction("InitFieldsWithNormals" , c("InitFromFieldsStageWithNormals","WallInit_CA" , "calcPhaseGrad_init", "calcWall_CA", "calcWallPhase_correction", "BaseInit")) } else { AddAction("Iteration", c("BaseIter", "calcPhase", "calcWall", "calcWallPhase_correction")) - AddAction("Init" , c("PhaseInit","WallInit" , "calcWall","calcWallPhase_correction", "BaseInit")) - AddAction("InitFields", c("InitFromFieldsStage","WallInit" , "calcWall", "calcWallPhase_correction", "BaseInit")) + AddAction("Init" , c("PhaseInit", "WallInit_Real", "WallInit" , "calcWall","calcWallPhase_correction", "BaseInit")) + AddAction("InitFields", c("InitFromFieldsStage","WallInit_Real","WallInit" , "calcWall", "calcWallPhase_correction", "BaseInit")) + AddAction("InitFieldsWithNormals", c("InitFromFieldsStageWithNormals", "WallInit" , "calcWall", "calcWallPhase_correction", "BaseInit")) } ####################### ########OUTPUTS######## diff --git a/models/multiphase/d3q27_pf_velocity/Dynamics.c.Rt b/models/multiphase/d3q27_pf_velocity/Dynamics.c.Rt index 02cf4ce43..ea1059442 100755 --- a/models/multiphase/d3q27_pf_velocity/Dynamics.c.Rt +++ b/models/multiphase/d3q27_pf_velocity/Dynamics.c.Rt @@ -287,6 +287,22 @@ CudaDeviceFunction void InitFromFieldsStage() pnorm = 0.0; // initialise as zero and fill in later stage } + +CudaDeviceFunction void InitFromFieldsStageWithNormals() +{ + PhaseF = Init_PhaseField_External; + U = Init_UX_External; + V = Init_UY_External; + W = Init_UZ_External; + if ( IamWall || IamSolid ) PhaseF = -999; + pnorm = 0.0; // initialise as zero and fill in later stage + nw_x = Init_nwx_external; + nw_y = Init_nwy_external; + nw_z = Init_nwz_external; +} + + + CudaDeviceFunction void specialCases_Init() { #ifdef OPTIONS_thermo From 5bcc8d4cc6def5d71afc3b65ca56e4d29774f34a Mon Sep 17 00:00:00 2001 From: Dmytro Sashko Date: Wed, 28 Feb 2024 16:45:41 +1000 Subject: [PATCH 04/26] Fix geometric model --- models/multiphase/d3q27_pf_velocity/Boundary.c.Rt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt index 1db215670..1fd7c74cc 100644 --- a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt +++ b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt @@ -735,8 +735,9 @@ CudaDeviceFunction void calcWallPhase(){ - // dont do staircase improvement if any of the interpolating nodes are solid - if (IsSpecialBoundaryPoint != ) { + // dont do staircase improvement if any of the interpolating nodes are solid, make sure to cover + // both cases...... + if (IsSpecialBoundaryPoint != && IsSpecialBoundaryPoint != ) { real_t pf_interpolated = coeff_v1 * pf_v1 + coeff_v2 * pf_v2 + coeff_v3 * pf_v3; h = 0.5 * sqrt(nw_actual_x*nw_actual_x + nw_actual_y*nw_actual_y + nw_actual_z*nw_actual_z); pf_f = pf_interpolated; From fd057e624f2224e65c664fbaf1a9e9365214f1d9 Mon Sep 17 00:00:00 2001 From: Dmytro Sashko Date: Wed, 13 Mar 2024 10:15:29 +1000 Subject: [PATCH 05/26] Fix undified behaviours --- .../d3q27_pf_velocity/Boundary.c.Rt | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt index 1fd7c74cc..f7cec0549 100644 --- a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt +++ b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt @@ -718,8 +718,21 @@ CudaDeviceFunction void calcWallPhase(){ pf_f = _dyn(nw_x, nw_y, nw_z); h = 0.5 * sqrt(nw_x*nw_x + nw_y*nw_y + nw_z*nw_z); - // if enabled compute staircase improved version of pf_f, - // and wallback to pf_f + // /now handle special cacses, that don't even + // need to calculate the phase field now (or have + // access to different fields) + if (h < 0.001) { + // If I am a wall/solid node and I am surrounded by solid nodes + PhaseF = 1; + } else if (IsSpecialBoundaryPoint == ) { + // Pass for now. Dont calculate anything, just set it to some huge number, purely to make sure + // that the value is corrected in calcWall_correction, and otherwise the error would be visible + // and hopefulyl break the simulation + PhaseF = ; + } else { + + // if enabled compute staircase improved version of pf_f, + // and wallback to pf_f, which is required is many places #ifdef OPTIONS_staircaseimp int face_index = int(triangle_index) / 8; int face_triangle_index = int(triangle_index) % 8; @@ -743,22 +756,15 @@ CudaDeviceFunction void calcWallPhase(){ pf_f = pf_interpolated; } #endif - // handling special cases - if (h < 0.001) { - // If I am a wall/solid node and I am surrounded by solid nodes - PhaseF = 1; - } else if (fabs(radAngle - PI/2.0) < 1e-4) { - // If I am not surrounded, but contact angle is pi/2 (90d) + if (fabs(radAngle - PI/2.0) < 1e-4) { + // If I am not surrounded, but contact angle is pi/2 (90d). Staircase improved + // already handled before PhaseF = pf_f; - } else if (IsSpecialBoundaryPoint == ) { - // Pass for now. Dont calculate anything, just set it to some huge number, purely to make sure - // that the value is corrected in calcWall_correction, and otherwise the error would be visible - // and hopefulyl break the simulation - PhaseF = ; } else if (IsSpecialBoundaryPoint == ) { // Eventhough I am geometric boundary condition, still apply surface energy - // here because otherwise we cant really apply anything else + // here because otherwise we cant really apply anything else. Staircase improved + // already handled before a = -h * (4.0/IntWidth) * cos( radAngle ); PhaseF = (1 + a - sqrt( (1+a)*(1+a) - 4*a*pf_f))/(a+1e-12) - pf_f; } else { @@ -864,6 +870,7 @@ CudaDeviceFunction void calcWallPhase(){ #endif // end boundary condition pick } } + } } CudaDeviceFunction real_t getSpecialBoundaryPoint() { From 1b4eca66b5e2f014ff0c407ebed18dfaf585951d Mon Sep 17 00:00:00 2001 From: Dmytro Sashko Date: Thu, 22 Jun 2023 09:40:09 +1000 Subject: [PATCH 06/26] Add utilities --- models/multiphase/d3q27_pf_velocity/Dynamics.R | 2 ++ models/multiphase/d3q27_pf_velocity/Dynamics.c.Rt | 2 ++ 2 files changed, 4 insertions(+) diff --git a/models/multiphase/d3q27_pf_velocity/Dynamics.R b/models/multiphase/d3q27_pf_velocity/Dynamics.R index 5118c085e..4d0be761d 100644 --- a/models/multiphase/d3q27_pf_velocity/Dynamics.R +++ b/models/multiphase/d3q27_pf_velocity/Dynamics.R @@ -320,3 +320,5 @@ if (Options$thermo){ AddGlobal(name="FluxX",comment='flux in x direction for flux_nodes', unit="1") AddGlobal(name="FluxY",comment='flux in y direction for flux_nodes', unit="1") AddGlobal(name="FluxZ",comment='flux in z direction for flux_nodes', unit="1") + AddGlobal(name="LiquidSaturation", comment="Liquid saturation(number of liquid nodes)", unit="1") + AddGlobal(name="GasSaturation", comment="Gas saturation(number of gas nodes)", unit="1") diff --git a/models/multiphase/d3q27_pf_velocity/Dynamics.c.Rt b/models/multiphase/d3q27_pf_velocity/Dynamics.c.Rt index ea1059442..87bf0d626 100755 --- a/models/multiphase/d3q27_pf_velocity/Dynamics.c.Rt +++ b/models/multiphase/d3q27_pf_velocity/Dynamics.c.Rt @@ -749,12 +749,14 @@ CudaDeviceFunction void updateMyGlobals(real_t pf){ AddToGasTotalVelocityZ( tmpPF*W ); AddToGasTotalPhase( tmpPF ); AddToXLocation( tmpPF*X ); + AddToGasSaturation(1); } else { AddToLiqTotalVelocity( pf*sqrt(u2mag)); AddToLiqTotalVelocityX( U*pf ); AddToLiqTotalVelocityY( V*pf ); AddToLiqTotalVelocityZ( W*pf ); AddToLiqTotalPhase( pf ); + AddToLiquidSaturation(1); } if ((NodeType & NODE_ADDITIONALS) == NODE_flux_nodes) { From 86d7854c02ea419614b26e811eaede0f80075ef8 Mon Sep 17 00:00:00 2001 From: Dmytro Sashko Date: Fri, 12 Apr 2024 10:04:28 +1000 Subject: [PATCH 07/26] Fix weighting --- models/multiphase/d3q27_pf_velocity/Boundary.c.Rt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt index f7cec0549..9baab6104 100644 --- a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt +++ b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt @@ -684,13 +684,12 @@ CudaDeviceFunction void calcWallPhase_correction() { int count = 0; real_t fluid_average = 0.0; real_t x, y, z; - for (int i=1; i<27 ; i++){ x = d3q27_ex[i]; y = d3q27_ey[i]; z = d3q27_ez[i]; if (!IsBoundary_dyn(int(x), int(y), int(z)) && PhaseF_dyn(int(x), int(y), int(z)) > -0.5) { - fluid_average += PhaseF_dyn(int(x), int(y), int(z)); + fluid_average += wg[i]*PhaseF_dyn(int(x), int(y), int(z)); count++; } } From 731ac874d5ef354052e01c1b9eed9e2bc4ff01be Mon Sep 17 00:00:00 2001 From: Dmytro Sashko Date: Tue, 21 May 2024 10:57:57 +1000 Subject: [PATCH 08/26] WIP Pressure boundary condition fix --- .../d3q27_pf_velocity/Boundary.c.Rt | 39 ++++++++++++++++--- .../d3q27_pf_velocity/Dynamics.c.Rt | 23 ++++++++++- 2 files changed, 55 insertions(+), 7 deletions(-) diff --git a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt index 9baab6104..d2ed4f364 100644 --- a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt +++ b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt @@ -73,6 +73,19 @@ CudaDeviceFunction void (){ CudaDeviceFunction void (){ real_t d = getRho(); + + real_t myPhaseField = 0.0; + // TODO: Need a proper fix soon + if ((NodeType & NODE_BOUNDARY) == NODE_WPressure){ + d = Density_l; + myPhaseField = 0.0; + } + + if ((NodeType & NODE_BOUNDARY) == NODE_EPressure){ + d = Density_h; + myPhaseField = 1.0; + } + real_t pstar = Pressure / (d*cs2); (){ ?> ) { // Pass for now. Dont calculate anything, just set it to some huge number, purely to make sure // that the value is corrected in calcWall_correction, and otherwise the error would be visible @@ -888,8 +902,23 @@ CudaDeviceFunction real_t Init_real_wallNorm() int i,j,k; real_t tmp = 0.0; + real_t PhaseF_tmp[3][3][3]; + // mirror in the beginning, in case of non-periodic boundaries + int nx = constContainer.nx; + for (i=-1;i<2;i++){for (j=-1;j<2;j++){for (k=-1;k<2;k++){ + if ((i == -1) && (X == 0.5)) { + PhaseF_tmp[i+1][j+1][k+1] = PhaseF_dyn(-i,j,k); + } + else if ((i == 1) && (X == nx - 0.5)) { + PhaseF_tmp[i+1][j+1][k+1] = PhaseF_dyn(-i,j,k); + } + else { + PhaseF_tmp[i+1][j+1][k+1] = PhaseF_dyn(i,j,k); + } + }} + } for (i=-1;i<2;i++){for (j=-1;j<2;j++){for (k=-1;k<2;k++){ - tmp += PhaseF_dyn(i,j,k); + tmp += PhaseF_tmp[i+1][j+1][k + 1]; }}} if (abs(tmp) > 26000) { @@ -901,17 +930,18 @@ CudaDeviceFunction real_t Init_real_wallNorm() // Calculate the normal direction based converting // negative PhaseF into actual solid flags for (i=0;i<27;i++){ + // no need to calculate the normal direction if in the beginning of the boundary nw_x += wg[i] * solidFlag[i] * d3q27_ex[i]; nw_y += wg[i] * solidFlag[i] * d3q27_ey[i]; nw_z += wg[i] * solidFlag[i] * d3q27_ez[i]; } + nw_x *= -1.0/3.0; nw_y *= -1.0/3.0; nw_z *= -1.0/3.0; tmp = nw_x*nw_x + nw_y*nw_y + nw_z*nw_z; @@ -942,7 +972,6 @@ CudaDeviceFunction void Init_wallNorm(){ coeff_v2 = 0; coeff_v3 = 0; #endif - //printf("PhaseF value is %f\n", PhaseF); if ( IamWall || IamSolid ) { IsBoundary = 1.0; int i,j,k; diff --git a/models/multiphase/d3q27_pf_velocity/Dynamics.c.Rt b/models/multiphase/d3q27_pf_velocity/Dynamics.c.Rt index 87bf0d626..f2b632c7d 100755 --- a/models/multiphase/d3q27_pf_velocity/Dynamics.c.Rt +++ b/models/multiphase/d3q27_pf_velocity/Dynamics.c.Rt @@ -81,12 +81,16 @@ CudaDeviceFunction vector_t getU(){ } CudaDeviceFunction real_t getPstar(){ + updateBoundary(); return ; } CudaDeviceFunction real_t getP(){ + // note: vtk export should happen after the boundary is updated, + // otherwise there would be some strange values + updateBoundary(); real_t d = getRho(); - real_t pstar = getPstar(); + real_t pstar = ; return pstar*d*cs2; } @@ -143,7 +147,14 @@ CudaDeviceFunction vector_t calcGradPhi() - #endif + + auto boundary_marker = NodeType & NODE_BOUNDARY; + if (boundary_marker == NODE_EPressure || boundary_marker == NODE_WPressure) { + gradPhi.x = 0.0; + gradPhi.y = 0.0; + gradPhi.z = 0.0; + } + #endif return gradPhi; } @@ -218,11 +229,19 @@ CudaDeviceFunction real_t calcMu(real_t C) ?> #endif #ifdef OPTIONS_thermo + mu = 4.0*(12.0*SurfaceTension(0,0,0)/IntWidth)*(C-PhaseField_l)*(C-PhaseField_h)*(C-pfavg) - (1.5 *SurfaceTension(0,0,0)*IntWidth) * lpPhi; #else + + auto boundary_marker = NodeType & NODE_BOUNDARY; + if (boundary_marker == NODE_EPressure || boundary_marker == NODE_WPressure) { + lpPhi = 0.0; + } + mu = 4.0*(12.0*sigma/IntWidth)*(C-PhaseField_l)*(C-PhaseField_h)*(C-pfavg) - (1.5 *sigma*IntWidth) * lpPhi; + #endif return mu; } From c45c99737a4845a44393b01ae1cec23a34beb6e1 Mon Sep 17 00:00:00 2001 From: Dmytro Sashko Date: Fri, 24 May 2024 08:50:07 +1000 Subject: [PATCH 09/26] Add Lukaszes boundary conditions --- .../d3q27_pf_velocity/Boundary.c.Rt | 102 +++++++++++++----- 1 file changed, 76 insertions(+), 26 deletions(-) diff --git a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt index d2ed4f364..e580d3fc6 100644 --- a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt +++ b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt @@ -87,34 +87,76 @@ CudaDeviceFunction void (){ } real_t pstar = Pressure / (d*cs2); - - + C(h[sel],nh[sel]) + ?> } + // no need to do anything on the boundary + auto boundary_marker = NodeType & NODE_BOUNDARY; + if (boundary_marker == NODE_EPressure || boundary_marker == NODE_WPressure) { + gradPhiVal_x = 0.0; + gradPhiVal_y = 0.0; + gradPhiVal_z = 0.0; + } + // simply copy the values gradPhi_PhaseF = PhaseF(0,0,0); } From e20e665eca974fd280c0f1e4dc6001bc0a115dfa Mon Sep 17 00:00:00 2001 From: Dmytro Sashko Date: Tue, 28 May 2024 08:42:08 +1000 Subject: [PATCH 10/26] Rewrite fixes generically --- .../d3q27_pf_velocity/Boundary.c.Rt | 92 +++++++++++++------ .../multiphase/d3q27_pf_velocity/Dynamics.R | 10 +- .../d3q27_pf_velocity/Dynamics.c.Rt | 31 +++++-- 3 files changed, 93 insertions(+), 40 deletions(-) diff --git a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt index e580d3fc6..f7e784f3f 100644 --- a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt +++ b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt @@ -70,55 +70,72 @@ CudaDeviceFunction void (){ C(h[sel], heq[sel] + heq[bounce][sel] - h[bounce][sel] - 0.5 * Unknowns * (exM)) ?> } + -CudaDeviceFunction void (){ + +CudaDeviceFunction void (){ real_t d = getRho(); - real_t myPhaseField = 0.0; - // TODO: Need a proper fix soon - if ((NodeType & NODE_BOUNDARY) == NODE_WPressure){ - d = Density_l; - myPhaseField = 0.0; + + if ((NodeType & NODE_BOUNDARY) == ){ + d = InvasionDrainage == 2? Density_l : Density_h; + myPhaseField = InvasionDrainage == 2? 0.0 : 1.0; } - if ((NodeType & NODE_BOUNDARY) == NODE_EPressure){ - d = Density_h; - myPhaseField = 1.0; + if ((NodeType & NODE_BOUNDARY) == ){ + d = InvasionDrainage == 2? Density_h : Density_l; + myPhaseField = InvasionDrainage == 2? 1.0 : 0.0; } real_t pstar = Pressure / (d*cs2); - (){ U_PF = U[1:PF_velocities,] EQ_h = MRT_eq(U_PF,PV(1),u) + # assuming no force shift here heq = pf * EQ_h$feq bounce = Bounce(U_PF) sel = as.vector( (U_PF %*% n) < 0) @@ -134,23 +152,35 @@ CudaDeviceFunction void (){ nh = h nh[sel] = heq[sel] + (h-heq)[bounce][sel] - equations = V(sum(nh),nh %*% U_PF) - rhs = V(desired_pf,desired_pf*u) + # write down the closure equation + # sum of phase-field densities equal to phase-field value (desired or imposed) + # the first moment equal to the desired phase-field momentum + equations_lhs = V(sum(nh),nh %*% U_PF) + equations_rhs = V(desired_pf,desired_pf*u) - if (type_h == "fix_pf") { - C_pull(equations[1] - rhs[1], "PF" ) + if (type_h == "fpf") { + # Make sure the sum of h is equal to the desired phase-field + # - "interface" will stop on the boundary + C_pull(equations_lhs[1] - equations_rhs[1], "PF" ) } else if (type_h == "open") { - C_pull(equations[1] - pf, "PF" ) + # The sum of phase-field is not enforced - the same is kept + # - "interface" is passing through the boundary + C_pull(equations_lhs[1] - pf, "PF" ) } else { + # desired phase-field is enforced via substitution in + # the equilibrium distribution function directly nh = subst(nh, PF=desired_pf) - equations = subst(equations, PF=desired_pf) - if (type_h == "fix_flux") { + # + lhs_equations = subst(equations_lhs, PF=desired_pf) + if (type_h == "fflux") { + # we are pretty much done } else if (type_h == "weird") { what_to_pull = c("","U","V","W") what_to_pull[1] = what_to_pull[1+direction] # pull out velocity from first equation which_to_pull = (1:4)[-(1+direction)] # throw out equation + # express velocities through the phase-field? for (i in which_to_pull) { - C_pull(equations[i] - rhs[i],what_to_pull[i]) + C_pull(equations_lhs[i] - equations_rhs[i],what_to_pull[i]) } } else stop("Unknown type of BC") } @@ -160,7 +190,7 @@ CudaDeviceFunction void (){ } #ifdef OPTIONS_OutFlow @@ -953,13 +983,17 @@ CudaDeviceFunction real_t Init_real_wallNorm() int i,j,k; real_t tmp = 0.0; real_t PhaseF_tmp[3][3][3]; - // mirror in the beginning, in case of non-periodic boundaries + + // find in which direction to do reflection + // mirror in the beginning, in case of non-periodic boundaries, + // so we don't accidentally take the value from the other phase + /// Can keep if the setting set to true int nx = constContainer.nx; for (i=-1;i<2;i++){for (j=-1;j<2;j++){for (k=-1;k<2;k++){ - if ((i == -1) && (X == 0.5)) { + if (InvasionDrainage && (i == -1) && (X == 0.5)) { PhaseF_tmp[i+1][j+1][k+1] = PhaseF_dyn(-i,j,k); } - else if ((i == 1) && (X == nx - 0.5)) { + else if (InvasionDrainage && (i == 1) && (X == nx - 0.5)) { PhaseF_tmp[i+1][j+1][k+1] = PhaseF_dyn(-i,j,k); } else { diff --git a/models/multiphase/d3q27_pf_velocity/Dynamics.R b/models/multiphase/d3q27_pf_velocity/Dynamics.R index 4d0be761d..6b95173fa 100644 --- a/models/multiphase/d3q27_pf_velocity/Dynamics.R +++ b/models/multiphase/d3q27_pf_velocity/Dynamics.R @@ -172,7 +172,7 @@ if (Options$thermo){ AddAction("Iteration", c("BaseIter", "calcPhase", calcGrad, "calcWall_CA", "calcWallPhase_correction")) AddAction("Init" , c("PhaseInit","WallInit_Real","WallInit_CA" , "calcPhaseGrad_init" , "calcWall_CA", "calcWallPhase_correction", "BaseInit")) AddAction("InitFields" , c("InitFromFieldsStage","WallInit_Real","WallInit_CA" , "calcPhaseGrad_init", "calcWall_CA", "calcWallPhase_correction", "BaseInit")) - AddAction("InitFieldsWithNormals" , c("InitFromFieldsStageWithNormals","WallInit_CA" , "calcPhaseGrad_init", "calcWall_CA", "calcWallPhase_correction", "BaseInit")) + AddAction("InitFieldsWithNormals" , c("InitFromFieldsStageWithNormals",,"WallInit_CA" , "calcPhaseGrad_init", "calcWall_CA", "calcWallPhase_correction", "BaseInit")) } else { AddAction("Iteration", c("BaseIter", "calcPhase", "calcWall", "calcWallPhase_correction")) AddAction("Init" , c("PhaseInit", "WallInit_Real", "WallInit" , "calcWall","calcWallPhase_correction", "BaseInit")) @@ -248,6 +248,7 @@ if (Options$thermo){ AddSetting(name="VelocityY", default=0.0, comment='inlet/outlet/init velocity', zonal=T) AddSetting(name="VelocityZ", default=0.0, comment='inlet/outlet/init velocity', zonal=T) AddSetting(name="Pressure" , default=0.0, comment='inlet/outlet/init density', zonal=T) + AddSetting(name='InvasionDrainage', default=0, comment='0 nothing, 1 flooding, -1 drainage') AddSetting(name="GravitationX", default=0.0, comment='applied (rho)*GravitationX') AddSetting(name="GravitationY", default=0.0, comment='applied (rho)*GravitationY') AddSetting(name="GravitationZ", default=0.0, comment='applied (rho)*GravitationZ') @@ -276,12 +277,17 @@ if (Options$thermo){ ########################## AddNodeType("Smoothing",group="ADDITIONALS") AddNodeType(name="flux_nodes", group="ADDITIONALS") + # the first one are "fix_pf" + pressure_boundary_types = c("", "open", "fflux") dotR_my_velocity_boundaries = paste0(c("N","E","S","W","F","B"),"Velocity") - dotR_my_pressure_boundaries = paste0(c("N","E","S","W","F","B"),"Pressure") + dotR_my_pressure_boundaries = outer(paste0(c("N","E","S","W","F","B"),"Pressure"), pressure_boundary_types, FUN = paste, sep="") for (ii in 1:6){ AddNodeType(name=dotR_my_velocity_boundaries[ii], group="BOUNDARY") + } + for (ii in 1:length(dotR_my_pressure_boundaries)) { AddNodeType(name=dotR_my_pressure_boundaries[ii], group="BOUNDARY") } + AddNodeType(name="MovingWall_N", group="BOUNDARY") AddNodeType(name="MovingWall_S", group="BOUNDARY") AddNodeType(name="Solid", group="BOUNDARY") diff --git a/models/multiphase/d3q27_pf_velocity/Dynamics.c.Rt b/models/multiphase/d3q27_pf_velocity/Dynamics.c.Rt index f2b632c7d..3a2ae382d 100755 --- a/models/multiphase/d3q27_pf_velocity/Dynamics.c.Rt +++ b/models/multiphase/d3q27_pf_velocity/Dynamics.c.Rt @@ -149,7 +149,8 @@ CudaDeviceFunction vector_t calcGradPhi() ?> auto boundary_marker = NodeType & NODE_BOUNDARY; - if (boundary_marker == NODE_EPressure || boundary_marker == NODE_WPressure) { + + if () { gradPhi.x = 0.0; gradPhi.y = 0.0; gradPhi.z = 0.0; @@ -235,7 +236,8 @@ CudaDeviceFunction real_t calcMu(real_t C) #else auto boundary_marker = NodeType & NODE_BOUNDARY; - if (boundary_marker == NODE_EPressure || boundary_marker == NODE_WPressure) { + + if () { lpPhi = 0.0; } @@ -274,12 +276,17 @@ CudaDeviceFunction real_t calcF_phi(int i, real_t tmp1, real_t nx, real_t ny, re return f_phi; } +CudaDeviceFunction void InitPhaseFforWallNormals() +{ + if ( IamWall || IamSolid ) PhaseF = -999; +} + /* INITIALISATION: */ CudaDeviceFunction void Init() { PhaseF = PhaseField; specialCases_Init(); - if ( IamWall || IamSolid ) PhaseF = -999; + InitPhaseFforWallNormals(); if (developedFlow > 0.1) { U = 6.0 * Uavg * Y*(HEIGHT - Y)/(HEIGHT*HEIGHT); @@ -302,7 +309,7 @@ CudaDeviceFunction void InitFromFieldsStage() U = Init_UX_External; V = Init_UY_External; W = Init_UZ_External; - if ( IamWall || IamSolid ) PhaseF = -999; + InitPhaseFforWallNormals(); pnorm = 0.0; // initialise as zero and fill in later stage } @@ -313,7 +320,7 @@ CudaDeviceFunction void InitFromFieldsStageWithNormals() U = Init_UX_External; V = Init_UY_External; W = Init_UZ_External; - if ( IamWall || IamSolid ) PhaseF = -999; + InitPhaseFforWallNormals(); pnorm = 0.0; // initialise as zero and fill in later stage nw_x = Init_nwx_external; nw_y = Init_nwy_external; @@ -719,16 +726,22 @@ CudaDeviceFunction void updateBoundary(){ BounceBack(); break; case NODE_: (); break; - case NODE_: - (); - break; + + case NODE_: + (); + break; + case NODE_MovingWall_N: MovingNWall(); From fe4f08b04f98fa707bf57101546776fd5422c478 Mon Sep 17 00:00:00 2001 From: Dmytro Sashko Date: Tue, 28 May 2024 09:01:35 +1000 Subject: [PATCH 11/26] Add comments --- models/multiphase/d3q27_pf_velocity/Boundary.c.Rt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt index f7e784f3f..6af24b6d6 100644 --- a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt +++ b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt @@ -987,7 +987,12 @@ CudaDeviceFunction real_t Init_real_wallNorm() // find in which direction to do reflection // mirror in the beginning, in case of non-periodic boundaries, // so we don't accidentally take the value from the other phase - /// Can keep if the setting set to true + // =========================================================== + // NOTE: Works only in X direction. To use pressure/velocity + // bondaries in other directions need to mark the boundaries + // with symmetry market, otherwise wall gradients might point + // to the other side. (I.e. SymmetryX_plus at the same location + // as EPressure, etc) int nx = constContainer.nx; for (i=-1;i<2;i++){for (j=-1;j<2;j++){for (k=-1;k<2;k++){ if (InvasionDrainage && (i == -1) && (X == 0.5)) { From 8c48c8df35dcf82af24b9fb16cc1d6f439073bb3 Mon Sep 17 00:00:00 2001 From: Dmytro Sashko Date: Tue, 28 May 2024 12:47:15 +1000 Subject: [PATCH 12/26] Make more explicit --- models/multiphase/d3q27_pf_velocity/Boundary.c.Rt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt index 6af24b6d6..fcdfa5c85 100644 --- a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt +++ b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt @@ -995,10 +995,10 @@ CudaDeviceFunction real_t Init_real_wallNorm() // as EPressure, etc) int nx = constContainer.nx; for (i=-1;i<2;i++){for (j=-1;j<2;j++){for (k=-1;k<2;k++){ - if (InvasionDrainage && (i == -1) && (X == 0.5)) { + if ((InvasionDrainage > 0) && (i == -1) && (X == 0.5)) { PhaseF_tmp[i+1][j+1][k+1] = PhaseF_dyn(-i,j,k); } - else if (InvasionDrainage && (i == 1) && (X == nx - 0.5)) { + else if ((InvasionDrainage > 0) && (i == 1) && (X == nx - 0.5)) { PhaseF_tmp[i+1][j+1][k+1] = PhaseF_dyn(-i,j,k); } else { From 34ea4257420c2dc38101b8f39292aed17c696131 Mon Sep 17 00:00:00 2001 From: Dmytro Sashko Date: Tue, 28 May 2024 13:05:28 +1000 Subject: [PATCH 13/26] Fix --- models/multiphase/d3q27_pf_velocity/Dynamics.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/multiphase/d3q27_pf_velocity/Dynamics.R b/models/multiphase/d3q27_pf_velocity/Dynamics.R index 6b95173fa..8629d5de7 100644 --- a/models/multiphase/d3q27_pf_velocity/Dynamics.R +++ b/models/multiphase/d3q27_pf_velocity/Dynamics.R @@ -172,7 +172,7 @@ if (Options$thermo){ AddAction("Iteration", c("BaseIter", "calcPhase", calcGrad, "calcWall_CA", "calcWallPhase_correction")) AddAction("Init" , c("PhaseInit","WallInit_Real","WallInit_CA" , "calcPhaseGrad_init" , "calcWall_CA", "calcWallPhase_correction", "BaseInit")) AddAction("InitFields" , c("InitFromFieldsStage","WallInit_Real","WallInit_CA" , "calcPhaseGrad_init", "calcWall_CA", "calcWallPhase_correction", "BaseInit")) - AddAction("InitFieldsWithNormals" , c("InitFromFieldsStageWithNormals",,"WallInit_CA" , "calcPhaseGrad_init", "calcWall_CA", "calcWallPhase_correction", "BaseInit")) + AddAction("InitFieldsWithNormals" , c("InitFromFieldsStageWithNormals","WallInit_CA" , "calcPhaseGrad_init", "calcWall_CA", "calcWallPhase_correction", "BaseInit")) } else { AddAction("Iteration", c("BaseIter", "calcPhase", "calcWall", "calcWallPhase_correction")) AddAction("Init" , c("PhaseInit", "WallInit_Real", "WallInit" , "calcWall","calcWallPhase_correction", "BaseInit")) From 98accf45f96e0cde59bf8347faf643aab76fe716 Mon Sep 17 00:00:00 2001 From: Dmytro Sashko Date: Tue, 4 Jun 2024 08:55:16 +1000 Subject: [PATCH 14/26] Fix --- models/multiphase/d3q27_pf_velocity/Boundary.c.Rt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt index fcdfa5c85..a672e94e4 100644 --- a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt +++ b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt @@ -972,7 +972,7 @@ CudaDeviceFunction real_t getSpecialBoundaryPoint() { /* Calculate the actual wall norm based on the solid *field */ -CudaDeviceFunction real_t Init_real_wallNorm() +CudaDeviceFunction void Init_real_wallNorm() { // set initial values nw_x = 0.0; From 660ce39361c9c0d7f6a31dea9e42202953e03a25 Mon Sep 17 00:00:00 2001 From: Dmytro Sashko Date: Wed, 5 Jun 2024 09:07:27 +1000 Subject: [PATCH 15/26] Change the default type --- models/multiphase/d3q27_pf_velocity/Boundary.c.Rt | 2 +- models/multiphase/d3q27_pf_velocity/Dynamics.R | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt index a672e94e4..65942baa1 100644 --- a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt +++ b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt @@ -93,7 +93,7 @@ CudaDeviceFunction void Date: Fri, 14 Jun 2024 11:19:21 +1000 Subject: [PATCH 16/26] Add setting pressure on the boundaries using RunR --- models/multiphase/d3q27_pf_velocity/Boundary.c.Rt | 4 ++++ models/multiphase/d3q27_pf_velocity/Dynamics.R | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt index 65942baa1..ef80fcd11 100644 --- a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt +++ b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt @@ -92,6 +92,10 @@ CudaDeviceFunction void 0){ + /// use pressure set externally from RunR + p_star = Pressure_external / (d*cs2); + } Date: Fri, 14 Jun 2024 12:53:20 +1000 Subject: [PATCH 17/26] Fix typo --- models/multiphase/d3q27_pf_velocity/Boundary.c.Rt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt index ef80fcd11..0a9aae192 100644 --- a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt +++ b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt @@ -94,7 +94,7 @@ CudaDeviceFunction void 0){ /// use pressure set externally from RunR - p_star = Pressure_external / (d*cs2); + pstar = Pressure_external / (d*cs2); } Date: Mon, 26 Aug 2024 14:09:22 +1000 Subject: [PATCH 18/26] Fix normalization for the special boundary points Need to normalise by the sum of weights obviously (otherwise would leads to crazy low values of the phase field in random points of the domain) --- models/multiphase/d3q27_pf_velocity/Boundary.c.Rt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt index 0a9aae192..7cfef71a9 100644 --- a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt +++ b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt @@ -781,17 +781,19 @@ CudaDeviceFunction void calcWallPhase_correction() { int count = 0; real_t fluid_average = 0.0; real_t x, y, z; + real_t denom = 0.0; for (int i=1; i<27 ; i++){ x = d3q27_ex[i]; y = d3q27_ey[i]; z = d3q27_ez[i]; if (!IsBoundary_dyn(int(x), int(y), int(z)) && PhaseF_dyn(int(x), int(y), int(z)) > -0.5) { fluid_average += wg[i]*PhaseF_dyn(int(x), int(y), int(z)); + denom += wg[i]; count++; } } // print sum and average and count - PhaseF = count == 0 ? 1 : fluid_average / count; + PhaseF = count == 0 ? 1 : fluid_average / denom; } else { PhaseF = point_in_the_normal_direction; } From 7fa107c62bf7f0df6cbb558f7d72dceab853f9fd Mon Sep 17 00:00:00 2001 From: Dmytro Sashko Date: Thu, 5 Sep 2024 15:54:07 +1000 Subject: [PATCH 19/26] Improve the phase field and density on Boundaries --- .../multiphase/d3q27_pf_velocity/Boundary.c.Rt | 16 ++++++---------- models/multiphase/d3q27_pf_velocity/Dynamics.R | 2 +- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt index 7cfef71a9..15467d732 100644 --- a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt +++ b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt @@ -78,18 +78,14 @@ CudaDeviceFunction void (){ for (ii in 1:cube_faces){ for (j in 1:length(pressure_boundary_types)) { ?> CudaDeviceFunction void (){ - real_t d = getRho(); - real_t myPhaseField = 0.0; - if ((NodeType & NODE_BOUNDARY) == ){ - d = InvasionDrainage == 2? Density_l : Density_h; - myPhaseField = InvasionDrainage == 2? 0.0 : 1.0; - } - if ((NodeType & NODE_BOUNDARY) == ){ - d = InvasionDrainage == 2? Density_h : Density_l; - myPhaseField = InvasionDrainage == 2? 1.0 : 0.0; - } + // can't use PhaseF or getRho() because + // the values can be streamed from the other side of the + // boundary + real_t myPhaseField = PhaseField; + real_t d = Density_l + (Density_h-Density_l) * (PhaseField - PhaseField_l)/(PhaseField_h - PhaseField_l); + real_t pstar = Pressure / (d*cs2); if (UseExternalPressure > 0){ diff --git a/models/multiphase/d3q27_pf_velocity/Dynamics.R b/models/multiphase/d3q27_pf_velocity/Dynamics.R index 314c1ab05..71f4bf875 100644 --- a/models/multiphase/d3q27_pf_velocity/Dynamics.R +++ b/models/multiphase/d3q27_pf_velocity/Dynamics.R @@ -252,7 +252,7 @@ if (Options$thermo){ AddSetting(name="VelocityY", default=0.0, comment='inlet/outlet/init velocity', zonal=T) AddSetting(name="VelocityZ", default=0.0, comment='inlet/outlet/init velocity', zonal=T) AddSetting(name="Pressure" , default=0.0, comment='inlet/outlet/init density', zonal=T) - AddSetting(name='InvasionDrainage', default=0, comment='0 nothing, 1 flooding, -1 drainage') + AddSetting(name='InvasionDrainage', default=0, comment='0 nothing, anything bigger is invasion/drainage case") AddSetting(name="GravitationX", default=0.0, comment='applied (rho)*GravitationX') AddSetting(name="GravitationY", default=0.0, comment='applied (rho)*GravitationY') AddSetting(name="GravitationZ", default=0.0, comment='applied (rho)*GravitationZ') From 010a091ad59e783fd5c9bf2baff3b628c8c74c55 Mon Sep 17 00:00:00 2001 From: Dmytro Sashko Date: Wed, 11 Sep 2024 14:40:13 +1000 Subject: [PATCH 20/26] Fix typo --- models/multiphase/d3q27_pf_velocity/Dynamics.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/multiphase/d3q27_pf_velocity/Dynamics.R b/models/multiphase/d3q27_pf_velocity/Dynamics.R index 71f4bf875..d5780da1d 100644 --- a/models/multiphase/d3q27_pf_velocity/Dynamics.R +++ b/models/multiphase/d3q27_pf_velocity/Dynamics.R @@ -252,7 +252,7 @@ if (Options$thermo){ AddSetting(name="VelocityY", default=0.0, comment='inlet/outlet/init velocity', zonal=T) AddSetting(name="VelocityZ", default=0.0, comment='inlet/outlet/init velocity', zonal=T) AddSetting(name="Pressure" , default=0.0, comment='inlet/outlet/init density', zonal=T) - AddSetting(name='InvasionDrainage', default=0, comment='0 nothing, anything bigger is invasion/drainage case") + AddSetting(name='InvasionDrainage', default=0, comment="0 nothing, anything bigger is invasion/drainage case") AddSetting(name="GravitationX", default=0.0, comment='applied (rho)*GravitationX') AddSetting(name="GravitationY", default=0.0, comment='applied (rho)*GravitationY') AddSetting(name="GravitationZ", default=0.0, comment='applied (rho)*GravitationZ') From 463ce27cefd4a56b6dce154cb82fe726afa02ab2 Mon Sep 17 00:00:00 2001 From: Dmytro Sashko Date: Tue, 17 Sep 2024 15:25:18 +1000 Subject: [PATCH 21/26] Add more robust version of special boundary points --- .../d3q27_pf_velocity/Boundary.c.Rt | 53 +++++++++---------- 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt index 15467d732..c300fe24b 100644 --- a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt +++ b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt @@ -765,35 +765,32 @@ CudaDeviceFunction void calcPhaseGradCloseToBoundary(){ * yet set value */ CudaDeviceFunction void calcWallPhase_correction() { - PhaseF = PhaseF(0,0,0); - if (IsSpecialBoundaryPoint == ) { - // take the phase field calculated already from the node in front. - // Might as well calculate using the neighbors, e.g. averaging - real_t point_in_the_normal_direction = PhaseF_dyn(nw_x, nw_y, nw_z); - // in some cases we might (TODO: investigate) still point into the solid node - // that has normal pointing into another, we need to avoid this - if (point_in_the_normal_direction == ) { - // ignore first node - int count = 0; - real_t fluid_average = 0.0; - real_t x, y, z; - real_t denom = 0.0; - for (int i=1; i<27 ; i++){ - x = d3q27_ex[i]; - y = d3q27_ey[i]; - z = d3q27_ez[i]; - if (!IsBoundary_dyn(int(x), int(y), int(z)) && PhaseF_dyn(int(x), int(y), int(z)) > -0.5) { - fluid_average += wg[i]*PhaseF_dyn(int(x), int(y), int(z)); - denom += wg[i]; - count++; - } - } - // print sum and average and count - PhaseF = count == 0 ? 1 : fluid_average / denom; - } else { - PhaseF = point_in_the_normal_direction; + PhaseF = PhaseF(0,0,0); + if (IsSpecialBoundaryPoint == ) { + // We could take the phase field calculated already from the node in front + // (solid in the direction of solid normal) + // if it is already has the phase field value calculated (from the BC application) + // however this seems to be less stable... + // More robust is calculate using the neighbors, e.g. averaging. + // If this also would not work at some point, more detailed investigation is needed + int count = 0; + real_t fluid_average = 0.0; + real_t x, y, z; + real_t denom = 0.0; + // ignore first node + for (int i=1; i<27 ; i++){ + x = d3q27_ex[i]; + y = d3q27_ey[i]; + z = d3q27_ez[i]; + if (!IsBoundary_dyn(int(x), int(y), int(z)) && PhaseF_dyn(int(x), int(y), int(z)) > -0.5) { + fluid_average += wg[i]*PhaseF_dyn(int(x), int(y), int(z)); + denom += wg[i]; + count++; + } } - } + // print sum and average and count + PhaseF = count == 0 ? 1 : fluid_average / denom; + } } From 0da8bbef53844f21ce208bc566a252bc6a6d4d4c Mon Sep 17 00:00:00 2001 From: Dmytro Sashko Date: Fri, 2 May 2025 08:05:47 +1000 Subject: [PATCH 22/26] Add velocity limiter --- models/multiphase/d3q27_pf_velocity/Dynamics.R | 2 ++ models/multiphase/d3q27_pf_velocity/Dynamics.c.Rt | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/models/multiphase/d3q27_pf_velocity/Dynamics.R b/models/multiphase/d3q27_pf_velocity/Dynamics.R index d5780da1d..37bd02927 100644 --- a/models/multiphase/d3q27_pf_velocity/Dynamics.R +++ b/models/multiphase/d3q27_pf_velocity/Dynamics.R @@ -259,6 +259,7 @@ if (Options$thermo){ AddSetting(name="BuoyancyX", default=0.0, comment='applied (rho_h-rho)*BuoyancyX') AddSetting(name="BuoyancyY", default=0.0, comment='applied (rho_h-rho)*BuoyancyY') AddSetting(name="BuoyancyZ", default=0.0, comment='applied (rho_h-rho)*BuoyancyZ') + AddSetting(name="vlimiter", default=0.0, comment="Velocity limiter value") ################################## ########TRACKING VARIABLES######## ################################## @@ -321,6 +322,7 @@ if (Options$thermo){ AddGlobal(name="LiqTotalVelocityX", comment='use to determine avg velocity of droplets', unit="m/s") AddGlobal(name="LiqTotalVelocityY", comment='use to determine avg velocity of droplets', unit="m/s") AddGlobal(name="LiqTotalVelocityZ", comment='use to determine avg velocity of droplets', unit="m/s") + AddGlobal(name="LimitedCells", comment='Number of cells where we limited the velocity', unit="1") AddGlobal(name="NumFluidCells", comment='Number of fluid cells') AddGlobal(name="NumSpecialPoints", comment='Number of special points') AddGlobal(name="NumWallBoundaryPoints", comment='Number of boundary nodes') diff --git a/models/multiphase/d3q27_pf_velocity/Dynamics.c.Rt b/models/multiphase/d3q27_pf_velocity/Dynamics.c.Rt index 3a2ae382d..580fbdab9 100755 --- a/models/multiphase/d3q27_pf_velocity/Dynamics.c.Rt +++ b/models/multiphase/d3q27_pf_velocity/Dynamics.c.Rt @@ -687,6 +687,18 @@ CudaDeviceFunction void CollisionMRT() } while (j vlimiter*vlimiter){ + real_t reducer = vlimiter / sqrt(vl); + AddToLimitedCells(1); + U = U * reducer; + V = V * reducer; + W = W * reducer; + } + } + // PHASE FIELD POPULATION UPDATE: tmp1 = (1.0 - 4.0*(C - 0.5)*(C - 0.5))/IntWidth; Date: Tue, 28 Jan 2025 07:42:01 +1000 Subject: [PATCH 23/26] Add tanh initialisation --- models/multiphase/d3q27_pf_velocity/Dynamics.c.Rt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/models/multiphase/d3q27_pf_velocity/Dynamics.c.Rt b/models/multiphase/d3q27_pf_velocity/Dynamics.c.Rt index 580fbdab9..622c1e94f 100755 --- a/models/multiphase/d3q27_pf_velocity/Dynamics.c.Rt +++ b/models/multiphase/d3q27_pf_velocity/Dynamics.c.Rt @@ -400,6 +400,10 @@ CudaDeviceFunction void specialCases_Init() PhaseF = 1 - 0.5 * ( tanh( 2.0 * ( X - Washburn_start ) / IntWidth ) - tanh( 2.0 * ( X - Washburn_end ) / IntWidth )); } + if (Tanh_init > 0) { + PhaseF = 0.5 + 0.5*( tanh( 2.0 * ( X - Tanh_init) / IntWidth )); + } + } CudaDeviceFunction void Init_distributions() From 04b4308b6d4d0238328471ad1d19d47cffd3d698 Mon Sep 17 00:00:00 2001 From: Dmytro Sashko Date: Sat, 22 Feb 2025 10:34:17 +1000 Subject: [PATCH 24/26] Fix typo --- models/multiphase/d3q27_pf_velocity/Dynamics.R | 1 + 1 file changed, 1 insertion(+) diff --git a/models/multiphase/d3q27_pf_velocity/Dynamics.R b/models/multiphase/d3q27_pf_velocity/Dynamics.R index 37bd02927..1289cc830 100644 --- a/models/multiphase/d3q27_pf_velocity/Dynamics.R +++ b/models/multiphase/d3q27_pf_velocity/Dynamics.R @@ -214,6 +214,7 @@ if (Options$thermo){ AddSetting(name="force_fixed_iterator", default=2, comment='to resolve implicit relation of viscous force') AddSetting(name="Washburn_start", default="0", comment='Start of washburn gas phase') AddSetting(name="Washburn_end", default="0", comment='End of washburn gas phase') + AddSetting(name="Tanh_init", default="0", comment='Start of tanh interface initialisation') AddSetting(name="radAngle", default='1.570796', comment='Contact angle in radians, can use units -> 90d where d=2pi/360', zonal=T) AddSetting(name="minGradient", default='1e-8', comment='if the phase gradient is less than this, set phase normals to zero') ##SPECIAL INITIALISATIONS From 69fddbf497b014a6bc2c3870a5e47204dc37dfed Mon Sep 17 00:00:00 2001 From: Dmytro Sashko Date: Mon, 15 Dec 2025 17:54:39 +1000 Subject: [PATCH 25/26] Restructure boundaries lists into a dataframe --- .../d3q27_pf_velocity/Boundary.c.Rt | 25 ++++++++----------- .../multiphase/d3q27_pf_velocity/Dynamics.R | 20 +++++++-------- .../d3q27_pf_velocity/Dynamics.c.Rt | 23 +++++------------ 3 files changed, 27 insertions(+), 41 deletions(-) diff --git a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt index c300fe24b..e50d8a129 100644 --- a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt +++ b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt @@ -2,8 +2,6 @@ ######################################################### # create pressure/velocity boundaries in all directions # ######################################################### - my_velocity_boundaries = PV(paste0(c("N","E","S","W","F","B"),"Velocity")) - my_pressure_boundaries = PV(paste0(c("N","E","S","W","F","B"),"Pressure")) my_normal_directions = rbind(c(0,1,0), c(1,0,0), c(0,-1,0), @@ -11,7 +9,6 @@ c(0,0,1), c(0,0,-1)) - cube_faces = 6 b_uavg = PV("Uavg") b_height = PV("HEIGHT") b_pipecentre_y = PV("pipeCentre_Y") @@ -26,12 +23,13 @@ b_pipe_flow_tmp = (coords_shift-b_pipecentre_y)^2+(coords_shift_2-b_pipecentre_z)^2 - for (ii in 1:cube_faces){ + for (bc in rows(my_velocity_boundaries)) { ?> -CudaDeviceFunction void (){ +CudaDeviceFunction void (){ U = VelocityX; V = VelocityY; W = VelocityZ; + if ( developedFlow > 0.1 ){ (){ ?> -CudaDeviceFunction void (){ + for (bc in rows(my_pressure_boundaries)) { +?> +CudaDeviceFunction void (){ // can't use PhaseF or getRho() because @@ -93,9 +91,8 @@ CudaDeviceFunction void #ifdef OPTIONS_OutFlow diff --git a/models/multiphase/d3q27_pf_velocity/Dynamics.R b/models/multiphase/d3q27_pf_velocity/Dynamics.R index 1289cc830..c8b864136 100644 --- a/models/multiphase/d3q27_pf_velocity/Dynamics.R +++ b/models/multiphase/d3q27_pf_velocity/Dynamics.R @@ -283,16 +283,16 @@ if (Options$thermo){ ########################## AddNodeType("Smoothing",group="ADDITIONALS") AddNodeType(name="flux_nodes", group="ADDITIONALS") - # the first one are "fflux" - pressure_boundary_types = c("", "open", "fpf") - dotR_my_velocity_boundaries = paste0(c("N","E","S","W","F","B"),"Velocity") - dotR_my_pressure_boundaries = outer(paste0(c("N","E","S","W","F","B"),"Pressure"), pressure_boundary_types, FUN = paste, sep="") - for (ii in 1:6){ - AddNodeType(name=dotR_my_velocity_boundaries[ii], group="BOUNDARY") - } - for (ii in 1:length(dotR_my_pressure_boundaries)) { - AddNodeType(name=dotR_my_pressure_boundaries[ii], group="BOUNDARY") - } + + my_boundaries = rbind(expand.grid(side = 1:6, type=c('Pressure'), subtype = c("", "open", "fpf")), + expand.grid(side = 1:6, type=c('Velocity'), subtype=c(""))) + my_boundaries$side_letter = c("N","E","S","W","F","B")[my_boundaries$side] + my_boundaries$name = paste0(my_boundaries$side_letter, my_boundaries$type, my_boundaries$subtype) + AddNodeType(name=my_boundaries$name, group="BOUNDARY") + + # for convienience + my_velocity_boundaries = my_boundaries[my_boundaries$type == 'Pressure', ] + my_pressure_boundaries = my_boundaries[my_boundaries$type == 'Velocity', ] AddNodeType(name="MovingWall_N", group="BOUNDARY") AddNodeType(name="MovingWall_S", group="BOUNDARY") diff --git a/models/multiphase/d3q27_pf_velocity/Dynamics.c.Rt b/models/multiphase/d3q27_pf_velocity/Dynamics.c.Rt index 622c1e94f..f32dfe755 100755 --- a/models/multiphase/d3q27_pf_velocity/Dynamics.c.Rt +++ b/models/multiphase/d3q27_pf_velocity/Dynamics.c.Rt @@ -149,7 +149,7 @@ CudaDeviceFunction vector_t calcGradPhi() ?> auto boundary_marker = NodeType & NODE_BOUNDARY; - + if () { gradPhi.x = 0.0; gradPhi.y = 0.0; @@ -236,7 +236,7 @@ CudaDeviceFunction real_t calcMu(real_t C) #else auto boundary_marker = NodeType & NODE_BOUNDARY; - + if () { lpPhi = 0.0; } @@ -742,23 +742,12 @@ CudaDeviceFunction void updateBoundary(){ BounceBack(); break; - case NODE_: - (); + case NODE_: + (); break; - - - case NODE_: - (); - break; - + case NODE_MovingWall_N: MovingNWall(); break; From b34f3ecd47aa82819614af4927556e6798aa95da Mon Sep 17 00:00:00 2001 From: Dmytro Sashko Date: Mon, 15 Dec 2025 18:02:00 +1000 Subject: [PATCH 26/26] Fix --- models/multiphase/d3q27_pf_velocity/Boundary.c.Rt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt index e50d8a129..f45cfc8a9 100644 --- a/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt +++ b/models/multiphase/d3q27_pf_velocity/Boundary.c.Rt @@ -91,7 +91,7 @@ CudaDeviceFunction void (){ pstar = Pressure_external / (d*cs2); } (){ what_to_pull = c("pstar","U","V","W") which_to_pull = 1:4 direction = which(n != 0) - if (type == "Pressure") { + if (bc$type == "Pressure") { # pop the pressure out of the list of equation # and don't duplicate which_to_pull = which_to_pull[-(1+direction)] what_to_pull[1] = what_to_pull[1+direction] # pull out velocity from first equation - } else if (type == "Velocity") { + } else if (bc$type == "Velocity") { # pop out the equation related to this velocity direction # from the list of equations, as it is already know which_to_pull = which_to_pull[-(1+direction)] # throw out the equation related to this velocity direction