Query against partitioned table accessing more partitions than necessary?
These trivial queries are automatically parameterized. As such, the literal values are replaced with parameters during compilation. Partitions are eliminated at runtime dynamically using the internal RangePartitonNew function in a range seek predicate. Importantly, the seek predicate start/end range is inclusive so that the same cached plan can be reused for any possible value, not just exact boundary matches as in your queries. Rows are subsequently filtered based on the WHERE clause predicate to return only the rows desired.
Below is the seek predicate from the first 2 queries. At run time, the first query seek is equivilent to partition_number &gt;= 1 AND partition_number &lt;= 1 and the second is partition_number &gt;= 1 AND partition_number &lt;= 2. Partition 1 is hard-coded as the start range due to the less than operator.
Seek Keys[1]: 
    Start: PtnId1001 &gt;= Scalar Operator((1)),
    End: PtnId1001 &lt;= Scalar Operator(RangePartitionNew(CONVERT(datetime2(0),[@1],0),(1),'2020-01-01 00:00:00','2021-01-01 00:00:00'))

The seek predicate from the third query differs only in that the start range also includes RangePartitionNew to eliminate partitions excluded by the greater than or equal to comparison operator. This seek is equivilent to predicate partition_number &gt;= 2 AND partition_number &lt;= 3.
Seek Keys[1]: 
    Start: PtnId1001 &gt;= Scalar Operator(RangePartitionNew(CONVERT(datetime2(0),[@1],0),(1),'2020-01-01 00:00:00','2021-01-01 00:00:00')),
        End: PtnId1001 &lt;= Scalar Operator(RangePartitionNew(CONVERT(datetime2(0),[@2],0),(1),'2020-01-01 00:00:00','2021-01-01 00:00:00'))

You can avoid simple parameterization with these techniques from Paul's blog article:

OPTION (RECOMPILE)
Add a dummy predicate like WHERE 1 &lt;&gt; 2

If exact boundary values are your only use case, you could add a predicate to evaluate the partition function with a less than comparison operator. This will retain parameterization benefits. For example:
AND $PARTITION.partfun(logdate) &lt; $PARTITION.partfun('20200101')

The resultant parameterized plan seek predicate subtracts one from the end of the boundary range to eliminate the partition excluded by the above predicate:
Seek Keys[1]: 
    Start: PtnId1001 &gt;= Scalar Operator((1)), 
    End: PtnId1001 &lt;= Scalar Operator(RangePartitionNew(CONVERT_IMPLICIT(datetime2(0),[@2],0),(1),'2020-01-01 00:00:00','2021-01-01 00:00:00')-(1))

Note that an index on the partitioning column will mitigate the need for these work-arounds. Even though an extra partition will be touched with exact boundary values, the overhead is only a couple of additional logical reads.