22 AddOption(
'h',
"help");
23 AddOption(
'p',
"partition",2,
"number");
24 AddOption(
'v',
"verb",1,
"level");
25 AddOption(
'c',
"clone",2,
"number");
26 AddOption(
'a',
"assembly");
27 AddOption(
'm',
"mesh");
28 AddOption(
'd',
"debug");
29 AddOption(
'k',
"checking");
30 AddOption(
'r',
"reorient");
31 AddOption(
'g',
"generate");
32 AddOption(
's',
"sparse");
33 AddOption(
't',
"metis");
34 AddOption(
'n',
"renumber");
35 AddArgument(
"input",1);
36 AddHelp(
"metis",
"Metis testing stub.");
37 AddHelp(
"sparse",
"Write out the sparse matrix for visualization.");
38 AddHelp(
"clone",
"Generate <number> of partitions identical to the input mesh.");
39 AddHelp(
"generate",
"Generate a uniform mesh with N nodes and quit.");
40 AddHelp(
"checking",
"Paranoid and insanely verbose dumping of all important arrays to Log.");
41 AddHelp(
"partition",
"Performs Metis partitioning of input mesh into <number> partitions.");
42 AddHelp(
"assembly",
"Performs assembly test.");
43 AddHelp(
"mesh",
"Performs mesh tests.");
44 AddHelp(
"help",
"Prints this long version of help.");
45 AddHelp(
"verb",
"Makes the test more verbose. Default level is 1.");
46 AddHelp(
"config",
"Specifies the name of the configuration file.");
47 AddHelp(
"out",
"Specifies the name of the output file.");
48 AddHelp(
"renumber",
"Uses ParMETIS to do optimal graph reordering.");
49 AddArgHelp(
"input",
"Mode dependent arguments");
50 std::ostringstream Ostr;
54 Ostr <<
"Test tool for exercising the mesh library.";
55 _description.assign(Ostr.str());
62 Ostr <<
"Size = " << con.size() << std::endl
63 <<
"Nelem = " << con.
Nelem() << std::endl;
70 double meanvalue = 0.0;
72 mean += con.
Esize(iii+1);
73 if(max < con.
Esize(iii+1))
74 max = con.
Esize(iii+1);
75 if(min > con.
Esize(iii+1))
76 min = con.
Esize(iii+1);
78 if(minvalue > con[iii][jjj])
79 minvalue = con[iii][jjj];
80 if(maxvalue < con[iii][jjj])
81 maxvalue = con[iii][jjj];
82 meanvalue += con[iii][jjj];
87 Ostr <<
"Esizes(min/max/mean): ("
88 << min <<
"/" << max <<
"/"
89 << mean/con.
Nelem() <<
")"
91 <<
"Flattened Size = " << nvalues
93 <<
"Values(min/max/mean): ("
96 << meanvalue/nvalues <<
")"
110 std::vector<Mesh::Border> &borders,
112 std::vector<Mesh::IndexType> &order,
113 Comm::CommunicatorObject &comm,
114 std::ostream *Out,
bool verbose)
117 std::vector<std::vector<Mesh::IndexType> > RcvBuf;
118 unsigned int nborders = borders.size();
119 RcvBuf.resize(nborders);
120 for(
unsigned int i = 0;
i < nborders;
i++){
121 RcvBuf[
i].resize(borders[
i].remote_dofcount);
125 *Out <<
"Posting receive for " << RcvBuf[
i].size() <<
" dofs from "
126 << borders[
i].rpart << std::endl;
130 *Out <<
"All procs receive posted in GlobalDofReMapExchange." << std::endl;
137 std::vector<std::vector<Mesh::IndexType> > SndBuf;
138 SndBuf.resize(nborders);
139 for(
unsigned int i = 0;
i < nborders;
i++){
141 std::vector<Mesh::IndexType>::iterator rni = borders[
i].nrecv.begin();
142 while(rni != borders[
i].nrecv.end()){
143 std::vector<Mesh::IndexType>::iterator ldi = NodalDofs[*rni-1].begin();
144 while(ldi != NodalDofs[*rni-1].end()){
145 SndBuf[
i].push_back(order[*ldi-1]+1);
151 *Out <<
"Posting send of " << SndBuf[
i].size() <<
" nodal dofs to "
152 << borders[
i].rpart <<
":" << std::endl;
153 DumpContents(*Out,SndBuf[
i],
" ");
160 comm.ClearRequests();
163 *Out <<
"All procs send posted 2." << std::endl;
166 for(
unsigned int i = 0;
i < nborders;
i++){
167 std::vector<Mesh::IndexType>::iterator rdi = RcvBuf[
i].begin();
168 std::vector<Mesh::IndexType>::iterator sni = borders[
i].nsend.begin();
170 *Out <<
"Unpacking recv'd dofs:" << std::endl;
171 DumpContents(*Out,RcvBuf[
i],
" ");
174 while(sni != borders[
i].nsend.end()){
176 std::vector<Mesh::IndexType>::iterator ndi = RemoteNodalDofs[rnindex].begin();
177 while(ndi != RemoteNodalDofs[rnindex].end())
192 *Out <<
"Forming dual connectivity for " << number_of_nodes <<
" nodes." << std::endl;
193 ec.
Inverse(dc,number_of_nodes);
195 *Out <<
"dual done." << std::endl;
197 std::vector<Mesh::IndexType> ssizes(nborders,0);
198 for(
unsigned int i = 0;
i < nborders;
i++){
200 borders[
i].data.SendAi.resize(0);
202 std::vector<Mesh::IndexType>::iterator sni = borders[
i].nsend.begin();
203 while(sni != borders[
i].nsend.end()){
205 std::list<Mesh::IndexType> doflist;
208 std::vector<Mesh::IndexType>::iterator ei = dc[*sni-1].begin();
209 while(ei != dc[*sni-1].end()){
210 std::vector<Mesh::IndexType>::iterator eni = ec[*ei-1].begin();
211 while(eni != ec[*ei-1].end()){
212 std::vector<Mesh::IndexType>::iterator ndi;
213 std::vector<Mesh::IndexType>::iterator ndend;
215 ndi = RemoteNodalDofs[*eni - info.
nlocal - 1].begin();
216 ndend = RemoteNodalDofs[*eni - info.
nlocal -1].end();
218 doflist.push_back(*ndi++);
222 ndi = NodalDofs[*eni-1].begin();
223 ndend = NodalDofs[*eni-1].end();
225 doflist.push_back(order[*ndi-1]+1);
231 eni = ElementDofs[*ei-1].begin();
232 while(eni != ElementDofs[*ei-1].end()){
233 doflist.push_back(order[*eni-1]+1);
240 std::list<Mesh::IndexType>::iterator dli = doflist.begin();
241 while(dli != doflist.end())
242 borders[
i].data.SendAi.push_back(*dli++);
246 *Out <<
"SendAp for color " << borders[
i].rpart <<
":" << std::endl;
247 DumpContents(*Out,borders[
i].data.SendAp,
" ");
249 <<
"SendAi for color " << borders[
i].rpart <<
":" << std::endl;
250 DumpContents(*Out,borders[i].data.SendAi,
" ");
256 *Out <<
"All procs have remapped SendAi." << std::endl;
262 for(
unsigned int i = 0;
i < nborders;
i++){
272 *Out <<
"RecvAP from partition " << borders[
i].rpart <<
":" << std::endl;
273 DumpContents(*Out,borders[
i].data.RecvAp,
" ");
277 std::vector<Mesh::IndexType>::reverse_iterator rsi = borders[
i].data.RecvAp.rbegin();
278 unsigned int totalsize = *rsi;
279 borders[
i].data.RecvAi.resize(totalsize);
281 *Out <<
"Posting RecvAi (" << borders[
i].data.RecvAi.size()
282 <<
") from partition" << borders[
i].rpart << std::endl;
287 *Out <<
"Posting SendAi (" << borders[
i].data.SendAi.size()
288 <<
") to partition" << borders[
i].rpart <<
":" << std::endl;
289 DumpContents(*Out,borders[
i].data.SendAi,
" ");
294 comm.ClearRequests();
297 for(
unsigned int i = 0;
i < nborders;
i++){
298 *Out <<
"Recieved RecvAi (" << borders[
i].data.RecvAi.size()
299 <<
") from partition" << borders[
i].rpart <<
":" << std::endl;
300 DumpContents(*Out,borders[
i].data.RecvAi,
" ");
308 Comm::CommunicatorObject &comm,std::ostream *Out,
bool verbose)
310 unsigned int okcount = 0;
311 unsigned int bcount = 0;
312 for(
unsigned int ntrial = 0;ntrial < 100;ntrial++){
315 *Out <<
"Inside MPI Test(" << ntrial <<
")" << std::endl;
320 std::vector<std::vector<Mesh::IndexType> > RcvBuf;
321 unsigned int nborders = borders.size();
322 RcvBuf.resize(nborders);
323 for(
unsigned int i = 0;
i < nborders;
i++){
326 RcvBuf[
i].resize(borders[
i].nsend.size());
328 *Out <<
"Posting receive for " << borders[
i].nsend.size() <<
" nodes from "
329 << borders[
i].rpart << std::endl << std::flush;
334 *Out <<
"All procs receives posted." << std::endl;
337 std::vector<std::vector<Mesh::IndexType> > SndBuf;
338 SndBuf.resize(nborders);
339 for(
unsigned int i = 0;
i < nborders;
i++){
340 SndBuf[
i].resize(borders[
i].nrecv.size());
342 std::vector<Mesh::IndexType>::iterator rni = borders[
i].nrecv.begin();
343 while(rni != borders[
i].nrecv.end()){
344 SndBuf[
i][
j] = NodalDofs[*rni-1].size();
349 *Out <<
"Posting send of " << borders[
i].nrecv.size() <<
" node's dof sizes to "
350 << borders[
i].rpart << std::endl;
352 DumpContents(*Out,SndBuf[
i],
" ");
353 *Out << std::endl << std::flush;
358 comm.ClearRequests();
360 for(
unsigned int i = 0;
i < nborders;
i++){
361 *Out <<
"Received(" <<
i+1 <<
"): ";
362 DumpContents(*Out,RcvBuf[i],
" ");
363 *Out << std::endl << std::flush;
364 if(RcvBuf[i][0] == 1)
370 *Out <<
"Bad Receives: " << bcount << std::endl << std::flush;
376 Comm::CommunicatorObject &comm,std::ostream *Out,
bool verbose)
379 *Out <<
"Inside Global Dof Exchange" << std::endl;
384 std::vector<std::vector<Mesh::IndexType> > RcvBuf;
385 unsigned int nborders = borders.size();
386 RcvBuf.resize(nborders);
387 for(
unsigned int i = 0;
i < nborders;
i++){
390 RcvBuf[
i].resize(borders[
i].nsend.size());
392 *Out <<
"Posting receive for " << borders[
i].nsend.size() <<
" nodes from "
393 << borders[
i].rpart << std::endl;
398 *Out <<
"All procs receives posted." << std::endl;
401 std::vector<std::vector<Mesh::IndexType> > SndBuf;
402 SndBuf.resize(nborders);
403 for(
unsigned int i = 0;
i < nborders;
i++){
404 SndBuf[
i].resize(borders[
i].nrecv.size());
406 std::vector<Mesh::IndexType>::iterator rni = borders[
i].nrecv.begin();
407 while(rni != borders[
i].nrecv.end()){
408 SndBuf[
i][
j] = NodalDofs[*rni-1].size();
413 *Out <<
"Posting send of " << borders[
i].nrecv.size() <<
" node's dof sizes to "
414 << borders[
i].rpart << std::endl;
418 comm.ClearRequests();
422 *Out <<
"All procs sends posted." << std::endl;
425 std::vector<unsigned int> totalsizes(nborders,0);
426 for(
unsigned int i = 0;
i < nborders;
i++){
427 std::vector<Mesh::IndexType>::iterator sni = borders[
i].nsend.begin();
430 *Out <<
"Received node sizes (in dofs) from " << borders[
i].rpart
432 DumpContents(*Out,RcvBuf[
i]);
435 while(sni != borders[
i].nsend.end()){
436 totalsizes[
i] += RcvBuf[
i][
j];
443 assert(NodalDofs[*sni-1].size() == RcvBuf[
i][j]);
445 RemoteNodalDofs[*sni-info.
nlocal-1].resize(RcvBuf[
i][j++]);
451 *Out <<
"All procs node sizes received." << std::endl;
455 for(
unsigned int i = 0;
i < nborders;
i++){
456 RcvBuf[
i].resize(totalsizes[
i]);
457 borders[
i].remote_dofcount = totalsizes[
i];
461 *Out <<
"Posting receive for " << RcvBuf[
i].size() <<
" dofs from "
462 << borders[
i].rpart << std::endl;
466 *Out <<
"All procs receive posted 2." << std::endl;
470 for(
unsigned int i = 0;
i < nborders;
i++){
472 std::vector<Mesh::IndexType>::iterator rni = borders[
i].nrecv.begin();
473 while(rni != borders[
i].nrecv.end()){
474 std::vector<Mesh::IndexType>::iterator ldi = NodalDofs[*rni-1].begin();
475 while(ldi != NodalDofs[*rni-1].end()){
476 SndBuf[
i].push_back(*ldi+doffset);
482 *Out <<
"Posting send of " << SndBuf[
i].size() <<
" nodal dofs to "
483 << borders[
i].rpart <<
":" << std::endl;
484 DumpContents(*Out,SndBuf[
i],
" ");
487 borders[
i].recvsize = SndBuf[
i].size();
491 comm.ClearRequests();
494 *Out <<
"All procs send posted 2." << std::endl;
497 for(
unsigned int i = 0;
i < nborders;
i++){
498 std::vector<Mesh::IndexType>::iterator rdi = RcvBuf[
i].begin();
499 std::vector<Mesh::IndexType>::iterator sni = borders[
i].nsend.begin();
501 *Out <<
"Unpacking recv'd dofs:" << std::endl;
502 DumpContents(*Out,RcvBuf[
i],
" ");
505 while(sni != borders[
i].nsend.end()){
507 std::vector<Mesh::IndexType>::iterator ndi = RemoteNodalDofs[rnindex].begin();
508 while(ndi != RemoteNodalDofs[rnindex].end())
521 std::ostream *Out,
bool verbose)
523 unsigned int nborders = borders.size();
529 std::vector<std::vector<Mesh::IndexType> > RcvBuf(nborders);
530 std::vector<Mesh::IndexType> rsizes(nborders,0);
531 for(
unsigned int i = 0;
i < nborders;
i++){
532 rsizes[
i] = borders[
i].nrecv.size();
533 RcvBuf[
i].resize(rsizes[
i]);
535 *Out <<
"Posting receives for " << rsizes[
i] <<
" sizes of stiffness entries "
536 <<
"from " << borders[
i].rpart <<
"." << std::endl;
541 *Out <<
"All procs have posted recvs." << std::endl;
550 *Out <<
"Forming dual connectivity for " << number_of_nodes <<
" nodes." << std::endl;
551 ec.
Inverse(dc,number_of_nodes);
553 *Out <<
"dual done." << std::endl;
554 std::vector<std::vector<Mesh::IndexType> > SndBuf(nborders);
555 std::vector<Mesh::IndexType> ssizes(nborders,0);
556 for(
unsigned int i = 0;
i < nborders;
i++){
557 borders[
i].data.SendAp.resize(0);
558 borders[
i].data.SendAi.resize(0);
559 borders[
i].data.SendAp.push_back(0);
560 std::vector<Mesh::IndexType>::iterator sni = borders[
i].nsend.begin();
561 while(sni != borders[
i].nsend.end()){
563 std::list<Mesh::IndexType> doflist;
566 std::vector<Mesh::IndexType>::iterator ei = dc[*sni-1].begin();
567 while(ei != dc[*sni-1].end()){
568 std::vector<Mesh::IndexType>::iterator eni = ec[*ei-1].begin();
569 while(eni != ec[*ei-1].end()){
570 std::vector<Mesh::IndexType>::iterator ndi;
571 std::vector<Mesh::IndexType>::iterator ndend;
574 ndi = RemoteNodalDofs[*eni - info.
nlocal - 1].begin();
575 ndend = RemoteNodalDofs[*eni - info.
nlocal -1].end();
579 ndi = NodalDofs[*eni-1].begin();
580 ndend = NodalDofs[*eni-1].end();
583 doflist.push_back(*ndi + offset);
588 eni = ElementDofs[*ei-1].begin();
589 while(eni != ElementDofs[*ei-1].end()){
590 doflist.push_back(*eni+info.
doffset);
601 SndBuf[
i].push_back(doflist.size());
602 borders[
i].data.SendAp.push_back(doflist.size() + *(borders[
i].data.SendAp.rbegin()));
603 std::list<Mesh::IndexType>::iterator dli = doflist.begin();
604 while(dli != doflist.end())
605 borders[
i].data.SendAi.push_back(*dli++);
609 *Out <<
"SendAp for color " << borders[
i].rpart <<
":" << std::endl;
610 DumpContents(*Out,borders[
i].data.SendAp,
" ");
612 <<
"SendAi for color " << borders[
i].rpart <<
":" << std::endl;
613 DumpContents(*Out,borders[i].data.SendAi,
" ");
615 *Out <<
"Posting send of " << SndBuf[
i].size() <<
" stiffness row sizes "
616 <<
"to " << borders[
i].rpart <<
":" << std::endl;
617 DumpContents(*Out,SndBuf[i],
" ");
624 *Out <<
"Receive Buffer: " << std::endl;
625 for(
unsigned int i = 0;
i < nborders;
i++){
626 *Out <<
"Partition " <<
i+1 <<
": ";
627 DumpContents(*Out,RcvBuf[i],
" ");
631 comm.ClearRequests();
634 *Out <<
"All procs have posted sends." << std::endl;
640 for(
unsigned int i = 0;
i < nborders;
i++){
641 borders[
i].data.RecvAp.resize(RcvBuf[
i].size()+1);
642 std::vector<Mesh::IndexType>::iterator rbi = RcvBuf[
i].begin();
643 std::vector<Mesh::IndexType>::iterator rai = borders[
i].data.RecvAp.begin();
645 while(rbi != RcvBuf[
i].end()){
650 *Out <<
"RecvAP from partition " << borders[
i].rpart <<
":" << std::endl;
651 DumpContents(*Out,borders[
i].data.RecvAp,
" ");
660 std::vector<Mesh::IndexType>::reverse_iterator rsi = borders[
i].data.RecvAp.rbegin();
661 unsigned int totalsize = *rsi;
662 borders[
i].data.RecvAi.resize(totalsize);
664 *Out <<
"Posting RecvAi (" << borders[
i].data.RecvAi.size()
665 <<
") from partition" << borders[
i].rpart << std::endl;
670 *Out <<
"Posting SendAi (" << borders[
i].data.SendAi.size()
671 <<
") to partition" << borders[
i].rpart <<
":" << std::endl;
672 DumpContents(*Out,borders[
i].data.SendAi,
" ");
677 comm.ClearRequests();
680 for(
unsigned int i = 0;
i < nborders;
i++){
681 *Out <<
"Recieved RecvAi (" << borders[
i].data.RecvAi.size()
682 <<
") from partition" << borders[
i].rpart <<
":" << std::endl;
683 DumpContents(*Out,borders[
i].data.RecvAi,
" ");
692 unsigned int nborders = borders.size();
693 unsigned int nalloc = 0;
694 for(
unsigned int i = 0;
i < nborders;
i++){
695 unsigned int nval_send = 0;
696 unsigned int nval_recv = 0;
697 std::vector<Mesh::IndexType>::iterator
ni = borders[
i].nrecv.begin();
698 std::vector<Mesh::IndexType>::iterator Api = borders[
i].data.RecvAp.begin();
699 while(ni != borders[
i].nrecv.end()){
702 nval_recv += ((*Api-begindex) * ndof);
707 *Out <<
"Allocating buffer(" << nval_recv <<
") for receiving stiffness blocks"
708 <<
" from " << borders[
i].rpart <<
"." << std::endl;
709 borders[
i].data.RecvBuffer.resize(nval_recv,0.0);
710 borders[
i].data.RecvBuffer.swap(borders[
i].data.RecvBuffer);
712 ni = borders[
i].nsend.begin();
713 Api = borders[
i].data.SendAp.begin();
715 while(ni != borders[i].nsend.end()){
718 nval_send += ((*Api-begindex) * ndof);
723 *Out <<
"Allocating buffer(" << nval_send <<
") for sending stiffness blocks"
724 <<
" to " << borders[
i].rpart <<
"." << std::endl;
725 borders[
i].data.SendBuffer.resize(nval_send,1.0);
726 borders[
i].data.SendBuffer.swap(borders[i].data.SendBuffer);
734 unsigned int nborders = borders.size();
735 for(
unsigned int i = 0;
i < nborders;
i++)
737 if(comm.SetSend(borders[
i].data.SendBuffer,borders[i].rpart-1) < 0)
739 if(comm.SetRecv(borders[i].data.RecvBuffer,borders[i].rpart-1) < 0)
754 nglobaldof += ElementDofs[pp].size();
758 nglobaldof += NodalDofs[pp].size();
760 nremotedof += NodalDofs[pp].size();
767 std::ostream* StdOut = NULL;
768 std::ostream* ErrOut = NULL;
769 std::ostream* LogOut = NULL;
770 std::ofstream LogFile;
771 Global::GlobalObj<std::string,Mesh::IndexType,Profiler::ProfilerObj> global;
772 Comm::CommunicatorObject comm(&argc,&argv);
773 unsigned int rank = comm.Rank();
774 unsigned int nproc = comm.Size();
775 global.Init(
"MeshTest",rank);
781 global.SetDebugLevel(0);
782 global.FunctionEntry(
"main");
785 int clerr = comline.ProcessOptions();
786 std::string sverb = comline.GetOption(
"verb");
787 std::string spart = comline.GetOption(
"partition");
788 std::string sclone = comline.GetOption(
"clone");
789 bool do_partitioning = !comline.GetOption(
"partition").empty();
790 bool do_mesh_testing = !comline.GetOption(
"mesh").empty();
791 bool do_assembly = !comline.GetOption(
"assembly").empty();
792 bool do_reorient = !comline.GetOption(
"reorient").empty();
793 bool debug = !comline.GetOption(
"debug").empty();
794 bool array_checking = !comline.GetOption(
"checking").empty();
795 bool do_generate = !comline.GetOption(
"generate").empty();
796 bool do_clone = !comline.GetOption(
"clone").empty();
797 bool do_dump_sparse = !comline.GetOption(
"sparse").empty();
799 bool do_renumbering = !comline.GetOption(
"renumber").empty();
801 Comm::DTSIZET : Comm::DTUINT);
802 if(!comline.GetOption(
"help").empty()){
804 *StdOut << comline.LongUsage() << std::endl;
812 *ErrOut << comline.ErrorReport() << std::endl
813 << std::endl << comline.ShortUsage() << std::endl;
821 if(sverb !=
".true."){
822 std::istringstream Istr(sverb);
827 if(!spart.empty() && spart !=
".true."){
828 std::istringstream Istr(spart);
831 if(!sclone.empty() && sclone !=
".true."){
832 std::istringstream Istr(sclone);
838 std::ostringstream debugfilename;
839 debugfilename << comline.ProgramName() <<
".output." <<
rank;
840 LogFile.open(debugfilename.str().c_str());
841 global.SetDebugStream(LogFile);
844 if(verblevel > 1 && rank > 0)
848 global.SetDebugStream(std::cerr);
852 if(verblevel > 1 || debug){
853 global.SetDebugLevel(1);
855 if(debug && rank > 0)
857 std::vector<std::string> infiles = comline.GetArgs();
858 if(infiles.size()==0) {
860 *ErrOut <<
"MeshTest::Error: No input specified." << std::endl
861 << std::endl << comline.ShortUsage() << std::endl;
868 std::string MeshName;
870 MeshName = infiles[0];
872 if(infiles.size() > 1){
873 std::istringstream Instr(infiles[1]);
881 ec.resize(number_of_elements);
882 if(StdOut && verblevel)
883 *StdOut <<
"Creating cube mesh with " << number_of_nodes <<
" nodes, "
884 << number_of_elements <<
" elements." << std::endl;
887 *LogOut <<
"NC.size() = " << nc.
Size() << std::endl;
890 for(
unsigned int k = 0;
k < N;
k++){
892 for(
unsigned int j = 0;
j < N;
j++){
894 for(
unsigned int i = 0;
i < N;
i++){
899 if(
k < (N-1) &&
j < (N-1) &&
i < (N-1)){
901 ec[element_id-1].push_back(ulnode);
902 ec[element_id-1].push_back(ulnode+N);
903 ec[element_id-1].push_back(ulnode+N+1);
904 ec[element_id-1].push_back(ulnode+1);
905 ec[element_id-1].push_back(ulnode+N*N);
906 ec[element_id-1].push_back(ulnode+N*N+N);
907 ec[element_id-1].push_back(ulnode+N*N+N+1);
908 ec[element_id-1].push_back(ulnode+N*N+1);
915 Ouf.open(MeshName.c_str());
916 Ouf << nc << std::endl << ec << std::endl;
924 std::string MeshName;
925 if(!infiles.empty()){
926 MeshName = infiles[0];
928 std::ostringstream Ostr;
931 Ostr <<
"." << rank+1 <<
".pmesh";
932 Inf.open(Ostr.str().c_str());
935 *ErrOut <<
"Failed to open " << Ostr.str() << std::endl;
943 global.FunctionEntry(
"ReadCoord");
945 global.FunctionExit(
"ReadCoord");
946 number_of_nodes = nc.
Size();
947 if(StdOut && verblevel)
948 *StdOut <<
"Number of nodes: " << number_of_nodes << std::endl;
949 std::vector<double> bounds(6,0.0);
951 if(StdOut && verblevel)
952 *StdOut <<
"Mesh Bounds: (" << bounds[0] <<
"," << bounds[1]
953 <<
") (" << bounds[2] <<
"," << bounds[3]
954 <<
") (" << bounds[4] <<
"," << bounds[5] <<
")" << std::endl;
956 global.FunctionEntry(
"ReadCon");
958 global.FunctionExit(
"ReadCon");
961 if(StdOut && verblevel)
962 *StdOut <<
"Number of elements: " << number_of_elements
966 if(infiles.size() > 1){
967 std::istringstream Istr(infiles[1]);
970 if(infiles.size() > 2){
971 std::istringstream Istr(infiles[2]);
975 Mesh::Connectivity::iterator ci = econ.begin();
977 while(ci != econ.end()){
978 if(StdOut && verblevel)
979 *StdOut <<
"Element " << el++ <<
": (";
980 std::vector<Mesh::IndexType>::iterator
ni = ci->begin();
981 while(ni != ci->end()){
982 if(StdOut && verblevel)
985 if(StdOut && verblevel)
988 if(StdOut && verblevel)
994 global.FunctionEntry(
"DualCon");
995 econ.
Inverse(dc,number_of_nodes);
996 global.FunctionExit(
"DualCon");
1001 bool do_neighborhood =
false;
1002 if(do_neighborhood){
1007 global.FunctionEntry(
"Neighborhood2");
1009 global.FunctionExit(
"Neighborhood2");
1050 Mesh::Connectivity::iterator ei2 = nl2.begin();
1052 while(ei2 != nl2.end()){
1053 if(StdOut && verblevel)
1054 *StdOut <<
"Element " << el++ <<
" neighbors: ";
1055 std::vector<Mesh::IndexType>::iterator
ni = ei2->begin();
1056 while(ni != ei2->end()){
1057 if(StdOut && verblevel)
1059 if(ni != ei2->end())
1060 if(StdOut && verblevel)
1063 if(StdOut && verblevel)
1064 *StdOut << std::endl;
1071 global.FunctionEntry(
"List Creation");
1072 std::vector<Mesh::IndexType> a;
1073 std::vector<Mesh::IndexType> b;
1078 b[N-
j] = (
j+100)%N + 1;
1080 global.FunctionExit(
"List Creation");
1081 global.FunctionEntry(
"Same Orientation");
1082 bool same_orientation = HaveSameOrientation(a,b);
1083 global.FunctionExit(
"Same Orientation");
1084 global.FunctionEntry(
"Opp Orientation");
1085 bool opp_orientation = HaveOppositeOrientation(a,b);
1086 global.FunctionExit(
"Opp Orientation");
1087 if(StdOut && verblevel)
1088 *StdOut <<
"Lists did " << (same_orientation ?
"" :
"not ")
1089 <<
"have same orientation.\n"
1090 <<
"Lists did " << (opp_orientation ?
"" :
"not ")
1091 <<
"have opposite orientation.\n";
1093 global.FunctionEntry(
"Orient elements");
1096 element_being_processed <= number_of_elements;
1097 element_being_processed++)
1106 if(!ge.
ShapeOK(econ[index],nc))
1107 *StdOut <<
"Element " << element_being_processed
1108 <<
" has bad shape!" << std::endl;
1110 global.FunctionExit(
"Orient elements");
1112 if(StdOut && verblevel)
1113 *StdOut <<
"Number of elements reoriented: " << invertedcount
1115 global.FunctionEntry(
"All Face Processing");
1122 std::vector<Mesh::SymbolicFace> sf;
1124 global.FunctionEntry(
"GetFaceConnectivites");
1125 econ.BuildFaceConnectivity(F_N,E_F,sf,dc);
1126 global.FunctionExit(
"GetFaceConnectivites");
1127 global.FunctionEntry(
"Face dual");
1129 global.FunctionExit(
"Face dual");
1130 global.FunctionEntry(
"Canned shrink");
1134 std::vector<Mesh::SymbolicFace>(sf).
swap(sf);
1135 global.FunctionExit(
"Canned shrink");
1136 global.FunctionEntry(
"Face syncsizes");
1139 global.FunctionExit(
"Face syncsizes");
1141 global.FunctionEntry(
"Face Stats");
1146 Mesh::Connectivity::iterator fei = F_E.begin();
1147 while(fei != F_E.end()){
1149 if(F_E.
Esize(faceid) == 1){
1150 if(F_N.
Esize(faceid) == 3)
1153 canned_bndry_quad++;
1156 if(F_N.
Esize(faceid) == 3)
1162 global.FunctionExit(
"Face Stats");
1163 if(StdOut && verblevel)
1164 *StdOut <<
"Estimated number of faces: " << nface_estimate << std::endl
1165 <<
"Actual Number of faces: " << F_N.
Nelem() <<
"\n"
1166 <<
"Boundary faces: " << canned_bndry_tri + canned_bndry_quad <<
"\n"
1167 <<
"Volume faces: " << canned_vol_tri + canned_vol_quad <<
"\n"
1168 << canned_vol_quad +canned_bndry_quad <<
" Quads.\n"
1169 << canned_vol_tri + canned_bndry_tri <<
" Tris.\n"
1170 << canned_bndry_quad+canned_bndry_tri <<
" Boundary faces ("
1171 << canned_bndry_quad <<
"," << canned_bndry_tri <<
")" << std::endl;
1172 global.FunctionExit(
"All Face Processing");
1177 global.FunctionEntry(
"Edges processing");
1180 std::vector<std::list<Mesh::IndexType> > anodelist;
1181 global.FunctionEntry(
"CreateAdjNodes Template");
1182 CreateAdjacentNodeList<std::vector<std::vector<Mesh::IndexType> >,
1183 std::vector<Mesh::IndexType> >
1184 (anodelist,F_N,number_of_nodes);
1185 global.FunctionExit(
"CreateAdjNodes Template");
1187 NumberOfEdges< std::vector<std::list<Mesh::IndexType> >,
1188 std::list<Mesh::IndexType> >(anodelist);
1189 global.FunctionExit(
"Edges processing");
1190 if(StdOut && verblevel)
1191 *StdOut <<
"Number of edges: " << nedges << std::endl;
1193 std::vector< std::list<Mesh::IndexType> >::iterator anli = anodelist.begin();
1195 while(anli != anodelist.end())
1197 if(StdOut && array_checking)
1198 *StdOut <<
"Node " << ++ii <<
" neighbors:";
1199 std::list<Mesh::IndexType>::iterator
ni = anli->begin();
1200 while(ni != anli->end())
1202 if(StdOut && array_checking)
1204 if(ni != anli->end())
1205 if(StdOut && array_checking)
1208 if(StdOut && array_checking)
1209 *StdOut << std::endl;
1219 global.FunctionEntry(
"Assembly Function");
1221 global.FunctionEntry(
"Initialization");
1230 *LogOut <<
"DataSize = " << datasize << std::endl;
1232 global.FunctionEntry(
"ReadCoord");
1233 std::string MeshName;
1234 if(!infiles.empty())
1235 MeshName = infiles[0];
1236 std::ostringstream FNOstr;
1238 FNOstr << MeshName <<
"." << rank+1 <<
".info";
1239 Inf.open(FNOstr.str().c_str());
1242 *ErrOut <<
"Failed to open " << FNOstr.str() << std::endl;
1251 FNOstr << MeshName <<
"." << rank+1 <<
".pmesh";
1258 Inf.open(FNOstr.str().c_str());
1261 *ErrOut <<
"Failed to open " << FNOstr.str() << std::endl;
1269 number_of_nodes = nc.
Size();
1271 global.FunctionExit(
"ReadCoord");
1272 global.FunctionEntry(
"ReadCon");
1275 global.FunctionExit(
"ReadCon");
1278 number_of_elements = econ.
Nelem();
1279 if(LogOut && verblevel > 1){
1281 *LogOut <<
"Connectivity size(bytes): " << (consize+(2*number_of_elements))*datasize << std::endl;
1284 info.
nnodes = number_of_nodes;
1286 info.
nlocal = number_of_nodes;
1287 info.
nelem = number_of_elements;
1289 if(StdOut && verblevel)
1290 *StdOut <<
"Number of elements: " << number_of_elements
1292 <<
"Number of nodes: " << number_of_nodes << std::endl
1293 <<
"Number of local nodes: " << info.
nlocal << std::endl;
1294 std::vector<Mesh::Border> borders;
1295 std::list<Mesh::IndexType> remotecolorlist;
1300 if(StdOut && verblevel)
1301 *StdOut <<
"Number of neighboring partitions: " << info.
nborder << std::endl;
1303 bordernodes.resize(info.
nborder);
1304 gbordernodes.resize(info.
nborder);
1310 Inf >> borders[nn].rpart >> nrecv >> nsend;
1313 remotecolorlist.push_back(borders[nn].rpart);
1317 borders[nn].nrecv.push_back(nodeid);
1318 bordernodes[nn].push_back(nodeid);
1320 gbordernodes[nn].push_back(nodeid);
1325 borders[nn].nsend.push_back(nodeid);
1326 bordernodes[nn].push_back(nodeid);
1328 gbordernodes[nn].push_back(nodeid);
1331 if(LogOut && verblevel > 1){
1332 *LogOut <<
"Border description storage size(bytes): "
1333 << (totalrecv+totalsend)*datasize
1338 if(LogOut && debug && array_checking)
1339 *LogOut <<
"BorderNodes:" << std::endl
1340 << bordernodes << std::endl
1341 <<
"GlobalBorderNodes:" << std::endl
1342 << gbordernodes << std::endl;
1346 if(infiles.size() > 1){
1347 std::istringstream Istr(infiles[1]);
1352 if(infiles.size() > 2){
1353 std::istringstream Istr(infiles[2]);
1359 if(LogOut && verblevel > 1)
1360 *LogOut <<
"All command line args processed." << std::endl;
1361 if(StdOut && verblevel){
1362 *StdOut <<
"Number of nodal dofs: " << N << std::endl
1363 <<
"Number of element dofs: " << N2 << std::endl;
1365 if(LogOut && verblevel > 1)
1366 *LogOut <<
"Building dual connectivity..." << std::endl;
1368 global.FunctionEntry(
"DualCon");
1369 econ.
Inverse(dc,number_of_nodes);
1370 global.FunctionExit(
"DualCon");
1374 if(LogOut && debug){
1375 *LogOut <<
"Dual Con size(bytes):"
1379 *LogOut <<
"dual connectivity:" << std::endl
1385 if(LogOut && verblevel > 1)
1386 *LogOut <<
"Building element neighborhood." << std::endl;
1387 global.FunctionEntry(
"Neighborhood");
1389 global.FunctionExit(
"Neighborhood");
1391 if(LogOut && array_checking)
1392 *LogOut <<
"Element Neighborhood:" << std::endl
1393 << nl2 << std::endl;
1396 *LogOut <<
"Neighborhood size(bytes): "
1400 NodalDofs.resize(number_of_nodes);
1403 ElementDofs.resize(number_of_elements);
1405 std::vector<FEM::FieldData> fields;
1408 FEM::FieldData nfield;
1410 nfield.Components(N);
1411 fields.push_back(nfield);
1415 FEM::FieldData efield;
1417 efield.Components(N2);
1418 fields.push_back(efield);
1430 if(LogOut && verblevel > 1)
1431 *LogOut <<
"All processors finished prepping."
1433 <<
"Now assigning DOFs." << std::endl;
1434 global.FunctionExit(
"Initialization");
1438 std::list<Mesh::IndexType> border_elements;
1442 std::vector<bool> is_border_element(number_of_elements,
false);
1443 std::vector<bool> element_processed(number_of_elements,
false);
1444 if(LogOut && verblevel)
1445 *LogOut <<
"Creating border element list for " << info.
nshared
1446 <<
" border nodes and " << nvolume_nodes <<
" volume nodes."
1448 global.FunctionEntry(
"Assembly Prep");
1449 global.FunctionEntry(
"Find Border Elements");
1454 std::vector<Mesh::IndexType>::iterator ei = dc[nn].begin();
1455 while(ei != dc[nn].end()){
1456 if(!element_processed[*ei-1]){
1457 element_processed[*ei-1] =
true;
1458 border_elements.push_back(*ei);
1459 is_border_element[*ei-1] =
true;
1464 border_elements.sort();
1465 global.FunctionExit(
"Find Border Elements");
1466 if(LogOut && verblevel){
1467 *LogOut <<
"Found " << border_elements.size() <<
" border elements."
1470 DumpContents(*LogOut,border_elements,
" ");
1471 *LogOut << std::endl;
1474 std::list<Mesh::IndexType> queue;
1477 std::vector<bool> neighbors_processed(number_of_elements,
false);
1478 element_processed.clear();
1479 element_processed.resize(number_of_elements,
false);
1481 std::list<Mesh::IndexType>::iterator qi = queue.begin();
1482 global.FunctionEntry(
"Element order queue");
1483 while(nprocessed < number_of_elements){
1484 bool from_queue =
false;
1490 if(qi != queue.end()){
1496 if(element_processed[
i])
1499 if(!element_processed[elnum]){
1500 element_processed[elnum] =
true;
1502 queue.push_back(elnum+1);
1506 if(!neighbors_processed[elnum]){
1507 neighbors_processed[elnum] =
true;
1508 std::vector<Mesh::IndexType>::iterator
ni = nl2[elnum].begin();
1509 while(ni != nl2[elnum].end()){
1510 if(!element_processed[*ni-1]){
1511 element_processed[*ni-1] =
true;
1512 queue.push_back(*ni);
1520 global.FunctionExit(
"Element order queue");
1521 if(LogOut && debug && array_checking){
1522 *LogOut <<
"Element order queue:" << std::endl;
1523 DumpContents(*LogOut,queue,
" ");
1524 *LogOut << std::endl;
1533 global.FunctionEntry(
"Dof Assignment");
1535 if(nproc == 1 &&
false){
1536 std::vector<bool> node_processed(number_of_nodes,
false);
1537 std::list<Mesh::IndexType>::iterator ei = queue.begin();
1538 while(ei != queue.end()){
1539 std::vector<Mesh::IndexType>::iterator
ni = econ[*ei-1].begin();
1540 while(ni != econ[*ei-1].end()){
1541 if(!node_processed[*ni-1]){
1542 node_processed[*ni-1] =
true;
1543 NodalDofs[*ni-1].resize(N);
1544 for(
unsigned int i = 0;
i < N;
i++)
1545 NodalDofs[*ni-1][
i] = nvoldof++;
1549 ElementDofs[*ei-1].resize(N2);
1550 for(
unsigned int i = 0;
i < N2;
i++)
1551 ElementDofs[*ei-1][
i] = nvoldof++;
1556 std::vector<bool> node_processed(number_of_nodes,
false);
1557 std::list<Mesh::IndexType>::iterator ei = queue.begin();
1558 while(ei != queue.end()){
1559 if(!is_border_element[*ei-1]){
1561 *LogOut <<
"Assigning dofs for nonborder element " << *ei << std::endl;
1562 std::vector<Mesh::IndexType>::iterator
ni = econ[*ei-1].begin();
1563 while(ni != econ[*ei-1].end()){
1564 if(!node_processed[*ni-1]){
1565 node_processed[*ni-1] =
true;
1566 NodalDofs[*ni-1].resize(N);
1567 for(
unsigned int i = 0;
i < N;
i++){
1569 *LogOut <<
"node " << *ni <<
" getting dof " << nvoldof << std::endl;
1570 NodalDofs[*ni-1][
i] = nvoldof++;
1575 ElementDofs[*ei-1].resize(N2);
1576 for(
unsigned int i = 0;
i < N2;
i++){
1578 *LogOut <<
"element " << *ei <<
" getting dof " << nvoldof << std::endl;
1579 ElementDofs[*ei-1][
i] = nvoldof++;
1586 ei = border_elements.begin();
1587 while(ei != border_elements.end()){
1588 ElementDofs[*ei-1].resize(N2);
1589 for(
unsigned int i = 0;
i < N2;
i++){
1591 *LogOut <<
"border element " << *ei <<
" getting dof " << nvoldof << std::endl;
1592 ElementDofs[*ei-1][
i] = nvoldof++;
1598 ei = border_elements.begin();
1599 while(ei != border_elements.end()){
1600 std::vector<Mesh::IndexType>::iterator
ni = econ[*ei-1].begin();
1601 while(ni != econ[*ei-1].end()){
1602 if(!node_processed[*ni-1] && *ni <= info.
nlocal){
1603 node_processed[*ni-1] =
true;
1604 NodalDofs[*ni-1].resize(N);
1605 for(
unsigned int i = 0;
i < N;
i++){
1607 *LogOut <<
"owned border node " << *ni <<
" getting dof "
1608 << nvoldof+nborderdof << std::endl;
1609 NodalDofs[*ni-1][
i] = (nvoldof + nborderdof++);
1616 nshareddof = nborderdof - 1;
1622 ei = border_elements.begin();
1623 while(ei != border_elements.end()){
1624 std::vector<Mesh::IndexType>::iterator
ni = econ[*ei-1].begin();
1625 while(ni != econ[*ei-1].end()){
1626 if(!node_processed[*ni-1]){
1627 node_processed[*ni-1] =
true;
1628 NodalDofs[*ni-1].resize(N);
1629 for(
unsigned int i = 0;
i < N;
i++){
1631 *LogOut <<
"remote border node " << *ni <<
" getting local dof "
1632 << nvoldof+nborderdof << std::endl;
1633 NodalDofs[*ni-1][
i] = (nvoldof + nborderdof++);
1641 ndoftot = nvoldof + nborderdof;
1642 nremotedof = nborderdof - nshareddof;
1643 nlocal_dofs = nvoldof + nshareddof;
1644 if(StdOut && verblevel)
1645 *StdOut <<
"NDof TOTAL (local + adjacent remote): " << ndoftot << std::endl
1646 <<
"NDof Local (local total) DOFS: " << nlocal_dofs << std::endl
1647 <<
"NDof Remote (initial count of dofs owned remotely) DOFS: "
1648 << nremotedof << std::endl
1649 <<
"NDof Border (total of dofs on partition boundaries) DOFS: "
1650 << nborderdof << std::endl
1651 <<
"NDof Shared (dofs on the partition boundary that I own) DOFS: "
1652 << nshareddof << std::endl;
1653 if(LogOut && debug){
1654 *LogOut <<
"nborderelems = " << border_elements.size() << std::endl;
1655 border_elements.sort();
1656 border_elements.unique();
1657 *LogOut <<
"after sort, size = " << border_elements.size() << std::endl;
1661 global.FunctionExit(
"Dof Assignment");
1662 if(StdOut && verblevel)
1663 *StdOut <<
"Number of local DOFs: " << nlocal_dofs << std::endl
1664 <<
"Number of Elements on partition boundaries: " << border_elements.size()
1666 if(LogOut && debug){
1667 *LogOut <<
"Total NodalDof storage(bytes): "
1668 << (
GetTotalSize(NodalDofs)+(number_of_nodes*2))*datasize
1670 <<
"Total ElementDof storage(bytes): "
1671 << (
GetTotalSize(ElementDofs)+(number_of_elements*2))*datasize
1680 if(LogOut && debug && array_checking)
1681 *LogOut <<
"NodalDofs: " << std::endl
1682 << NodalDofs << std::endl
1683 <<
"ElementDofs: " << std::endl
1684 << ElementDofs << std::endl;
1694 *LogOut <<
"All processors entering global dof counting."
1696 global.FunctionEntry(
"Global DOF counting");
1698 std::vector<Mesh::IndexType> ngdofs_p(nproc,0);
1699 std::vector<Mesh::IndexType> nnbr_p(nproc,0);
1700 ngdofs_p[
rank] = nglobal_dofs;
1701 ndoftotal = ndoftot;
1705 *LogOut <<
"All processors done counting local dofs."
1707 <<
"Now gathering ..." << std::endl;
1708 int commstat = comm.AllGather(nglobal_dofs,ngdofs_p);
1710 if(LogOut && debug){
1711 *LogOut <<
"Global Dofcount verification = " << nglobal_dofs << std::endl
1712 <<
"commstat = " << commstat << std::endl;
1714 *LogOut <<
"NGDofs:" << std::endl;
1715 DumpContents(*LogOut,ngdofs_p);
1716 *LogOut << std::endl;
1722 for(
unsigned int nn1 = 0;nn1 <
rank;nn1++)
1723 info.
doffset += ngdofs_p[nn1];
1724 for(
unsigned int nn2 = 0;nn2 < nproc;nn2++)
1725 ndof_global_total += ngdofs_p[nn2];
1726 if(StdOut && verblevel)
1727 *StdOut <<
"Number of global dofs on this proc: " << nglobal_dofs << std::endl
1728 <<
"Number of remote dofs on this proc: " << nremote_dofs << std::endl
1729 <<
"Number of global dofs over all procs: " << ndof_global_total << std::endl;
1730 if(StdOut && verblevel)
1731 *StdOut <<
"My global offset: " << info.
doffset << std::endl;
1737 *LogOut <<
"All procs entering global dof exchange."
1747 if(LogOut && verblevel)
1748 *LogOut <<
"Number of remote nodes: " << nremote_nodes << std::endl;
1749 RemoteNodalDofs.resize(nremote_nodes);
1750 RemoteNodalDofs.
Sync();
1763 global.FunctionEntry(
"Nodal DOF Exchange");
1764 GlobalDofExchange(borders,NodalDofs,RemoteNodalDofs,info,comm,LogOut,array_checking);
1765 global.FunctionExit(
"Nodal DOF Exchange");
1770 global.FunctionEntry(
"Count Dofs");
1773 CountDofs(ElementDofs,NodalDofs,info,nglobdof,nremotedof2);
1774 global.FunctionExit(
"Count Dofs");
1775 if(StdOut && verblevel)
1776 *StdOut <<
"After global exchange and recount: " << std::endl
1777 <<
"Number of global dofs on this proc: " << nglobdof << std::endl
1778 <<
"Number of remote dofs on this proc: " << nremotedof2 << std::endl;
1780 assert(nglobdof == nglobal_dofs);
1786 global.FunctionEntry(
"Build Communicated Stiffness");
1787 BuildBorderStiffness(econ,borders,NodalDofs,ElementDofs,RemoteNodalDofs,info,comm,LogOut,array_checking);
1788 global.FunctionExit(
"Build Communicated Stiffness");
1792 *LogOut <<
"Allocated " << nalloc*
sizeof(double) <<
" bytes of communication buffers."
1795 if(LogOut && verblevel)
1796 *LogOut <<
"Registering Comm Buffers." << std::endl;
1800 *ErrOut <<
"Error setting registering the communication buffers."
1806 global.FunctionExit(
"Global DOF counting");
1809 *LogOut <<
"All processors have exchanged interpartition DOF information."
1811 <<
"Proceeding with dof sorting." << std::endl;
1814 global.FunctionEntry(
"Build Sparsity");
1828 global.FunctionEntry(
"Create E[LD]");
1830 E_LD.resize(number_of_elements);
1832 std::vector<Mesh::IndexType>::iterator eni = econ[en].begin();
1833 while(eni != econ[en].end()){
1835 std::vector<Mesh::IndexType>::iterator ndi = NodalDofs[node_id-1].begin();
1836 while(ndi != NodalDofs[node_id-1].end())
1837 E_LD[en].push_back(*ndi++);
1840 std::vector<Mesh::IndexType>::iterator edi = ElementDofs[en].begin();
1841 while(edi != ElementDofs[en].end())
1842 E_LD[en].push_back(*edi++);
1844 global.FunctionEntry(
"E[LD] post");
1849 std::vector<Mesh::IndexType> element_ndofs(number_of_elements,0);
1851 element_ndofs[ei] = E_LD.
Esize(ei+1);
1852 global.FunctionExit(
"E[LD] post");
1853 global.FunctionExit(
"Create E[LD]");
1861 global.FunctionEntry(
"Invert E[LD]");
1863 global.FunctionExit(
"Invert E[LD]");
1872 assert(LD_E.
Nelem() == ndoftot);
1880 global.FunctionEntry(
"Sparsity Pattern");
1882 global.FunctionExit(
"Sparsity Pattern");
1888 if(LogOut && debug && array_checking)
1889 *LogOut <<
"All Local K:" << std::endl << symbstiff
1906 global.FunctionEntry(
"K update");
1908 std::vector<Mesh::IndexType> local_dof_to_global;
1909 local_dof_to_global.resize(ndoftot-nglobdof);
1911 std::vector<Mesh::IndexType>::iterator ndi = NodalDofs[
ni].begin();
1912 std::vector<Mesh::IndexType>::iterator rdi = RemoteNodalDofs[
ni-info.
nlocal].begin();
1913 assert(NodalDofs[
ni].size() == RemoteNodalDofs[
ni-info.
nlocal].size());
1914 while(ndi != NodalDofs[
ni].end()){
1915 local_dof_to_global[*ndi-nglobdof-1] = *rdi;
1920 Mesh::Connectivity::iterator ConIt = symbstiff.begin();
1921 while(ConIt != symbstiff.end()){
1922 std::vector<Mesh::IndexType>::iterator dofIt = ConIt->begin();
1924 while(dofIt != ConIt->end()){
1926 if(dof_id <= nglobdof)
1927 (*ConIt)[ind++] = dof_id+info.
doffset;
1929 (*ConIt)[ind++] = local_dof_to_global[dof_id - nglobdof - 1];
1942 for(
unsigned int nn = 0;nn < info.
nborder;nn++){
1943 std::vector<Mesh::IndexType>::iterator bni = borders[nn].nrecv.begin();
1944 std::vector<Mesh::IndexType>::iterator Api = borders[nn].data.RecvAp.begin();
1946 while(bni != borders[nn].nrecv.end()){
1948 std::vector<Mesh::IndexType>::iterator ndi = NodalDofs[*bni-1].begin();
1951 while(ndi != NodalDofs[*bni-1].end()){
1953 for(
unsigned int i = 0;
i <
nvals;
i++)
1954 symbstiff[*ndi-1].push_back(borders[nn].data.RecvAi[begindex+
i]);
1960 global.FunctionExit(
"K update");
1961 if(LogOut && debug && array_checking)
1962 *LogOut <<
"K after update:" << std::endl << symbstiff
1966 global.FunctionEntry(
"K sort");
1967 Mesh::Connectivity::iterator ssIt = symbstiff.begin();
1968 while(ssIt != symbstiff.end()){
1969 std::sort(ssIt->begin(),ssIt->end());
1970 std::vector<Mesh::IndexType> tmp(ssIt->begin(),std::unique(ssIt->begin(),ssIt->end()));
1974 global.FunctionExit(
"K sort");
1975 if(LogOut && debug && array_checking)
1976 *LogOut <<
"Sorted K:" << std::endl << symbstiff
1980 global.FunctionEntry(
"Create Stiffness");
1983 FEM::DummyStiffness<double,Mesh::IndexType,Mesh::Connectivity,std::vector<Mesh::IndexType> >
k;
1984 k._dofs = &symbstiff;
1987 k._data.resize(1000,0.0);
1988 k._sizes.resize(nglobdof+1,0);
1989 Mesh::Connectivity::iterator dci = symbstiff.begin();
1991 while(indcnt <= nglobdof){
1992 k.
_sizes[indcnt] = dci->size()+k._sizes[indcnt-1];
2001 std::vector<Mesh::IndexType> ApLoc(1,k._sizes[nglobdof]);
2002 std::vector<Mesh::IndexType> ApTot(1,0);
2004 comm.Reduce(ApLoc,ApTot,IndexDT,Comm::SUMOP,0);
2005 if(LogOut && verblevel){
2006 std::vector<Mesh::IndexType>::iterator si = k._sizes.begin();
2007 std::vector<Mesh::IndexType>::iterator si2 = k._sizes.begin();
2011 while(si != k._sizes.end())
2012 myav += (*si++ - *si2++);
2013 myav /= (k._sizes.size()-1);
2014 *LogOut <<
"The average NZ per stiffness row is: " << myav << std::endl;
2018 *LogOut <<
"Siffness storage(bytes): "
2019 << nnz*datasize << std::endl;
2022 if(StdOut && verblevel)
2023 *StdOut <<
"Total number of local Stiffness entries: " << nnz
2024 <<
":" << k._sizes[nglobdof] <<
":" << totsize << std::endl
2025 <<
"Total NZ over all procs: " << ApTot[0] << std::endl;
2028 std::ostringstream Ostr;
2029 std::ostringstream ZeroStr;
2030 unsigned int pwr10 = 10;
2031 while(nproc/pwr10 && !(rank/pwr10)){
2035 Ostr << infiles[0] <<
"_sparse_"
2036 << ZeroStr.str() << rank+1;
2038 Ouf.open(Ostr.str().c_str());
2039 Ouf << ndof_global_total << std::endl;
2040 Ouf << k._ndof << std::endl;
2045 global.FunctionExit(
"Create Stiffness");
2046 global.FunctionExit(
"Build Sparsity");
2050 std::vector<Mesh::IndexType> Order;
2054 global.FunctionEntry(
"Renumbering");
2055 std::vector<idxtype> adj;
2056 std::vector<idxtype> xadj;
2057 std::vector<idxtype> vtxdist;
2058 vtxdist.resize(ngdofs_p.size()+1);
2059 std::vector<Mesh::IndexType>::iterator ngdi = ngdofs_p.begin();
2060 std::vector<idxtype>::iterator vtdi = vtxdist.begin();
2062 while(ngdi != ngdofs_p.end()){
2063 idxtype nn =
static_cast<idxtype
>(*vtdi++ + *ngdi++);
2068 if(array_checking && LogOut){
2069 *LogOut <<
"Graph K:" << std::endl << symbstiff
2073 global.FunctionEntry(
"Container2CSR");
2074 MultiContainer2CSR< std::vector< std::vector<Mesh::IndexType> >,
2075 std::vector<Mesh::IndexType>,
2076 std::vector<idxtype>,idxtype>
2077 (xadj,adj,symbstiff);
2079 global.FunctionExit(
"Container2CSR");
2080 if(array_checking && LogOut){
2081 *LogOut <<
"Matrix K:" << std::endl << symbstiff
2084 std::vector<idxtype> order(ngdofs_p[rank],0);
2085 std::vector<idxtype> sizes(ngdofs_p.size()*2,0);
2093 *LogOut <<
"Vtxdist:" << std::endl;
2094 DumpContents(*LogOut,vtxdist,
" ");
2095 *LogOut << std::endl <<
"Xadj:" << std::endl;
2096 DumpContents(*LogOut,xadj,
" ");
2097 *LogOut << std::endl <<
"Adj:" << std::endl;
2098 DumpContents(*LogOut,adj,
" ");
2099 *LogOut << std::endl <<
"Ngdofs_p:" << std::endl;
2100 DumpContents(*LogOut,ngdofs_p,
" ");
2101 *LogOut << std::endl;
2103 global.FunctionEntry(
"Metis-NodeID");
2105 ParMETIS_V3_NodeND(&vtxdist[0],&xadj[0],&adj[0],&numflag,
2106 options,&order[0],&sizes[0],&communicator);
2108 global.FunctionExit(
"Metis-NodeID");
2110 *LogOut <<
"Order:" << std::endl;
2111 DumpContents(*LogOut,order,
" ");
2112 *LogOut << std::endl <<
"Sizes:" << std::endl;
2113 DumpContents(*LogOut,sizes,
" ");
2114 *LogOut << std::endl;
2116 global.FunctionEntry(
"OrderSort");
2117 std::vector<idxtype> sorder(order);
2118 Order.resize(order.size());
2119 std::vector<idxtype>::iterator oi = order.begin();
2120 std::vector<Mesh::IndexType>::iterator Oi = Order.begin();
2121 while(oi != order.end())
2124 std::sort(sorder.begin(),sorder.end());
2125 global.FunctionExit(
"OrderSort");
2126 std::vector<idxtype>::iterator soi = sorder.begin();
2127 *LogOut <<
"Reordered Min: " << *sorder.begin() << std::endl
2128 <<
"Reordered Max: " << *--sorder.end() << std::endl;
2129 unsigned int ttcount = 0;
2130 idxtype max_contig = 0;
2131 idxtype min_contig = 0;
2133 idxtype contig_min = 0;
2134 idxtype contig_max = 0;
2139 } binrank_p[nproc], binrank[nproc];
2140 for(
unsigned int iii = 0;iii < nproc;iii++){
2141 binrank[iii].nbin = 0;
2142 binrank[iii].rank =
rank;
2143 binrank_p[iii].rank = 0;
2144 binrank_p[iii].nbin = 0;
2146 std::vector<unsigned int> nbin(nproc,0);
2147 int binsize = ndof_global_total/nproc;
2148 while(soi != sorder.end()){
2149 idxtype first = *soi++;
2150 idxtype second = first;
2151 bool unbinned =
true;
2152 unsigned int aaa = 0;
2154 while(aaa < nproc && unbinned){
2155 if(first < (binmin + binsize)){
2157 binrank[aaa].nbin++;
2162 if(soi != sorder.end()){
2164 if(second != first+1){
2165 if(ncontig > 1000 && debug)
2166 *LogOut <<
"Large contiguous block(" << ncontig <<
"): ("
2167 << min_contig <<
"," << first <<
")" << std::endl;
2168 if(ncontig > max_contig){
2169 max_contig = ncontig;
2171 contig_min = min_contig;
2173 min_contig = second;
2176 *LogOut <<
"NonSequential(" << ttcount <<
"): " << first <<
":"
2177 << second << std::endl;
2186 *LogOut <<
"Maximum contiguous block(" << max_contig <<
"): (" << contig_min
2187 <<
"," << contig_max <<
")" << std::endl;
2192 for(
unsigned int iii = 0;iii < nproc;iii++){
2194 *LogOut <<
"Bin(" << binmin <<
"," << binmin+binsize <<
"): " << binrank[iii].nbin
2196 if(binrank[iii].nbin > maxbin){
2197 maxbin = binrank[iii].nbin;
2202 *LogOut <<
"My Preferred Solve Rank = " << solve_rank << std::endl;
2203 MPI_Allreduce(binrank,binrank_p,nproc,MPI_2INT,MPI_MAXLOC,
MPI_COMM_WORLD);
2204 std::vector<unsigned int> solve_ranks(nproc,0);
2205 std::vector<unsigned int> srank_to_rank(nproc,0);
2206 std::vector<bool> solve_rank_covered(nproc,
false);
2207 std::vector<unsigned int> rank_conflict;
2209 for(
unsigned int iii = 0;iii < nproc;iii++){
2210 solve_ranks[binrank_p[iii].rank] = iii;
2211 srank_to_rank[iii] = binrank_p[iii].rank;
2214 Comm::CommunicatorObject solvercomm;
2215 commstat = comm.Split(0,solve_ranks[rank],solvercomm);
2218 *LogOut <<
"MPI Error: " << commstat << std::endl;
2223 solve_rank = solvercomm.Rank();
2224 *LogOut <<
"My Solve Rank = " << solve_rank << std::endl;
2227 unsigned int ncovered = 0;
2228 for(
unsigned int iii = 0;iii < nproc;iii++){
2229 *LogOut <<
"SolveRanks[" << iii <<
"] == " << solve_ranks[iii]
2231 <<
"SRank[" << iii <<
"] == " << srank_to_rank[iii] << std::endl;
2233 if(solve_ranks[iii] == solve_ranks[rank])
2234 rank_conflict.push_back(iii);
2236 solve_rank_covered[solve_ranks[iii]] =
true;
2241 solve_rank_covered[solve_ranks[iii]] =
true;
2245 if(!rank_conflict.empty()){
2247 *LogOut <<
"Conflicting for solve_rank(" << solve_rank
2249 DumpContents(*LogOut,rank_conflict,
" ");
2250 *LogOut << std::endl;
2252 if(ncovered != nproc){
2254 *LogOut <<
"Uncovered bins: ";
2255 unsigned int bincount = 0;
2256 std::vector<bool>::iterator rci = solve_rank_covered.begin();
2257 while(rci != solve_rank_covered.end()){
2259 *LogOut << bincount <<
" ";
2262 *LogOut << std::endl;
2266 int binxtra = ndof_global_total%nproc;
2267 unsigned int mynrows = binsize + (solve_rank < binxtra ? 1 : 0);
2268 std::vector<unsigned int> nrows_p(nproc,0);
2269 nrows_p[solve_rank] = mynrows;
2270 commstat = solvercomm.AllGather(mynrows,nrows_p);
2271 solvercomm.Barrier();
2272 int solve_doffset = 0;
2273 for(
int iii = 0;iii < solve_rank;iii++)
2274 solve_doffset += nrows_p[iii];
2275 int my_first_row = solve_doffset;
2276 int my_last_row = my_first_row + mynrows - 1;
2278 *LogOut <<
"My Rows (" << mynrows <<
") = (" << my_first_row
2279 <<
"," << my_last_row <<
")" << std::endl;
2281 RemoteRows.resize(nproc);
2282 for(
unsigned int iii = 0;iii < nglobdof;iii++){
2283 unsigned int row_index = Order[iii];
2284 unsigned int solve_procid = 0;
2285 unsigned int findrow = nrows_p[0];
2286 while(findrow < row_index)
2287 findrow += nrows_p[++solve_procid];
2288 RemoteRows[solve_procid].push_back(row_index);
2291 *LogOut <<
"RemoteRows:" << std::endl
2292 << RemoteRows << std::endl;
2294 *LogOut <<
"Row distribution: " << std::endl;
2295 for(
unsigned int iii = 0;iii < nproc;iii++)
2296 *LogOut <<
"Rows on Solve Rank " << iii <<
": "
2297 << RemoteRows[iii].size() << std::endl;
2299 unsigned int nlocal_rows = RemoteRows[solve_rank].size();
2301 *LogOut <<
"Number of solved Rows I own: " << nlocal_rows << std::endl
2302 <<
"Number of Rows I assemble: " << nglobdof << std::endl
2303 <<
"Number of Rows I solve: " << mynrows << std::endl;
2304 int nremote_rows = 0;
2305 for(
int iii = 0;iii < (int)nproc;iii++)
2306 if(iii != solve_rank)
2307 nremote_rows += RemoteRows[iii].size();
2308 int nrecvd_rows = mynrows - nlocal_rows;
2310 *LogOut <<
"Number of Remote Rows I assemble (Sent Rows): " << nremote_rows << std::endl
2311 <<
"Number of my Rows assembled remotely (Recvd Rows): " << nrecvd_rows << std::endl;
2320 borders,info,Order,comm,LogOut,array_checking);
2323 global.FunctionEntry(
"Build Sparsity");
2337 global.FunctionEntry(
"Create E[LD]");
2339 E_LD.resize(number_of_elements);
2341 std::vector<Mesh::IndexType>::iterator eni = econ[en].begin();
2342 while(eni != econ[en].end()){
2344 std::vector<Mesh::IndexType>::iterator ndi = NodalDofs[node_id-1].begin();
2345 while(ndi != NodalDofs[node_id-1].end())
2346 E_LD[en].push_back(*ndi++);
2349 std::vector<Mesh::IndexType>::iterator edi = ElementDofs[en].begin();
2350 while(edi != ElementDofs[en].end())
2351 E_LD[en].push_back(*edi++);
2353 global.FunctionEntry(
"E[LD] post");
2358 std::vector<Mesh::IndexType> element_ndofs(number_of_elements,0);
2360 element_ndofs[ei] = E_LD.
Esize(ei+1);
2361 global.FunctionExit(
"E[LD] post");
2362 global.FunctionExit(
"Create E[LD]");
2370 global.FunctionEntry(
"Invert E[LD]");
2372 global.FunctionExit(
"Invert E[LD]");
2381 assert(LD_E.
Nelem() == ndoftot);
2389 global.FunctionEntry(
"Sparsity Pattern");
2391 global.FunctionExit(
"Sparsity Pattern");
2397 if(LogOut && debug && array_checking)
2398 *LogOut <<
"All Local K:" << std::endl << symbstiff
2415 global.FunctionEntry(
"K update");
2417 std::vector<Mesh::IndexType> local_dof_to_global;
2418 local_dof_to_global.resize(ndoftot-nglobdof);
2420 std::vector<Mesh::IndexType>::iterator ndi = NodalDofs[
ni].begin();
2421 std::vector<Mesh::IndexType>::iterator rdi = RemoteNodalDofs[
ni-info.
nlocal].begin();
2422 assert(NodalDofs[
ni].size() == RemoteNodalDofs[
ni-info.
nlocal].size());
2423 while(ndi != NodalDofs[
ni].end()){
2424 local_dof_to_global[*ndi-nglobdof-1] = *rdi;
2429 Mesh::Connectivity::iterator ConIt = symbstiff.begin();
2430 while(ConIt != symbstiff.end()){
2431 std::vector<Mesh::IndexType>::iterator dofIt = ConIt->begin();
2433 while(dofIt != ConIt->end()){
2435 if(dof_id <= nglobdof)
2436 (*ConIt)[ind++] = Order[dof_id-1]+1;
2438 (*ConIt)[ind++] = local_dof_to_global[dof_id - nglobdof - 1];
2451 for(
unsigned int nn = 0;nn < info.
nborder;nn++){
2452 std::vector<Mesh::IndexType>::iterator bni = borders[nn].nrecv.begin();
2453 std::vector<Mesh::IndexType>::iterator Api = borders[nn].data.RecvAp.begin();
2455 while(bni != borders[nn].nrecv.end()){
2457 std::vector<Mesh::IndexType>::iterator ndi = NodalDofs[*bni-1].begin();
2460 while(ndi != NodalDofs[*bni-1].end()){
2462 for(
unsigned int i = 0;
i <
nvals;
i++)
2463 symbstiff[*ndi-1].push_back(borders[nn].data.RecvAi[begindex+
i]);
2469 global.FunctionExit(
"K update");
2470 if(LogOut && debug && array_checking)
2471 *LogOut <<
"K after update:" << std::endl << symbstiff
2475 global.FunctionEntry(
"K sort");
2476 Mesh::Connectivity::iterator ssIt = symbstiff.begin();
2477 while(ssIt != symbstiff.end()){
2478 std::sort(ssIt->begin(),ssIt->end());
2479 std::vector<Mesh::IndexType> tmp(ssIt->begin(),std::unique(ssIt->begin(),ssIt->end()));
2483 global.FunctionExit(
"K sort");
2484 if(LogOut && debug && array_checking)
2485 *LogOut <<
"Sorted K:" << std::endl << symbstiff
2489 global.FunctionEntry(
"Create Stiffness");
2493 k._dofs = &symbstiff;
2496 k._data.resize(1000,0.0);
2497 k._sizes.resize(nglobdof+1,0);
2498 Mesh::Connectivity::iterator dci = symbstiff.begin();
2500 while(indcnt <= nglobdof){
2501 k.
_sizes[indcnt] = dci->size()+k._sizes[indcnt-1];
2509 std::vector<Mesh::IndexType> ApLoc(1,k._sizes[nglobdof]);
2510 std::vector<Mesh::IndexType> ApTot(1,0);
2513 if(LogOut && verblevel){
2514 std::vector<Mesh::IndexType>::iterator si = k._sizes.begin();
2515 std::vector<Mesh::IndexType>::iterator si2 = k._sizes.begin();
2519 while(si != k._sizes.end())
2520 myav += (*si++ - *si2++);
2521 myav /= (k._sizes.size()-1);
2522 *LogOut <<
"The average NZ per stiffness row is: " << myav << std::endl;
2526 *LogOut <<
"Stiffness storage(bytes): "
2527 << nnz*datasize << std::endl;
2531 *LogOut <<
"Total number of local Stiffness entries: "
2532 << k._sizes[nglobdof] << std::endl
2533 <<
"Total NZ over all procs: " << totsize << std::endl;
2535 std::ostringstream Ostr;
2536 std::ostringstream ZeroStr;
2537 unsigned int pwr10 = 10;
2538 while(nproc/pwr10 && !(rank/pwr10)){
2542 Ostr << infiles[0] <<
"_sparse_rnm_"
2543 << ZeroStr.str() << rank+1;
2545 Ouf.open(Ostr.str().c_str());
2546 Ouf << ndof_global_total << std::endl;
2547 Ouf << k._ndof << std::endl;
2548 DumpContents(Ouf,Order,
" ");
2553 global.FunctionExit(
"Create Stiffness");
2554 global.FunctionExit(
"Build Sparsity");
2555 std::vector<bool> element_processed(number_of_elements,
false);
2556 std::vector<bool> is_border_element(number_of_elements,
false);
2557 for(
unsigned int iii = 0;iii < info.
nlocal;iii++){
2558 std::vector<Mesh::IndexType>::iterator ndi = NodalDofs[iii].begin();
2559 bool node_processed =
false;
2560 while(ndi != NodalDofs[iii].end() && !node_processed){
2561 if(Order[*ndi] <= (
unsigned int)my_first_row ||
2562 Order[*ndi] >= (
unsigned int)my_last_row){
2563 std::vector<Mesh::IndexType>::iterator bei = dc[iii].begin();
2564 while(bei != dc[iii].end())
2565 is_border_element[*bei++] =
true;
2566 node_processed =
true;
2571 for(
unsigned int iii = info.
nlocal;iii < number_of_nodes;iii++){
2572 std::vector<Mesh::IndexType>::iterator bei = dc[iii].begin();
2573 while(bei != dc[iii].end())
2574 is_border_element[*bei++] =
true;
2576 for(
unsigned int iii = 0;iii < number_of_elements;iii++){
2577 std::vector<Mesh::IndexType>::iterator edi = ElementDofs[iii].begin();
2578 bool element_processed =
false;
2579 while(edi != ElementDofs[iii].end() && !element_processed){
2580 if(Order[*edi] <= (
unsigned int)my_first_row ||
2581 Order[*edi] >= (
unsigned int)my_last_row){
2582 is_border_element[iii] =
true;
2583 element_processed =
true;
2588 std::vector<bool>::iterator bei = is_border_element.begin();
2589 unsigned int nborder_elements = 0;
2590 while(bei != is_border_element.end()){
2595 *LogOut <<
"Border Elements: " << nborder_elements
2596 <<
"/" << number_of_elements << std::endl;
2597 global.FunctionExit(
"Renumbering");
2604 global.FunctionEntry(
"Border Node Mapping");
2605 std::vector<std::pair<unsigned int,unsigned int> > boundary_node_map(info.
nnodes-info.
nlocal);
2606 for(
unsigned int i = 0;
i < info.
nborder;
i++){
2607 std::vector<Mesh::IndexType>::iterator sni = borders[
i].nsend.begin();
2608 unsigned int index = 0;
2609 while(sni != borders[
i].nsend.end()){
2610 boundary_node_map[*sni - info.
nlocal - 1] = std::make_pair(
i+1,index+1);
2615 global.FunctionExit(
"Border Node Mapping");
2616 std::list<Mesh::IndexType> nonborder_queue;
2619 global.FunctionEntry(
"Find Border Elements");
2620 is_border_element.clear();
2621 is_border_element.resize(0);
2622 is_border_element.swap(is_border_element);
2623 element_processed.clear();
2624 element_processed.resize(0);
2625 element_processed.resize(number_of_elements,
false);
2626 border_elements.clear();
2627 border_elements.resize(0);
2629 std::vector<Mesh::IndexType>::iterator ei = dc[nn].begin();
2630 while(ei != dc[nn].end()){
2631 if(!element_processed[*ei-1]){
2632 element_processed[*ei-1] =
true;
2633 border_elements.push_back(*ei);
2638 border_elements.sort();
2639 std::list<Mesh::IndexType>::iterator ei = queue.begin();
2640 while(ei != queue.end()){
2641 if(!element_processed[*ei-1])
2642 nonborder_queue.push_back(*ei);
2645 if(LogOut && verblevel){
2646 *LogOut <<
"Found " << border_elements.size() <<
" border elements." << std::endl
2647 <<
"Found " << nonborder_queue.size() <<
" non border elements."
2650 *LogOut <<
"Border Elements:" << std::endl;
2651 DumpContents(*LogOut,border_elements,
" ");
2652 *LogOut << std::endl <<
"NonBorder Elements:" << std::endl;
2653 DumpContents(*LogOut,nonborder_queue,
" ");
2654 *LogOut << std::endl;
2657 global.FunctionExit(
"Find Border Elements");
2659 element_processed.clear();
2660 element_processed.resize(0);
2661 element_processed.resize(number_of_elements,
false);
2662 global.FunctionExit(
"Assembly Prep");
2664 global.FunctionEntry(
"Search Test");
2665 Mesh::Connectivity::iterator ci = symbstiff.begin();
2666 while(ci != symbstiff.end()){
2667 std::vector<Mesh::IndexType>::iterator ssrbegin = ci->begin();
2668 std::vector<Mesh::IndexType>::iterator ssrend = ci->end();
2669 std::vector<Mesh::IndexType>::iterator ssi = ci->begin();
2670 std::vector<Mesh::IndexType>::iterator curpos = ci->begin();
2671 std::vector<Mesh::IndexType>::iterator last_one = ci->begin();
2672 while(ssi != ci->end()){
2674 curpos = std::lower_bound(ssrbegin,ssrend,*ssi++);
2678 global.FunctionExit(
"Search Test");
2684 std::vector<double> dofdat(100000,1.0);
2686 global.FunctionEntry(
"Assembly Processing");
2691 global.FunctionEntry(
"Posting receives");
2693 global.FunctionExit(
"Posting receives");
2698 global.FunctionEntry(
"Send Buffer Assembly");
2699 std::list<Mesh::IndexType>::iterator bei = border_elements.begin();
2700 while(bei != border_elements.end()){
2702 element_processed[eindex]=
true;
2704 if(!((eindex+1) > 0 && (eindex+1) <= ElementDofs.
Nelem())){
2705 *ErrOut <<
"ERROR: ElementDofs[" << eindex <<
"].size() = " << ElementDofs[eindex].size()
2706 <<
" and ElementDofs.size() = " << ElementDofs.
Nelem() << std::endl;
2710 Mesh::IndexType search = FEM::AssembleBorderElementII(econ[eindex],ElementDofs[eindex],endof,nedof,
2711 NodalDofs,RemoteNodalDofs,k,borders,
2712 boundary_node_map,dofdat,info,LogOut,debug);
2713 bordersearch+=search;
2716 global.FunctionExit(
"Send Buffer Assembly");
2719 global.FunctionEntry(
"Posting Sends");
2721 global.FunctionExit(
"Posting Sends");
2724 global.FunctionEntry(
"Assembly Loop");
2727 std::list<Mesh::IndexType>::iterator ei = nonborder_queue.begin();
2728 while(ei != nonborder_queue.end()){
2736 search = FEM::AssembleLocalElementII(econ[nnn],ElementDofs[nnn],endof,nedof,
2737 NodalDofs,k,dofdat,info);
2741 global.FunctionExit(
"Assembly Loop");
2745 global.FunctionEntry(
"Fast Assembly");
2746 fast_searches = FEM::FastAssembleLocalElements(nonborder_queue,econ,k,
2747 NodalDofs,ElementDofs,element_ndofs,info);
2748 global.FunctionExit(
"Fast Assembly");
2751 global.FunctionEntry(
"Wait for messages");
2753 global.FunctionExit(
"Wait for messages");
2756 global.FunctionEntry(
"Recv Buffer Assembly");
2759 for(
unsigned int i = 0;
i < info.
nborder;
i++){
2760 int search = RecvBufAssembly(borders[
i],NodalDofs,k,dofdat);
2764 global.FunctionExit(
"Recv Buffer Assembly");
2765 global.FunctionExit(
"Assembly Processing");
2766 if(StdOut && verblevel)
2767 *StdOut <<
"Slow Ass searches = " << nsearches << std::endl
2768 <<
"Border searches = " << bordersearch << std::endl
2769 <<
"Recv Buf searches = " << postsearch << std::endl
2770 <<
"Fast Ass searches = " << fast_searches << std::endl;
2771 comm.ClearRequests();
2773 global.FunctionExit(
"Assembly Function");
2781 if(do_partitioning){
2784 *ErrOut <<
"Error: partitioning is for serial runs." << std::endl;
2789 global.FunctionEntry(
"Partitioning");
2791 std::string MeshName(infiles[0]);
2792 std::string MeshBaseName(MeshName.substr(0,MeshName.find_last_of(
".")));
2793 Inf.open(MeshName.c_str());
2796 *ErrOut <<
"Failed to open " << MeshName << std::endl;
2799 global.FunctionEntry(
"Read Mesh");
2804 number_of_nodes = nc.
Size();
2807 if(StdOut && verblevel)
2808 *StdOut <<
"Number of nodes: " << number_of_nodes << std::endl;
2811 global.FunctionExit(
"Read Mesh");
2815 if(StdOut && verblevel)
2816 *StdOut <<
"Number of elements: " << number_of_elements
2823 Inf.open(MeshName.c_str());
2826 *ErrOut <<
"Failed to open " << MeshName << std::endl;
2829 global.FunctionEntry(
"ReadCoords");
2832 global.FunctionExit(
"ReadCoords");
2833 global.FunctionEntry(
"Element Reorientation");
2835 element_being_processed <= number_of_elements;
2836 element_being_processed++)
2839 Mesh::IndexType size_of_element = econ.Esize(element_being_processed);
2844 global.FunctionExit(
"Element Reorientation");
2856 global.FunctionEntry(
"DualCon");
2857 econ.
Inverse(dc,number_of_nodes);
2858 global.FunctionExit(
"DualCon");
2863 std::vector<Mesh::SymbolicFace> sf;
2865 global.FunctionEntry(
"GetFaceConnectivites");
2866 econ.BuildFaceConnectivity(F_N,E_F,sf,dc);
2867 global.FunctionExit(
"GetFaceConnectivites");
2868 global.FunctionEntry(
"Shrinking");
2869 std::vector<Mesh::SymbolicFace>(sf).
swap(sf);
2870 global.FunctionExit(
"Shrinking");
2871 global.FunctionEntry(
"Creating Graph");
2873 std::vector<Mesh::SymbolicFace>::iterator sfi = sf.begin();
2874 while(sfi != sf.end()){
2875 if(sfi->second.first > 0){
2876 nl2[sfi->first.first-1].push_back(sfi->second.first);
2877 nl2[sfi->second.first-1].push_back(sfi->first.first);
2881 global.FunctionExit(
"Creating Graph");
2883 std::vector<idxtype> adj;
2884 std::vector<idxtype> xadj;
2885 global.FunctionEntry(
"Container2CSR");
2886 MultiContainer2CSR< std::vector< std::vector<Mesh::IndexType> >,
2887 std::vector<Mesh::IndexType>,
2888 std::vector<idxtype>,idxtype>
2890 global.FunctionExit(
"Container2CSR");
2892 std::vector<idxtype> order(number_of_elements,0);
2893 std::vector<idxtype> sizes(2,0);
2894 idxtype wgtflag = 0;
2895 idxtype numflag = 0;
2898 idxtype edgecuts = 0;
2902 std::vector<idxtype> vtxdist(2,0);
2903 vtxdist[1] = number_of_elements;
2904 std::vector<idxtype> part(number_of_elements,0);
2905 global.FunctionEntry(
"Metis");
2911 *LogOut <<
"Vtxdist:" << std::endl;
2912 DumpContents(*LogOut,vtxdist,
" ");
2913 *LogOut << std::endl <<
"Xadj:" << std::endl;
2914 DumpContents(*LogOut,xadj,
" ");
2915 *LogOut << std::endl <<
"Adj:" << std::endl;
2916 DumpContents(*LogOut,adj,
" ");
2917 *LogOut << std::endl;
2920 global.FunctionEntry(
"Renumbering");
2922 ParMETIS_V3_NodeND(&vtxdist[0],&xadj[0],&adj[0],&numflag,
2923 options,&order[0],&sizes[0],&comm);
2925 global.FunctionExit(
"Renumbering");
2927 *LogOut <<
"Order:" << std::endl;
2928 DumpContents(*LogOut,order,
" ");
2929 *LogOut << std::endl <<
"Sizes:" << std::endl;
2930 DumpContents(*LogOut,sizes,
" ");
2931 *LogOut << std::endl;
2935 ParMETIS_V3_PartKway(&vtxdist[0],&xadj[0],&adj[0],NULL,NULL,&wgtflag,
2936 &numflag,NULL,&nparts,NULL,NULL,
2937 options,&edgecuts,&part[0],&comm);
2939 METIS_PartGraphKway(&vtxdist[1],&xadj[0],&adj[0],NULL,NULL,&wgtflag,
2940 &numflag,&nparts,options,&edgecuts,&part[0]);
2942 global.FunctionExit(
"Metis");
2947 pcon.resize(number_of_elements);
2949 pcon[
i].push_back(part[
i]+1);
2956 if(StdOut && verblevel)
2957 *StdOut <<
"Number of edgecuts: " << edgecuts << std::endl;
2959 if(StdOut && verblevel)
2960 *StdOut <<
"Partition Table: ";
2961 DumpContents(*StdOut,part,
" ");
2962 if(StdOut && verblevel)
2963 *StdOut << std::endl;
2970 global.FunctionEntry(
"Dual Pcon");
2972 pcon.
Inverse(dual_pcon,nparts);
2973 global.FunctionExit(
"Dual Pcon");
2976 global.FunctionEntry(
"GetAdj nodecolors");
2980 global.FunctionExit(
"GetAdj nodecolors");
2982 global.FunctionEntry(
"Inverse colornodes");
2984 nodecolors.
Inverse(colorsofnodes,nparts);
2985 global.FunctionExit(
"Inverse colornodes");
2988 global.FunctionEntry(
"ColorNeighbors");
2991 global.FunctionExit(
"ColorNeighbors");
3004 bool report_each =
false;
3006 if(StdOut && verblevel)
3007 *StdOut <<
"Nshared nodes/partition:" << std::endl;
3008 double mean_nbnodes = 0;
3013 if(report_each && StdOut)
3014 *StdOut <<
"Partition " << iii+1 <<
": "
3015 << nbsize << std::endl;
3016 mean_nbnodes +=
static_cast<double>(nbsize);
3017 if(nbsize > max_nbnodes) max_nbnodes = nbsize;
3018 if(nbsize < min_nbnodes) min_nbnodes = nbsize;
3020 mean_nbnodes /=
static_cast<double>(nparts);
3021 if(StdOut && verblevel)
3022 *StdOut <<
"(Max/Min/Mean) shared nodes/partition: (" << max_nbnodes <<
"/"
3023 << min_nbnodes <<
"/" << mean_nbnodes <<
")" << std::endl;
3026 std::map<Mesh::IndexType,Mesh::IndexType> bnodemap;
3027 std::list<Mesh::IndexType> bnodes;
3028 global.FunctionEntry(
"Flatten");
3029 Flatten<Mesh::Connectivity,std::vector<Mesh::IndexType>,std::list<Mesh::IndexType> >
3031 global.FunctionExit(
"Flatten");
3032 global.FunctionEntry(
"SortUnique");
3035 global.FunctionExit(
"SortUnique");
3037 bn_index_map.resize(number_of_border_nodes);
3039 std::list<Mesh::IndexType>::iterator eli = bnodes.begin();
3040 while(eli != bnodes.end()){
3041 bn_index_map[
i] = *eli;
3042 bnodemap.insert(std::make_pair(*eli,i+1));
3047 global.FunctionEntry(
"MapBorderNodes");
3051 std::vector<Mesh::IndexType>,std::map<Mesh::IndexType,Mesh::IndexType> >
3052 (bordercon,bordercon_mapped,bnodemap);
3053 global.FunctionExit(
"MapBorderNodes");
3054 Mesh::Connectivity bcon_dual;
3055 bordercon_mapped.
Sync();
3056 bordercon_mapped.Inverse(bcon_dual,number_of_border_nodes);
3065 Mesh::Connectivity owner;
3066 std::vector<Mesh::IndexType> ncomnodes(nparts,0);
3067 owner.resize(number_of_border_nodes);
3068 Mesh::Connectivity::iterator bni = bcon_dual.begin();
3070 while(bni != bcon_dual.end()){
3074 if(ncomnodes[(*bni)[color-1] - 1] > ncomnodes[(*bni)[ci]-1])
3076 std::vector<Mesh::IndexType>::iterator bnici = bni->begin();
3081 owner[ownind++].push_back(*bnici);
3082 ncomnodes[*bnici-1]++;
3086 Mesh::Connectivity dual_owner;
3088 owner.
Inverse(dual_owner,nparts);
3090 min_nbnodes = number_of_nodes;
3095 if(StdOut && verblevel)
3096 *StdOut <<
"Partition " << iii+1 <<
": "
3097 << nbsize << std::endl;
3098 mean_nbnodes +=
static_cast<double>(nbsize);
3099 if(nbsize > max_nbnodes) max_nbnodes = nbsize;
3100 if(nbsize < min_nbnodes) min_nbnodes = nbsize;
3102 mean_nbnodes /=
static_cast<double>(nparts);
3103 if(StdOut && verblevel)
3104 *StdOut <<
"(Max/Min/Mean) recvd nodes/partition: (" << max_nbnodes <<
"/"
3105 << min_nbnodes <<
"/" << mean_nbnodes <<
")" << std::endl;
3109 std::vector<Mesh::PartInfo> ColorInfo(nparts);
3111 ColorInfo[colind].part = colind+1;
3112 ColorInfo[colind].nelem = dual_pcon[colind].size();
3113 ColorInfo[colind].nborder = colorneighbors[colind].size();
3114 ColorInfo[colind].nnodes = colorsofnodes[colind].size();
3115 ColorInfo[colind].nshared = bordercon[colind].size();
3116 ColorInfo[colind].nown = dual_owner[colind].size();
3119 global.FunctionEntry(
"Colorization");
3120 global.FunctionEntry(
"Colorization 1");
3123 Mesh::Connectivity PartitionedNodes;
3124 PartitionedNodes.resize(Nparts);
3126 Primitive::MultiContainer<Mesh::IndexType,Mesh::IndexType>::VecMap pglob2loc;
3127 pglob2loc.resize(Nparts);
3128 psize.resize(Nparts,0);
3131 if(nodecolors.
Esize(node_id) == 1){
3133 PartitionedNodes[thecolor-1].push_back(node_id);
3134 psize[thecolor-1]++;
3135 pglob2loc[thecolor-1].insert(std::make_pair(node_id,psize[thecolor-1]));
3141 std::vector<Mesh::IndexType>::iterator doi = dual_owner[jjj].begin();
3142 while(doi != dual_owner[jjj].end()){
3145 PartitionedNodes[jjj].push_back(global_node_id);
3147 pglob2loc[jjj].insert(std::make_pair(global_node_id,psize[jjj]));
3156 global.FunctionExit(
"Colorization 1");
3159 global.FunctionEntry(
"Colorization 2");
3161 Primitive::MultiContainer<Mesh::Border>::VecVec ColorBorders;
3163 ColorBorders.resize(nparts);
3164 colormap.resize(nparts);
3166 ColorBorders[iii].resize(colorneighbors[iii].size());
3167 Mesh::IndexVec::iterator cni = colorneighbors[iii].begin();
3169 while(cni != colorneighbors[iii].end()){
3170 colormap[iii].insert(std::make_pair(*cni,colorind+1));
3171 ColorBorders[iii][colorind].rpart = *cni;
3176 global.FunctionExit(
"Colorization 2");
3178 global.FunctionEntry(
"Colorization 3");
3184 Mesh::IndexVec::iterator nrcvIt = dual_owner[jjj].begin();
3185 while(nrcvIt != dual_owner[jjj].end()){
3189 Mesh::IndexVec::iterator ncIt = nodecolors[global_bn_id-1].begin();
3190 while(ncIt != nodecolors[global_bn_id-1].end()){
3192 if(remote_color_id != this_color){
3195 assert(ColorBorders[jjj][local_border_id-1].rpart == remote_color_id);
3196 ColorBorders[jjj][local_border_id-1].nrecv.push_back(global_bn_id);
3198 Mesh::IndexType remote_border_id = colormap[remote_color_id-1][this_color];
3199 assert(ColorBorders[remote_color_id-1][remote_border_id-1].rpart == this_color);
3200 ColorBorders[remote_color_id-1][remote_border_id-1].nsend.push_back(global_bn_id);
3206 global.FunctionExit(
"Colorization 3");
3212 global.FunctionEntry(
"Colorization 4");
3214 std::list<Mesh::IndexType> sendnodes;
3217 std::vector<Mesh::IndexType>::iterator bni = ColorBorders[jjj][iii].nsend.begin();
3218 while(bni != ColorBorders[jjj][iii].nsend.end())
3219 sendnodes.push_back(*bni++);
3223 std::list<Mesh::IndexType>::iterator sni = sendnodes.begin();
3224 while(sni != sendnodes.end()){
3226 PartitionedNodes[jjj].push_back(send_node_id);
3228 pglob2loc[jjj].insert(std::make_pair(send_node_id,psize[jjj]));
3231 global.FunctionExit(
"Colorization 4");
3234 global.FunctionEntry(
"Color validation");
3236 assert(psize[jjj] == ColorInfo[jjj].nnodes);
3238 global.FunctionExit(
"Color validation");
3239 global.FunctionExit(
"Colorization");
3240 global.FunctionEntry(
"Writing Partitions");
3242 global.FunctionEntry(
"Read Coords");
3244 Inf.open(MeshName.c_str());
3247 *ErrOut <<
"Failed to open " << MeshName << std::endl;
3252 global.FunctionExit(
"Read Coords");
3253 std::vector<std::string> nodal_props(number_of_nodes);
3254 std::vector<std::string> elemental_props(number_of_elements);
3255 bool mesh_has_properties =
false;
3256 std::string propname = MeshBaseName +
".prop";
3257 Inf.open(propname.c_str());
3259 mesh_has_properties =
true;
3260 global.FunctionEntry(
"Read Properties");
3261 for(
unsigned int propcount = 0;propcount < number_of_nodes;propcount++)
3262 std::getline(Inf,nodal_props[propcount]);
3263 std::getline(Inf,elemental_props[0]);
3264 for(
unsigned int propcount = 0;propcount < number_of_elements;propcount++)
3265 std::getline(Inf,elemental_props[propcount]);
3267 global.FunctionExit(
"Read Properties");
3270 std::ostringstream Ostr;
3271 Ostr << MeshBaseName <<
"." << jjj+1 <<
".info";
3272 std::ofstream OutFile;
3273 std::ofstream OutProp;
3274 OutFile.open(Ostr.str().c_str());
3275 if(mesh_has_properties){
3277 Ostr << MeshBaseName <<
"." << jjj+1 <<
".prop";
3278 OutProp.open(Ostr.str().c_str());
3280 OutFile << Nparts << std::endl << jjj+1 << std::endl
3281 << ColorInfo[jjj].nelem << std::endl
3282 << ColorInfo[jjj].nnodes << std::endl
3283 << ColorInfo[jjj].nborder << std::endl
3284 << ColorInfo[jjj].nshared << std::endl
3285 << ColorInfo[jjj].nown << std::endl;
3288 Ostr << MeshBaseName <<
"." << jjj+1 <<
".pmesh";
3289 OutFile.open(Ostr.str().c_str());
3291 OutFile << ColorInfo[jjj].nnodes << std::endl;
3294 OutFile << nc.x(node_id) <<
" " << nc.y(node_id) <<
" "
3295 << nc.z(node_id) << std::endl;
3297 OutProp << nodal_props[node_id-1] << std::endl;
3300 OutProp << std::endl;
3302 OutFile << ColorInfo[jjj].nelem << std::endl;
3305 std::vector<Mesh::IndexType>::iterator eni = econ[eid-1].begin();
3306 while(eni != econ[eid-1].end()){
3307 OutFile << pglob2loc[jjj][*eni];
3308 if(eni != econ[eid-1].end())
3312 OutFile << std::endl;
3314 OutProp << elemental_props[eid-1] << std::endl;
3319 OutFile << ColorInfo[jjj].nborder << std::endl;
3321 OutFile << ColorBorders[jjj][iii].rpart <<
" "
3322 << ColorBorders[jjj][iii].nrecv.size() <<
" "
3323 << ColorBorders[jjj][iii].nsend.size() << std::endl;
3324 std::vector<Mesh::IndexType>::iterator rni = ColorBorders[jjj][iii].nrecv.begin();
3325 while(rni != ColorBorders[jjj][iii].nrecv.end()){
3326 OutFile << pglob2loc[jjj][*rni] <<
" " << *rni << std::endl;
3329 rni = ColorBorders[jjj][iii].nsend.begin();
3330 while(rni != ColorBorders[jjj][iii].nsend.end()){
3331 OutFile << pglob2loc[jjj][*rni] <<
" " << *rni << std::endl;
3337 global.FunctionExit(
"Writing Partitions");
3338 global.FunctionExit(
"Partitioning");
3863 *ErrOut <<
"Error: Cloning is a serial operation." << std::endl;
3866 if(infiles.empty()){
3868 *ErrOut <<
"Error: Nothing to clone." << std::endl;
3873 global.FunctionEntry(
"Cloning");
3875 std::string MeshName(infiles[0]);
3877 if(infiles.size() > 1){
3878 std::istringstream Instr(infiles[1]);
3883 if(StdOut && verblevel)
3884 *StdOut <<
"Cloning " << MeshName <<
" into " << npartitions <<
" partitions."
3886 Inf.open(MeshName.c_str());
3889 *ErrOut <<
"Failed to open " << MeshName << std::endl;
3892 global.FunctionEntry(
"Read Mesh");
3896 number_of_nodes = nc.
Size();
3897 std::vector<double> bounds(6,0.0);
3899 if(StdOut && verblevel)
3900 *StdOut <<
"Number of nodes: " << number_of_nodes << std::endl
3901 <<
"Mesh Bounds: (" << bounds[0] <<
"," << bounds[1]
3902 <<
") (" << bounds[2] <<
"," << bounds[3]
3903 <<
") (" << bounds[4] <<
"," << bounds[5] <<
")" << std::endl;
3904 double Xmin = bounds[0];
3905 double Xmax = bounds[1];
3911 global.FunctionExit(
"Read Mesh");
3913 if(StdOut && verblevel)
3914 *StdOut <<
"Number of elements: " << number_of_elements
3916 global.FunctionEntry(
"Forming Clones");
3918 std::vector<Mesh::IndexType> left_owned;
3919 std::vector<Mesh::IndexType> left_remote;
3920 std::vector<Mesh::IndexType> right_owned;
3921 std::vector<Mesh::IndexType> right_remote;
3922 std::vector<Mesh::IndexType> non_boundary;
3923 bool left_polarity =
true;
3924 bool right_polarity =
false;
3926 if(nc.x(nn) == Xmin){
3928 left_owned.push_back(nn);
3929 left_polarity =
false;
3932 left_remote.push_back(nn);
3933 left_polarity =
true;
3936 else if(nc.x(nn) == Xmax){
3938 right_owned.push_back(nn);
3939 right_polarity =
false;
3942 right_remote.push_back(nn);
3943 right_polarity =
true;
3947 non_boundary.push_back(nn);
3956 if(StdOut && verblevel)
3957 *StdOut <<
"Number of internal nodes/partition: " << nnbn << std::endl
3958 <<
"Number of shared nodes/partition: " << nshared_nodes << std::endl;
3960 global.FunctionEntry(
"Mapping Clone Genes");
3961 std::vector<Mesh::IndexType> NodeMap(number_of_nodes,0);
3962 std::vector<Mesh::IndexType>::iterator
ni = non_boundary.begin();
3964 while(ni != non_boundary.end())
3965 NodeMap[*ni++ - 1] = node_id++;
3966 ni = left_owned.begin();
3967 while(ni != left_owned.end())
3968 NodeMap[*ni++ - 1] = node_id++;
3969 ni = right_owned.begin();
3970 while(ni != right_owned.end())
3971 NodeMap[*ni++ - 1] = node_id++;
3972 ni = left_remote.begin();
3973 while(ni != left_remote.end())
3974 NodeMap[*ni++ - 1] = node_id++;
3975 ni = right_remote.begin();
3976 while(ni != right_remote.end())
3977 NodeMap[*ni++ - 1] = node_id++;
3979 assert(node_id == number_of_nodes);
3980 global.FunctionExit(
"Mapping Clone Genes");
3981 global.FunctionExit(
"Forming Clones");
3982 global.FunctionEntry(
"Writing Clones");
3984 std::ostringstream Ostr;
3985 Ostr << MeshName <<
"." << jjj+1 <<
".info";
3986 std::ofstream OutFile;
3987 OutFile.open(Ostr.str().c_str());
3988 OutFile << N << std::endl << jjj+1 << std::endl
3989 << number_of_elements << std::endl
3990 << number_of_nodes << std::endl
3992 << nshared_nodes << std::endl
3993 << nown_left+nown_right << std::endl;
3996 Ostr << MeshName <<
"." << jjj+1 <<
".pmesh";
3997 OutFile.open(Ostr.str().c_str());
3999 OutFile << number_of_nodes << std::endl;
4000 std::vector<Mesh::IndexType>::iterator nbni = non_boundary.begin();
4001 while(nbni != non_boundary.end()){
4002 OutFile << nc.x(*nbni) <<
" " << nc.y(*nbni) <<
" "
4003 << nc.z(*nbni) << std::endl;
4006 nbni = left_owned.begin();
4007 while(nbni != left_owned.end()){
4008 OutFile << nc.x(*nbni) <<
" " << nc.y(*nbni) <<
" "
4009 << nc.z(*nbni) << std::endl;
4012 nbni = right_owned.begin();
4013 while(nbni != right_owned.end()){
4014 OutFile << nc.x(*nbni) <<
" " << nc.y(*nbni) <<
" "
4015 << nc.z(*nbni) << std::endl;
4018 nbni = left_remote.begin();
4019 while(nbni != left_remote.end()){
4020 OutFile << nc.x(*nbni) <<
" " << nc.y(*nbni) <<
" "
4021 << nc.z(*nbni) << std::endl;
4024 nbni = right_remote.begin();
4025 while(nbni != right_remote.end()){
4026 OutFile << nc.x(*nbni) <<
" " << nc.y(*nbni) <<
" "
4027 << nc.z(*nbni) << std::endl;
4031 OutFile << number_of_elements << std::endl;
4033 std::vector<Mesh::IndexType>::iterator eni = econ[iii].begin();
4034 while(eni != econ[iii].end()){
4035 OutFile << NodeMap[*eni-1];
4036 if(eni != econ[iii].end())
4040 OutFile << std::endl;
4043 OutFile << 2 << std::endl;
4044 OutFile << (jjj == 0 ? N : jjj) <<
" "
4046 << nleft - nown_left << std::endl;
4047 std::vector<Mesh::IndexType>::iterator rni = left_owned.begin();
4048 while(rni != left_owned.end()){
4049 OutFile << NodeMap[*rni-1] <<
" " << *rni << std::endl;
4052 rni = left_remote.begin();
4053 while(rni != left_remote.end()){
4054 OutFile << NodeMap[*rni-1] <<
" " << *rni << std::endl;
4057 OutFile << (jjj == (N-1) ? 1 : jjj+2) <<
" "
4058 << nown_right <<
" "
4059 << nright - nown_right << std::endl;
4060 rni = right_owned.begin();
4061 while(rni != right_owned.end()){
4062 OutFile << NodeMap[*rni-1] <<
" " << *rni << std::endl;
4065 rni = right_remote.begin();
4066 while(rni != right_remote.end()){
4067 OutFile << NodeMap[*rni-1] <<
" " << *rni << std::endl;
4072 global.FunctionExit(
"Writing Clones");
4073 global.FunctionExit(
"Cloning");
4077 *LogOut <<
"All processors made it to the end." << std::endl;
4078 global.FunctionExit(
"main");
4081 *LogOut <<
"All processors made it to the end." << std::endl;
4084 if(StdOut && verblevel)
4086 global.Report(*StdOut);
4114 virtual int f1(){
return 0; };
4115 virtual int f2(){
return 0; };
4119 template <
typename DataType>
4125 template <
typename DataType>
4148 std::vector<TestBasePtr> TestVector;
4152 TestVector.push_back(&t11);
4153 TestVector.push_back(&t12);
4154 TestVector.push_back(&t21);
void swap(int &a, int &b)
here we put it at the!beginning of the common block The point to point and collective!routines know about but MPI_TYPE_STRUCT as yet does not!MPI_STATUS_IGNORE and MPI_STATUSES_IGNORE are similar objects!Until the underlying MPI library implements the C version of these are declared as arrays of MPI_STATUS_SIZE!The types and are OPTIONAL!Their values are zero if they are not available Note that!using these reduces the portability of MPI_IO INTEGER MPI_BOTTOM INTEGER MPI_DOUBLE_PRECISION INTEGER MPI_LOGICAL INTEGER MPI_2REAL INTEGER MPI_2DOUBLE_COMPLEX INTEGER MPI_LB INTEGER MPI_WTIME_IS_GLOBAL INTEGER MPI_COMM_WORLD
int RegisterCommBuffers(std::vector< Mesh::Border > &borders, Comm::CommunicatorObject &comm)
void GetAdjacent(Connectivity &rl, Connectivity &dc, IndexType n=0, bool sortit=false)
General connectivity object.
std::vector< IndexType > _sizes
void int int REAL REAL * y
ComLineObject for testing app.
Vector_n max(const Array_n_const &v1, const Array_n_const &v2)
void GlobalDofReMapExchange(Mesh::Connectivity &ec, Mesh::Connectivity &NodalDofs, Mesh::Connectivity &ElementDofs, Mesh::Connectivity &RemoteNodalDofs, std::vector< Mesh::Border > &borders, Mesh::PartInfo &info, std::vector< Mesh::IndexType > &order, Comm::CommunicatorObject &comm, std::ostream *Out, bool verbose)
MeshTestComLine(const char *args[])
void GetNeighborhood(NeighborHood &, const Connectivity &dc, IndexType size=0)
real *8 function offset(vNorm, x2, y2, z2)
bool ShapeOK(std::vector< IndexType > &ec, NodalCoordinates &nc) const
void MapElements(OuterCont &src, OutCont &trg, MapType &m)
IRAD::Primitive::MultiContainer< IndexType, IndexType >::VecMap VecMap
std::vector< IndexType > IndexVec
IndexType GetTotalSize(OuterContType &con)
Return the total number of entries in a multicontainer.
void GlobalDofExchange(std::vector< Mesh::Border > &borders, Mesh::Connectivity &NodalDofs, Mesh::Connectivity &RemoteNodalDofs, Mesh::PartInfo &info, Comm::CommunicatorObject &comm, std::ostream *Out, bool verbose)
double & z(IndexType n=1)
void int int int REAL REAL REAL * z
void ReOrient(std::vector< IndexType > &ec)
void matrix_mode(IndexType offset=0)
void Inverse(Connectivity &, IndexType nnodes=0) const
bool Inverted(std::vector< IndexType > &ec, NodalCoordinates &nc) const
Mesh::IndexType doffset
number of local nodes (convenience)
IndexType Esize(IndexType n) const
Mesh::IndexType part
total number of partitions
void BuildBorderStiffness(Mesh::Connectivity &ec, std::vector< Mesh::Border > &borders, Mesh::Connectivity &NodalDofs, Mesh::Connectivity &ElementDofs, Mesh::Connectivity &RemoteNodalDofs, Mesh::PartInfo &info, Comm::CommunicatorObject &comm, std::ostream *Out, bool verbose)
std::vector< DataType > DerivedNative
unsigned int AllocateCommBuffers(std::vector< Mesh::Border > &borders, Mesh::Connectivity &NodalDofs, std::ostream *Out, bool verbose)
Mesh::IndexType nnodes
total number of elems
double & x(IndexType n=1)
void TestMPI(std::vector< Mesh::Border > &borders, Mesh::Connectivity &NodalDofs, Mesh::Connectivity &RemoteNodalDofs, Mesh::PartInfo &info, Comm::CommunicatorObject &comm, std::ostream *Out, bool verbose)
void graph_mode(IndexType offset=0)
int main(int argc, char *argv[])
Vector_n min(const Array_n_const &v1, const Array_n_const &v2)
Mesh::IndexType nborder
total number of nodes
void InverseDegenerate(Connectivity &, IndexType nnodes=0) const
unsigned long time()
Get the value of a system timer with a millisecond precision.
Mesh::IndexType nlocal
number of shared nodes owned
void CountDofs(Mesh::Connectivity &ElementDofs, Mesh::Connectivity &NodalDofs, Mesh::PartInfo &info, Mesh::IndexType &nglobaldof, Mesh::IndexType &nremotedof)
Mesh::IndexType nelem
partition id
**********************************************************************Rocstar Simulation Suite Illinois Rocstar LLC All rights reserved ****Illinois Rocstar LLC IL **www illinoisrocstar com **sales illinoisrocstar com WITHOUT WARRANTY OF ANY **EXPRESS OR INCLUDING BUT NOT LIMITED TO THE WARRANTIES **OF FITNESS FOR A PARTICULAR PURPOSE AND **NONINFRINGEMENT IN NO EVENT SHALL THE CONTRIBUTORS OR **COPYRIGHT HOLDERS BE LIABLE FOR ANY DAMAGES OR OTHER WHETHER IN AN ACTION OF TORT OR **Arising OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE **USE OR OTHER DEALINGS WITH THE SOFTWARE **********************************************************************INTERFACE USE ModDataTypes USE nvals
std::vector< DataType > DerivedNative
double rand()
Return a random variable between [0,1] with respect to an uniform distribution.
void int int REAL REAL REAL *z blockDim dim * ni
void GetCoordinateBounds(NodalCoordinates &nc, std::vector< double > &)
void GetStatistics(std::ostream &Ostr, Mesh::Connectivity &con)
IRAD::Primitive::IndexType IndexType
void info()
Print informations about CImg environement variables.
here we put it at the!beginning of the common block The point to point and collective!routines know about but MPI_TYPE_STRUCT as yet does not!MPI_STATUS_IGNORE and MPI_STATUSES_IGNORE are similar objects!Until the underlying MPI library implements the C version of these are declared as arrays of MPI_STATUS_SIZE!The types and are OPTIONAL!Their values are zero if they are not available Note that!using these reduces the portability of MPI_IO INTEGER MPI_BOTTOM INTEGER MPI_DOUBLE_PRECISION INTEGER MPI_LOGICAL INTEGER MPI_2REAL INTEGER MPI_2DOUBLE_COMPLEX INTEGER MPI_LB INTEGER MPI_WTIME_IS_GLOBAL INTEGER MPI_GROUP_EMPTY INTEGER MPI_SUM
Mesh::IndexType nown
number of shared nodes
Mesh::IndexType nshared
number of borders
double & y(IndexType n=1)