Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
WriteOutput.C
Go to the documentation of this file.
1 #include <iomanip>
2 #include "DriverProgram.H"
3 
4 namespace GridConversion{ namespace DriverProgram{
5 
7 
8  std::ostringstream Ostr;
9  std::stringstream ss;
10 
11 
12  // Open the specified output file for writing
13  bool use_outfile = false;
14  if(!output_name.empty()){
15  use_outfile = true;
16  Ouf.open(output_name.c_str());
17  if(!Ouf){
18  // If the output file failed to open, notify
19  // to error stream and return non-zero
20  std::ostringstream ErrOstr;
21  ErrOstr << "Error: Unable to open output file, " << output_name << ".";
22  StdOut(Ostr.str());
23  Ostr.str("");
24  ErrOut(ErrOstr.str());
25  ErrOstr.str("");
26  // don't forget to tell the profiler/stacker the
27  // function is exiting.
28  FunctionExit("Run");
29  return(1);
30  }
31  }
32 
33  // Write mesh info to output file or screen
34  ss.clear();
35  ss.str("");
36 
37  //Write Patran packet 25 Intro (unused)
38  ss << "unused line" << std::endl;
39  ss << "unused line" << std::endl;
40  //Write Patran packet 26
41  ss << "26 1 1 1 " << numNodes << " " << numElems << " 1 1 1" << std::endl;
42  ss << "unused line" << std::endl;
43 
44  unsigned int ePos, expPos;
45  std::stringstream numSS;
46  std::string output, exponent;
47  //Write Patran packet 1 node coordinates
48  for(int i=0; i < numNodes; i++){
49  ss << "1 " << i+1 << std::endl;
50 
51  if(fabs(nodes[3*i+0]) > 1.0e-10 || nodes[3*i+0] == 0.0){
52  numSS << std::setprecision(9) << std::scientific << nodes[3*i + 0];
53  ePos = numSS.str().find("e");
54  expPos = numSS.str().find_last_of("0");
55  //std::cout << "numSS.str() = " << numSS.str() << std::endl;
56  //std::cout << "expPos = " << expPos << std::endl;
57  //std::cout << "numSS.str().size() = " << numSS.str().size() << std::endl;
58  if(expPos == numSS.str().size()-1)
59  exponent = "0";
60  else
61  exponent = numSS.str().substr(expPos+1,numSS.str().size());
62  output = numSS.str().substr(0,ePos+2) + exponent;
63  }
64  else{//we have to be careful with numbers that have two digit exponents
65  //in scientific notation because Rocfrac expects all numbers to take a
66  //specific number of columns.
67  if(nodes[3*i+0] < 0.0)
68  numSS << std::setprecision(8) << std::scientific << nodes[3*i + 0];
69  else
70  numSS << std::setprecision(9) << std::scientific << nodes[3*i + 0];
71 
72  output = numSS.str();
73  }
74  ss << std::setw(16) << output;
75  numSS.str("");
76  numSS.clear();
77 
78  if(fabs(nodes[3*i+1]) > 1.0e-10 || nodes[3*i+1] == 0.0){
79  numSS << std::setprecision(9) << std::scientific << nodes[3*i + 1];
80  ePos = numSS.str().find("e");
81  expPos = numSS.str().find_last_of("0");
82  //std::cout << "numSS.str() = " << numSS.str() << std::endl;
83  //std::cout << "expPos = " << expPos << std::endl;
84  //std::cout << "numSS.str().size() = " << numSS.str().size() << std::endl;
85  if(expPos == numSS.str().size()-1)
86  exponent = "0";
87  else
88  exponent = numSS.str().substr(expPos+1,numSS.str().size());
89  output = numSS.str().substr(0,ePos+2) + exponent;
90  }
91  else{//we have to be careful with numbers that have two digit exponents
92  //in scientific notation because Rocfrac expects all numbers to take a
93  //specific number of columns.
94  if(nodes[3*i+1] < 0.0)
95  numSS << std::setprecision(8) << std::scientific << nodes[3*i + 1];
96  else
97  numSS << std::setprecision(9) << std::scientific << nodes[3*i + 1];
98 
99  output = numSS.str();
100  }
101  ss << std::setw(16) << output;
102  numSS.str("");
103  numSS.clear();
104 
105  if(fabs(nodes[3*i+2]) > 1.0e-10 || nodes[3*i+2] == 0.0){
106  numSS << std::setprecision(9) << std::scientific << nodes[3*i + 2];
107  ePos = numSS.str().find("e");
108  expPos = numSS.str().find_last_of("0");
109  //std::cout << "numSS.str() = " << numSS.str() << std::endl;
110  //std::cout << "expPos = " << expPos << std::endl;
111  //std::cout << "numSS.str().size() = " << numSS.str().size() << std::endl;
112  if(expPos == numSS.str().size()-1)
113  exponent = "0";
114  else
115  exponent = numSS.str().substr(expPos+1,numSS.str().size());
116  output = numSS.str().substr(0,ePos+2) + exponent;
117  }
118  else{//we have to be careful with numbers that have two digit exponents
119  //in scientific notation because Rocfrac expects all numbers to take a
120  //specific number of columns.
121  if(nodes[3*i+2] < 0.0)
122  numSS << std::setprecision(8) << std::scientific << nodes[3*i + 2];
123  else
124  numSS << std::setprecision(9) << std::scientific << nodes[3*i + 2];
125 
126  output = numSS.str();
127  }
128  ss << std::setw(16) << output << std::endl;
129  numSS.str("");
130  numSS.clear();
131 
132  ss << "unused line" << std::endl;
133  }
134 
135  //Write Patran packet 2 element connectivities
136  for(int i=0; i < numElems; i++){
137  ss << "2 " << i+1 << " " << elemShape << std::endl
138  << " " << numNodesPerElem << " 0"
139  << " 0" << std::endl;
140  for(int j=0; j < numNodesPerElem; j++){
141  ss << elems[i*numNodesPerElem + j] << " ";
142  }
143  ss << std::endl;
144  }
145 
146  //Write Patran packet 8 (all nodes with this boundary type)
147  for(int i=0; i < numNodes; i++){
148  for(int k=0; k < nodeBCs[i].size(); k++){
149  if(nodeBCs[i][k] == 8){
150  ss << "8 " << i+1 << " 1 2" << std::endl;
151  ss << " 0";
152  for(int j=0; j < 3; j++)
153  ss << int(nodeBCValues[i][k][j]);
154  ss << "000" << std::endl;
155  for(int j=3; j < 6; j++){
156  if(nodeBCValues[i][k][j-3] != 0)
157  ss << " " << nodeBCValues[i][k][j];
158  }
159  ss << std::endl;
160  }
161  }
162  }
163 
164 
165  //Write Patran packet 6 (all elements with this boundary type)
166  //loop over all the elements
167  //std::cout << "bcs of type 6: " << std::endl;
168  for(int i=0; i < numElems; i++){
169  //std::cout << "elem " << i+1 << ": " << std::endl;
170  //loop over the domains for that element (we only want
171  //to print one domain's bcs for the element at a time
172  for(int doms=0; doms < elemsToDomains[i].size(); doms++){
173  int domain=elemsToDomains[i][doms]-1;
174  //std::cout << "domain " << domain+1 << std::endl;
175  //loop over the boundary flags for that domain
176  for(int j=0; j < domainBCs[domain].size(); j++){
177  int bcCount=0;
178  if(domainBCs[domain][j] == 6){
179  //std::cout << "bc " << j+1 << ": " << std::endl;
180  ss << "6 " << i+1 << " 1 2 0 0 0 0 0" << std::endl;
181  ss << "111100000";
182  //loop over the nodes for that element
183  for(int k=0; k < numNodesPerElem; k++){
184  bool onBC=false;
185  int node = elems[i*numNodesPerElem + k]-1;
186  //std::cout << "node " << k+1 << " (" << node+1 << ")" << std::endl;
187  //loop over the bc flags for that node
188  for(int l=0; l < nodeBCs[node].size(); l++){
189  if(nodeBCs[node][l] == 6){
190  //check if the bcs have the same values
191  for(int m=0; m < nodeBCValues[node][l].size(); m++){
192  if(nodeBCValues[node][l][m] != domainBCValues[domain][j][m])
193  break;
194  else if(m == nodeBCValues[node][l].size()-1){
195  onBC=true;
196  bcCount++;
197  //std::cout << "has bc" << std::endl;
198  }
199  }
200  }
201  }//loop over node bcs
202  if(onBC){
203  //now check that the node is on that domain
204  int domCount;
205  for(domCount=0; domCount < nodesToDomains[node].size(); domCount++){
206  if(nodesToDomains[node][domCount] == domain+1){
207  //std::cout << "node on domain (writing it)" << std::endl;
208  ss << "1";
209  break;
210  }
211  }
212  if(domCount == nodesToDomains[node].size())
213  ss << "0";
214  }
215  else
216  ss << "0";
217  }//loop over nodes for the element
218  //Fill in with 0's at the end if we are using tet elements
219  if(numNodesPerElem == 4)
220  ss << "0000";
221  ss << std::endl;
222  for(int m=0; m < domainBCValues[domain][j].size(); m++)
223  ss << domainBCValues[domain][j][m] << " ";
224  ss << std::endl;
225  }//if it is bc type 6
226  }//loop over bc flags for domain
227  }//loop over the domains for the element
228  }//loop over all elements
229  ss << "99 0 0 1";
230 
231  if(use_outfile){
232  Ouf << ss.str();
233  }
234  else
235  StdOut(ss.str());
236  // Close output file
237  Ouf.close();
238 
239  StdOut(Ostr.str());
240  Ostr.str("");
241 
242  return 0;
243 
244  } //ReadOutput function
245 
246 }; //DriverProgram namespace
247 }; //GridConversion namespace
virtual int WriteOutput()
This function writes the output grid file.
Definition: WriteOutput.C:6
j indices k indices k
Definition: Indexing.h:6
GridConversion interface.
std::vector< unsigned int > elems
vector for holding element connectivies read from input
Definition: adj.h:150
int numElems
number of elements in mesh
std::vector< std::vector< int > > elemsToDomains
vector to hold the domains for each element
std::vector< std::vector< int > > nodeBCs
std::string output_name
Name of file for output.
SolverUtils::Mesh::Connectivity nodesToDomains
std::ofstream Ouf
Outfile stream for output.
blockLoc i
Definition: read.cpp:79
int numNodesPerElem
number of nodes per element
std::vector< std::vector< int > > domainBCs
vector to hold list of domain bc flags
std::vector< std::vector< std::vector< double > > > domainBCValues
vector to hold list of domain bc values (these are different for each bc type - see the Rocfrac docum...
j indices j
Definition: Indexing.h:6
int elemShape
integer to denote the shape of elements used in the mesh
std::vector< double > nodes
vector for holding nodal coordinates read from input
std::vector< std::vector< std::vector< double > > > nodeBCValues
vector to hold list of node bc values (these are different for each bc type - see the Rocfrac documen...