PolyFEM
Loading...
Searching...
No Matches
DifferentiableNonlinearElasticVarForm.cpp
Go to the documentation of this file.
2
12
13#include <igl/Timer.h>
14
15#include <polysolve/linear/Solver.hpp>
16#include <polysolve/nonlinear/Solver.hpp>
17
18namespace polyfem::varform
19{
21 Eigen::MatrixXd &solution,
22 const InitialConditionOverride *initial_condition_override,
23 const ForwardStepCallback &post_step,
24 const bool differentiable)
25 {
26 differentiable_mode_ = differentiable;
27 NonlinearElasticVarForm::solve(solution, initial_condition_override, post_step);
28 }
29
34
36 {
37 if (args["geometry"].size() != 1)
38 {
39 log_and_throw_error("Mesh replacement requires one FEM geometry.");
40 }
41
42 json updated_args = args;
43 // Generated vertices already include physical scaling; do not reapply the input geometry transform or refinement.
44 updated_args["geometry"][0]["mesh"] = std::filesystem::absolute(path).string();
45 updated_args["geometry"][0]["unit"] = "";
46 updated_args["geometry"][0]["n_refs"] = 0;
47 updated_args["geometry"][0]["advanced"]["normalize_mesh"] = false;
48 updated_args["geometry"][0]["transformation"] = {
49 {"dimensions", nullptr}, {"scale", 1}, {"rotation", nullptr}, {"rotation_mode", "xyz"}, {"translation", json::array()}};
50 updated_args["contact"]["_dhat_was_explicit"] = contact_dhat_was_explicit_;
51 const io::FileSystemIO generated_resources(resources_.host_directory());
52 auto updated_mesh = mesh::GeometryLoader(units, generated_resources).load_fem(updated_args["geometry"]);
53 const std::string formulation = primary_assembler_->name();
54 const Units saved_units = units;
55 const std::string saved_output_path = output_path;
56 // Destroy forms before rebuilding the data they reference; preserve this object's identity for objective references.
57 forms.clear();
59 NonlinearElasticVarForm::init(formulation, saved_units, updated_args, saved_output_path);
60 set_mesh(std::move(updated_mesh));
61 }
62
64 const std::string &path,
65 const Eigen::MatrixXd &solution,
66 const double time,
67 const double dt) const
68 {
71 const auto opts = NonlinearElasticVarForm::export_options(space);
73 path, space, NonlinearElasticVarForm::output_field_function(solution, opts), time, dt, opts);
74 }
75
78
80 {
81 assert(mesh_ && "The mesh must be loaded before it is accessed");
82 return *mesh_;
83 }
84
86 {
87 assert(problem && "The problem must be initialized before it is accessed");
88 return *problem;
89 }
90
92 {
93 assert(problem && "The problem must be initialized before it is accessed");
94 return *problem;
95 }
96
97 std::string DifferentiableNonlinearElasticVarForm::output_file_path(const std::string &path) const
98 {
100 }
101
104
107
109 {
110 assert(primary_assembler_ && "The primary assembler must be initialized before it is accessed");
111 return *primary_assembler_;
112 }
113
115 {
116 assert(mass_assembler_ && "The mass assembler must be initialized before it is accessed");
117 return *mass_assembler_;
118 }
119
125 const ipc::CollisionMesh &DifferentiableNonlinearElasticVarForm::collision_mesh() const { return collision_mesh_; }
127
132
137
139 Eigen::MatrixXd &solution,
140 const InitialConditionOverride *override) const
141 {
143 }
144
146 Eigen::MatrixXd &velocity,
147 const InitialConditionOverride *override) const
148 {
150 }
151
153 Eigen::MatrixXd &acceleration,
154 const InitialConditionOverride *override) const
155 {
156 NonlinearElasticVarForm::initial_acceleration(acceleration, override);
157 }
158
165
167 {
168 assert(mesh_ && "Vertex positions can only be updated after loading a mesh");
169 return *mesh_;
170 }
171
185
198
200 const int discr_order,
201 const int discr_orderq,
202 const int geometry_discr_order) const
203 {
204 return NonlinearElasticVarForm::n_boundary_samples(discr_order, discr_orderq, geometry_discr_order);
205 }
206
207 // The differentiable path matches NonlinearElasticVarForm::init_forms except
208 // that it enables IPC shape derivatives when constructing the contact forms.
210 const json &args,
211 const int dim,
212 Eigen::MatrixXd &solution,
213 const double time)
214 {
216 {
217 NonlinearElasticVarForm::init_forms(args, dim, solution, time);
218 return;
219 }
220
221 damping_assembler_ = std::make_shared<assembler::ViscousDamping>();
222 set_materials(*damping_assembler_, mesh_->dimension());
223
225
226 damping_prev_assembler_ = std::make_shared<assembler::ViscousDampingPrev>();
228
229 const solver::ElementInversionCheck check_inversion = args["solver"]["advanced"]["check_inversion"];
230
232 units,
234 dim, time, space_.space_in_node_to_node,
235 space_.n_bases, *space_.bases, space_.geometry_basis_list(), *primary_assembler_, ass_vals_cache_, mass_ass_vals_cache_, args["solver"]["advanced"]["jacobian_threshold"], check_inversion,
236 args["solver"]["advanced"]["conservative_max_iter"],
239 elastic_boundary_samples(), rhs_, solution, mass_assembler_->density(),
241 args.value("/time/quasistatic"_json_pointer, true), mass_,
242 damping_assembler_->is_valid() ? damping_assembler_ : nullptr,
243 args["solver"]["advanced"]["lagged_regularization_weight"],
244 args["solver"]["advanced"]["lagged_regularization_iterations"],
245 obstacle.ndof(), args["constraints"]["hard"], args["constraints"]["soft"], args["constraints"]["zero_mean"],
246 args["contact"]["enabled"],
247 args["contact"]["periodic"] ? periodic_collision_mesh_ : collision_mesh_,
248 args["contact"]["dhat"],
249 avg_mass_, args["contact"]["use_convergent_formulation"] ? bool(args["contact"]["use_area_weighting"]) : false,
250 args["contact"]["use_convergent_formulation"] ? bool(args["contact"]["use_improved_max_operator"]) : false,
251 args["contact"]["use_convergent_formulation"] ? bool(args["contact"]["use_physical_barrier"]) : false,
252 args["contact"]["collision_set_type"].get<std::string>(),
253 args["contact"]["skip_obstacles"].get<bool>(),
254 args["contact"]["barrier"].get<std::string>(),
255 args["solver"]["contact"]["barrier_stiffness"],
256 args["solver"]["contact"]["initial_barrier_stiffness"],
257 args["solver"]["contact"]["dhat_epsilon_scale"],
258 args["solver"]["contact"]["CCD"]["broad_phase"],
259 args["solver"]["contact"]["CCD"]["tolerance"],
260 args["solver"]["contact"]["CCD"]["max_iterations"],
261 true,
262 args["contact"]["use_gcp_formulation"],
263 args["contact"]["alpha_t"],
264 args["contact"]["alpha_n"],
265 args["contact"]["use_adaptive_dhat"],
266 args["contact"]["min_distance_ratio"],
267 args["contact"]["use_esp_formulation"],
268 args["contact"]["esp_params"],
269 args["contact"]["adhesion"]["adhesion_enabled"],
270 args["contact"]["adhesion"]["dhat_p"],
271 args["contact"]["adhesion"]["dhat_a"],
272 args["contact"]["adhesion"]["adhesion_strength"],
273 args["contact"]["adhesion"]["tangential_adhesion_coefficient"],
274 args["contact"]["adhesion"]["epsa"],
275 args["solver"]["contact"]["tangential_adhesion_iterations"],
277 args["contact"]["periodic"], periodic_collision_mesh_to_basis_,
278 args["contact"]["friction_coefficient"],
279 args["contact"]["epsv"],
280 args["solver"]["contact"]["friction_iterations"],
281 args["solver"]["rayleigh_damping"],
282 args["solver"]["augmented_lagrangian"]["lumping"],
284 args["boundary_conditions"]["periodic"], /*fe_space_id=*/-1);
285
286 for (const auto &form : forms)
287 form->set_output_dir(output_path);
288
289 if (solve_data_.contact_form != nullptr)
290 solve_data_.contact_form->save_ccd_debug_meshes = args["output"]["advanced"]["save_ccd_debug_meshes"];
291 }
292
293 // The differentiable path performs the initial nonlinear solve but skips the
294 // subsequent lagging iterations. The adjoint uses the forms frozen at that
295 // solution instead of differentiating through the lagging update loop.
297 const int step,
298 Eigen::MatrixXd &solution,
299 const bool init_lagging)
300 {
302 {
303 NonlinearElasticVarForm::solve_tensor_nonlinear(step, solution, init_lagging);
304 return;
305 }
306
307 assert(solve_data_.nl_problem != nullptr && "Nonlinear forms must initialize the nonlinear problem before solving");
309 assert(solution.size() == rhs_.size());
310
311 if (nl_problem.uses_lagging())
312 {
313 if (init_lagging)
314 {
315 POLYFEM_SCOPED_TIMER("Initializing lagging");
316 nl_problem.init_lagging(solution);
317 }
318 logger().info("Lagging iteration 1:");
319 }
320
321 save_subsolve(0, step, solution);
322
323 std::shared_ptr<polysolve::nonlinear::Solver> nl_solver =
324 polysolve::nonlinear::Solver::create(
325 args["solver"]["augmented_lagrangian"]["nonlinear"],
326 args["solver"]["linear"], units.characteristic_length(), logger());
327
328 solver::ALSolver al_solver(
330 args["solver"]["augmented_lagrangian"]["initial_weight"],
331 args["solver"]["augmented_lagrangian"]["scaling"],
332 args["solver"]["augmented_lagrangian"]["max_weight"],
333 args["solver"]["augmented_lagrangian"]["eta"],
334 [&](const Eigen::VectorXd &) {
335 solve_data_.update_barrier_stiffness(solution);
336 });
337
338 al_solver.post_subsolve = [&](const double al_weight) {
339 stats.solver_info.push_back(
340 {{"type", al_weight > 0 ? "al" : "rc"},
341 {"t", step},
342 {"info", nl_solver->info()}});
343 if (al_weight > 0)
344 stats.solver_info.back()["weight"] = al_weight;
345 save_subsolve(stats.solver_info.size(), step, solution);
346 };
347
348 al_solver.solve_al(
349 nl_problem, solution,
350 args["solver"]["augmented_lagrangian"]["nonlinear"],
351 args["solver"]["linear"], units.characteristic_length());
352
353 al_solver.solve_reduced(
354 nl_problem, solution,
355 args["solver"]["nonlinear"],
356 args["solver"]["linear"], units.characteristic_length());
357
358 if (args["space"]["advanced"]["count_flipped_els_continuous"])
359 {
360 const auto invalid = utils::count_invalid(
361 mesh_->dimension(), space_.basis_list(), space_.geometry_basis_list(), solution);
362 logger().debug("Flipped elements (cnt {}) : {}", invalid.size(), invalid);
363 }
364 }
365 // Same as NonlinearElasticStaticVarForm
367 Eigen::MatrixXd &solution,
368 const InitialConditionOverride *initial_condition_override,
369 const ForwardStepCallback &post_step)
370 {
371 assert(
372 (!initial_condition_override
373 || (initial_condition_override->velocity.size() == 0
374 && initial_condition_override->acceleration.size() == 0))
375 && "Static elasticity does not accept initial velocity or acceleration overrides");
376
377 stats.spectrum.setZero();
378
379 igl::Timer timer;
380 timer.start();
381 logger().info("Solving {}", primary_assembler_->name());
382
383 {
384 POLYFEM_SCOPED_TIMER("Setup RHS");
385
386 if (initial_condition_override && initial_condition_override->solution.size() != 0)
387 initial_solution(solution, initial_condition_override);
388 else if (solution.size() <= 0)
389 initial_solution(solution, initial_condition_override);
390
391 if (initial_condition_override && initial_condition_override->solution.size() != 0)
392 assert(solution.cols() == 1 && "Static initial solution override must have exactly one column");
393 else if (solution.cols() != 1)
394 log_and_throw_error("Static elasticity requires exactly one initial solution column.");
395 }
396
397 if (is_homogenization())
398 {
399 Eigen::VectorXd extended_solution = init_homogenization_solve(solution, /*time=*/0, initial_condition_override);
400 solve_homogenization_step(0, 0.0, extended_solution, solution, post_step);
401 timer.stop();
402 timings.solving_time = timer.getElapsedTime();
403 logger().info(" took {}s", timings.solving_time);
404 return;
405 }
406
407 init_solve(solution, 1.0, initial_condition_override);
408 solve_tensor_nonlinear(0, solution, true);
409 if (post_step)
410 post_step(0, solution);
411
412 timer.stop();
413 timings.solving_time = timer.getElapsedTime();
414 logger().info(" took {}s", timings.solving_time);
415 }
416
417 // Same as NonlinearElasticTransientVarForm.
419 Eigen::MatrixXd &solution,
420 const InitialConditionOverride *initial_condition_override,
421 const ForwardStepCallback &post_step)
422 {
423 const bool save_stats = args["output"]["stats"];
424 stats.spectrum.setZero();
425
426 igl::Timer timer;
427 timer.start();
428 logger().info("Solving {}", primary_assembler_->name());
429
430 {
431 POLYFEM_SCOPED_TIMER("Setup RHS");
432
433 if (initial_condition_override && initial_condition_override->solution.size() != 0)
434 initial_solution(solution, initial_condition_override);
435 else if (solution.size() <= 0)
436 initial_solution(solution, initial_condition_override);
437
438 if (solution.cols() > 1)
439 solution.conservativeResize(Eigen::NoChange, 1);
440 }
441
442 init_solve(solution, t0 + dt, initial_condition_override);
443 if (post_step)
444 post_step(0, solution);
445
446 int save_i = 0;
447 std::unique_ptr<io::EnergyCSVWriter> energy_csv;
448 std::unique_ptr<io::RuntimeStatsCSVWriter> stats_csv;
449
450 if (save_stats)
451 {
452 logger().debug(
453 "Saving nl stats to {} and {}",
454 resolve_output_path("energy.csv"), resolve_output_path("stats.csv"));
455 energy_csv = std::make_unique<io::EnergyCSVWriter>(resolve_output_path("energy.csv"), solve_data_);
456 const io::OutputSpace space = output_space();
457 stats_csv = std::make_unique<io::RuntimeStatsCSVWriter>(
458 resolve_output_path("stats.csv"),
460 space.mesh ? space.mesh->n_elements() : 0,
461 t0, dt);
462 }
463
464 if (energy_csv)
465 energy_csv->write(save_i, solution);
466 save_timestep(t0, 0, t0, dt, solution);
467 ++save_i;
468
469 for (int t = 1; t <= time_steps; ++t)
470 {
471 double forward_solve_time = 0;
472 const double remeshing_time = 0;
473 const double global_relaxation_time = 0;
474
475 {
476 POLYFEM_SCOPED_TIMER(forward_solve_time);
477 solve_tensor_nonlinear(t, solution, true);
478 }
479 if (post_step)
480 post_step(t, solution);
481
482 if (energy_csv)
483 energy_csv->write(save_i, solution);
484 save_timestep(t0 + dt * t, t, t0, dt, solution);
485 ++save_i;
486
487 {
488 POLYFEM_SCOPED_TIMER("Update quantities");
490 solve_data_.time_integrator->update_quantities(solution);
491 solve_data_.nl_problem->update_quantities(t0 + (t + 1) * dt, solution);
494 }
495
496 logger().info("{}/{} t={}", t, time_steps, t0 + dt * t);
499 if (stats_csv)
500 stats_csv->write(t, forward_solve_time, remeshing_time, global_relaxation_time);
501 }
502
503 timer.stop();
504 timings.solving_time = timer.getElapsedTime();
505 logger().info(" took {}s", timings.solving_time);
506 }
507} // namespace polyfem::varform
#define POLYFEM_SCOPED_TIMER(...)
Definition Timer.hpp:10
double characteristic_length() const
Definition Units.hpp:22
Caches basis evaluation and geometric mapping at every element.
void save_vtu(const std::string &path, const OutputSpace &space, const OutputFieldFunction &output_fields, const double t, const double dt, const ExportOptions &opts) const
saves the vtu file for time t
Definition OutData.cpp:2164
double solving_time
time to solve
json solver_info
information of the solver, eg num iteration, time, errors, etc the informations varies depending on t...
Eigen::Vector4d spectrum
spectrum of the stiffness matrix, enable only if POLYSOLVE_WITH_SPECTRA is ON (off by default)
virtual const std::filesystem::path & host_directory() const =0
Host directory used only as the base for ordinary filesystem outputs.
Applies geometry JSON semantics while delegating all decoding to MeshLoader.
std::unique_ptr< Mesh > load_fem(const json &geometry, bool non_conforming=false) const
Load and combine the enabled FEM entries in a geometry configuration.
Abstract mesh class to capture 2d/3d conforming and non-conforming meshes.
Definition Mesh.hpp:50
int n_elements() const
utitlity to return the number of elements, cells or faces in 3d and 2d
Definition Mesh.hpp:148
void solve_reduced(NLProblem &nl_problem, Eigen::MatrixXd &sol, std::shared_ptr< polysolve::nonlinear::Solver > nl_solver)
Definition ALSolver.hpp:41
std::function< void(const double)> post_subsolve
Definition ALSolver.hpp:53
void solve_al(NLProblem &nl_problem, Eigen::MatrixXd &sol, std::shared_ptr< polysolve::nonlinear::Solver > nl_solver)
Definition ALSolver.hpp:29
void init_lagging(const TVector &x) override
class to store time stepping data
Definition SolveData.hpp:56
void update_dt()
updates the dt inside the different forms
std::shared_ptr< solver::NLProblem > nl_problem
std::shared_ptr< solver::ContactForm > contact_form
std::vector< std::shared_ptr< solver::AugmentedLagrangianForm > > al_form
std::shared_ptr< time_integrator::ImplicitTimeIntegrator > time_integrator
void update_barrier_stiffness(const Eigen::VectorXd &x)
update the barrier stiffness for the forms
std::vector< std::shared_ptr< Form > > init_forms(const Units &units, const io::ResourceIO &resources, const int dim, const double t, const Eigen::VectorXi &in_node_to_node, const int n_bases, std::vector< basis::ElementBases > &bases, const std::vector< basis::ElementBases > &geom_bases, const assembler::Assembler &assembler, assembler::AssemblyValsCache &ass_vals_cache, const assembler::AssemblyValsCache &mass_ass_vals_cache, const double jacobian_threshold, const solver::ElementInversionCheck check_inversion, const unsigned conservative_max_iter, const int n_pressure_bases, const std::vector< int > &boundary_nodes, const std::vector< mesh::LocalBoundary > &local_boundary, const std::vector< mesh::LocalBoundary > &local_neumann_boundary, const QuadratureOrders &n_boundary_samples, const Eigen::MatrixXd &rhs, const Eigen::MatrixXd &sol, const assembler::Density &density, const std::vector< mesh::LocalBoundary > &local_pressure_boundary, const std::unordered_map< int, std::vector< mesh::LocalBoundary > > &local_pressure_cavity, const std::shared_ptr< assembler::PressureAssembler > pressure_assembler, const bool ignore_inertia, const StiffnessMatrix &mass, const std::shared_ptr< assembler::ViscousDamping > damping_assembler, const double lagged_regularization_weight, const int lagged_regularization_iterations, const size_t obstacle_ndof, const std::vector< std::string > &hard_constraint_files, const std::vector< json > &soft_constraint_files, const json &zero_mean, const bool contact_enabled, const ipc::CollisionMesh &collision_mesh, const double dhat, const double avg_mass, const bool use_area_weighting, const bool use_improved_max_operator, const bool use_physical_barrier, const std::string &collision_set_type, const bool skip_obstacles, const std::string &barrier, const json &barrier_stiffness, const double initial_barrier_stiffness, const double dhat_epsilon_scale, const ipc::BroadPhaseMethod broad_phase, const double ccd_tolerance, const long ccd_max_iterations, const bool enable_shape_derivatives, const bool use_gcp_formulation, const double alpha_t, const double alpha_n, const bool use_adaptive_dhat, const double min_distance_ratio, const bool use_esp_formulation, json esp_params, const bool adhesion_enabled, const double dhat_p, const double dhat_a, const double Y, const double tangential_adhesion_coefficient, const double epsa, const int tangential_adhesion_iterations, const assembler::MacroStrainValue &macro_strain_constraint, const bool periodic_contact, const Eigen::VectorXi &tiled_to_single, const double friction_coefficient, const double epsv, const int friction_iterations, const json &rayleigh_damping, const BCLumpingMode al_lumping=BCLumpingMode::ROW_SUM, const mesh::Mesh *periodic_mesh=nullptr, const std::vector< mesh::LocalBoundary > *periodic_local_boundary=nullptr, const json &periodic_conditions=json::array(), const int fe_space_id=-1)
Initialize the forms and return a vector of pointers to them.
Definition SolveData.cpp:87
void solve_problem(Eigen::MatrixXd &solution, const InitialConditionOverride *initial_condition_override, const ForwardStepCallback &post_step) override
void solve_problem(Eigen::MatrixXd &solution, const InitialConditionOverride *initial_condition_override, const ForwardStepCallback &post_step) override
void init_forms(const json &args, int dim, Eigen::MatrixXd &solution, double time) override
const assembler::ViscousDampingPrev * damping_prev_assembler() const override
QuadratureOrders boundary_samples(int discr_order, int discr_orderq, int geometry_discr_order) const override
void initial_solution(Eigen::MatrixXd &solution, const InitialConditionOverride *override=nullptr) const override
void initial_velocity(Eigen::MatrixXd &velocity, const InitialConditionOverride *override=nullptr) const override
void solve_tensor_nonlinear(int step, Eigen::MatrixXd &solution, bool init_lagging=true) override
void solve(Eigen::MatrixXd &solution, const InitialConditionOverride *initial_condition_override, const ForwardStepCallback &post_step, bool differentiable) override
const assembler::AssemblyValsCache & assembly_cache() const override
void initial_acceleration(Eigen::MatrixXd &acceleration, const InitialConditionOverride *override=nullptr) const override
bool is_contact_enabled() const override
Check if contact is enabled for the variational formulation, for output purposes.
const assembler::AssemblyValsCache & mass_assembly_cache() const override
void save_vtu(const std::string &path, const Eigen::MatrixXd &solution, double time, double dt) const override
std::string output_file_path(const std::string &path) const override
void replace_mesh(const std::string &path) override
For shock obsorption optimization, mesh is generated by an external inflator program that convert gra...
virtual Eigen::MatrixXd displacement_gradient() const
std::shared_ptr< assembler::Assembler > primary_assembler_
QuadratureOrders elastic_boundary_samples() const
assembler::AssemblyValsCache ass_vals_cache_
std::shared_ptr< assembler::Mass > mass_assembler_
void save_elastic_step_state(const double t0, const double dt, const int t, const Eigen::MatrixXd &solution, const time_integrator::ImplicitTimeIntegrator *time_integrator) const
std::shared_ptr< assembler::RhsAssembler > rhs_assembler_
assembler::AssemblyValsCache mass_ass_vals_cache_
void initial_velocity(Eigen::MatrixXd &velocity, const InitialConditionOverride *override=nullptr, const std::string &state_prefix="") const
void initial_acceleration(Eigen::MatrixXd &acceleration, const InitialConditionOverride *override=nullptr, const std::string &state_prefix="") const
void initial_solution(Eigen::MatrixXd &solution, const InitialConditionOverride *override=nullptr, const std::string &state_prefix="") const
A finite-element space for one scalar- or vector-valued field.
Definition FESpace.hpp:59
const std::vector< basis::ElementBases > & geometry_basis_list() const
Definition FESpace.hpp:115
std::shared_ptr< std::vector< basis::ElementBases > > bases
Per-element basis data.
Definition FESpace.hpp:68
int n_bases
Number of globally indexed scalar basis functions in the space.
Definition FESpace.hpp:65
Eigen::VectorXi space_in_node_to_node
Definition FESpace.hpp:91
const std::vector< basis::ElementBases > & basis_list() const
Definition FESpace.hpp:109
assembler::MacroStrainValue macro_strain_constraint_
Prescribed macro displacement-gradient values and fixed components.
virtual void init_forms(const json &args, int dim, Eigen::MatrixXd &sol, double t)
std::shared_ptr< assembler::PressureAssembler > elasticity_pressure_assembler
Eigen::VectorXd init_homogenization_solve(Eigen::MatrixXd &solution, double time, const InitialConditionOverride *initial_condition_override)
Return the initial extended solution [periodic displacement fluctuation | flatten(G)].
Eigen::MatrixXd displacement_gradient_
For periodic structure, displacement u = periodic fluctuation ũ + macro strain GX.
std::shared_ptr< assembler::ViscousDampingPrev > damping_prev_assembler_
virtual void solve_tensor_nonlinear(int step, Eigen::MatrixXd &sol, bool init_lagging=true)
void init_solve(Eigen::MatrixXd &sol, double t, const InitialConditionOverride *initial_condition_override)
void solve_homogenization_step(int step, double time, Eigen::VectorXd &extended_solution, Eigen::MatrixXd &solution, const ForwardStepCallback &post_step)
void init(const std::string &formulation, const Units &units, const json &args, const std::string &out_path) override
Initialize the variational formulation with the given parameters.
std::shared_ptr< assembler::ViscousDamping > damping_assembler_
io::OutputSpace output_space() const override
Get the output space of the variational formulation, for output purposes.
bool is_contact_enabled() const override
Check if contact is enabled for the variational formulation, for output purposes.
std::vector< std::shared_ptr< solver::Form > > forms
std::shared_ptr< assembler::PressureAssembler > build_pressure_assembler() const
void prepare()
Prepare all discretization and assembly data without running a solve.
Definition VarForm.cpp:259
std::shared_ptr< assembler::Problem > problem
current problem, it contains rhs and bc
Definition VarForm.hpp:263
void solve(Eigen::MatrixXd &sol, const InitialConditionOverride *initial_condition_override=nullptr, const ForwardStepCallback &post_step={})
Solve the variational formulation and store the solution in the given matrix.
Definition VarForm.cpp:594
std::unique_ptr< mesh::Mesh > mesh_
Definition VarForm.hpp:275
io::OutStatsData stats
Definition VarForm.hpp:267
void notify_time_step(const int t, const int time_steps, const double t0, const double dt) const
Definition VarForm.cpp:1105
io::OutGeometryData::ExportOptions export_options(const io::OutputSpace &space) const
Definition VarForm.cpp:835
io::OutGeometryData output_geometry_
Definition VarForm.hpp:279
void save_subsolve(const int i, const int t, const Eigen::MatrixXd &solution) const
Definition VarForm.cpp:1086
io::OutputFieldFunction output_field_function(const Eigen::MatrixXd &solution, const io::OutGeometryData::ExportOptions &opts) const
Definition VarForm.cpp:844
QuadratureOrders n_boundary_samples(const int discr_order, const int discr_orderq, const int gdiscr_order) const
Definition VarForm.cpp:185
std::string resolve_output_path(const std::string &path) const
Definition VarForm.cpp:1116
void set_mesh(std::unique_ptr< mesh::Mesh > mesh, const double loading_mesh_time=0)
Set the mesh for the variational formulation.
Definition VarForm.cpp:223
void ensure_output_sampler() const
Definition VarForm.cpp:821
void save_timestep(const double time, const int t, const double t0, const double dt, const Eigen::MatrixXd &solution) const
Definition VarForm.cpp:1047
io::OutRuntimeData timings
runtime statistics
Definition VarForm.hpp:270
const io::ResourceIO & resources_
Definition VarForm.hpp:285
void set_materials(assembler::Assembler &assembler, const int size) const
Definition VarForm.cpp:806
std::vector< int > count_invalid(const int dim, const std::vector< basis::ElementBases > &bases, const std::vector< basis::ElementBases > &gbases, const Eigen::VectorXd &u, const unsigned max_iter)
Definition Jacobian.cpp:122
std::function< void(int step, const Eigen::MatrixXd &solution)> ForwardStepCallback
Definition VarForm.hpp:55
spdlog::logger & logger()
Retrieves the current logger.
Definition Logger.cpp:44
std::array< int, 2 > QuadratureOrders
Definition Types.hpp:19
nlohmann::json json
Definition Common.hpp:9
void log_and_throw_error(const std::string &msg)
Definition Logger.cpp:73
Eigen::SparseMatrix< double, Eigen::ColMajor > StiffnessMatrix
Definition Types.hpp:24
const mesh::Mesh * mesh
Temporary compatibility wrapper for boundary data belonging to one FE space.
Definition FESpace.hpp:152
std::vector< mesh::LocalBoundary > local_boundary
Definition FESpace.hpp:155
std::vector< mesh::LocalBoundary > local_neumann_boundary
Definition FESpace.hpp:156
std::vector< mesh::LocalBoundary > total_local_boundary
Definition FESpace.hpp:154
std::vector< mesh::LocalBoundary > local_pressure_boundary
Definition FESpace.hpp:157
std::unordered_map< int, std::vector< mesh::LocalBoundary > > local_pressure_cavity
Definition FESpace.hpp:158