From b028cfff563166abca33b1e0fdb2b596b77b11b6 Mon Sep 17 00:00:00 2001 From: Eric Dalissier <Eric.Dalissier@imag.fr> Date: Tue, 6 Nov 2012 14:03:57 +0000 Subject: [PATCH] forward euler test add --- .../hysop/operator/differentialOperator_d.py | 34 +++++- HySoP/hysop/operator/stretching_d.py | 3 +- .../integrator/runge_kutta4.py | 32 ++--- .../test_particular_solvers/test_euler.py | 114 ++++++++++++++++++ 4 files changed, 167 insertions(+), 16 deletions(-) create mode 100644 HySoP/hysop/test/test_particular_solvers/test_euler.py diff --git a/HySoP/hysop/operator/differentialOperator_d.py b/HySoP/hysop/operator/differentialOperator_d.py index 739b6e4ab..1c3fd582d 100755 --- a/HySoP/hysop/operator/differentialOperator_d.py +++ b/HySoP/hysop/operator/differentialOperator_d.py @@ -100,7 +100,39 @@ class DifferentialOperator_d(DiscreteOperator): self.result[2][...]= temp1 + temp2 +temp3 elif self.choice == 'curl': - pass + temp1 = (1.0 * self.field1[2][:,np.roll(ind,+2),:] - + 8.0 * self.field1[2][:,np.roll(ind,+1),:] +\ + 8.0 * self.field1[2][:,np.roll(ind,-1),:] -\ + 1.0 * self.field1[2][:,np.roll(ind,-2),:] ) / (12. * mesh_size[1]) + + temp2 = (1.0 * self.field1[1][...,np.roll(ind,+2)] -\ + 8.0 * self.field1[1][...,np.roll(ind,+1)] +\ + 8.0 * self.field1[1][...,np.roll(ind,-1)] -\ + 1.0 * self.field1[1][...,np.roll(ind,-2)] ) / (12. * mesh_size[2]) + self.result[0]= temp1 - temp2 + + temp1 = (1.0 * self.field1[2][np.roll(ind,+2),...] - + 8.0 * self.field1[2][np.roll(ind,+1),...] +\ + 8.0 * self.field1[2][np.roll(ind,-1),...] -\ + 1.0 * self.field1[2][np.roll(ind,-2),...] ) / (12. * mesh_size[0]) + + temp2 = (1.0 * self.field1[0][...,np.roll(ind,+2)] -\ + 8.0 * self.field1[0][...,np.roll(ind,+1)] +\ + 8.0 * self.field1[0][...,np.roll(ind,-1)] -\ + 1.0 * self.field1[0][...,np.roll(ind,-2)] ) / (12. * mesh_size[2]) + self.result[1]= temp1 - temp2 + + temp1 = (1.0 * self.field1[1][...,np.roll(ind,+2)] - + 8.0 * self.field1[1][...,np.roll(ind,+1)] +\ + 8.0 * self.field1[1][...,np.roll(ind,-1)] -\ + 1.0 * self.field1[1][...,np.roll(ind,-2)] ) / (12. * mesh_size[0]) + + temp2 = (1.0 * self.field1[0][:,np.roll(ind,+2),:] -\ + 8.0 * self.field1[0][:,np.roll(ind,+1),:] +\ + 8.0 * self.field1[0][:,np.roll(ind,-1),:] -\ + 1.0 * self.field1[0][:,np.roll(ind,-2),:] ) / (12. * mesh_size[1]) + self.result[2]= temp1 - temp2 + else: raise ValueError("Unknown differiential operator: " + str(self.choice)) diff --git a/HySoP/hysop/operator/stretching_d.py b/HySoP/hysop/operator/stretching_d.py index 51c0e221f..4b02ba8f4 100755 --- a/HySoP/hysop/operator/stretching_d.py +++ b/HySoP/hysop/operator/stretching_d.py @@ -66,7 +66,8 @@ class Stretching_d(DiscreteOperator): self.stretchTerm.discreteOperator.apply() # Time integration of dw/dt = div(wu) - methodInt=self.method() + methodInt=self.method(self.stretchTerm.discreteOperator) + print dir(methodInt) for i in range(self.vorticity.topology.dim): self.res_vorticity[i][...] = methodInt.integrate(self.vorticity, self.stretchTermResult, t, dt, direction=i) diff --git a/HySoP/hysop/particular_solvers/integrator/runge_kutta4.py b/HySoP/hysop/particular_solvers/integrator/runge_kutta4.py index fe8f05794..b528ca612 100755 --- a/HySoP/hysop/particular_solvers/integrator/runge_kutta4.py +++ b/HySoP/hysop/particular_solvers/integrator/runge_kutta4.py @@ -15,7 +15,7 @@ class RK4(ODESolver): y(t_n+1)= y(t_n) + dt*y'[y(t_n)+dt/2*y'(y(t_n))]. """ - def __init__(self, f=None, conditions=lambda x: x, dim=3): + def __init__(self, f=None, dim=3): """ Constructor. @@ -24,11 +24,7 @@ class RK4(ODESolver): @param conditions : function to apply boundary conditions. """ ODESolver.__init__(self, f) - # Boundary conditions function. - self.boundaryConditions = conditions - self.gpu_kernel = """ - """ - self.nb_flop = 5 + def integrate(self, f, yp , t, dt): """ @@ -36,18 +32,26 @@ class RK4(ODESolver): yp= y + dt*y'[y+dt/2*y'(y)]. @param y : position at time t. - @param fy : y'(y) value at time t. + @param f : operator to calcul y'(y) value at time t. @param yp : result position at time t + dt @param t : current time. @param dt : time step. """ - K1 = yp + dt * f(t, yp) - K2 = yp + dt * f(t + 0.5 * dt, (yp + K1) * 0.5) - K3 = yp + dt * f(t + 0.5 * dt, (yp + K2) * 0.5) - return (yp + (1/6.0) * dt * ( f(t, yp) + - 2. * f(t + 0.5 * dt, (yp + K1) * 0.5) + - 2. * f(t + 0.5 * dt, (yp + K2) * 0.5) + - f(t + dt, K3 )) ) + dt2 = dt / 2.0 + K1 = f.field1() * dt + yt = f(field1= yp + K1*0.5, f.field2() ) + yt.apply() + K2 = yt.field1() * dt + yt = f(field1= yp + K2*0.5, f.field2() ) + yt.apply() + K3 = yt.field1() * dt + yt = f(field1= yp + K3, f.field2() ) + yt.apply() + K4 = yt.field1() * dt + unew = yp + (1/6.0) * (K1 + K2 *2. + K3 * 2. + K4) + return unew + + def __str__(self): """ToString method""" diff --git a/HySoP/hysop/test/test_particular_solvers/test_euler.py b/HySoP/hysop/test/test_particular_solvers/test_euler.py new file mode 100644 index 000000000..12b0dac2d --- /dev/null +++ b/HySoP/hysop/test/test_particular_solvers/test_euler.py @@ -0,0 +1,114 @@ +# -*- coding: utf-8 -*- +import unittest +from parmepy.fields.discrete import * +from parmepy.fields.continuous import * +from parmepy.fields.analytical import * +from parmepy.domain.topology import * +from parmepy.domain.box import * +from parmepy.constants import * +from parmepy.particular_solvers.integrator.integrator import ODESolver +from parmepy.particular_solvers.integrator.euler import Euler +import numpy as np +import numpy.testing as npt +import math + + +class test_Euler(unittest.TestCase): + """ + Euler test + solve u'(t) = f( u(t),t ) + u(t) = a t + U0 + f(u,t) = a + (u - (at + U0))^4 + """ + def setUp(self): + self.e = 0.0002 # Accepted error between result and analytical result + self.dim = 3 + self.boxLength = [1., 1., 1.] + self.boxMin = [ 0., 0., 0.] + self.nbPts = [6, 6, 6] + self.box = Box(dimension=self.dim, + length=self.boxLength, + origin=self.boxMin) + self.dt = 0.1 + self.FinalTime = 3 + self.U0 = [1.0 , 2.0, 3.0 ] + + def testEulerInt(self): + # Continuous fields and operator declaration + self.velo = AnalyticalField(domain=self.box, formula=self.vitesse, name='Velocity', vector=True) + # Topology definition / Fields and operator discretization + self.result = [np.ones((self.nbPts), dtype=PARMES_REAL, order=ORDER) for d in xrange(self.dim)] + self.topo3D = CartesianTopology(domain=self.box, resolution=self.nbPts, dim=self.dim) + self.velo.discretize(self.topo3D) + self.velo.initialize() + self.resol = self.topo3D.mesh.resolution + #test for t=0 and initialization of the fonction f + t = 0. + fctInter = [np.ones((self.nbPts), dtype=PARMES_REAL, order=ORDER) for d in xrange(self.dim)] + method = Euler() + + #Solution calculated with Euler + fctInter = self.fctTest(t,self.velo.discreteField[self.velo._fieldId].data[0]\ + ,self.velo.discreteField[self.velo._fieldId].data[1]\ + ,self.velo.discreteField[self.velo._fieldId].data[2]) + for d in xrange(self.dim) : + self.result[d][...] = method.integrate(self.velo.discreteField[self.velo._fieldId], fctInter, t, self.dt, d ) + + t=t+self.dt + + #Analytical solution + self.anal=self.analyticalSolution(t,self.velo.discreteField[self.velo._fieldId].data[0]\ + ,self.velo.discreteField[self.velo._fieldId].data[1]\ + ,self.velo.discreteField[self.velo._fieldId].data[2]) + npt.assert_array_less(abs(self.anal[0]-self.result[0]), self.e) + npt.assert_array_less(abs(self.anal[1]-self.result[1]), self.e) + npt.assert_array_less(abs(self.anal[2]-self.result[2]), self.e) + + # time loop + while t < self.FinalTime : + #print "T=" , t + fctInter = self.fctTest(t,self.result[0],self.result[1],self.result[2]) + for d in xrange(self.dim) : + self.result[d][...] = method.integrate(self.result, fctInter, t, self.dt, d ) + + t = t + self.dt + + self.anal=self.analyticalSolution(t,self.velo.discreteField[self.velo._fieldId].data[0]\ + ,self.velo.discreteField[self.velo._fieldId].data[1]\ + ,self.velo.discreteField[self.velo._fieldId].data[2]) + # Comparison with analytical solution + npt.assert_array_less(abs(self.anal[0]-self.result[0]), self.e) + npt.assert_array_less(abs(self.anal[1]-self.result[1]), self.e) + npt.assert_array_less(abs(self.anal[2]-self.result[2]), self.e) + + + def vitesse(self, x, y, z): + vx = 1.0 + vy = 2.0 + vz = 3.0 + return vx, vy, vz + + def fctTest(self, t, x, y, z): + wx = 0.2 +( x - self.analyticalSolution(t, 1., 2., 3.)[0])**4 + wy = 0.5 +( y - self.analyticalSolution(t, 1., 2., 3.)[1])**4 + wz = 1. +( z - self.analyticalSolution(t, 1., 2., 3.)[2])**4 + return [wx,wy,wz] + + def analyticalSolution(self, t, x, y, z): + sx = 0.2 *t + x + sy = 0.5 *t + y + sz = 1. *t + z + return [sx, sy, sz] + + def runTest(self): + self.setUp() + self.testOperatorDiv() + + +def suite(): + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(test_Euler)) + return suite + +if __name__ == "__main__": + unittest.TextTestRunner(verbosity=2).run(suite()) -- GitLab