Xpetra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Xpetra_BlockReorderManager.cpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Xpetra: A linear algebra interface package
4 //
5 // Copyright 2012 NTESS and the Xpetra contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
11 
12 namespace Xpetra {
13 
14 void BlockReorderManager::SetBlock(int blockIndex, int reorder) {
15  TEUCHOS_ASSERT(blockIndex < (int)children_.size());
16  Teuchos::RCP<BlockReorderManager> child = Teuchos::rcp(new BlockReorderLeaf(reorder));
17  children_[blockIndex] = child;
18 }
19 
20 void BlockReorderManager::SetBlock(int blockIndex, const Teuchos::RCP<BlockReorderManager>& reorder) {
21  TEUCHOS_ASSERT(blockIndex < (int)children_.size());
22  children_[blockIndex] = reorder;
23 }
24 
25 // this function tokenizes a string, breaking out whitespace but saving the
26 // brackets [,] as special tokens.
27 void tokenize(std::string srcInput, std::string whitespace, std::string prefer, std::vector<std::string>& tokens) {
28  std::string input = srcInput;
29  std::vector<std::string> wsTokens;
30  std::size_t endPos = input.length() - 1;
31  while (endPos < input.length()) {
32  std::size_t next = input.find_first_of(whitespace);
33 
34  // get the sub string
35  std::string s;
36  if (next != std::string::npos) {
37  s = input.substr(0, next);
38 
39  // break out the old substring
40  input = input.substr(next + 1, endPos);
41  } else {
42  s = input;
43  input = "";
44  }
45 
46  endPos = input.length() - 1;
47 
48  // add it to the WS tokens list
49  if (s == "") continue;
50  wsTokens.push_back(s);
51  }
52 
53  for (unsigned int i = 0; i < wsTokens.size(); i++) {
54  // get string to break up
55  input = wsTokens[i];
56 
57  endPos = input.length() - 1;
58  while (endPos < input.length()) {
59  std::size_t next = input.find_first_of(prefer);
60 
61  std::string s = input;
62  if (next > 0 && next < input.length()) {
63  // get the sub string
64  s = input.substr(0, next);
65 
66  input = input.substr(next, endPos);
67  } else if (next == 0) {
68  // get the sub string
69  s = input.substr(0, next + 1);
70 
71  input = input.substr(next + 1, endPos);
72  } else
73  input = "";
74 
75  // break out the old substring
76  endPos = input.length() - 1;
77 
78  // add it to the tokens list
79  tokens.push_back(s);
80  }
81  }
82 }
83 
84 // this function takes a set of tokens and returns the first "block", i.e. those
85 // values (including) brackets that correspond to the first block
86 std::vector<std::string>::const_iterator buildSubBlock(
87  std::vector<std::string>::const_iterator begin,
88  std::vector<std::string>::const_iterator end,
89  std::vector<std::string>& subBlock) {
90  std::stack<std::string> matched;
91  std::vector<std::string>::const_iterator itr;
92  for (itr = begin; itr != end; ++itr) {
93  subBlock.push_back(*itr);
94 
95  // push/pop brackets as they are discovered
96  if (*itr == "[")
97  matched.push("[");
98  else if (*itr == "]")
99  matched.pop();
100 
101  // found all matching brackets
102  if (matched.empty())
103  return itr;
104  }
105 
106  TEUCHOS_ASSERT(matched.empty());
107 
108  return itr - 1;
109 }
110 
111 // This function takes a tokenized vector and converts it to a block reorder manager
112 Teuchos::RCP<Xpetra::BlockReorderManager> blockedReorderFromTokens(const std::vector<std::string>& tokens) {
113  // base case
114  if (tokens.size() == 1)
115  return Teuchos::rcp(new Xpetra::BlockReorderLeaf(Teuchos::StrUtils::atoi(tokens[0])));
116 
117  // check first and last character
118  TEUCHOS_ASSERT(*(tokens.begin()) == "[")
119  TEUCHOS_ASSERT(*(tokens.end() - 1) == "]");
120 
121  std::vector<Teuchos::RCP<Xpetra::BlockReorderManager> > vecRMgr;
122  std::vector<std::string>::const_iterator itr = tokens.begin() + 1;
123  while (itr != tokens.end() - 1) {
124  // figure out which tokens are relevant for this block
125  std::vector<std::string> subBlock;
126  itr = buildSubBlock(itr, tokens.end() - 1, subBlock);
127 
128  // build the child block reorder manager
129  vecRMgr.push_back(blockedReorderFromTokens(subBlock));
130 
131  // move the iterator one more
132  itr++;
133  }
134 
135  // build the parent reorder manager
136  Teuchos::RCP<Xpetra::BlockReorderManager> rMgr = Teuchos::rcp(new Xpetra::BlockReorderManager());
137  rMgr->SetNumBlocks(vecRMgr.size());
138  for (unsigned int i = 0; i < vecRMgr.size(); i++)
139  rMgr->SetBlock(i, vecRMgr[i]);
140 
141  return rMgr;
142 }
143 
155 Teuchos::RCP<const Xpetra::BlockReorderManager> blockedReorderFromString(std::string reorder) {
156  // vector of tokens to use
157  std::vector<std::string> tokens;
158 
159  // manager to be returned
160 
161  // build tokens vector
162  tokenize(reorder, " \t\n", "[]", tokens);
163 
164  // parse recursively and build reorder manager
165  Teuchos::RCP<Xpetra::BlockReorderManager> mgr = blockedReorderFromTokens(tokens);
166 
167  return mgr;
168 }
169 
170 } // namespace Xpetra
std::vector< std::string >::const_iterator buildSubBlock(std::vector< std::string >::const_iterator begin, std::vector< std::string >::const_iterator end, std::vector< std::string > &subBlock)
Teuchos::RCP< const Xpetra::BlockReorderManager > blockedReorderFromString(std::string reorder)
Convert a string to a block reorder manager object.
void tokenize(std::string srcInput, std::string whitespace, std::string prefer, std::vector< std::string > &tokens)
virtual void SetBlock(int blockIndex, int reorder)
Sets the subblock to a specific index value.
Teuchos::RCP< Xpetra::BlockReorderManager > blockedReorderFromTokens(const std::vector< std::string > &tokens)
std::vector< Teuchos::RCP< BlockReorderManager > > children_
definitions of the subblocks