From 2d793b78c8841432fd7fc28218d95884b9a5e86d Mon Sep 17 00:00:00 2001
From: Eric Dalissier <Eric.Dalissier@imag.fr>
Date: Mon, 17 Dec 2012 13:32:12 +0000
Subject: [PATCH] Add vorticity penalization, and penalization for NS

---
 Examples/NavierStokes3dStretch.py             | 142 ++++++++++++++++++
 .../hysop/operator/differentialOperator_d.py  |   1 +
 HySoP/hysop/operator/penalization.py          |  10 +-
 HySoP/hysop/operator/penalization_d.py        |   8 +-
 .../test/test_operator/test_Penalization.py   |  12 +-
 5 files changed, 166 insertions(+), 7 deletions(-)
 create mode 100644 Examples/NavierStokes3dStretch.py

diff --git a/Examples/NavierStokes3dStretch.py b/Examples/NavierStokes3dStretch.py
new file mode 100644
index 000000000..a8b300e86
--- /dev/null
+++ b/Examples/NavierStokes3dStretch.py
@@ -0,0 +1,142 @@
+#!/usr/bin/python
+import parmepy as pp
+import parmepy.f2py
+import numpy as np
+import mpi4py.MPI as MPI
+import math as m
+import time
+
+#from numpy import linalg as LA
+
+pi = m.pi
+
+# Import scales and fftw solvers
+ppfft = parmepy.f2py.fftw2py
+scales = parmepy.f2py.scales2py
+
+rank = MPI.COMM_WORLD.Get_rank()
+print "Mpi process number ", rank
+
+# ----------- A 3d problem -----------
+print " ========= Start test for Navier-Stokes 3D ========="
+
+# Physical Domain description
+Lx = Ly = Lz = 2 * pi
+myDomain3d = pp.Box(dimension=3, length=[Lx, Ly, Lz], origin=[0., 0., 0.])
+resolution3d = np.asarray((65, 65, 65))
+ncells = resolution3d - 1
+hx = Lx / ncells[0]
+hy = Ly / ncells[1]
+hz = Lz / ncells[2]
+
+# Simulation parameters
+finalTime = 0.05
+timeStep = 1e-3
+outputFilePrefix = './res/Stretching_'
+outputModulo = 1
+
+t0 = time.time()
+
+## Obstacle
+lambd=np.array([0, 1, 10**8],dtype = PARMES_REAL, order=ORDER)
+sphere = pp.Obstacle(box, name='sphere', zlayer=0.1, radius=0.1, center=[0.5,0.5,0.5], orientation='West', porousLayer=0.05)
+
+# Fields declaration
+
+# 1 - Poisson/diffusion solvers initialisation.
+# See poisson3d.py for a working example.
+# poisson = pp.Poisson(vorticity,velocity)
+# 
+localres, localoffset = ppfft.init_fftw_solver(resolution3d,
+                                               myDomain3d.length)
+
+print "FFT solver local resolution/offset: ", localres, localoffset
+
+##topofft = poisson.getTopology()
+topofft = pp.CartesianTopology(domain=myDomain3d, resolution=resolution3d, dim=3)
+
+
+def computeVel(x, y, z):
+    vx = 2./np.sqrt(3) * np.sin(2.* pi/3.) * np.sin(x) * np.cos(y) * np.cos(z)
+    vy = 2./np.sqrt(3) * np.sin(-2.* pi/3.) * np.cos(x) * np.sin(y) * np.cos(z)
+    vz = 0.
+    return vx , vy , vz 
+
+
+def computeVort(x, y, z):
+    wx = - np.cos(x) * np.sin(y) * np.sin(z)
+    wy = - np.sin(x) * np.cos(y) * np.sin(z)
+    wz = 2. * np.sin(x) * np.sin(y) * np.cos(z)
+    return wx , wy , wz
+
+
+velocity = pp.AnalyticalField(domain=myDomain3d, formula=computeVel,
+                              name='Velocity', vector=True)
+vorticity = pp.AnalyticalField(domain=myDomain3d, formula=computeVort,
+                               name='Vorticity', vector=True)
+
+## 2 - Advection solver initialisation. See testScales for a working example.
+## Based on scales JB solver
+## Warning : fields input for scales should be of size (ncells), not localres.
+#scalesres, scalesoffset, stab_coeff = \
+#    scales.init_advection_solver(ncells, myDomain3d.length, order='p_O2')
+
+# 3 - Stretching
+stretch = pp.Stretching(vorticity, velocity)
+
+# 4 - Penalization
+penal = pp.Penalization(velo, vorti, sphere, lambd)
+
+navierStokes = pp.Problem(topofft, [stretch,penal])
+printer = pp.Printer(fields=[vorticity, velocity], frequency=outputModulo,
+                     outputPrefix=outputFilePrefix)
+
+navierStokes.setSolver(finalTime, timeStep, solver_type='basic', io=printer)
+
+## Problem => ParticularSover = basic.initialize()
+navierStokes.initSolver()
+
+## end of init ##
+## Mind that scales works on arrays of size resolution - 1
+## --> pointers to subarrays of velocity/vorticity
+#svx = velocity[0][:-1, :-1, :-1]
+#svy = velocity[1][:-1, :-1, :-1]
+#svz = velocity[2][:-1, :-1, :-1]
+#somega_x = vorticity[0][:-1, :-1, :-1]
+#somega_y = vorticity[1][:-1, :-1, :-1]
+#somega_z = vorticity[2][:-1, :-1, :-1]
+
+## solve advection
+#scales.solve_advection(timeStep, svx, svy, svz, somega_x)
+#scales.solve_advection(timeStep, svx, svy, svz, somega_y)
+#scales.solve_advection(timeStep, svx, svy, svz, somega_z)
+
+t1 = time.time()
+
+## solve stretching
+navierStokes.solve()
+
+## solve diffusion
+#vx = velocity[0]
+#vy = velocity[1]
+#vz = velocity[2]
+#omega_x = vorticity[0]
+#omega_y = vorticity[1]
+#omega_z = vorticity[2]
+
+#omega_x, omega_y, omega_z = ppfft.solve_diffusion_3d(vx, vy, vz)
+
+## solve poisson
+#vx, vy, vz = ppfft.solve_poisson_3d(omega_x, omega_y, omega_z)
+
+## end of time loop ##
+
+# Clean memory buffers
+#ppfft.clean_fftw_solver(myDomain3d.dimension)
+
+tf = time.time()
+
+print "\n"
+print "Total time : ", tf - t0, "sec (CPU)"
+print "Init time : ", t1 - t0, "sec (CPU)"
+print "Solving time : ", tf - t1, "sec (CPU)"
diff --git a/HySoP/hysop/operator/differentialOperator_d.py b/HySoP/hysop/operator/differentialOperator_d.py
index 247ad5472..8955cbf12 100755
--- a/HySoP/hysop/operator/differentialOperator_d.py
+++ b/HySoP/hysop/operator/differentialOperator_d.py
@@ -238,6 +238,7 @@ class DifferentialOperator_d(DiscreteOperator):
                      1.0 * self.field1[0][:,np.roll(ind,-2),:] ) / (12. * self.meshSize[1]) 
             tmp3 = temp1 - temp2
             result = np.concatenate((np.array([tmp1]), np.array([tmp2]), np.array([tmp3])))
+            print 'curly' ,  result
             return result
 
         else:
diff --git a/HySoP/hysop/operator/penalization.py b/HySoP/hysop/operator/penalization.py
index a33e19bea..663463a8f 100644
--- a/HySoP/hysop/operator/penalization.py
+++ b/HySoP/hysop/operator/penalization.py
@@ -13,7 +13,7 @@ class Penalization(ContinuousOperator):
     Penalization operator representation
     """
 
-    def __init__(self, velocity, obstacle, lambd):
+    def __init__(self, velocity, vorticity, obstacle, lambd):
         """
         Constructor.
         Create a Penalization operator from given velocity variavle.
@@ -25,18 +25,20 @@ class Penalization(ContinuousOperator):
         self.obstacle = obstacle
         ## velocity variable to penalize
         self.velocity = velocity
+        ## vorticity variable to penalize
+        self.vorticity = vorticity
         ## lambda penalization function
         self.lambd = lambd
-        self.addVariable([velocity])
+        self.addVariable([velocity, vorticity])
 
-    def discretize(self, idVelocityD=0, idObstacleD=0):
+    def discretize(self, idVelocityD=0, idVorticityD=0, idObstacleD=0):
         """
         Penalization operator discretization method.
         Create a PenalizationDOp.PenalizationDOp from given specifications.
 
         """
         if self.discreteOperator is None:
-            self.discreteOperator = Penalization_d(self, idVelocityD, idObstacleD)
+            self.discreteOperator = Penalization_d(self, idVelocityD, idVorticityD, idObstacleD)
 
     def __str__(self):
         """ToString method"""
diff --git a/HySoP/hysop/operator/penalization_d.py b/HySoP/hysop/operator/penalization_d.py
index b56d7b45e..ff1895940 100644
--- a/HySoP/hysop/operator/penalization_d.py
+++ b/HySoP/hysop/operator/penalization_d.py
@@ -5,6 +5,7 @@ Discrete penalization representation
 """
 from ..constants import *
 from .discrete import DiscreteOperator
+from .differentialOperator_d import DifferentialOperator_d
 #from ..obstacle.obstacle import Obstacle
 import pyopencl as cl
 import numpy as np
@@ -17,7 +18,7 @@ class Penalization_d(DiscreteOperator):
     DiscreteOperator.DiscreteOperator specialization.
     """
 
-    def __init__(self, penal, idVelocityD=0, idObstacleD=0):
+    def __init__(self, penal, idVelocityD=0, idVorticityD=0, idObstacleD=0):
         """
         Constructor.
         Create a Penalization operator on a given continuous domain.
@@ -30,6 +31,8 @@ class Penalization_d(DiscreteOperator):
         self.penal = penal
         ## Velocity.
         self.velocity = penal.velocity.discreteField[idVelocityD]
+        ## Vorticity.
+        self.vorticity = penal.vorticity.discreteField[idVorticityD]
         ## Obstacle represented by characteristic function Chi
         self.obstacle = self.penal.obstacle.discreteObstacle[idObstacleD]
 #        ## Topology
@@ -62,6 +65,9 @@ class Penalization_d(DiscreteOperator):
             self.velocity[1][k[0],k[1],k[2]] = coef[2] * self.velocity[1][k[0],k[1],k[2]]
             self.velocity[2][k[0],k[1],k[2]] = coef[2] * self.velocity[2][k[0],k[1],k[2]]
 
+        self.vorticity.data = DifferentialOperator_d(self.velocity, self.vorticity, choice='curl', resolution=self.vorticity.topology.resolution, meshSize=self.vorticity.topology.mesh.size).apply()
+
+
         return self.compute_time
 
     def printComputeTime(self):
diff --git a/HySoP/hysop/test/test_operator/test_Penalization.py b/HySoP/hysop/test/test_operator/test_Penalization.py
index 62b552a73..4ec5a0be3 100644
--- a/HySoP/hysop/test/test_operator/test_Penalization.py
+++ b/HySoP/hysop/test/test_operator/test_Penalization.py
@@ -14,6 +14,13 @@ def vitesse(x, y, z):
     vz = 2.
     return vx, vy, vz
 
+def vorticite(x, y, z):
+    wx = 3.
+    wy = 3.
+    wz = 3.
+    return wx, wy, wz
+
+
 def run():
     # Parameters
     nb = 128
@@ -36,9 +43,10 @@ def run():
 
     ## Fields
     velo = pp.AnalyticalField(domain=box, formula=vitesse, name='Velocity', vector=True)
+    vorti = pp.AnalyticalField(domain=box, formula=vorticite, name='Vorticity', vector=True)
 
     ## Operators
-    penal = pp.Penalization(velo, sphere, lambd)
+    penal = pp.Penalization(velo, vorti, sphere, lambd)
 
     ## Solver creation (discretisation of objects is done in solver initialisation)
     topo3D = pp.CartesianTopology(domain=box, resolution=[nb, nb, nb], dim=3)
@@ -46,7 +54,7 @@ def run():
     pb = pp.Problem(topo3D, [penal])
 
     ## Setting solver to Problem
-    pb.setSolver(finalTime, timeStep, solver_type='basic', io=pp.Printer(fields=[velo], frequency=outputModulo, outputPrefix=outputFilePrefix))
+    pb.setSolver(finalTime, timeStep, solver_type='basic', io=pp.Printer(fields=[velo, vorti], frequency=outputModulo, outputPrefix=outputFilePrefix))
     pb.solver.ODESolver= RK4# RK3# RK2# Euler#
     pb.initSolver()
     t1 = time.time()
-- 
GitLab