1 /* $Header: /var/cvs/mbdyn/mbdyn/mbdyn-1.0/mbdyn/base/streamoutelem.cc,v 1.26 2017/08/28 10:34:39 masarati Exp $ */
2 /*
3 * MBDyn (C) is a multibody analysis code.
4 * http://www.mbdyn.org
5 *
6 * Copyright (C) 1996-2017
7 *
8 * Pierangelo Masarati <masarati@aero.polimi.it>
9 * Paolo Mantegazza <mantegazza@aero.polimi.it>
10 *
11 * Dipartimento di Ingegneria Aerospaziale - Politecnico di Milano
12 * via La Masa, 34 - 20156 Milano, Italy
13 * http://www.aero.polimi.it
14 *
15 * Changing this copyright notice is forbidden.
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation (version 2 of the License).
20 *
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 */
31
32 /*
33 * Portions Copyright Michele Attolico <attolico@aero.polimi.it>
34 */
35
36 #include "mbconfig.h" /* This goes first in every *.c,*.cc file */
37
38 #include "dataman.h"
39 #include "streamoutelem.h"
40 #include "geomdata.h"
41 #include "socketstream_out_elem.h"
42 #include "bufferstream_out_elem.h"
43 #include "socketstreammotionelem.h"
44 #include "bufmod.h"
45
46 /* StreamOutElem - begin */
47
StreamOutElem(unsigned int uL,const std::string & name,unsigned int oe)48 StreamOutElem::StreamOutElem(unsigned int uL,
49 const std::string& name,
50 unsigned int oe)
51 : Elem(uL, flag(0)),
52 name(name),
53 OutputEvery(oe), OutputCounter(0)
54 {
55 ASSERT(OutputEvery > 0);
56 }
57
~StreamOutElem(void)58 StreamOutElem::~StreamOutElem(void)
59 {
60 NO_OP;
61 }
62
63 Elem::Type
GetElemType(void) const64 StreamOutElem::GetElemType(void) const
65 {
66 return Elem::SOCKETSTREAM_OUTPUT;
67 }
68
69 void
WorkSpaceDim(integer * piRows,integer * piCols) const70 StreamOutElem::WorkSpaceDim(integer* piRows, integer* piCols) const
71 {
72 *piRows = 0;
73 *piCols = 0;
74 }
75
76 SubVectorHandler&
AssRes(SubVectorHandler & WorkVec,doublereal dCoef,const VectorHandler & X,const VectorHandler & XP)77 StreamOutElem::AssRes(SubVectorHandler& WorkVec, doublereal dCoef,
78 const VectorHandler& X, const VectorHandler& XP)
79 {
80 WorkVec.Resize(0);
81 return WorkVec;
82 }
83
84 VariableSubMatrixHandler&
AssJac(VariableSubMatrixHandler & WorkMat,doublereal dCoef,const VectorHandler & X,const VectorHandler & XP)85 StreamOutElem::AssJac(VariableSubMatrixHandler& WorkMat, doublereal dCoef,
86 const VectorHandler& X, const VectorHandler& XP)
87 {
88 WorkMat.SetNullMatrix();
89 return WorkMat;
90 }
91
92 /* StreamOutElem - end */
93
94
95 /* StreamContent - begin */
96
StreamContent(size_t size,StreamContent::Modifier * pMod)97 StreamContent::StreamContent(size_t size, StreamContent::Modifier *pMod)
98 : buf(size), m_pMod(pMod)
99 {
100 if (m_pMod == 0) {
101 m_pMod = new StreamContent::Copy(size, &buf[0]);
102
103 } else {
104 m_pMod->Set(size, &buf[0]);
105 }
106 }
107
~StreamContent(void)108 StreamContent::~StreamContent(void)
109 {
110 if (m_pMod != 0) {
111 delete m_pMod;
112 m_pMod = 0;
113 }
114 }
115
116 void *
GetBuf(void) const117 StreamContent::GetBuf(void) const
118 {
119 return (void *)&buf[0];
120 }
121
122 int
GetSize(void) const123 StreamContent::GetSize(void) const
124 {
125 return buf.size();
126 }
127
128 const void *
GetOutBuf(void) const129 StreamContent::GetOutBuf(void) const
130 {
131 return m_pMod->GetOutBuf();
132 }
133
134 int
GetOutSize(void) const135 StreamContent::GetOutSize(void) const
136 {
137 return m_pMod->GetOutSize();
138 }
139
~Modifier(void)140 StreamContent::Modifier::~Modifier(void)
141 {
142 NO_OP;
143 }
144
Copy(size_t size,const char * outbuf)145 StreamContent::Copy::Copy(size_t size, const char *outbuf)
146 : m_size(size), m_outbuf(outbuf)
147 {
148 NO_OP;
149 }
150
151 void
Set(size_t size,const char * outbuf)152 StreamContent::Copy::Set(size_t size, const char *outbuf)
153 {
154 m_size = size;
155 m_outbuf = outbuf;
156 }
157
158 void
Modify(void)159 StreamContent::Copy::Modify(void)
160 {
161 NO_OP;
162 }
163
164 const void *
GetOutBuf(void) const165 StreamContent::Copy::GetOutBuf(void) const
166 {
167 return m_outbuf;
168 }
169
170 int
GetOutSize(void) const171 StreamContent::Copy::GetOutSize(void) const
172 {
173 return m_size;
174 }
175
StreamContentCopyCast(size_t size,const char * buf,size_t outsize,const std::vector<BufCast * > & data)176 StreamContentCopyCast::StreamContentCopyCast(size_t size, const char *buf, size_t outsize, const std::vector<BufCast *>& data)
177 : m_size(size), m_buf(buf), m_outbuf(outsize), m_data(data)
178 {
179 #ifdef DEBUG
180 std::vector<BufCast *>::const_iterator i = data.end();
181 ASSERT(i > data.begin());
182 --i;
183 size_t minsize = (*i)->offset() + (*i)->size();
184 ASSERT(outsize >= minsize);
185 #endif
186 }
187
188 void
Set(size_t size,const char * buf)189 StreamContentCopyCast::Set(size_t size, const char *buf)
190 {
191 m_size = size;
192 m_buf = buf;
193
194 // FIXME: what about outbuf?
195 // in principle, size is sizeof(doublereal)*nChannels
196 ASSERT(m_size == sizeof(doublereal)*m_data.size());
197 }
198
199 void
Modify(void)200 StreamContentCopyCast::Modify(void)
201 {
202 ASSERT(m_size == m_data.size()*sizeof(doublereal));
203
204 doublereal *rbuf = (doublereal *)&m_buf[0];
205 for (size_t i = 0; i < m_data.size(); i++) {
206 m_data[i]->uncast(&m_outbuf[0], rbuf[i]);
207 }
208 }
209
210 const void *
GetOutBuf(void) const211 StreamContentCopyCast::GetOutBuf(void) const
212 {
213 return &m_outbuf[0];
214 }
215
216 int
GetOutSize(void) const217 StreamContentCopyCast::GetOutSize(void) const
218 {
219 return m_outbuf.size();
220 }
221
222 /* StreamContent - end */
223
224
225 /* StreamContentValue - begin */
226
StreamContentValue(const std::vector<ScalarValue * > & v,StreamContent::Modifier * pMod)227 StreamContentValue::StreamContentValue(const std::vector<ScalarValue *>& v,
228 StreamContent::Modifier *pMod)
229 : StreamContent(sizeof(doublereal)*v.size(), pMod), Values(v)
230 {
231 ASSERT(Values.size() > 0);
232 }
233
~StreamContentValue(void)234 StreamContentValue::~StreamContentValue(void)
235 {
236 for (std::vector<ScalarValue *>::iterator i = Values.begin();
237 i != Values.end(); ++i)
238 {
239 delete *i;
240 }
241 }
242
243 void
Prepare(void)244 StreamContentValue::Prepare(void)
245 {
246 char *curbuf = &buf[0];
247 for (std::vector<ScalarValue *>::iterator i = Values.begin(); i != Values.end(); ++i) {
248 /* assign value somewhere into mailbox buffer */
249 doublereal v = (*i)->dGetValue();
250
251 doublereal *dbuf = (doublereal *)curbuf;
252 dbuf[0] = v;
253
254 curbuf += sizeof(doublereal);
255 }
256
257 m_pMod->Modify();
258 }
259
260 unsigned
GetNumChannels(void) const261 StreamContentValue::GetNumChannels(void) const
262 {
263 return Values.size();
264 }
265
266 /* StreamContentValue - end */
267
268 /*
269 * NOTE: the use of type to determine what type of stream contents
270 * to read is only a hack; needs improvements
271 */
272
273 StreamContent::Modifier *
ReadStreamContentModifier(MBDynParser & HP,integer nCh)274 ReadStreamContentModifier(MBDynParser& HP, integer nCh)
275 {
276 StreamContent::Modifier *pSCM(0);
277
278 if (HP.IsKeyWord("copy" "cast")) {
279 std::vector<BufCast *> data(nCh);
280 ReadBufCast(HP, data);
281 size_t minsize = data[data.size() - 1]->offset() + data[data.size() - 1]->size();
282 size_t size = minsize;
283 if (HP.IsKeyWord("size")) {
284 integer i = HP.GetInt();
285 if (i <= 0) {
286 silent_cerr("ReadStreamContentModifier: invalid size " << i
287 << " at line " << HP.GetLineData() << std::endl);
288 throw ErrGeneric(MBDYN_EXCEPT_ARGS);
289 }
290
291 size = size_t(i);
292 if (size < minsize) {
293 silent_cerr("ReadStreamContentModifier: size " << size
294 << " is less than min size " << minsize
295 << " at line " << HP.GetLineData() << std::endl);
296 throw ErrGeneric(MBDYN_EXCEPT_ARGS);
297 }
298 }
299
300 pSCM = new StreamContentCopyCast(0, 0, size, data);
301
302 } else if (!HP.IsKeyWord("copy")) {
303 silent_cerr("ReadStreamContentModifier: unknown modifier type at line " << HP.GetLineData() << std::endl);
304 throw ErrGeneric(MBDYN_EXCEPT_ARGS);
305 }
306
307 return pSCM;
308 }
309
310 #if 0
311 StreamContent *
312 ReadStreamContent(DataManager *pDM, MBDynParser& HP, StreamContent::Type type)
313 {
314 switch (type) {
315 case StreamContent::UNKNOWN:
316 type = StreamContent::VALUES;
317 // fallthru
318
319 case StreamContent::VALUES:
320 if (HP.IsKeyWord("motion")) {
321 type = StreamContent::MOTION;
322
323 } else if (!HP.IsKeyWord("values")) {
324 silent_cerr("ReadStreamContent: "
325 "missing type, assuming \"values\" "
326 "at line " << HP.GetLineData() << std::endl);
327 }
328 break;
329
330 default:
331 break;
332 }
333
334 StreamContent *pSC = 0;
335 switch (type) {
336 case StreamContent::VALUES: {
337 int nch = HP.GetInt();
338 if (nch <= 0) {
339 silent_cerr("illegal number of channels for StreamContent "
340 "at line " << HP.GetLineData() << std::endl);
341 throw ErrGeneric(MBDYN_EXCEPT_ARGS);
342 }
343
344 std::vector<ScalarValue *> Values(nch);
345 ReadScalarValues(pDM, HP, Values);
346
347 StreamContent::Modifier *pMod(0);
348 if (HP.IsKeyWord("modifier")) {
349 pMod = ReadStreamContentModifier(HP, nch);
350 }
351
352 SAFENEWWITHCONSTRUCTOR(pSC, StreamContentValue, StreamContentValue(Values, pMod));
353 } break;
354
355 case StreamContent::MOTION: {
356 unsigned uFlags = GeometryData::X;
357 if (HP.IsKeyWord("output" "flags")) {
358 uFlags = 0;
359 while (true) {
360 if (HP.IsKeyWord("position")) {
361 if (uFlags & GeometryData::X) {
362 silent_cerr("StreamContent: "
363 "position flag already defined "
364 "at line " << HP.GetLineData()
365 << std::endl);
366 throw ErrGeneric(MBDYN_EXCEPT_ARGS);
367 }
368 uFlags |= GeometryData::X;
369
370 } else if (HP.IsKeyWord("orientation" "matrix")) {
371 if (uFlags & GeometryData::ORIENTATION_MASK) {
372 silent_cerr("StreamContent: "
373 "orientation flag already defined "
374 "at line " << HP.GetLineData()
375 << std::endl);
376 throw ErrGeneric(MBDYN_EXCEPT_ARGS);
377 }
378 uFlags |= GeometryData::R;
379
380 } else if (HP.IsKeyWord("orientation" "matrix" "transpose")) {
381 if (uFlags & GeometryData::ORIENTATION_MASK) {
382 silent_cerr("StreamContent: "
383 "orientation flag already defined "
384 "at line " << HP.GetLineData()
385 << std::endl);
386 throw ErrGeneric(MBDYN_EXCEPT_ARGS);
387 }
388 uFlags |= GeometryData::RT;
389
390 } else if (HP.IsKeyWord("velocity")) {
391 if (uFlags & GeometryData::V) {
392 silent_cerr("StreamContent: "
393 "velocity flag already defined "
394 "at line " << HP.GetLineData()
395 << std::endl);
396 throw ErrGeneric(MBDYN_EXCEPT_ARGS);
397 }
398 uFlags |= GeometryData::V;
399
400 } else if (HP.IsKeyWord("angular" "velocity")) {
401 if (uFlags & GeometryData::W) {
402 silent_cerr("StreamContent: "
403 "angular velocity flag already defined "
404 "at line " << HP.GetLineData()
405 << std::endl);
406 throw ErrGeneric(MBDYN_EXCEPT_ARGS);
407 }
408 uFlags |= GeometryData::W;
409
410 } else {
411 break;
412 }
413 }
414 }
415
416 std::vector<const StructNode *> nodes;
417 if (HP.IsKeyWord("all")) {
418
419 DataManager::NodeContainerType::const_iterator i = pDM->begin(Node::STRUCTURAL);
420 DataManager::NodeContainerType::const_iterator e = pDM->end(Node::STRUCTURAL);
421
422 if (e == i) {
423 silent_cerr("ReadStreamContent: no structural nodes " << std::endl);
424 throw ErrGeneric(MBDYN_EXCEPT_ARGS);
425 }
426
427 for (; i != e; ++i) {
428 const StructDispNode *pN = dynamic_cast<const StructDispNode *>(i->second);
429 const StructNode *pSN = dynamic_cast<const StructNode *>(pN);
430 ASSERT(pN != 0);
431 if (pSN && pSN->GetStructNodeType() == StructNode::DUMMY) {
432 continue;
433 }
434
435 nodes.insert(nodes.end(), pSN);
436 }
437
438 } else {
439 while (HP.IsArg()) {
440 nodes.insert(nodes.end(), pDM->ReadNode<const StructNode, Node::STRUCTURAL>(HP));
441 }
442 }
443
444 // FIXME: right now, we don't modify stream motion stuff
445 StreamContent::Modifier *pMod(0);
446
447 SAFENEWWITHCONSTRUCTOR(pSC, StreamContentMotion, StreamContentMotion(uFlags, nodes, pMod));
448 } break;
449
450 default:
451 silent_cerr("ReadStreamContent: unknown type "
452 "at line " << HP.GetLineData() << std::endl);
453 throw ErrGeneric(MBDYN_EXCEPT_ARGS);
454 }
455
456 return pSC;
457 }
458 #endif
459
460 /* StreamOutEcho - begin */
461
StreamOutEcho(std::string & sOutFileName,int iPrecision,doublereal dShift)462 StreamOutEcho::StreamOutEcho(std::string& sOutFileName, int iPrecision, doublereal dShift)
463 : sOutFileName(sOutFileName),
464 iPrecision(iPrecision),
465 dShift(dShift)
466 {
467 NO_OP;
468 }
469
~StreamOutEcho(void)470 StreamOutEcho::~StreamOutEcho(void)
471 {
472 NO_OP;
473 }
474
475 bool
Init(const std::string & msg,unsigned uLabel,unsigned nChannels)476 StreamOutEcho::Init(const std::string& msg, unsigned uLabel, unsigned nChannels)
477 {
478 outFile.open(sOutFileName.c_str());
479 if (!outFile) {
480 silent_cerr(msg << "(" << uLabel << "): "
481 "unable to open echo file \"" << sOutFileName << "\"" << std::endl);
482 throw ErrGeneric(MBDYN_EXCEPT_ARGS);
483 }
484
485 if (iPrecision > 0) {
486 outFile.precision(iPrecision);
487 }
488 outFile.setf(std::ios::scientific);
489
490 outFile
491 << "# generated by " << msg << "(" << uLabel << ")"
492 << std::endl;
493 if (nChannels == 1) {
494 outFile
495 << "# Channel #1"
496 << std::endl;
497
498 } else {
499 outFile
500 << "# Channels #1-" << nChannels
501 << std::endl;
502 }
503
504 return true;
505 }
506
507 void
Echo(const doublereal * pbuf,unsigned size)508 StreamOutEcho::Echo(const doublereal *pbuf, unsigned size)
509 {
510 outFile << pbuf[0];
511 for (unsigned i = 1; i < size; i++) {
512 outFile << " " << pbuf[i];
513 }
514 outFile << std::endl;
515 }
516
517 StreamOutEcho *
ReadStreamOutEcho(MBDynParser & HP)518 ReadStreamOutEcho(MBDynParser& HP)
519 {
520 StreamOutEcho *pSOE(0);
521
522 std::string sOutFileName;
523 int iPrecision = -1;
524 doublereal dShift = 0.;
525
526 if (HP.IsKeyWord("echo")) {
527 const char *s = HP.GetFileName();
528 if (s == NULL) {
529 silent_cerr("ReadStreamOutEcho: "
530 "unable to parse echo file name "
531 "at line " << HP.GetLineData()
532 << std::endl);
533 throw ErrGeneric(MBDYN_EXCEPT_ARGS);
534 }
535
536 sOutFileName = s;
537
538 if (HP.IsKeyWord("precision")) {
539 iPrecision = HP.GetInt();
540 if (iPrecision <= 0) {
541 silent_cerr("ReadStreamOutEcho: "
542 "invalid echo precision " << iPrecision
543 << " at line " << HP.GetLineData()
544 << std::endl);
545 throw ErrGeneric(MBDYN_EXCEPT_ARGS);
546 }
547 }
548
549 if (HP.IsKeyWord("shift")) {
550 dShift = HP.GetReal();
551 }
552
553 pSOE = new StreamOutEcho(sOutFileName, iPrecision, dShift);
554 }
555
556 return pSOE;
557 }
558
559 /* StreamOutEcho - end */
560
561 Elem *
ReadOutputElem(DataManager * pDM,MBDynParser & HP,unsigned int uLabel,StreamOutElem::Type eType,StreamContent::Type sType)562 ReadOutputElem(DataManager *pDM, MBDynParser& HP, unsigned int uLabel, StreamOutElem::Type eType, StreamContent::Type sType)
563 {
564 Elem *pE(0);
565
566 if (eType == StreamOutElem::UNDEFINED) {
567 sType = StreamContent::UNKNOWN;
568
569 if (HP.IsKeyWord("socket" "stream")) {
570 eType = StreamOutElem::SOCKETSTREAM;
571
572 } else if (HP.IsKeyWord("buffer" "stream")) {
573 eType = StreamOutElem::BUFFERSTREAM;
574
575 } else {
576 silent_cerr("ReadOutputElem(" << uLabel << "): "
577 "unknown \"type\" at line " << HP.GetLineData() << std::endl);
578 throw ErrGeneric(MBDYN_EXCEPT_ARGS);
579 }
580 }
581
582 switch (eType) {
583 case StreamOutElem::SOCKETSTREAM:
584 pE = ReadSocketStreamElem(pDM, HP, uLabel, sType);
585 break;
586
587 case StreamOutElem::BUFFERSTREAM:
588 pE = ReadBufferStreamElem(pDM, HP, uLabel, sType);
589 break;
590
591 default:
592 throw ErrGeneric(MBDYN_EXCEPT_ARGS);
593 }
594
595 return pE;
596 }
597
598 /*----------------------------------------------------------------------------
599 management of 'content type' for stream output element ('values','motion', etc)
600 ------------------------------------------------------------------------------
601
602 Rearranged by Luca Conti (May 2017) on the basis of previous existing code
603 (fully working, just rearranged).
604
605 Edited in order to apply the same mechanism with 'readers' and 'maps' (std::map)
606 already in use for constitutive laws and drives
607 */
608
609 StreamOutputContentTypeMap streamOutputContentTypeMap;
610 StreamOutputContentTypeWordSetType streamOutputContentTypeWordSet;
611 unsigned streamOutputInitFunctionCalls = 0;
612
613 /* content type search inside of the content-type bag: execution of its Read method */
ReadStreamContent(DataManager * pDM,MBDynParser & HP,StreamContent::Type type)614 StreamContent* ReadStreamContent(DataManager *pDM, MBDynParser& HP, StreamContent::Type type) {
615 //searches in the bag the content type found in MBDyn input file
616 const char *s = HP.IsWord(streamOutputContentTypeWordSet);
617
618 StreamOutputContentTypeMap::iterator it = streamOutputContentTypeMap.find(std::string(s));
619 if (it == streamOutputContentTypeMap.end()) {
620 silent_cerr("[streamoutelem.cc] ReadStreamContent:unknown stream output content type "
621 "\"" << s << "\" "
622 "at line " << HP.GetLineData() << std::endl);
623 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
624 }
625 return it->second->Read(pDM, HP);
626 }
627
628 /* default content type options: reader for 'motion' */
Read(DataManager * pDM,MBDynParser & HP)629 StreamContent* MotionContentTypeReader::Read(DataManager* pDM, MBDynParser& HP) {
630 // instructions executed for 'motion' case content type
631
632 StreamContent* pSC;
633
634 unsigned uFlags = GeometryData::X;
635 if (HP.IsKeyWord("output" "flags")) {
636 uFlags = 0;
637 while (true) {
638 if (HP.IsKeyWord("position")) {
639 if (uFlags & GeometryData::X) {
640 silent_cerr("StreamContent: "
641 "position flag already defined "
642 "at line " << HP.GetLineData()
643 << std::endl);
644 throw ErrGeneric(MBDYN_EXCEPT_ARGS);
645 }
646 uFlags |= GeometryData::X;
647
648 } else if (HP.IsKeyWord("orientation" "matrix")) {
649 if (uFlags & GeometryData::ORIENTATION_MASK) {
650 silent_cerr("StreamContent: "
651 "orientation flag already defined "
652 "at line " << HP.GetLineData()
653 << std::endl);
654 throw ErrGeneric(MBDYN_EXCEPT_ARGS);
655 }
656 uFlags |= GeometryData::R;
657
658 } else if (HP.IsKeyWord("orientation" "matrix" "transpose")) {
659 if (uFlags & GeometryData::ORIENTATION_MASK) {
660 silent_cerr("StreamContent: "
661 "orientation flag already defined "
662 "at line " << HP.GetLineData()
663 << std::endl);
664 throw ErrGeneric(MBDYN_EXCEPT_ARGS);
665 }
666 uFlags |= GeometryData::RT;
667
668 } else if (HP.IsKeyWord("velocity")) {
669 if (uFlags & GeometryData::V) {
670 silent_cerr("StreamContent: "
671 "velocity flag already defined "
672 "at line " << HP.GetLineData()
673 << std::endl);
674 throw ErrGeneric(MBDYN_EXCEPT_ARGS);
675 }
676 uFlags |= GeometryData::V;
677
678 } else if (HP.IsKeyWord("angular" "velocity")) {
679 if (uFlags & GeometryData::W) {
680 silent_cerr("StreamContent: "
681 "angular velocity flag already defined "
682 "at line " << HP.GetLineData()
683 << std::endl);
684 throw ErrGeneric(MBDYN_EXCEPT_ARGS);
685 }
686 uFlags |= GeometryData::W;
687
688 } else {
689 break;
690 }
691 }
692 }
693
694 std::vector<const StructNode *> nodes;
695 if (HP.IsKeyWord("all")) {
696 /* FIXME: todo */
697
698 } else {
699 while (HP.IsArg()) {
700 nodes.insert(nodes.end(), pDM->ReadNode<const StructNode, Node::STRUCTURAL>(HP));
701 }
702 }
703
704 // FIXME: right now, we don't modify stream motion stuff
705 StreamContent::Modifier *pMod(0);
706
707 SAFENEWWITHCONSTRUCTOR(pSC, StreamContentMotion, StreamContentMotion(uFlags, nodes, pMod));
708
709 return pSC;
710 }
711
712 /* default content type options: reader for 'values' */
Read(DataManager * pDM,MBDynParser & HP)713 StreamContent* ValuesContentTypeReader::Read(DataManager* pDM, MBDynParser& HP) {
714 /* instructions executed for 'values' case content type */
715
716 StreamContent* pSC;
717
718 int nch = HP.GetInt();
719 if (nch <= 0) {
720 silent_cerr("illegal number of channels for StreamContent "
721 "at line " << HP.GetLineData() << std::endl);
722 throw ErrGeneric(MBDYN_EXCEPT_ARGS);
723 }
724
725 std::vector<ScalarValue *> Values(nch);
726 ReadScalarValues(pDM, HP, Values);
727
728 StreamContent::Modifier *pMod(0);
729 if (HP.IsKeyWord("modifier")) {
730 pMod = ReadStreamContentModifier(HP, nch);
731 }
732
733 SAFENEWWITHCONSTRUCTOR(pSC, StreamContentValue, StreamContentValue(Values, pMod));
734
735 return pSC;
736 }
737
738 /* stream output content type parsing checker: allows the parser
739 to understand if the next keyword is a content type */
IsWord(const std::string & s) const740 bool StreamOutputContentTypeWordSetType::IsWord(const std::string& s) const {
741 return streamOutputContentTypeMap.find(std::string(s)) != streamOutputContentTypeMap.end();
742 };
743
744 /*registration function: CALL IT TO REGISTER A NEW CONTENT TYPE -
745 it is also used by InitStreamOutputContentTypes(void) in order to load default options ('values','motion') */
SetStreamOutputContentType(const char * name,StreamOutputContentTypeReader * rf)746 bool SetStreamOutputContentType(const char *name, StreamOutputContentTypeReader *rf){
747 pedantic_cout("registering stream output content type \"" << name << "\""
748 << std::endl );
749 return streamOutputContentTypeMap.insert(StreamOutputContentTypeMap::value_type(name, rf)).second;
750 }
751
752 /* initialization function: called by mbpar.cc in order to load default options ('values','motion')*/
InitStreamOutputContentTypes(void)753 void InitStreamOutputContentTypes(void){
754 if (streamOutputInitFunctionCalls++ > 0)
755 return;
756
757 /* loads default content types */
758 SetStreamOutputContentType("values", new ValuesContentTypeReader);
759 SetStreamOutputContentType("motion", new MotionContentTypeReader);
760 }
761 /*deallocation of all content types in streamOutputContentTypeMap - called by mbpar.cc*/
DestroyStreamOutputContentTypes(void)762 void DestroyStreamOutputContentTypes(void){
763 if (streamOutputInitFunctionCalls == 0) {
764 silent_cerr("DestroyStreamOutputContentTypes() called once too many" << std::endl);
765 throw ErrGeneric(MBDYN_EXCEPT_ARGS);
766 }
767
768 if (--streamOutputInitFunctionCalls > 0) {
769 return;
770 }
771
772 /* empties all of the content types contained in streamOutputContentTypeMap*/
773 for (StreamOutputContentTypeMap::iterator i = streamOutputContentTypeMap.begin(); i != streamOutputContentTypeMap.end(); ++i) {
774 delete i->second;
775 }
776 streamOutputContentTypeMap.clear();
777 }
778