IgANet
IgANets - Isogeometric Analysis Networks
Loading...
Searching...
No Matches
GismoLinearElasticityModel.hpp
Go to the documentation of this file.
1
15#pragma once
16
17#include <GismoPdeModel.hpp>
18
19using namespace std::string_literals;
20
21namespace iganet {
22
23namespace webapp {
24
26template <short_t d, typename T>
28
29 static_assert(d >= 1 && d <= 3, "Spatial dimension must be between 1 and 3");
30
31private:
34
36 gismo::gsMultiBasis<T> basis_;
37
39 gismo::gsBoundaryConditions<T> bc_;
40
42 gismo::gsFunctionExpr<T> rhsFunc_;
43 gismo::gsFunctionExpr<T> loadFunc_;
44
46 std::array<gismo::gsFunctionExpr<T>, 2 * d> bcFunc_;
47
49 std::array<gismo::condition_type::type, 2 * d> bcType_;
50
53
56
58 void solve() {
59
60 // Setup assembler
61 gismo::gsElasticityAssembler<T> assembler(Base::geo_, basis_, bc_, rhsFunc_);
62 assembler.options().setReal("YoungsModulus", YoungsModulus_);
63 assembler.options().setReal("PoissonsRatio", PoissonsRatio_);
64 assembler.options().setInt("MaterialLaw", gismo::material_law::hooke);
65 assembler.options().setInt("DirichletStrategy", gismo::dirichlet::elimination);
66
67 // Initialize assembler
68 assembler.assemble();
69
70 // Solve system
71 typename gismo::gsSparseSolver<T>::CGDiagonal solver(assembler.matrix());
72 gismo::gsMatrix<T> solution(solver.solve(assembler.rhs()));
73
74 // Extract solution
75 assembler.constructSolution(solution, assembler.allFixedDofs(),
77 }
78
79public:
82
84 GismoLinearElasticityModel(const std::array<short_t, d> degrees,
85 const std::array<int64_t, d> ncoeffs,
86 const std::array<int64_t, d> npatches,
87 const std::array<T, d> dimensions)
88 : Base(degrees, ncoeffs, npatches, dimensions), basis_(Base::geo_, true),
89 YoungsModulus_(210e9), PoissonsRatio_(0.3), rhsFunc_("0", "0", "0", 3),
90 loadFunc_("0", "0", "-1e5", 3) {
91
92 // Set boundary conditions type and expression
93 for (const auto &side : GismoBoundarySides<d>) {
94 bcType_[side - 1] = gismo::condition_type::unknownType;
95 bcFunc_[side - 1] = gismo::give(gismo::gsFunctionExpr<T>("0", "0", "0", 3));
96 // bc_.addCondition(0, side, bcType_[side - 1], &bcFunc_[side - 1]);
97 }
98
99 bc_.addCondition(0, gismo::boundary::west, gismo::condition_type::dirichlet,
100 nullptr, 0);
101 bc_.addCondition(0, gismo::boundary::west, gismo::condition_type::dirichlet,
102 nullptr, 1);
103 bc_.addCondition(0, gismo::boundary::west, gismo::condition_type::dirichlet,
104 nullptr, 2);
105
106 bc_.addCondition(0, gismo::boundary::east, gismo::condition_type::neumann,
107 &loadFunc_);
108
109 // Set geometry
110 bc_.setGeoMap(Base::geo_);
111
112 // Regenerate solution
113 solve();
114 }
115
118
120 std::string getName() const override {
121 return "GismoLinearElasticity" + std::to_string(d) + "d";
122 }
123
125 std::string getDescription() const override {
126 return "G+Smo linear elasticity model in " + std::to_string(d) +
127 " dimensions";
128 };
129
131 nlohmann::json getOptions() const override {
132
133 nlohmann::json json = Base::getOptions();
134
135 return json;
136 }
137
139 nlohmann::json getOutputs() const override {
140 auto json = R"([{
141 "name" : "Displacement",
142 "description" : "Displament magnitude",
143 "type" : 1},{
144 "name" : "Displacement_x",
145 "description" : "Displacement x-component",
146 "type" : 1},{
147 "name" : "Displacement_y",
148 "description" : "Displacement x-component",
149 "type" : 1},{
150 "name" : "Displacement_z",
151 "description" : "Displacement z-component",
152 "type" : 1}])"_json;
153
154 for (auto const &output : Base::getOutputs())
155 json.push_back(output);
156
157 return json;
158 }
159
161 nlohmann::json getParameters() const override {
162
163 auto json = nlohmann::json::array();
164 int uiid = 0;
165
166 // Lambda expression to add a JSON entry
167 auto add_json = [&json, &uiid]<typename Type, typename Value>(
168 const std::string &name, const std::string &label,
169 const std::string &group,
170 const std::string &description, const Type &type,
171 const Value &value) {
172 nlohmann::json item;
173 item["name"] = name;
174 item["label"] = label;
175 item["description"] = description;
176 item["group"] = group;
177 item["type"] = type;
178 item["value"] = value;
179 item["default"] = value;
180 item["uuid"] = uiid++;
181 json.push_back(item);
182 };
183
184 // Lambda expression to add a JSON entry with different default type
185 auto add_json_default =
186 [&json, &uiid]<typename Type, typename Value, typename DefaultValue>(
187 const std::string &name, const std::string &label,
188 const std::string &group, const std::string &description,
189 const Type &type, const Value &value,
190 const DefaultValue &defaultValue) {
191 nlohmann::json item;
192 item["name"] = name;
193 item["label"] = label;
194 item["description"] = description;
195 item["group"] = group;
196 item["type"] = type;
197 item["value"] = value;
198 item["default"] = defaultValue;
199 item["uuid"] = uiid++;
200 json.push_back(item);
201 };
202
203 add_json("YoungModulus", "Young", "", "Young's modulus", "float",
205 add_json("PoissonRatio", "Poisson", "", "Poisson's ratio", "float",
207
208 // add_json("rhs", "Right-hand side function",
209 // std::vector<std::string>{"text", "text", "text"},
210 // std::vector<std::string>{rhsFunc_.expression(0),
211 // rhsFunc_.expression(1),
212 // rhsFunc_.expression(2)});
213
214 return json;
215 }
216
218 nlohmann::json updateAttribute(const std::string &patch,
219 const std::string &component,
220 const std::string &attribute,
221 const nlohmann::json &json) override {
222
223 nlohmann::json result = R"({})"_json;
224
225 if (attribute == "YoungModulus") {
226 if (!json.contains("data"))
228 if (!json["data"].contains("YoungModulus"))
230
231 YoungsModulus_ = json["data"]["YoungModulus"].get<T>();
232 }
233
234 else if (attribute == "PoissonRatio") {
235 if (!json.contains("data"))
237 if (!json["data"].contains("PoissonRatio"))
239
240 PoissonsRatio_ = json["data"]["PoissonRatio"].get<T>();
241 }
242
243 else
245
246 // Solve updated problem
247 solve();
248
249 return result;
250 }
251
253 nlohmann::json eval(const std::string &patch, const std::string &component,
254 const nlohmann::json &json) const override {
255
256 int patchIndex(-1);
257
258 try {
259 patchIndex = stoi(patch);
260 } catch (...) {
261 // Invalid patchIndex
262 return R"({ INVALID REQUEST })"_json;
263 }
264
265 if (component == "Displacement" ||
266 component == "Displacement_x" ||
267 component == "Displacement_y" ||
268 component == "Displacement_z") {
269
270 nlohmann::json result;
271
272 // degrees
273 result["degrees"] = nlohmann::json::array();
274
275 for (std::size_t i = 0; i < Base::solution_.patch(patchIndex).parDim(); ++i)
277
278 // ncoeffs
279 result["ncoeffs"] = nlohmann::json::array();
280
281 if (auto bspline =
282 dynamic_cast<const gismo::gsBSpline<T> *>(&Base::solution_.patch(patchIndex)))
283 for (std::size_t i = 0; i < bspline->parDim(); ++i)
284 result["ncoeffs"].push_back(bspline->basis().size(i));
285 else if (auto bspline = dynamic_cast<const gismo::gsTensorBSpline<d, T> *>(
287 for (std::size_t i = 0; i < bspline->parDim(); ++i)
288 result["ncoeffs"].push_back(bspline->basis().size(i));
289 else
290 return R"({ INVALID REQUEST })"_json;
291
292 // nknots
293 result["nknots"] = nlohmann::json::array();
294
295 if (auto bspline =
296 dynamic_cast<const gismo::gsBSpline<T> *>(&Base::solution_.patch(patchIndex)))
297 for (std::size_t i = 0; i < bspline->parDim(); ++i)
298 result["nknots"].push_back(bspline->knots(i).size());
299 else if (auto bspline = dynamic_cast<const gismo::gsTensorBSpline<d, T> *>(
301 for (std::size_t i = 0; i < bspline->parDim(); ++i)
302 result["nknots"].push_back(bspline->knots(i).size());
303 else
304 return R"({ INVALID REQUEST })"_json;
305
306 // knots
307 result["knots"] = nlohmann::json::array();
308
309 if (auto bspline =
310 dynamic_cast<const gismo::gsBSpline<T> *>(&Base::solution_.patch(patchIndex)))
311 for (std::size_t i = 0; i < bspline->parDim(); ++i)
312 result["knots"].push_back(bspline->knots(i));
313 else if (auto bspline = dynamic_cast<const gismo::gsTensorBSpline<d, T> *>(
315 for (std::size_t i = 0; i < bspline->parDim(); ++i)
316 result["knots"].push_back(bspline->knots(i));
317 else
318 return R"({ INVALID REQUEST })"_json;
319
320 // coeffs
321 gismo::gsMatrix<T> coeffs;
322 if (component == "Displacement") {
323 coeffs = Base::solution_.patch(patchIndex).coefs().rowwise().norm();
324 } else if (component == "Displacement_x") {
325 coeffs = Base::solution_.patch(patchIndex).coefs().col(0);
326 } else if (component == "Displacement_y") {
327 coeffs = Base::solution_.patch(patchIndex).coefs().col(1);
328 } else if (component == "Displacement_z") {
329 coeffs = Base::solution_.patch(patchIndex).coefs().col(2);
330 }
331 result["coeffs"] = utils::to_json(coeffs, true, false);
332
333 return result;
334 }
335
336 else
337 return Base::eval(patch, component, json);
338 }
339
341 void elevate(const nlohmann::json &json = NULL) override {
342
343 bool geometry = true;
344
345 if (json.contains("data"))
346 if (json["data"].contains("num"))
347 geometry = json["data"]["geometry"].get<bool>();
348
349 if (geometry) {
350 // Elevate geometry
352
353 // Set geometry
354 bc_.setGeoMap(Base::geo_);
355 }
356
357 int num(1), dim(-1), patchIndex(-1);
358
359 if (json.contains("data")) {
360 if (json["data"].contains("num"))
361 num = json["data"]["num"].get<int>();
362
363 if (json["data"].contains("dim"))
364 dim = json["data"]["dim"].get<int>();
365
366 if (json["data"].contains("patch"))
367 patchIndex = json["data"]["patch"].get<int>();
368 }
369
370 // Degree elevate basis of solution space
371 if (patchIndex == -1)
372 basis_.degreeElevate(num, dim);
373 else
374 basis_.basis(patchIndex).degreeElevate(num, dim);
375
376 // Regenerate solution
377 solve();
378 }
379
381 void increase(const nlohmann::json &json = NULL) override {
382
383 bool geometry = true;
384
385 if (json.contains("data"))
386 if (json["data"].contains("num"))
387 geometry = json["data"]["geometry"].get<bool>();
388
389 if (geometry) {
390 // Increase geometry
392
393 // Set geometry
394 bc_.setGeoMap(Base::geo_);
395 }
396
397 int num(1), dim(-1), patchIndex(-1);
398
399 if (json.contains("data")) {
400 if (json["data"].contains("num"))
401 num = json["data"]["num"].get<int>();
402
403 if (json["data"].contains("dim"))
404 dim = json["data"]["dim"].get<int>();
405
406 if (json["data"].contains("patch"))
407 patchIndex = json["data"]["patch"].get<int>();
408 }
409
410 // Degree increase basis of solution space
411 if (patchIndex == -1)
412 basis_.degreeIncrease(num, dim);
413 else
414 basis_.basis(patchIndex).degreeIncrease(num, dim);
415
416 // Regenerate solution
417 solve();
418 }
419
421 void refine(const nlohmann::json &json = NULL) override {
422
423 bool geometry = true;
424
425 if (json.contains("data"))
426 if (json["data"].contains("num"))
427 geometry = json["data"]["geometry"].get<bool>();
428
429 if (geometry) {
430 // Refine geometry
432
433 // Set geometry
434 bc_.setGeoMap(Base::geo_);
435 }
436
437 int num(1), dim(-1), patchIndex(-1);
438
439 if (json.contains("data")) {
440 if (json["data"].contains("num"))
441 num = json["data"]["num"].get<int>();
442
443 if (json["data"].contains("dim"))
444 dim = json["data"]["dim"].get<int>();
445
446 if (json["data"].contains("patch"))
447 patchIndex = json["data"]["patch"].get<int>();
448 }
449
450 // Refine basis of solution space
451 if (patchIndex == -1)
452 basis_.uniformRefine(num, 1, dim);
453 else
454 basis_.basis(patchIndex).uniformRefine(num, 1, dim);
455
456 // Regenerate solution
457 solve();
458 }
459
461 void addPatch(const nlohmann::json &json = NULL) override {
462
463 // Add patch from geometry
465
466 // Set geometry
467 bc_.setGeoMap(Base::geo_);
468
469 throw std::runtime_error("Adding patches is not yet implemented in G+Smo");
470
471 // Regenerate solution
472 solve();
473 }
474
476 void removePatch(const std::string &patch,
477 const nlohmann::json &json = NULL) override {
478
479 // Remove patch from geometry
481
482 // Set geometry
483 bc_.setGeoMap(Base::geo_);
484
485 int patchIndex(-1);
486
487 if (json.contains("data")) {
488 if (json["data"].contains("patch"))
489 patchIndex = json["data"]["patch"].get<int>();
490 }
491
492 // if (patchIndex == -1)
493 // throw std::runtime_error("Invalid patch index");
494
495 // throw std::runtime_error("Patch removal is not yet implemented in G+Smo");
496
497 // Regenerate solution
498 solve();
499 }
500};
501
502} // namespace webapp
503} // namespace iganet
G+Smo PDE model.
virtual void addPatch(const nlohmann::json &json)=0
Adds a patch to a model.
virtual void elevate(const nlohmann::json &json)=0
Elevates the model's degrees, preserves smoothness.
virtual nlohmann::json eval(const std::string &patch, const std::string &component, const nlohmann::json &json) const =0
Evaluates model.
virtual nlohmann::json getOutputs() const =0
Returns the model's outputs.
virtual nlohmann::json getOptions() const =0
Returns the model's options.
virtual nlohmann::json updateAttribute(const std::string &patch, const std::string &component, const std::string &attribute, const nlohmann::json &json)
Updates the attributes of the model.
Definition model.hpp:297
virtual void increase(const nlohmann::json &json)=0
Increases the model's degrees, preserves multiplicity.
virtual void refine(const nlohmann::json &json)=0
Refines model.
virtual void removePatch(const std::string &patch, const nlohmann::json &json)=0
Adds a patch to a model.
gismo::gsMultiPatch< T > geo_
Multi-patch geometry.
Definition GismoGeometryModel.hpp:39
G+Smo Linear elasticity model.
Definition GismoLinearElasticityModel.hpp:27
void refine(const nlohmann::json &json=NULL) override
Refines the model.
Definition GismoLinearElasticityModel.hpp:421
nlohmann::json getParameters() const override
Returns the model's parameters.
Definition GismoLinearElasticityModel.hpp:161
void solve()
Solve the Linear elasticity problem.
Definition GismoLinearElasticityModel.hpp:58
std::array< gismo::condition_type::type, 2 *d > bcType_
Boundary condition type.
Definition GismoLinearElasticityModel.hpp:49
std::array< gismo::gsFunctionExpr< T >, 2 *d > bcFunc_
Boundary condition values.
Definition GismoLinearElasticityModel.hpp:46
gismo::gsFunctionExpr< T > loadFunc_
Definition GismoLinearElasticityModel.hpp:43
GismoLinearElasticityModel(const std::array< short_t, d > degrees, const std::array< int64_t, d > ncoeffs, const std::array< int64_t, d > npatches, const std::array< T, d > dimensions)
Constructor for equidistant knot vectors.
Definition GismoLinearElasticityModel.hpp:84
nlohmann::json updateAttribute(const std::string &patch, const std::string &component, const std::string &attribute, const nlohmann::json &json) override
Updates the attributes of the model.
Definition GismoLinearElasticityModel.hpp:218
std::string getDescription() const override
Returns the model's description.
Definition GismoLinearElasticityModel.hpp:125
gismo::gsBoundaryConditions< T > bc_
Boundary conditions.
Definition GismoLinearElasticityModel.hpp:39
gismo::gsMultiBasis< T > basis_
Multi-patch basis.
Definition GismoLinearElasticityModel.hpp:36
void increase(const nlohmann::json &json=NULL) override
Increases the model's degrees, preserves multiplicity.
Definition GismoLinearElasticityModel.hpp:381
T YoungsModulus_
Young's modulus.
Definition GismoLinearElasticityModel.hpp:52
nlohmann::json getOutputs() const override
Returns the model's outputs.
Definition GismoLinearElasticityModel.hpp:139
nlohmann::json eval(const std::string &patch, const std::string &component, const nlohmann::json &json) const override
Evaluates the model.
Definition GismoLinearElasticityModel.hpp:253
void addPatch(const nlohmann::json &json=NULL) override
Add new patch to the model.
Definition GismoLinearElasticityModel.hpp:461
std::string getName() const override
Returns the model's name.
Definition GismoLinearElasticityModel.hpp:120
T PoissonsRatio_
Poisson's ratio.
Definition GismoLinearElasticityModel.hpp:55
void removePatch(const std::string &patch, const nlohmann::json &json=NULL) override
Remove existing patch from the model.
Definition GismoLinearElasticityModel.hpp:476
nlohmann::json getOptions() const override
Returns the model's options.
Definition GismoLinearElasticityModel.hpp:131
GismoLinearElasticityModel()=delete
Default constructor.
~GismoLinearElasticityModel()
Destructor.
Definition GismoLinearElasticityModel.hpp:117
void elevate(const nlohmann::json &json=NULL) override
Elevates the model's degrees, preserves smoothness.
Definition GismoLinearElasticityModel.hpp:341
gismo::gsFunctionExpr< T > rhsFunc_
Right-hand side function.
Definition GismoLinearElasticityModel.hpp:42
G+Smo PDE model.
Definition GismoPdeModel.hpp:58
gismo::gsMultiPatch< T > solution_
Solution.
Definition GismoPdeModel.hpp:190
auto to_json(const torch::TensorAccessor< T, N > &accessor)
Converts a torch::TensorAccessor object to a JSON object.
Definition serialize.hpp:41
degree
Enumerator for specifying the degree of B-splines.
Definition BSplineModel.hpp:23
Definition boundary.hpp:22
constexpr bool is_SplineType_v
Alias to the value of is_SplineType.
Definition bspline.hpp:3243
side
Identifiers for topological sides.
Definition boundary.hpp:25
InvalidModelAttribute exception.
Definition model.hpp:42