b2api
B2000++ API Reference Manual, VERSION 4.6
 
Loading...
Searching...
No Matches
b2domain_database.H
Go to the documentation of this file.
1//------------------------------------------------------------------------
2// b2domain_database.H --
3//
4//
5// written by Mathias Doreille
6// Neda Ebrahimi Pour <neda.ebrahimipour@dlr.de>
7// Thomas Blome <thomas.blome@dlr.de>
8//
9// (c) 2004-2012,2016,2017 SMR Engineering & Development SA
10// 2502 Bienne, Switzerland
11//
12// (c) 2023 Deutsches Zentrum für Luft- und Raumfahrt (DLR) e.V.
13// Linder Höhe, 51147 Köln
14//
15// All Rights Reserved. Proprietary source code. The contents of
16// this file may not be disclosed to third parties, copied or
17// duplicated in any form, in whole or in part, without the prior
18// written permission of SMR.
19//------------------------------------------------------------------------
20
21#ifndef B2DOMAIN_DATABASE_H_
22#define B2DOMAIN_DATABASE_H_
23
24#include <cassert>
25#include <map>
26#include <set>
27#include <sstream>
28#include <string>
29#include <vector>
30
31#include "b2branch_property.H"
32#include "b2component.H"
33#include "b2domain_property.H"
34#include "b2fortran_element_property.H"
35#include "b2material_property.H"
36#include "b2ppconfig.h"
37#include "ip/b2ip_transformations.H"
38#include "model/b2domain.H"
39#include "model/b2element.H"
40#include "model/b2node.H"
41#include "utils/b2allocator.H"
42#include "utils/b2object.H"
43#include "utils/b2threading.H"
44#include "utils/b2type.H"
45
50namespace b2000::b2dbv3 {
51
62class Domain : public b2000::Domain {
63public:
64 enum struct element_type_t {
65 real_symmetric,
66 real_unsymmetric,
67 csda_symmetric,
68 csda_unsymmetric,
69 complex_symmetric,
70 complex_unsymmetric,
71 unknown
72 };
73
74 void set_model(b2000::Model& model) override;
75
76 void set_case(b2000::Case& case_) override;
77
78 void set_subcase_id(const int subcase_id_) override {
79 for (auto& i : list_branch) { i.property.set_subcase_id(subcase_id_); }
80 }
81
82 bool have_temperature() const override {
83 for (auto& i : list_branch) {
84 if (i.property.have_temperature()) { return true; }
85 }
86 return false;
87 }
88
89 size_t get_number_of_dof() const override { return nb_dof; }
90
91 size_t get_number_of_elements() const override {
92 size_t nb = 0;
93 for (list_branch_t::const_iterator i = list_branch.begin(); i != list_branch.end(); ++i) {
94 nb += i->get_number_of_elements();
95 }
96 return nb;
97 }
98
100 size_t nb = 0;
101 for (list_branch_t::const_iterator i = list_branch.begin(); i != list_branch.end(); ++i) {
102 nb += i->get_number_of_elements_and_subelements();
103 }
104 return nb;
105 }
106
107 size_t get_number_of_nodes() const override {
108 size_t nb = 0;
109 for (list_branch_t::const_iterator i = list_branch.begin(); i != list_branch.end(); ++i) {
110 nb += i->get_number_of_nodes();
111 }
112 return nb;
113 }
114
115 const std::vector<Element::VariableInfo> get_value_info() const override { return value_info; }
116
117 struct Branch {
118 struct CompFortranElementProperty {
119 bool operator()(
120 const FortranElementProperty* a, const FortranElementProperty* b) const {
121 return *a < *b;
122 }
123 };
124
125 struct ParentNodeMapping {
126 size_t parent_internal_branch;
127 size_t parent_internal_element;
128 double global_icoor[3];
129 };
130
131 struct ParentElementMapping {
132 size_t parent_internal_branch;
133 size_t parent_internal_element;
134 b2linalg::Matrix<double> global_icoor;
135 };
136
137 using list_nodes_t = std::vector<Node*>;
138 using list_elements_t = std::vector<Element*>;
139 using ElementProperties = std::set<FortranElementProperty*, CompFortranElementProperty>;
140
141 // To iterate over all elements and sub-elements of this
142 // branch. The sub-elements are determined and iterated
143 // over only after the parent element has been called.
144 class ElementIterator {
145 public:
146 ElementIterator(Branch& branch)
147 : estart(branch.list_all_elements.begin()), eend(branch.list_all_elements.end()) {}
148
149 Element* next() {
150 if (first) {
151 first = false;
152 } else {
153 increment();
154 }
155 Element* e = current();
156 return e;
157 }
158
159 private:
160 Element* current() {
161 if (in_sub) { return *sstart; }
162 if (estart != eend) { return *estart; }
163 return nullptr;
164 }
165
166 void increment() {
167 if (!in_sub) {
168 std::pair<size_t, Element**> s = (*estart)->get_subelements();
169 if (s.second != 0) {
170 sstart = s.second;
171 send = s.second + s.first;
172 in_sub = true;
173 }
174 } else if (++sstart == send) {
175 in_sub = false;
176 }
177 if (!in_sub) {
178 ++estart;
179 sstart = send = nullptr;
180 }
181 }
182
183 Branch::list_elements_t::iterator estart;
184 Branch::list_elements_t::iterator eend;
185
186 Element** sstart{};
187 Element** send{};
188
189 bool in_sub{};
190 bool first{true};
191 };
192
193 Branch(DomainProperty* dp) : property(*dp) {}
194
195 size_t get_number_of_elements() const { return list_all_elements.size(); }
196
197 size_t get_number_of_elements_and_subelements() const {
198 size_t nb = 0;
199 for (size_t i = 0; i != list_all_elements.size(); ++i) {
200 nb += 1 + list_all_elements[i]->get_subelements().first;
201 }
202 return nb;
203 }
204
205 size_t get_number_of_nodes() const { return list_nodes.size(); }
206
207 list_elements_t list_all_elements;
208
209 list_nodes_t list_nodes;
210 size_t nb_node_dof{};
211 size_t nb_element_dof{};
212 std::string id{};
213
214 Transformation3D<double> btog_transformation;
215 Transformation3D<b2000::csda<double>> btog_transformation_cs;
216
217 std::vector<Transformation3D<double>> ltob;
218 std::vector<Transformation3D<b2000::csda<double>>> ltob_cs;
219 std::vector<ParentNodeMapping> parent_node_mapping;
220 std::vector<ParentElementMapping> parent_element_mapping;
221
222 BranchProperty property;
223
224 ElementProperties element_properties;
225
226 int min_number_of_dof_by_element{std::numeric_limits<int>::max()};
227 int max_number_of_dof_by_element{};
228 int min_number_of_dof_by_node{std::numeric_limits<int>::max()};
229 int max_number_of_dof_by_node{};
230 };
231
232 std::vector<size_t> first_element_internal_id_of_branch;
233 std::vector<size_t> first_node_internal_id_of_branch;
234
235 using list_branch_t = std::vector<Branch>;
236 list_branch_t list_branch;
237
238 using branch_eid_to_branch_iid_t = std::map<size_t, size_t>;
239 branch_eid_to_branch_iid_t branch_eid_to_branch_iid;
240
241 using Materials = std::map<int, std::pair<MaterialProperty*, FortranElementProperty::type_t*>>;
242 Materials materials;
243 Materials properties;
244
245 MaterialProperty* get_material_property_from_mid(size_t mid) {
246 Materials::iterator i = materials.find(mid);
247 if (i == materials.end()) { return nullptr; }
248 return i->second.first;
249 }
250
251 MaterialProperty* get_material_property_from_pid(size_t pid) {
252 Materials::iterator i = properties.find(pid);
253 if (i == properties.end()) { return nullptr; }
254 return i->second.first;
255 }
256
257 b2linalg::Matrix<double, b2linalg::Mcompressed_col> ltob_transformation;
258 b2linalg::Matrix<b2000::csda<double>, b2linalg::Mcompressed_col> ltob_transformation_cs;
259 b2linalg::Matrix<std::complex<double>, b2linalg::Mcompressed_col> ltob_transformation_c;
260
261 std::vector<const double*> nodes_local_referential;
262 std::vector<const b2000::csda<double>*> nodes_local_referential_cs;
263
264 ip::Transformations transformations;
265
266 Branch& get_branch_from_eid(size_t eid) {
267 branch_eid_to_branch_iid_t::iterator i = branch_eid_to_branch_iid.find(eid);
268 if (i == branch_eid_to_branch_iid.end()) {
269 KeyError() << "Internal branch " << eid << " not found." << THROW;
270 }
271 return list_branch[i->second];
272 }
273
274 Branch& get_branch_from_eid(const std::string& eid) {
275 std::istringstream s(eid);
276 size_t seid;
277 s >> seid;
278 return get_branch_from_eid(seid);
279 }
280
281 class NodeIterator : public b2000::Domain::NodeIterator {
282 public:
283 Node* next() override {
284 while (bstart != bend) {
285 if (start != end) { return *start++; }
286 ++bstart;
287 if (bstart != bend) {
288 start = bstart->list_nodes.begin();
289 end = bstart->list_nodes.end();
290 }
291 }
292 return nullptr;
293 }
294
295 private:
296 NodeIterator(Domain& domain)
297 : bstart(domain.list_branch.begin()), bend(domain.list_branch.end()) {
298 while (bstart != bend && bstart->list_nodes.empty()) { ++bstart; }
299 if (bstart != bend) {
300 start = bstart->list_nodes.begin();
301 end = bstart->list_nodes.end();
302 }
303 }
304 friend class b2dbv3::Domain;
305 list_branch_t::iterator bstart;
306 list_branch_t::const_iterator bend;
307 Branch::list_nodes_t::iterator start;
308 Branch::list_nodes_t::const_iterator end;
309 };
310
311 node_iterator get_node_iterator() override { return node_iterator(new NodeIterator(*this)); }
312
313 // To iterate over all elements and sub-elements. The
314 // sub-elements are determined and iterated over only after
315 // the parent element has been called.
316 class ElementIterator : public b2000::Domain::ElementIterator {
317 public:
318 Element* next() override {
319 if (first) {
320 first = false;
321 } else {
322 increment();
323 }
324 Element* e = current();
325 return e;
326 }
327
328 protected:
329 ElementIterator(Domain& domain)
330 : bstart(domain.list_branch.begin()), bend(domain.list_branch.end()) {
331 assert(bstart != bend);
332 estart = bstart->list_all_elements.begin();
333 eend = bstart->list_all_elements.end();
334 in_sub = false;
335 sstart = send = nullptr;
336 }
337
338 Element* current() {
339 if (in_sub) { return *sstart; }
340 if (estart != eend) { return *estart; }
341 return nullptr;
342 }
343
344 void increment() {
345 if (estart != eend) {
346 if (!in_sub) {
347 std::pair<size_t, Element**> s = (*estart)->get_subelements();
348 if (s.second != 0) {
349 sstart = s.second;
350 send = s.second + s.first;
351 in_sub = true;
352 }
353 } else if (++sstart == send) {
354 in_sub = false;
355 }
356 }
357 if (!in_sub) {
358 if (++estart == eend) {
359 if (++bstart != bend) {
360 estart = bstart->list_all_elements.begin();
361 eend = bstart->list_all_elements.end();
362 }
363 }
364 sstart = send = nullptr;
365 }
366 }
367
368 friend class b2dbv3::Domain;
369 bool first{true};
370 list_branch_t::iterator bstart;
371 list_branch_t::const_iterator bend;
372 Branch::list_elements_t::iterator estart;
373 Branch::list_elements_t::iterator eend;
374 bool in_sub;
375 Element** sstart;
376 Element** send;
377 };
378
379 element_iterator get_element_iterator() override {
380 return element_iterator(new ElementIterator(*this));
381 }
382
383 ~Domain() override {
384 // Don't delete any sub-elements --> do not use ElementIterator.
385 for (std::vector<Branch>::iterator branch = list_branch.begin();
386 branch != list_branch.end(); ++branch) {
387 for (size_t i = 0; i != branch->list_all_elements.size(); ++i) {
388 Element* e = branch->list_all_elements[i];
389 e->decref_or_free();
390 }
391 }
392 {
393 node_iterator i = get_node_iterator();
394 for (Node* n = i->next(); n != nullptr; n = i->next()) { n->decref_or_free(); }
395 }
396 {
397 MaterialIterator* i = get_material_iterator();
398 MaterialProperty* m;
399 while ((m = i->next()) != nullptr) { m->decref_or_free(); }
400 delete i;
401 }
402 {
403 MaterialIterator* i = get_property_iterator();
404 MaterialProperty* m;
405 while ((m = i->next()) != nullptr) { m->decref_or_free(); }
406 delete i;
407 }
408 }
409
410 template <typename T>
411 void save_global_dof(
412 SetName name, const b2linalg::Vector<T, b2linalg::Vdense_constref>& dof,
413 RTable desc = RTable());
414
415 template <typename T>
416 void save_global_dof_indexed(
417 SetName name, const b2linalg::Vector<T, b2linalg::Vdense_constref>& dof,
418 RTable desc = RTable());
419
421 const std::string& name,
422 const b2linalg::Vector<double, b2linalg::Vdense_constref>& dof) override {
423 RTable desc;
424 desc.set("TYPE", "NODE");
425 desc.set("SYSTEM", "BRANCH");
426 save_global_dof(name, dof, desc);
427 }
428
430 const std::string& name,
431 const b2linalg::Vector<b2000::csda<double>, b2linalg::Vdense_constref>& dof) override {
432 RTable desc;
433 desc.set("TYPE", "NODE");
434 desc.set("SYSTEM", "BRANCH");
435 save_global_dof(name, dof, desc);
436 }
437
439 const std::string& name,
440 const b2linalg::Vector<std::complex<double>, b2linalg::Vdense_constref>& dof) override {
441 RTable desc;
442 desc.set("TYPE", "NODE");
443 desc.set("SYSTEM", "BRANCH");
444 save_global_dof(name, dof, desc);
445 }
446
447 template <typename T>
448 void load_global_dof(
449 SetName name, b2linalg::Vector<T, b2linalg::Vdense_ref> dof, RTable* desc = nullptr);
450
451 void load_node_set(SetName name, std::vector<Node*>& nodes_set) {
452 size_t s = 0;
453 for (size_t branch = 0; branch != list_branch.size(); ++branch) {
454 name.branch(list_branch[branch].id);
455 if (database->has_key(name)) { s += database->dims(name)[0]; }
456 }
457 nodes_set.clear();
458 nodes_set.reserve(s);
459 for (size_t branch = 0; branch != list_branch.size(); ++branch) {
460 name.branch(list_branch[branch].id);
461 if (database->has_key(name)) {
462 std::vector<mcInt32> list_node;
463 database->get(name, list_node);
464 for (size_t n = 0; n != list_node.size(); ++n) {
465 const size_t nn = list_node[n];
466 if (nn < 1 || nn > list_branch[branch].list_nodes.size()) {
467 DBError() << "invalid internal node id " << nn << " in the set " << name
468 << "." << THROW;
469 }
470 nodes_set.push_back(list_branch[branch].list_nodes[nn - 1]);
471 }
472 }
473 }
474 }
475
476 template <typename T>
477 void load_nodal_values(SetName name_, b2linalg::Matrix<T>& value) {
478 SetName name(name_);
479 bool init = false;
480 size_t internal_node_id = 0;
481 for (size_t branch = 0; branch != list_branch.size(); ++branch) {
482 const size_t internal_node_id_end =
483 internal_node_id + list_branch[branch].get_number_of_nodes();
484 name.branch(list_branch[branch].id);
485 if (database->has_key(name)) {
486 if (!init) {
487 if (value.size1() == 0) {
488 const std::vector<size_t> dims = database->dims(name);
489 if (dims.empty()) { DBError() << THROW; }
490 if (dims.size() == 1) {
491 value.resize(1, get_number_of_nodes());
492 } else {
493 value.resize(database->dims(name)[1], get_number_of_nodes());
494 }
495 } else {
496 value.resize(value.size1(), get_number_of_nodes());
497 }
498 init = true;
499 }
500 database->get(
501 name, value(b2linalg::Interval(0, value.size1()),
502 b2linalg::Interval(internal_node_id, internal_node_id_end)));
503 } else if (value.size1() != 0) {
504 value(b2linalg::Interval(0, value.size1()),
505 b2linalg::Interval(internal_node_id, internal_node_id_end))
506 .set_zero();
507 }
508
509 internal_node_id = internal_node_id_end;
510 }
511 }
512
513 const b2linalg::Matrix<double, b2linalg::Mrectangle>& get_nodal_values_double(SetName name) {
514 b2linalg::Matrix<double, b2linalg::Mrectangle>& res = list_nodal_values[name];
515 if (res.size2() == 0) { load_nodal_values(name, res); }
516 return res;
517 }
518
519 const b2linalg::Matrix<b2000::csda<double>, b2linalg::Mrectangle>& get_nodal_values_csda(
520 SetName name) {
521 b2linalg::Matrix<b2000::csda<double>, b2linalg::Mrectangle>& res =
522 list_nodal_values_cs[name];
523 if (res.size2() == 0) { load_nodal_values(name, res); }
524 return res;
525 }
526
527 template <typename T>
528 const b2linalg::Matrix<T, b2linalg::Mrectangle>& get_nodal_values(SetName name);
529
530 void save_state(const std::string& state_id) override {
531 if (state_buffers_size.first == 0 && state_buffers_size.second == 0) { return; }
532 {
533 std::vector<int> vi(state_buffers_size.first);
534 std::vector<double> vd(state_buffers_size.second);
535 std::pair<int*, double*> bufptr(&vi[0], &vd[0]);
536 for (list_branch_t::iterator b = list_branch.begin(); b != list_branch.end(); ++b) {
537 for (Branch::list_elements_t::iterator e = b->list_all_elements.begin();
538 e != b->list_all_elements.end(); ++e) {
539 bufptr = (*e)->get_state_buffer(bufptr);
540 }
541 }
542 if (!vi.empty()) { database->set(state_id + ".I", vi); }
543 if (!vd.empty()) { database->set(state_id + ".F", vd); }
544 }
545 }
546
547 void load_state(const std::string& state_id) override {
548 if (state_buffers_size.first == 0 && state_buffers_size.second == 0) { return; }
549 {
550 std::vector<int> vi(state_buffers_size.first);
551 std::vector<double> vd(state_buffers_size.second);
552 if (!vi.empty()) { database->get(state_id + ".I", vi); }
553 if (!vd.empty()) { database->get(state_id + ".F", vd); }
554 std::pair<const int*, const double*> bufptr(&vi[0], &vd[0]);
555 for (list_branch_t::iterator b = list_branch.begin(); b != list_branch.end(); ++b) {
556 for (Branch::list_elements_t::iterator e = b->list_all_elements.begin();
557 e != b->list_all_elements.end(); ++e) {
558 bufptr = (*e)->set_state_buffer(bufptr);
559 }
560 }
561 }
562 }
563
564 b2linalg::SparseMatrixConnectivityType get_dof_connectivity_type() const override {
565 return connectivity_type;
566 }
567
568 element_type_t get_element_base_type_code() const {
569 switch (static_cast<element_type_t>(element_base_type_code)) {
570 case element_type_t::real_symmetric:
571 return element_type_t::real_symmetric;
572 case element_type_t::real_unsymmetric:
573 return element_type_t::real_unsymmetric;
574 case element_type_t::csda_symmetric:
575 return element_type_t::csda_symmetric;
576 case element_type_t::csda_unsymmetric:
577 return element_type_t::csda_unsymmetric;
578 case element_type_t::complex_symmetric:
579 return element_type_t::complex_symmetric;
580 case element_type_t::complex_unsymmetric:
581 return element_type_t::complex_unsymmetric;
582 default:
583 return element_type_t::unknown;
584 }
585 }
586
587 bool is_unsymmetric() const {
588 if (element_base_type_code == static_cast<int>(element_type_t::unknown)) {
589 Exception() << THROW;
590 }
591 return element_base_type_code & static_cast<int>(element_type_t::real_unsymmetric);
592 }
593
594 bool is_csda() const {
595 if (element_base_type_code == static_cast<int>(element_type_t::unknown)) {
596 Exception() << THROW;
597 }
598 return element_base_type_code & static_cast<int>(element_type_t::csda_symmetric);
599 }
600
601 bool is_complex() const {
602 if (element_base_type_code == static_cast<int>(element_type_t::unknown)) {
603 Exception() << THROW;
604 }
605 return element_base_type_code & static_cast<int>(element_type_t::complex_symmetric);
606 }
607
608 Node* get_node(const std::string& node_name) override {
609 ObjectNameToNodeMap::iterator i = object_name_to_node_map.find(node_name);
610 if (i == object_name_to_node_map.end()) { return nullptr; }
611 return i->second;
612 }
613
614 Element* get_element(const std::string& element_name) override {
615 ObjectNameToElementMap::iterator i = object_name_to_element_map.find(element_name);
616 if (i == object_name_to_element_map.end()) { return nullptr; }
617 return i->second;
618 }
619
621 std::pair<int, const Node* const*> node_list,
622 std::vector<AdjacentElement>& adjacent_elements) override {
623 init_node_connectivity();
624
625 std::map<Element*, std::vector<int>> tmp;
626 for (const Node* const* n = node_list.second; n != node_list.second + node_list.first;
627 ++n) {
628 size_t nid = (*n)->get_id();
629 std::vector<std::pair<Element*, int>>::const_iterator begin =
630 node_element_connectivity.begin() + node_element_connectivity_index[nid];
631 std::vector<std::pair<Element*, int>>::const_iterator end =
632 node_element_connectivity.begin() + node_element_connectivity_index[nid + 1];
633 for (; begin != end; ++begin) { tmp[begin->first].push_back(begin->second); }
634 }
635 size_t nb_adjacent_elements = 0;
636 for (std::map<Element*, std::vector<int>>::iterator i = tmp.begin(); i != tmp.end(); ++i) {
637 if (i->second.size() == size_t(node_list.first)) { nb_adjacent_elements += 1; }
638 }
639 adjacent_elements.resize(nb_adjacent_elements);
640 nb_adjacent_elements = 0;
641 for (std::map<Element*, std::vector<int>>::iterator i = tmp.begin(); i != tmp.end(); ++i) {
642 if (i->second.size() == size_t(node_list.first)) {
643 AdjacentElement& ad = adjacent_elements[nb_adjacent_elements++];
644 ad.element = i->first;
645 ad.internal_node_id_list.swap(i->second);
646 }
647 }
648 }
649
651 const Element* e, double dist, std::vector<Element*>& element_list) override;
652
653 void get_slave_node(std::vector<std::pair<const Node*, const Node*>>& slave_node) override;
654
655 void set_dof(const b2linalg::Matrix<double, b2linalg::Mrectangle_constref>& dof) override {
656 global_dof_array_double = dof;
657 global_dof_array_csda_double =
658 b2linalg::Matrix<b2000::csda<double>, b2linalg::Mrectangle_constref>::null;
659 global_dof_array_complex_double =
660 b2linalg::Matrix<std::complex<double>, b2linalg::Mrectangle_constref>::null;
661 global_dof_array_double_tmp.resize(0, dof.size2());
662 list_element_aabb_intersection.clear();
663 }
664
665 void set_dof(const b2linalg::Matrix<b2000::csda<double>, b2linalg::Mrectangle_constref>& dof)
666 override {
667 global_dof_array_double = b2linalg::Matrix<double, b2linalg::Mrectangle_constref>::null;
668 global_dof_array_csda_double = dof;
669 global_dof_array_complex_double =
670 b2linalg::Matrix<std::complex<double>, b2linalg::Mrectangle_constref>::null;
671 global_dof_array_double_tmp.resize(0, 0);
672 list_element_aabb_intersection.clear();
673 }
674
675 void set_dof(const b2linalg::Matrix<std::complex<double>, b2linalg::Mrectangle_constref>& dof)
676 override {
677 global_dof_array_double = b2linalg::Matrix<double, b2linalg::Mrectangle_constref>::null;
678 global_dof_array_csda_double =
679 b2linalg::Matrix<b2000::csda<double>, b2linalg::Mrectangle_constref>::null;
680 global_dof_array_complex_double = dof;
681 global_dof_array_double_tmp.resize(0, 0);
682 list_element_aabb_intersection.clear();
683 }
684
685 const b2linalg::Matrix<double, b2linalg::Mrectangle_constref>& get_dof(double) override {
686 if (global_dof_array_double.is_null()) {
687 if (global_dof_array_csda_double.is_null()
688 && global_dof_array_complex_double.is_null()) {
689 return global_dof_array_double;
690 } else {
691 if (global_dof_array_double_tmp.size1()
692 != global_dof_array_complex_double.size1()) {
693 global_dof_array_double_tmp.copy_real(global_dof_array_complex_double);
694 global_dof_array_double_tmpref = global_dof_array_double_tmp;
695 }
696 return global_dof_array_double_tmpref;
697 }
698 } else {
699 return global_dof_array_double;
700 }
701 }
702
703 const b2linalg::Matrix<b2000::csda<double>, b2linalg::Mrectangle_constref>& get_dof(
704 b2000::csda<double>) override {
705 if (global_dof_array_csda_double.is_null()) {
706 if (global_dof_array_double.is_null() && global_dof_array_complex_double.is_null()) {
707 return global_dof_array_csda_double;
708 } else {
709 TypeError(
710 "Cannot obtain csda dof because the solver is "
711 "real-valued or complex-valued.")
712 << THROW;
713 }
714 } else {
715 return global_dof_array_csda_double;
716 }
717 return b2linalg::Matrix<b2000::csda<double>, b2linalg::Mrectangle_constref>::null;
718 }
719
720 const b2linalg::Matrix<std::complex<double>, b2linalg::Mrectangle_constref>& get_dof(
721 std::complex<double>) override {
722 if (global_dof_array_complex_double.is_null()) {
723 if (global_dof_array_double.is_null() && global_dof_array_csda_double.is_null()) {
724 return global_dof_array_complex_double;
725 } else {
726 TypeError(
727 "Cannot obtain complex dof because the solver is "
728 "real-valued or csda-valued.")
729 << THROW;
730 }
731 } else {
732 return global_dof_array_complex_double;
733 }
734 return b2linalg::Matrix<std::complex<double>, b2linalg::Mrectangle_constref>::null;
735 }
736
737 const std::pair<std::map<std::string, size_t>, b2linalg::Index>& get_dof_field() override {
738 if (dof_field.second.size() != nb_dof) {
739 dof_field.first.clear();
740 dof_field.first["Unknown"] = 0;
741 dof_field.second.resize(nb_dof);
742 dof_field.second.set_zero();
743 DegreesOfFreedom::ListDofField ldf = {
744 dof_field.first,
745 dof_field.second,
746 };
747 {
748 node_iterator i = get_node_iterator();
749 for (Node* node = i->next(); node != nullptr; node = i->next()) {
750 node->add_dof_field(ldf);
751 }
752 }
753 {
754 element_iterator i = get_element_iterator();
755 for (Element* element = i->next(); element != nullptr; element = i->next()) {
756 element->add_dof_field(ldf);
757 }
758 }
759 }
760 return dof_field;
761 }
762
763 std::pair<size_t, size_t> get_internal_branch_and_element_id(const Element& e) {
764 const size_t eid = e.get_id();
765 const std::vector<size_t>::const_iterator i =
766 std::upper_bound(
767 first_element_internal_id_of_branch.begin(),
768 first_element_internal_id_of_branch.end(), eid)
769 - 1;
770 return std::pair<size_t, size_t>(i - first_element_internal_id_of_branch.begin(), eid - *i);
771 }
772
773 std::pair<size_t, size_t> get_internal_branch_and_node_id(const Node& n) {
774 const size_t eid = n.get_id();
775 const std::vector<size_t>::const_iterator i =
776 std::upper_bound(
777 first_node_internal_id_of_branch.begin(),
778 first_node_internal_id_of_branch.end(), eid)
779 - 1;
780 return std::pair<size_t, size_t>(i - first_node_internal_id_of_branch.begin(), eid - *i);
781 }
782
784 b2000::Domain& parent_domain, const b2000::Element& element,
785 b2linalg::Matrix<double>& parent_nodes_internal_coor) override {
786 std::pair<size_t, size_t> iid = get_internal_branch_and_element_id(element);
787 if (list_branch[iid.first].parent_element_mapping.empty()) {
788 DBError() << "The set MULTISCALE-NODE-MAPPINGS." << list_branch[iid.first].id
789 << " is missing on the database." << THROW;
790 }
791 const Branch::ParentElementMapping& pem =
792 list_branch[iid.first].parent_element_mapping[iid.second];
793 if (!parent_nodes_internal_coor.is_null()) {
794 parent_nodes_internal_coor = pem.global_icoor;
795 }
796 Domain& d = dynamic_cast<Domain&>(parent_domain);
797 if (pem.parent_internal_branch >= d.list_branch.size()) {
798 DBError() << "The set MULTISCALE-NODE-MAPPINGS." << list_branch[iid.first].id
799 << " has some wrong internal branch id." << THROW;
800 }
801 if (pem.parent_internal_element
802 >= d.list_branch[pem.parent_internal_branch].list_all_elements.size()) {
803 DBError() << "The set MULTISCALE-NODE-MAPPINGS." << list_branch[iid.first].id
804 << " has some wrong internal element id." << THROW;
805 }
806 return d.list_branch[pem.parent_internal_branch]
807 .list_all_elements[pem.parent_internal_element];
808 }
809
811 b2000::Domain& parent_domain, const b2000::Node& node,
812 b2linalg::Vector<double>& parent_internal_coor) override {
813 std::pair<size_t, size_t> iid = get_internal_branch_and_node_id(node);
814 if (list_branch[iid.first].parent_node_mapping.empty()) {
815 DBError() << "The set MULTISCALE-NODE-MAPPINGS." << list_branch[iid.first].id
816 << " is missing on the database." << THROW;
817 }
818 const Branch::ParentNodeMapping& pnm =
819 list_branch[iid.first].parent_node_mapping[iid.second];
820 if (!parent_internal_coor.is_null()) {
821 parent_internal_coor.assign(pnm.global_icoor, pnm.global_icoor + 3);
822 }
823 Domain& d = dynamic_cast<Domain&>(parent_domain);
824 if (pnm.parent_internal_branch >= d.list_branch.size()) {
825 DBError() << "The set MULTISCALE-NODE-MAPPINGS." << list_branch[iid.first].id
826 << " has some wrong internal branch id." << THROW;
827 }
828 if (pnm.parent_internal_element
829 >= d.list_branch[pnm.parent_internal_branch].list_all_elements.size()) {
830 DBError() << "The set MULTISCALE-NODE-MAPPINGS." << list_branch[iid.first].id
831 << " has some wrong internal element id." << THROW;
832 }
833 return d.list_branch[pnm.parent_internal_branch]
834 .list_all_elements[pnm.parent_internal_element];
835 }
836
837 const double* get_node_local_referential_double(const Node& node) const override {
838 if (nodes_local_referential.empty()) { return nullptr; }
839 assert(node.get_id() < nodes_local_referential.size());
840 return nodes_local_referential[node.get_id()];
841 }
842
843 const b2000::csda<double>* get_node_local_referential_csda(const Node& node) const override {
844 if (nodes_local_referential_cs.empty()) { return nullptr; }
845 assert(node.get_id() < nodes_local_referential_cs.size());
846 return nodes_local_referential_cs[node.get_id()];
847 }
848
849protected:
850 class MaterialIterator {
851 public:
852 MaterialProperty* next() {
853 if (start == end) { return nullptr; }
854 return (*start++).second.first;
855 }
856
857 private:
858 MaterialIterator(Materials& materials) : start(materials.begin()), end(materials.end()) {}
859 Materials::iterator start;
860 Materials::const_iterator end;
861 friend class b2dbv3::Domain;
862 };
863
864 MaterialIterator* get_material_iterator() { return new MaterialIterator(materials); }
865
866 MaterialIterator* get_property_iterator() { return new MaterialIterator(properties); }
867
868private:
869 Allocator allocator;
870 Model* model{};
871 DataBase* database{};
872 size_t nb_dof{};
873 b2linalg::SparseMatrixConnectivityType connectivity_type{
874 b2linalg::sparse_matrix_connectivity_unknown};
875 DomainProperty property{*this};
876 std::vector<Element::VariableInfo> value_info;
877 std::pair<size_t, size_t> state_buffers_size;
878 int element_base_type_code{static_cast<int>(element_type_t::real_symmetric)};
879
880 b2linalg::Matrix<double, b2linalg::Mrectangle_constref> global_dof_array_double;
881 b2linalg::Matrix<b2000::csda<double>, b2linalg::Mrectangle_constref>
882 global_dof_array_csda_double;
883 b2linalg::Matrix<std::complex<double>, b2linalg::Mrectangle_constref>
884 global_dof_array_complex_double;
885
886 b2linalg::Matrix<double, b2linalg::Mrectangle> global_dof_array_double_tmp;
887 b2linalg::Matrix<double, b2linalg::Mrectangle_constref> global_dof_array_double_tmpref;
888
889 std::vector<std::pair<Element*, int>> node_element_connectivity;
890 std::vector<size_t> node_element_connectivity_index;
891
892 std::map<std::string, b2linalg::Matrix<double, b2linalg::Mrectangle>> list_nodal_values;
893 std::map<std::string, b2linalg::Matrix<b2000::csda<double>, b2linalg::Mrectangle>>
894 list_nodal_values_cs;
895
896 std::pair<std::map<std::string, size_t>, b2linalg::Index> dof_field;
897
898 using merged_node_type_t = std::map<std::pair<Node::type_t*, Node::type_t*>, Node::type_t*>;
899 merged_node_type_t merged_node_type;
900
901 using list_one_node_pear_node_type_t = std::map<Node::type_t*, Node*>;
902
903 using ObjectNameToNodeMap = std::map<std::string, Node*>;
904 ObjectNameToNodeMap object_name_to_node_map;
905 using ObjectNameToElementMap = std::map<std::string, Element*>;
906 ObjectNameToElementMap object_name_to_element_map;
907
908 list_one_node_pear_node_type_t list_one_node_pear_node_type;
909 Node::type_t* get_merged_node_type(Node::type_t* a, Node::type_t* b) {
910 if (a == b) { return a; }
911 if (a > b) { std::swap(a, b); }
912 Node::type_t* mnt = merged_node_type[std::pair<Node::type_t*, Node::type_t*>(a, b)];
913 if (mnt != nullptr) { return mnt; }
914 if (list_one_node_pear_node_type.empty()) {
915 const std::map<std::string, ObjectType*>& node_type_list =
916 node::module.get_object_types_list();
917 for (std::map<std::string, ObjectType*>::const_iterator i = node_type_list.begin();
918 i != node_type_list.end(); ++i) {
919 Node::type_t* nt = dynamic_cast<Node::type_t*>(i->second);
920 if (nt == nullptr) {
921 Exception() << "Internal error: Object identified by \"" << i->first
922 << "\" cannot be cast to Node::type_t*." << THROW;
923 }
924 list_one_node_pear_node_type[nt] = nt->new_object(allocator);
925 }
926 }
927 Node* na = list_one_node_pear_node_type[a];
928 Node* nb = list_one_node_pear_node_type[b];
929 for (list_one_node_pear_node_type_t::iterator i = list_one_node_pear_node_type.begin();
930 i != list_one_node_pear_node_type.end(); ++i) {
931 if (na->is_subnode(i->second) && nb->is_subnode(i->second)) {
932 // we have a candidate node
933 if (mnt == nullptr) {
934 mnt = i->first;
935 } else {
936 // we take the node with the minimum dof
937 if (list_one_node_pear_node_type[mnt]->get_number_of_dof()
938 > i->second->get_number_of_dof()) {
939 mnt = i->first;
940 }
941 }
942 }
943 }
944 if (mnt == nullptr) {
945 IOError() << "Could not find a common node type for the nodes " << a->get_cpp_name()
946 << " and " << b->get_cpp_name() << "." << THROW;
947 } else {
948 merged_node_type[std::pair<Node::type_t*, Node::type_t*>(a, b)] = mnt;
949 }
950 // std::cout << "merge " << a->get_cpp_name() << " and " << b->get_cpp_name() << " get " <<
951 // mnt->get_cpp_name() << std::endl;
952 return mnt;
953 }
954
955 void init_node_connectivity();
956
957 struct ElementIndex {
958 const std::type_info& type;
959 bool operator<(const ElementIndex& e) const { return type.before(e.type); }
960 };
961
962 struct ElementIntersectionIndex {
963 const double dist;
964 const std::type_info& type;
965 bool operator<(const ElementIntersectionIndex& e) const {
966 if (dist == e.dist) { return type.before(e.type); }
967 return dist < e.dist;
968 }
969 };
970
971 struct AABBox {
972 static const int ndim = 3;
973 double min[3];
974 double max[3];
975 };
976
977 template <typename SET = std::set<Element*>>
978 struct PairIntersectionList {
979 void init(
980 size_t size, const AABBox* start_aabb_,
981 const std::vector<std::pair<Element*, size_t>>& list_element_) {
982 start_aabb = start_aabb_;
983 list_element = &list_element_;
984 pair_list.assign(size, std::set<Element*>());
985 nb_pair = 0;
986 }
987 void add(const AABBox* a, const AABBox* b) {
988 size_t ai = a - start_aabb;
989 size_t bi = b - start_aabb;
990 if ((*list_element)[ai].second == (*list_element)[bi].second) { return; }
991 if (ai > bi) { std::swap(ai, bi); }
992 if (pair_list[(*list_element)[ai].first->get_id()]
993 .insert((*list_element)[bi].first)
994 .second) {
995 ++nb_pair;
996 }
997 return;
998 }
999 size_t get_nb_pair() const { return nb_pair; }
1000 std::vector<SET> pair_list;
1001 size_t nb_pair;
1002 const AABBox* start_aabb;
1003 const std::vector<std::pair<Element*, size_t>>* list_element;
1004 };
1005
1006 std::map<ElementIntersectionIndex, PairIntersectionList<std::set<Element*>>>
1007 list_element_aabb_intersection;
1008 std::map<ElementIndex, std::vector<std::pair<Element*, size_t>>> list_element_abbbb;
1009
1010 b2spin_rw_mutex list_element_aabb_intersection_mutex;
1011
1012public:
1013 using type_t = ObjectTypeComplete<Domain, b2000::Domain::type_t>;
1014 static type_t type;
1015};
1016
1017template <>
1018inline const b2linalg::Matrix<double, b2linalg::Mrectangle>& Domain::get_nodal_values(
1019 SetName name) {
1020 return get_nodal_values_double(name);
1021}
1022
1023template <>
1024inline const b2linalg::Matrix<b2000::csda<double>, b2linalg::Mrectangle>& Domain::get_nodal_values(
1025 SetName name) {
1026 return get_nodal_values_csda(name);
1027}
1028
1029} // namespace b2000::b2dbv3
1030
1031template <typename T>
1032void b2000::b2dbv3::Domain::save_global_dof(
1033 SetName name, const b2linalg::Vector<T, b2linalg::Vdense_constref>& dof, RTable desc) {
1034 desc.set("SYSTEM", "BRANCH");
1035 desc.set("TYPE", "CELL");
1036 size_t pos = 0;
1037
1038 SetName name_e = name;
1039 name_e.gname(name.get_gname() + "_E");
1040 for (size_t branch = 0; branch != list_branch.size(); ++branch) {
1041 name_e.branch(list_branch[branch].id);
1042 if (list_branch[branch].max_number_of_dof_by_element == 0) { continue; }
1043 if (list_branch[branch].min_number_of_dof_by_element
1044 < list_branch[branch].max_number_of_dof_by_element) {
1045 b2linalg::Matrix<T, b2linalg::Mrectangle> m(
1046 list_branch[branch].max_number_of_dof_by_element,
1047 list_branch[branch].list_all_elements.size());
1048 Branch::list_elements_t& le = list_branch[branch].list_all_elements;
1049 for (size_t i = 0; i != m.size2(); ++i) {
1050 int s = le[i]->get_number_of_dof();
1051 std::copy(&dof[pos], &dof[pos + s], &m(0, i));
1052 pos += s;
1053 }
1054 database->set(name_e, m);
1055 } else {
1056 b2linalg::Interval interval(pos, pos + list_branch[branch].nb_element_dof);
1057 database->set(
1058 name_e, b2linalg::Matrix<T, b2linalg::Mrectangle_constref>(
1059 list_branch[branch].max_number_of_dof_by_element,
1060 list_branch[branch].list_all_elements.size(), dof(interval)));
1061 pos += list_branch[branch].nb_element_dof;
1062 }
1063 database->set_desc(name_e, desc);
1064 }
1065
1066 desc.set("TYPE", "NODE");
1067 for (size_t branch = 0; branch != list_branch.size(); ++branch) {
1068 name.branch(list_branch[branch].id);
1069 if (list_branch[branch].max_number_of_dof_by_node == 0) { continue; }
1070 if (list_branch[branch].min_number_of_dof_by_node
1071 < list_branch[branch].max_number_of_dof_by_node) {
1072 b2linalg::Matrix<T, b2linalg::Mrectangle> m(
1073 list_branch[branch].max_number_of_dof_by_node,
1074 list_branch[branch].list_nodes.size());
1075 Branch::list_nodes_t& ln = list_branch[branch].list_nodes;
1076 for (size_t i = 0; i != m.size2(); ++i) {
1077 int s = ln[i]->get_number_of_dof();
1078 std::copy(&dof[pos], &dof[pos + s], &m(0, i));
1079 pos += s;
1080 }
1081 database->set(name, m);
1082 } else {
1083 b2linalg::Interval interval(pos, pos + list_branch[branch].nb_node_dof);
1084 database->set(
1085 name, b2linalg::Matrix<T, b2linalg::Mrectangle_constref>(
1086 list_branch[branch].max_number_of_dof_by_node,
1087 list_branch[branch].list_nodes.size(), dof(interval)));
1088 pos += list_branch[branch].nb_node_dof;
1089 }
1090 database->set_desc(name, desc);
1091 }
1092}
1093
1094template <typename T>
1095void b2000::b2dbv3::Domain::save_global_dof_indexed(
1096 SetName name, const b2linalg::Vector<T, b2linalg::Vdense_constref>& dof, RTable desc) {
1097 desc.set("SYSTEM", "BRANCH");
1098 desc.set("TYPE", "NODE");
1099 desc.set("INDEXED", true);
1100
1101 SetName name_e = name;
1102 name_e.gname(name.get_gname() + "_E");
1103 for (size_t branch = 0; branch != list_branch.size(); ++branch) {
1104 if (list_branch[branch].max_number_of_dof_by_element == 0) { continue; }
1105 Branch::list_elements_t& le = list_branch[branch].list_all_elements;
1106 std::vector<T> res;
1107 res.reserve(list_branch[branch].max_number_of_dof_by_element * le.size() * 3);
1108 for (size_t i = 0; i != le.size(); ++i) {
1109 size_t dof_id = 1;
1110 for (std::pair<size_t, size_t> dn = le[i]->get_global_dof_numbering();
1111 dn.first != dn.second; ++dn.first, ++dof_id) {
1112 if (dof[dn.first] != T(0)) {
1113 res.push_back(le[i]->get_id() + 1);
1114 res.push_back(dof_id);
1115 res.push_back(dof[dn.first]);
1116 }
1117 }
1118 }
1119 if (!res.empty()) {
1120 name_e.branch(list_branch[branch].id);
1121 database->set(
1122 name_e,
1123 b2linalg::Matrix<T, b2linalg::Mrectangle_constref>(3, res.size() / 3, &res[0]));
1124 database->set_desc(name_e, desc);
1125 }
1126 }
1127
1128 for (size_t branch = 0; branch != list_branch.size(); ++branch) {
1129 name.branch(list_branch[branch].id);
1130 if (list_branch[branch].max_number_of_dof_by_node == 0) { continue; }
1131 Branch::list_nodes_t& ln = list_branch[branch].list_nodes;
1132 std::vector<T> res;
1133 res.reserve(list_branch[branch].max_number_of_dof_by_node * ln.size() * 3);
1134 for (size_t i = 0; i != ln.size(); ++i) {
1135 size_t dof_id = 1;
1136 for (std::pair<size_t, size_t> dn = ln[i]->get_global_dof_numbering();
1137 dn.first != dn.second; ++dn.first, ++dof_id) {
1138 if (dof[dn.first] != T(0)) {
1139 res.push_back(ln[i]->get_id() + 1);
1140 res.push_back(dof_id);
1141 res.push_back(dof[dn.first]);
1142 }
1143 }
1144 }
1145 if (!res.empty()) {
1146 name.branch(list_branch[branch].id);
1147 database->set(
1148 name,
1149 b2linalg::Matrix<T, b2linalg::Mrectangle_constref>(3, res.size() / 3, &res[0]));
1150 database->set_desc(name, desc);
1151 }
1152 }
1153}
1154
1155template <typename T>
1156void b2000::b2dbv3::Domain::load_global_dof(
1157 SetName name, b2linalg::Vector<T, b2linalg::Vdense_ref> dof, RTable* rtable) {
1158 size_t pos = 0;
1159 bool zero_init = true;
1160
1161 SetName name_e = name;
1162 name_e.gname(name.get_gname() + "_E");
1163 for (size_t branch = 0; branch != list_branch.size(); ++branch) {
1164 if (list_branch[branch].max_number_of_dof_by_element == 0) { continue; }
1165 name_e.branch(list_branch[branch].id);
1166 if (!database->has_key(name_e)) {
1167 std::fill_n(&dof[pos], list_branch[branch].nb_element_dof, 0);
1168 pos += list_branch[branch].nb_element_dof;
1169 } else {
1170 if (rtable) { database->get_desc(name_e, *rtable); }
1171 if (list_branch[branch].min_number_of_dof_by_element
1172 < list_branch[branch].max_number_of_dof_by_element) {
1173 zero_init = false;
1174 b2linalg::Matrix<T, b2linalg::Mrectangle> m(
1175 list_branch[branch].max_number_of_dof_by_element,
1176 list_branch[branch].list_all_elements.size());
1177 database->get(name_e, m);
1178 Branch::list_elements_t& ln = list_branch[branch].list_all_elements;
1179 for (size_t i = 0; i != m.size2(); ++i) {
1180 int s = ln[i]->get_number_of_dof();
1181 std::copy(&m(0, i), &m(0, i) + s, &dof[pos]);
1182 pos += s;
1183 }
1184 } else {
1185 zero_init = false;
1186 b2linalg::Interval interval(pos, pos + list_branch[branch].nb_element_dof);
1187 database->get(
1188 (const std::string&)name_e,
1189 b2linalg::Matrix<T, b2linalg::Mrectangle_increment_ref>(
1190 b2linalg::Matrix<T, b2linalg::Mrectangle_ref>(
1191 list_branch[branch].max_number_of_dof_by_element,
1192 list_branch[branch].list_all_elements.size(), dof(interval))));
1193 pos += list_branch[branch].nb_element_dof;
1194 }
1195 }
1196 }
1197
1198 for (size_t branch = 0; branch != list_branch.size(); ++branch) {
1199 name.branch(list_branch[branch].id);
1200 if (!database->has_key(name)) {
1201 std::fill_n(&dof[pos], list_branch[branch].nb_node_dof, 0);
1202 pos += list_branch[branch].nb_node_dof;
1203 continue;
1204 }
1205 RTable desc_;
1206 RTable desc = rtable ? *rtable : desc_;
1207 bool has_desc = database->get_desc(name, desc, false);
1208 if (has_desc && desc.get_string("DOMAIN", "") == "DOF" && desc.get_bool("INDEXED", false)) {
1209 zero_init = false;
1210 b2linalg::Matrix<T, b2linalg::Mrectangle> m;
1211 database->get(name, m);
1212 std::fill_n(&dof[pos], list_branch[branch].nb_node_dof, 0);
1213 for (size_t i = 0; i != m.size2(); ++i) {
1214 size_t n = size_t(b2000::real(m(0, i))) - 1;
1215 const std::pair<size_t, size_t> node_dof =
1216 list_branch[branch].list_nodes[n]->get_global_dof_numbering();
1217 ssize_t d = ssize_t(b2000::real(m(1, i))) - 1;
1218 if (d < 0) {
1219 DBError() << "A dof number of a node cannot be a negative value."
1220 " In the dataset "
1221 << name << ", row " << i + 1 << "." << THROW;
1222 }
1223 d += node_dof.first;
1224 if (d <= ssize_t(node_dof.second)) { dof[d] = m(2, i); }
1225 }
1226 pos += list_branch[branch].nb_node_dof;
1227 } else if (has_desc && desc.get_string("TYPE", "") == "NODE-INDEXED") {
1228 zero_init = false;
1229 b2linalg::Matrix<T, b2linalg::Mrectangle> m;
1230 database->get(name, m);
1231 std::fill_n(&dof[pos], list_branch[branch].nb_node_dof, 0);
1232 for (size_t i = 0; i != m.size2(); ++i) {
1233 size_t n = size_t(b2000::real(m(0, i))) - 1;
1234 const std::pair<size_t, size_t> node_dof =
1235 list_branch[branch].list_nodes[n]->get_global_dof_numbering();
1236 const size_t s = std::min(node_dof.second - node_dof.first, m.size1());
1237 std::copy(&m(1, i), &m(1, i) + s, &dof[pos + node_dof.first]);
1238 }
1239 pos += list_branch[branch].nb_node_dof;
1240 } else {
1241 zero_init = false;
1242 if (list_branch[branch].min_number_of_dof_by_node
1243 < list_branch[branch].max_number_of_dof_by_node) {
1244 b2linalg::Matrix<T, b2linalg::Mrectangle> m(
1245 list_branch[branch].max_number_of_dof_by_node,
1246 list_branch[branch].list_nodes.size());
1247 database->get(name, m);
1248 Branch::list_nodes_t& ln = list_branch[branch].list_nodes;
1249 for (size_t i = 0; i != m.size2(); ++i) {
1250 int s = ln[i]->get_number_of_dof();
1251 std::copy(&m(0, i), &m(0, i) + s, &dof[pos]);
1252 pos += s;
1253 }
1254 } else {
1255 b2linalg::Interval interval(pos, pos + list_branch[branch].nb_node_dof);
1256 database->get(
1257 (const std::string&)name,
1258 b2linalg::Matrix<T, b2linalg::Mrectangle_increment_ref>(
1259 b2linalg::Matrix<T, b2linalg::Mrectangle_ref>(
1260 list_branch[branch].max_number_of_dof_by_node,
1261 list_branch[branch].list_nodes.size(), dof(interval))));
1262 pos += list_branch[branch].nb_node_dof;
1263 }
1264 }
1265 }
1266 if (zero_init) {
1267 DBError() << "The set " << name << " could not be read or is empty." << THROW;
1268 }
1269}
1270
1271#endif // B2DOMAIN_DATABASE_H_
bool operator<(const csda< T1 > &a, const csda< T2 > &b)
Comparison of two csda numbers is performed on the real part only.
Definition b2csda.H:262
#define THROW
Definition b2exception.H:198
Definition b2case.H:110
const std::vector< size_t > dims(const std::string &key) const
Definition b2database.H:389
bool has_key(const std::string &key) const
Definition b2database.H:323
void get(const std::string &key, std::vector< T > &v, const DBSlice &s1=DBSlice::all) const
Read a positional dataset.
Definition b2database.H:458
void set(const std::string &key, const std::vector< T > &v, const DBSlice &s1=DBSlice::all, bool new_set=false)
Write a positional dataset.
Definition b2database.H:888
Definition b2domain.H:88
Definition b2domain.H:78
Definition b2domain.H:70
Defines the complete interface for Element instances (C++ representations of Finite Elements).
Definition b2element.H:156
iterator begin()
Definition b2element.H:583
Definition b2model.H:69
Definition b2node.H:53
size_t get_id() const
Definition b2node.H:67
Definition b2rtable.H:427
void set(const std::string &key, const T &v, const bool new_key=false)
Assign a single value. If new_key is true, the key must not exist.
Definition b2rtable.H:463
MemCom dataset names according to the B2000++ conventions.
Definition b2database.H:49
A in-core implementation of the b2dbv3::Domain. All the Element, Node and ElementProperty objects are...
Definition b2domain_database.H:62
size_t get_number_of_dof() const override
Definition b2domain_database.H:89
void set_dof(const b2linalg::Matrix< double, b2linalg::Mrectangle_constref > &dof) override
Definition b2domain_database.H:655
element_iterator get_element_iterator() override
Definition b2domain_database.H:379
Element * get_element(const std::string &element_name) override
Definition b2domain_database.H:614
const b2000::csda< double > * get_node_local_referential_csda(const Node &node) const override
Definition b2domain_database.H:843
size_t get_number_of_elements() const override
Definition b2domain_database.H:91
bool have_temperature() const override
Definition b2domain_database.H:82
void get_adjacent_elements(std::pair< int, const Node *const * > node_list, std::vector< AdjacentElement > &adjacent_elements) override
Definition b2domain_database.H:620
void set_dof(const b2linalg::Matrix< b2000::csda< double >, b2linalg::Mrectangle_constref > &dof) override
Definition b2domain_database.H:665
b2linalg::SparseMatrixConnectivityType get_dof_connectivity_type() const override
Definition b2domain_database.H:564
void get_elements_of_same_type_near(const Element *e, double dist, std::vector< Element * > &element_list) override
Definition b2domain_database.C:1093
const b2linalg::Matrix< double, b2linalg::Mrectangle_constref > & get_dof(double) override
Definition b2domain_database.H:685
void set_case(b2000::Case &case_) override
Definition b2domain_database.C:835
size_t get_number_of_nodes() const override
Definition b2domain_database.H:107
Node * get_node(const std::string &node_name) override
Definition b2domain_database.H:608
void save_state(const std::string &state_id) override
Definition b2domain_database.H:530
void save_field(const std::string &name, const b2linalg::Vector< std::complex< double >, b2linalg::Vdense_constref > &dof) override
Definition b2domain_database.H:438
void set_dof(const b2linalg::Matrix< std::complex< double >, b2linalg::Mrectangle_constref > &dof) override
Definition b2domain_database.H:675
void save_field(const std::string &name, const b2linalg::Vector< double, b2linalg::Vdense_constref > &dof) override
Definition b2domain_database.H:420
size_t get_number_of_elements_and_subelements() const override
Definition b2domain_database.H:99
void set_subcase_id(const int subcase_id_) override
Definition b2domain_database.H:78
const double * get_node_local_referential_double(const Node &node) const override
Definition b2domain_database.H:837
Element * get_parent_element_mapping(b2000::Domain &parent_domain, const b2000::Node &node, b2linalg::Vector< double > &parent_internal_coor) override
Definition b2domain_database.H:810
Element * get_parent_element_and_nodes_mapping(b2000::Domain &parent_domain, const b2000::Element &element, b2linalg::Matrix< double > &parent_nodes_internal_coor) override
Definition b2domain_database.H:783
node_iterator get_node_iterator() override
Definition b2domain_database.H:311
void load_state(const std::string &state_id) override
Definition b2domain_database.H:547
void set_model(b2000::Model &model) override
Definition b2domain_database.C:95
void save_field(const std::string &name, const b2linalg::Vector< b2000::csda< double >, b2linalg::Vdense_constref > &dof) override
Definition b2domain_database.H:429
void get_slave_node(std::vector< std::pair< const Node *, const Node * > > &slave_node) override
Definition b2domain_database.C:1164
const std::vector< Element::VariableInfo > get_value_info() const override
Definition b2domain_database.H:115
Definition b2fortran_element_property.H:53
Definition b2material_property.H:30
GenericException< IOError_name > IOError
Definition b2exception.H:335
GenericException< KeyError_name > KeyError
Definition b2exception.H:320
GenericException< TypeError_name > TypeError
Definition b2exception.H:325
GenericException< DBError_name > DBError
Definition b2exception.H:340
Definition b2domain.H:105
Element * element
Definition b2domain.H:107