1 /* $Header: /var/cvs/mbdyn/mbdyn/mbdyn-1.0/mbdyn/hydr/preselem.cc,v 1.47 2017/01/12 14:46:32 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  * Copyright 1999-2000 Lamberto Puggelli <puggelli@tiscalinet.it>
34  * Dipartimento di Ingegneria Aerospaziale - Politecnico di Milano
35  */
36 
37 #include "mbconfig.h"           /* This goes first in every *.c,*.cc file */
38 
39 #include <cfloat>
40 #include <limits>
41 
42 #include "dataman.h"
43 #include "preselem.h"
44 
45 #include "actuator.h"
46 #include "hfluid.h"
47 #include "hminor.h"
48 #include "hutils.h"
49 #include "pipe.h"
50 #include "valve.h"
51 
52 /* HydraulicElem - begin */
53 
HydraulicElem(unsigned int uL,const DofOwner * pDO,HydraulicFluid * hf,flag fOut)54 HydraulicElem::HydraulicElem(unsigned int uL, const DofOwner* pDO,
55 			     HydraulicFluid* hf, flag fOut)
56 : Elem(uL, fOut),
57 ElemWithDofs(uL, pDO, fOut),
58 HF(hf)
59 {
60    ASSERT(HF != NULL);
61 }
62 
63 
~HydraulicElem(void)64 HydraulicElem::~HydraulicElem(void)
65 {
66    if (HF != NULL) {
67       SAFEDELETE(HF);
68    }
69 }
70 
71 
72 /* Tipo dell'elemento (usato per debug ecc.) */
GetElemType(void) const73 Elem::Type HydraulicElem::GetElemType(void) const
74 {
75    return Elem::HYDRAULIC;
76 }
77 
78 
79 /* Contributo al file di restart
80  * (Nota: e' incompleta, deve essere chiamata dalla funzione corrispndente
81  * relativa alla classe derivata */
Restart(std::ostream & out) const82 std::ostream& HydraulicElem::Restart(std::ostream& out) const
83 {
84    return out << "  hydraulic: " << GetLabel();
85 }
86 
87 /* HydraulicElem - end */
88 
89 
90 
91 
92 
ReadHydraulicElem(DataManager * pDM,MBDynParser & HP,const DofOwner * pDO,unsigned int uLabel)93 Elem* ReadHydraulicElem(DataManager* pDM,
94 			MBDynParser& HP,
95 			const DofOwner* pDO,
96 			unsigned int uLabel)
97 {
98    DEBUGCOUT("ReadHydraulicElem()");
99 
100    const char* sKeyWords[] = {
101       "minor" "loss",
102       "three" "way" "minor" "loss",
103       "control" "valve",
104       "control" "valve" "2",
105       "dynamic" "control" "valve",
106       "pressure" "flow" "control",
107       "pressure" "valve",
108       "flow" "valve",
109       "orifice",
110       "accumulator",
111       "tank",
112       "pipe",
113       "dynamic" "pipe",
114       "actuator",
115       NULL
116    };
117 
118    /* enum delle parole chiave */
119    enum KeyWords {
120       UNKNOWN = -1,
121       MINOR_LOSS = 0,
122       THREEWAYMINORLOSS,
123       CONTROL_VALVE,
124       CONTROL_VALVE2,
125       DYNAMIC_CONTROL_VALVE,
126       PRESSURE_FLOW_CONTROL_VALVE,
127       PRESSURE_VALVE,
128       FLOW_VALVE,
129       ORIFICE,
130       ACCUMULATOR,
131       TANK,
132       PIPE,
133       DYNAMIC_PIPE,
134       ACTUATOR,
135 
136       LASTKEYWORD
137    };
138 
139    /* tabella delle parole chiave */
140    KeyTable K(HP, sKeyWords);
141 
142    /* lettura del tipo di elemento elettrico */
143    KeyWords CurrKeyWord = KeyWords(HP.GetWord());
144 
145 #ifdef DEBUG
146    if (CurrKeyWord >= 0) {
147       std::cout << "hydraulic element type: "
148 	<< sKeyWords[CurrKeyWord] << std::endl;
149    }
150 #endif
151 
152    Elem* pEl = NULL;
153 
154    switch (CurrKeyWord) {
155 
156     case ACTUATOR: {
157        /* lettura dei dati specifici */
158        /* due nodi idraulici e due nodi strutturali */
159 
160        /* nodo idraulico 1 */
161        const PressureNode* pNodeHyd1 = pDM->ReadNode<const PressureNode, Node::HYDRAULIC>(HP);
162 
163        /* nodo idraulico 2 */
164        const PressureNode* pNodeHyd2 = pDM->ReadNode<const PressureNode, Node::HYDRAULIC>(HP);
165 
166        /* nodo strutturale 1 */
167        const StructNode* pNodeStr1 = pDM->ReadNode<const StructNode, Node::STRUCTURAL>(HP);
168 
169        Vec3 f1(HP.GetPosRel(ReferenceFrame(pNodeStr1)));
170        DEBUGCOUT("Offset 1: " << f1 << std::endl);
171 
172        /* nodo strutturale 2 */
173        const StructNode* pNodeStr2 = pDM->ReadNode<const StructNode, Node::STRUCTURAL>(HP);
174 
175        Vec3 f2(HP.GetPosRel(ReferenceFrame(pNodeStr2)));
176        DEBUGCOUT("Offset 2: " << f2 << std::endl);
177 
178        ReferenceFrame RF(pNodeStr1);
179        Vec3 axis(0., 0., 1.);
180        if (HP.IsKeyWord("direction")) {
181           try {
182 	     axis = HP.GetUnitVecRel(RF);
183           } catch (ErrNullNorm) {
184 	     silent_cerr("Actuator(" << uLabel << "): "
185 		     "need a definite direction, not "
186 		     << axis << "!" << std::endl);
187 	     throw ErrNullNorm(MBDYN_EXCEPT_ARGS);
188 	  }
189        }
190 
191        /* Area nodo1 */
192        doublereal area1 = HP.GetReal();
193        if (area1 <= std::numeric_limits<doublereal>::epsilon()) {
194 	  silent_cerr("Actuator(" << uLabel << "): "
195 			  "null or negative area1 "
196 			  "at line " << HP.GetLineData() << std::endl);
197 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
198        }
199        DEBUGCOUT("Area1: " << area1 << std::endl);
200 
201        /* Area nodo2 */
202        doublereal area2 = HP.GetReal();
203        if (area2 <= std::numeric_limits<doublereal>::epsilon()) {
204 	  silent_cerr("Actuator(" << uLabel << "): "
205 			  "null or negative area2 "
206 			  "at line " << HP.GetLineData() << std::endl);
207 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
208        }
209        DEBUGCOUT("Area2: " << area2 << std::endl);
210 
211        /* lunghezza cilindro (a meno dello spessore */
212        doublereal dl = HP.GetReal();
213        if (dl <= std::numeric_limits<doublereal>::epsilon()) {
214 	  silent_cerr("Actuator(" << uLabel << "): "
215 			  "null or negative dl "
216 			  "at line " << HP.GetLineData() << std::endl);
217 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
218        }
219        DEBUGCOUT("dl: " << dl << std::endl);
220 
221 
222        HydraulicFluid* hf1 = HP.GetHydraulicFluid();
223        ASSERT(hf1 != NULL);
224 
225        HydraulicFluid* hf2 = NULL;
226        if (HP.IsKeyWord("same")) {
227 	  hf2 = hf1->pCopy();
228        } else {
229 	  hf2 = HP.GetHydraulicFluid();
230        }
231        ASSERT(hf2 != NULL);
232 
233        flag fOut = pDM->fReadOutput(HP, Elem::HYDRAULIC);
234 
235        SAFENEWWITHCONSTRUCTOR(pEl,
236 			      Actuator,
237 			      Actuator(uLabel, pDO,
238 				       pNodeHyd1, pNodeHyd2,
239 				       pNodeStr1, pNodeStr2,
240 				       f1, f2, axis, hf1, hf2,
241 				       area1, area2, dl,
242 				       fOut));
243 
244        break;
245     }
246 
247     case MINOR_LOSS: {
248 
249        /* nodo 1 */
250        const PressureNode* pNode1 = pDM->ReadNode<const PressureNode, Node::HYDRAULIC>(HP);
251 
252        /* nodo 2 */
253        const PressureNode* pNode2 = pDM->ReadNode<const PressureNode, Node::HYDRAULIC>(HP);
254 
255        /* Kappa1 diretto */
256        doublereal dKappa1 = HP.GetReal();
257        if (dKappa1 < 0.) {
258 	  silent_cerr("MinorLoss(" << uLabel << "): "
259 		  "negative Kappa1 at line " << HP.GetLineData() << std::endl);
260 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
261        }
262        DEBUGCOUT("Kappa1: " << dKappa1 << std::endl);
263 
264        /* Kappa2 inverso */
265        doublereal dKappa2 = HP.GetReal();
266        if (dKappa2 < 0.) {
267 	  silent_cerr("MinorLoss(" << uLabel << "): "
268 		  "negative Kappa2 at line " << HP.GetLineData() << std::endl);
269 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
270        }
271        DEBUGCOUT("Kappa2: " << dKappa2 << std::endl);
272 
273        /* Area */
274        doublereal area = HP.GetReal();
275        if (area <= std::numeric_limits<doublereal>::epsilon()) {
276 	  silent_cerr("MinorLoss(" << uLabel << "): "
277 		  "null or negative area "
278 		  "at line " << HP.GetLineData() << std::endl);
279 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
280        }
281        DEBUGCOUT("Area: " << area << std::endl);
282 
283        HydraulicFluid* hf = HP.GetHydraulicFluid();
284        ASSERT(hf != NULL);
285 
286        flag fOut = pDM->fReadOutput(HP, Elem::HYDRAULIC);
287 
288        SAFENEWWITHCONSTRUCTOR(pEl,
289 			      MinorLoss,
290                               MinorLoss(uLabel, pDO, hf, pNode1, pNode2,
291 					 dKappa1, dKappa2, area, fOut));
292 
293        break;
294     }
295 
296     case THREEWAYMINORLOSS: {
297 
298        /* nodo 0 */
299        const PressureNode* pNode0 = pDM->ReadNode<const PressureNode, Node::HYDRAULIC>(HP);
300 
301        /* nodo 1 */
302        const PressureNode* pNode1 = pDM->ReadNode<const PressureNode, Node::HYDRAULIC>(HP);
303 
304        /* nodo 2 */
305        const PressureNode* pNode2 = pDM->ReadNode<const PressureNode, Node::HYDRAULIC>(HP);
306 
307        /* Kappa1 diretto */
308        doublereal dKappa1 = HP.GetReal();
309        if (dKappa1 < 0.) {
310 	  silent_cerr("ThreeWayMinorLoss(" << uLabel << "): "
311 		  "negative Kappa1 at line " << HP.GetLineData() << std::endl);
312 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
313        }
314        DEBUGCOUT("Kappa1: " << dKappa1 << std::endl);
315 
316        /* Kappa2 inverso */
317        doublereal dKappa2 = HP.GetReal();
318        if (dKappa2 < 0.) {
319 	  silent_cerr("ThreeWayMinorLoss(" << uLabel << "): "
320 		  "negative Kappa2 at line " << HP.GetLineData() << std::endl);
321 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
322        }
323        DEBUGCOUT("Kappa2: " << dKappa2 << std::endl);
324 
325        /* Area 1 */
326        doublereal area1 = HP.GetReal();
327        if (area1 <= std::numeric_limits<doublereal>::epsilon()) {
328 	  silent_cerr("ThreeWayMinorLoss(" << uLabel << "): "
329 		  "null or negative area1 "
330 		  "at line " << HP.GetLineData() << std::endl);
331 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
332        }
333        DEBUGCOUT("Area: " << area1 << std::endl);
334 
335        /* Area 2 */
336        doublereal area2 = HP.GetReal();
337        if (area1 <= std::numeric_limits<doublereal>::epsilon()) {
338 	  silent_cerr("ThreeWayMinorLoss(" << uLabel << "): "
339 		  "null or negative area2 "
340 		  "at line " << HP.GetLineData() << std::endl);
341 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
342        }
343        DEBUGCOUT("Area: " << area2 << std::endl);
344 
345        HydraulicFluid* hf = HP.GetHydraulicFluid();
346        ASSERT(hf != NULL);
347 
348        flag fOut = pDM->fReadOutput(HP, Elem::HYDRAULIC);
349 
350        SAFENEWWITHCONSTRUCTOR(pEl,
351 			      ThreeWayMinorLoss,
352                               ThreeWayMinorLoss(uLabel, pDO, hf,
353 				      pNode0, pNode1, pNode2,
354 				      dKappa1, dKappa2, area1, area2, fOut));
355 
356        break;
357     }
358 
359     case CONTROL_VALVE:
360     case CONTROL_VALVE2: {
361 
362        /* nodo 1 */
363        const PressureNode* pNode1 = pDM->ReadNode<const PressureNode, Node::HYDRAULIC>(HP);
364 
365        /* nodo 2 */
366        const PressureNode* pNode2 = pDM->ReadNode<const PressureNode, Node::HYDRAULIC>(HP);
367 
368        /* nodo 3 */
369        const PressureNode* pNode3 = pDM->ReadNode<const PressureNode, Node::HYDRAULIC>(HP);
370 
371        /* nodo 4 */
372        const PressureNode* pNode4 = pDM->ReadNode<const PressureNode, Node::HYDRAULIC>(HP);
373 
374        /* Area massima della valvola */
375        doublereal area_max = HP.GetReal();
376        if (area_max <= 0.) {
377 	  silent_cerr("ControlValve(" << uLabel << "): "
378 		  "null or negative area_max "
379 		  "at line " << HP.GetLineData() << std::endl);
380 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
381        }
382        DEBUGCOUT("Area_max: " << area_max << std::endl);
383 
384        /* Area di trafilamento in % sull'area massima:valore di default = 1.e-6 */
385        doublereal loss_area = 0.; /* 1.e-6; */
386        if (HP.IsKeyWord("loss")) {
387 	  loss_area = HP.GetReal();
388 	  if (loss_area  < 0.) {
389 	     silent_cerr("ControlValve(" << uLabel << "): "
390 		     "negative loss_area "
391 		     "at line " << HP.GetLineData() << std::endl);
392 	     throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
393 	  }
394 	  DEBUGCOUT("Loss_area in %= " << loss_area << std::endl);
395        }
396 
397        /* Stato */
398        DriveCaller* pDC = HP.GetDriveCaller();
399 
400        HydraulicFluid* hf = HP.GetHydraulicFluid();
401        ASSERT(hf != NULL);
402 
403        flag fOut = pDM->fReadOutput(HP, Elem::HYDRAULIC);
404 
405        switch (CurrKeyWord) {
406        case CONTROL_VALVE:
407        SAFENEWWITHCONSTRUCTOR(pEl,
408 			      Control_valve,
409 			      Control_valve(uLabel, pDO, hf,
410 				      pNode1, pNode2, pNode3, pNode4,
411 				      area_max, loss_area, pDC, fOut));
412        break;
413 
414        case CONTROL_VALVE2:
415        SAFENEWWITHCONSTRUCTOR(pEl,
416 			      Control_valve2,
417 			      Control_valve2(uLabel, pDO, hf,
418 				      pNode1, pNode2, pNode3, pNode4,
419 				      area_max, loss_area, pDC, fOut));
420        break;
421 
422        default:
423           throw ErrGeneric(MBDYN_EXCEPT_ARGS);
424        }
425 
426        break;
427     }
428 
429     case DYNAMIC_CONTROL_VALVE: {
430 
431        /* nodo 1 */
432        const PressureNode* pNode1 = pDM->ReadNode<const PressureNode, Node::HYDRAULIC>(HP);
433 
434        /* nodo 2 */
435        const PressureNode* pNode2 = pDM->ReadNode<const PressureNode, Node::HYDRAULIC>(HP);
436 
437        /* nodo 3 */
438        const PressureNode* pNode3 = pDM->ReadNode<const PressureNode, Node::HYDRAULIC>(HP);
439 
440        /* nodo 4 */
441        const PressureNode* pNode4 = pDM->ReadNode<const PressureNode, Node::HYDRAULIC>(HP);
442 
443        /* Forza */
444        DriveCaller* pDC = HP.GetDriveCaller();
445 
446        /* spostamento iniziale */
447        doublereal start = HP.GetReal();
448        DEBUGCOUT("Start: " << start << std::endl);
449 
450        /* Spostamento massimo della valvola */
451        doublereal s_max = HP.GetReal();
452        if (s_max < 0.) {
453 	  silent_cerr("DynamicControlValve(" << uLabel << "): "
454 		  "negative s_max at line " << HP.GetLineData() << std::endl);
455 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
456        }
457        DEBUGCOUT("S_max: " << s_max << std::endl);
458 
459        /* Larghezza del condotto */
460        doublereal width = HP.GetReal();
461        if (width <= 0.) {
462 	  silent_cerr("DynamicControlValve(" << uLabel << "): "
463 		  "null or negative width "
464 		  "at line " << HP.GetLineData() << std::endl);
465 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
466        }
467        DEBUGCOUT("Width: " << width << std::endl);
468 
469        /* Area di trafilamento in % sull'area massima(==width*s_max):valore di default = 1.e-6 */
470        doublereal loss_area = 0.; /* 1.e-6; */
471        if (HP.IsKeyWord("loss")) {
472 	  loss_area = HP.GetReal();
473 	  if (loss_area < 0.) {
474 	     silent_cerr("DynamicControlValve(" << uLabel << "): "
475 		     "negative loss_area "
476 		     "at line " << HP.GetLineData() << std::endl);
477 	     throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
478 	  }
479 	  DEBUGCOUT("Loss_area in %= " << loss_area << std::endl);
480        }
481 
482        /* Diametro della valvola */
483        doublereal valve_diameter = HP.GetReal();
484        if (valve_diameter <= 0.) {
485 	  silent_cerr("DynamicControlValve(" << uLabel << "): "
486 		  "null or negative valve diameter "
487 		  "at line " << HP.GetLineData() << std::endl);
488 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
489        }
490        DEBUGCOUT("Valve diameter: " << valve_diameter << std::endl);
491 
492        /* Densita' del corpo della valvola */
493        doublereal valve_density = HP.GetReal();
494        if (valve_density <= 0.) {
495 	  silent_cerr("DynamicControlValve(" << uLabel << "): "
496 		  "null or negative valve density "
497 		  "at line " << HP.GetLineData() << std::endl);
498 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
499        }
500        DEBUGCOUT("Valve density: " << valve_density << std::endl);
501 
502        /* c dello spostamento */
503        doublereal c_spost = HP.GetReal();
504        DEBUGCOUT("c_spost: " << c_spost << std::endl);
505 
506        /* c della velocita' */
507        doublereal c_vel = HP.GetReal();
508        DEBUGCOUT("c_vel: " << c_vel << std::endl);
509 
510        /* c della accelerazione */
511        doublereal c_acc = HP.GetReal();
512        DEBUGCOUT("c_acc: " << c_acc << std::endl);
513 
514        HydraulicFluid* hf = HP.GetHydraulicFluid();
515        ASSERT(hf != NULL);
516 
517        flag fOut = pDM->fReadOutput(HP, Elem::HYDRAULIC);
518 
519        SAFENEWWITHCONSTRUCTOR(pEl,
520 			      Dynamic_control_valve,
521 			      Dynamic_control_valve(uLabel, pDO, hf,
522 						    pNode1, pNode2,
523 						    pNode3, pNode4,
524 						    pDC, start,
525 						    s_max, width,
526 						    loss_area,
527 						    valve_diameter,
528 						    valve_density,
529 						    c_spost, c_vel, c_acc,
530 						    fOut));
531        break;
532     }
533 
534     case PRESSURE_FLOW_CONTROL_VALVE: {
535 
536        /* nodo 1 */
537        const PressureNode* pNode1 = pDM->ReadNode<const PressureNode, Node::HYDRAULIC>(HP);
538 
539        /* nodo 2 */
540        const PressureNode* pNode2 = pDM->ReadNode<const PressureNode, Node::HYDRAULIC>(HP);
541 
542        /* nodo 3 */
543        const PressureNode* pNode3 = pDM->ReadNode<const PressureNode, Node::HYDRAULIC>(HP);
544 
545        /* nodo 4 */
546        const PressureNode* pNode4 = pDM->ReadNode<const PressureNode, Node::HYDRAULIC>(HP);
547 
548          /* nodo 5 */
549        const PressureNode* pNode5 = pDM->ReadNode<const PressureNode, Node::HYDRAULIC>(HP);
550 
551          /* nodo 6 */
552        const PressureNode* pNode6 = pDM->ReadNode<const PressureNode, Node::HYDRAULIC>(HP);
553 
554        /* Forza */
555        DriveCaller* pDC = HP.GetDriveCaller();
556 
557        /* spostamento iniziale */
558        doublereal start = HP.GetReal();
559        if (start < 0.) {
560 	  silent_cerr("PressureFlowControlValve(" << uLabel << "): "
561 		  "negative start "
562 		  "at line " << HP.GetLineData() << std::endl);
563 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
564        }
565        DEBUGCOUT("Start: " << start << std::endl);
566 
567        /* Spostamento massimo della valvola */
568        doublereal s_max = HP.GetReal();
569        if (s_max < 0.) {
570 	  silent_cerr("PressureFlowControlValve(" << uLabel << "): "
571 		  "negative s_max "
572 		  "at line " << HP.GetLineData() << std::endl);
573 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
574        }
575        DEBUGCOUT("S_max: " << s_max << std::endl);
576 
577        /* Larghezza del condotto */
578        doublereal width = HP.GetReal();
579        if (width <= 0.) {
580 	  silent_cerr("PressureFlowControlValve(" << uLabel << "): "
581 		  "null or negative width "
582 		  "at line " << HP.GetLineData() << std::endl);
583 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
584        }
585        DEBUGCOUT("Width: " << width << std::endl);
586 
587        /* Area di trafilamento in % sull'area massima(==width*s_max):valore di default = 1.e-6 */
588        doublereal loss_area = 0.; /* 1.e-6; */
589        if (HP.IsKeyWord("loss")) {
590 	  loss_area = HP.GetReal();
591 	  if (loss_area < 0.) {
592 	     silent_cerr("PressureFlowControlValve(" << uLabel << "): "
593 		     "negative loss_area "
594 		     "at line " << HP.GetLineData() << std::endl);
595 	     throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
596 	  }
597 	  DEBUGCOUT("Loss_area in %= " << loss_area << std::endl);
598        }
599 
600        /* Diametro della valvola */
601        doublereal valve_diameter = HP.GetReal();
602        if (valve_diameter <= 0.) {
603 	  silent_cerr("PressureFlowControlValve(" << uLabel << "): "
604 		  "null or negative valve diameter "
605 		  "at line " << HP.GetLineData() << std::endl);
606 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
607        }
608        DEBUGCOUT("Valve diameter: " << valve_diameter << std::endl);
609 
610        /* Densita' del corpo della valvola */
611        doublereal valve_density = HP.GetReal();
612        if (valve_density <= 0.) {
613 	  silent_cerr("PressureFlowControlValve(" << uLabel << "): "
614 		  "null or negative valve density "
615 		  "at line " << HP.GetLineData() << std::endl);
616 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
617        }
618        DEBUGCOUT("Valve density: " << valve_density << std::endl);
619 
620        /* c dello spostamento */
621        doublereal c_spost = HP.GetReal();
622        DEBUGCOUT("c_spost: " << c_spost << std::endl);
623 
624        /* c della velocita' */
625        doublereal c_vel = HP.GetReal();
626        DEBUGCOUT("c_vel: " << c_vel << std::endl);
627 
628        /* c della accelerazione */
629        doublereal c_acc = HP.GetReal();
630        DEBUGCOUT("c_acc: " << c_acc << std::endl);
631 
632        HydraulicFluid* hf = HP.GetHydraulicFluid();
633        ASSERT(hf != NULL);
634 
635        flag fOut = pDM->fReadOutput(HP, Elem::HYDRAULIC);
636 
637        SAFENEWWITHCONSTRUCTOR(pEl,
638 			      Pressure_flow_control_valve,
639 			      Pressure_flow_control_valve(uLabel, pDO, hf,
640 						    pNode1, pNode2,
641 						    pNode3, pNode4,
642 						    pNode5, pNode6,
643 						    pDC, start,
644 						    s_max, width,
645 						    loss_area,
646 						    valve_diameter,
647 						    valve_density,
648 						    c_spost, c_vel, c_acc,
649 						    fOut));
650        break;
651     }
652 
653 
654     case PRESSURE_VALVE: {
655 
656        /* nodo 1 */
657        const PressureNode* pNode1 = pDM->ReadNode<const PressureNode, Node::HYDRAULIC>(HP);
658 
659        /* nodo 2 */
660        const PressureNode* pNode2 = pDM->ReadNode<const PressureNode, Node::HYDRAULIC>(HP);
661 
662        /* Area diaframma */
663        doublereal area_diaf = HP.GetReal();
664        if (area_diaf <= 0.) {
665 	  silent_cerr("PressureValve(" << uLabel << "): "
666 		  "null or negative area_diaf "
667 		  "at line " << HP.GetLineData() << std::endl);
668 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
669        }
670        DEBUGCOUT("Area_diaf: " << area_diaf << std::endl);
671 
672        /* Massa valvola */
673        doublereal mass = HP.GetReal();
674        if (mass <= 0.) {
675 	  silent_cerr("PressureValve(" << uLabel << "): "
676 		  "null or negative valve mass "
677 		  "at line " << HP.GetLineData() << std::endl);
678 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
679        }
680        DEBUGCOUT("Valve mass: " << mass << std::endl);
681 
682        /* Area massima della valvola */
683        doublereal area_max = HP.GetReal();
684        if (area_max <= 0.) {
685 	  silent_cerr("PressureValve(" << uLabel << "): "
686 		  "null or negative area_max "
687 		  "at line " << HP.GetLineData() << std::endl);
688 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
689        }
690        DEBUGCOUT("Area_max: " << area_max << std::endl);
691 
692        /* Spostamento massimo della valvola */
693        doublereal s_max = HP.GetReal();
694        if (s_max < 0.) {
695 	  silent_cerr("PressureValve(" << uLabel << "): "
696 		  "negative s_max "
697 		  "at line " << HP.GetLineData() << std::endl);
698 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
699        }
700        DEBUGCOUT("S_max: " << s_max << std::endl);
701 
702        /* Kappa : costante della molla */
703        doublereal Kappa = HP.GetReal();
704        if (Kappa < 0.) {
705 	  silent_cerr("PressureValve(" << uLabel << "): "
706 		  "negative Kappa "
707 		  "at line " << HP.GetLineData() << std::endl);
708 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
709        }
710        DEBUGCOUT("Kappa: " << Kappa << std::endl);
711 
712        /* Forza0: precarico della molla */
713        doublereal force0 = HP.GetReal();
714        if (force0 < 0.) {
715 	  silent_cerr("PressureValve(" << uLabel << "): "
716 		  "negative force0 "
717 		  "at line " << HP.GetLineData() << std::endl);
718 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
719        }
720        DEBUGCOUT("Force0: " << force0 << std::endl);
721 
722        /* Larghezza luce di passaggio */
723        doublereal width = HP.GetReal();
724        if (width <= 0.) {
725 	  silent_cerr("PressureValve(" << uLabel << "): "
726 		  "null or negative width "
727 		  "at line " << HP.GetLineData() << std::endl);
728 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
729        }
730        DEBUGCOUT("Width: " << width << std::endl);
731 
732        /* c dello spostamento */
733        doublereal c_spost = HP.GetReal();
734        DEBUGCOUT("c_spost: " << c_spost << std::endl);
735 
736        /* c della velocita' */
737        doublereal c_vel = HP.GetReal();
738        DEBUGCOUT("c_vel: " << c_vel << std::endl);
739 
740        /* c della accelerazione */
741        doublereal c_acc = HP.GetReal();
742        DEBUGCOUT("c_acc: " << c_acc << std::endl);
743 
744        HydraulicFluid* hf = HP.GetHydraulicFluid();
745        ASSERT(hf != NULL);
746 
747        flag fOut = pDM->fReadOutput(HP, Elem::HYDRAULIC);
748 
749        SAFENEWWITHCONSTRUCTOR(pEl,
750 			      Pressure_valve,
751                               Pressure_valve(uLabel, pDO, hf, pNode1, pNode2,
752 					     area_diaf, mass, area_max,
753 					     s_max, Kappa, force0, width,
754 					     c_spost, c_vel, c_acc,
755 					     fOut));
756 
757        break;
758     }
759 
760     case FLOW_VALVE: {
761 
762        /* nodo 1 */
763        const PressureNode* pNode1 = pDM->ReadNode<const PressureNode, Node::HYDRAULIC>(HP);
764 
765        /* nodo 2 */
766        const PressureNode* pNode2 = pDM->ReadNode<const PressureNode, Node::HYDRAULIC>(HP);
767 
768        /* nodo 3 */
769        const PressureNode* pNode3 = pDM->ReadNode<const PressureNode, Node::HYDRAULIC>(HP);
770 
771        /* Area diaframma */
772        doublereal area_diaf = HP.GetReal();
773        if (area_diaf <= 0.) {
774 	  silent_cerr("FlowValve(" << uLabel << "): "
775 		  "null or negative area_diaf "
776 		  "at line " << HP.GetLineData() << std::endl);
777 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
778        }
779        DEBUGCOUT("Area_diaf: " << area_diaf << std::endl);
780 
781        /* Massa valvola */
782        doublereal mass = HP.GetReal();
783        if (mass <= 0.) {
784 	  silent_cerr("FlowValve(" << uLabel << "): "
785 		  "null or negative valve mass "
786 		  "at line " << HP.GetLineData() << std::endl);
787 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
788        }
789        DEBUGCOUT("Valve mass: " << mass << std::endl);
790 
791        /* Area tubo */
792        doublereal area_pipe = HP.GetReal();
793        if (area_pipe <= 0.) {
794 	  silent_cerr("FlowValve(" << uLabel << "): "
795 		  "null or negative area_pipe "
796 		  "at line " << HP.GetLineData() << std::endl);
797 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
798        }
799        DEBUGCOUT("Area_pipe: " << area_pipe << std::endl);
800 
801        /* Area massima della valvola */
802        doublereal area_max = HP.GetReal();
803        if (area_max <= 0.) {
804 	  silent_cerr("FlowValve(" << uLabel << "): "
805 		  "null or negative area_max "
806 		  "at line " << HP.GetLineData() << std::endl);
807 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
808        }
809        DEBUGCOUT("Area_max: " << area_max << std::endl);
810 
811        /* Kappa : costante della molla */
812        doublereal Kappa = HP.GetReal();
813        if (Kappa <= 0.) {
814 	  silent_cerr("FlowValve(" << uLabel << "): "
815 		  "null or negative Kappa "
816 		  "at line " << HP.GetLineData() << std::endl);
817 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
818        }
819        DEBUGCOUT("Kappa: " << Kappa << std::endl);
820 
821        /* Forza0: precarico della molla */
822        doublereal force0 = HP.GetReal();
823        if (force0 < 0.) {
824 	  silent_cerr("FlowValve(" << uLabel << "): "
825 		  "negative force0 "
826 		  "at line " << HP.GetLineData() << std::endl);
827 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
828        }
829        DEBUGCOUT("Force0: " << force0 << std::endl);
830 
831        /* Larghezza luce di passaggio */
832        doublereal width = HP.GetReal();
833        if (width <= 0.) {
834 	  silent_cerr("FlowValve(" << uLabel << "): "
835 		  "null or negative width "
836 		  "at line " << HP.GetLineData() << std::endl);
837 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
838        }
839        DEBUGCOUT("Width: " << width << std::endl);
840 
841        /* Corsa massima della valvola */
842        doublereal s_max = HP.GetReal();
843        if (s_max < 0.) {
844 	  silent_cerr("FlowValve(" << uLabel << "): "
845 		  "negative s_max "
846 		  "at line " << HP.GetLineData() << std::endl);
847 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
848        }
849        DEBUGCOUT("s_max: " << s_max << std::endl);
850 
851        /* c dello spostamento */
852        doublereal c_spost = HP.GetReal();
853        DEBUGCOUT("c_spost: " << c_spost << std::endl);
854 
855        /* c della velocita' */
856        doublereal c_vel = HP.GetReal();
857        DEBUGCOUT("c_vel: " << c_vel << std::endl);
858 
859        /* c della accelerazione */
860        doublereal c_acc = HP.GetReal();
861        DEBUGCOUT("c_acc: " << c_acc << std::endl);
862 
863        HydraulicFluid* hf = HP.GetHydraulicFluid();
864        ASSERT(hf != NULL);
865 
866        flag fOut = pDM->fReadOutput(HP, Elem::HYDRAULIC);
867 
868        SAFENEWWITHCONSTRUCTOR(pEl,
869 			      Flow_valve,
870                               Flow_valve(uLabel, pDO, hf,
871 					 pNode1, pNode2, pNode3,
872 					 area_diaf, mass,area_pipe, area_max,
873 					 Kappa, force0, width, s_max,
874 					 c_spost, c_vel, c_acc,
875 					 fOut));
876 
877        break;
878     }
879 
880     case ORIFICE: {
881 
882        /* nodo 1 */
883        const PressureNode* pNode1 = pDM->ReadNode<const PressureNode, Node::HYDRAULIC>(HP);
884 
885        /* nodo 2 */
886        const PressureNode* pNode2 = pDM->ReadNode<const PressureNode, Node::HYDRAULIC>(HP);
887 
888        /* Diametro */
889        doublereal diameter = HP.GetReal();
890        if (diameter <= 0.) {
891 	  silent_cerr("Orifice(" << uLabel << "): "
892 		  "null or negative diameter "
893 		  "at line " << HP.GetLineData() << std::endl);
894 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
895        }
896        DEBUGCOUT("Diameter: " << diameter << std::endl);
897 
898        /* Area diaframma */
899        doublereal area_diaf = HP.GetReal();
900        if (area_diaf <= 0.) {
901 	  silent_cerr("Orifice(" << uLabel << "): "
902 		  "null or negative area_diaf "
903 		  "at line " << HP.GetLineData() << std::endl);
904 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
905        }
906        DEBUGCOUT("Area_diaf: " << area_diaf << std::endl);
907 
908        /* Area del tubo */
909        doublereal area_pipe = diameter*diameter*0.785;
910        if (HP.IsKeyWord("area"))
911 	 {
912 	    area_pipe = HP.GetReal();
913 	    if (area_pipe <= 0.)
914 	      {
915 		 silent_cerr("Orifice(" << uLabel << "): "
916 			 "null or negative area_pipe "
917 			 "at line " << HP.GetLineData() << std::endl);
918 		 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
919 	      }
920 	 }
921        DEBUGCOUT("Area_pipe: " << area_pipe << std::endl);
922 
923        doublereal ReCr = 10;
924        if (HP.IsKeyWord("reynolds"))
925 	 {
926 	    ReCr = HP.GetReal();
927 	    if (ReCr <= 0.)
928 	      {
929 		 silent_cerr("Orifice(" << uLabel << "): "
930 			 "null or negative Reynold's number "
931 			 "at line " << HP.GetLineData() << std::endl);
932 		 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
933 	      }
934 	 }
935        DEBUGCOUT("Reynold critico: " << ReCr << std::endl);
936 
937        HydraulicFluid* hf = HP.GetHydraulicFluid();
938        ASSERT(hf != NULL);
939 
940        flag fOut = pDM->fReadOutput(HP, Elem::HYDRAULIC);
941 
942        SAFENEWWITHCONSTRUCTOR(pEl,
943 			      Orifice,
944 			      Orifice(uLabel, pDO, hf,
945 				      pNode1, pNode2,
946 				      diameter,
947 				      area_diaf, area_pipe, ReCr, fOut));
948        break;
949     }
950 
951     case ACCUMULATOR: {
952 
953        /* nodo */
954        const PressureNode* pNode = pDM->ReadNode<const PressureNode, Node::HYDRAULIC>(HP);
955 
956        /* Corsa pistone */
957        doublereal stroke = HP.GetReal();
958        if (stroke <= 0.) {
959 	  silent_cerr("Accumulator(" << uLabel << "): "
960 		  "null or negative stroke "
961 		  "at line " << HP.GetLineData() << std::endl);
962 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
963        }
964        DEBUGCOUT("Stroke: " << stroke << std::endl);
965 
966        doublereal start = 0.;
967        if (HP.IsKeyWord("start")) {
968 	  // Corsa iniziale del setto
969 	  start = HP.GetReal();
970 	  if (start > stroke)
971 	    {
972 	       silent_cerr("Accumulator(" << uLabel << "): "
973 		       "stroke less then initial position "
974 		       "at line " << HP.GetLineData() << std::endl);
975 	       throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
976 	    }
977        }
978        DEBUGCOUT("start: " << start << std::endl);
979 
980        /* Area stantuffo */
981        doublereal area = HP.GetReal();
982        if (area <= 0.) {
983 	  silent_cerr("Accumulator(" << uLabel << "): "
984 		  "null or negative area "
985 		  "at line " << HP.GetLineData() << std::endl);
986 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
987        }
988        DEBUGCOUT("Area: " << area << std::endl);
989 
990        /* Area pipe */
991        doublereal area_pipe = HP.GetReal();
992        if (area_pipe <= 0.) {
993 	  silent_cerr("Accumulator(" << uLabel << "): "
994 		  "null or negative area_pipe "
995 		  "at line " << HP.GetLineData() << std::endl);
996 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
997        }
998        DEBUGCOUT("area_pipe: " << area_pipe << std::endl);
999 
1000        /* Massa stantuffo */
1001        doublereal mass = HP.GetReal();
1002        if (mass <= 0.) {
1003 	  silent_cerr("Accumulator(" << uLabel << "): "
1004 		  "null or negative mass "
1005 		  "at line " << HP.GetLineData() << std::endl);
1006 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
1007        }
1008        DEBUGCOUT("Mass: " << mass << std::endl);
1009 
1010        doublereal h_in = 1;
1011        if (HP.IsKeyWord("lossin")) {
1012 	  // Perdita di carico entrata
1013 	  h_in = HP.GetReal();
1014 	  if (h_in < 0.)
1015 	    {
1016 	       silent_cerr("Accumulator(" << uLabel << "): "
1017 		       "negative loss_in "
1018 		       "at line " << HP.GetLineData() << std::endl);
1019 	       throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
1020 	    }
1021        }
1022        DEBUGCOUT("Loss_in: " << h_in << std::endl);
1023 
1024        doublereal h_out = 0.5;
1025 	    if (HP.IsKeyWord("lossout")) {
1026 	       // Perdita di carico uscita
1027 	       h_out = HP.GetReal();
1028  	       if (h_out < 0.)
1029 		 {
1030 		    silent_cerr("Accumulator(" << uLabel << "): "
1031 			    "negative loss_out "
1032 			    "at line " << HP.GetLineData() << std::endl);
1033 		    throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
1034 		 }
1035 	    }
1036 	    DEBUGCOUT("loss_out: " << h_out << std::endl);
1037 
1038        doublereal press0   = 0.;
1039        doublereal press_max= 0.;
1040        doublereal Kappa    = 0.;
1041 
1042        if (HP.IsKeyWord("gas")) {
1043 
1044 	  /* Pressione gas accumulatore scarico */
1045 	  press0 = HP.GetReal();
1046 	  if (press0 <= 0.) {
1047 	     silent_cerr("Accumulator(" << uLabel << "): "
1048 		     "null or negative pressure0 "
1049 		     "at line " << HP.GetLineData() << std::endl);
1050 	     throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
1051 	  }
1052 	  DEBUGCOUT("press0: " << press0 << std::endl);
1053 
1054 	  /* Pressione massima del gas */
1055 	  press_max = HP.GetReal();
1056 	  if (press_max <= 0.) {
1057 	     silent_cerr("Accumulator(" << uLabel << "): "
1058 		     "null or negative pressure max "
1059 		     "at line " << HP.GetLineData() << std::endl);
1060 	     throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
1061 	  }
1062 	  DEBUGCOUT("Pressure max: " << press_max << std::endl);
1063 
1064 	  Kappa = HP.GetReal();
1065 	  if (Kappa < 0.) {
1066 	     silent_cerr("Accumulator(" << uLabel << "): "
1067 		     "negative Kappa "
1068 		     "at line " << HP.GetLineData() << std::endl);
1069 	     throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
1070 	  }
1071 	  DEBUGCOUT("Kappa: " << Kappa << std::endl);
1072        }
1073 
1074        doublereal weight = 0.;
1075        if (HP.IsKeyWord("weight")) {
1076 	  weight = HP.GetReal();
1077 	  if (weight <= 0.) {
1078 	     silent_cerr("Accumulator(" << uLabel << "): "
1079 		     "null or negative weight "
1080 		     "at line " << HP.GetLineData() << std::endl);
1081 	     throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
1082 	  }
1083 	  DEBUGCOUT("weight: " << weight << std::endl);
1084        }
1085 
1086        doublereal spring = 0.;
1087        doublereal force0 = 0.;
1088        if (HP.IsKeyWord("spring")) {
1089 	  spring = HP.GetReal();
1090 	  if (spring < 0.) {
1091 	     silent_cerr("Accumulator(" << uLabel << "): "
1092 		     "negative spring "
1093 		     "at line " << HP.GetLineData() << std::endl);
1094 	     throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
1095 	  }
1096 
1097 	  force0 = HP.GetReal();
1098 	  if (force0 < 0.) {
1099 	     silent_cerr("Accumulator(" << uLabel << "): "
1100 		     "negative force0 "
1101 		     "at line " << HP.GetLineData() << std::endl);
1102 	     throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
1103 	  }
1104 	  DEBUGCOUT("spring: " << spring << std::endl);
1105 	  DEBUGCOUT("force0: " << force0 << std::endl);
1106        }
1107 
1108        /* c dello spostamento */
1109        doublereal c_spost = HP.GetReal();
1110        DEBUGCOUT("c_spost: " << c_spost << std::endl);
1111 
1112        /* c della velocita' */
1113        doublereal c_vel = HP.GetReal();
1114        DEBUGCOUT("c_vel: " << c_vel << std::endl);
1115 
1116        /* c della accelerazione */
1117        doublereal c_acc = HP.GetReal();
1118        DEBUGCOUT("c_acc: " << c_acc << std::endl);
1119 
1120        HydraulicFluid* hf = HP.GetHydraulicFluid();
1121        ASSERT(hf != NULL);
1122 
1123        flag fOut = pDM->fReadOutput(HP, Elem::HYDRAULIC);
1124 
1125        SAFENEWWITHCONSTRUCTOR(pEl,
1126 			      Accumulator,
1127 			      Accumulator(uLabel, pDO, hf, pNode,
1128 					  stroke, start, area, area_pipe,
1129 					  mass,h_in, h_out,
1130 					  press0, press_max,
1131 					  Kappa, weight, spring, force0,
1132 					  c_spost, c_vel, c_acc, fOut));
1133        break;
1134     }
1135 
1136     case TANK: {
1137 
1138        /* nodo 1 */
1139        const PressureNode* pNode1 = pDM->ReadNode<const PressureNode, Node::HYDRAULIC>(HP);
1140 
1141        /* nodo 2 */
1142        const PressureNode* pNode2 = pDM->ReadNode<const PressureNode, Node::HYDRAULIC>(HP);
1143 
1144        /* Pressione serbatoio */
1145        doublereal press = HP.GetReal();
1146        if (press <= 0.) {
1147 	  silent_cerr("Tank(" << uLabel << "): "
1148 		  "null or negative pressure "
1149 		  "at line " << HP.GetLineData() << std::endl);
1150 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
1151        }
1152        DEBUGCOUT("Pressure: " << press << std::endl);
1153 
1154        /* Area pipe */
1155        doublereal area_pipe = HP.GetReal();
1156        if (area_pipe <= 0.) {
1157 	  silent_cerr("Tank(" << uLabel << "): "
1158 		  "null or negative area_pipe "
1159 		  "at line " << HP.GetLineData() << std::endl);
1160 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
1161        }
1162        DEBUGCOUT("Area_pipe: " << area_pipe << std::endl);
1163 
1164        /* Area serbatoio */
1165        doublereal area_serb = HP.GetReal();
1166        if (area_serb <= 0.) {
1167 	  silent_cerr("Tank(" << uLabel << "): "
1168 		  "null or negative area_serb "
1169 		  "at line " << HP.GetLineData() << std::endl);
1170 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
1171        }
1172        DEBUGCOUT("Area serbatoio: " << area_serb << std::endl);
1173 
1174        /* Livello massimo dell'olio */
1175        doublereal s_max = HP.GetReal();
1176        if (s_max < 0.) {
1177 	  silent_cerr("Tank(" << uLabel << "): "
1178 		  "negative s_max "
1179 		  "at line " << HP.GetLineData() << std::endl);
1180 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
1181        }
1182        DEBUGCOUT("Livello massimo dell'olio: " << s_max << std::endl);
1183 
1184        /* Livello iniziale */
1185        doublereal level= .5*s_max; /* valore di default 50% del massimo */
1186 
1187        if (HP.IsKeyWord("startlevel")) {
1188 	  level = HP.GetReal();
1189 	  if (level < 0.) {
1190 	     silent_cerr("Tank(" << uLabel << "): "
1191 		     "negative level "
1192 		     "at line " << HP.GetLineData() << std::endl);
1193 	     throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
1194 	  }
1195 	  DEBUGCOUT("Livello iniziale: " << level << std::endl);
1196        }
1197 
1198        /* Soglia di allarme */
1199        doublereal s_min = .1*s_max; /* valore di default 10% del massimo */
1200        if (HP.IsKeyWord("alarmlevel")) {
1201 	  doublereal s_min = HP.GetReal();
1202 	  if (s_min < 0.) {
1203 	     silent_cerr("Tank(" << uLabel << "): "
1204 		     "negative s_min "
1205 		     "at line " << HP.GetLineData() << std::endl);
1206 	     throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
1207 	  }
1208 	  DEBUGCOUT("Soglia di allarme: " << s_min << std::endl);
1209        }
1210 
1211        /* c dello spostamento */
1212        doublereal c_spost = HP.GetReal();
1213        DEBUGCOUT("c_spost: " << c_spost << std::endl);
1214 
1215        HydraulicFluid* hf = HP.GetHydraulicFluid();
1216        ASSERT(hf != NULL);
1217 
1218        flag fOut = pDM->fReadOutput(HP, Elem::HYDRAULIC);
1219 
1220        SAFENEWWITHCONSTRUCTOR(pEl,
1221 			      Tank,
1222 			      Tank (uLabel, pDO, hf, pNode1,pNode2, press,
1223 				    area_pipe, area_serb,
1224 				    level, s_max, s_min, c_spost, fOut));
1225        break;
1226     }
1227 
1228     case PIPE: {
1229 
1230        /* nodo 1 */
1231        const PressureNode* pNode1 = pDM->ReadNode<const PressureNode, Node::HYDRAULIC>(HP);
1232 
1233        /* nodo 2 */
1234        const PressureNode* pNode2 = pDM->ReadNode<const PressureNode, Node::HYDRAULIC>(HP);
1235 
1236        /* Diametro */
1237        doublereal diameter = HP.GetReal();
1238        if (diameter <= 0.) {
1239 	  silent_cerr("Pipe(" << uLabel << "): "
1240 		  "null or negative diameter "
1241 		  "at line " << HP.GetLineData() << std::endl);
1242 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
1243        }
1244        DEBUGCOUT("Diameter: " << diameter << std::endl);
1245 
1246        // Area
1247        doublereal area = diameter*diameter*M_PI_4;
1248        if (HP.IsKeyWord("area"))
1249 	 {
1250 	    area = HP.GetReal();
1251 	    if (area <= 0.)
1252 	      {
1253 		 silent_cerr("Pipe(" << uLabel << "): "
1254 			 "null or negative area "
1255 			 "at line " << HP.GetLineData() << std::endl);
1256 		 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
1257 	      }
1258 	      }
1259        DEBUGCOUT("Area: " << area << std::endl);
1260 
1261        /* Lunghezza */
1262        doublereal lenght = HP.GetReal();
1263        if (lenght <= 0.) {
1264 	  silent_cerr("Pipe(" << uLabel << "): "
1265 		  "null or negative lenght "
1266 		  "at line " << HP.GetLineData() << std::endl);
1267 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
1268        }
1269        DEBUGCOUT("Lenght: " << lenght << std::endl);
1270 
1271        /* Transizione se e' 0 parto da laminare se e' 1 parto da turbolento */
1272        flag turbulent = 0;
1273        if (HP.IsKeyWord("turbulent")) {
1274 	  turbulent = 1;
1275 	  DEBUGCOUT("Turbulent" << std::endl);
1276        }
1277        doublereal q0 = 0.;
1278        if (HP.IsKeyWord("initial" "value")) {
1279 	  q0 = HP.GetReal();
1280 	  DEBUGCOUT("Initial q = " << q0 << std::endl);
1281        }
1282 
1283        HydraulicFluid* hf = HP.GetHydraulicFluid();
1284        ASSERT(hf != NULL);
1285 
1286        flag fOut = pDM->fReadOutput(HP, Elem::HYDRAULIC);
1287 
1288        SAFENEWWITHCONSTRUCTOR(pEl,
1289 			      Pipe,
1290 			      Pipe(uLabel, pDO, hf, pNode1, pNode2,
1291 				   diameter,
1292 				   area, lenght, turbulent, q0, fOut));
1293        break;
1294     }
1295 
1296     case DYNAMIC_PIPE: {
1297 
1298        /* nodo 1 */
1299        const PressureNode* pNode1 = dynamic_cast<PressureNode *>(pDM->ReadNode(HP, Node::HYDRAULIC));
1300 
1301        /* nodo 2 */
1302        const PressureNode* pNode2 = dynamic_cast<PressureNode *>(pDM->ReadNode(HP, Node::HYDRAULIC));
1303 
1304        doublereal diameter = HP.GetReal();
1305        if (diameter <= 0.) {
1306 	  silent_cerr("DynamicPipe(" << uLabel << "): "
1307 		  "null or negative diameter "
1308 		  "at line " << HP.GetLineData() << std::endl);
1309 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
1310        }
1311        DEBUGCOUT("Diameter: " << diameter << std::endl);
1312 
1313        // Area
1314        doublereal area = diameter*diameter*M_PI_4;
1315        if (HP.IsKeyWord("area"))
1316 	      {
1317 		 area = HP.GetReal();
1318 		 if (area <= 0.) {
1319 		    silent_cerr("DynamicPipe(" << uLabel << "): "
1320 			    "null or negative area "
1321 			    "at line " << HP.GetLineData() << std::endl);
1322 		    throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
1323 		 }
1324 	      }
1325        DEBUGCOUT("Area: " << area << std::endl);
1326 
1327        /* Lunghezza */
1328        doublereal lenght = HP.GetReal();
1329        if (lenght <= 0.) {
1330 	  silent_cerr("DynamicPipe(" << uLabel << "): "
1331 		  "null or negative lenght "
1332 		  "at line " << HP.GetLineData() << std::endl);
1333 	  throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
1334        }
1335        DEBUGCOUT("Lenght: " << lenght << std::endl);
1336 
1337        /* Transizione se e' 0 parto da laminare se e' 1 parto da turbolento */
1338        flag turbulent = 0;
1339        if (HP.IsKeyWord("turbulent")) {
1340 	  turbulent = 1;
1341 	  DEBUGCOUT("Turbulent" << std::endl);
1342        }
1343        doublereal q0 = 0.;
1344        if (HP.IsKeyWord("initial" "value")) {
1345 	  q0 = HP.GetReal();
1346 	  DEBUGCOUT("Initial q = " << q0 << std::endl);
1347        }
1348 
1349        HydraulicFluid* hf = HP.GetHydraulicFluid();
1350        ASSERT(hf != NULL);
1351 
1352        flag fOut = pDM->fReadOutput(HP, Elem::HYDRAULIC);
1353 
1354        SAFENEWWITHCONSTRUCTOR(pEl,
1355 			      DynamicPipe,
1356 			      DynamicPipe(uLabel, pDO, hf,
1357 					   pNode1, pNode2, diameter,
1358 					   area, lenght, turbulent, q0, fOut));
1359        break;
1360     }
1361 
1362       /* Aggiungere altri elementi idraulici */
1363 
1364     default: {
1365        silent_cerr("unknown hydraulic element type "
1366 	       "for hydraulic element " << uLabel
1367       	       << " at line " << HP.GetLineData() << std::endl);
1368        throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
1369     }
1370    }
1371 
1372    /* Se non c'e' il punto e virgola finale */
1373    if (HP.IsArg()) {
1374       silent_cerr("semicolon expected "
1375 	      "at line " << HP.GetLineData() << std::endl);
1376       throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
1377    }
1378 
1379    return pEl;
1380 }
1381