G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsBoundaryConditions.hpp
Go to the documentation of this file.
1
14#include <gsIO/gsXml.h>
19
20namespace gismo
21{
22
23namespace internal
24{
25
27template<class T>
28class gsXml< gsBoundaryConditions<T> >
29{
30private:
31 gsXml() { }
32 typedef gsBoundaryConditions<T> Object;
33public:
34 GSXML_COMMON_FUNCTIONS(Object);
35 static std::string tag () { return "boundaryConditions"; }
36 static std::string type () { return ""; }
37
38 GSXML_GET_POINTER(Object);
39
40 static void get_into(gsXmlNode * node, Object & result)
41 {
42 GISMO_ASSERT(!strcmp(node->name(), tag().c_str()),
43 "Something went wrong. Expected tag "<< tag());
44
45 std::istringstream str;
46 std::map<int, int> ids;
47
48 // Check if any of the BCs is defined on a boundary set name
49 const int mp_index = atoi(node->first_attribute("multipatch")->value());
50 gsXmlNode* toplevel = node->parent();
51 std::vector< patchSide > allboundaries;
52 for (gsXmlNode * child = node->first_node("bc"); child;
53 child = child->next_sibling("bc"))
54 {
55 std::map<int, int> tmp_ids;;
56
57 const gsXmlAttribute * att_name = child->first_attribute("name");
58 if (NULL != att_name)
59 {
60 gsXmlNode* mp_node = searchId(mp_index, toplevel);
61 GISMO_ASSERT( mp_node != NULL,
62 "No Multipatch with Id "<<mp_index<<" found in the XML data.");
63
64 gsXmlNode * tmp = mp_node->first_node("patches");
65 std::istringstream tmp_str ;
66 tmp_str.str( tmp->value() );
67 // Handle id_range or id_index for multipatches. This is needed to assign the right indices for the BCs
68 if ( ! strcmp( tmp->first_attribute("type")->value(),"id_range") )
69 {
70 int first, last;
71 gsGetInt(tmp_str, first);
72 gsGetInt(tmp_str, last);
73 for ( int i = first; i<=last; ++i )
74 tmp_ids[i] = i - first;
75 }
76 else if ( ! strcmp( tmp->first_attribute("type")->value(),"id_index") )
77 {
78 int c = 0;
79 for (int pindex; gsGetInt(tmp_str, pindex);)
80 tmp_ids[pindex] = c++;
81 }
82 else
83 {
84 gsWarn<<"Unknown tag in XML multipatch object.\n";
85 }
86
87 for (gsXmlNode * ch= mp_node->first_node("boundary"); ch;
88 ch = ch->next_sibling("boundary"))
89 {
90 std::vector< patchSide > tmp_boundaries;
91 if (ch)
92 {
93 getBoundaries(ch, tmp_ids, tmp_boundaries);
94 allboundaries.insert( allboundaries.end(), tmp_boundaries.begin(), tmp_boundaries.end() );
95 }
96 }
97 break;
98 }
99 }
100
101 //gsXmlNode * tmp = node->first_node("patches");
102 //GISMO_ASSERT(tmp, "No pathes tag");
103//
104// std::istringstream str;
105// str.str( tmp->value() );
106// // Resolve ID numbers
107// std::map<int,int> ids;
108// if ( ! strcmp( tmp->first_attribute("type")->value(), "id_range") )
109// {
110// int first, last;
111// gsGetInt(str, first);
112// gsGetInt(str, last);
113// for ( int i = first; i<=last; ++i )
114// ids[i] = i - first;
115// }
116// else if ( ! strcmp( tmp->first_attribute("type")->value(),"id_index") )
117// {
118// int c = 0;
119// for (int pindex; gsGetInt(str, pindex);)
120// ids[pindex] = c++;
121// }
122// else
123// {
124// gsWarn<<"Incomplete tag \"patch\" in boundaryConditions.\n";
125// }
126
127 // Read function inventory using a map, in case indices are not
128 // consecutive
129 std::map<int, typename gsFunctionExpr<T>::Ptr> function_map{};
130 for (gsXmlNode* child = node->first_node("Function"); child;
131 child = child->next_sibling("Function")) {
132 const int function_index =
133 atoi(child->first_attribute("index")->value());
134 function_map[function_index] =
135 memory::make_shared(new gsFunctionExpr<T>);
136 internal::gsXml<gsFunctionExpr<T> >::get_into(
137 child, *function_map[function_index]);
138 }
139
140 // Read boundary conditions
141 std::vector<patchSide> boundaries;
142 for (gsXmlNode* child = node->first_node("bc"); child;
143 child = child->next_sibling("bc")) {
144 const int uIndex = atoi(child->first_attribute("unknown")->value());
145 const int fIndex = atoi(child->first_attribute("function")->value());
146
147 const gsXmlAttribute* comp = child->first_attribute("component");
148 int cIndex = -1;
149 if (NULL != comp) cIndex = atoi(comp->value());
150
151 const gsXmlAttribute* att_ispar =
152 child->first_attribute("parametric");
153 bool ispar = false;
154 if (NULL != att_ispar) ispar = atoi(att_ispar->value());
155
156 const gsXmlAttribute* att_name = child->first_attribute("name");
157 if (NULL != att_name) {
158 boundaries.clear();
159 std::string name = att_name->value();
160 for (typename std::vector<patchSide>::const_iterator it =
161 allboundaries.begin();
162 it != allboundaries.end(); it++)
163 if (it->label() == name) boundaries.push_back(*it);
164 } else
165 getBoundaries(child, ids, boundaries);
166
167 if (boundaries.size() == 0) {
168 gsWarn << "Boundary condition without boundary to apply to. The"
169 " following bc will be unused\n"
170 << *child << std::endl;
171 }
172
173 const gsXmlAttribute* bcat = child->first_attribute("type");
174 GISMO_ASSERT(NULL != bcat, "No type provided");
175 const char* bctype = bcat->value();
176 for (std::vector<patchSide>::const_iterator it = boundaries.begin();
177 it != boundaries.end(); ++it)
178 result.add(it->patch, it->side(), bctype, function_map[fIndex], uIndex,
179 cIndex, ispar);
180 }
181
182 T val(0);
183 for (gsXmlNode * child = node->first_node("cv"); child;
184 child = child->next_sibling("cv"))
185 {
186 str.clear();
187 str.str(child->value());
188 GISMO_ENSURE(gsGetReal(str, val), "No value");
189
190 // Unknown is optional, otherwise 0
191 const gsXmlAttribute * unk = child->first_attribute("unknown");
192 int uIndex = 0;
193 if (NULL != unk)
194 uIndex = atoi( unk->value() );
195
196 // Component is optional, otherwise -1
197 const gsXmlAttribute * comp = child->first_attribute("component");
198 int cIndex = -1;
199 if (NULL != comp)
200 cIndex = atoi( comp->value() );
201
202 const int cornIndex = atoi(child->first_attribute("corner")->value());
203 int pIndex = atoi(child->first_attribute("patch")->value());
204
205 result.addCornerValue(cornIndex, val, pIndex, uIndex, cIndex);
206 }
207 }
208
209 static gsXmlNode * put(const Object & obj, gsXmlTree & data)
210 {
211 // Check if the last node is a multipatch
212 //gsXmlNode * mp = data.getRoot()->last_node("MultiPatch");
213
214 gsXmlNode * BCs = internal::makeNode("boundaryConditions", data);
215 //data.appendToRoot(BCs);
216 gsXmlAttribute * multi = internal::makeAttribute("multipatch", "0",
217 data);
218
219 BCs->append_attribute(multi);
220
221 // inventory of functions
222 typedef typename gsBoundaryConditions<T>::const_bciterator bctype_it;
223 typedef typename Object::const_iterator bc_it;
224
225 std::vector<typename gsFunctionSet<T>::Ptr> fun;
226 //gsSortedVector<typename gsFunction<T>::Ptr> fun;
227 typedef typename std::vector<const boundary_condition<T>*> bctype_vec;
228 typedef typename std::map<int, bctype_vec> bctype_map;
229 std::map<std::string, bctype_map> fi;
230
231 for (bctype_it it = obj.beginAll(); it != obj.endAll(); ++it)
232 {
233 std::string label = it->first;
234 bctype_map map;
235 for (bc_it bc = it->second.begin(); bc != it->second.end(); ++bc)
236 {
237 typename gsFunctionSet<T>::Ptr ptr = bc->function();
238 bool contains = std::find(fun.begin(), fun.end(), ptr)
239 != fun.end();
240 if (!contains)
241 {
242 fun.push_back(ptr);
243 }
244 int index = std::find(fun.begin(), fun.end(), ptr)
245 - fun.begin();
246// fun.push_sorted_unique(ptr);
247// int index = fun.getIndex(ptr);
248 std::vector<const boundary_condition<T>*> vec = map[index];
249 const boundary_condition<T>* b = &(*bc);
250 vec.push_back(b);
251 map[index] = vec;
252 }
253 std::pair<std::string, bctype_map> pair(label, map);
254 fi.insert(pair);
255 }
256
257 int count = 0;
258 typedef typename std::vector<typename gsFunctionSet<T>::Ptr>::const_iterator fun_it;
259 for (fun_it fit = fun.begin(); fit != fun.end(); ++fit)
260 {
261 gsXmlNode * ff = putFunctionToXml<T>(*fit, data, count);
262 BCs->append_node(ff);
263 ++count;
264 }
265
266 // for all bcs, append bc, cv
267 typedef typename std::map<std::string, bctype_map>::const_iterator bctype_map_it;
268 typedef typename std::map<int, bctype_vec>::const_iterator bctype_iv_it;
269 typedef typename bctype_vec::const_iterator bctype_vec_it;
270
271 count = 0;
272 for (bctype_map_it it = fi.begin(); it != fi.end(); ++it)
273 {
274 std::string label = it->first;
275 //gsDebug << "Label='" << label << "'\n";
276 bctype_map map = it->second;
277
278 for (bctype_iv_it bcV = map.begin(); bcV != map.end(); ++bcV)
279 {
280 int index = bcV->first;
281 bctype_vec vec = bcV->second;
282 //gsDebug << "index='" << index << "'\n";
283 //gsDebug << "vec='" << vec.size() << "'\n";
284 gsXmlNode * bcNode = internal::makeNode("bc", data);
285 gsXmlAttribute * typeNode = internal::makeAttribute("type",
286 label, data);
287 gsXmlAttribute * indexNode = internal::makeAttribute("function",
288 index, data);
289 bcNode->append_attribute(typeNode);
290 bcNode->append_attribute(indexNode);
291 bool first = true;
292 std::ostringstream oss;
293 for (bctype_vec_it bc = vec.begin(); bc != vec.end(); ++bc)
294 {
295 const boundary_condition<T> b = (**bc);
296 //gsDebug << "iterate over boundary condition with '"
297 // << b.m_label << "'\n";
298 if (first)
299 {
300 gsXmlAttribute * unknownNode = internal::makeAttribute(
301 "unknown", b.m_unknown, data);
302 gsXmlAttribute * componentNode = internal::makeAttribute("component",
303 b.unkComponent(), data);
304 bcNode->append_attribute(componentNode);
305 bcNode->append_attribute(unknownNode);
306 first = false;
307 }
308 else
309 {
310 oss << " ";
311 }
312 oss << b.ps.patch << " " << b.ps.m_index;
313 }
314 char * value = data.allocate_string(oss.str().c_str());
315 bcNode->value(value);
316 BCs->append_node(bcNode);
317 ++count;
318 }
319 }
320 typename gsBoundaryConditions<T>::const_citerator ci;
321 for (ci = obj.cornerValues().begin(); ci != obj.cornerValues().end();
322 ci++)
323 {
324 corner_value<T> c = *ci;
325 gsXmlNode * cvNode = internal::makeNode("cv", data);
326 gsXmlAttribute * unknownNode = internal::makeAttribute("unknown",
327 c.unknown, data);
328 gsXmlAttribute * componentNode = internal::makeAttribute("component",
329 c.component, data);
330 gsXmlAttribute * patchNode = internal::makeAttribute("patch",
331 c.patch, data);
332 gsXmlAttribute * cornerNode = internal::makeAttribute("corner",
333 c.corner.m_index, data);
334 cvNode->append_attribute(unknownNode);
335 cvNode->append_attribute(componentNode);
336 cvNode->append_attribute(patchNode);
337 cvNode->append_attribute(cornerNode);
338 std::ostringstream oss;
339 oss << c.value;
340 char * value = data.allocate_string(oss.str().c_str());
341 cvNode->value(value);
343 BCs->append_node(cvNode);
344 }
345 return BCs;
346 }
347};
348
349} // end namespace internal
350
351} // end namespace gismo
memory::shared_ptr< gsFunctionSet > Ptr
Shared pointer for gsFunctionSet.
Definition gsFunctionSet.h:223
Provides declaration of ConstantFunction class.
#define gsWarn
Definition gsDebug.h:50
#define GISMO_ENSURE(cond, message)
Definition gsDebug.h:102
#define GISMO_ASSERT(cond, message)
Definition gsDebug.h:89
Provides declaration of FunctionExpr class.
An std::vector with sorting capabilities.
Provides implementation of generic XML functions.
Provides declaration of input/output XML utilities struct.
gsXmlNode * makeNode(const std::string &name, gsXmlTree &data)
Helper to allocate XML node.
Definition gsXml.cpp:54
gsXmlAttribute * makeAttribute(const std::string &name, const std::string &value, gsXmlTree &data)
Helper to allocate XML attribute.
Definition gsXml.cpp:37
gsXmlNode * searchId(const int id, gsXmlNode *root, const char *tag_name=NULL, const bool print_warning=true)
Definition gsXml.h:254
shared_ptr< T > make_shared(T *x)
Definition gsMemory.h:181
The G+Smo namespace, containing all definitions for the library.