Beispiel #1
0
 def __init__(self):
     self.env = SPHEnv()
     self.env.h = 1.0
     self.env.maxneighs = 100
     self.env.dt = 0.0001
     self.env.g = 9.81
     self.env.avgneighs = 50
     self.env.maxdvar = 0.1
     self.env.avgdvar = 0.1
     self.env.maxiter = 500
     self.env.slipcoeff = 1.
     self.env.auto_dt_coeff = 0.01
     self.env.dt_min = 0.01
     self.wkernels = {}
     self.wkernels['WendlandC2'] = WendC2_mod(self.h, self.avgneighs)
     self.wkernels['WendlandC4'] = WendC4_mod(self.h, self.avgneighs)
     self.wkernels['WendlandC6'] = WendC6_mod(self.h, self.avgneighs)
     self.wkrn = 'WendlandC2'
     self.particles = ParticleField()
     self.particles.setup_vec('pos', 'vel', 'vel_adv', 'force', 'pforce', 'dii', 'sum_dijpjl')
     self.particles.setup_scal('press', 'new_press', 'rho0', 'rho', 'rho_adv', 'new_rho', 'mass', 'visc', 'dcorr', 'aii', 'kappa', 'rho_err')
     self.particles.info = CLChar()
     self.particles.index = CLUInt()
     self.particles.indvec = CLUInt4()
     self.neighsearch = Neighsearch(posarg=self.particles.pos, group=self.particles._group, h=self.h, maxneighs=self.maxneighs, index=self.particles.index, indvec=self.particles.indvec)      
     self.steps = {}
Beispiel #2
0
class IISPHSolver(object):            
    consts = {}
    consts['MAT_IGNORE'] = - 1
    consts['MAT_FLUID'] = 0
    consts['MAT_FIXEDBOUND'] = 1
    CONSTS_SRC = ''
    for i in consts.iteritems():
        CONSTS_SRC += 'constant int ' + i[0] + ' = ' + str(i[1]) + ';\n'
    CONSTS_SRC += NEIGHSEARCH_MACRO
    
    def __init__(self):
        self.env = SPHEnv()
        self.env.h = 1.0
        self.env.maxneighs = 100
        self.env.dt = 0.0001
        self.env.g = 9.81
        self.env.avgneighs = 50
        self.env.maxdvar = 0.1
        self.env.avgdvar = 0.1
        self.env.maxiter = 500
        self.env.slipcoeff = 1.
        self.env.auto_dt_coeff = 0.01
        self.env.dt_min = 0.01
        self.wkernels = {}
        self.wkernels['WendlandC2'] = WendC2_mod(self.h, self.avgneighs)
        self.wkernels['WendlandC4'] = WendC4_mod(self.h, self.avgneighs)
        self.wkernels['WendlandC6'] = WendC6_mod(self.h, self.avgneighs)
        self.wkrn = 'WendlandC2'
        self.particles = ParticleField()
        self.particles.setup_vec('pos', 'vel', 'vel_adv', 'force', 'pforce', 'dii', 'sum_dijpjl')
        self.particles.setup_scal('press', 'new_press', 'rho0', 'rho', 'rho_adv', 'new_rho', 'mass', 'visc', 'dcorr', 'aii', 'kappa', 'rho_err')
        self.particles.info = CLChar()
        self.particles.index = CLUInt()
        self.particles.indvec = CLUInt4()
        self.neighsearch = Neighsearch(posarg=self.particles.pos, group=self.particles._group, h=self.h, maxneighs=self.maxneighs, index=self.particles.index, indvec=self.particles.indvec)      
        self.steps = {}
            
    @property    
    def wkrn(self):
        return self._wkrn
    
    @wkrn.setter    
    def wkrn(self, value):
        self._wkrn = self.wkernels[value]
        
    @property
    def h(self):
        return self.env.h.value
        
    @h.setter
    def h(self, value):
        self.env.h.value = value
        for kernel in self.wkernels.values():
            kernel.update(self.h, self.avgneighs)
            
    @property
    def maxneighs(self):
        return int(self.env.maxneighs.value)
        
    @maxneighs.setter
    def maxneighs(self, value):
        self.env.maxneighs.value = value
        
    @property
    def dt(self):
        return self.env.dt.value
        
    @dt.setter
    def dt(self, value):
        self.env.dt.value = value
        
    @property
    def g(self):
        return self.env.g.value
        
    @g.setter
    def g(self, value):
        self.env.g.value = value
        
    @property
    def avgneighs(self):
        return self.env.avgneighs.value
        
    @avgneighs.setter
    def avgneighs(self, value):
        self.env.avgneighs.value = value
        for kernel in self.wkernels.values():
            kernel.update(self.h, self.avgneighs)      
        
    @property
    def maxdvar(self):
        return self.env.maxdvar.value
        
    @maxdvar.setter
    def maxdvar(self, value):
        self.env.maxdvar.value = value
        
    @property
    def avgdvar(self):
        return self.env.avgdvar.value
        
    @avgdvar.setter
    def avgdvar(self, value):
        self.env.avgdvar.value = value
        
    @property
    def maxiter(self):
        return self.env.maxiter.value
        
    @maxiter.setter
    def maxiter(self, value):
        self.env.maxiter.value = value
        
    @property
    def auto_dt_coeff(self):
        return self.env.auto_dt_coeff.value
        
    @auto_dt_coeff.setter
    def auto_dt_coeff(self, value):
        self.env.auto_dt_coeff.value = value
        
    @property
    def dt_min(self):
        return self.env.dt_min.value
        
    @dt_min.setter
    def dt_min(self, value):
        self.env.dt_min.value = value
        
    def setup(self):
        self.steps['compute_bound_mass'] = SolverStep(src=COMPUTE_BOUND_MASS, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='compute_bound_mass')
        self.steps['compute_density'] = SolverStep(src=COMPUTE_DENSITY, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='compute_density')
        self.steps['reset_force'] = SolverStep(src=RESET_FORCE, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='reset_force')
        self.steps['apply_gravity'] = SolverStep(src=APPLY_GRAVITY, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='apply_gravity')
        self.steps['apply_viscosity'] = SolverStep(src=APPLY_VISCOSITY, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='apply_viscosity')
        self.steps['apply_surface_tension'] = SolverStep(src=APPLY_SURFACE_TENSION, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='apply_surface_tension')
        self.steps['compute_vel_adv'] = SolverStep(src=COMPUTE_VEL_ADV, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='compute_vel_adv')
        self.steps['compute_dii'] = SolverStep(src=COMPUTE_DII, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='compute_dii')
        self.steps['compute_rho_adv_init_press'] = SolverStep(src=COMPUTE_RHO_ADV_INIT_PRESS, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='compute_rho_adv_init_press')    
        self.steps['compute_aii'] = SolverStep(src=COMPUTE_AII, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='compute_aii')    
        self.steps['compute_sum_dijpjl'] = SolverStep(src=COMPUTE_SUM_DIJPJL, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='compute_sum_dijpjl')    
        self.steps['compute_pressure'] = SolverStep(src=COMPUTE_PRESSURE, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='compute_pressure')    
        self.steps['set_pressure_clamped'] = SolverStep(src=SET_PRESSURE_CLAMPED, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='set_pressure_clamped')    
        self.steps['compute_new_rho'] = SolverStep(src=COMPUTE_NEW_RHO, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='compute_new_rho')    
        self.steps['compute_density_error'] = SolverStep(src=COMPUTE_DENSITY_ERROR, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='compute_density_error')    
        self.steps['compute_pressure_force'] = SolverStep(src=COMPUTE_PRESSURE_FORCE, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='compute_pressure_force')    
        self.steps['integrate'] = SolverStep(src=INTEGRATE, field=self.particles, env=self.env, wkrn=self.wkrn, consts=IISPHSolver.CONSTS_SRC, neighsearch=self.neighsearch, name='integrate')

    def autoset_dt(self):
        vmax = max_length_real4(self.particles.vel)
        vadvmax = max_length_real4(self.particles.vel_adv)
        dt_new_v = self.dt
        dt_new_adv = self.dt
        if (vmax > 0.0):
            dt_new_v = self.auto_dt_coeff*self.h/vmax
        if (vadvmax > 0.0):
            dt_new_adv = self.auto_dt_coeff*self.h/vadvmax   
        if dt_new_v < dt_new_adv:
            self.dt = min(dt_new_v, self.dt_min)
            #print 'vel', self.dt
        else:
            self.dt = min(dt_new_adv, self.dt_min)
            #print 'vel_adv', self.dt
    
    @timing    
    def update(self):
        self.neighsearch.search(h=self.h, maxneighs=self.maxneighs)
        self.autoset_dt()
        self.steps['compute_bound_mass']()
        self.steps['compute_density']()
        self.steps['reset_force']()
        self.steps['apply_gravity']()
        self.steps['apply_viscosity']()
        self.steps['apply_surface_tension']()
        self.steps['compute_vel_adv']()
        self.steps['compute_dii']()
        self.steps['compute_rho_adv_init_press']()
        self.steps['compute_aii']()
        for i in range(self.maxiter):
            self.steps['compute_sum_dijpjl']()
            self.steps['compute_pressure']()
            self.steps['set_pressure_clamped']()
            self.steps['compute_new_rho']()
            self.steps['compute_density_error']()
            maxerr = max_reduce(self.particles.rho_err)
            avgerr = maxerr/len(self.particles.rho_err)
            if ((maxerr < self.maxdvar) or (avgerr < self.avgdvar)) and (i >= 2):
                #print 'pressure solve iterations: ', i
                break 
        self.steps['compute_pressure_force']()
        self.steps['integrate']()