From fe9aff9bdb08ad02b07d67a7efc86cf81ab6eee1 Mon Sep 17 00:00:00 2001 From: Chloe Mimeau <Chloe.Mimeau@imag.fr> Date: Fri, 15 Mar 2013 09:04:39 +0000 Subject: [PATCH] Adding tests for each of the NS operators --- HySoP/hysop/domain/obstacle/semi_cylinder.py | 110 ++++++++++++++++++ HySoP/hysop/operator/tests/test_Stretching.py | 97 +++++++++++++++ .../hysop/operator/tests/test_advec_scales.py | 96 +++++++++++++++ .../hysop/operator/tests/test_diff_poisson.py | 108 +++++++++++++++++ .../operator/tests/test_penalization_2D.py | 91 +++++++++++++++ .../operator/tests/test_penalization_3D.py | 95 +++++++++++++++ 6 files changed, 597 insertions(+) create mode 100644 HySoP/hysop/domain/obstacle/semi_cylinder.py create mode 100755 HySoP/hysop/operator/tests/test_Stretching.py create mode 100755 HySoP/hysop/operator/tests/test_advec_scales.py create mode 100755 HySoP/hysop/operator/tests/test_diff_poisson.py create mode 100644 HySoP/hysop/operator/tests/test_penalization_2D.py create mode 100644 HySoP/hysop/operator/tests/test_penalization_3D.py diff --git a/HySoP/hysop/domain/obstacle/semi_cylinder.py b/HySoP/hysop/domain/obstacle/semi_cylinder.py new file mode 100644 index 000000000..c5bca7414 --- /dev/null +++ b/HySoP/hysop/domain/obstacle/semi_cylinder.py @@ -0,0 +1,110 @@ +""" +Semi-cylinder obstacle description +""" +from parmepy.constants import np, PARMES_INTEGER +from parmepy.domain.obstacle.obstacle_2D import Obstacle2D + + +class SemiCylinder(Obstacle2D): + """ + Discrete obstacles representation. + """ + + def __init__(self, obst, radius=0.2): + """ + Creates the semi-cylinder obsctacle and y-boundaries and + returns 3 arrays corresponding to the characteristic + functions of three different porous media. + + @param obstacle2D : Two dimensional obstacle description. + @param radius : Semi-cylinder radius + """ + ## 2D parent obstacle + self.obst = obst + ## Radius of the semi-cylinder + self.radius = radius + ## Characteristic function (array) for y-boundaries + self.chiBoundary = None + ## Characteristic function (array) for the solid + self.chiSolid = None + ## Characteristic function (array) for the porous area + self.chiPorous = None + print 'obstacle =', self.obst.obstacleName + + def setUp(self, topology): + """ + Compute the characteristic functions associated + to y-boundaries and semi-cylinder + """ + ## Temporary arrays + chiBoundary_i = [] + chiBoundary_j = [] + chiSolid_i = [] + chiSolid_j = [] + chiPorous_i = [] + chiPorous_j = [] + + step = topology.mesh.space_step + ghosts = topology.ghosts + local_start = topology.mesh.local_start + local_end = topology.mesh.local_end + coord_start = topology.mesh.origin + (ghosts * step) + coord_end = topology.mesh.end - (ghosts * step) + layerMin = coord_start[1] + self.obst.zlayer + layerMax = coord_end[1] - self.obst.zlayer + if not (self.obst.porousLayerThickn <= self.radius): + raise ValueError("Error, porous layer thickness" + + "is higher than semi-cylinder radius.") + radiusMinuslayer = self.radius- self.obst.porousLayerThickn + + print 'step, ghosts, local_start, local_end, zlayer', \ + step, ghosts, local_start, local_end, self.obst.zlayer + print 'start, end, layerMin, layerMax, radiusMinuslayer', \ + coord_start, coord_end, layerMin, layerMax, radiusMinuslayer + + for j in xrange (local_start[1], local_end[1] + 1): + cy = coord_start[1] + j * step[1] + for i in xrange (local_start[0], local_end[0] + 1): + if (cy >= layerMax or cy <= layerMin): + # we are in the y-layer boundary: + chiBoundary_i.append(i) + chiBoundary_j.append(j) + else : + cx = coord_start[0] + i * step[0] + dist = np.sqrt((cx - self.obst.center[0]) ** 2 + + (cy - self.obst.center[1]) ** 2) + if (radiusMinuslayer < dist + and dist <= self.radius + 1E-12 + and cx <= self.obst.center[0] + and self.obst.porousLayerThickn != 0.): + # we are in the porous region of the semi-cylinder: + chiPorous_i.append(i) + chiPorous_j.append(j) + if (dist <= radiusMinuslayer + 1E-12 + and cx <= self.obst.center[0]): + # we are in the solid region of the semi-cylinder: + chiSolid_i.append(i) + chiSolid_j.append(j) + + ## Characteristic function of penalized boundaries + chiBoundary_i = np.asarray(chiBoundary_i, dtype=PARMES_INTEGER) + chiBoundary_j = np.asarray(chiBoundary_j, dtype=PARMES_INTEGER) + self.chiBoundary = tuple([chiBoundary_i, chiBoundary_j]) + + ## Characteristic function of solid areas + chiSolid_i = np.asarray(chiSolid_i, dtype=PARMES_INTEGER) + chiSolid_j = np.asarray(chiSolid_j, dtype=PARMES_INTEGER) + self.chiSolid = tuple([chiSolid_i, chiSolid_j]) + + ## Characteristic function of porous areas + chiPorous_i = np.asarray(chiPorous_i, dtype=PARMES_INTEGER) + chiPorous_j = np.asarray(chiPorous_j, dtype=PARMES_INTEGER) + self.chiPorous = tuple([chiPorous_i, chiPorous_j]) + + def __str__(self): + """ToString method""" + return "SemiCylinder" + +if __name__ == "__main__" : + print "This module defines the following classe:" + print "SemiCylinder: ", SemiCylinder.__doc__ diff --git a/HySoP/hysop/operator/tests/test_Stretching.py b/HySoP/hysop/operator/tests/test_Stretching.py new file mode 100755 index 000000000..62912496f --- /dev/null +++ b/HySoP/hysop/operator/tests/test_Stretching.py @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- +import time + +import parmepy as pp +import numpy as np +import numpy.testing as npt +from parmepy.fields.analytical import AnalyticalField +from parmepy.operator.stretching import Stretching +from parmepy.problem.navier_stokes import NSProblem + + +def computeVel(x, y, z): + amodul = np.cos(np.pi * 1. / 3.) + pix = np.pi * x + piy = np.pi * y + piz = np.pi * z + pi2x = 2. * pix + pi2y = 2. * piy + pi2z = 2. * piz + vx = 2. * np.sin(pix) * np.sin(pix) \ + * np.sin(pi2y) * np.sin(pi2z) * amodul + vy = - np.sin(pi2x) * np.sin(piy) \ + * np.sin(piy) * np.sin(pi2z) * amodul + vz = - np.sin(pi2x) * np.sin(piz) \ + * np.sin(piz) * np.sin(pi2y) * amodul + return vx, vy, vz + +def computeVort(x, y, z): + amodul = np.cos(np.pi * 1. / 3.) + pix = np.pi * x + piy = np.pi * y + piz = np.pi * z + pi2x = 2. * pix + pi2y = 2. * piy + pi2z = 2. * piz + wx = 2.* np.pi * np.sin(pi2x) * amodul*(- np.cos(pi2y) \ + * np.sin(piz) * np.sin(piz) \ + + np.sin(piy) * np.sin(piy) * np.cos(pi2z)) + wy = 2.* np.pi * np.sin(pi2y) * amodul*(2. * np.cos(pi2z) \ + * np.sin(pix) * np.sin(pix) \ + + np.sin(piz) * np.sin(piz) * np.cos(pi2x)) + wz = -2.* np.pi * np.sin(pi2z) * amodul *(np.cos(pi2x) \ + * np.sin(piy) * np.sin(piy) \ + + np.sin(pix) * np.sin(pix) * np.cos(pi2y)) + return wx, wy, wz + +def test_Stretching(): + # Parameters + nb = 33 + dim = 3 + boxLength = [1., 1., 1.] + boxMin = [0., 0., 0.] + nbElem = [nb, nb, nb] + + timeStep = 0.05 + finalTime = timeStep + + t0 = time.time() + + ## Domain + box = pp.Box(dim, length=boxLength, origin=boxMin) + + ## Fields + velo = AnalyticalField(domain=box, formula=computeVel, + name='Velocity', vector=True) + vorti = AnalyticalField(domain=box, formula=computeVort, + name='Vorticity', vector=True) + + ## Operators + stretch = Stretching(velo, vorti, + resolutions={velo: nbElem, + vorti: nbElem}, + method='FD_order4 RK3', + propertyOp='divConservation' + ) + + ##Problem + pb = NSProblem([stretch]) + + ## Setting solver to Problem + pb.setUp(finalTime, timeStep) + + t1 = time.time() + + ## Solve problem + timings = pb.solve() + + 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)" + + +if __name__ == "__main__": + test_Stretching() diff --git a/HySoP/hysop/operator/tests/test_advec_scales.py b/HySoP/hysop/operator/tests/test_advec_scales.py new file mode 100755 index 000000000..dbd2f71e3 --- /dev/null +++ b/HySoP/hysop/operator/tests/test_advec_scales.py @@ -0,0 +1,96 @@ +# -*- coding: utf-8 -*- +import time + +import parmepy as pp +import numpy as np +import numpy.testing as npt +from parmepy.fields.analytical import AnalyticalField +from parmepy.operator.advection import Advection +from parmepy.problem.navier_stokes import NSProblem +from parmepy.operator.monitors.printer import Printer +from math import sqrt, pi, exp + + +def computeVel(x, y, z): + vx = 0. + vy = 0. + vz = 0.1 + return vx, vy, vz + +def computeVort(x, y, z): + xc = 1. / 2. + yc = 1. / 2. + zc = 1. / 4. + R = 0.2 + sigma = R / 2. + Gamma = 0.0075 + dist = sqrt((x-xc) ** 2 + (y-yc) ** 2) + s2 = (z - zc) ** 2 + (dist - R) ** 2 + wx = 0. + wy = 0. + wz = 0. + if (dist != 0.): + cosTheta = (x - xc) / dist + sinTheta = (y - yc) / dist + wTheta = Gamma / (pi * sigma ** 2) * \ + exp(-(s2 / sigma ** 2)) + wx = - wTheta * sinTheta + wy = wTheta * cosTheta + wz = 0. + return wx, wy, wz + +def test_Advection_scales(): + # Parameters + nb = 65 + dim = 3 + boxLength = [1., 1., 1.] + boxMin = [0., 0., 0.] + nbElem = [nb, nb, nb] + + timeStep = 0.01 + finalTime = 150 * timeStep + outputFilePrefix = './scales_' + outputModulo = 10 + + t0 = time.time() + + ## Domain + box = pp.Box(dim, length=boxLength, origin=boxMin) + + ## Fields + velo = AnalyticalField(domain=box, formula=computeVel, + name='Velocity', vector=True) + vorti = AnalyticalField(domain=box, formula=computeVort, + name='Vorticity', vector=True) + + ## Advection (with scales) operator + advec = Advection(velo, vorti, + resolutions={velo: nbElem, + vorti: nbElem}, + method='scales_p_02' + ) + + ## Problem + pb = NSProblem([advec], + monitors=[Printer(fields=[vorti], + frequency=outputModulo, + outputPrefix=outputFilePrefix)]) + + ## Setting solver to Problem + pb.setUp(finalTime, timeStep) + + t1 = time.time() + + ## Solve problem + timings = pb.solve() + + 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)" + + +if __name__ == "__main__": + test_Advection_scales() diff --git a/HySoP/hysop/operator/tests/test_diff_poisson.py b/HySoP/hysop/operator/tests/test_diff_poisson.py new file mode 100755 index 000000000..7ecebea58 --- /dev/null +++ b/HySoP/hysop/operator/tests/test_diff_poisson.py @@ -0,0 +1,108 @@ +# -*- coding: utf-8 -*- +import time + +import parmepy as pp +import numpy as np +from parmepy.constants import PARMES_REAL, ORDER +from parmepy.fields.analytical import AnalyticalField +from parmepy.operator.poisson import Poisson +from parmepy.operator.diffusion import Diffusion +from parmepy.problem.navier_stokes import NSProblem +from parmepy.operator.monitors.energy_enstrophy import Energy_enstrophy +from math import sqrt, pi, exp + + +def computeVel(x, y, z): + vx = 0. + vy = 0. + vz = 0. + return vx, vy, vz + +def computeVort(x, y, z): + xc = 1. / 2. + yc = 1. / 2. + zc = 1. / 4. + R = 0.2 + sigma = R / 2. + Gamma = 0.0075 + dist = sqrt((x-xc) ** 2 + (y-yc) ** 2) + s2 = (z - zc) ** 2 + (dist - R) ** 2 + wx = 0. + wy = 0. + wz = 0. + if (dist != 0.): + cosTheta = (x - xc) / dist + sinTheta = (y - yc) / dist + wTheta = Gamma / (pi * sigma ** 2) * \ + exp(-(s2 / sigma ** 2)) + wx = - wTheta * sinTheta + wy = wTheta * cosTheta + wz = 0. + return wx, wy, wz + +def test_Diff_Poisson(): + # Parameters + nb = 65 + dim = 3 + boxLength = [1., 1., 1.] + boxMin = [0., 0., 0.] + nbElem = [nb, nb, nb] + + timeStep = 0.01 + finalTime = 150 * timeStep + outputFilePrefix = './Energies' + outputModulo = 10 + + t0 = time.time() + + ## Domain + box = pp.Box(dim, length=boxLength, origin=boxMin) + + ## Fields + velo = AnalyticalField(domain=box, formula=computeVel, + name='Velocity', vector=True) + vorti = AnalyticalField(domain=box, formula=computeVort, + name='Vorticity', vector=True) + + ## FFT Diffusion operators and FFT Poisson solver + diffusion = Diffusion(velo, vorti, + resolutions={velo: nbElem, + vorti: nbElem}, + method='', + viscosity=0.002, + with_curl=False + ) + + poisson = Poisson(velo, vorti, + resolutions={velo: nbElem, + vorti: nbElem}, + method='', + domain=box + ) + + ## Problem + pb = NSProblem([diffusion, poisson], + monitors=[Energy_enstrophy( + fields=[velo, vorti], + frequency=outputModulo, + outputPrefix=outputFilePrefix)]) + + + ## Setting solver to Problem + pb.setUp(finalTime, timeStep) + + t1 = time.time() + + ## Solve problem + timings = pb.solve() + + 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)" + + +if __name__ == "__main__": + test_Diff_Poisson() diff --git a/HySoP/hysop/operator/tests/test_penalization_2D.py b/HySoP/hysop/operator/tests/test_penalization_2D.py new file mode 100644 index 000000000..b5e86515a --- /dev/null +++ b/HySoP/hysop/operator/tests/test_penalization_2D.py @@ -0,0 +1,91 @@ +# -*- coding: utf-8 -*- +import time +import parmepy as pp +import numpy as np +from parmepy.constants import PARMES_REAL, ORDER +from parmepy.domain.obstacle.obstacle_2D import Obstacle2D +from parmepy.fields.analytical import AnalyticalField +from parmepy.operator.penalization import Penalization +from parmepy.problem.navier_stokes import NSProblem +from parmepy.operator.monitors.printer import Printer + + +def computeVel(x, y, ): + vx = 1. + vy = 1. + return vx, vy + +def computeVort(x, y): + wx = 0. + wy = 0. + return wx, wy + +def test_Penal2D(): + # Parameters + nb = 101 + dim = 2 + boxLength = [1., 1.] + boxMin = [0., 0.] + nbElem = [nb, nb] + + timeStep = 0.05 + finalTime = timeStep + outputFilePrefix = './penal2D_' + outputModulo = 1 + + t0 = time.time() + + ## Domain + box = pp.Box(dim, length=boxLength, origin=boxMin) + + ## Obstacle + lambd = np.array([10.E8, 10.], + dtype=PARMES_REAL, order=ORDER) + cylinder = Obstacle2D(box, center=[0.5, 0.5], + zlayer=0.02, + porousLayerThickn=0.05, + porousLayerConfig='', + obstacleName='semi_cylinder', + radius=0.2) + + ## Fields + velo = AnalyticalField(domain=box, formula=computeVel, + name='Velocity', vector=True) + vorti = AnalyticalField(domain=box, formula=computeVort, + name='Vorticity', vector=True) + + ## Operators + penal = Penalization(velo, vorti, + obstacle=cylinder, + lambd=lambd, + resolutions={velo: nbElem, + vorti: nbElem}, + method='', + ) + + ##Problem + pb = NSProblem([penal], + monitors=[Printer(fields=[velo], + frequency=outputModulo, + outputPrefix=outputFilePrefix)]) + + ## Setting solver to Problem + pb.setUp(finalTime, timeStep) + + t1 = time.time() + + ## Solve problem + timings = pb.solve() + + 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)" + print "" +# return pb.timings_info[0] + "\"Solving time\" \"Init time\" \"Total time\"", pb.timings_info[1] + str(tf - t1) + " " + str(t1 - t0) + " " + str(tf - t0) + +if __name__ == "__main__": + test_Penal2D() diff --git a/HySoP/hysop/operator/tests/test_penalization_3D.py b/HySoP/hysop/operator/tests/test_penalization_3D.py new file mode 100644 index 000000000..59159c214 --- /dev/null +++ b/HySoP/hysop/operator/tests/test_penalization_3D.py @@ -0,0 +1,95 @@ +# -*- coding: utf-8 -*- +import time +import parmepy as pp +import numpy as np +from parmepy.constants import PARMES_REAL, ORDER +from parmepy.domain.obstacle.obstacle_3D import Obstacle3D +from parmepy.fields.analytical import AnalyticalField +from parmepy.operator.penalization import Penalization +from parmepy.problem.navier_stokes import NSProblem +from parmepy.operator.monitors.printer import Printer + + +def computeVel(x, y, z): + vx = 1. + vy = 1. + vz = 1. + return vx, vy, vz + +def computeVort(x, y, z): + wx = 0. + wy = 0. + wz = 0. + return wx, wy, wz + +def test_Penal3D(): + ## Parameters + nb = 129 + dim = 3 + boxLength = [1., 1., 1.] + boxMin = [0., 0., 0.] + nbElem = [nb, nb, nb] + + timeStep = 0.05 + finalTime = timeStep + outputFilePrefix = './penal3D_' + outputModulo = 1 + + t0 = time.time() + + ## Domain + box = pp.Box(dim, length=boxLength, origin=boxMin) + + ## Obstacle + obstacle = Obstacle3D(box, center=[0.5, 0.5, 0.5], + zlayer=0.02, + porousLayerThickn=0.1, + porousLayerConfig='', + obstacleName='hemisphere', + radius=0.3) + + ## Penalization parameter lambda + lambd = np.array([10.E8, 10.], + dtype=PARMES_REAL, order=ORDER) + + ## Fields + velo = AnalyticalField(domain=box, formula=computeVel, + name='Velocity', vector=True) + vorti = AnalyticalField(domain=box, formula=computeVort, + name='Vorticity', vector=True) + + ## Penalization operator + penal = Penalization(velo, vorti, + obstacle=obstacle, + lambd=lambd, + resolutions={velo: nbElem, + vorti: nbElem}, + method='', + ) + + ## Problem + pb = NSProblem([penal], + monitors=[Printer(fields=[velo], + frequency=outputModulo, + outputPrefix=outputFilePrefix)]) + + ## Setting solver to Problem + pb.setUp(finalTime, timeStep) + + t1 = time.time() + + ## Solve problem + timings = pb.solve() + + 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)" + print "" +# return pb.timings_info[0] + "\"Solving time\" \"Init time\" \"Total time\"", pb.timings_info[1] + str(tf - t1) + " " + str(t1 - t0) + " " + str(tf - t0) + +if __name__ == "__main__": + test_Penal3D() -- GitLab