25 using namespace solver;
26 using namespace time_integrator;
30 assert(!
problem->is_time_dependent());
31 assert(
assembler->name() ==
"NavierStokes");
37 std::shared_ptr<assembler::Assembler> velocity_stokes_assembler = std::make_shared<assembler::StokesVelocity>();
45 *velocity_stokes_assembler,
62 user_post_step(step, *
this, sol,
nullptr, &pressure);
68 assert(
assembler->name() ==
"OperatorSplitting" &&
problem->is_time_dependent());
70 Eigen::MatrixXd local_pts;
72 if (
mesh->dimension() == 2)
74 if (gbases[0].
bases.size() == 3)
81 if (gbases[0].
bases.size() == 4)
87 std::vector<int> bnd_nodes;
91 if (!(*it %
mesh->dimension()))
93 bnd_nodes.push_back(*it /
mesh->dimension());
96 const int dim =
mesh->dimension();
97 const int n_el = int(
bases.size());
98 const int shape = gbases[0].bases.size();
100 auto fluid_assembler = std::dynamic_pointer_cast<assembler::OperatorSplitting>(
assembler);
101 if (!fluid_assembler)
104 double viscosity_ = fluid_assembler->viscosity()(0, 0, 0, 0, 0);
105 assert(viscosity_ >= 0);
107 logger().info(
"Matrices assembly...");
108 StiffnessMatrix stiffness_viscosity, mixed_stiffness, velocity_mass, stiffness;
126 mixed_stiffness = mixed_stiffness.transpose();
127 logger().info(
"Matrices assembly ends!");
131 stiffness_viscosity, stiffness, velocity_mass, dt, viscosity_,
args[
"solver"][
"linear"]);
139 user_post_step(0, *
this, sol,
nullptr, &pressure);
143 for (
int t = 1; t <= time_steps; t++)
145 double time = t * dt;
146 logger().info(
"{}/{} steps, t={}s", t, time_steps, time);
149 logger().info(
"Advection...");
150 if (
args[
"space"][
"advanced"][
"use_particle_advection"])
154 logger().info(
"Advection finished!");
161 logger().info(
"Solving diffusion...");
164 logger().info(
"Diffusion solved!");
170 logger().info(
"Pressure projection...");
175 logger().info(
"Pressure projection finished!");
177 pressure = pressure / dt;
188 user_post_step(t, *
this, sol,
nullptr, &pressure);
195 assert(
assembler->name() ==
"NavierStokes" &&
problem->is_time_dependent());
198 Eigen::MatrixXd current_rhs =
rhs;
204 StiffnessMatrix velocity_stiffness, mixed_stiffness, pressure_stiffness;
206 Eigen::VectorXd prev_sol;
209 if (
args[
"time"][
"integrator"].is_object() &&
args[
"time"][
"integrator"][
"type"] ==
"BDF")
211 time_integrator.
init(sol, Eigen::VectorXd::Zero(sol.size()), Eigen::VectorXd::Zero(sol.size()), dt);
213 std::shared_ptr<assembler::Assembler> velocity_stokes_assembler = std::make_shared<assembler::StokesVelocity>();
230 user_post_step(0, *
this, sol,
nullptr, &pressure);
233 for (
int t = 1; t <= time_steps; ++t)
235 double time = t0 + t * dt;
236 double current_dt = dt;
240 logger().info(
"{}/{} steps, dt={}s t={}s", t, time_steps, current_dt, time);
248 const int prev_size = current_rhs.size();
249 if (prev_size !=
rhs.size())
251 current_rhs.conservativeResize(prev_size + n_larger, current_rhs.cols());
252 current_rhs.block(prev_size, 0, n_larger, current_rhs.cols()).setZero();
255 Eigen::VectorXd tmp_sol;
267 pressure_stiffness, velocity_mass, current_rhs, tmp_sol);
276 user_post_step(t, *
this, sol,
nullptr, &pressure);
void solve_navier_stokes(int step, Eigen::MatrixXd &sol, Eigen::MatrixXd &pressure, UserPostStepCallback user_post_step={})
solves a navier stokes
int n_bases
number of bases
int n_pressure_bases
number of pressure bases
assembler::AssemblyValsCache ass_vals_cache
used to store assembly values for small problems
const std::vector< basis::ElementBases > & geom_bases() const
Get a constant reference to the geometry mapping bases.
void sol_to_pressure(Eigen::MatrixXd &sol, Eigen::MatrixXd &pressure)
splits the solution in solution and pressure for mixed problems
std::shared_ptr< assembler::Assembler > assembler
assemblers
bool use_avg_pressure
use average pressure for stokes problem to fix the additional dofs, true by default if false,...
void set_materials(std::vector< std::shared_ptr< assembler::Assembler > > &assemblers) const
set the material and the problem dimension
std::vector< int > pressure_boundary_nodes
list of neumann boundary nodes
void save_timestep(const double time, const int t, const double t0, const double dt, const Eigen::MatrixXd &sol, const Eigen::MatrixXd &pressure)
saves a timestep
std::vector< basis::ElementBases > pressure_bases
FE pressure bases for mixed elements, the size is #elements.
std::shared_ptr< assembler::Assembler > pressure_assembler
std::shared_ptr< assembler::Mass > mass_matrix_assembler
std::unique_ptr< mesh::Mesh > mesh
current mesh, it can be a Mesh2D or Mesh3D
StiffnessMatrix mass
Mass matrix, it is computed only for time dependent problems.
std::shared_ptr< assembler::Problem > problem
current problem, it contains rhs and bc
json args
main input arguments containing all defaults
std::vector< basis::ElementBases > bases
FE bases, the size is #elements.
void solve_transient_navier_stokes_split(const int time_steps, const double dt, Eigen::MatrixXd &sol, Eigen::MatrixXd &pressure, UserPostStepCallback user_post_step={})
solves transient navier stokes with operator splitting
assembler::AssemblyValsCache pressure_ass_vals_cache
used to store assembly values for pressure for small problems
void build_stiffness_mat(StiffnessMatrix &stiffness)
utility that builds the stiffness matrix and collects stats, used only for linear problems
std::vector< mesh::LocalBoundary > local_boundary
mapping from elements to nodes for dirichlet boundary conditions
QuadratureOrders n_boundary_samples() const
quadrature used for projecting boundary conditions
assembler::AssemblyValsCache mass_ass_vals_cache
std::vector< int > boundary_nodes
list of boundary nodes
solver::SolveData solve_data
timedependent stuff cached
void solve_transient_navier_stokes(const int time_steps, const double t0, const double dt, Eigen::MatrixXd &sol, Eigen::MatrixXd &pressure, UserPostStepCallback user_post_step={})
solves transient navier stokes with FEM
std::vector< mesh::LocalBoundary > local_neumann_boundary
mapping from elements to nodes for neumann boundary conditions
std::shared_ptr< assembler::MixedAssembler > mixed_assembler
Eigen::MatrixXd rhs
System right-hand side.
virtual void set_size(const int size)
Eigen::Matrix< double, Eigen::Dynamic, 1, 0, 9, 1 > assemble(const LinearAssemblerData &data) const override
computes local stiffness matrix (1x1) for bases i,j where i,j is passed in through data ie integral o...
void minimize(const int n_bases, const int n_pressure_bases, const std::vector< basis::ElementBases > &bases, const std::vector< basis::ElementBases > &pressure_bases, const std::vector< basis::ElementBases > &gbases, const assembler::Assembler &velocity_stokes_assembler, assembler::NavierStokesVelocity &velocity_assembler, const assembler::MixedAssembler &mixed_assembler, const assembler::Assembler &pressure_assembler, const assembler::AssemblyValsCache &ass_vals_cache, const assembler::AssemblyValsCache &pressure_ass_vals_cache, const std::vector< int > &boundary_nodes, const bool use_avg_pressure, const int problem_dim, const bool is_volume, const Eigen::MatrixXd &rhs, Eigen::VectorXd &x)
void solve_pressure(const StiffnessMatrix &mixed_stiffness, const std::vector< int > &pressure_boundary_nodes, Eigen::MatrixXd &sol, Eigen::MatrixXd &pressure)
void projection(const StiffnessMatrix &velocity_mass, const StiffnessMatrix &mixed_stiffness, const std::vector< int > &boundary_nodes_, Eigen::MatrixXd &sol, const Eigen::MatrixXd &pressure)
void external_force(const mesh::Mesh &mesh, const assembler::Assembler &assembler, const std::vector< basis::ElementBases > &gbases, const std::vector< basis::ElementBases > &bases, const double dt, Eigen::MatrixXd &sol, const Eigen::MatrixXd &local_pts, const std::shared_ptr< assembler::Problem > problem, const double time)
void advection(const mesh::Mesh &mesh, const std::vector< basis::ElementBases > &gbases, const std::vector< basis::ElementBases > &bases, Eigen::MatrixXd &sol, const double dt, const Eigen::MatrixXd &local_pts, const int order=1, const int RK=1)
void advection_FLIP(const mesh::Mesh &mesh, const std::vector< basis::ElementBases > &gbases, const std::vector< basis::ElementBases > &bases, Eigen::MatrixXd &sol, const double dt, const Eigen::MatrixXd &local_pts, const int order=1)
void solve_diffusion_1st(const StiffnessMatrix &mass, const std::vector< int > &bnd_nodes, Eigen::MatrixXd &sol)
std::shared_ptr< assembler::RhsAssembler > rhs_assembler
void minimize(const int n_bases, const int n_pressure_bases, const double t, const std::vector< basis::ElementBases > &bases, const std::vector< basis::ElementBases > &gbases, assembler::NavierStokesVelocity &velocity_assembler, const assembler::AssemblyValsCache &ass_vals_cache, const std::vector< int > &boundary_nodes, const bool use_avg_pressure, const int problem_dim, const bool is_volume, const double beta_dt, const Eigen::VectorXd &prev_sol, const StiffnessMatrix &velocity_stiffness, const StiffnessMatrix &mixed_stiffness, const StiffnessMatrix &pressure_stiffness, const StiffnessMatrix &velocity_mass1, const Eigen::MatrixXd &rhs, Eigen::VectorXd &x)
Backward Differential Formulas.
void set_parameters(const json ¶ms) override
Set the number of steps parameters from a json object.
Eigen::VectorXd weighted_sum_x_prevs() const
Compute the weighted sum of the previous solutions.
void update_quantities(const Eigen::VectorXd &x) override
Update the time integration quantities (i.e., , , and ).
double acceleration_scaling() const override
Compute the acceleration scaling used to scale forces when integrating a second order ODE.
virtual void init(const Eigen::MatrixXd &x_prevs, const Eigen::MatrixXd &v_prevs, const Eigen::MatrixXd &a_prevs, double dt)
Initialize the time integrator with the previous values for , , and .
void q_nodes_2d(const int q, Eigen::MatrixXd &val)
void p_nodes_2d(const int p, Eigen::MatrixXd &val)
void p_nodes_3d(const int p, Eigen::MatrixXd &val)
void q_nodes_3d(const int q, Eigen::MatrixXd &val)
spdlog::logger & logger()
Retrieves the current logger.
std::array< int, 2 > QuadratureOrders
std::function< void(int step, State &state, const Eigen::MatrixXd &sol, const Eigen::MatrixXd *disp_grad, const Eigen::MatrixXd *pressure)> UserPostStepCallback
User callback at the end of every solver step.
void log_and_throw_error(const std::string &msg)
Eigen::SparseMatrix< double, Eigen::ColMajor > StiffnessMatrix