13 std::shared_ptr<mesh::MeshNodes> mesh_nodes,
15 const std::vector<std::shared_ptr<Form>> &forms,
16 const std::vector<std::shared_ptr<AugmentedLagrangianForm>> &penalty_forms,
17 const bool solve_symmetric_macro_strain,
18 const std::shared_ptr<polysolve::linear::Solver> &solver,
19 const double char_length,
20 const double char_force,
23 :
NLProblem(full_size, t, forms, penalty_forms, solver, char_length, char_force, lumped_mass, dimension),
25 dimension_(dimension),
26 mesh_nodes_(std::move(mesh_nodes)),
27 only_symmetric(solve_symmetric_macro_strain),
28 macro_strain_constraint_(macro_strain_constraint)
41 for (
int i = 0, idx = 0; i <
dim; i++)
43 for (
int j = i; j <
dim; j++)
68 Eigen::VectorXd reduced(dof1 + dof2);
80 assert(reduced.size() == dof1 + dof2);
84 Eigen::VectorXd extended(full.size() + disp_grad.size());
85 extended << full, disp_grad;
96 Eigen::VectorXd grad(dof1 + dof2);
136 Eigen::VectorXd grad_extended;
147 Eigen::MatrixXd A12, A22;
149 Eigen::MatrixXd tmp = Eigen::MatrixXd(extended.rightCols(
dim *
dim));
154 std::vector<Eigen::Triplet<double>>
entries;
155 entries.reserve(extended.nonZeros() + A12.size() * 2 + A22.size());
158 for (StiffnessMatrix::InnerIterator it(extended, k); it; ++it)
160 entries.emplace_back(it.row(), it.col(), it.value());
162 for (
int i = 0; i < A12.rows(); i++)
164 for (
int j = 0; j < A12.cols(); j++)
171 for (
int i = 0; i < A22.rows(); i++)
172 for (
int j = 0; j < A22.cols(); j++)
179 reduced.resize(0, 0);
184 assert(dof1 ==
Q2_.cols());
189 for (
int k = 0; k <
Q2_.cols(); ++k)
190 for (StiffnessMatrix::InnerIterator it(
Q2_, k); it; ++it)
192 entries.emplace_back(it.row(), it.col(), it.value());
195 for (
int k = 0; k < dof2; k++)
197 entries.emplace_back(
Q2_.rows() + k, dof1 + k, 1);
203 reduced = Q2_extended.transpose() * reduced * Q2_extended;
205 reduced.prune([](
const Eigen::Index &row,
const Eigen::Index &col,
const Scalar &
value) {
206 return std::abs(
value) > 1e-10;
227 THessian hess_extended;
240 Eigen::VectorXd fixed_mask;
241 fixed_mask.setZero(
dim *
dim);
242 fixed_mask(fixed_entry.array()).setOnes();
246 for (
int i = 0; i < fixed_mask.size(); i++)
247 if (abs(fixed_mask(i)) > 1e-8)
252 for (
int i = 0, j = 0; i <
fixed_mask_.size(); i++)
265 Eigen::MatrixXd A12 =
hessian * tmp.transpose();
266 Eigen::MatrixXd A22 = tmp * A12;
268 std::vector<Eigen::Triplet<double>>
entries;
269 entries.reserve(
hessian.nonZeros() + A12.size() * 2 + A22.size());
271 for (
int k = 0; k <
hessian.outerSize(); ++k)
272 for (StiffnessMatrix::InnerIterator it(
hessian, k); it; ++it)
273 entries.emplace_back(it.row(), it.col(), it.value());
275 for (
int i = 0; i < A12.rows(); i++)
276 for (
int j = 0; j < A12.cols(); j++)
282 for (
int i = 0; i < A22.rows(); i++)
283 for (
int j = 0; j < A22.cols(); j++)
292 assert(dof1 ==
Q2_.cols());
297 for (
int k = 0; k <
Q2_.cols(); ++k)
298 for (StiffnessMatrix::InnerIterator it(
Q2_, k); it; ++it)
300 entries.emplace_back(it.row(), it.col(), it.value());
303 for (
int k = 0; k < dof2; k++)
305 entries.emplace_back(
Q2_.rows() + k, dof1 + k, 1);
313 hessian.prune([](
const Eigen::Index &row,
const Eigen::Index &col,
const Scalar &
value) {
314 return std::abs(
value) > 1e-10;
332 reduced.setZero(dof1 + dof2);
346 reduced.setZero(dof1 + dof2);
357 TVector reduced_diag;
358 reduced_diag.setZero(dof1 + dof2);
392 mid(i) = fixed_values(i);
441 form->post_step(polysolve::nonlinear::PostStepData(
480 for (
int i = 0; i < X.rows(); i++)
481 for (
int j = 0; j <
dim; j++)
482 for (
int k = 0; k <
dim; k++)
483 jac(j *
dim + k, i *
dim + j) = X(i, k);
std::vector< Eigen::Triplet< double > > entries
Eigen::MatrixXd eval(const double t) const
static Eigen::MatrixXd generate_linear_field(const int n_bases, const std::shared_ptr< mesh::MeshNodes > mesh_nodes, const Eigen::MatrixXd &grad)
static Eigen::MatrixXd get_bases_position(const int n_bases, const std::shared_ptr< mesh::MeshNodes > mesh_nodes)
virtual void hessian(const TVector &x, THessian &hessian) override
virtual double value(const TVector &x) override
virtual void init(const TVector &x0) override
virtual void gradient(const TVector &x, TVector &gradv) override
std::shared_ptr< mesh::MeshNodes > mesh_nodes_
Eigen::MatrixXd reduced_to_disp_grad(const TVector &reduced, bool homogeneous=false) const
Eigen::VectorXi fixed_mask_
void gradient(const TVector &x, TVector &gradv) override
void init(const TVector &x0) override
void post_step(const polysolve::nonlinear::PostStepData &data) override
Eigen::MatrixXd macro_mid_to_reduced_
int macro_reduced_size() const
void set_fixed_entry(const Eigen::VectorXi &fixed_entry)
TVector macro_full_to_reduced(const TVector &full) const
bool is_step_valid(const TVector &x0, const TVector &x1) override
Eigen::MatrixXd macro_mid_to_full_
NLHomoProblem(const int full_size, const assembler::MacroStrainValue ¯o_strain_constraint, int n_bases, std::shared_ptr< mesh::MeshNodes > mesh_nodes, double t, const std::vector< std::shared_ptr< Form > > &forms, const std::vector< std::shared_ptr< AugmentedLagrangianForm > > &penalty_forms, bool solve_symmetric_macro_strain, const std::shared_ptr< polysolve::linear::Solver > &solver, double char_length, double char_force, StiffnessMatrix lumped_mass, int dimension)
const assembler::MacroStrainValue & macro_strain_constraint_
void line_search_begin(const TVector &x0, const TVector &x1) override
void update_quantities(const double t, const TVector &x) override
Eigen::MatrixXd macro_full_to_mid_
TVector extended_to_reduced_grad(const TVector &extended) const
void hessian(const TVector &x, THessian &hessian) override
void init_lagging(const TVector &x) override
TVector full_to_reduced_diag(const TVector &full_diag) const override
TVector reduced_to_extended(const TVector &reduced, bool homogeneous=false) const
TVector reduced_to_full(const TVector &reduced) const
TVector extended_to_reduced(const TVector &extended) const
std::vector< std::shared_ptr< Form > > homo_forms
Eigen::MatrixXd constraint_grad() const
Eigen::MatrixXd macro_full_to_reduced_grad(const Eigen::MatrixXd &full) const
double value(const TVector &x) override
TVector full_to_reduced(const TVector &full, const Eigen::MatrixXd &disp_grad) const
TVector full_to_reduced_grad(const TVector &full) const override
void full_hessian_to_reduced_hessian(THessian &hessian) const
const bool only_symmetric
void solution_changed(const TVector &new_x) override
double max_step_size(const TVector &x0, const TVector &x1) override
void extended_hessian_to_reduced_hessian(const THessian &extended, THessian &reduced) const
bool is_step_collision_free(const TVector &x0, const TVector &x1) override
void update_lagging(const TVector &x, const int iter_num) override
TVector macro_reduced_to_full(const TVector &reduced, bool homogeneous=false) const
const int full_size_
Size of the full problem.
void line_search_begin(const TVector &x0, const TVector &x1) override
StiffnessMatrix Q2_
Q2 block of the QR decomposition of the constraints matrix.
virtual bool is_step_valid(const TVector &x0, const TVector &x1) override
virtual void post_step(const polysolve::nonlinear::PostStepData &data) override
virtual TVector full_to_reduced_grad(const TVector &full) const
virtual TVector full_to_reduced_diag(const TVector &full_diag) const
TVector full_to_reduced(const TVector &full) const
virtual void update_quantities(const double t, const TVector &x)
void init_lagging(const TVector &x) override
virtual bool is_step_collision_free(const TVector &x0, const TVector &x1) override
TVector reduced_to_full(const TVector &reduced) const
void update_lagging(const TVector &x, const int iter_num) override
virtual double max_step_size(const TVector &x0, const TVector &x1) override
void solution_changed(const TVector &new_x) override
std::shared_ptr< FullNLProblem > penalty_problem_
Eigen::MatrixXd unflatten(const Eigen::VectorXd &x, int dim)
Unflatten rowwises, so every dim elements in x become a row.
Eigen::VectorXd flatten(const Eigen::MatrixXd &X)
Flatten rowwises.
void log_and_throw_error(const std::string &msg)
Eigen::SparseMatrix< double, Eigen::ColMajor > StiffnessMatrix