Add div to specific sub-menu

The WordPress native Walker class doesn’t pass the arguments you need to the start_lvl() method. So to do this, you will need to add a custom display_element() method to your custom walker. You can use most of the original, with something similar to the commented section below:

public function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) {
    if ( ! $element ) {
        return;
    }

    $id_field = $this->db_fields['id'];
    $id       = $element->$id_field;

    //display this element
    $this->has_children = ! empty( $children_elements[ $id ] );
    if ( isset( $args[0] ) && is_array( $args[0] ) ) {
        $args[0]['has_children'] = $this->has_children; // Backwards compatibility.
    }

    $cb_args = array_merge( array( &$output, $element, $depth ), $args );
    call_user_func_array( array( $this, 'start_el' ), $cb_args );

    // descend only when the depth is right and there are childrens for this element
    if ( ( $max_depth == 0 || $max_depth > $depth + 1 ) && isset( $children_elements[ $id ] ) ) {

        foreach ( $children_elements[ $id ] as $child ) {

            if ( ! isset( $newlevel ) ) {
                $newlevel = true;
                //start the child delimiter
                $cb_args = array_merge( array( &$output, $depth ), $args );

                /** Additional check for custom addition of id to sub-level */
                if ( $element->post_name="Megatron" ) {
                    $cb_args['sub_menu_id'] = 'megatron';
                }
                /** End custom check */

                call_user_func_array( array( $this, 'start_lvl' ), $cb_args );
            }
            $this->display_element( $child, $children_elements, $max_depth, $depth + 1, $args, $output );
        }
        unset( $children_elements[ $id ] );
    }

    if ( isset( $newlevel ) && $newlevel ) {
        //end the child delimiter
        $cb_args = array_merge( array( &$output, $depth ), $args );
        call_user_func_array( array( $this, 'end_lvl' ), $cb_args );
    }

    //end this element
    $cb_args = array_merge( array( &$output, $element, $depth ), $args );
    call_user_func_array( array( $this, 'end_el' ), $cb_args );
}

The added code here checks for your main element name and then appends id information to the args that will be sent to start_lvl().

Now you can output the correct markup in your start_lvl() method with something like:

public function start_lvl( &$output, $depth = 0, $args = array(), $sub_menu_div = null ) {
    $indent = str_repeat("\t", $depth);
    if ( $sub_menu_div ) {
        $output .= "\n$indent<div id=\"$sub_menu_div\"><ul class=\"sub-menu\">\n";
    } else {
        $output .= "\n$indent<ul class=\"sub-menu\">\n";
    }
}

Hope that helps. Good luck!