I'm mostly used to writing scientific code in MATLAB / Python / Julia and my experience with C++ is very limited. I've implemented a fairly simple computation of the Rotne-Prager-Yamakawa tensor in dimensionless form using the Eigen library in C++11 (currently using the Visual Studio toolchain).
#include <iostream>
#include <random>
#include <chrono>
#include <Eigen/Dense>
using namespace Eigen;
using namespace std;
using namespace std::chrono;
MatrixXd rotne_prager(Vector3d coords[], double r, const int p)
{
MatrixXd rpy = MatrixXd::Zero(3 * (p + 1), 3 * (p + 1));
Vector3d rvec;
double Rij;
double distance_ratio;
for (int i = 0; i < p + 1; i++)
{
for (int j = 0; j < p + 1; j++)
{
rvec(0) = coords[j](0) - coords[i](0);
rvec(1) = coords[j](1) - coords[i](1);
rvec(2) = coords[j](2) - coords[i](2);
Rij = sqrt(rvec(0)*rvec(0) + rvec(1)*rvec(1) + rvec(2)*rvec(2));
distance_ratio = r / Rij;
if (Rij > 2 * r)
{
rpy.block<3, 3>(3 * (i + 1) - 3, 3 * (j + 1) - 3) = 0.75 * distance_ratio * (1.0 - 2.0*distance_ratio * distance_ratio) * rvec * rvec.transpose();
rpy.block<3, 3>(3 * (i + 1) - 3, 3 * (j + 1) - 3).diagonal().array() += 0.75 * distance_ratio * (1.0 + 2.0 / 3.0 * distance_ratio * distance_ratio);
}
else
{
rpy.block<3, 3>(3 * (i + 1) - 3, 3 * (j + 1) - 3) = 3.0 / 32.0 / distance_ratio * rvec*rvec.transpose();
rpy.block<3, 3>(3 * (i + 1) - 3, 3 * (j + 1) - 3).diagonal().array() += 1.0 - 9.0 / 32.0 / distance_ratio;
}
}
}
return rpy;
}
int main()
{
random_device rd;
mt19937 gen(rd());
uniform_real_distribution<> dis(0, 1);
Eigen::setNbThreads(8);
auto start = high_resolution_clock::now();
const int p = 4000;
Vector3d coords[p + 1];
for (int i = 0; i < p + 1; i++)
{
coords[i](0) = dis(gen); coords[i](1) = dis(gen); coords[i](2) = dis(gen);
}
MatrixXd rpy = rotne_prager(coords, 0.01, p);
auto end = high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
cout << "p = " << p << ", time elapsed: " << duration << " ms" << endl;
}
The code produces correct results, but I'm sure it could have been written much better. I'd appreciate any performance optimization tips as well as any suggestions about writing more idiomatic (insofar as that term even applies in the C++ world) and concise code.