PolyFEM
Loading...
Searching...
No Matches
SumModel.cpp
Go to the documentation of this file.
1#include "SumModel.hpp"
2#include "MatParams.hpp"
3
4#include <jse/jse.h>
5
6// #include <polyfem/basis/Basis.hpp>
7// #include <polyfem/autogen/auto_elasticity_rhs.hpp>
8
9// #include <igl/Timer.h>
10
11namespace polyfem::assembler
12{
13 void SumModel::add_multimaterial(const int index, const json &params, const Units &units, const std::string &root_path)
14 {
15 assert(size() == 2 || size() == 3);
16 if (params.count("models") == 0)
17 return;
18
19 auto models = params["models"];
20
21 // add_multimaterial may be invoked once per mesh element (see Assembler::set_materials),
22 // so the child assemblers must be created once and then reused across calls, not appended every time.
23 if (assemblers_.empty())
24 {
25 for (const auto &model : models)
26 {
27 const std::string model_name = model["type"];
28
29 const auto assembler = AssemblerUtils::make_assembler(model_name);
30 // cast assembler to elasticity assembler
31 assemblers_.emplace_back(std::dynamic_pointer_cast<NLAssembler>(assembler));
32 assert(assemblers_.back() != nullptr);
33 assemblers_.back()->set_size(size());
34 }
35 }
36
37 assert(assemblers_.size() == models.size());
38 for (size_t i = 0; i < assemblers_.size(); ++i)
39 {
40 json model = models[i];
41 if (params.contains(MATERIAL_ELEMENT_INDEX))
43 assemblers_[i]->add_multimaterial(index, model, units, root_path);
44 }
45 }
46
47 Eigen::Matrix<double, Eigen::Dynamic, 1, 0, 3, 1>
49 {
50 assert(pt.size() == size());
51 Eigen::Matrix<double, Eigen::Dynamic, 1, 0, 3, 1> res;
52 assert(false);
53
54 return res;
55 }
56
57 Eigen::VectorXd
59 {
60 Eigen::VectorXd gradient = assemblers_.front()->assemble_gradient(data);
61 for (size_t i = 1; i < assemblers_.size(); ++i)
62 {
63 const auto assembler = assemblers_[i];
64 gradient += assembler->assemble_gradient(data);
65 }
66 return gradient;
67 }
68
69 Eigen::MatrixXd
71 {
72 Eigen::MatrixXd hessian = assemblers_.front()->assemble_hessian(data);
73 for (size_t i = 1; i < assemblers_.size(); ++i)
74 {
75 const auto assembler = assemblers_[i];
76 hessian += assembler->assemble_hessian(data);
77 }
78 return hessian;
79 }
80
82 {
83 double energy = assemblers_.front()->compute_energy(data);
84 for (size_t i = 1; i < assemblers_.size(); ++i)
85 {
86 const auto assembler = assemblers_[i];
87 energy += assembler->compute_energy(data);
88 }
89 return energy;
90 }
91
93 const OutputData &data,
94 const int all_size,
95 const ElasticityTensorType &type,
96 Eigen::MatrixXd &all,
97 const std::function<Eigen::MatrixXd(const Eigen::MatrixXd &)> &fun) const
98 {
99 all.resize(data.local_pts.rows(), all_size);
100 all.setZero();
101
102 Eigen::MatrixXd tmp;
103
104 if (type == ElasticityTensorType::F)
105 {
106 std::dynamic_pointer_cast<assembler::ElasticityAssembler>(assemblers_.front())
107 ->assign_stress_tensor(data, all_size, type, all, fun);
108 return;
109 }
110
111 for (const auto &assembler : assemblers_)
112 {
113 std::dynamic_pointer_cast<assembler::ElasticityNLAssembler>(assembler)->assign_stress_tensor(data, all_size, type, tmp, fun);
114 all += tmp;
115 }
116 }
117
118 std::map<std::string, Assembler::ParamFunc> SumModel::parameters() const
119 {
120 std::map<std::string, Assembler::ParamFunc> params;
121 for (const auto &a : assemblers_)
122 {
123 auto p = a->parameters();
124 for (auto &it : p)
125 {
126 params[a->name() + "/" + it.first] = it.second;
127 }
128 }
129 return params;
130 }
131} // namespace polyfem::assembler
static std::shared_ptr< Assembler > make_assembler(const std::string &formulation)
const Eigen::MatrixXd & local_pts
void add_multimaterial(const int index, const json &params, const Units &units, const std::string &root_path) override
Definition SumModel.cpp:13
std::map< std::string, ParamFunc > parameters() const override
Definition SumModel.cpp:118
VectorNd compute_rhs(const AutodiffHessianPt &pt) const override
Definition SumModel.cpp:48
Eigen::VectorXd assemble_gradient(const NonLinearAssemblerData &data) const override
Definition SumModel.cpp:58
Eigen::MatrixXd assemble_hessian(const NonLinearAssemblerData &data) const override
Definition SumModel.cpp:70
std::vector< std::shared_ptr< assembler::NLAssembler > > assemblers_
Definition SumModel.hpp:42
double compute_energy(const NonLinearAssemblerData &data) const override
Definition SumModel.cpp:81
void assign_stress_tensor(const OutputData &data, const int all_size, const ElasticityTensorType &type, Eigen::MatrixXd &all, const std::function< Eigen::MatrixXd(const Eigen::MatrixXd &)> &fun) const override
Definition SumModel.cpp:92
Used for test only.
constexpr const char * MATERIAL_ELEMENT_INDEX
Definition MatParams.hpp:9
Eigen::Matrix< AutodiffScalarHessian, Eigen::Dynamic, 1, 0, 3, 1 > AutodiffHessianPt
nlohmann::json json
Definition Common.hpp:9