diff --git a/bird/preprocess/dynamic_mixer/io_fvModels.py b/bird/preprocess/dynamic_mixer/io_fvModels.py index f41b701d..6d405984 100644 --- a/bird/preprocess/dynamic_mixer/io_fvModels.py +++ b/bird/preprocess/dynamic_mixer/io_fvModels.py @@ -42,18 +42,26 @@ def write_preamble(output_folder): f.write("\t\tconst volVectorField& UL =\n") f.write('\t\t\tmesh().lookupObject("U.liquid");\n') f.write("\t\tdouble pi=3.141592654;\n") + f.write(f"\t\tdouble source_pt_x;\n") + f.write(f"\t\tdouble source_pt_y;\n") + f.write(f"\t\tdouble source_pt_z;\n") + f.write(f"\t\tdouble disk_rad;\n") + f.write("\t\tdouble disk_area;\n") + f.write(f"\t\tdouble power;\n") + f.write(f"\t\tdouble smear_factor;\n") + f.write(f"\t\tdouble startTime;\n") def write_mixer(mixer, output_folder): with open(os.path.join(output_folder, "fvModels"), "a+") as f: - f.write(f"\t\tdouble source_pt_x={mixer.x};\n") - f.write(f"\t\tdouble source_pt_y={mixer.y};\n") - f.write(f"\t\tdouble source_pt_z={mixer.z};\n") - f.write(f"\t\tdouble disk_rad={mixer.rad};\n") - f.write("\t\tdouble disk_area=pi*disk_rad*disk_rad;\n") - f.write(f"\t\tdouble power={mixer.power};\n") - f.write(f"\t\tdouble smear_factor={float(mixer.smear)};\n") - f.write(f"\t\tconst scalar startTime = {mixer.start_time};\n") + f.write(f"\t\tsource_pt_x={mixer.x};\n") + f.write(f"\t\tsource_pt_y={mixer.y};\n") + f.write(f"\t\tsource_pt_z={mixer.z};\n") + f.write(f"\t\tdisk_rad={mixer.rad};\n") + f.write("\t\tdisk_area=pi*disk_rad*disk_rad;\n") + f.write(f"\t\tpower={mixer.power};\n") + f.write(f"\t\tsmear_factor={float(mixer.smear)};\n") + f.write(f"\t\tstartTime = {mixer.start_time};\n") f.write("\t\tif (time.value() > startTime)\n") f.write("\t\t{\n") f.write("\t\t\t// Get V1\n") @@ -61,7 +69,7 @@ def write_mixer(mixer, output_folder): f.write("\t\t\tdouble V1 = 0;\n") f.write("\t\t\tdouble V2 = 0;\n") f.write("\t\t\tdouble rhoV;\n") - f.write("\t\t\tdouble dist_tol = disk_rad*5;\n") + f.write("\t\t\tdouble dist_tol = disk_rad*3;\n") f.write("\n") f.write("\t\t\tdouble dist_n;\n") f.write("\t\t\tdouble upV = 0;\n") diff --git a/bird/preprocess/dynamic_mixer/mixing_fvModels.py b/bird/preprocess/dynamic_mixer/mixing_fvModels.py index 95eb04f6..146fc510 100644 --- a/bird/preprocess/dynamic_mixer/mixing_fvModels.py +++ b/bird/preprocess/dynamic_mixer/mixing_fvModels.py @@ -28,7 +28,7 @@ def check_input(input_dict): return mix_type -def write_fvModel(input_dict, output_folder="."): +def write_fvModel(input_dict, output_folder=".", force_sign=False): mix_type = check_input(input_dict) write_preamble(output_folder) if "loop" in mix_type: @@ -39,13 +39,19 @@ def write_fvModel(input_dict, output_folder="."): if mtype == "expl": mixer.update_from_expl_dict(input_dict["mixers"][imix]) if mixer.ready: - write_mixer(mixer, output_folder) + if force_sign: + write_mixer_force_sign(mixer, output_folder) + else: + write_mixer(mixer, output_folder) elif mtype == "loop": mixer.update_from_loop_dict( input_dict["mixers"][imix], geom_dict, mesh_dict ) if mixer.ready: - write_mixer(mixer, output_folder) + if force_sign: + write_mixer_force_sign(mixer, output_folder) + else: + write_mixer(mixer, output_folder) write_end(output_folder) diff --git a/bird/preprocess/stl_patch/stl_bc.py b/bird/preprocess/stl_patch/stl_bc.py index 29a96c4c..a14584fa 100644 --- a/bird/preprocess/stl_patch/stl_bc.py +++ b/bird/preprocess/stl_patch/stl_bc.py @@ -12,7 +12,7 @@ def check_input(input_dict): assert isinstance(input_dict, dict) need_geom = False for bound in input_dict: - if not bound == "Geometry": + if not bound == "Geometry" and not bound == "Meshing": assert isinstance(input_dict[bound], list) for patch in input_dict[bound]: assert isinstance(patch, dict) diff --git a/bird/utilities/ofio.py b/bird/utilities/ofio.py index 503780fc..a8cd223f 100644 --- a/bird/utilities/ofio.py +++ b/bird/utilities/ofio.py @@ -129,13 +129,16 @@ def readSizeGroups(file): return sizeGroup, binGroup -def getCaseTimes(casePath): +def getCaseTimes(casePath, remove_zero=False): # Read Time times_tmp = os.listdir(casePath) # remove non floats for i, entry in reversed(list(enumerate(times_tmp))): try: a = float(entry) + if remove_zero: + if abs(a) < 1e-12: + _ = times_tmp.pop(i) except ValueError: print(f"{entry} not a time folder, removing") a = times_tmp.pop(i) diff --git a/bird/version.py b/bird/version.py index 3afce8fc..75d8e719 100644 --- a/bird/version.py +++ b/bird/version.py @@ -1,3 +1,3 @@ """Bio reactor design version""" -__version__ = "0.0.18" +__version__ = "0.0.19" diff --git a/docs/source/airlift.rst b/docs/source/airlift.rst index f64d8200..3147febd 100644 --- a/docs/source/airlift.rst +++ b/docs/source/airlift.rst @@ -15,6 +15,9 @@ Initial conditions Setup the bubble model ------------ +Turbulence model +------------ + Run the solver ------------ diff --git a/docs/source/bubbleColumn.rst b/docs/source/bubbleColumn.rst index cf67974b..74dcd692 100644 --- a/docs/source/bubbleColumn.rst +++ b/docs/source/bubbleColumn.rst @@ -37,7 +37,7 @@ This command generates the appropriate ``blockMeshDict`` Block geometry ~~~~~~~~~~~ -BiRD uses a block cyclindral geometry description (:ref:`Block cylindrical meshing`). The block description of the geometry is in ``${BCE_CASE}/system/mesh.json`` under the ``Geometry`` key +BiRD uses a block cylindral geometry description (:ref:`Block cylindrical meshing`). The block description of the geometry is in ``${BCE_CASE}/system/mesh.json`` under the ``Geometry`` key .. code-block:: json @@ -67,7 +67,7 @@ Those numbers describes the coordinates of the cylindrical blocks. Using the blo Note that the first radial number ``column_trans`` is special and results in 2 radial blocks. The first radial block is the square of the pillow-mesh where the edge is half of the first coordinate :math:`(275/2=137.5)`. The second radial block is the outer-shell of the pillow. -By default, the coordinates of the block cyclindrical geometry are in meters. In this case, the intention was to indicate milimeters instead. This will be handled during the :ref:`Mesh post-treatment` below. +By default, the coordinates of the block cylindrical geometry are in meters. In this case, the intention was to indicate millimeters instead. This will be handled during the :ref:`Mesh post-treatment` below. Each one of the cylindrical blocks will be meshed because we are constructing a bubble column. So there is no need for defining one of the blocks as a wall (conversely to the example shown in :ref:`Block cylindrical meshing`). @@ -184,7 +184,7 @@ Inlet patch ------------ BiRD allows for the generation of complex patches through the generation of ``.stl`` files that describe the patch geometry. -Note that we could have generated the outlet patch with another stl file (we do it in the case of the loop reactor tutorial). Here, since the outlet can be simply defined as an entire block cyclindrical face, we prefer to define it that way. In the case of the inlet, only part of a block cyclindrical face is the inlet, and it is more convenient to use the ``.stl`` approach. +Note that we could have generated the outlet patch with another stl file (we do it in the case of the loop reactor tutorial). Here, since the outlet can be simply defined as an entire block cylindrical face, we prefer to define it that way. In the case of the inlet, only part of a block cylindrical face is the inlet, and it is more convenient to use the ``.stl`` approach. Here, we would like to create a circular sparger centered on :math:`(x,y,z)=(0,0,0)`, and of radius :math:`0.2` m, with a normal face along the :math:`y`-direction Recall that we scaled our mesh so the outer radius of the column is now :math:`0.360` m, and not :math:`360` m. @@ -320,6 +320,14 @@ For example, one choose to use the constant diameter model and do cd ${BCE_CASE} cp constant/phaseProperties_constantd constant/phaseProperties +Turbulence model +------------ + +The turbulence model is set as :math:`k-\varepsilon` in the gas phase and the liquid phase. The turbulence model can be activated through ``${BCE_CASE}/constant/momentumTransport.gas`` for the gas phase and ``${BCE_CASE}/constant/momentumTransport.liquid`` for the liquid phase. + +The boundary conditions for the turbulence model are set in ``0.orig/k.*``, ``0.orig/epsilon.*``, ``0.orig/nut.*``. The inlet boundary values are calculated from freestream turbulence correlations shown in ``constant/globalVars``. For example, ``k_inlet_liq #calc "1.5 * Foam::pow(($uGasPhase), 2) * Foam::pow($intensity, 2)";``. + + Run the solver ------------ The solver can be run by executing diff --git a/docs/source/loopReactor.rst b/docs/source/loopReactor.rst index 887a9c25..8c737223 100644 --- a/docs/source/loopReactor.rst +++ b/docs/source/loopReactor.rst @@ -15,6 +15,9 @@ Initial conditions Setup the bubble model ------------ +Turbulence model +------------ + Run the solver ------------ diff --git a/docs/source/side_sparger.rst b/docs/source/side_sparger.rst index 8e948ed2..06cba44c 100644 --- a/docs/source/side_sparger.rst +++ b/docs/source/side_sparger.rst @@ -15,6 +15,9 @@ Initial conditions Setup the bubble model ------------ +Turbulence model +------------ + Run the solver ------------ diff --git a/docs/source/stirred_tank.rst b/docs/source/stirred_tank.rst index db8177fc..66f56ece 100644 --- a/docs/source/stirred_tank.rst +++ b/docs/source/stirred_tank.rst @@ -15,6 +15,9 @@ Initial conditions Setup the bubble model ------------ +Turbulence model +------------ + Run the solver ------------ diff --git a/docs/source/tutorials.rst b/docs/source/tutorials.rst index df14a45b..1d19efcf 100644 --- a/docs/source/tutorials.rst +++ b/docs/source/tutorials.rst @@ -13,7 +13,3 @@ Tutorials bubbleColumn.rst calibration_normal_beta.rst calibration_bsd.rst - loopReactor.rst - airlift.rst - stirred_tank.rst - side_sparger.rst diff --git a/tutorial_cases/bubble_column_20L/0.orig/epsilon.gas b/tutorial_cases/bubble_column_20L/0.orig/epsilon.gas index 09a52d7f..dfeb30b0 100644 --- a/tutorial_cases/bubble_column_20L/0.orig/epsilon.gas +++ b/tutorial_cases/bubble_column_20L/0.orig/epsilon.gas @@ -34,7 +34,8 @@ boundaryField defaultFaces { - type zeroGradient; + type epsilonWallFunction; + value $internalField; } } diff --git a/tutorial_cases/bubble_column_20L/0.orig/k.gas b/tutorial_cases/bubble_column_20L/0.orig/k.gas index 4a3d44ca..c5d6f1fb 100644 --- a/tutorial_cases/bubble_column_20L/0.orig/k.gas +++ b/tutorial_cases/bubble_column_20L/0.orig/k.gas @@ -36,7 +36,8 @@ boundaryField defaultFaces { - type zeroGradient; + type kqRWallFunction; + value $internalField; } } diff --git a/tutorial_cases/bubble_column_20L/0.orig/nut.gas b/tutorial_cases/bubble_column_20L/0.orig/nut.gas index ba16dd4c..1e32e6e0 100644 --- a/tutorial_cases/bubble_column_20L/0.orig/nut.gas +++ b/tutorial_cases/bubble_column_20L/0.orig/nut.gas @@ -15,7 +15,9 @@ FoamFile dimensions [0 2 -1 0 0 0 0]; -internalField uniform 1e-8; +#include "${FOAM_CASE}/constant/globalVars" + +internalField uniform $nut_inlet_gas; boundaryField { @@ -33,16 +35,10 @@ boundaryField defaultFaces { - //type nutkWallFunction; - //value $internalField; - type calculated; + type nutkWallFunction; value $internalField; } - // defaultFaces - // { - // type empty; - // } } // ************************************************************************* // diff --git a/tutorial_cases/bubble_column_20L/0.orig/nut.liquid b/tutorial_cases/bubble_column_20L/0.orig/nut.liquid index 1442e07f..e197d74f 100644 --- a/tutorial_cases/bubble_column_20L/0.orig/nut.liquid +++ b/tutorial_cases/bubble_column_20L/0.orig/nut.liquid @@ -15,7 +15,9 @@ FoamFile dimensions [0 2 -1 0 0 0 0]; -internalField uniform 1e-4; +#include "${FOAM_CASE}/constant/globalVars" + +internalField uniform $nut_inlet_liq; boundaryField { diff --git a/tutorial_cases/bubble_column_20L/constant/globalVars b/tutorial_cases/bubble_column_20L/constant/globalVars index 4cb668c3..8d745c68 100644 --- a/tutorial_cases/bubble_column_20L/constant/globalVars +++ b/tutorial_cases/bubble_column_20L/constant/globalVars @@ -87,3 +87,5 @@ eps_inlet_gas #calc "pow(0.09,0.75) * Foam::pow($k_inlet_gas, 1.5) / ($l_scale * eps_inlet_liq #calc "pow(0.09,0.75) * Foam::pow($k_inlet_liq, 1.5) / ($l_scale * 0.07)"; omega_inlet_gas #calc "pow(0.09,-0.25) * pow($k_inlet_gas,0.5) / ($l_scale * 0.07)"; omega_inlet_liq #calc "pow(0.09,-0.25) * pow($k_inlet_liq,0.5) / ($l_scale * 0.07)"; +nut_inlet_gas #calc "0.09 * Foam::pow(($k_inlet_gas), 2) / $eps_inlet_gas"; +nut_inlet_liq #calc "0.09 * Foam::pow(($k_inlet_liq), 2) / $eps_inlet_liq"; diff --git a/tutorial_cases/bubble_column_20L/constant/globalVars_temp b/tutorial_cases/bubble_column_20L/constant/globalVars_temp index 1e219071..2e3dfeb8 100644 --- a/tutorial_cases/bubble_column_20L/constant/globalVars_temp +++ b/tutorial_cases/bubble_column_20L/constant/globalVars_temp @@ -87,3 +87,5 @@ eps_inlet_gas #calc "pow(0.09,0.75) * Foam::pow($k_inlet_gas, 1.5) / ($l_scale * eps_inlet_liq #calc "pow(0.09,0.75) * Foam::pow($k_inlet_liq, 1.5) / ($l_scale * 0.07)"; omega_inlet_gas #calc "pow(0.09,-0.25) * pow($k_inlet_gas,0.5) / ($l_scale * 0.07)"; omega_inlet_liq #calc "pow(0.09,-0.25) * pow($k_inlet_liq,0.5) / ($l_scale * 0.07)"; +nut_inlet_gas #calc "0.09 * Foam::pow(($k_inlet_gas), 2) / $eps_inlet_gas"; +nut_inlet_liq #calc "0.09 * Foam::pow(($k_inlet_liq), 2) / $eps_inlet_liq";