Loop repeating design pattern

You could use 3 separate loops, and break out of each loop early once you’ve got enough posts.

For example, here is a 2 column grid with a single query:

$q = new WP_Query( ... );

if ( $q->have_posts() ) {
    ?>
    <div class="columns">
        <div>
            <?php
            $counter = 0;
            while( $q->have_posts() ) {
                $q->the_post();
                the_title();
                $counter++;
                if ( $counter === $q->post_count/2 ) {
                    break;
                }
            }
            ?>
        </div>
        <div>
            <?php
            $counter = 0;
            while( $q->have_posts() ) {
                $q->the_post();
                the_title();
                $counter++;
                if ( $counter === $q->post_count/2 ) {
                    break;
                }
            }
            ?>
        </div>
    </div>
    <?php
} else {
    echo 'No posts found';
}

Notice how I counted each post as it was displayed, then exited the loop early when the counter was halfway through?

Arbitrary Columns

Note that here the columns are all of the same design, and the conditional check has been changed.

$q = new WP_Query( ... );

if ( $q->have_posts() ) {
    ?>
    <div class="columns">
        <?php
        $columns = 2;
        for ( $i = 1; $i < $columns; $i++ ) {
            echo '<div>';
            $counter = 0;
            while ( $q->have_posts() ) {
                $q->the_post();
                get_template_part( 'column','post' );
                $counter++;
                if ( $counter > $q->post_count/$columns ) {
                    break;
                }
            }
            echo '</div>';
        }
        ?>
    </div>
    <?php
} else {
    echo 'No posts found';
}

Note the get_template_part call, simplifying the template.

With these 2 examples, and some basic math you can turn these into any combination of columns

Alternatively, have rows of posts floated to the left and make each post 50% width or fixed width, using CSS to avoid PHP entirely