Skip to content

Commit 7d9f26d

Browse files
author
Rusty Holleman
committed
python cell centers, global wse without holes
1 parent b27647c commit 7d9f26d

File tree

3 files changed

+375
-24
lines changed

3 files changed

+375
-24
lines changed

examples/dev_openfoam.py

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
from stompy.model.openfoam import depth_average
2+
import numpy as np
3+
from stompy import utils
4+
5+
import six
6+
7+
sim_dir="y:/DWR/fishpassage-DWR-7/fishpassage-DWR-7-7cms-local"
8+
##
9+
six.moves.reload_module(depth_average)
10+
pf = depth_average.PostFoam(sim_dir=sim_dir)
11+
12+
# OF generated:
13+
#centers0=pf.cell_centers(proc)
14+
import time
15+
16+
center_fn="test-centers.dat"
17+
t=time.time()
18+
pf.compute_cell_centers_py(proc,center_fn)
19+
print("Elapsed: ",time.time()-t)
20+
21+
22+
23+
import pandas as pd
24+
df = pd.read_csv(center_fn,sep=r'\s+',names=['type','x','y','z'])
25+
centers_py = df[ ['x','y','z'] ].values
26+
err = centers0 - centers_py
27+
print("RMSE: " , np.sqrt(np.mean(err**2)))
28+
29+
##
30+
31+
# about 25s for a processor with 35k faces, almost all the time
32+
# in calc_face_center
33+
34+
def calc_face_center(face):
35+
VSMALL=1e-14
36+
if len(face)==3:
37+
return face.mean(axis=0),0.5*np.cross(face[1]-face[0],face[2]-face[0])
38+
else:
39+
sumN=np.zeros(3,np.float64)
40+
sumA=0.0
41+
sumAc=np.zeros(3,np.float64)
42+
43+
fCentre = face.mean(axis=0)
44+
45+
nPoints=face.shape[0]
46+
for pi in range(nPoints):
47+
p1=face[pi]
48+
p2=face[(pi+1)%nPoints]
49+
50+
centroid3 = p1 + p2 + fCentre
51+
area_norm = np.cross( p2 - p1, fCentre - p1)
52+
area = utils.mag(area_norm)
53+
54+
sumN += area_norm;
55+
sumA += area;
56+
sumAc += area*centroid3;
57+
58+
return (1.0/3.0)*sumAc/(sumA + VSMALL), 0.5*sumN
59+
60+
def cell_center_py(facefile, xyz, owner, neigh):
61+
"""
62+
facefile:
63+
xyz: pointfile.values.reshape([-1,3])
64+
owner: [Nfaces] index of face's owner cell
65+
neigh: [NInternalFaces] index of faces's neighbor cell
66+
"""
67+
# replicate cell center calculation from openfoam-master/src/meshTools/primitiveMeshGeometry.C
68+
faces=[] # [N,{xyz}] array per face
69+
70+
VSMALL=1e-14
71+
nfaces = facefile.nfaces
72+
# WRONG ncells = owner.shape[0]
73+
ncells = 1+max(owner.max(),neigh.max()) # or get it from owner file
74+
n_internal = neigh.shape[0]
75+
76+
face_ctr=np.zeros((nfaces,3),np.float64)
77+
face_area=np.zeros((nfaces,3),np.float64)
78+
79+
if 1: # get face centers
80+
# 20 s for one domain
81+
for fIdx in utils.progress(range(nfaces)):
82+
face_nodes = facefile.faces[fIdx]["id_pts"][:]
83+
face = xyz[list(face_nodes)]
84+
face_ctr[fIdx],face_area[fIdx] = calc_face_center(face)
85+
86+
if 1: # estimated cell centers
87+
cell_est_centers = np.zeros( (ncells,3), np.float64)
88+
cell_n_faces = np.zeros( ncells, np.int32)
89+
90+
for j,ctr in enumerate(face_ctr):
91+
c_own = owner[j]
92+
cell_est_centers[c_own] += ctr
93+
cell_n_faces[c_own] += 1
94+
95+
for j,ctr in enumerate(face_ctr[:n_internal]):
96+
c_nbr = neigh[j]
97+
cell_est_centers[c_nbr] += ctr
98+
cell_n_faces[c_nbr] += 1
99+
100+
cell_est_centers[:] /= cell_n_faces[:,None]
101+
102+
if 1: # refined cell centers
103+
cell_centers=np.zeros_like(cell_est_centers)
104+
cell_volumes=np.zeros(ncells,np.float64)
105+
106+
def mydot(a,b): # fighting with numpy to get vectorized dot product
107+
return (a*b).sum(axis=-1)
108+
109+
pyr3Vol_own = mydot(face_area, face_ctr - cell_est_centers[owner]).clip(VSMALL)
110+
pyrCtr_own = (3.0/4.0)*face_ctr + (1.0/4.0)*cell_est_centers[owner]
111+
for j in range(nfaces):
112+
cell_centers[owner[j]] += pyr3Vol_own[j,None] * pyrCtr_own[j]
113+
cell_volumes[owner[j]] += pyr3Vol_own[j]
114+
115+
# note sign flip to account for nbr normal
116+
pyr3Vol_nbr = mydot(face_area[:n_internal], cell_est_centers[neigh] - face_ctr[:n_internal]).clip(VSMALL)
117+
pyrCtr_nbr = (3.0/4.0)*face_ctr[:n_internal] + (1.0/4.0)*cell_est_centers[neigh]
118+
119+
for j in range(n_internal):
120+
cell_centers[neigh[j]] += pyr3Vol_nbr[j,None] * pyrCtr_nbr[j]
121+
cell_volumes[neigh[j]] += pyr3Vol_nbr[j]
122+
123+
cell_centers /= cell_volumes[:,None]
124+
cell_volumes *= 1.0/3.0
125+
126+
return cell_centers, cell_volumes
127+
128+
proc=0
129+
centers0=pf.cell_centers(proc)
130+
131+
faces0 = pf.face_centers(proc)
132+
133+
facefile = pf.read_facefile(proc)
134+
pointfile = pf.read_pointfile(proc)
135+
owner = pf.read_owner(proc)
136+
neigh = pf.read_neighbor(proc)
137+
138+
ctrs,vols = cell_center_py(facefile, pointfile.values.reshape([-1,3]), owner.values, neigh.values)

0 commit comments

Comments
 (0)