Sort query output on taxonomy term archive by post type using pre_get_posts

You should have a look at this answer.

Group by isn’t what you want. WordPress, by default, groups by post ID to eliminate duplicate posts from the list. Since you’ll need to group by ID and post_type, there will always be only a single combination of post_type and ID (your group by will do nothing, in other words).

Instead of hooking into post_groupby use posts_orderby. And you add an order by post type, even getting really granular with a SQL FIELD function:

<?php
add_filter('posts_orderby', 'wpse87578_posts_orderby', 10, 2);
function wpse87578_posts_orderby($orderby, $query)
{
    global $wpdb;

    if (is_admin() || !$query->is_main_query() || !is_tax()) {
        return $orderby;
    }

    $new = "FIELD({$wpdb->posts}.post_type, 'profile', 'page', 'post', 'letter') ASC";

    if ($orderby) {
        $orderby = $new . ', ' . $orderby;
    } else {
        $orderby = $new;
    }

    return $orderby;
}