result_t vec_cast(const source_t& source, typename detail::enable_if_c<!has_ptr_or_ref<result_t>::value>::type* = NULL){ return initial_values(source); }
// NB : matrix is passed in Column-Major storage. void lod_cn_travelling_wave(double* const inout_matrix, const int space_nb_x, const int space_nb_y, const double final_time, const double tau, const double eps) { double h_x = 1./((double)space_nb_x-1.), h_y = 1./((double)space_nb_y-1.); Eigen::VectorXd x_border, y_border, x(space_nb_x), y(space_nb_y); Eigen::MatrixXd values, after_x, after_y, after_reaction; Eigen::SparseMatrix<double> operator_x, operator_y, laplace_x, unit_matrix_x, laplace_y, unit_matrix_y; // Boundaries. x_border.setLinSpaced(space_nb_x, 0., 1.); y_border.setLinSpaced(space_nb_y, 0., 1.); // Initial values. initial_values(values, x_border, y_border, eps); // Operators initialization; laplace_operator_1d(laplace_x, space_nb_x); identity_operator(unit_matrix_x, space_nb_x); laplace_operator_1d(laplace_y, space_nb_y); identity_operator(unit_matrix_y, space_nb_y); space_operator(operator_x, laplace_x, (tau*eps)/(h_x*h_x), unit_matrix_x); space_operator(operator_y, laplace_y, (tau*eps)/(h_y*h_y), unit_matrix_y); #ifdef DEBUG_LOD_CN debug_print("init values", values, 5, 5); debug_print("laplace x", laplace_x, 5, 5); debug_print("I x", unit_matrix_x, 5, 5); debug_print("laplace y", laplace_y, 5, 5); debug_print("I y", unit_matrix_y, 5, 5); debug_print("Op x", operator_x, 5, 5); debug_print("Op y", operator_y, 5, 5); #endif double time = 0.; const double tcoeff = 1.; while (time < final_time) { // Step in x direction. // NB. Operators x and y are hermitian, so that we can commute them. // Apply an operator in x direction. #ifdef DEBUG_LOD_CN debug_print("values", values, 5, 5); #endif after_x = values*operator_x; bc_x(y, y_border, time, 0., eps); after_x.col(0) = y*tcoeff; bc_x(y, y_border, time, 1., eps); after_x.col(space_nb_x-1) = y*tcoeff; #ifdef DEBUG_LOD_CN debug_print("after_x", after_x, 5, 5); #endif // Apply an operator in y direction. after_y = operator_y*values; bc_y(x, x_border, time, 0., eps); after_y.row(0) = x.transpose()*tcoeff; bc_y(x, x_border, time, 1., eps); after_y.row(space_nb_y-1) = x.transpose()*tcoeff; #ifdef DEBUG_LOD_CN debug_print("after_y", after_y, 5, 5); #endif // Apply the reaction operator. auto transform = ::boost::bind(reaction_operator, _1, tau/eps); after_reaction = after_y+after_y.unaryExpr(transform); #ifdef DEBUG_LOD_CN debug_print("after_reaction", after_reaction, 5, 5); #endif // Time advance. time += tau; // Second application of an operator in y direction. after_y = operator_y*after_reaction; bc_y(x, x_border, time, 0., eps); after_y.row(0) = x.transpose()*tcoeff; bc_y(x, x_border, time, 1., eps); after_y.row(space_nb_y-1) = x.transpose()*tcoeff; #ifdef DEBUG_LOD_CN debug_print("after_y", after_y, 5, 5); #endif // Second application of an operator in x direction. values = after_y*operator_x; bc_x(y, y_border, time, 0., eps); values.col(0) = y*tcoeff; bc_x(y, y_border, time, 1., eps); values.col(space_nb_x-1) = y*tcoeff; } // Copy to the return value. memcpy(inout_matrix, values.data(), space_nb_x*space_nb_y*sizeof(double)); }