PlasCom2  1.0
XPACC Multi-physics simluation application
primitive_utilities.H
Go to the documentation of this file.
1 #ifndef _BASIC_UTILITIES_
7 #define _BASIC_UTILITIES_
8 
9 #include <iostream>
10 #include <string>
11 #include <fstream>
12 #include <cstring>
13 #include <algorithm>
14 #include <cmath>
15 #include <limits>
16 #include "PrimitiveTypes.H"
17 
18 
19 namespace ix {
20 
25  namespace util {
27  typedef int Error;
28  // void Vectorize(std::vector<std::string> &retVal,const char **in);
29  // void Vectorize(std::vector<std::string> &retVal,const char **in,int);
30  // int String2Buf(const std::string &instr,void **buf);
31 
32 
33  // void GetContentUntil(std::istream &In,
34  // std::string ret,
35  // const std::string &etag);
36  //
37  // std::string GetNextContent(std::istream &In);
38 
39 
40  // must be sorted, or this doesn't work out
41  template<typename Container>
42  bool LessThan(const Container &c1,const Container &c2)
43  {
44  typename Container::const_iterator c1i = c1.begin();
45  typename Container::const_iterator c2i = c2.begin();
46  while(c1i != c1.end() && c2i != c2.end()){
47  if(*c1i < *c2i)
48  return(true);
49  if(*c1i++ > *c2i++)
50  return(false);
51  }
52  if(c1i == c1.end()){
53  if(c2i == c2.end()){
54  return(false);
55  }
56  else {
57  return(true);
58  }
59  }
60  return(false);
61  }
62 
63 
64  // Inverts a container
65  template<typename Container>
66  void InvertContainer(const Container &c1,Container &c2)
67  {
68  unsigned int size = c1.size();
69  c2.resize(size);
70  typename Container::const_iterator c1i = c1.begin();
71  for(unsigned int iii = 0;iii < size;iii++)
72  c2[*c1i++] = iii;
73  }
74 
81  template<typename ContainerType>
82  void DumpContents(std::ostream &Ostr,const ContainerType &c,std::string del = "\n"){
83  if(!c.empty()){
84  typename ContainerType::const_iterator ci = c.begin();
85  Ostr << *ci++;
86  while(ci != c.end())
87  Ostr << del << *ci++;
88  }
89  }
90 
91  //template<typename IndexType,typename ValueType>
92  //void Invert(IndexedVectorObj<IndexType,ValueType> &ico){
93  // return;
94  //}
95 
106  template<typename BufferDataType>
107  int PackBuffer(const BufferDataType *sourceBuffer,const std::vector<size_t> &sourceIndices,
108  BufferDataType *targetBuffer,const std::vector<size_t> &targetIndices)
109  {
110  size_t numVal = sourceIndices.size();
111  if(numVal == 0 || (targetIndices.size() != numVal))
112  return(1);
113  const size_t *sourceIndex = &sourceIndices[0];
114  const size_t *targetIndex = &targetIndices[0];
115  for(size_t iVal = 0;iVal < numVal;iVal++)
116  targetBuffer[targetIndex[iVal]] = sourceBuffer[sourceIndex[iVal]];
117  return(0);
118  }
119 
120  template<typename ContainerType,typename T>
121  void CopyIntoContainer(ContainerType &cont,const T* src,size_t count)
122  {
123  size_t datasize = sizeof(T);
124  cont.resize(count);
125  memcpy(&cont[0],src,count*datasize);
126  }
127 
128  template<typename OuterCont,typename OutCont,typename InnerCont,typename MapType>
129  void MapElements(OuterCont &src,OutCont &trg,MapType &m)
130  {
131  trg.resize(src.size());
132  typename OuterCont::iterator sci = src.begin();
133  typename OutCont::iterator oci = trg.begin();
134  while(sci != src.end()){
135  typename InnerCont::iterator ici = sci->begin();
136  while(ici != sci->end())
137  oci->push_back(m[*ici++]);
138  sci++;
139  oci++;
140  }
141  }
142 
144  template<typename ListContainerType, typename ListType>
145  primitive::IndexType MaxNodeId(const ListContainerType &fc)
146  {
147  primitive::IndexType maxid = 0;
148  typename ListContainerType::const_iterator lci = fc.begin();
149  while(lci != fc.end()){
150  typename ListType::const_iterator li = lci->begin();
151  while(li != lci->end()){
152  if(maxid < *li){
153  maxid = *li;
154  }
155  li++;
156  }
157  lci++;
158  }
159  return(maxid);
160  }
161 
163  template<typename OuterCont,typename InnerCont,typename OutCont>
164  void Flatten(OuterCont &con,OutCont &ocon){
165  typename OuterCont::iterator cci = con.begin();
166  ocon.resize(0);
167  while(cci != con.end()){
168  typename InnerCont::iterator ccni = cci->begin();
169  while(ccni != cci->end())
170  ocon.push_back(*ccni++);
171  cci++;
172  }
173  }
174 
176  template<typename OuterContType>
177  primitive::IndexType GetTotalSize(OuterContType &con)
178  {
179  primitive::IndexType total_size = 0;
180  typename OuterContType::iterator ci = con.begin();
181  while(ci != con.end()){
182  total_size += ci->size();
183  ci++;
184  }
185  return(total_size);
186  }
187 
188  template<typename OuterContType,typename InnerContType,typename RetCont,typename idxtype>
189  void MultiContainer2CSR(RetCont &xadj,RetCont &adj,
190  OuterContType &source)
191  {
192  primitive::IndexType number_of_elements = source.size();
193  xadj.resize(number_of_elements+1);
194  primitive::IndexType number_entries = GetTotalSize<OuterContType>(source);
195  adj.reserve(number_entries);
196  typename OuterContType::iterator si = source.begin();
197  primitive::IndexType elm = 0;
198  xadj[elm++] = 0;
199  while(si != source.end()){
200  typename InnerContType::iterator ei = si->begin();
201  xadj[elm] = static_cast<idxtype>(si->size() + xadj[elm-1]);
202  elm++;
203  while(ei != si->end())
204  adj.push_back(static_cast<idxtype>(*ei++-1));
205  si++;
206  }
207  }
208 
213  template<typename ListContainerType, typename ListType>
214  void CreateAdjacentNodeList(std::vector<std::list<primitive::IndexType> > &anodelist,
215  ListContainerType &fc,primitive::IndexType nnodes=0)
216  {
217  if(nnodes == 0)
218  nnodes = MaxNodeId<ListContainerType,ListType>(fc);
219  anodelist.resize(nnodes);
220  typename ListContainerType::iterator lci = fc.begin();
221  while(lci != fc.end())
222  {
223  typename ListType::iterator li = lci->begin();
224  while(li != lci->end()){
225  primitive::IndexType this_node = *li++ - 1;
226  primitive::IndexType next_node = 0;
227  if(li == lci->end())
228  next_node = *(lci->begin());
229  else
230  next_node = *li++;
231  anodelist[this_node].push_back(next_node);
232  anodelist[next_node-1].push_back(this_node+1);
233  }
234  lci++;
235  }
236  for(primitive::IndexType node = 0;node < nnodes;node++)
237  {
238  anodelist[node].sort();
239  anodelist[node].unique();
240  }
241  }
242 
249  template<typename ListContainerType, typename ListType>
250  void AdjEList(std::vector<std::list<primitive::IndexType> > &aelist,
251  ListContainerType &dual_con,unsigned long nel=0)
252  {
253  if(nel == 0)
254  nel = MaxNodeId<ListContainerType,ListType>(dual_con);
255  aelist.resize(nel);
256  typename ListContainerType::iterator lci = dual_con.begin();
257  while(lci != dual_con.end())
258  {
259  typename ListType::iterator li = lci->begin();
260  while(li != lci->end()){
261  primitive::IndexType this_node = *li++ - 1;
262  typename ListType::iterator li2 = li;
263  while(li2 != lci->end()){
264  primitive::IndexType nexnode = *li2++ - 1;
265  aelist[this_node].push_back(nexnode+1);
266  aelist[nexnode].push_back(this_node+1);
267  }
268  }
269  lci++;
270  }
271  for(primitive::IndexType node = 0;node < nel;node++)
272  {
273  aelist[node].sort();
274  aelist[node].unique();
275  }
276  }
277 
278  template<typename ConType,typename IConType>
280  {
281  typename ConType::iterator ci = con.begin();
282  primitive::IndexType node = 0;
283  primitive::IndexType nedges = 0;
284  while(ci != con.end())
285  {
286  primitive::IndexType tnode = ++node;
287  typename IConType::iterator eni = ci->begin();
288  while(eni != ci->end())
289  {
290  primitive::IndexType anode = *eni++;
291  if((tnode) < anode)
292  nedges++;
293  }
294  ci++;
295  }
296  return(nedges);
297  }
298 
299  template<typename ContainerType,typename Icont>
300  void FormGraph(const ContainerType &adjlist)
301  {
302  // empty for now
303  }
304 
306  template<typename BufferDataType>
307  void ReportBufferStats(std::ostream &outStream,size_t numValues,const BufferDataType *dataBuffer)
308  {
309  size_t minLocation = 0;
310  size_t maxLocation = 0;
311  BufferDataType minValue = std::numeric_limits<BufferDataType>::max();
312  BufferDataType maxValue = std::numeric_limits<BufferDataType>::min();
313  double bufferMean = 0;
314  double bufferDev = 0;
315  for(size_t iValue = 0;iValue < numValues;iValue++){
316  if(dataBuffer[iValue] < minValue){
317  minValue = dataBuffer[iValue];
318  minLocation = iValue;
319  }
320  if(dataBuffer[iValue] > maxValue){
321  maxValue = dataBuffer[iValue];
322  maxLocation = iValue;
323  }
324  bufferMean += dataBuffer[iValue];
325  bufferDev += dataBuffer[iValue]*dataBuffer[iValue];
326  }
327  bufferMean /= numValues;
328  bufferDev /= numValues;
329  bufferDev -= (bufferMean*bufferMean);
330  bufferDev = std::sqrt(bufferDev);
331  outStream << "Min: " << minValue << " @ " << minLocation << std::endl
332  << "Max: " << maxValue << " @ " << maxLocation << std::endl
333  << "Mean: " << bufferMean << " +/- " << bufferDev << std::endl;
334  return;
335  };
336 
343  template<typename Container>
344  bool HaveSameOrientation(Container &c1,Container &c2)
345  {
346  if(c1.size() != c2.size())
347  return(false);
348  typename Container::iterator c1i = c1.begin();
349  typename Container::iterator c2i =
350  std::find(c2.begin(),c2.end(),*c1i);
351  if(c2i == c2.end())
352  return(false);
353  while(c1i != c1.end()){
354  if(*c1i != *c2i)
355  return false;
356  c1i++;
357  c2i++;
358  if(c2i == c2.end())
359  c2i = c2.begin();
360 
361  }
362  return(true);
363  }
364 
371  template<typename Container>
372  bool HaveOppositeOrientation(Container &c1,Container &c2)
373  {
374  if(c1.size() != c2.size())
375  return(false);
376  typename Container::iterator c1i = c1.begin();
377  typename Container::reverse_iterator c2i =
378  std::find(c2.rbegin(),c2.rend(),*c1i);
379  if(c2i == c2.rend())
380  return(false);
381  while(c1i != c1.end()){
382  if(*c1i++ != *c2i++)
383  return false;
384  if(c2i == c2.rend())
385  c2i = c2.rbegin();
386  }
387  return(true);
388  }
389 
390 
391  template<class T>
392  struct CmpPairs
393  {
394  CmpPairs(const std::vector<T> &v): v_(v) {}
395  std::vector<T> v_;
396  bool operator()(int a, int b){ return v_[a] < v_[b]; }
397  };
398 
399  template<class T>
400  CmpPairs<T> CreateCmpPairs(const std::vector<T> & v)
401  { return CmpPairs<T>(v); };
402 
403  template<class T>
404  void SortPermutation(const std::vector<T> &values, std::vector<unsigned int>& v)
405  {
406  unsigned int size = values.size();
407  v.clear();
408  v.reserve(size);
409  for(unsigned int i=0; i < size; ++i)
410  v.push_back(i);
411  std::sort(v.begin(), v.end(), CreateCmpPairs(values));
412  };
413 
414 
415  inline std::string GetNextContent(std::istream &In)
416  {
417  std::string line;
418  std::string ret;
419  while(ret.empty() && std::getline(In,line)){
420  line = line.substr(0,line.find("#"));
421  std::istringstream Istr(line);
422  std::string token;
423  Istr >> token;
424  if(!token.empty() && token[0] != '#')
425  ret.assign(line);
426  }
427  return(ret);
428  }
429 
430  inline void GetContentUntil(std::istream &In,
431  std::string ret,
432  const std::string &etag)
433  {
434  std::ostringstream Ostr;
435  std::string line;
436  while(std::getline(In,line) && ret.empty()){
437  line = line.substr(0,line.find("#"));
438  if(!line.empty()){
439  std::istringstream Istr(line);
440  std::string token;
441  Istr >> token;
442  if(!token.empty()){
443  if(token == etag){
444  // Ostr << line << std::endl;
445  ret = Ostr.str();
446  }
447  else
448  Ostr << line << std::endl;
449  }
450  }
451  }
452  }
453 
454  inline int NumLines(const std::string &instr){
455  std::istringstream Istr(instr);
456  std::string line;
457  int n = 0;
458  while(std::getline(Istr,line))
459  n++;
460  return(n);
461  }
462 
463  inline int String2Buf(const std::string &instr,void **buf)
464  {
465  if(instr.empty())
466  return 0;
467  int rval = instr.size();
468  *buf = new char [rval];
469  void *resl = std::memcpy(*buf,instr.c_str(),rval);
470  if(!resl)
471  return(0);
472  return(rval);
473  }
474 
478  inline void Trim(std::string &instr,bool preserve_newline = false)
479  {
480  std::istringstream Istr(instr);
481  std::string line;
482  std::ostringstream Ostr;
483  while(std::getline(Istr,line)){
484  std::istringstream Line(line);
485  std::string token;
486  Line >> token;
487  Ostr << token;
488  while(Line >> token)
489  if(!token.empty())
490  Ostr << " " << token;
491  if(preserve_newline)
492  Ostr << "\n";
493  }
494  instr = Ostr.str();
495  }
496 
500  inline const std::string Trimmed(const std::string &instr,bool preserve_newline = false)
501  {
502  std::istringstream Istr(instr);
503  std::string line;
504  std::ostringstream Ostr;
505  while(std::getline(Istr,line)){
506  std::istringstream Line(line);
507  std::string token;
508  Line >> token;
509  Ostr << token;
510  while(Line >> token)
511  if(!token.empty())
512  Ostr << " " << token;
513  if(preserve_newline)
514  Ostr << "\n";
515  }
516  return(Ostr.str());
517  }
518 
525  inline const std::string
526  stripdirs(const std::string &pname)
527  {
528  std::string retval;
529  std::string::size_type x = pname.find("/");
530  if(x == std::string::npos)
531  return(pname);
532  return(pname.substr(pname.find_last_of("/")+1));
533  }
534 
540  inline void
541  TokenizeString(std::vector<std::string> &tokens,const std::string &source)
542  {
543  tokens.resize(0);
544  std::istringstream Istr(source);
545  std::string token;
546  while(Istr >> token)
547  tokens.push_back(token);
548  }
549 
555  inline void
556  TokenizeString(std::vector<std::string> &tokens,const std::string &source,const char delim)
557  {
558  tokens.resize(0);
559  std::string::size_type ssize = source.size();
560  std::string::size_type x = 0;
561  std::ostringstream Ostr;
562  std::string token;
563  while(x < ssize){
564  if(source[x] != delim)
565  token += source[x];
566  if((source[x] == delim) || (x == (ssize-1))){
567  tokens.push_back(token);
568  token.erase();
569  }
570  x++;
571  }
572  }
573 
577  template<typename NumType>
578  void ProcessRange(NumType &t1,NumType &t2,const std::string stinter)
579  {
580  if(!stinter.empty()){
581  std::string::size_type x = stinter.find(":");
582  std::string t1s = stinter;
583  std::string t2s = stinter;
584  if(x != std::string::npos){
585  t1s = stinter.substr(0,x);
586  t2s = stinter.substr(x+1);
587  if(!t2s.empty()){
588  std::istringstream Istr(t2s);
589  Istr >> t2;
590  }
591  }
592  else {
593  t1s.erase();
594  }
595  if(!t1s.empty()){
596  std::istringstream Istr(t1s);
597  Istr >> t1;
598  }
599  if(!t2s.empty()){
600  std::istringstream Istr(t2s);
601  Istr >> t2;
602  }
603 
604  }
605  }
606 
610  inline int OpenFile(std::ifstream &Inf,const std::string &filename)
611  {
612  Inf.open(filename.c_str());
613  if(!Inf)
614  return(-1);
615  return 0;
616  }
617 
618  // Utilities
619  inline void
620  Vectorize(std::vector<std::string> &retVal,const char **in)
621  {
622  int i = 0;
623  while(in[i] != NULL)
624  retVal.push_back(in[i++]);
625  }
626 
627  inline void
628  Vectorize(std::vector<std::string> &retVal,const char **in,int n)
629  {
630  // retVal.resize(0);
631  if(n <= 0) return;
632  int i = 0;
633  while((in[i] != NULL) && i < n)
634  retVal.push_back(in[i++]);
635  }
636 
637  inline void
638  RenewStream(std::ostringstream &outStream){
639  outStream.clear();
640  outStream.str("");
641  }
642 
643  inline void
644  RenewStream(std::istringstream &inStream){
645  inStream.clear();
646  inStream.str("");
647  }
648 
649  };
651 };
652 #endif
void FormGraph(const ContainerType &adjlist)
void Trim(std::string &instr, bool preserve_newline=false)
Creates space delimited tokens in place.
void Flatten(OuterCont &con, OutCont &ocon)
Populate OutCont with a flat list of entries from a multicontainer.
void TokenizeString(std::vector< std::string > &tokens, const std::string &source)
Tokenize string.
Simple utility classes.
void DumpContents(std::ostream &Ostr, const ContainerType &c, std::string del="\)
Dump container contents.
int OpenFile(std::ifstream &Inf, const std::string &filename)
File opener.
void Vectorize(std::vector< std::string > &retVal, const char **in)
primitive::IndexType MaxNodeId(const ListContainerType &fc)
Return the maximum of all elements of a multicontainer.
void RenewStream(std::ostringstream &outStream)
std::string GetNextContent(std::istream &In)
Defines MPI-specific parallel global and program classes.
int PackBuffer(const BufferDataType *sourceBuffer, const std::vector< size_t > &sourceIndices, BufferDataType *targetBuffer, const std::vector< size_t > &targetIndices)
Pack subset of target buffer from subset of source buffer.
bool HaveSameOrientation(Container &c1, Container &c2)
Cyclic test.
void MultiContainer2CSR(RetCont &xadj, RetCont &adj, OuterContType &source)
primitive::IndexType NumberOfEdges(ConType &con)
void const size_t const size_t const size_t const double const double * x
void CreateAdjacentNodeList(std::vector< std::list< primitive::IndexType > > &anodelist, ListContainerType &fc, primitive::IndexType nnodes=0)
Given an array of adjacent node lists (like an array of face connectivities), this function will loop...
void AdjEList(std::vector< std::list< primitive::IndexType > > &aelist, ListContainerType &dual_con, unsigned long nel=0)
Given an array of adjacent node lists (like an array of face connectivities), this function will loop...
void ReportBufferStats(std::ostream &outStream, size_t numValues, const BufferDataType *dataBuffer)
Reports min/max/mean/stddev for data in buffer.
primitive::IndexType GetTotalSize(OuterContType &con)
Return the total number of entries in a multicontainer.
const std::string Trimmed(const std::string &instr, bool preserve_newline=false)
Returns space delimited tokens.
unsigned int IndexType
int String2Buf(const std::string &instr, void **buf)
void SortPermutation(const std::vector< T > &values, std::vector< unsigned int > &v)
void MapElements(OuterCont &src, OutCont &trg, MapType &m)
void size_t int size_t int size_t int int int int double int int double double *void size_t int size_t int int int int int double int size_t size_t size_t double double *void size_t int size_t int size_t size_t int double int double double *void size_t size_t size_t double * a
const std::string stripdirs(const std::string &pname)
Strip absolute path.
int NumLines(const std::string &instr)
bool operator()(int a, int b)
void ProcessRange(NumType &t1, NumType &t2, const std::string stinter)
Process a range in the format "t1:t2".
int Error
Error type.
void GetContentUntil(std::istream &In, std::string ret, const std::string &etag)
CmpPairs(const std::vector< T > &v)
void CopyIntoContainer(ContainerType &cont, const T *src, size_t count)
void InvertContainer(const Container &c1, Container &c2)
bool HaveOppositeOrientation(Container &c1, Container &c2)
Anti-cyclic test.
bool LessThan(const Container &c1, const Container &c2)
CmpPairs< T > CreateCmpPairs(const std::vector< T > &v)