Пример #1
0
    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
            ]
Пример #2
0
    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)
Пример #3
0
    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
            ]