Binary &Op是什麼

2023-02-26 12:00:29

前言

在並行開發時我們經常會用到Pstream::gather()函數或是全域性函數reduce()或者其他,需要輸入引數Binary &Op,本篇主要討論Binary &Op是什麼

template<class T, class BinaryOp>
void reduce
(
    T& Value,
    const BinaryOp& bop, // 這裡要輸入什麼引數
    const int tag,
    const label comm,
    label& request
)
{
    NotImplemented;
}

Binary &Op

單從名字上看,猜是一個二進位制的操作,類似一組操作返回一個二進位制的標記
然後去openfoam官網去找,找不到Binary &Op的任何釋義
去網上找,發現了一點端倪
c++標準庫中有應用Binary &Op這個輸入引數,使用的函數也叫reduce,詳情可見該網頁

這裡順便說幾個學習C++不錯的網址,查詢起來很方便

https://en.cppreference.com/w/
https://learncpp-cn.github.io/
https://cplusplus.com/
https://www.tutorialspoint.com/index.htm
https://awesome-cpp.readthedocs.io/en/latest/README.html#
https://stackoverflow.org.cn/

標準庫對輸入引數binary_op的解釋是:
將以未指定順序應用於解除參照輸入迭代器結果、其他 binary_op 結果及 init 上的二元函數物件 (FunctionObject) 。
我們再看下類似的std::transform,詳情可見該網頁
可能實現的版本有

template<class InputIt1, class InputIt2, 
         class OutputIt, class BinaryOperation>
OutputIt transform(InputIt1 first1, InputIt1 last1, InputIt2 first2, 
                   OutputIt d_first, BinaryOperation binary_op)
{
    while (first1 != last1) {
        *d_first++ = binary_op(*first1++, *first2++);
    }
    return d_first;
}

在這個程式中我們看到輸入的引數可以傳的引數可以函數指標,也可以是仿函數,而且這個仿函數需要傳兩個引數,按要求送達至返回值中
但按照C++的風格更喜歡是仿函數了
所以我們經常能看到類似這樣的函數使用模式

#include <iostream>
#include <functional>
#include <algorithm>

int main () {
   bool foo[] = {true,true,false,false};
   bool bar[] = {true,false,true,false};
   bool result[4];
   std::transform (foo, foo+4, bar, result, std::logical_or<bool>());
   std::cout << std::boolalpha << "Logical OR example as shown below:\n";
   for (int i=0; i<4; i++)
      std::cout << foo[i] << " OR " << bar[i] << " = " << result[i] << "\n";
   return 0;
}

以下是輸出結果:

Logical OR example as shown below:
true OR true = true
true OR false = true
false OR true = true
false OR false = false

那麼我類似的把std::logical_or()放到openfoam的reduce函數裡可不可以呢
答案是可以的

當然啊,std::logical_or()放到reduce函數中是沒什麼意義的,但是我們這就可以清楚,我們需要寫怎麼樣的函數,或者函數指標傳送到Binary &Op引數中

對於reduce而言,在ops.H中內建了很豐富的仿函數以供呼叫

Op(sum, x + y)
Op(plus, x + y)
Op(minus, x - y)
Op(multiply, x * y)
Op(divide, x / y)
Op(cmptMultiply, cmptMultiply(x, y))
Op(cmptPow, cmptPow(x, y))
Op(cmptDivide, cmptDivide(x, y))
Op(stabilise, stabilise(x, y))
Op(max, max(x, y))
Op(min, min(x, y))
Op(minMagSqr, (magSqr(x)<=magSqr(y) ? x : y))
Op(maxMagSqr, (magSqr(x)>=magSqr(y) ? x : y))
Op(minMod, minMod(x, y))
Op(and, x && y)
Op(or, x || y)
Op(not, x != y)
Op(eqEq, x == y)
Op(less, x < y)
Op(lessEq, x <= y)
Op(greater, x > y)
Op(greaterEq, x >= y)

如果想寫自己的Binary &Op操作,可以在ops.H的基礎上去建立,要輕鬆很多


結語

一起探索openfoam也是相當有趣的一件事,非常歡迎私信討論
指正的價值要比打賞更重要,下面是個人聯絡方式,希望能結交到志同道合的朋友