Skip to content

Commit d8b5fe8

Browse files
committed
update
1 parent f7bcc2b commit d8b5fe8

9 files changed

Lines changed: 122 additions & 45 deletions

File tree

CfdOF/Mesh/CfdMeshTools.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,32 @@
3636

3737

3838

39+
def _get_interior_point(solid):
40+
"""Return a point guaranteed to be inside the solid material.
41+
42+
CenterOfMass can lie outside the material for non-convex solids (e.g. an air
43+
shell surrounding an object). When that happens, fall back to sampling a 3-D
44+
grid of points within the bounding box and return the first one that passes
45+
the isInside test.
46+
"""
47+
tol = 1e-3
48+
centroid = solid.CenterOfMass
49+
if solid.isInside(centroid, tol, True):
50+
return centroid
51+
bb = solid.BoundBox
52+
for xi in (0.1, 0.3, 0.5, 0.7, 0.9):
53+
for yi in (0.1, 0.3, 0.5, 0.7, 0.9):
54+
for zi in (0.1, 0.3, 0.5, 0.7, 0.9):
55+
pt = FreeCAD.Vector(
56+
bb.XMin + xi * bb.XLength,
57+
bb.YMin + yi * bb.YLength,
58+
bb.ZMin + zi * bb.ZLength,
59+
)
60+
if solid.isInside(pt, tol, True):
61+
return pt
62+
return centroid
63+
64+
3965
def _getCompoundLinks(part_obj):
4066
"""Return the list of child body objects from a compound or BooleanFragments shape object."""
4167
if hasattr(part_obj, 'Links'): # Part::Compound
@@ -724,7 +750,7 @@ def writeMeshCase(self):
724750
body_shapes[lnk.Name] = lnk.Shape
725751
shapes = list(body_shapes.values())
726752
vol_indices = [i for i, s in enumerate(result_solids, start=1)
727-
if any(sh.isInside(s.CenterOfMass, 1e-3, True) for sh in shapes)]
753+
if any(sh.isInside(_get_interior_point(s), 1e-3, True) for sh in shapes)]
728754
solid_vol_indices_all.update(vol_indices)
729755
if vol_indices:
730756
region_volume_map[rname] = ', '.join(str(v) for v in vol_indices)

CfdOF/Solve/CfdCaseWriterFoam.py

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -254,32 +254,26 @@ def writeCase(self):
254254
return True
255255

256256
def _renameChtRegionDirs(self):
257-
"""Rename constant/fluid, 0/fluid, system/fluid (and solid) to actual CHT region names."""
257+
"""Rename constant/fluid, 0/fluid, system/fluid template subdirs to actual fluid region name.
258+
259+
Solid region files are written directly to per-region paths by the template's
260+
filename-loop mechanism, so no renaming is needed for solids.
261+
"""
258262
import shutil
259-
settings = self.settings
260-
fluid_names = settings.get('multiRegionFluidNames', [])
261-
solid_names = settings.get('multiRegionSolidNames', [])
262-
if not fluid_names and not solid_names:
263+
fluid_names = self.settings.get('multiRegionFluidNames', [])
264+
if not fluid_names:
263265
return
264-
renames = []
265-
if fluid_names:
266-
renames.append(('fluid', fluid_names[0]))
267-
if solid_names:
268-
renames.append(('solid', solid_names[0]))
269266
for top in ('constant', '0', 'system'):
270-
for template_name, region_name in renames:
271-
if template_name == region_name:
272-
continue
273-
src = os.path.join(self.case_folder, top, template_name)
274-
dst = os.path.join(self.case_folder, top, region_name)
275-
if os.path.isdir(src):
276-
if os.path.isdir(dst):
277-
# Merge: copy files from src into existing dst, then remove src
278-
for fname in os.listdir(src):
279-
shutil.copy2(os.path.join(src, fname), os.path.join(dst, fname))
280-
shutil.rmtree(src)
281-
else:
282-
os.rename(src, dst)
267+
src = os.path.join(self.case_folder, top, 'fluid')
268+
dst = os.path.join(self.case_folder, top, fluid_names[0])
269+
if src == dst or not os.path.isdir(src):
270+
continue
271+
if os.path.isdir(dst):
272+
for fname in os.listdir(src):
273+
shutil.copy2(os.path.join(src, fname), os.path.join(dst, fname))
274+
shutil.rmtree(src)
275+
else:
276+
os.rename(src, dst)
283277

284278
def getSolverName(self):
285279
"""

Data/Templates/case/0/solid/T

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
%{%(solver/SolverName%)
22
%:chtMultiRegionSimpleFoam chtMultiRegionFoam
3+
%{%(multiRegionSolidNames%)
34
%[_header%]
45
FoamFile
56
{
67
version 2.0;
78
format ascii;
89
class volScalarField;
9-
location "0/%(multiRegionSolidNames/0%)";
10+
location "0/%(multiRegionSolidNames/%(0%)%)";
1011
object T;
1112
}
1213
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -77,4 +78,5 @@ boundaryField
7778
}
7879

7980
// ************************************************************************* //
81+
%} 0/%(multiRegionSolidNames/%(0%)%)/T
8082
%}

Data/Templates/case/0/solid/p

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
%{%(solver/SolverName%)
22
%:chtMultiRegionSimpleFoam chtMultiRegionFoam
3+
%{%(multiRegionSolidNames%)
34
%[_header%]
45
FoamFile
56
{
67
version 2.0;
78
format ascii;
89
class volScalarField;
9-
location "0/%(multiRegionSolidNames/0%)";
10+
location "0/%(multiRegionSolidNames/%(0%)%)";
1011
object p;
1112
}
1213
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -40,4 +41,5 @@ boundaryField
4041
}
4142

4243
// ************************************************************************* //
44+
%} 0/%(multiRegionSolidNames/%(0%)%)/p
4345
%}

Data/Templates/case/Allrun

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,19 @@ runCommand splitMeshRegions -cellZones -overwrite
133133
env -u PYTHONPATH -u PYTHONHOME python3 << 'PYEOF'
134134
import re, os, glob
135135
136-
FLUID_REGION = '%(multiRegionFluidNames/0%)'
137-
SOLID_REGION = '%(multiRegionSolidNames/0%)'
136+
FLUID_REGIONS = []
137+
SOLID_REGIONS = []
138+
try:
139+
with open('constant/regionProperties') as f:
140+
txt = f.read()
141+
fm = re.search(r'fluid\s*\(\s*([^)]*?)\s*\)', txt)
142+
sm = re.search(r'solid\s*\(\s*([^)]*?)\s*\)', txt)
143+
if fm:
144+
FLUID_REGIONS = fm.group(1).split()
145+
if sm:
146+
SOLID_REGIONS = sm.group(1).split()
147+
except FileNotFoundError:
148+
pass
138149
139150
def fix_samplemode_to_ami(bfile):
140151
"""Upgrade sampleMode nearestPatchFace → nearestPatchFaceAMI for parallel CHT."""
@@ -151,6 +162,14 @@ def get_mapped_patches(bfile):
151162
txt = f.read()
152163
return re.findall(r'\n\s+(\w+)\s*\n\s*\{[^}]*type\s+mappedWall', txt)
153164
165+
def get_nonmapped_patches(bfile):
166+
"""Return names of all non-mappedWall patches in boundary file."""
167+
with open(bfile) as f:
168+
txt = f.read()
169+
all_patches = re.findall(r'\n (\w+)\n \{', txt)
170+
mapped = set(re.findall(r'\n\s+(\w+)\s*\n\s*\{[^}]*type\s+mappedWall', txt))
171+
return [p for p in all_patches if p not in mapped]
172+
154173
def patch_present(field_txt, patch_name):
155174
return bool(re.search(r'\n\s+' + re.escape(patch_name) + r'\s*\n\s*\{', field_txt))
156175
@@ -206,16 +225,36 @@ def add_missing_patches_to_fields(region, patches, is_fluid):
206225
elif fname in ('k', 'epsilon', 'omega', 'nuTilda', 'alphat') and is_fluid:
207226
add_patch_entry(field_file, patch, ['type zeroGradient;'])
208227
209-
fix_samplemode_to_ami('constant/' + FLUID_REGION + '/polyMesh/boundary')
210-
fix_samplemode_to_ami('constant/' + SOLID_REGION + '/polyMesh/boundary')
228+
for r in FLUID_REGIONS:
229+
fix_samplemode_to_ami('constant/' + r + '/polyMesh/boundary')
230+
for r in SOLID_REGIONS:
231+
fix_samplemode_to_ami('constant/' + r + '/polyMesh/boundary')
211232
212233
# Add 0/ field entries for all mappedWall interface patches splitMeshRegions created
213-
fluid_mapped = [p for p in get_mapped_patches('constant/' + FLUID_REGION + '/polyMesh/boundary')
214-
if p != 'defaultFaces']
215-
solid_mapped = [p for p in get_mapped_patches('constant/' + SOLID_REGION + '/polyMesh/boundary')
216-
if p != 'defaultFaces']
217-
add_missing_patches_to_fields(FLUID_REGION, fluid_mapped, is_fluid=True)
218-
add_missing_patches_to_fields(SOLID_REGION, solid_mapped, is_fluid=False)
234+
for r in FLUID_REGIONS:
235+
mapped = [p for p in get_mapped_patches('constant/' + r + '/polyMesh/boundary')
236+
if p != 'defaultFaces']
237+
add_missing_patches_to_fields(r, mapped, is_fluid=True)
238+
for r in SOLID_REGIONS:
239+
mapped = [p for p in get_mapped_patches('constant/' + r + '/polyMesh/boundary')
240+
if p != 'defaultFaces']
241+
add_missing_patches_to_fields(r, mapped, is_fluid=False)
242+
243+
# Add default BC entries for non-mapped patches in solid regions that aren't yet in
244+
# the field files (e.g. inlet/outlet/wall faces that fall inside a solid volume after
245+
# splitMeshRegions). OpenFOAM requires an explicit entry for every patch in boundaryField.
246+
for r in SOLID_REGIONS:
247+
nonmapped = get_nonmapped_patches('constant/' + r + '/polyMesh/boundary')
248+
for patch in nonmapped:
249+
for field_file in glob.glob(os.path.join('0', r, '*')):
250+
fname = os.path.basename(field_file)
251+
if fname == 'T':
252+
add_patch_entry(field_file, patch, ['type zeroGradient;'])
253+
elif fname == 'p':
254+
add_patch_entry(field_file, patch, [
255+
'type calculated;',
256+
'value $internalField;',
257+
])
219258
PYEOF
220259

221260
%}
@@ -261,7 +300,7 @@ then
261300
%{%(solver/SolverName%)
262301
%:chtMultiRegionSimpleFoam chtMultiRegionFoam
263302
# Copy decomposeParDict to each region's system directory
264-
for region in %(multiRegionFluidNames/0%) %(multiRegionSolidNames/0%); do
303+
for region in $(ls -d constant/*/polyMesh 2>/dev/null | cut -d/ -f2); do
265304
mkdir -p system/$region
266305
cp system/decomposeParDict system/$region/decomposeParDict
267306
done

Data/Templates/case/constant/regionProperties

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,16 @@ FoamFile
1212

1313
regions
1414
(
15-
fluid ( %(multiRegionFluidNames/0%) )
16-
solid ( %(multiRegionSolidNames/0%) )
15+
fluid (
16+
%{%(multiRegionFluidNames%)
17+
%(multiRegionFluidNames/%(0%)%)
18+
%}
19+
)
20+
solid (
21+
%{%(multiRegionSolidNames%)
22+
%(multiRegionSolidNames/%(0%)%)
23+
%}
24+
)
1725
);
1826

1927
// ************************************************************************* //

Data/Templates/case/constant/solid/thermophysicalProperties

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
%{%(solver/SolverName%)
22
%:chtMultiRegionSimpleFoam chtMultiRegionFoam
3+
%{%(multiRegionSolidNames%)
34
%[_header%]
45
FoamFile
56
{
67
version 2.0;
78
format ascii;
89
class dictionary;
9-
location "constant/%(multiRegionSolidNames/0%)";
10+
location "constant/%(multiRegionSolidNames/%(0%)%)";
1011
object thermophysicalProperties;
1112
}
1213
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -31,18 +32,19 @@ mixture
3132
}
3233
transport
3334
{
34-
kappa %(solidProperties/0/ThermalConductivity%);
35+
kappa %(solidProperties/%(0%)/ThermalConductivity%);
3536
}
3637
thermodynamics
3738
{
38-
Cp %(solidProperties/0/Cp%);
39+
Cp %(solidProperties/%(0%)/Cp%);
3940
Hf 0;
4041
}
4142
equationOfState
4243
{
43-
rho %(solidProperties/0/Density%);
44+
rho %(solidProperties/%(0%)/Density%);
4445
}
4546
}
4647

4748
// ************************************************************************* //
49+
%} constant/%(multiRegionSolidNames/%(0%)%)/thermophysicalProperties
4850
%}

Data/Templates/case/system/solid/fvSchemes

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
%{%(solver/SolverName%)
22
%:chtMultiRegionSimpleFoam chtMultiRegionFoam
3+
%{%(multiRegionSolidNames%)
34
%[_header%]
45
FoamFile
56
{
67
version 2.0;
78
format ascii;
89
class dictionary;
9-
location "system/%(multiRegionSolidNames/0%)";
10+
location "system/%(multiRegionSolidNames/%(0%)%)";
1011
object fvSchemes;
1112
}
1213
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -42,4 +43,5 @@ snGradSchemes
4243
}
4344

4445
// ************************************************************************* //
46+
%} system/%(multiRegionSolidNames/%(0%)%)/fvSchemes
4547
%}

Data/Templates/case/system/solid/fvSolution

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
%{%(solver/SolverName%)
22
%:chtMultiRegionSimpleFoam chtMultiRegionFoam
3+
%{%(multiRegionSolidNames%)
34
%[_header%]
45
FoamFile
56
{
67
version 2.0;
78
format ascii;
89
class dictionary;
9-
location "system/%(multiRegionSolidNames/0%)";
10+
location "system/%(multiRegionSolidNames/%(0%)%)";
1011
object fvSolution;
1112
}
1213
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -53,4 +54,5 @@ relaxationFactors
5354
}
5455

5556
// ************************************************************************* //
57+
%} system/%(multiRegionSolidNames/%(0%)%)/fvSolution
5658
%}

0 commit comments

Comments
 (0)