Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions CfdOF/Mesh/CfdMeshRefinement.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
EXTRUSION_NAMES = ["2D planar mesh", "2D wedge mesh", "Patch-normal", "Rotational"]
EXTRUSION_TYPES = ["2DPlanar", "2DWedge", "PatchNormal", "Rotational"]
EXTRUSION_UI = [[2], [6], [1, 2, 4, 5], [1, 3, 4, 5, 6]]
SPEED_NAMES = ["constant speed", "variable speed"]
SPEED_TYPES = ["ConstantSpeed", "VariableSpeed"]


def makeCfdMeshRefinement(base_mesh, name="MeshRefinement"):
Expand Down Expand Up @@ -302,6 +304,34 @@ def initProperties(self, obj):
QT_TRANSLATE_NOOP("App::Property", "Axis of rotation (MMR)"),
)

if addObjectProperty(
obj,
"SpeedType",
SPEED_TYPES,
"App::PropertyEnumeration",
"Moving mesh Region",
QT_TRANSLATE_NOOP("App::Property", "set the type of speed"),
):
SPEED_TYPES[0]

addObjectProperty(
obj,
"SpeedList",
[0.0],
"App::PropertyFloatList",
"Moving mesh Region",
QT_TRANSLATE_NOOP("App::Property", "speed point for defining variable speed"),
)

addObjectProperty(
obj,
"TimeList",
[0.0],
"App::PropertyFloatList",
"Moving mesh Region",
QT_TRANSLATE_NOOP("App::Property", "time point for defining variable speed"),
)

def onDocumentRestored(self, obj):
self.initProperties(obj)

Expand Down
87 changes: 87 additions & 0 deletions CfdOF/Mesh/TaskPanelCfdMeshRefinement.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,24 @@
from CfdOF import CfdFaceSelectWidget
from CfdOF.Mesh import CfdMeshRefinement
from FreeCAD import Units
from PySide6.QtWidgets import QTableWidgetItem

translate = FreeCAD.Qt.translate

def getCellValue(row, colum, table):
cell = table.item(row, colum)
return(float(cell.text()))

class floatDelegate(QtGui.QItemDelegate):

def createEditor(self, parent, option, index):
editor = super().createEditor(parent, option, index)
if isinstance(editor, QtGui.QLineEdit):
# Allow only floats
editor.setValidator(QtGui.QDoubleValidator(editor))
return editor


class TaskPanelCfdMeshRefinement:
""" The TaskPanel for editing References property of MeshRefinement objects """

Expand Down Expand Up @@ -76,6 +91,7 @@ def __init__(self, obj):
self.form.extrusionTypeCombo.addItems(CfdMeshRefinement.EXTRUSION_NAMES)
self.form.extrusionTypeCombo.currentIndexChanged.connect(self.updateUI)
self.form.pickAxisButton.clicked.connect(self.pickFromSelection)
self.form.comboBoxSpeedType.addItems(CfdMeshRefinement.SPEED_NAMES)

self.form.if_rellen.setToolTip("Cell size relative to base cell size")
self.form.label_rellen.setToolTip("Cell size relative to base cell size")
Expand All @@ -85,6 +101,12 @@ def __init__(self, obj):
self.form.surfaceRefinementToggle.toggled.connect(self.changeInternal)
self.form.volumeRefinementToggle.toggled.connect(self.changeInternal)
self.form.movingMeshRegionToggle.toggled.connect(self.changeInternal)
self.form.comboBoxSpeedType.currentIndexChanged.connect(self.comboBoxSpeedTypeChanged)
delegate = floatDelegate()
self.form.tableTimeVsSpeed.setItemDelegate(delegate)

self.form.pushButtonAddRow.clicked.connect(self.add)
self.form.pushButtonDeleteRow.clicked.connect(self.remove)

self.form.if_refinethick.setToolTip("Distance the refinement region extends from the reference "
"surface")
Expand Down Expand Up @@ -147,6 +169,22 @@ def load(self):
setQuantity(self.form.inputMMRAxisz, self.obj.MMRModelAxis.z)

setQuantity(self.form.inputMMRRPM, self.obj.MMRModelRPM)
self.form.comboBoxSpeedType.setCurrentIndex(
indexOrDefault(CfdMeshRefinement.SPEED_TYPES, self.obj.SpeedType, 0))
self.comboBoxSpeedTypeChanged()

# load the table with values from SpeedList and TimeList arrays
# set nrows to be the larger length between the 2 arrays
nrows = max(len(self.obj.TimeList), len(self.obj.SpeedList))
self.form.tableTimeVsSpeed.setRowCount(nrows)
for i in range(2):
for j in range(nrows):
try:
entery = [self.obj.TimeList, self.obj.SpeedList][i][j]
except:
entery = 0
cell = QTableWidgetItem(str(entery))
self.form.tableTimeVsSpeed.setItem(j, i, cell)

def updateUI(self):
self.form.surfaceOrInernalVolume.setVisible(True)
Expand Down Expand Up @@ -215,6 +253,43 @@ def updateUI(self):
self.form.extrusionFrame.setVisible(False)
self.updateSelectionButtonUI()

def comboBoxSpeedTypeChanged(self):
if self.form.comboBoxSpeedType.currentIndex() == 1:
self.form.frameVariableSpeed.setVisible(True)
self.form.labelRPM.setVisible(False)
self.form.inputMMRRPM.setVisible(False)
else:
self.form.frameVariableSpeed.setVisible(False)
self.form.labelRPM.setVisible(True)
self.form.inputMMRRPM.setVisible(True)

def add(self):
"""Adds a new row below the last one"""
cur_row = self.form.tableTimeVsSpeed.currentRow()
self.form.tableTimeVsSpeed.insertRow(cur_row + 1)
time_cell = QTableWidgetItem("0")
speed_cell = QTableWidgetItem("0")

if cur_row == 0: # the 2nd row give the data of the first
time_cell.setText(str(getCellValue(cur_row, 0, self.form.tableTimeVsSpeed)))
speed_cell.setText(str(getCellValue(cur_row, 1, self.form.tableTimeVsSpeed)))
elif cur_row > 0: # else 3rd = 2nd + (2nd-1st)
prev_time_cell = getCellValue(cur_row, 0, self.form.tableTimeVsSpeed)
prev_time_cell2 = getCellValue(cur_row-1, 0, self.form.tableTimeVsSpeed)
time_cell.setText(str(round(prev_time_cell + (prev_time_cell- prev_time_cell2), 7)))
prev_speed_cell = getCellValue(cur_row, 1, self.form.tableTimeVsSpeed)
prev_speed_cell2 = getCellValue(cur_row-1, 1, self.form.tableTimeVsSpeed)
speed_cell.setText(str(round(prev_speed_cell + (prev_speed_cell- prev_speed_cell2), 7)))

self.form.tableTimeVsSpeed.setItem(cur_row+1, 0, time_cell)
self.form.tableTimeVsSpeed.setItem(cur_row+1, 1, speed_cell)

def remove(self):
"""Removes the current row"""
indices = self.form.tableTimeVsSpeed.selectionModel().selectedRows()
for index in sorted(indices, reverse=True):
self.form.tableTimeVsSpeed.removeRow(index.row())

def getMeshObject(self):
analysis_obj = CfdTools.getActiveAnalysis()
mesh_obj = CfdTools.getMeshObject(analysis_obj)
Expand Down Expand Up @@ -331,6 +406,18 @@ def accept(self):
self.form.inputMMRAxisy.property("quantity").Value,
self.form.inputMMRAxisz.property("quantity").Value)
storeIfChanged(self.obj, 'MMRModelAxis', model_axis)
storeIfChanged(self.obj, 'SpeedType',
CfdMeshRefinement.SPEED_TYPES[self.form.comboBoxSpeedType.currentIndex()])

# convert the table data to 2 arrays (time and speed)
temp_speed_list = []
temp_time_list = []
for i in range(self.form.tableTimeVsSpeed.rowCount()):
temp_time_list.append(getCellValue(i, 0, self.form.tableTimeVsSpeed))
temp_speed_list.append(getCellValue(i, 1, self.form.tableTimeVsSpeed))

storeIfChanged(self.obj, 'TimeList', temp_time_list)
storeIfChanged(self.obj, 'SpeedList', temp_speed_list)

FreeCADGui.doCommand("FreeCAD.ActiveDocument.recompute()")
return True
Expand Down
33 changes: 32 additions & 1 deletion CfdOF/Solve/CfdCaseWriterFoam.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,40 @@ def writeCase(self):
't_MMRModelCoR': tuple(Units.Quantity(p, Units.Length).getValueAs('m') for p in mr_obj.MMRModelCoR),
't_MMRModelAxis': tuple(d for d in mr_obj.MMRModelAxis),
'MMRModelRPM': mr_obj.MMRModelRPM,# revolution per minute
'MMRModelRPS': (mr_obj.MMRModelRPM/9.5) # rad/s #for the openCFD version
'MMRModelRPS': (mr_obj.MMRModelRPM/9.5), # rad/s #for the openCFD version
'SpeedType': mr_obj.SpeedType,
'VariableSpeedRPM': "",
'VariableSpeedRPS': ""
}

longer = max(len(mr_obj.TimeList), len(mr_obj.SpeedList))
for i in range(longer):
self.settings['MovingMeshRegions'][mr_obj.Label]['VariableSpeedRPM'] += "\t\t\t\t\t("
self.settings['MovingMeshRegions'][mr_obj.Label]['VariableSpeedRPS'] += "\t\t\t\t\t\t("
for j in range(2): # iterate over the 2 lists to copy the values to the buff
try:
entery = [mr_obj.TimeList, mr_obj.SpeedList][j][i]
except:
entery = 0 # make the value 0 when the lists are not the same length
self.settings['MovingMeshRegions'][mr_obj.Label]['VariableSpeedRPM'] += str(entery)
if j == 0:
self.settings['MovingMeshRegions'][mr_obj.Label]['VariableSpeedRPS'] += str(entery) + " "
self.settings['MovingMeshRegions'][mr_obj.Label]['VariableSpeedRPM'] += " "
else:
self.settings['MovingMeshRegions'][mr_obj.Label]['VariableSpeedRPS'] += str(entery/9.5)
self.settings['MovingMeshRegions'][mr_obj.Label]['VariableSpeedRPM'] += ")\n"
self.settings['MovingMeshRegions'][mr_obj.Label]['VariableSpeedRPS'] += ")\n"
# if the first time in the list is not 0 then add a 0 with a speed eqaul the first speed
# to avoid getting an error in the OpenCFD version
if mr_obj.TimeList[0] > 0:
self.settings['MovingMeshRegions'][mr_obj.Label]['VariableSpeedRPS'] = "\t\t\t\t\t\t(0 "+str(mr_obj.SpeedList[0]/9.5)+")\n" + self.settings['MovingMeshRegions'][mr_obj.Label]['VariableSpeedRPS']
# if the last time in the list is less than the EndTime then add a new pair with time = EndTime and with a speed eqaul the last speed
# to avoid getting an error in the OpenCFD version
if mr_obj.TimeList[len(mr_obj.TimeList)-1] < self.settings['solver']['EndTime']:
self.settings['MovingMeshRegions'][mr_obj.Label]['VariableSpeedRPS'] += "\t\t\t\t\t\t("+str(self.settings['solver']['EndTime'])+" "+str(mr_obj.SpeedList[len(mr_obj.SpeedList)-1]/9.5)+")\n"



if len(self.settings["MovingMeshRegions"]) > 0:
self.settings['MovingMeshRegionsPresent'] = True
else:
Expand Down
25 changes: 25 additions & 0 deletions Data/Templates/case/constant/dynamicMeshDict
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,19 @@ dynamicMultiMotionSolverFvMeshCoeffs
{
origin (%(MovingMeshRegions/%(0%)/t_MMRModelCoR%));
axis (%(MovingMeshRegions/%(0%)/t_MMRModelAxis%));
%{%(MovingMeshRegions/%(0%)/SpeedType%)
%:ConstantSpeed
omega %(MovingMeshRegions/%(0%)/MMRModelRPS%);
%:VariableSpeed
omega
{
type table;
values
(
%(MovingMeshRegions/%(0%)/VariableSpeedRPS%)
);
}
%}
}
}
}
Expand All @@ -192,7 +204,20 @@ mover
solidBodyMotionFunction rotatingMotion;
origin (%(MovingMeshRegions/%(0%)/t_MMRModelCoR%));
axis (%(MovingMeshRegions/%(0%)/t_MMRModelAxis%));
%{%(MovingMeshRegions/%(0%)/SpeedType%)
%:ConstantSpeed
omega %(MovingMeshRegions/%(0%)/MMRModelRPM%) [rpm];
%:VariableSpeed
omega
{
type table;
units ([s] [rpm]);
values
(
%(MovingMeshRegions/%(0%)/VariableSpeedRPM%)
);
}
%}
}
%}
}
Expand Down
91 changes: 91 additions & 0 deletions Data/TestFiles/cases/WaterPouring/case/0/U
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*--------------------------------*- C++ -*----------------------------------*\
| |
| Generated by the CfdOF workbench for FreeCAD |
| https://github.com/jaheyns/CfdOF |
| |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volVectorField;
object U;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

dimensions [0 1 -1 0 0 0 0];

internalField uniform (0.0 0.0 0.0);

boundaryField
{
// Foundation:

nonConformalCyclic_on_MeshRefinement_M
{
type nonConformalCyclic;
value $internalField;
}

nonConformalError_on_MeshRefinement_M
{
type nonConformalError;
}

nonConformalCyclic_on_MeshRefinement_S
{
type nonConformalCyclic;
value $internalField;
}

nonConformalError_on_MeshRefinement_S
{
type nonConformalError;
}


MeshRefinement_M
{
#include "MMR/vector";
}
MeshRefinement_S
{
#include "MMR/vector";
}


open
{
type pressureInletOutletVelocity;
value $internalField;
}

bottle_wall
{
// movingWallVelocity reduces to fixedValue if the mesh is not moving
type movingWallVelocity;
value uniform (0 0 0);
}

cup_wall
{
// movingWallVelocity reduces to fixedValue if the mesh is not moving
type movingWallVelocity;
value uniform (0 0 0);
}

side_wall
{
type slip;
value $internalField;
}

defaultFaces
{
type slip;
value $internalField;
}

}

// ************************************************************************* //
Loading