00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #ifndef __NODE_VECT_H
00035 #define __NODE_VECT_H
00036
00037 #include "AbsVect.h"
00038
00039 namespace OFELI {
00040
00045 template <class T_> class Vect;
00046 template <class T_> class AbsVect;
00047
00048
00049
00050
00051
00052
00053 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00054 template<class T_>
00055 struct ErrorInNodeVect {
00056 void Message(const string &file, int line, int code, int p1=0)
00057 {
00058 cerr << "\n*** Fatal Error in OFELI ***\n";
00059 cerr << "File: " << file << ", Line: " << line << "\nIn NodeVect<>::";
00060 switch (code) {
00061
00062 case 21:
00063 cerr << "NodeVect(mesh,nb_dof) : Illegal value of nb_dof : " << p1 << endl;
00064 break;
00065
00066 case 31:
00067 cerr << "NodeVect(mesh,nb_dof,name,time) : Illegal value of nb_dof : " << p1 << endl;
00068 break;
00069
00070 case 51:
00071 cerr << "NodeVect(mesh,v,nb_dof,first_dof,name,time) : Illegal value of nb_dof : " << p1 << endl;
00072 break;
00073
00074 case 52:
00075 cerr << "NodeVect(mesh,v,nb_dof,first_dof,name,time) : Illegal value of first_dof : " << p1 << endl;
00076 break;
00077
00078 case 91:
00079 cerr << "FromVect(v,nb_dof,first_dof,name,time) : ";
00080 cerr << "Illegal value of first_dof : " << p1 << endl;
00081 break;
00082
00083 case 101:
00084 cerr << "Init() : Impossible memory allocation for array ptr_";
00085 break;
00086
00087 case 102:
00088 cerr << "Init() : Impossible memory allocation for array _v";
00089 break;
00090
00091 case 111:
00092 cerr << "Fill(v,dof) : Illegal value of dof : " << p1 << endl;
00093 break;
00094
00095 case 121:
00096 cerr << "Get(ff) : Number of nodes in mesh and input file do not match\n";
00097 break;
00098
00099 case 131:
00100 cerr << "Get(ff,time) : Number of nodes in mesh and input file do not match\n";
00101 break;
00102
00103 case 141:
00104 cerr << "View(ff) : Number of nodes in mesh and input file do not match\n";
00105 exit(1);
00106 break;
00107 }
00108 cerr << "Program stops" << endl;
00109 exit(1);
00110 }
00111 };
00112 #endif
00113
00114
00129 template <class T_>
00130 class NodeVect : virtual public AbsVect<T_>
00131 {
00132
00133 public:
00134
00135 using AbsVect<T_>::setName;
00136 using AbsVect<T_>::Init;
00137
00139 NodeVect();
00140
00145 NodeVect(const class Mesh &mesh, size_t nb_dof=1);
00146
00153 NodeVect(const class Mesh &mesh, int nb_dof, const string &name=" ", double time=0);
00154
00157 NodeVect(const NodeVect<T_> &v);
00158
00165 NodeVect(const class Mesh &mesh, const Vect<T_> &v, const string &name=" ", double time=0);
00166
00175 NodeVect(const class Mesh &mesh, const Vect<T_> &v, int nb_dof, size_t first_dof, const string &name=" ", double time=0);
00176
00184 NodeVect(const class Element &el, const NodeVect<T_> &v);
00185
00191 NodeVect(const class Side &sd, const NodeVect<T_> &v);
00192
00200 NodeVect(const class Mesh &mesh, const Vect<T_> &v, const Vect<T_> &bc, const string &name=" ", double time=0);
00201
00203 ~NodeVect();
00204
00209 void setMesh(const class Mesh &ms, size_t nb_dof=0);
00210
00217 void set(size_t dof, const string ®exp);
00218
00225 void fromVect(const Vect<T_> &v, size_t first_dof, const char *name, double time);
00226
00234 void fromVect(const class Mesh &mesh, const Vect<T_> &v, size_t first_dof, const string &name, double time);
00235
00242 void insertBC(const Vect<T_> &v, const Vect<T_> &bc);
00243
00249 void insertBC(const Vect<T_> &bc);
00250
00253 int get(const string &file);
00254
00259 int get(const string &file, double time);
00260
00261 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00262 int Get(const string &file) { return get(file); }
00263 int Get(const string &file, double time) { return get(file,time); }
00264 #endif
00265
00267 size_t getNbNodes() const;
00268
00271 NodeVect<T_> & operator=(T_ a);
00272
00275 NodeVect<T_> & operator=(const string &exp);
00276
00281 NodeVect<T_> & operator+=(const NodeVect<T_> &x);
00282
00287 NodeVect<T_> & operator+=(const T_ &a);
00288
00291 NodeVect<T_> & operator-=(const NodeVect<T_> &x);
00292
00297 NodeVect<T_> & operator-=(const T_ &a);
00298
00301 NodeVect<T_> &operator*=(const T_ &a);
00302
00305 NodeVect<T_> &operator/=(const T_ &a);
00306
00307 protected:
00308
00309 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00310 ErrorInNodeVect<T_> _e;
00311 size_t _nb_nodes;
00312
00313 using AbsVect<T_>::_nbn;
00314 using AbsVect<T_>::_nb;
00315 using AbsVect<T_>::_nb_dof;
00316 using AbsVect<T_>::_first_dof;
00317 using AbsVect<T_>::_length;
00318 using AbsVect<T_>::_time;
00319 using AbsVect<T_>::_name;
00320 using AbsVect<T_>::_theMesh;
00321 using AbsVect<T_>::_v;
00322 using AbsVect<T_>::_M;
00323 using AbsVect<T_>::_b;
00324 using AbsVect<T_>::_this_dof;
00325 using AbsVect<T_>::_kw;
00326 #endif
00327 };
00328
00329
00331
00333
00334 template<class T_>
00335 NodeVect<T_>::NodeVect()
00336 {
00337 #ifdef _OFELI_DEBUG
00338 std::clog << "An instance of class NodeVect is constructed.\n";
00339 std::clog << "File: " << __FILE__ << ", Line: " << __LINE__ << endl;
00340 #endif
00341 }
00342
00343
00344 template <class T_>
00345 NodeVect<T_>::NodeVect(const class Mesh &mesh, size_t nb_dof) : AbsVect<T_>(mesh,nb_dof)
00346 {
00347 if (nb_dof <= 0)
00348 _e.Message(__FILE__,__LINE__,21,int(nb_dof));
00349 _nb = _nb_nodes = mesh.getNbNodes();
00350 _length = _nb_dof * _nb;
00351 Init();
00352 #ifdef _OFELI_DEBUG
00353 std::clog << "An instance of class NodeVect is constructed.\n";
00354 std::clog << "File: " << __FILE__ << ", Line: " << __LINE__ << endl;
00355 #endif
00356 }
00357
00358
00359 template <class T_>
00360 NodeVect<T_>::NodeVect(const class Mesh &mesh, int nb_dof, const string &name, double time)
00361 : AbsVect<T_>(mesh,nb_dof,name,time)
00362 {
00363 if (nb_dof <= 0)
00364 _e.Message(__FILE__,__LINE__,31,nb_dof);
00365 _nb = _nb_nodes = mesh.getNbNodes();
00366 _length = _nb_dof * _nb_nodes;
00367 Init();
00368 #ifdef _OFELI_DEBUG
00369 std::clog << "An instance of class NodeVect is constructed.\n";
00370 std::clog << "File: " << __FILE__ << ", Line: " << __LINE__ << endl;
00371 #endif
00372 }
00373
00374
00375 template <class T_>
00376 NodeVect<T_>::NodeVect(const NodeVect<T_> &v) : AbsVect<T_>(v)
00377 {
00378 _nbn = 1;
00379 _time = v._time;
00380 _name = v._name;
00381 _length = v.getLength();
00382 _nb = _nb_nodes = v.getNbNodes();
00383 _theMesh = v._theMesh;
00384 Init();
00385 _v = v._v;
00386 _M.resize((v._M).size());
00387 _M = v._M;
00388 _b.resize((v._b).size());
00389 _b = v._b;
00390 #ifdef _OFELI_DEBUG
00391 std::clog << "An instance of class NodeVect is constructed.\n";
00392 std::clog << "File: " << __FILE__ << ", Line: " << __LINE__ << endl;
00393 #endif
00394 }
00395
00396
00397 template <class T_>
00398 NodeVect<T_>::NodeVect(const class Mesh &mesh, const Vect<T_> &v, const string &name, double time)
00399 : AbsVect<T_>(mesh,name,time)
00400 {
00401 _nb = _nb_nodes = mesh.getNbNodes();
00402 const Node *nd;
00403 _nb_dof = _theMesh->getPtrNode(1)->getNbDOF();
00404 Init();
00405 size_t l=0;
00406 for (mesh.topNode(); (nd=mesh.getNode());)
00407 for (size_t k=0; k<nd->getNbDOF(); k++)
00408 _v[_nb_dof*(nd->getLabel()-1)+k] = v[l++];
00409 #ifdef _OFELI_DEBUG
00410 std::clog << "An instance of class NodeVect is constructed.\n";
00411 std::clog << "File: " << __FILE__ << ", Line: " << __LINE__ << endl;
00412 #endif
00413 }
00414
00415
00416 template <class T_>
00417 NodeVect<T_>::NodeVect(const class Mesh &mesh, const Vect<T_> &v, int nb_dof, size_t first_dof, const string &name, double time)
00418 : AbsVect<T_>(mesh,nb_dof,first_dof,name,time)
00419 {
00420 if (nb_dof <= 0 || nb_dof > int(mesh.getNbDOF()))
00421 _e.Message(__FILE__,__LINE__,51,nb_dof);
00422 if (first_dof < 1 || first_dof > mesh.getNbDOF())
00423 _e.Message(__FILE__,__LINE__,52,int(first_dof));
00424 _nb = _nb_nodes = mesh.getNbNodes();
00425 _length = nb_dof * _nb_nodes;
00426 Init();
00427 size_t l=0;
00428 const Node *nd;
00429 for (mesh.topNode(); (nd=mesh.getNode());) {
00430 for (size_t k=1; k<=nd->getNbDOF(); k++) {
00431 if (k>=_first_dof && k<=_nb_dof)
00432 _v[_nb_dof*(nd->getLabel()-1)+k-1] = v[l];
00433 l++;
00434 }
00435 }
00436 #ifdef _OFELI_DEBUG
00437 std::clog << "An instance of class NodeVect is constructed.\n";
00438 std::clog << "File: " << __FILE__ << ", Line: " << __LINE__ << endl;
00439 #endif
00440 }
00441
00442
00443 template <class T_>
00444 NodeVect<T_>::NodeVect(const class Element &el, const NodeVect<T_> &v)
00445 {
00446 _nbn = 1;
00447 _first_dof = 1;
00448 _time = 0.;
00449 const Node *nd;
00450 _length = el.getNbEq();
00451 _nb = _nb_nodes = el.getNbNodes();
00452 _nb_dof = el.getPtrNode(1)->getNbDOF();
00453 _name = v._name;
00454 Init();
00455 for (size_t j=0; j<_nb_nodes; j++) {
00456 nd = el.getPtrNode(j+1);
00457 for (size_t k=0; k<_nb_dof; k++)
00458 _v[_nb_dof*j+k] = v(nd->getLabel(),nd->getNbDOF());
00459 }
00460 #ifdef _OFELI_DEBUG
00461 std::clog << "An instance of class NodeVect is constructed.\n";
00462 std::clog << "File: " << __FILE__ << ", Line: " << __LINE__ << endl;
00463 #endif
00464 }
00465
00466
00467 template <class T_>
00468 NodeVect<T_>::NodeVect(const class Side &sd, const NodeVect<T_> &v)
00469 {
00470 _nbn = 1;
00471 _first_dof = 1;
00472 _time = 0.;
00473 const Node *nd;
00474 _length = sd.getNbEq();
00475 _nb_nodes = sd.getNbNodes();
00476 _name = v._name;
00477 _nb_dof = sd.getPtrNode(1)->getNbDOF();
00478 Init();
00479 for (size_t j=0; j<_nb_nodes; j++) {
00480 nd = sd.getPtrNode(j+1);
00481 for (size_t k=0; k<_nb_dof; k++)
00482 _v[_nb_dof*j+k] = v._v[_nb_dof*(nd->getLabel()-1)+k];
00483 }
00484 #ifdef _OFELI_DEBUG
00485 std::clog << "An instance of class NodeVect is constructed.\n";
00486 std::clog << "File: " << __FILE__ << ", Line: " << __LINE__ << endl;
00487 #endif
00488 }
00489
00490
00491 template <class T_>
00492 NodeVect<T_>::NodeVect(const class Mesh &mesh, const Vect<T_> &v, const Vect<T_> &bc, const string &name, double time)
00493 : AbsVect<T_>(mesh,name,time)
00494 {
00495 _nb = _nb_nodes = _theMesh->getNbNodes();
00496 _length = _theMesh->getNbDOF();
00497 _nb_dof = _theMesh->getPtrNode(1)->getNbDOF();
00498 Init();
00499 insertBC(v,bc);
00500 #ifdef _OFELI_DEBUG
00501 std::clog << "An instance of class NodeVect is constructed.\n";
00502 std::clog << "File: " << __FILE__ << ", Line: " << __LINE__ << endl;
00503 #endif
00504 }
00505
00506
00507 template <class T_>
00508 NodeVect<T_>::~NodeVect()
00509 {
00510 #ifdef _OFELI_DEBUG
00511 std::clog << "An instance of class NodeVect is destructed.\n";
00512 std::clog << "File: " << __FILE__ << ", Line: " << __LINE__ << endl;
00513 #endif
00514 }
00515
00516
00517 template <class T_>
00518 void NodeVect<T_>::setMesh(const class Mesh &ms, size_t nb_dof)
00519 {
00520 _theMesh = &ms;
00521 _first_dof = 1;
00522 _nbn = 1;
00523 _nb_dof = nb_dof;
00524 if (nb_dof==0)
00525 _nb_dof = ms.getPtrNode(1)->getNbDOF();
00526 _nb = _nb_nodes = ms.getNbNodes();
00527 _length = _nb_dof * _nb_nodes;
00528 Init();
00529 }
00530
00531
00532 template <class T_>
00533 void NodeVect<T_>::set(size_t dof, const string ®exp)
00534 {
00535 int err;
00536 double d[4];
00537 _theParser.Parse(regexp.c_str(),"x,y,t,z");
00538 const Node *nd;
00539 for (_theMesh->topNode(); (nd=_theMesh->getNode());) {
00540 d[0] = nd->getCoord(1);
00541 d[1] = nd->getCoord(2);
00542 d[3] = nd->getCoord(3);
00543 _v[_nb_dof*(nd->getLabel()-1)+dof-1] = _theParser.Eval(d);
00544 if ((err=_theParser.EvalError()))
00545 _e.Message(__FILE__,__LINE__,1,err);
00546 }
00547 }
00548
00549
00550 template <class T_>
00551 void NodeVect<T_>::fromVect(const Vect<T_> &v, size_t first_dof, const char *name, double time)
00552 {
00553 if (first_dof < 1 || first_dof > _theMesh->getNbDOF())
00554 _e.Message(__FILE__,__LINE__,91,int(first_dof));
00555 _length = _nb_dof * _nb_nodes;
00556 _first_dof = first_dof;
00557 _time = time;
00558 _name = string(name);
00559 Init();
00560 const Node *nd;
00561 for (_theMesh->topNode(); (nd=_theMesh->getNode());)
00562 for (size_t k=0; k<nd->getNbDOF(); k++)
00563 _v[_nb_dof*(nd->getLabel()-1)+k] = v(nd->getDOF(k+1));
00564 }
00565
00566
00567 template <class T_>
00568 void NodeVect<T_>::fromVect(const class Mesh &mesh, const Vect<T_> &v, size_t first_dof, const string &name, double time)
00569 {
00570 _theMesh = &mesh;
00571 if (first_dof < 1 || first_dof > _theMesh->getNbDOF())
00572 _e.Message(__FILE__,__LINE__,91,int(first_dof));
00573 _nb_nodes = _theMesh->getNbNodes();
00574 const Node *nd;
00575 _length = _theMesh->getNbDOF();
00576 _time = time;
00577 _name = string(name);
00578 Init();
00579 for (_theMesh->topNode(); (nd=_theMesh->getNode());)
00580 for (size_t k=0; k<nd->getNbDOF(); k++)
00581 _v[_nb_dof*(nd->getLabel()-1)+k] = v(nd->getDOF(k+1));
00582 }
00583
00584
00585 template <class T_>
00586 void NodeVect<T_>::insertBC(const Vect<T_> &v, const Vect<T_> &bc)
00587 {
00588 const Node *nd;
00589 for (_theMesh->topNode(); (nd=_theMesh->getNode());) {
00590 for (size_t i=0; i<nd->getNbDOF(); i++) {
00591 size_t n = _nb_dof*(nd->getLabel()-1) + i;
00592 _v[n] = bc[n];
00593 if (nd->getCode(i+1) == 0)
00594 _v[n] = v[nd->getDOF(i+1)-1];
00595 }
00596 }
00597 }
00598
00599
00600 template <class T_>
00601 void NodeVect<T_>::insertBC(const Vect<T_> &bc)
00602 {
00603 const Node *nd;
00604 for (_theMesh->topNode(); (nd=_theMesh->getNode());) {
00605 for (size_t i=0; i<nd->getNbDOF(); i++) {
00606 size_t n = _nb_dof*(nd->getLabel()-1) + i;
00607 if (nd->getCode(i+1) > 0)
00608 _v[n] = bc[n];
00609 }
00610 }
00611 }
00612
00613
00614 template <class T_>
00615 int NodeVect<T_>::get(const string &file)
00616 {
00617 _kw[3] = "NbNodes$";
00618 size_t nb_nodes, i, j, n;
00619 int key;
00620 FFI ff(file,"#NODE_FIELD!");
00621 ff.setKeywords(_kw);
00622
00623 do {
00624 switch (key=ff.getKW()) {
00625
00626 case -1:
00627 exit(1);
00628
00629 case 1:
00630 setName(ff.getS());
00631 break;
00632
00633 case 2:
00634 _nb_dof = ff.getI();
00635 _length = _nb_dof * _nb_nodes;
00636 break;
00637
00638 case 3:
00639 nb_nodes = ff.getI();
00640 if (nb_nodes != _nb_nodes)
00641 _e.Message(__FILE__,__LINE__,121);
00642 break;
00643
00644 case 4:
00645 _time = ff.getD();
00646 break;
00647
00648 case 5:
00649 Init();
00650 for (j=0; j<_nb_nodes; j++) {
00651 n = ff.getI();
00652 for (i=0; i<_nb_dof; i++)
00653 _v[_nb_dof*(n-1)+i] = ff.getD();
00654 }
00655 break;
00656 }
00657 } while (key);
00658
00659 ff.Close();
00660 return 0;
00661 }
00662
00663
00664 template <class T_>
00665 int NodeVect<T_>::get(const string &file, double time)
00666 {
00667 _kw[3] = "NbNodes$";
00668 size_t nb_nodes, i, j, n;
00669 int key;
00670 int time_found=0;
00671 FFI ff(file,"#NODE_FIELD!");
00672 ff.setKeywords(_kw);
00673
00674 do {
00675 switch (key=ff.getKW()) {
00676
00677 case -1:
00678 exit(1);
00679
00680 case 1:
00681 setName(ff.getS());
00682 break;
00683
00684 case 3:
00685 nb_nodes = ff.getI();
00686 if (nb_nodes != _nb_nodes)
00687 _e.Message(__FILE__,__LINE__,121);
00688 break;
00689
00690 case 2:
00691 _nb_dof = ff.getI();
00692 _length = _nb_dof * _nb_nodes;
00693 break;
00694
00695 case 4:
00696 _time = ff.getD();
00697 if (_time == time)
00698 time_found = 1;
00699 break;
00700
00701 case 5:
00702 Init();
00703 for (j=0; j<_nb_nodes; j++) {
00704 n = ff.getI();
00705 for (i=0; i<_nb_dof; i++)
00706 _v[_nb_dof*(n-1)+i] = ff.getD();
00707 }
00708 if (time_found==1) {
00709 ff.Close();
00710 return 0;
00711 }
00712 break;
00713 }
00714 } while (key);
00715 ff.Close();
00716 return 1;
00717 }
00718
00719
00720 template <class T_>
00721 size_t NodeVect<T_>::getNbNodes() const
00722 {
00723 return _nb_nodes;
00724 }
00725
00726
00727 template <class T_>
00728 NodeVect<T_> &NodeVect<T_>::operator=(T_ a)
00729 {
00730 for (size_t i=0; i<_length; ++i)
00731 _v[i] = a;
00732 return *this;
00733 }
00734
00735
00736 template <class T_>
00737 NodeVect<T_> & NodeVect<T_>::operator+=(const NodeVect<T_> &x)
00738 {
00739 for (size_t i=0; i<_length; ++i)
00740 _v[i] += x._v[i];
00741 return *this;
00742 }
00743
00744
00745 template <class T_>
00746 NodeVect<T_> & NodeVect<T_>::operator+=(const T_ &a)
00747 {
00748 for (size_t i=0; i<_length; ++i)
00749 _v[i] += a;
00750 return *this;
00751 }
00752
00753
00754 template <class T_>
00755 NodeVect<T_> & NodeVect<T_>::operator-=(const NodeVect<T_> &x)
00756 {
00757 for (size_t i=0; i<_length; ++i)
00758 _v[i] -= x._v[i];
00759 return *this;
00760 }
00761
00762
00763 template <class T_>
00764 NodeVect<T_> & NodeVect<T_>::operator-=(const T_ &a)
00765 {
00766 for (size_t i=0; i<_length; ++i)
00767 _v[i] -= a;
00768 return *this;
00769 }
00770
00771
00772 template <class T_>
00773 NodeVect<T_> &NodeVect<T_>::operator*=(const T_ &a)
00774 {
00775 for (size_t i=0; i<_length; ++i)
00776 _v[i] *= a;
00777 return *this;
00778 }
00779
00780
00781 template <class T_>
00782 NodeVect<T_> &NodeVect<T_>::operator/=(const T_ &a)
00783 {
00784 for (size_t i=0; i<_length; ++i)
00785 _v[i] /= a;
00786 return *this;
00787 }
00788
00789
00791
00793
00797 template <class T_>
00798 istream& operator>>(istream& s, NodeVect<T_> &v)
00799 {
00800 size_t j, n;
00801 double time;
00802 static char name[40];
00803 s >> name;
00804 v.setName(name);
00805 s >> n >> time;
00806 v.setTime(time);
00807
00808 for (size_t i=1; i<=n; i++) {
00809 s >> j;
00810 for (size_t k=1; k<=v.getNbDOF(i); k++)
00811 s >> v(i,j) >> " ";
00812 }
00813 return s;
00814 }
00815
00816
00820 template <class T_>
00821 ostream& operator<<(ostream &s, const NodeVect<T_> &v)
00822 {
00823 const Node *nd;
00824 s << v.getName() << " at time = " << v.getTime() << endl << endl;
00825 s.setf(ios::scientific);
00826 for (v.getMesh().topNode(); (nd=v.getMesh().getNode());) {
00827 size_t i = nd->getLabel();
00828 s << setw(6) << i << " ";
00829 for (size_t j=1; j<=v.getNbDOF(); j++)
00830 s << setprecision(8) << setw(18) << v(i,j);
00831 s << endl;
00832 }
00833 s << endl;
00834 return s;
00835 }
00836
00837 }
00838
00839 #endif