Please explain CFeeRate::GetFee(size_t nBytes) Referring to the function CAmount CFeeRate::GetFee(size_t nBytes_) in feerate.cpp: 

If I pass in say 2000 as the nBytes argument, what will this function return as the fee nFee? I don't understand how nSatoshisPerK is defined. Also, curious as to why this is used instead of letting miners determine this fee through selective mining.

CAmount CFeeRate::GetFee(size_t nBytes_) const
{
    assert(nBytes_ &lt;= uint64_t(std::numeric_limits&lt;int64_t&gt;::max()));
    int64_t nSize = int64_t(nBytes_);

    CAmount nFee = nSatoshisPerK * nSize / 1000;

    if (nFee == 0 &amp;&amp; nSize != 0) {
        if (nSatoshisPerK &gt; 0)
            nFee = CAmount(1);
        if (nSatoshisPerK &lt; 0)
            nFee = CAmount(-1);
    }

    return nFee;
}
If I pass in say 2000 as the nBytes argument, what will this function return as the fee nFee?


It depends on the fee rate that the CFeeRate object represents. The fee rate is denoted in Bitcoin per Kilobyte. So you pass in the number of bytes into GetFee and and calculates the amount in Bitcoin for the fee to be paid for something of size nBytes_.

If, for example, your CFeeRate object represents 0.00020000 Bitcoin per Kilobyte (or 20 satoshis per byte), giving 2000 as nBytes means that your fee will be 2000 * 0.0002 / 1000 = 0.0004 BTC.


  I don't understand how nSatoshisPerK is defined.


It is defined at the creation of the object. Whatever created the object specifies the fee rate to use.


  Also, curious as to why this is used instead of letting miners determine this fee through selective mining.


This is just an implementation detail, not an actual network thing that specifies the fee rate for everyone to use. CFeeRate is internal to Bitcoin Core and is simply just how fee rates are representing in internal logic. The fee rates themselves are constructed by the fee estimator which calculates fees based upon mined transactions.