17 using namespace solver;
18 using namespace time_integrator;
22 assert(!
problem->is_time_dependent());
23 assert(
assembler->name() ==
"NavierStokes");
29 std::shared_ptr<assembler::Assembler> velocity_stokes_assembler = std::make_shared<assembler::StokesVelocity>();
37 *velocity_stokes_assembler,
55 assert(
assembler->name() ==
"OperatorSplitting" &&
problem->is_time_dependent());
57 Eigen::MatrixXd local_pts;
59 if (
mesh->dimension() == 2)
61 if (gbases[0].
bases.size() == 3)
68 if (gbases[0].
bases.size() == 4)
74 std::vector<int> bnd_nodes;
78 if (!(*it %
mesh->dimension()))
80 bnd_nodes.push_back(*it /
mesh->dimension());
83 const int dim =
mesh->dimension();
84 const int n_el = int(
bases.size());
85 const int shape = gbases[0].bases.size();
87 auto fluid_assembler = std::dynamic_pointer_cast<assembler::OperatorSplitting>(
assembler);
91 double viscosity_ = fluid_assembler->viscosity()(0, 0, 0, 0, 0);
92 assert(viscosity_ >= 0);
94 logger().info(
"Matrices assembly...");
95 StiffnessMatrix stiffness_viscosity, mixed_stiffness, velocity_mass, stiffness;
113 mixed_stiffness = mixed_stiffness.transpose();
114 logger().info(
"Matrices assembly ends!");
118 stiffness_viscosity, stiffness, velocity_mass, dt, viscosity_,
args[
"solver"][
"linear"]);
124 for (
int t = 1; t <= time_steps; t++)
126 double time = t * dt;
127 logger().info(
"{}/{} steps, t={}s", t, time_steps, time);
130 logger().info(
"Advection...");
131 if (
args[
"space"][
"advanced"][
"use_particle_advection"])
135 logger().info(
"Advection finished!");
142 logger().info(
"Solving diffusion...");
145 logger().info(
"Diffusion solved!");
151 logger().info(
"Pressure projection...");
156 logger().info(
"Pressure projection finished!");
158 pressure = pressure / dt;
171 assert(
assembler->name() ==
"NavierStokes" &&
problem->is_time_dependent());
174 Eigen::MatrixXd current_rhs =
rhs;
180 StiffnessMatrix velocity_stiffness, mixed_stiffness, pressure_stiffness;
182 Eigen::VectorXd prev_sol;
185 if (
args[
"time"][
"integrator"].is_object() &&
args[
"time"][
"integrator"][
"type"] ==
"BDF")
187 time_integrator.
init(sol, Eigen::VectorXd::Zero(sol.size()), Eigen::VectorXd::Zero(sol.size()), dt);
189 std::shared_ptr<assembler::Assembler> velocity_stokes_assembler = std::make_shared<assembler::StokesVelocity>();
202 for (
int t = 1; t <= time_steps; ++t)
204 double time = t0 + t * dt;
205 double current_dt = dt;
209 logger().info(
"{}/{} steps, dt={}s t={}s", t, time_steps, current_dt, time);
217 const int prev_size = current_rhs.size();
218 if (prev_size !=
rhs.size())
220 current_rhs.conservativeResize(prev_size + n_larger, current_rhs.cols());
221 current_rhs.block(prev_size, 0, n_larger, current_rhs.cols()).setZero();
224 Eigen::VectorXd tmp_sol;
236 pressure_stiffness, velocity_mass, current_rhs, tmp_sol);
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
int n_boundary_samples() const
quadrature used for projecting boundary conditions
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.
void solve_navier_stokes(Eigen::MatrixXd &sol, Eigen::MatrixXd &pressure)
solves a navier stokes
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)
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
void solve_transient_navier_stokes(const int time_steps, const double t0, const double dt, Eigen::MatrixXd &sol, Eigen::MatrixXd &pressure)
solves transient navier stokes with FEM
assembler::AssemblyValsCache mass_ass_vals_cache
std::vector< int > boundary_nodes
list of boundary nodes
solver::SolveData solve_data
timedependent stuff cached
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.
void log_and_throw_error(const std::string &msg)
Eigen::SparseMatrix< double, Eigen::ColMajor > StiffnessMatrix