/// This function is not provided by AutoDiffBlock, so we must add it here. inline CollOfScalar sqrt(const CollOfScalar& x) { // d(sqrt(x))/dy = 1/(2*sqrt(x)) * dx/dy const auto& xjac = x.derivative(); if (xjac.empty()) { return CollOfScalar(sqrt(x.value())); } const int num_blocks = xjac.size(); std::vector<CollOfScalar::M> jac(num_blocks); const auto sqrt_x = sqrt(x.value()); const CollOfScalar::M one_over_two_sqrt_x((0.5/sqrt_x).matrix().asDiagonal()); for (int block = 0; block < num_blocks; ++block) { jac[block] = one_over_two_sqrt_x * xjac[block]; } return CollOfScalar::ADB::function(sqrt_x, jac); }
CollOfVector EquelleRuntimeCPU::centroid(const CollOfCell& cells) const { const int n = cells.size(); const int dim = grid_.dimensions; Eigen::Array<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor> c(n, dim); for (int i = 0; i < n; ++i) { const double* fc = grid_.cell_centroids + dim * cells[i].index; for (int d = 0; d < dim; ++d) { c(i, d) = fc[d]; } } CollOfVector centroids(dim); for (int d = 0; d < dim; ++d) { centroids.col(d) = CollOfScalar(c.col(d)); } return centroids; }
CollOfVector EquelleRuntimeCPU::normal(const CollOfFace& faces) const { const int n = faces.size(); const int dim = grid_.dimensions; Eigen::Array<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor> nor(n, dim); for (int i = 0; i < n; ++i) { const double* fn = grid_.face_normals + dim * faces[i].index; for (int d = 0; d < dim; ++d) { nor(i, d) = fn[d]; } } // Since the UnstructuredGrid uses the unorthodox convention that face // normals are scaled with the face areas, we must renormalize them. nor.colwise() /= nor.matrix().rowwise().norm().array(); CollOfVector normals(dim); for (int d = 0; d < dim; ++d) { normals.col(d) = CollOfScalar(nor.col(d)); } return normals; }