def execute(self, pset, endtime, dt, recovery=None, output_file=None): """Execute this Kernel over a ParticleSet for several timesteps""" def remove_deleted(pset): """Utility to remove all particles that signalled deletion""" indices = [ i for i, p in enumerate(pset.particles) if p.state in [ErrorCode.Delete] ] if len(indices) > 0 and output_file is not None: output_file.write(pset[indices], endtime, deleted_only=True) pset.remove(indices) if recovery is None: recovery = {} recovery_map = recovery_base_map.copy() recovery_map.update(recovery) for g in pset.fieldset.gridset.grids: if len( g.load_chunk ) > 0: # not the case if a field in not called in the kernel g.load_chunk = np.where(g.load_chunk > 0, 3, g.load_chunk) # Execute the kernel over the particle set if self.ptype.uses_jit: self.execute_jit(pset, endtime, dt) else: self.execute_python(pset, endtime, dt) # Remove all particles that signalled deletion remove_deleted(pset) # Identify particles that threw errors error_particles = [ p for p in pset.particles if p.state != ErrorCode.Success ] while len(error_particles) > 0: # Apply recovery kernel for p in error_particles: if p.state == ErrorCode.Repeat: p.state = ErrorCode.Success else: recovery_kernel = recovery_map[p.state] p.state = ErrorCode.Success recovery_kernel(p, self.fieldset, p.time) # Remove all particles that signalled deletion remove_deleted(pset) # Execute core loop again to continue interrupted particles if self.ptype.uses_jit: self.execute_jit(pset, endtime, dt) else: self.execute_python(pset, endtime, dt) error_particles = [ p for p in pset.particles if p.state != ErrorCode.Success ]
def execute(self, pset, endtime, dt, recovery=None, output_file=None, execute_once=False): """Execute this Kernel over a ParticleSet for several timesteps""" particles = pset.data_accessor() for p in range(pset.size): particles.set_index(p) particles.set_state(ErrorCode.Evaluate) if abs(dt) < 1e-6 and not execute_once: logger.warning_once( "'dt' is too small, causing numerical accuracy limit problems. Please chose a higher 'dt' and rather scale the 'time' axis of the field accordingly. (related issue #762)" ) def remove_deleted(pset): """Utility to remove all particles that signalled deletion""" indices = pset.particle_data['state'] == ErrorCode.Delete if np.count_nonzero(indices) > 0 and output_file is not None: output_file.write(pset, endtime, deleted_only=indices) pset.remove_booleanvector(indices) if recovery is None: recovery = {} elif ErrorCode.ErrorOutOfBounds in recovery and ErrorCode.ErrorThroughSurface not in recovery: recovery[ErrorCode.ErrorThroughSurface] = recovery[ ErrorCode.ErrorOutOfBounds] recovery_map = recovery_base_map.copy() recovery_map.update(recovery) for g in pset.fieldset.gridset.grids: if len( g.load_chunk ) > 0: # not the case if a field in not called in the kernel g.load_chunk = np.where(g.load_chunk == 2, 3, g.load_chunk) # Execute the kernel over the particle set if self.ptype.uses_jit: self.execute_jit(pset, endtime, dt) else: self.execute_python(pset, endtime, dt) # Remove all particles that signalled deletion remove_deleted(pset) # Identify particles that threw errors error_particles = np.isin(pset.particle_data['state'], [ErrorCode.Success, ErrorCode.Evaluate], invert=True) while np.any(error_particles): # Apply recovery kernel for p in np.where(error_particles)[0]: particles.set_index(p) if particles.state == ErrorCode.StopExecution: return if particles.state == ErrorCode.Repeat: particles.set_state(ErrorCode.Evaluate) elif particles.state in recovery_map: recovery_kernel = recovery_map[particles.state] particles.set_state(ErrorCode.Success) recovery_kernel(particles, self.fieldset, particles.time) if particles.state == ErrorCode.Success: particles.set_state(ErrorCode.Evaluate) else: logger.warning_once( 'Deleting particle because of bug in #749 and #737') particles.delete() # Remove all particles that signalled deletion remove_deleted(pset) # Execute core loop again to continue interrupted particles if self.ptype.uses_jit: self.execute_jit(pset, endtime, dt) else: self.execute_python(pset, endtime, dt) error_particles = np.isin(pset.particle_data['state'], [ErrorCode.Success, ErrorCode.Evaluate], invert=True)
def execute(self, pset, endtime, dt, recovery=None, output_file=None): """Execute this Kernel over a ParticleSet for several timesteps""" def remove_deleted(pset): """Utility to remove all particles that signalled deletion""" indices = [ i for i, p in enumerate(pset.particles) if p.state in [ErrorCode.Delete] ] if len(indices) > 0 and output_file is not None: output_file.write(pset[indices], endtime, deleted_only=True) pset.remove(indices) if recovery is None: recovery = {} elif ErrorCode.ErrorOutOfBounds in recovery and ErrorCode.ErrorThroughSurface not in recovery: recovery[ErrorCode.ErrorThroughSurface] = recovery[ ErrorCode.ErrorOutOfBounds] recovery_map = recovery_base_map.copy() recovery_map.update(recovery) for g in pset.fieldset.gridset.grids: if len( g.load_chunk ) > 0: # not the case if a field in not called in the kernel g.load_chunk = np.where(g.load_chunk == 2, 3, g.load_chunk) # Execute the kernel over the particle set if self.ptype.uses_jit: self.execute_jit(pset, endtime, dt) else: self.execute_python(pset, endtime, dt) # Remove all particles that signalled deletion remove_deleted(pset) # Identify particles that threw errors error_particles = [ p for p in pset.particles if p.state != ErrorCode.Success ] while len(error_particles) > 0: # Apply recovery kernel for p in error_particles: if p.state == ErrorCode.Repeat: p.state = ErrorCode.Success elif p.state in recovery_map: # hotfix for #749, #737 and related issues recovery_kernel = recovery_map[p.state] p.state = ErrorCode.Success recovery_kernel(p, self.fieldset, p.time) else: logger.warning_once( 'Deleting particle because of bug in #749 and #737') p.delete() # Remove all particles that signalled deletion remove_deleted(pset) # Execute core loop again to continue interrupted particles if self.ptype.uses_jit: self.execute_jit(pset, endtime, dt) else: self.execute_python(pset, endtime, dt) error_particles = [ p for p in pset.particles if p.state != ErrorCode.Success ]