From d19cc0cdc5babb1e1b1e4b0ba854505c3a7901b3 Mon Sep 17 00:00:00 2001 From: Chloe Mimeau <Chloe.Mimeau@imag.fr> Date: Thu, 31 Jan 2013 15:08:37 +0000 Subject: [PATCH] about forces --- HySoP/hysop/physics/compute_forces.py | 137 ++++++++---------- HySoP/hysop/test/test_operator/test_Forces.py | 14 +- 2 files changed, 68 insertions(+), 83 deletions(-) diff --git a/HySoP/hysop/physics/compute_forces.py b/HySoP/hysop/physics/compute_forces.py index ec9ebfa39..d49d92e2d 100644 --- a/HySoP/hysop/physics/compute_forces.py +++ b/HySoP/hysop/physics/compute_forces.py @@ -33,14 +33,12 @@ class Compute_forces(object): self.res = topology.mesh.resolution self.step = topology.mesh.size self.coordMin = topology.mesh.origin + (topology.ghosts* self.step) - self.coordMax = (topology.mesh.end + 1) * self.step + topology.domain.origin - 2.* (topology.ghosts* self.step) + self.coordMax = topology.mesh.end * self.step + topology.domain.origin - 2.* (topology.ghosts* self.step) self.ghosts = topology.ghosts self.periods = topology.periods - print 'periods, ', self.periods +# print 'res, dx, cMin, cMax, bmin, bMax', self.res, self.step, self.coordMin, self.coordMax, self.boxMin, self.boxMax self.compute_control_box() - print 'res, dx, cMin, cMax, bmin, bMax', self.res, self.step, self.coordMin, self.coordMax, self.boxMin, self.boxMax - def compute_control_box(self) : """ Compute indicator functions for the control box (including the obstacle) @@ -65,20 +63,18 @@ class Compute_forces(object): distMin = self.boxMin - self.coordMin distMax = self.boxMax - self.coordMax - print 'distMin, distMax', distMin, distMax for i in xrange(self.dim): if (distMin[i]>=0. and distMax[i]<=0.): # the control volume is included inside the local domain tmp_ind[i][0] = distMin[i] // self.step[i] # Down, West, South - tmp_ind[i][1] = self.res[i] -2. * self.ghosts[i] + distMax[i] // self.step[i] -1 * np.invert(self.periods[i])# Up, East, North - print 'tmp_ind', tmp_ind[i][0], tmp_ind[i][1] + tmp_ind[i][1] = self.res[i] -2. * self.ghosts[i] + distMax[i] // self.step[i] -1# Up, East, North if (distMin[i]>=0. and self.boxMin[i]<= self.coordMax[i] and distMax[i]>=0.): # only min corner of control volume is included inside the local domain tmp_ind[i][0] = distMin[i] // self.step[i] tmp_ind[i][1] = self.res[i] -2. * self.ghosts[i] - 1 if (distMin[i]<=0. and self.boxMax[i]>= self.coordMin[i] and distMax[i]<=0.) : # only max corner of control volume is included inside the local domain - tmp_ind[i][1] = self.res[i] -2.*self.ghosts[i] + distMax[i] // self.step[i] -1 * np.invert(self.periods[i]) + tmp_ind[i][1] = self.res[i] -2.*self.ghosts[i] + distMax[i] // self.step[i] -1 if (distMin[i]<=0. and distMax[i]>=0.): # the local domain is included inside the control volume tmp_ind[i][1] = self.res[i] - 2. * self.ghosts[i] - 1 @@ -92,7 +88,7 @@ class Compute_forces(object): ind[self.East] = tmp_ind[1][1] ind[self.South] = tmp_ind[2][0] ind[self.North] = tmp_ind[2][1] - print 'ind_Down, ind_South', ind[self.Down], ind[self.Up] +# print 'ind_Down, ind_South', ind[self.Down], ind[self.Up] # Remove last point to integrate properly ... ????????? # ind[self.Up] = ind[self.Up] - 1 @@ -108,6 +104,8 @@ class Compute_forces(object): nbPoints[self.South] = (ind[self.East] - ind[self.West] + 1) * (ind[self.Up] - ind[self.Down] + 1) nbPoints[self.North] = (ind[self.East] - ind[self.West] + 1) * (ind[self.Up] - ind[self.Down] + 1) +# print 'nb points plan Down', nbPoints[self.Down] + # if there is no volume control inside the local domain => nbPoints=0 => forces are not computed if (distMin[0]<0. and distMax[0]<0. and self.boxMax[0]< self.coordMin[0]): nbPoints[self.Down] = 0 @@ -128,94 +126,84 @@ class Compute_forces(object): boxDim[2] = ind[self.North] - ind[self.South] + 1 nbPointsBox = boxDim[0] * boxDim[1] * boxDim[2] - tmp_box = np.zeros([self.dim,nbPointsBox], dtype=PARMES_INTEGER) - coords = np.zeros(self.dim, dtype=PARMES_INTEGER) +# print 'nb points box', nbPointsBox + + tmp_box = np.zeros([nbPointsBox,self.dim], dtype=PARMES_INTEGER) + coords = np.zeros(self.dim, dtype=PARMES_REAL) count_box = 0 if(boxDim.all() >0): - for k in xrange (ind[self.South],ind[self.North]): ## enlever les boucles !! + for k in xrange (ind[self.South],ind[self.North]+1): ## enlever les boucles !! coords[2] = self.coordMin[2] + k * self.step[2] - for j in xrange (ind[self.West],ind[self.East]): + for j in xrange (ind[self.West],ind[self.East]+1): coords[1] = self.coordMin[1] + j * self.step[1] - for i in xrange (ind[self.Down],ind[self.Up]): + for i in xrange (ind[self.Down],ind[self.Up]+1): coords[0] = self.coordMin[0] + i * self.step[0] dist = np.vdot(coords - self.obstacle.center,coords - self.obstacle.center) - self.obstacle.radius ** 2 if(dist >=0.0): # We are on or outside the sphere ... + tmp_box[count_box] = [i, j, k] count_box = count_box + 1 - tmp_box[0][count_box] = i - tmp_box[1][count_box] = j - tmp_box[2][count_box] = k + +# print 'tmp_box', tmp_box, tmp_box.shape, count_box # local indices of points in the control box which are outside the obstacle - self.chi_box = tmp_box[:][0:count_box] + self.chi_box = np.zeros([count_box,self.dim], dtype=PARMES_INTEGER) + self.chi_box = tmp_box[0:count_box,:] ### PBM !!! - self.chi_up = np.zeros([self.dim,nbPoints[self.Up]], dtype=PARMES_INTEGER) - self.chi_down = np.zeros([self.dim,nbPoints[self.Down]], dtype=PARMES_INTEGER) - self.chi_east = np.zeros([self.dim,nbPoints[self.East]], dtype=PARMES_INTEGER) - self.chi_west = np.zeros([self.dim,nbPoints[self.West]], dtype=PARMES_INTEGER) - self.chi_north = np.zeros([self.dim,nbPoints[self.North]], dtype=PARMES_INTEGER) - self.chi_south = np.zeros([self.dim,nbPoints[self.South]], dtype=PARMES_INTEGER) + self.chi_up = np.zeros([nbPoints[self.Up],self.dim], dtype=PARMES_INTEGER) + self.chi_down = np.zeros([nbPoints[self.Down],self.dim], dtype=PARMES_INTEGER) + self.chi_east = np.zeros([nbPoints[self.East],self.dim], dtype=PARMES_INTEGER) + self.chi_west = np.zeros([nbPoints[self.West],self.dim], dtype=PARMES_INTEGER) + self.chi_north = np.zeros([nbPoints[self.North],self.dim], dtype=PARMES_INTEGER) + self.chi_south = np.zeros([nbPoints[self.South],self.dim], dtype=PARMES_INTEGER) # local indices of points located on the surfaces of the control box if(nbPoints[self.South]!=0.): # South boundary is in the domain count = 0 - self.chi_south[2][:] = ind[self.South] - for j in xrange (ind[self.West],ind[self.East]): - for i in xrange (ind[self.Down],ind[self.Up]): - self.chi_south[0][count] = i - self.chi_south[1][count] = j + for j in xrange (ind[self.West],ind[self.East] + 1): + for i in xrange (ind[self.Down],ind[self.Up] + 1): + self.chi_south[count] = [i, j, ind[self.South]] count = count + 1 if(nbPoints[self.East]!=0.): # East boundary is in the domain count = 0 - self.chi_east[1][:] = ind[self.East] - for k in xrange (ind[self.South],ind[self.North]): - for i in xrange (ind[self.Down],ind[self.Up]): - self.chi_east[0][count] = i - self.chi_east[2][count] = k + for k in xrange (ind[self.South],ind[self.North] + 1): + for i in xrange (ind[self.Down],ind[self.Up] + 1): + self.chi_east[count] = [i, ind[self.East], k] count = count + 1 if(nbPoints[self.Down]!=0.): # Down boundary is in the domain count = 0 - self.chi_down[0][:] = ind[self.Down] - for k in xrange (ind[self.South],ind[self.North]): - for j in xrange (ind[self.West],ind[self.East]): - self.chi_down[1][count] = j - self.chi_down[2][count] = k + for k in xrange (ind[self.South],ind[self.North] + 1): + for j in xrange (ind[self.West],ind[self.East] + 1): + self.chi_down[count] = [ind[self.Down], j, k] count = count + 1 if(nbPoints[self.North]!=0.): # North boundary is in the domain count = 0 - self.chi_north[2][:] = ind[self.North] - for j in xrange (ind[self.West],ind[self.East]): - for i in xrange (ind[self.Down],ind[self.Up]): - self.chi_north[0][count] = i - self.chi_north[1][count] = j + for j in xrange (ind[self.West],ind[self.East] + 1): + for i in xrange (ind[self.Down],ind[self.Up] + 1): + self.chi_north[count] = [i, j, ind[self.North]] count = count + 1 if(nbPoints[self.West]!=0.): # West boundary is in the domain count = 0 - self.chi_west[1][:] = ind[self.West] - for k in xrange (ind[self.South],ind[self.North]): - for i in xrange (ind[self.Down],ind[self.Up]): - self.chi_west[0][count] = i - self.chi_west[2][count] = k + for k in xrange (ind[self.South],ind[self.North] + 1): + for i in xrange (ind[self.Down],ind[self.Up] + 1): + self.chi_west[count] = [i, ind[self.West], k] count = count + 1 if(nbPoints[self.Up]!=0.): # Up boundary is in the domain count = 0 - self.chi_up[0][:] = ind[self.Up] - for k in xrange (ind[self.South],ind[self.North]): - for j in xrange (ind[self.West],ind[self.East]): - self.chi_up[1][count] = j - self.chi_up[2][count] = k + for k in xrange (ind[self.South],ind[self.North] + 1): + for j in xrange (ind[self.West],ind[self.East] + 1): + self.chi_up[count] = [ind[self.Up], j, k] count = count + 1 self.bufferForce = 0. - # Compute coef used to compute the drag coefficient + # Compute coef used to determine drag coefficient : cD = coef.Fx = 2.Fx/rho.uinf**2.D uinf = 1. self.coef = 2. / (uinf ** 2 * PI * self.obstacle.radius ** 2) - def apply(self, t, dt, velo, vort, Re): """ Computation of the drag according to the "impulsion" formula presented by @@ -223,7 +211,7 @@ class Compute_forces(object): """ localForce = np.zeros(self.dim, dtype=PARMES_REAL) force = np.zeros(self.dim, dtype=PARMES_REAL) - # computation of hessian matrices (d2_u1, d2_u2 and d2_u3) and jacobian matrix (d_u) (no ghost points) + # computation of hessian matrices (d2_u1, d2_u2 and d2_u3) and jacobian matrix (d_u) hessian1, hessian2, hessian3 = Fct2Op(vort, velo, choice = 'hessianU', topology=self.topo).apply(None,None) self.jacobian, maxgersh = DifferentialOperator_d(vort, velo, choice='gradV', topology=self.topo).apply() # computation of the components of Div(T) where T = 1/Re * (Nabla(U) + Nabla(U)T) @@ -262,13 +250,13 @@ class Compute_forces(object): # For all points in the box for ind in xrange (chi.shape[1]): # adjust indices for vector fields with ghost points - l = chi[0][ind] + self.ghosts[0] - m = chi[1][ind] + self.ghosts[1] - n = chi[2][ind] + self.ghosts[2] + i = chi[ind][0] + self.ghosts[0] + j = chi[ind][1] + self.ghosts[1] + k = chi[ind][2] + self.ghosts[2] # coordinates of the current point - coords = self.coordMin + chi[:,ind] * self.step + coords = self.coordMin + chi[ind] * self.step # part1 of the force - int1 = int1 + np.vdot(coords,vort[l,m,n]) + int1 = int1 + np.vdot(coords,vort[i,j,k]) force = force + fact * (int1 - self.bufferForce) # 1st order time integration self.bufferForce = int1 # Save for next time step ... @@ -288,28 +276,25 @@ class Compute_forces(object): X_n_DivT = np.zeros(self.dim, dtype=PARMES_REAL) n_T = np.zeros(self.dim, dtype=PARMES_REAL) # For each point of the current plane - for ind in xrange (chi.shape[1]): - i = chi[0][ind] - j = chi[1][ind] - k = chi[2][ind] + for ind in xrange (chi.shape[0]): # adjust indices for vector fields with ghost points - l = chi[0][ind] + self.ghosts[0] - m = chi[1][ind] + self.ghosts[1] - n = chi[2][ind] + self.ghosts[2] + i = chi[ind][0] + self.ghosts[0] + j = chi[ind][1] + self.ghosts[1] + k = chi[ind][2] + self.ghosts[2] # part1 = 1/2(velocity.velocity)n - (n.velocity)velocity - 1/(dim-1)((n.velocity)(coord X vorticity) + 1/(dim-1)(n.vorticity)(coord X velocity) # (velocity.velocity) - u_u = np.vdot(velo[l,m,n],velo[l,m,n]) + u_u = np.vdot(velo[i,j,k],velo[i,j,k]) # normal.velocity - n_u = np.vdot(velo[l,m,n],NormalVec[:]) + n_u = np.vdot(velo[i,j,k],NormalVec[:]) # normal.vorticity - n_w = np.vdot(vort[l,m,n],NormalVec[:]) + n_w = np.vdot(vort[i,j,k],NormalVec[:]) # coordinates of the current point - coords = self.coordMin[:] + chi[:,ind] * self.step[:] + coords = self.coordMin[:] + chi[ind] * self.step[:] # part1 of the force - int1 = int1 + 0.5 * u_u * NormalVec[:] - n_u * velo[l,m,n] \ - - fact * n_u * np.cross(coords,vort[l,m,n]) \ - + fact * n_w * np.cross(coords,velo[l,m,n]) + int1 = int1 + 0.5 * u_u * NormalVec[:] - n_u * velo[i,j,k] \ + - fact * n_u * np.cross(coords,vort[i,j,k]) \ + + fact * n_w * np.cross(coords,velo[i,j,k]) # part 2 of the force : part 2 = 1/(dim-1)(X^(n^Div(T)) + n.T if (chi.all() == self.chi_down.all()): # normalVec = (-1,0,0) diff --git a/HySoP/hysop/test/test_operator/test_Forces.py b/HySoP/hysop/test/test_operator/test_Forces.py index 169bd80ff..d78333fef 100755 --- a/HySoP/hysop/test/test_operator/test_Forces.py +++ b/HySoP/hysop/test/test_operator/test_Forces.py @@ -54,9 +54,9 @@ class test_Forces(unittest.TestCase): def testComputeForces(self): # Parameters - nb = 32 + nb = 11 timeStep = 0.09 - finalTime = 0.18 + finalTime = 0.36 self.t = 0. t0 = time.time() @@ -73,7 +73,7 @@ class test_Forces(unittest.TestCase): vorti = pp.AnalyticalField(domain=box, formula=self.vorticite, name='Vorticity', vector=True) ## Solver creation (discretisation of objects is done in solver initialisation) - topo3D = pp.CartesianTopology(domain=box, resolution=[nb, nb, nb], dim=3, ghosts=[2.,2.,2.]) + topo3D = pp.CartesianTopology(domain=box, resolution=[nb, nb, nb], dim=3, ghosts=[2,2,2]) ## Fields discretization vorti.discretize(topo3D) @@ -83,16 +83,16 @@ class test_Forces(unittest.TestCase): # Forces computation Re = 200. - noca = Compute_forces(topo3D, sphere, boxMin= [0.25, 0.25, 0.25], boxMax=[0.75, 0.75, 0.75]) + noca = Compute_forces(topo3D, sphere, boxMin= [0.2, 0.2, 0.2], boxMax=[0.8, 0.8, 0.8]) if (topo3D.rank == 0): f = open('./parmepy/test/test_operator/NocaForces.dat', 'w') while (self.t <= finalTime): nocares = noca.apply(self.t, timeStep, velo.discreteField[velo._fieldId], vorti.discreteField[vorti._fieldId], Re) if (topo3D.rank == 0): -# f.write(t, force, force / self.coef, '\n') - f.write(str(nocares)) - f.write('\n') + # print time and forces values in the following order : time, cX, cY, cZ + f.write("%s %s %s %s\n" % (self.t, nocares[0], nocares[1], nocares[2])) + self.t = self.t + timeStep -- GitLab