MBDyn-1.7.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
discctrl.cc
Go to the documentation of this file.
1 /* $Header: /var/cvs/mbdyn/mbdyn/mbdyn-1.0/mbdyn/elec/discctrl.cc,v 1.43 2017/01/12 14:46:22 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 /* Discrete Control:
33  * writes the output of selected dofs to a subprocess that generates the
34  * input; then applies the input to selected dofs as an abstract force
35  */
36 
37 #include "mbconfig.h" /* This goes first in every *.c,*.cc file */
38 
39 #include <cerrno>
40 #include <cstdlib>
41 
42 #include "discctrl.h"
43 
44 /* DiscreteControlProcess - begin */
45 
47 {
48  NO_OP;
49 }
50 
51 /* DiscreteControlProcess - end */
52 
53 /* DiscreteControlARXProcess_Debug - begin */
54 
55 int
57  doublereal* pd,
58  unsigned int iNumRows,
59  unsigned int iNumCols,
60  unsigned int iNumSubMats,
61  const char* sMatName)
62 {
63  // Matrices alpha_i
64 
65  // for every k + 1 = 1->p (every matrix)
66  for (unsigned int k = 0; k < iNumSubMats; k++) {
67  int iShift = iNumCols*k;
68 
69  // for every row
70  for (unsigned int i = 0; i < iNumRows; i++) {
71  doublereal* pdTmp = pd + iShift + iNumSubMats*iNumCols*i;
72 
73  // for every column
74  for (unsigned int j = 0; j < iNumCols; j++) {
75  In >> pdTmp[j];
76  if (!In) {
77  silent_cerr("Error: unexpected end of stream while reading "
78  << sMatName << '_' << k + 1
79  << '(' << i + 1 << ',' << j + 1 << ')'
80  << std::endl);
81 
83  }
84 
85  DEBUGLCOUT(MYDEBUG_INIT, sMatName << '_' << k + 1
86  << "(" << i << "," << j << ") = " << pdTmp[j]
87  << std::endl);
88  }
89  }
90  }
91 
92  return 0;
93 }
94 
96  integer iNumIn,
97  integer iOrdA,
98  integer iOrdB,
99  const std::string& infile)
100 : iNumOutputs(iNumOut),
101 iNumInputs(iNumIn),
102 iOrderA(iOrdA),
103 iOrderB(iOrdB),
104 pdA(0),
105 pdY(0),
106 pdB(0),
107 pdU(0),
108 pdU0(0),
109 iRefA(0),
110 iRefB(0)
111 {
112  /* The control model is handled as follows:
113  * the outputs and inputs are stored in two vector:
114  * Y = [y(k-1), ..., y(k-pa)], U = [u(k-1), ..., u(k-pb)]
115  * as soon as new y, u are available, the oldes values are replaced by
116  * the newest and the vector is used as a queue, i.e. it starts from
117  * a floating reference and goes back to the beginning when it's
118  * over.
119  * Mathices alpha, beta are stacked in two big matrtices:
120  * A = [alpha_1, ..., alpha_pa], B = [beta_1, ..., beta_pb]
121  * the input is calculated as A*Y + B*U
122  */
123 
124  // At present at least one input and one output are required
125  ASSERT(iNumInputs > 0);
126  ASSERT(iNumOutputs > 0);
127  ASSERT(iOrderA > 0);
128  ASSERT(iOrderB > 0);
129 
130  // Size of working area
131  int iSize = iNumInputs*iNumOutputs*iOrderA // Matrix A
132  + iNumInputs*iNumInputs*iOrderB // Matrix B
133  + iNumOutputs*iOrderA // Vector Y
134  + iNumInputs*iOrderB // Vector U
135  + iNumInputs; // Vector u(k)
136 
137  doublereal *pd = 0;
138  SAFENEWARR(pd, doublereal, iSize);
139 
140  pdA = pd;
141  pd += iNumInputs*iNumOutputs*iOrderA;
142 
143  pdB = pd;
144  pd += iNumInputs*iNumInputs*iOrderB;
145 
146  pdY = pd;
147  pd += iNumOutputs*iOrderA;
148 
149  pdU = pd;
150  pd += iNumInputs*iOrderB;
151 
152  pdU0 = pd;
153 
154  for (int i = iSize; i-- > 0; ) {
155  pdA[i] = 0.;
156  }
157 
158  /* In the input file, for human readability matrices are written as:
159  * alpha_1,
160  * alpha_2,
161  * ...
162  * alpha_p,
163  * beta_1,
164  * ...
165  * beta_p
166  */
167 
168  std::ifstream In(infile.c_str());
169  if (!In) {
170  silent_cerr("DiscreteControlARXProcess_Debug: "
171  "unable to open control data file \"" << infile << "\""
172  << std::endl);
174  }
175 
176  ReadMatrix(In, pdA, iNumInputs, iNumOutputs, iOrderA, "alpha");
177  ReadMatrix(In, pdB, iNumInputs, iNumInputs, iOrderB, "beta");
178 }
179 
181 {
182  /* It must be non-null;
183  * matrices and arrays come from one allocation only */
184  if (pdA != 0) {
186  }
187 }
188 
189 void
190 DiscreteControlARXProcess_Debug::GetInput(std::vector<doublereal>& dIn)
191 {
192  for (int i = iNumInputs; i-- > 0; ) {
193  dIn[i] = pdU0[i];
194  }
195 }
196 
197 void
198 DiscreteControlARXProcess_Debug::PutOutput(const std::vector<doublereal>& dOut,
199  const std::vector<doublereal>& dIn,
200  const std::vector<doublereal>& /* dDesiredOut */ )
201 {
202  /* At present dDesiredOutput is not used;
203  * it will be when the system is controlled
204  * and ID'd at the same time */
205 
206  // Moves reference backwards
207  if (iRefA == 0) {
208  iRefA = iOrderA;
209  }
210  iRefA--;
211 
212  doublereal* pdOff = pdY + iNumOutputs*iRefA;
213  for (int i = iNumOutputs; i-- > 0; ) {
214  pdOff[i] = dOut[i];
215  }
216 
217  // Moves reference backwards
218  if (iRefB == 0) {
219  iRefB = iOrderB;
220  }
221  iRefB--;
222 
223  pdOff = pdU + iNumInputs*iRefB;
224  for (int i = iNumInputs; i-- > 0; ) {
225  /* dIn contiene la somma dell'ingresso esogeno e dell'ingresso
226  * di controllo, ovvero l'ingresso totale applicato al sistema;
227  * pdU0 contiene il solo ingresso generato dal controllore */
228  pdOff[i] = dIn[i];
229  pdU0[i] = 0.;
230  }
231 
232  // Matrices are row-oriented
234  // Y shiftato di iRefA
235  doublereal* pdVecOff = pdY + iRefA*iNumOutputs;
236  for (int i = iNumInputs; i-- > 0; ) {
237  for (int j = iRefA*iNumOutputs; j-- > 0; ) {
238  pdMatOff--;
239  pdU0[i] += pdMatOff[0]*pdY[j];
240  }
241  for (int j = (iOrderA-iRefA)*iNumOutputs; j-- > 0; ) {
242  pdMatOff--;
243  pdU0[i] += pdMatOff[0]*pdVecOff[j];
244  }
245  }
246 
247  pdMatOff = pdB + iOrderB*iNumInputs*iNumInputs;
248  pdVecOff = pdU + iRefB*iNumInputs;
249  for (int i = iNumInputs; i-- > 0; ) {
250  for (int j = iRefB*iNumInputs; j-- > 0; ) {
251  pdMatOff--;
252  pdU0[i] += pdMatOff[0]*pdU[j];
253  }
254  for (int j = (iOrderB-iRefB)*iNumInputs; j-- > 0; ) {
255  pdMatOff--;
256  pdU0[i] += pdMatOff[0]*pdVecOff[j];
257  }
258  }
259 }
260 
261 /* DiscreteControlProcess_Debug - end */
262 
263 
264 /* DiscreteIdentProcess_Debug - begin */
265 
267  integer iNumIn,
268  integer iOrdA,
269  integer iOrdB,
270  ForgettingFactor* pf,
272  unsigned f_proc,
273  const std::string& sf)
274 : iNumOutputs(iNumOut), iNumInputs(iNumIn),
275 iOrderA(iOrdA), iOrderB(iOrdB), pId(0), pPx(px),
276 outfile(sf)
277 {
278  ASSERT(pf != 0);
279  ASSERT(px != 0);
280 
281  switch (f_proc) {
282  case DISCPROC_ARX:
284  IdentARXProcess(iNumOut, iNumIn, iOrdA, iOrdB, pf));
285  break;
286 
287  case DISCPROC_ARMAX:
289  IdentARMAXProcess(iNumOut, iNumIn, iOrdA, iOrdB, pf));
290  break;
291 
292  default:
293  silent_cerr("DiscreteIdentProcess_Debug: "
294  "unknown model type " << f_proc << std::endl);
296  }
297 
298  // temporaneo ?!?
299  if (!outfile.empty()) {
300  out.open(outfile.c_str());
301  }
302 }
303 
305 {
306  if (pId != 0) {
307  SAFEDELETE(pId);
308  }
309 
310  if (pPx != 0) {
311  SAFEDELETE(pPx);
312  }
313 
314  // temporaneo ?!?
315  if (!outfile.empty()) {
316  out.close();
317  }
318 }
319 
320 /* Returns the new control input values in array dIn */
321 void
322 DiscreteIdentProcess_Debug::GetInput(std::vector<doublereal>& dIn)
323 {
324  /* azzera per sicurezza */
325  for (integer i = iNumInputs; i-- > 0; ) {
326  dIn[i] = 0.;
327  }
328 
329  pPx->AddInput(&dIn[0]);
330 }
331 
332 const unsigned long BUFSIZE = 102400;
334 
335 /* Sets the new measures (and eventually the input) */
336 void
337 DiscreteIdentProcess_Debug::PutOutput(const std::vector<doublereal>& dOut,
338  const std::vector<doublereal>& dIn,
339  const std::vector<doublereal>& /* dDesiredOut */ )
340 {
341  pId->Update(&dOut[0], &dIn[0]);
342 
343  if (!outfile.empty()) {
344  integer size = pId->iGetSize()*pId->iGetNumOutput();
345  if (size*sizeof(doublereal) > BUFSIZE) {
346  silent_cerr("buffer is too small" << std::endl);
347 
348  } else {
349  pId->GetTheta(buf);
350  for (integer i = 0; i < pId->iGetSize()*pId->iGetNumOutput(); i++) {
351  out << std::setw(16) << buf[i];
352  }
353  out << std::setw(16) << pId->dGetForgettingFactor() << std::endl;
354  }
355  }
356 }
357 
358 /* DiscreteIdentProcess_Debug - end */
359 
360 
361 /* DAC_Process_Debug - begin */
362 
364  integer iNumIn,
365  integer iOrdA,
366  integer iOrdB,
367  ForgettingFactor* pf,
368  GPCDesigner* pd,
370  DriveCaller* pTrig,
371  std::vector<DriveCaller *>& vDesOut,
372  const std::string& sf,
373  unsigned f_proc)
374 : iNumOutputs(iNumOut),
375 iNumInputs(iNumIn),
376 iOrderA(iOrdA),
377 iOrderB(iOrdB),
378 iOrderMd(0),
379 pdBase(0),
380 pdTheta(0),
381 pdA(0),
382 pdY(0),
383 pdB(0),
384 pdU(0),
385 f_proc(f_proc),
386 pdC(0),
387 pdE(0),
388 pdMd(0),
389 pdYd(0),
390 pdU0(0),
391 iRefA(0),
392 iRefB(0),
393 iRefMd(0),
394 pId(0), pCD(pd), pPx(px), Trigger(pTrig),
395 outfile(sf)
396 {
397  /* The control model is handled as follows:
398  * the outputs and inputs are stored in two vector:
399  * Y = [y(k-1), ..., y(k-pa)], U = [u(k-1), ..., u(k-pb)]
400  * as soon as new y, u are available, the oldes values are replaced by
401  * the newest and the vector is used as a queue, i.e. it starts from
402  * a floating reference and goes back to the beginning when it's
403  * over.
404  * Mathices alpha, beta are stacked in two big matrtices:
405  * A = [alpha_1, ..., alpha_pa], B = [beta_1, ..., beta_pb]
406  * the input is calculated as A*Y + B*U
407  */
408 
409  /* At present at least one input and one output are required */
410  ASSERT(iNumInputs > 0);
411  ASSERT(iNumOutputs > 0);
412  ASSERT(iOrderA > 0);
413  ASSERT(iOrderB > 0);
414 
415  ASSERT(pCD != 0);
416  ASSERT(pPx != 0);
417 
419  ASSERT(iOrderMd > 0);
420 
421  /* Size of working area */
422  int iSize =
423  iNumOutputs*iOrderA // Vector Y
424  +iNumInputs*iOrderB // Vector U
425  +iNumOutputs*iOrderMd // Vector Yd
426  +iNumInputs // Vector u(k)
427  +iNumOutputs*(iNumOutputs*iOrderA + iNumInputs*(iOrderB + 1)); // Theta
428 
429  if ((f_proc & DISCPROC_MA) == DISCPROC_MA) {
430  iSize += iNumOutputs*iOrderA // Vector E
431  + iNumOutputs*iNumOutputs*iOrderA; // Theta e' piu' grande!
432  }
433 
434  SAFENEWARR(pdBase, doublereal, iSize);
435 
436  pdY = pdBase;
437  pdU = pdY + iNumOutputs*iOrderA;
439  pdU0 = pdYd + iNumOutputs*iOrderMd;
440  pdTheta = pdU0 + iNumInputs;
441 
442  if ((f_proc & DISCPROC_MA) == DISCPROC_MA) {
443  pdE = pdU0 + iNumInputs;
444  pdTheta = pdE + iNumOutputs*iOrderA;
445  }
446 
447  for (int i = iSize; i-- > 0; ) {
448  pdBase[i] = 0.;
449  }
450 
451  /* In the input file, for human readability matrices are written as:
452  * alpha_1,
453  * alpha_2,
454  * ...
455  * alpha_p,
456  * beta_1,
457  * ...
458  * beta_p
459  */
460 
461  /* Si costruisce l'identificatore ARX */
462  switch (f_proc) {
463  case DISCPROC_ARX:
465  IdentARXProcess(iNumOut, iNumIn, iOrdA, iOrdB, pf));
466  break;
467 
468  case DISCPROC_ARMAX:
470  IdentARMAXProcess(iNumOut, iNumIn, iOrdA, iOrdB, pf));
471  break;
472 
473  default:
474  silent_cerr("DAC_Process_Debug: "
475  "unknown identification type " << f_proc
476  << std::endl);
478  }
479 
480  if (!vDesOut.empty()) {
481  vDesiredOut.resize(iNumOutputs);
482 
483  for (integer i = 0; i < iNumOutputs; i++) {
484  vDesiredOut[i] = 0;
486  DriveOwner,
487  DriveOwner(vDesOut[i]));
488  }
489  }
490 
491  // temporaneo ?!?
492  if (!outfile.empty()) {
493  out.open(outfile.c_str());
494  // mettere un test?
495  }
496 }
497 
498 
500 {
501  // matrices and arrays come from one allocation only
502 
503  if (pdBase != 0) {
505  }
506 
507  if (pId != 0) {
508  SAFEDELETE(pId);
509  }
510 
511  if (pCD != 0) {
512  SAFEDELETE(pCD);
513  }
514 
515  if (pPx) {
516  SAFEDELETE(pPx);
517  }
518 
519  // can be null (no desired output
520  for (std::vector<DriveOwner *>::iterator i = vDesiredOut.begin();
521  i != vDesiredOut.end(); ++i)
522  {
523  SAFEDELETE(*i);
524  }
525 
526  // temporaneo ?!?
527  if (!outfile.empty()) {
528  out.close();
529  }
530 }
531 
532 void
533 DAC_Process_Debug::GetInput(std::vector<doublereal>& dIn)
534 {
535  // control input
536  for (int i = iNumInputs; i-- > 0; ) {
537  dIn[i] = pdU0[i];
538  }
539 
540  // persistent excitation
541  pPx->AddInput(&dIn[0]);
542 }
543 
544 void
545 DAC_Process_Debug::PutOutput(const std::vector<doublereal>& dOut,
546  const std::vector<doublereal>& dIn,
547  const std::vector<doublereal>& dDesiredOut)
548 {
549  /* At present dDesiredOutput is not used;
550  * it will be when the system is controlled
551  * and ID'd at the same time */
552 
553  ASSERT(pId != 0);
554  ASSERT(pCD != 0);
555 
556  pId->Update(&dOut[0], &dIn[0]);
557 
558  if (!outfile.empty()) {
559  pId->GetTheta(pdTheta);
560 
561  for (integer i = 0; i < pId->iGetSize()*pId->iGetNumOutput(); i++) {
562  out << std::setw(16) << pdTheta[i];
563  }
564  out << std::setw(16) << pId->dGetForgettingFactor() << std::endl;
565  }
566 
567  if (Trigger.dGet()) {
568  pCD->DesignControl(pdTheta, &pdA, &pdB, &pdMd, &pdC);
569  }
570 
571  // Moves reference backwards
572  if (iRefA == 0) {
573  iRefA = iOrderA;
574  }
575  iRefA--;
576 
577  doublereal* pdOff = pdY + iNumOutputs*iRefA;
578  for (int i = iNumOutputs; i-- > 0; ) {
579  pdOff[i] = dOut[i];
580  }
581 
582  if ((f_proc & DISCPROC_MA) == DISCPROC_MA) {
583  pdOff = pdE + iNumOutputs*iRefA;
584  pId->GetErr(pdOff);
585  }
586 
587  /* Moves reference backwards */
588  if (iRefB == 0) {
589  iRefB = iOrderB;
590  }
591  iRefB--;
592 
593  pdOff = pdU + iNumInputs*iRefB;
594  for (int i = iNumInputs; i-- > 0; ) {
595  /* dIn contiene la somma dell'ingresso esogeno e dell'ingresso
596  * di controllo, ovvero l'ingresso totale applicato al sistema;
597  * pdU0 contiene il solo ingresso generato dal controllore */
598  pdOff[i] = dIn[i];
599  pdU0[i] = 0.;
600  }
601 
602  // Moves reference backwards
603  if (!vDesiredOut.empty()) {
604  if (iRefMd == 0) {
605  iRefMd = iOrderMd;
606  }
607  iRefMd--;
608 
609  doublereal* pdOff = pdYd + iNumOutputs*iRefMd;
610  for (int i = iNumOutputs; i-- > 0; ) {
611  pdOff[i] = vDesiredOut[i]->dGet();
612  }
613 
614  if (!dDesiredOut.empty()) {
615  for (int i = iNumOutputs; i-- > 0; ) {
616  pdOff[i] += dDesiredOut[i];
617  }
618  }
619  }
620 
621  if (pdB == 0) {
622  return;
623  }
624 
625  // Matrices are row-oriented
627  // Y shiftato di iRefA
628  doublereal* pdVecOff = pdY + iRefA*iNumOutputs;
629  for (int i = iNumInputs; i-- > 0; ) {
630  for (int j = iRefA*iNumOutputs; j-- > 0; ) {
631  pdMatOff--;
632  pdU0[i] += pdMatOff[0]*pdY[j];
633  }
634  for (int j = (iOrderA-iRefA)*iNumOutputs; j-- > 0; ) {
635  pdMatOff--;
636  pdU0[i] += pdMatOff[0]*pdVecOff[j];
637  }
638  }
639 
640  pdMatOff = pdB + iOrderB*iNumInputs*iNumInputs;
641  pdVecOff = pdU + iRefB*iNumInputs;
642  for (int i = iNumInputs; i-- > 0; ) {
643  for (int j = iRefB*iNumInputs; j-- > 0; ) {
644  pdMatOff--;
645  pdU0[i] += pdMatOff[0]*pdU[j];
646  }
647  for (int j = (iOrderB - iRefB)*iNumInputs; j-- > 0; ) {
648  pdMatOff--;
649  pdU0[i] += pdMatOff[0]*pdVecOff[j];
650  }
651  }
652 
653  if ((f_proc & DISCPROC_MA) == DISCPROC_MA) {
654  pdMatOff = pdC + iOrderA*iNumOutputs*iNumInputs;
655  // E shiftato di iRefA
656  pdVecOff = pdE + iRefA*iNumOutputs;
657  for (int i = iNumInputs; i-- > 0; ) {
658  for (int j = iRefA*iNumOutputs; j-- > 0; ) {
659  pdMatOff--;
660  pdU0[i] += pdMatOff[0]*pdE[j];
661  }
662  for (int j = (iOrderA - iRefA)*iNumOutputs; j-- > 0; ) {
663  pdMatOff--;
664  pdU0[i] += pdMatOff[0]*pdVecOff[j];
665  }
666  }
667  }
668 
669  if (!vDesiredOut.empty()) {
670  pdMatOff = pdMd + iOrderMd*iNumOutputs*iNumInputs;
671  // Yd shiftato di iRefMd
672  pdVecOff = pdYd + iRefMd*iNumOutputs;
673  for (int i = iNumInputs; i-- > 0; ) {
674  for (int j = iRefMd*iNumOutputs; j-- > 0; ) {
675  pdMatOff--;
676  pdU0[i] += pdMatOff[0]*pdYd[j];
677  }
678  for (int j = (iOrderMd - iRefMd)*iNumOutputs; j-- > 0; ) {
679  pdMatOff--;
680  pdU0[i] += pdMatOff[0]*pdVecOff[j];
681  }
682  }
683  }
684 }
685 
686 /* DAC_Process_Debug - end */
687 
688 /* DiscreteControlElem - begin */
689 
691  const DofOwner* pDO,
692  integer iNumOut,
693  std::vector<ScalarValue *>& vOut,
694  std::vector<DriveCaller *>& vOutSF,
695  integer iNumIn,
696  ScalarDof* pIn,
698  integer iNIt,
699  flag fOut)
700 : Elem(uL, fOut),
701 Electric(uL, pDO, fOut),
702 pDCP(p),
703 bNewStep(true),
704 iNumIter(iNIt),
705 iCurrIter(0),
706 iNumOutputs(iNumOut),
707 vOutputs(vOut),
708 dOut(iNumOutputs),
709 iNumInputs(iNumIn),
710 pInputs(pIn),
711 dIn(iNumInputs)
712 {
713  /* The inputs should be all scalar dofs; an abtract force is
714  * applied to every node;
715  * the outputs can be of every kind */
716 
717  /* Allocs and resets memory for input and output current values */
718  ASSERT(iNumInputs > 0);
719  ASSERT(iNumOutputs > 0);
720 
721  vOutScaleFact.resize(iNumOutputs);
722 
723  for (int i = iNumOutputs; i-- > 0; ) {
724  vOutScaleFact[i] = 0;
726  DriveOwner,
727  DriveOwner(vOutSF[i]));
728  }
729 
730  for (std::vector<doublereal>::iterator i = dIn.begin();
731  i != dIn.end(); ++i)
732  {
733  *i = 0.;
734  }
735 
736  for (std::vector<doublereal>::iterator i = dOut.begin();
737  i != dOut.end(); ++i)
738  {
739  *i = 0.;
740  }
741 }
742 
744 {
745  for (std::vector<DriveOwner *>::iterator i = vOutScaleFact.begin();
746  i != vOutScaleFact.end(); ++i)
747  {
748  SAFEDELETE(*i);
749  }
750 
751  for (std::vector<ScalarValue *>::iterator i = vOutputs.begin();
752  i != vOutputs.end(); ++i)
753  {
754  SAFEDELETE(*i);
755  }
756 
757  // Allocated by DataManager
759 
760  // Must destroy the other processes too
761  SAFEDELETE(pDCP);
762 }
763 
766 {
768 }
769 
770 /* Scrive il contributo dell'elemento al file di restart */
771 std::ostream&
772 DiscreteControlElem::Restart(std::ostream& out) const
773 {
774  out << " electric: " << GetLabel() << ", discrete control; "
775  "# to be implemented" << std::endl;
776  return out;
777 }
778 
779 static const std::vector<doublereal> dEmptyDesiredOut;
780 
781 void
783  const VectorHandler& XP)
784 {
785  // Sets the flag for a new step
786  if (++iCurrIter == iNumIter) {
787  iCurrIter = 0;
788 
789  ASSERT(bNewStep == false);
790  bNewStep = true;
791 
792  // Gets output from solution
793  for (int iCnt = iNumOutputs; iCnt-- > 0; ) {
794  dOut[iCnt] = vOutScaleFact[iCnt]->dGet()*vOutputs[iCnt]->dGetValue();
795  }
796 
797  // Gets input from solution
798  for (int iCnt = iNumInputs; iCnt-- > 0; ) {
799  dIn[iCnt] = pInputs[iCnt].dGetValue();
800  }
801 
802  // Puts measures to control subprocess
803  // DCP knows the length of dOut and dIn
805  }
806 
807  // Add extra output as needed
808 }
809 
810 /* assemblaggio residuo */
813  doublereal /* dCoef */ ,
814  const VectorHandler& /* XCurr */ ,
815  const VectorHandler& /* XPrimeCurr */ )
816 {
817  WorkVec.ResizeReset(iNumInputs);
818 
819  // At first iteration gets the input from the control subprocess
820  if (bNewStep) {
821  // Gets the inputs from subprocess
822  // DCP knows the length of dIn
823  pDCP->GetInput(dIn);
824 
825  // resets the flag
826  bNewStep = false;
827  }
828 
829  // Sets the parameters
830  for (int iCnt = iNumInputs; iCnt-- > 0; ) {
831  // Equivalent to an abstract force
832  WorkVec.PutItem(iCnt + 1, pInputs[iCnt].pNode->iGetFirstRowIndex() + 1, dIn[iCnt]);
833  }
834 
835  return WorkVec;
836 }
837 
838 /* ritorna il numero di Dofs per gli elementi che sono anche DofOwners */
839 unsigned int
841 {
842  return 0;
843 }
844 
845 /* esegue operazioni sui dof di proprieta' dell'elemento */
847 DiscreteControlElem::GetDofType(unsigned int /* i */ ) const
848 {
849  ASSERTMSG(0, "You shouldn't have called this function");
850  return DofOrder::UNKNOWN;
851 }
852 
853 /* Dimensioni del workspace */
854 void
855 DiscreteControlElem::WorkSpaceDim(integer* piNumRows, integer* piNumCols) const
856 {
857  *piNumRows = iNumInputs;
858  *piNumCols = 1;
859 }
860 
861 /* assemblaggio jacobiano */
864  doublereal /* dCoef */ ,
865  const VectorHandler& /* XCurr */ ,
866  const VectorHandler& /* XPrimeCurr */ )
867 {
868  WorkMat.SetNullMatrix();
869  return WorkMat;
870 }
871 
872 unsigned int
874 {
875  return iNumInputs;
876 }
877 
878 unsigned int
880 {
881  /*
882  * legal values:
883  *
884  * "u[<idx>]" with <idx> ::= positive integer between 1 and iNumInputs
885  */
886  switch (s[0]) {
887  case 'u':
888  s++;
889  break;
890 
891  default:
892  return 0;
893  }
894 
895  if (s[0] != '[') {
896  return 0;
897  }
898  s++;
899 
900  if (s[0] == '-') {
901  return 0;
902  }
903 
904  char *next;
905  errno = 0;
906  long idx = std::strtol(s, &next, 10);
907  int save_errno = errno;
908  if (next == s || next[0] != ']') {
909  return 0;
910  }
911 
912  if (save_errno == ERANGE) {
913  silent_cerr("DiscreteControlElem(" << GetLabel() << "): "
914  "warning, private data index " << std::string(s, next - s)
915  << " overflows" << std::endl);
916  return 0;
917  }
918 
919  if (idx > iNumInputs) {
920  return 0;
921  }
922 
923  return idx;
924 }
925 
928 {
929  if (i < 1 || i > (unsigned int)iNumInputs) {
931  }
932 
933  return dIn[i - 1];
934 }
935 
936 /* Fornisce il tipo e la label dei nodi che sono connessi all'elemento
937  * utile per l'assemblaggio della matrice di connessione fra i dofs */
938 void
940  std::vector<const Node *>& connectedNodes) const {
941  connectedNodes.resize(iNumInputs + iNumOutputs);
942  for (int i = 0; i < iNumInputs; i++) {
943  connectedNodes[i] = pInputs[i].pNode;
944  }
945 
946  unsigned cnt = unsigned(iNumInputs);
947  for (int i = 0; i < iNumOutputs; i++) {
948  ScalarDofValue *psdv = dynamic_cast<ScalarDofValue *>(vOutputs[i]);
949  if (psdv) {
950  connectedNodes[cnt] = psdv->pNode;
951  cnt++;
952  }
953  }
954 
955  ASSERT(cnt <= connectedNodes.size());
956 
957  if (cnt != connectedNodes.size()) {
958  connectedNodes.resize(cnt);
959  }
960 }
961 
962 /* DiscreteControlElem - end */
963 
unsigned f_proc
Definition: discctrl.h:224
ScalarNode * pNode
Definition: node.h:708
integer iGetNumOutput(void) const
Definition: id.h:115
std::vector< doublereal > dOut
Definition: discctrl.h:281
long int flag
Definition: mbdyn.h:43
integer iNumOutputs
Definition: discctrl.h:213
#define MBDYN_EXCEPT_ARGS
Definition: except.h:63
const std::string outfile
Definition: discctrl.h:185
virtual void AfterConvergence(const VectorHandler &X, const VectorHandler &XP)
Definition: discctrl.cc:782
virtual void ResizeReset(integer)
Definition: vh.cc:55
IdentProcess * pId
Definition: discctrl.h:234
std::vector< DriveOwner * > vOutScaleFact
Definition: discctrl.h:280
virtual doublereal dGetForgettingFactor(void)
Definition: id.h:108
void GetInput(std::vector< doublereal > &dIn)
Definition: discctrl.cc:533
doublereal * pdU0
Definition: discctrl.h:229
std::vector< doublereal > dIn
Definition: discctrl.h:285
doublereal * pdC
Definition: discctrl.h:225
std::vector< DriveOwner * > vDesiredOut
Definition: discctrl.h:239
integer iNumInputs
Definition: discctrl.h:214
#define SAFEDELETEARR(pnt)
Definition: mynewmem.h:713
DAC_Process_Debug(integer iNumOut, integer iNumIn, integer iOrdA, integer iOrdB, ForgettingFactor *pf, GPCDesigner *pd, PersistentExcitation *px, DriveCaller *PTrig, std::vector< DriveCaller * > &vDesOut, const std::string &sf, unsigned f_proc)
Definition: discctrl.cc:363
#define ASSERTMSG(expr, msg)
Definition: myassert.h:219
virtual unsigned int iGetPrivDataIdx(const char *s) const
Definition: discctrl.cc:879
#define NO_OP
Definition: myassert.h:74
IdentProcess * pId
Definition: discctrl.h:181
virtual Electric::Type GetElectricType(void) const
Definition: discctrl.cc:765
virtual VariableSubMatrixHandler & AssJac(VariableSubMatrixHandler &WorkMat, doublereal, const VectorHandler &, const VectorHandler &)
Definition: discctrl.cc:863
virtual ~DiscreteControlProcess(void)
Definition: discctrl.cc:46
virtual void PutItem(integer iSubRow, integer iRow, const doublereal &dCoef)
Definition: submat.h:1445
doublereal * pdE
Definition: discctrl.h:226
GPCDesigner * pCD
Definition: discctrl.h:235
integer iOrderA
Definition: discctrl.h:215
virtual SubVectorHandler & AssRes(SubVectorHandler &WorkVec, doublereal dCoef, const VectorHandler &XCurr, const VectorHandler &XPrimeCurr)
Definition: discctrl.cc:812
DiscreteControlProcess * pDCP
Definition: discctrl.h:273
integer iOrderB
Definition: discctrl.h:216
doublereal * pdTheta
Definition: discctrl.h:219
virtual ~DAC_Process_Debug(void)
Definition: discctrl.cc:499
PersistentExcitation * pPx
Definition: discctrl.h:236
std::vector< ScalarValue * > vOutputs
Definition: discctrl.h:279
doublereal * pdBase
Definition: discctrl.h:218
doublereal * pdU
Definition: discctrl.h:223
ScalarDof * pInputs
Definition: discctrl.h:284
void SetNullMatrix(void)
Definition: submat.h:1159
void GetInput(std::vector< doublereal > &dIn)
Definition: discctrl.cc:322
void PutOutput(const std::vector< doublereal > &dOut, const std::vector< doublereal > &dIn, const std::vector< doublereal > &dDesiredOut)
Definition: discctrl.cc:337
const std::string outfile
Definition: discctrl.h:242
static int outfile
PersistentExcitation * pPx
Definition: discctrl.h:182
doublereal * pdY
Definition: discctrl.h:221
virtual void Update(const doublereal *pdY, const doublereal *pdU)=0
Definition: elec.h:43
DiscreteIdentProcess_Debug(integer iNumOut, integer iNumIn, integer iOrdA, integer iOrdB, ForgettingFactor *pf, PersistentExcitation *px, unsigned f_proc, const std::string &sf)
Definition: discctrl.cc:266
Definition: mbdyn.h:77
#define ASSERT(expression)
Definition: colamd.c:977
integer iNumOutputs
Definition: discctrl.h:278
Type
Definition: elec.h:46
virtual void GetTheta(doublereal *pdTheta)=0
std::ofstream out
Definition: discctrl.h:243
virtual ~DiscreteControlARXProcess_Debug(void)
Definition: discctrl.cc:180
#define SAFENEWWITHCONSTRUCTOR(pnt, item, constructor)
Definition: mynewmem.h:698
virtual void GetConnectedNodes(std::vector< const Node * > &connectedNodes) const
Definition: discctrl.cc:939
DriveOwner Trigger
Definition: discctrl.h:237
integer iNumInputs
Definition: discctrl.h:283
virtual void PutOutput(const std::vector< doublereal > &dOut, const std::vector< doublereal > &dIn, const std::vector< doublereal > &dDesiredOut)=0
void GetInput(std::vector< doublereal > &dIn)
Definition: discctrl.cc:190
const unsigned long BUFSIZE
Definition: discctrl.cc:332
virtual integer iGetSize(void) const =0
doublereal * pdB
Definition: discctrl.h:222
virtual ~DiscreteControlElem(void)
Definition: discctrl.cc:743
integer iOrderMd
Definition: discctrl.h:217
doublereal * pdMd
Definition: discctrl.h:227
virtual void WorkSpaceDim(integer *piNumRows, integer *piNumCols) const
Definition: discctrl.cc:855
Definition: elem.h:75
virtual ~DiscreteIdentProcess_Debug(void)
Definition: discctrl.cc:304
virtual void GetErr(doublereal *pdE)
Definition: id.cc:191
virtual unsigned int iGetNumDof(void) const
Definition: discctrl.cc:840
doublereal dGet(const doublereal &dVar) const
Definition: drive.cc:664
integer iRefMd
Definition: discctrl.h:232
int ReadMatrix(std::istream &In, doublereal *pd, unsigned int iRows, unsigned int iCols, unsigned int iNumSubMats, const char *sMatName)
Definition: discctrl.cc:56
virtual void GetInput(std::vector< doublereal > &dIn)=0
doublereal * pdA
Definition: discctrl.h:220
integer iGetPredHor(void) const
Definition: gpc.h:219
static const std::vector< doublereal > dEmptyDesiredOut
Definition: discctrl.cc:779
#define SAFENEWARR(pnt, item, sz)
Definition: mynewmem.h:701
integer iGetPredStep(void) const
Definition: gpc.h:207
virtual void AddInput(doublereal *pd) const =0
DiscreteControlElem(unsigned int uL, const DofOwner *pDO, integer iNumOut, std::vector< ScalarValue * > &vOut, std::vector< DriveCaller * > &vOutSF, integer iNumIn, ScalarDof *ppIn, DiscreteControlProcess *p, integer iNIt, flag fOut)
Definition: discctrl.cc:690
virtual void DesignControl(const doublereal *, doublereal **ppda=NULL, doublereal **ppdb=NULL, doublereal **ppdm=NULL, doublereal **ppdc=NULL)
Definition: gpc.cc:818
static doublereal buf[BUFSIZE]
Definition: discctrl.cc:333
void PutOutput(const std::vector< doublereal > &dOut, const std::vector< doublereal > &dIn, const std::vector< doublereal > &dDesiredOut)
Definition: discctrl.cc:198
double doublereal
Definition: colamd.c:52
virtual std::ostream & Restart(std::ostream &out) const
Definition: discctrl.cc:772
DiscreteControlARXProcess_Debug(integer iNumOut, integer iNumIn, integer iOrdA, integer iOrdB, const std::string &infile)
Definition: discctrl.cc:95
long int integer
Definition: colamd.c:51
void PutOutput(const std::vector< doublereal > &dOut, const std::vector< doublereal > &dIn, const std::vector< doublereal > &dDesiredOut)
Definition: discctrl.cc:545
unsigned int GetLabel(void) const
Definition: withlab.cc:62
const doublereal & dGetValue(void) const
Definition: node.cc:730
#define DEBUGLCOUT(level, msg)
Definition: myassert.h:244
virtual DofOrder::Order GetDofType(unsigned int) const
Definition: discctrl.cc:847
virtual doublereal dGetPrivData(unsigned int i) const
Definition: discctrl.cc:927
#define SAFEDELETE(pnt)
Definition: mynewmem.h:710
virtual unsigned int iGetNumPrivData(void) const
Definition: discctrl.cc:873
doublereal * pdYd
Definition: discctrl.h:228