Thanks to visit codestin.com
Credit goes to glvis.github.io

GLVis  v4.2
Accurate and flexible finite element visualization
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
glvis.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
2 // at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3 // LICENSE and NOTICE for details. LLNL-CODE-443271.
4 //
5 // This file is part of the GLVis visualization tool and library. For more
6 // information and source code availability see https://glvis.org.
7 //
8 // GLVis is free software; you can redistribute it and/or modify it under the
9 // terms of the BSD-3 license. We welcome feedback and contributions, see file
10 // CONTRIBUTING.md for details.
11 
12 
13 // GLVis - an OpenGL visualization server based on the MFEM library
14 
15 #include <limits>
16 #include <iostream>
17 #include <fstream>
18 #include <string>
19 #include <cstdio>
20 #include <cstring>
21 #include <ctime>
22 
23 // SDL may redefine main() as SDL_main() ostensibly to ease portability.
24 // (WinMain() instead of main() is used as the entry point in a non-console
25 // Windows program.)
26 //
27 // We must instead define SDL_MAIN_HANDLED so that SDL doesn't do this
28 // substitution, since we need a console to accept certain user input from
29 // stdin.
30 #ifdef _WIN32
31 #define SDL_MAIN_HANDLED
32 #endif
33 
34 #include "mfem.hpp"
35 #include "lib/palettes.hpp"
36 #include "lib/visual.hpp"
37 #include "lib/stream_reader.hpp"
38 
39 using namespace std;
40 using namespace mfem;
41 
42 const char *string_none = "(none)";
43 const char *string_default = "(default)";
44 
45 // Global variables for command line arguments
46 const char *mesh_file = string_none;
47 const char *sol_file = string_none;
48 const char *vec_sol_file = string_none;
49 const char *gfunc_file = string_none;
50 const char *arg_keys = string_none;
51 int pad_digits = 6;
52 int gf_component = -1;
53 bool keep_attr = false;
54 int window_x = 0; // not a command line option
55 int window_y = 0; // not a command line option
56 int window_w = 400;
57 int window_h = 350;
60 thread_local string plot_caption;
61 thread_local string extra_caption;
62 bool secure = socketstream::secure_default;
63 
64 // Global variables
65 int input = 1;
67 thread_local VisualizationSceneScalarData *vs = NULL;
68 extern thread_local GLVisCommand* glvis_command;
69 thread_local communication_thread *comm_thread = NULL;
70 
71 thread_local GeometryRefiner GLVisGeometryRefiner;
72 
73 const char *window_titles[] = { "GLVis [scalar data]",
74  "GLVis [vector data]", "GLVis [mesh]"
75  };
76 istream *script = NULL;
77 int scr_running = 0;
78 int scr_level = 0;
79 Vector *init_nodes = NULL;
81 
82 extern char **environ;
83 
84 using StreamCollection = vector<unique_ptr<istream>>;
85 
86 void PrintSampleUsage(ostream &out);
87 
88 // read the mesh and the solution from a file
89 void ReadSerial(StreamState& state);
90 
91 // choose grid function component and set the input flag
92 void SetGridFunction(StreamState& state);
93 
94 // read the mesh and the solution from multiple files
95 void ReadParallel(int np, StreamState& state);
96 
97 int ReadParMeshAndGridFunction(int np, const char *mesh_prefix,
98  const char *sol_prefix, StreamState& state,
99  int keep_attr);
100 
101 int ReadInputStreams(StreamState& state, const StreamCollection& input_streams);
102 
103 // Visualize the data in the global variables mesh, sol/grid_f, etc
104 // 0 - scalar data, 1 - vector data, 2 - mesh only, (-1) - unknown
105 bool GLVisInitVis(int field_type, StreamCollection input_streams)
106 {
107  if (field_type < 0 || field_type > 2)
108  {
109  return false;
110  }
111 
112  const char *win_title = (window_title == string_default) ?
113  window_titles[field_type] : window_title;
114 
116  {
117  cerr << "Initializing the visualization failed." << endl;
118  return false;
119  }
120 
121  if (input_streams.size() > 0)
122  {
125  comm_thread = new communication_thread(std::move(input_streams), glvis_command);
126  }
127 
128  double mesh_range = -1.0;
129  if (field_type == 0 || field_type == 2)
130  {
131  if (stream_state.grid_f)
132  {
133  stream_state.grid_f->GetNodalValues(stream_state.sol);
134  }
135  if (stream_state.mesh->SpaceDimension() == 2)
136  {
138  if (stream_state.normals.Size() > 0)
139  {
142  }
143  else
144  {
146  }
147  if (stream_state.grid_f)
148  {
150  }
151  if (field_type == 2)
152  {
154  vs->SetLight(false);
155  vs->Zoom(1.8);
156  // Use the 'bone' palette when visualizing a 2D mesh only (otherwise
157  // the 'jet-like' palette is used in 2D, see vssolution.cpp).
158  vs->palette.SetIndex(4);
159  }
160  }
161  else if (stream_state.mesh->SpaceDimension() == 3)
162  {
165  stream_state.sol);
166  if (stream_state.grid_f)
167  {
168  vss->SetGridFunction(stream_state.grid_f.get());
169  }
170  if (field_type == 2)
171  {
172  if (stream_state.mesh->Dimension() == 3)
173  {
174  // Use the 'white' palette when visualizing a 3D volume mesh only
175  vss->palette.SetIndex(11);
176  vss->SetLightMatIdx(4);
177  }
178  else
179  {
180  // Use the 'bone' palette when visualizing a surface mesh only
181  vss->palette.SetIndex(4);
182  }
183  // Otherwise, the 'vivid' palette is used in 3D see vssolution3d.cpp
184  vss->ToggleDrawAxes();
185  vss->ToggleDrawMesh();
186  }
187  }
188  if (field_type == 2)
189  {
190  if (stream_state.grid_f)
191  {
192  mesh_range = stream_state.grid_f->Max() + 1.0;
193  }
194  else
195  {
196  mesh_range = stream_state.sol.Max() + 1.0;
197  }
198  }
199  }
200  else if (field_type == 1)
201  {
202  if (stream_state.mesh->SpaceDimension() == 2)
203  {
204  if (stream_state.grid_f)
205  {
207  }
208  else
209  {
212  }
213  }
214  else if (stream_state.mesh->SpaceDimension() == 3)
215  {
216  if (stream_state.grid_f)
217  {
221  }
222  else
223  {
226  }
227  }
228  }
229 
230  if (vs)
231  {
232  // increase the refinement factors if visualizing a GridFunction
233  if (stream_state.grid_f)
234  {
235  vs->AutoRefine();
236  vs->SetShading(2, true);
237  }
238  if (mesh_range > 0.0)
239  {
240  vs->SetValueRange(-mesh_range, mesh_range);
241  vs->SetAutoscale(0);
242  }
243  if (stream_state.mesh->SpaceDimension() == 2 && field_type == 2)
244  {
246  }
247  else
248  {
250  }
251  }
252  return true;
253 }
254 
256 {
257  RunVisualization(); // deletes vs
258  vs = NULL;
259  if (glvis_command)
260  {
262  delete comm_thread;
263  delete glvis_command;
264  glvis_command = NULL;
265  }
266  cout << "GLVis window closed." << endl;
267 }
268 
269 int ScriptReadSolution(istream &scr, StreamState& state)
270 {
271  string mword,sword;
272 
273  cout << "Script: solution: " << flush;
274  // read the mesh
275  scr >> ws >> mword; // mesh filename (can't contain spaces)
276  cout << "mesh: " << mword << "; " << flush;
277  named_ifgzstream imesh(mword.c_str());
278  if (!imesh)
279  {
280  cout << "Can not open mesh file: " << mword << endl;
281  return 1;
282  }
283  state.mesh.reset(new Mesh(imesh, 1, 0, state.fix_elem_orient));
284 
285  // read the solution (GridFunction)
286  scr >> ws >> sword;
287  if (sword == mword) // mesh and solution in the same file
288  {
289  cout << "solution: " << mword << endl;
290  state.grid_f.reset(new GridFunction(state.mesh.get(), imesh));
291  }
292  else
293  {
294  cout << "solution: " << sword << endl;
295  ifgzstream isol(sword.c_str());
296  if (!isol)
297  {
298  cout << "Can not open solution file: " << sword << endl;
299  return 2;
300  }
301  state.grid_f.reset(new GridFunction(state.mesh.get(), isol));
302  }
303 
304  state.Extrude1DMeshAndSolution();
305 
306  return 0;
307 }
308 
309 int ScriptReadParSolution(istream &scr, StreamState& state)
310 {
311  int np, scr_keep_attr, err_read;
312  string mesh_prefix, sol_prefix;
313 
314  cout << "Script: psolution: " << flush;
315  // read number of processors
316  scr >> np;
317  cout << "# processors: " << np << "; " << flush;
318  // read the mesh prefix
319  scr >> ws >> mesh_prefix; // mesh prefix (can't contain spaces)
320  cout << "mesh prefix: " << mesh_prefix << "; " << flush;
321  scr >> ws >> scr_keep_attr;
322  if (scr_keep_attr)
323  {
324  cout << "(real attributes); " << flush;
325  }
326  else
327  {
328  cout << "(processor attributes); " << flush;
329  }
330  // read the solution prefix
331  scr >> ws >> sol_prefix;
332  cout << "solution prefix: " << sol_prefix << endl;
333 
334  err_read = ReadParMeshAndGridFunction(np, mesh_prefix.c_str(),
335  sol_prefix.c_str(), state, scr_keep_attr);
336  if (!err_read)
337  {
338  state.Extrude1DMeshAndSolution();
339  }
340  return err_read;
341 }
342 
343 int ScriptReadDisplMesh(istream &scr, StreamState& state)
344 {
345  StreamState meshstate;
346  string word;
347 
348  cout << "Script: mesh: " << flush;
349  scr >> ws >> word;
350  {
351  named_ifgzstream imesh(word.c_str());
352  if (!imesh)
353  {
354  cout << "Can not open mesh file: " << word << endl;
355  return 1;
356  }
357  cout << word << endl;
358  meshstate.mesh.reset(new Mesh(imesh, 1, 0, state.fix_elem_orient));
359  }
360  meshstate.Extrude1DMeshAndSolution();
361  Mesh* const m = meshstate.mesh.get();
362  if (init_nodes == NULL)
363  {
364  init_nodes = new Vector;
365  meshstate.mesh->GetNodes(*init_nodes);
366  state.mesh = NULL;
367  state.grid_f = NULL;
368  }
369  else
370  {
371  FiniteElementCollection *vfec = NULL;
372  FiniteElementSpace *vfes;
373  vfes = (FiniteElementSpace *)m->GetNodalFESpace();
374  if (vfes == NULL)
375  {
376  vfec = new LinearFECollection;
377  vfes = new FiniteElementSpace(m, vfec, m->SpaceDimension());
378  }
379 
380  meshstate.grid_f.reset(new GridFunction(vfes));
381  GridFunction * const g = meshstate.grid_f.get();
382  if (vfec)
383  {
384  g->MakeOwner(vfec);
385  }
386  m->GetNodes(*g);
387  if (g->Size() == init_nodes->Size())
388  {
389  subtract(*init_nodes, *g, *g);
390  }
391  else
392  {
393  cout << "Script: incompatible meshes!" << endl;
394  *g = 0.0;
395  }
396 
397  state.mesh = std::move(meshstate.mesh);
398  state.grid_f = std::move(meshstate.grid_f);
399  }
400 
401  return 0;
402 }
403 
405 {
406  if (!script)
407  {
408  cout << "No script stream defined! (Bug?)" << endl;
409  return;
410  }
411 
412  istream &scr = *script;
413  string word;
414  int done_one_command = 0;
415  while (!done_one_command)
416  {
417  scr >> ws;
418  if (!scr.good())
419  {
420  cout << "End of script." << endl;
421  scr_level = 0;
422  return;
423  }
424  if (scr.peek() == '#')
425  {
426  getline(scr, word);
427  continue;
428  }
429  scr >> word;
430  if (word == "{")
431  {
432  scr_level++;
433  }
434  else if (word == "}")
435  {
436  scr_level--;
437  if (scr_level < 0)
438  {
439  scr_level = 0;
440  }
441  }
442  else if (word == "solution" || word == "mesh" || word == "psolution")
443  {
444  StreamState new_state;
445 
446  if (word == "solution")
447  {
448  if (ScriptReadSolution(scr, new_state))
449  {
450  done_one_command = 1;
451  continue;
452  }
453  }
454  else if (word == "mesh")
455  {
456  if (ScriptReadDisplMesh(scr, new_state))
457  {
458  done_one_command = 1;
459  continue;
460  }
461  if (new_state.mesh == NULL)
462  {
463  cout << "Script: unexpected 'mesh' command!" << endl;
464  done_one_command = 1;
465  continue;
466  }
467  }
468  else if (word == "psolution")
469  {
470  if (ScriptReadParSolution(scr, new_state))
471  {
472  done_one_command = 1;
473  continue;
474  }
475  }
476 
477  if (stream_state.SetNewMeshAndSolution(std::move(new_state), vs))
478  {
479  MyExpose();
480  }
481  else
482  {
483  cout << "Different type of mesh / solution." << endl;
484  }
485  }
486  else if (word == "screenshot")
487  {
488  scr >> ws >> word;
489 
490  cout << "Script: screenshot: " << flush;
491 
492  if (Screenshot(word.c_str(), true))
493  {
494  cout << "Screenshot(" << word << ") failed." << endl;
495  done_one_command = 1;
496  continue;
497  }
498  cout << "-> " << word << endl;
499 
500  if (scr_min_val > vs->GetMinV())
501  {
502  scr_min_val = vs->GetMinV();
503  }
504  if (scr_max_val < vs->GetMaxV())
505  {
506  scr_max_val = vs->GetMaxV();
507  }
508  }
509  else if (word == "viewcenter")
510  {
511  scr >> vs->ViewCenterX >> vs->ViewCenterY;
512  cout << "Script: viewcenter: "
513  << vs->ViewCenterX << ' ' << vs->ViewCenterY << endl;
514  MyExpose();
515  }
516  else if (word == "perspective")
517  {
518  scr >> ws >> word;
519  cout << "Script: perspective: " << word;
520  if (word == "off")
521  {
523  }
524  else if (word == "on")
525  {
527  }
528  else
529  {
530  cout << '?';
531  }
532  cout << endl;
533  MyExpose();
534  }
535  else if (word == "light")
536  {
537  scr >> ws >> word;
538  cout << "Script: light: " << word;
539  if (word == "off")
540  {
541  vs->SetLight(false);
542  }
543  else if (word == "on")
544  {
545  vs->SetLight(true);
546  }
547  else
548  {
549  cout << '?';
550  }
551  cout << endl;
552  MyExpose();
553  }
554  else if (word == "view")
555  {
556  double theta, phi;
557  scr >> theta >> phi;
558  cout << "Script: view: " << theta << ' ' << phi << endl;
559  vs->SetView(theta, phi);
560  MyExpose();
561  }
562  else if (word == "zoom")
563  {
564  double factor;
565  scr >> factor;
566  cout << "Script: zoom: " << factor << endl;
567  vs->Zoom(factor);
568  MyExpose();
569  }
570  else if (word == "shading")
571  {
572  scr >> ws >> word;
573  cout << "Script: shading: " << flush;
574  int s = -1;
575  if (word == "flat")
576  {
577  s = 0;
578  }
579  else if (word == "smooth")
580  {
581  s = 1;
582  }
583  else if (word == "cool")
584  {
585  s = 2;
586  }
587  if (s != -1)
588  {
589  vs->SetShading(s, false);
590  cout << word << endl;
591  MyExpose();
592  }
593  else
594  {
595  cout << word << " ?" << endl;
596  }
597  }
598  else if (word == "subdivisions")
599  {
600  int t, b;
601  scr >> t >> b;
602  cout << "Script: subdivisions: " << flush;
603  vs->SetRefineFactors(t, b);
604  cout << t << ' ' << b << endl;
605  MyExpose();
606  }
607  else if (word == "valuerange")
608  {
609  double min, max;
610  scr >> min >> max;
611  cout << "Script: valuerange: " << flush;
612  vs->SetValueRange(min, max);
613  cout << min << ' ' << max << endl;
614  MyExpose();
615  }
616  else if (word == "autoscale")
617  {
618  scr >> ws >> word;
619  cout << "Script: autoscale: " << word;
620  if (word == "off")
621  {
622  vs->SetAutoscale(0);
623  }
624  else if (word == "on")
625  {
626  vs->SetAutoscale(1);
627  }
628  else if (word == "value")
629  {
630  vs->SetAutoscale(2);
631  }
632  else if (word == "mesh")
633  {
634  vs->SetAutoscale(3);
635  }
636  else
637  {
638  cout << '?';
639  }
640  cout << endl;
641  }
642  else if (word == "window")
643  {
644  scr >> window_x >> window_y >> window_w >> window_h;
645  cout << "Script: window: " << window_x << ' ' << window_y
646  << ' ' << window_w << ' ' << window_h << endl;
648  MyExpose();
649  }
650  else if (word == "keys")
651  {
652  scr >> stream_state.keys;
653  cout << "Script: keys: '" << stream_state.keys << "'" << endl;
654  // SendKeySequence(keys.c_str());
656  MyExpose();
657  }
658  else if (word == "palette")
659  {
660  int pal;
661  scr >> pal;
662  cout << "Script: palette: " << pal << endl;
663  vs->palette.SetIndex(pal-1);
664  MyExpose();
665  }
666  else if (word == "palette_repeat")
667  {
668  int rpt_times;
669  scr >> rpt_times;
670  cout << "Script: palette_repeat: " << rpt_times << endl;
671  vs->palette.SetRepeatTimes(rpt_times);
672  vs->palette.Init();
673  MyExpose();
674  }
675  else if (word == "toggle_attributes")
676  {
677  Array<int> attr_list;
678  cout << "Script: toggle_attributes:";
679  for (scr >> ws; scr.peek() != ';'; scr >> ws)
680  {
681  attr_list.Append(0);
682  scr >> attr_list.Last();
683  if (attr_list.Size() <= 256)
684  {
685  cout << ' ' << attr_list.Last();
686  }
687  else if (attr_list.Size() == 257)
688  {
689  cout << " ... " << flush;
690  }
691  }
692  scr.get(); // read the end symbol: ';'
693  cout << endl;
694  vs->ToggleAttributes(attr_list);
695  MyExpose();
696  }
697  else if (word == "rotmat")
698  {
699  cout << "Script: rotmat:";
700  for (int i = 0; i < 16; i++)
701  {
702  scr >> vs->rotmat[i/4][i%4];
703  cout << ' ' << vs->rotmat[i/4][i%4];
704  }
705  cout << endl;
706  MyExpose();
707  }
708  else if (word == "camera")
709  {
710  double cam[9];
711  cout << "Script: camera:";
712  for (int i = 0; i < 9; i++)
713  {
714  scr >> cam[i];
715  cout << ' ' << cam[i];
716  }
717  cout << endl;
718  vs->cam.Set(cam);
719  MyExpose();
720  }
721  else if (word == "scale")
722  {
723  double scale;
724  cout << "Script: scale:";
725  scr >> scale;
726  cout << ' ' << scale;
727  cout << endl;
728  vs->Scale(scale);
729  MyExpose();
730  }
731  else if (word == "translate")
732  {
733  double x, y, z;
734  cout << "Script: translate:";
735  scr >> x >> y >> z;
736  cout << ' ' << x << ' ' << y << ' ' << z;
737  cout << endl;
738  vs->Translate(x, y, z);
739  MyExpose();
740  }
741  else if (word == "plot_caption")
742  {
743  char delim;
744  scr >> ws >> delim;
745  getline(scr, plot_caption, delim);
746  vs->PrepareCaption(); // turn on or off the caption
747  MyExpose();
748  }
749  else
750  {
751  cout << "Unknown command in script: " << word << endl;
752  }
753 
754  done_one_command = 1;
755  }
756 }
757 
758 void ScriptControl();
759 
761 {
763  if (scr_level == 0)
764  {
765  ScriptControl();
766  }
767 }
768 
770 {
771  if (scr_running)
772  {
773  scr_running = 0;
775  }
776  else
777  {
778  scr_running = 1;
780  }
781 }
782 
783 void PlayScript(istream &scr)
784 {
785  string word;
786 
787  scr_min_val = numeric_limits<double>::infinity();
789 
790  // read initializing commands
791  while (1)
792  {
793  scr >> ws;
794  if (!scr.good())
795  {
796  cout << "Error in script" << endl;
797  return;
798  }
799  if (scr.peek() == '#')
800  {
801  getline(scr, word);
802  continue;
803  }
804  scr >> word;
805  if (word == "window")
806  {
807  scr >> window_x >> window_y >> window_w >> window_h;
808  }
809  else if (word == "solution")
810  {
812  {
813  return;
814  }
815 
816  // start the visualization
817  break;
818  }
819  else if (word == "psolution")
820  {
822  {
823  return;
824  }
825 
826  // start the visualization
827  break;
828  }
829  else if (word == "mesh")
830  {
832  {
833  return;
834  }
835  if (stream_state.mesh)
836  {
837  break;
838  }
839  }
840  else
841  {
842  cout << "Unknown command in script: " << word << endl;
843  }
844  }
845 
846  scr_level = scr_running = 0;
847  script = &scr;
848  stream_state.keys.clear();
849 
850  std::thread worker_thread
851  {
852  [&](StreamState local_state)
853  {
854  // set the thread-local StreamState
855  stream_state = std::move(local_state);
857  {
859  }
860  if (GLVisInitVis((stream_state.grid_f->VectorDim() == 1) ? 0 : 1, {}))
861  {
862  GetAppWindow()->setOnKeyDown(SDLK_SPACE, ScriptControl);
863  GLVisStartVis();
864  }
865  },
866  std::move(stream_state)
867  };
868 
869  SDLMainLoop();
870  worker_thread.join();
871 
872  delete init_nodes; init_nodes = NULL;
873 
874  cout << "Script: min_val = " << scr_min_val
875  << ", max_val = " << scr_max_val << endl;
876 
877  script = NULL;
878 }
879 
880 struct Session
881 {
882  StreamCollection input_streams;
883  StreamState state;
884  int ft = -1;
885  std::thread handler;
886 
887  Session(bool fix_elem_orient,
888  bool save_coloring)
889  {
890  state.fix_elem_orient = fix_elem_orient;
891  state.save_coloring = save_coloring;
892  }
893 
894  Session(int other_ft, StreamState other_state)
895  : state(std::move(other_state))
896  , ft(other_ft)
897  { }
898 
899  ~Session() = default;
900 
901  Session(Session&& from) = default;
902  Session& operator= (Session&& from) = default;
903 
904  void StartSession()
905  {
906  auto funcThread =
907  [](StreamState thread_state, int ftype, StreamCollection is)
908  {
909  // Set thread-local stream state
910  stream_state = std::move(thread_state);
912  {
914  }
915 
916  if (GLVisInitVis(ftype, std::move(is)))
917  {
918  GLVisStartVis();
919  }
920  };
921  handler = std::thread {funcThread,
922  std::move(state), ft, std::move(input_streams)};
923  handler.detach();
924  }
925 
926  bool StartSavedSession(std::string stream_file)
927  {
928  unique_ptr<ifstream> ifs(new ifstream(stream_file));
929  if (!(*ifs))
930  {
931  cout << "Can not open stream file: " << stream_file << endl;
932  return false;
933  }
934  string data_type;
935  *ifs >> data_type >> ws;
936  ft = state.ReadStream(*ifs, data_type);
937  input_streams.emplace_back(std::move(ifs));
938 
939  StartSession();
940  return true;
941  }
942 };
943 
944 void GLVisServer(int portnum, bool save_stream, bool fix_elem_orient,
945  bool save_coloring)
946 {
947  std::vector<Session> current_sessions;
948  string data_type;
949  int viscount = 0;
950  unsigned int nproc = 1, proc = 0;
951 
952 #ifdef MFEM_USE_GNUTLS
953  unique_ptr<GnuTLS_global_state> state;
954  unique_ptr<GnuTLS_session_params> params;
955  if (secure)
956  {
957  state.reset(new GnuTLS_global_state);
958  // state->set_log_level(1000);
959  string home_dir(getenv("HOME"));
960  string server_dir = home_dir + "/.config/glvis/server/";
961 #ifndef MFEM_USE_GNUTLS_X509
962  string pubkey = server_dir + "pubring.gpg";
963  string privkey = server_dir + "secring.gpg";
964  string trustedkeys = server_dir + "trusted-clients.gpg";
965 #else
966  string pubkey = server_dir + "cert.pem";
967  string privkey = server_dir + "key.pem";
968  string trustedkeys = server_dir + "trusted-clients.pem";
969 #endif
970  params.reset(new GnuTLS_session_params(
971  *state, pubkey.c_str(), privkey.c_str(),
972  trustedkeys.c_str(), GNUTLS_SERVER));
973  if (!params->status.good())
974  {
975  cout << " public key = " << pubkey << '\n'
976  << " private key = " << privkey << '\n'
977  << " trusted keys = " << trustedkeys << endl;
978  cout << "Error setting GLVis server parameters.\n"
979  "Generate your GLVis keys with:"
980  " bash glvis-keygen.sh [\"Your Name\"] [\"Your Email\"]"
981  << endl;
982  return;
983  }
984  }
985 #endif
986 
987  const int backlog = 128;
988  socketserver server(portnum, backlog);
989  if (server.good())
990  {
991  cout << "Waiting for data on port " << portnum << " ..." << endl;
992  }
993  else
994  {
995  cout << "Server already running on port " << portnum << ".\n" << endl;
996  exit(2);
997  }
998  while (1)
999  {
1000 
1001  unique_ptr<socketstream> isock;
1002 #ifndef MFEM_USE_GNUTLS
1003  isock.reset(new socketstream);
1004 #else
1005  isock.reset(secure ? new socketstream(*params) : new socketstream(false));
1006 #endif
1007  vector<unique_ptr<istream>> input_streams;
1008  while (server.accept(*isock) < 0)
1009  {
1010 #ifdef GLVIS_DEBUG
1011  cout << "GLVis: server.accept(...) failed." << endl;
1012 #endif
1013  }
1014 
1015  *isock >> data_type >> ws;
1016 
1017  if (save_stream)
1018  {
1019  viscount++;
1020  }
1021 
1022  int par_data = 0;
1023  if (data_type == "parallel")
1024  {
1025  par_data = 1;
1026  unsigned int np = 0;
1027  do
1028  {
1029  *isock >> nproc >> proc;
1030 #ifdef GLVIS_DEBUG
1031  cout << "new connection: parallel " << nproc << ' ' << proc
1032  << endl;
1033 #endif
1034  if (np == 0)
1035  {
1036  if (nproc <= 0)
1037  {
1038  cout << "Invalid number of processors: " << nproc << endl;
1039  mfem_error();
1040  }
1041  input_streams.resize(nproc);
1042  }
1043  else
1044  {
1045  if (nproc != input_streams.size())
1046  {
1047  cout << "Unexpected number of processors: " << nproc
1048  << ", expected: " << input_streams.size() << endl;
1049  mfem_error();
1050  }
1051  }
1052  if (proc >= nproc)
1053  {
1054  cout << "Invalid processor rank: " << proc
1055  << ", number of processors: " << nproc << endl;
1056  mfem_error();
1057  }
1058  if (input_streams[proc])
1059  {
1060  cout << "Second connection attempt from processor rank: "
1061  << proc << endl;
1062  mfem_error();
1063  }
1064 
1065  input_streams[proc] = std::move(isock);
1066 #ifndef MFEM_USE_GNUTLS
1067  isock.reset(new socketstream);
1068 #else
1069  isock.reset(secure ? new socketstream(*params) :
1070  new socketstream(false));
1071 #endif
1072  np++;
1073  if (np == nproc)
1074  {
1075  break;
1076  }
1077  // read next available socket stream
1078  while (server.accept(*isock) < 0)
1079  {
1080 #ifdef GLVIS_DEBUG
1081  cout << "GLVis: server.accept(...) failed." << endl;
1082 #endif
1083  }
1084  *isock >> data_type >> ws; // "parallel"
1085  if (data_type != "parallel")
1086  {
1087  cout << "Expected keyword \"parallel\", got \"" << data_type
1088  << '"' << endl;
1089  mfem_error();
1090  }
1091  }
1092  while (1);
1093  }
1094 
1095  Session new_session(fix_elem_orient, save_coloring);
1096 
1097  char tmp_file[50];
1098  if (save_stream)
1099  {
1100  sprintf(tmp_file,"glvis-saved.%04d",viscount);
1101  ofstream ofs(tmp_file);
1102  if (!par_data)
1103  {
1104  ofs << data_type << '\n';
1105  ofs << isock->rdbuf();
1106  isock->close();
1107  }
1108  else
1109  {
1110  ReadInputStreams(new_session.state, input_streams);
1111  ofs.precision(8);
1112  ofs << "solution\n";
1113  new_session.state.mesh->Print(ofs);
1114  new_session.state.grid_f->Save(ofs);
1115  }
1116  ofs.close();
1117  cout << "Data saved in " << tmp_file << endl;
1118 
1119  new_session.StartSavedSession(tmp_file);
1120  }
1121  else
1122  {
1123  if (!par_data)
1124  {
1125  new_session.ft = new_session.state.ReadStream(*isock, data_type);
1126  input_streams.emplace_back(std::move(isock));
1127  }
1128  else
1129  {
1130  new_session.ft = ReadInputStreams(new_session.state, input_streams);
1131  }
1132  // Pass ownership of input streams into session object
1133  new_session.input_streams = std::move(input_streams);
1134  new_session.StartSession();
1135  }
1136  current_sessions.emplace_back(std::move(new_session));
1137  }
1138 }
1139 
1140 int main (int argc, char *argv[])
1141 {
1142 #ifdef _WIN32
1143  // Call needed to avoid SDL_Init failure when not substituting main() for
1144  // SDL_main().
1145  SDL_SetMainReady();
1146 #endif
1147  // variables for command line arguments
1148  int np = 0;
1149  bool save_stream = false;
1150  const char *stream_file = string_none;
1151  const char *script_file = string_none;
1152  const char *font_name = string_default;
1153  int portnum = 19916;
1154  int multisample = GetMultisample();
1155  double line_width = 1.0;
1156  double ms_line_width = gl3::LINE_WIDTH_AA;
1157  int geom_ref_type = Quadrature1D::ClosedUniform;
1158  bool legacy_gl_ctx = false;
1159  bool enable_hidpi = true;
1160 
1161  OptionsParser args(argc, argv);
1162 
1163  args.AddOption(&mesh_file, "-m", "--mesh",
1164  "Mesh file to visualize.");
1165  args.AddOption(&gfunc_file, "-g", "--grid-function",
1166  "Solution (GridFunction) file to visualize.");
1167  args.AddOption(&gf_component, "-gc", "--grid-function-component",
1168  "Select a grid function component, [0-<num-comp>) or"
1169  " -1 for all.");
1170  args.AddOption(&sol_file, "-s", "--scalar-solution",
1171  "Scalar solution (vertex values) file to visualize.");
1172  args.AddOption(&vec_sol_file, "-v", "--vector-solution",
1173  "Vector solution (vertex values) file to visualize.");
1174  args.AddOption(&np, "-np", "--num-proc",
1175  "Load mesh/solution from multiple processors.");
1176  args.AddOption(&pad_digits, "-d", "--pad-digits",
1177  "Number of digits used for processor ranks in file names.");
1178  args.AddOption(&script_file, "-run", "--run-script",
1179  "Run a GLVis script file.");
1180  args.AddOption(&arg_keys, "-k", "--keys",
1181  "Execute key shortcut commands in the GLVis window.");
1182  args.AddOption(&stream_state.fix_elem_orient, "-fo", "--fix-orientations",
1183  "-no-fo", "--dont-fix-orientations",
1184  "Attempt to fix the orientations of inverted elements.");
1185  args.AddOption(&keep_attr, "-a", "--real-attributes",
1186  "-ap", "--processor-attributes",
1187  "When opening a parallel mesh, use the real mesh attributes"
1188  " or replace them with the processor rank.");
1189  args.AddOption(&geom_ref_type, "-grt", "--geometry-refiner-type",
1190  "Set of points to use when refining geometry:"
1191  " 3 = uniform, 1 = Gauss-Lobatto, (see mfem::Quadrature1D).");
1192  args.AddOption(&stream_state.save_coloring, "-sc", "--save-coloring",
1193  "-no-sc", "--dont-save-coloring",
1194  "Save the mesh coloring generated when opening only a mesh.");
1195  args.AddOption(&portnum, "-p", "--listen-port",
1196  "Specify the port number on which to accept connections.");
1197  args.AddOption(&secure, "-sec", "--secure-sockets",
1198  "-no-sec", "--standard-sockets",
1199  "Enable or disable GnuTLS secure sockets.");
1200  args.AddOption(&save_stream, "-save", "--save-stream",
1201  "-no-save", "--dont-save-stream",
1202  "In server mode, save incoming data to a file before"
1203  " visualization.");
1204  args.AddOption(&stream_file, "-saved", "--saved-stream",
1205  "Load a GLVis stream saved to a file.");
1206  args.AddOption(&window_w, "-ww", "--window-width",
1207  "Set the window width.");
1208  args.AddOption(&window_h, "-wh", "--window-height",
1209  "Set the window height.");
1210  args.AddOption(&window_title, "-wt", "--window-title",
1211  "Set the window title.");
1212  args.AddOption(&c_plot_caption, "-c", "--plot-caption",
1213  "Set the plot caption (visible when colorbar is visible).");
1214  args.AddOption(&font_name, "-fn", "--font",
1215  "Set the font: [<font-name>[:style=<style>]][-<font-size>],"
1216  " e.g. -fn \"Helvetica:style=Bold-16\".");
1217  args.AddOption(&multisample, "-ms", "--multisample",
1218  "Set the multisampling mode (toggled with the 'A' key).");
1219  args.AddOption(&line_width, "-lw", "--line-width",
1220  "Set the line width (multisampling off).");
1221  args.AddOption(&ms_line_width, "-mslw", "--multisample-line-width",
1222  "Set the line width (multisampling on).");
1223  args.AddOption(&legacy_gl_ctx, "-oldgl", "--legacy-gl",
1224  "-anygl", "--any-gl",
1225  "Only try to create a legacy OpenGL (< 2.1) context.");
1226  args.AddOption(&enable_hidpi, "-hidpi", "--high-dpi",
1227  "-nohidpi", "--no-high-dpi",
1228  "Enable/disable support for HiDPI at runtime, if supported.");
1229 
1230  cout << endl
1231  << " _/_/_/ _/ _/ _/ _/" << endl
1232  << " _/ _/ _/ _/ _/_/_/" << endl
1233  << " _/ _/_/ _/ _/ _/ _/ _/_/" << endl
1234  << " _/ _/ _/ _/ _/ _/ _/_/" << endl
1235  << " _/_/_/ _/_/_/_/ _/ _/ _/_/_/" << endl
1236  << endl ;
1237 
1238  args.Parse();
1239  if (!args.Good())
1240  {
1241  if (!args.Help())
1242  {
1243  args.PrintError(cout);
1244  cout << endl;
1245  }
1246  PrintSampleUsage(cout);
1247  args.PrintHelp(cout);
1248  return 1;
1249  }
1250 
1251  // set options
1252  if (mesh_file != string_none)
1253  {
1254  input |= 2;
1255  }
1256  if (sol_file != string_none)
1257  {
1258  input |= 4;
1259  }
1260  if (vec_sol_file != string_none)
1261  {
1263  input |= 8;
1264  }
1265  if (gfunc_file != string_none)
1266  {
1267  sol_file = gfunc_file;
1268  stream_state.is_gf = 255;
1269  }
1270  if (np > 0)
1271  {
1272  input |= 256;
1273  }
1274  if (arg_keys != string_none)
1275  {
1277  }
1278  if (font_name != string_default)
1279  {
1280  SetFont(font_name);
1281  }
1282  if (multisample != GetMultisample())
1283  {
1284  SetMultisample(multisample);
1285  }
1286  if (line_width != GetLineWidth())
1287  {
1288  SetLineWidth(line_width);
1289  }
1290  if (ms_line_width != GetLineWidthMS())
1291  {
1292  SetLineWidthMS(ms_line_width);
1293  }
1294  if (c_plot_caption != string_none)
1295  {
1297  }
1298  if (legacy_gl_ctx == true)
1299  {
1300  SetLegacyGLOnly(legacy_gl_ctx);
1301  }
1302  SetUseHiDPI(enable_hidpi);
1303 
1304  GLVisGeometryRefiner.SetType(geom_ref_type);
1305 
1306  string data_type;
1307 
1308  // check for saved stream file
1309  if (stream_file != string_none)
1310  {
1311  Session stream_session(stream_state.fix_elem_orient,
1313 
1314  if (!stream_session.StartSavedSession(stream_file))
1315  {
1316  return 1;
1317  }
1318 
1319  SDLMainLoop();
1320  return 0;
1321  }
1322 
1323  // check for script file
1324  if (script_file != string_none)
1325  {
1326  ifstream scr(script_file);
1327  if (!scr)
1328  {
1329  cout << "Can not open script: " << script_file << endl;
1330  return 1;
1331  }
1332  PlayScript(scr);
1333  return 0;
1334  }
1335 
1336  // print help for wrong input
1337  if (!(input == 1 || input == 3 || input == 7 || input == 11 || input == 259 ||
1338  (stream_state.is_gf && (input == 3 || input == 259))))
1339  {
1340  cout << "Invalid combination of mesh/solution options!\n\n";
1341  PrintSampleUsage(cout);
1342  args.PrintHelp(cout);
1343  return 1;
1344  }
1345 
1346 #ifndef MFEM_USE_GNUTLS
1347  if (secure)
1348  {
1349  cout << "The secure option can only be used when MFEM is compiled with"
1350  " GnuTLS support." << endl;
1351  return 1;
1352  }
1353 #endif
1354 
1355  // server mode, read the mesh and the solution from a socket
1356  if (input == 1)
1357  {
1358  // Run server in new thread
1359  std::thread serverThread{GLVisServer, portnum, save_stream,
1362 
1363  // Start SDL in main thread
1364  SDLMainLoop(true);
1365 
1366  serverThread.detach();
1367  }
1368  else // input != 1, non-server mode
1369  {
1370  if (input & 256)
1371  {
1373  }
1374  else
1375  {
1377  }
1378 
1379  bool use_vector_soln = (input & 8);
1380  bool use_soln = (input & 4);
1381  int field_type;
1382  if (use_vector_soln)
1383  {
1384  field_type = 1;
1385  }
1386  else
1387  {
1388  field_type = (use_soln) ? 0 : 2;
1389  }
1390  Session single_session(field_type, std::move(stream_state));
1391  single_session.StartSession();
1392 
1393  SDLMainLoop();
1394  }
1395 
1396  cout << "Thank you for using GLVis." << endl;
1397 
1398  return 0;
1399 }
1400 
1401 
1402 void PrintSampleUsage(ostream &os)
1403 {
1404  os <<
1405  "Start a GLVis server:\n"
1406  " glvis\n"
1407  "Visualize a mesh:\n"
1408  " glvis -m <mesh_file>\n"
1409  "Visualize mesh and solution (grid function):\n"
1410  " glvis -m <mesh_file> -g <grid_function_file> [-gc <component>]\n"
1411  "Visualize parallel mesh and solution (grid function):\n"
1412  " glvis -np <#proc> -m <mesh_prefix> [-g <grid_function_prefix>]\n\n"
1413  "All Options:\n";
1414 }
1415 
1416 
1418 {
1419  // get the mesh from a file
1420  named_ifgzstream meshin(mesh_file);
1421  if (!meshin)
1422  {
1423  cerr << "Can not open mesh file " << mesh_file << ". Exit.\n";
1424  exit(1);
1425  }
1426 
1427  state.mesh.reset(new Mesh(meshin, 1, 0, state.fix_elem_orient));
1428 
1429  if (state.is_gf || (input & 4) || (input & 8))
1430  {
1431  // get the solution from file
1432  bool freesolin = false;
1433  ifgzstream *solin = NULL;
1434  if (!strcmp(mesh_file,sol_file))
1435  {
1436  solin = &meshin;
1437  }
1438  else
1439  {
1440  solin = new ifgzstream(sol_file);
1441  freesolin = true;
1442  if (!(*solin))
1443  {
1444  cerr << "Can not open solution file " << sol_file << ". Exit.\n";
1445  exit(1);
1446  }
1447  }
1448 
1449  if (state.is_gf)
1450  {
1451  state.grid_f.reset(new GridFunction(state.mesh.get(), *solin));
1452  SetGridFunction(state);
1453  }
1454  else if (input & 4)
1455  {
1456  // get rid of NetGen's info line
1457  char buff[128];
1458  solin->getline(buff,128);
1459  state.sol.Load(*solin, state.mesh->GetNV());
1460  }
1461  else if (input & 8)
1462  {
1463  state.solu.Load(*solin, state.mesh->GetNV());
1464  state.solv.Load(*solin, state.mesh->GetNV());
1465  if (state.mesh->SpaceDimension() == 3)
1466  {
1467  state.solw.Load(*solin, state.mesh->GetNV());
1468  }
1469  }
1470  if (freesolin)
1471  {
1472  delete solin;
1473  }
1474  }
1475  else
1476  {
1477  state.SetMeshSolution();
1478  }
1479 
1480  state.Extrude1DMeshAndSolution();
1481 }
1482 
1483 
1485 {
1486  if (gf_component != -1)
1487  {
1488  if (gf_component < 0 || gf_component >= state.grid_f->VectorDim())
1489  {
1490  cerr << "Invalid component " << gf_component << '.' << endl;
1491  exit(1);
1492  }
1493  FiniteElementSpace *ofes = state.grid_f->FESpace();
1494  FiniteElementCollection *fec =
1495  FiniteElementCollection::New(ofes->FEColl()->Name());
1496  FiniteElementSpace *fes = new FiniteElementSpace(state.mesh.get(), fec);
1497  GridFunction *new_gf = new GridFunction(fes);
1498  new_gf->MakeOwner(fec);
1499  for (int i = 0; i < new_gf->Size(); i++)
1500  {
1501  (*new_gf)(i) = (*state.grid_f)(ofes->DofToVDof(i, gf_component));
1502  }
1503  state.grid_f.reset(new_gf);
1504  }
1505  if (state.grid_f->VectorDim() == 1)
1506  {
1507  state.grid_f->GetNodalValues(state.sol);
1508  input |= 4;
1509  }
1510  else
1511  {
1512  input |= 8;
1513  }
1514 }
1515 
1516 
1517 void ReadParallel(int np, StreamState& state)
1518 {
1519  int read_err;
1520 
1521  if (state.is_gf)
1522  {
1524  state, keep_attr);
1525  if (!read_err)
1526  {
1527  SetGridFunction(state);
1528  }
1529  }
1530  else
1531  {
1532  read_err = ReadParMeshAndGridFunction(np, mesh_file, NULL,
1533  state, keep_attr);
1534  if (!read_err)
1535  {
1536  state.SetMeshSolution();
1537  }
1538  }
1539 
1540  if (read_err)
1541  {
1542  exit(1);
1543  }
1544 
1545  state.Extrude1DMeshAndSolution();
1546 }
1547 
1548 int ReadParMeshAndGridFunction(int np, const char *mesh_prefix,
1549  const char *sol_prefix,
1550  StreamState& state, int keep_attribs)
1551 {
1552  state.mesh = NULL;
1553 
1554  // are the solutions bundled together with the mesh files?
1555  bool same_file = false;
1556  if (sol_prefix)
1557  {
1558  same_file = !strcmp(sol_prefix, mesh_prefix);
1559  state.grid_f = NULL;
1560  }
1561 
1562  Array<Mesh *> mesh_array(np);
1563  Array<GridFunction *> gf_array(np);
1564  mesh_array = NULL;
1565  gf_array = NULL;
1566 
1567  int read_err = 0;
1568  for (int p = 0; p < np; p++)
1569  {
1570  ostringstream fname;
1571  fname << mesh_prefix << '.' << setfill('0') << setw(pad_digits) << p;
1572  named_ifgzstream meshfile(fname.str().c_str());
1573  if (!meshfile)
1574  {
1575  cerr << "Could not open mesh file: " << fname.str() << '!' << endl;
1576  read_err = 1;
1577  break;
1578  }
1579 
1580  mesh_array[p] = new Mesh(meshfile, 1, 0, state.fix_elem_orient);
1581 
1582  if (!keep_attribs)
1583  {
1584  // set element and boundary attributes to be the processor number + 1
1585  for (int i = 0; i < mesh_array[p]->GetNE(); i++)
1586  {
1587  mesh_array[p]->GetElement(i)->SetAttribute(p+1);
1588  }
1589  for (int i = 0; i < mesh_array[p]->GetNBE(); i++)
1590  {
1591  mesh_array[p]->GetBdrElement(i)->SetAttribute(p+1);
1592  }
1593  }
1594 
1595  // read the solution
1596  if (sol_prefix)
1597  {
1598  if (!same_file)
1599  {
1600  ostringstream sol_fname;
1601  sol_fname << sol_prefix << '.' << setfill('0') << setw(pad_digits) << p;
1602  ifgzstream solfile(sol_fname.str().c_str());
1603  if (!solfile)
1604  {
1605  cerr << "Could not open solution file "
1606  << sol_fname.str() << '!' << endl;
1607  read_err = 2;
1608  break;
1609  }
1610 
1611  gf_array[p] = new GridFunction(mesh_array[p], solfile);
1612  }
1613  else // mesh and solution in the same file
1614  {
1615  gf_array[p] = new GridFunction(mesh_array[p], meshfile);
1616  }
1617  }
1618  }
1619 
1620  if (!read_err)
1621  {
1622  // create the combined mesh and gf
1623  state.mesh.reset(new Mesh(mesh_array, np));
1624  if (sol_prefix)
1625  {
1626  state.grid_f.reset(new GridFunction(state.mesh.get(), gf_array, np));
1627  }
1628  }
1629 
1630  for (int p = 0; p < np; p++)
1631  {
1632  delete gf_array[np-1-p];
1633  delete mesh_array[np-1-p];
1634  }
1635 
1636  return read_err;
1637 }
1638 
1639 int ReadInputStreams(StreamState& state, const StreamCollection& input_streams)
1640 {
1641  int nproc = input_streams.size();
1642  Array<Mesh *> mesh_array(nproc);
1643  Array<GridFunction *> gf_array(nproc);
1644  string data_type;
1645 
1646  int gf_count = 0;
1647  int field_type = 0;
1648 
1649  for (int p = 0; p < nproc; p++)
1650  {
1651 #ifdef GLVIS_DEBUG
1652  cout << "connection[" << p << "]: reading initial data ... " << flush;
1653 #endif
1654  istream &isock = *input_streams[p];
1655  // assuming the "parallel nproc p" part of the stream has been read
1656  isock >> ws >> data_type >> ws; // "*_data" / "mesh" / "solution"
1657 #ifdef GLVIS_DEBUG
1658  cout << " type " << data_type << " ... " << flush;
1659 #endif
1660  mesh_array[p] = new Mesh(isock, 1, 0, state.fix_elem_orient);
1661  if (!keep_attr)
1662  {
1663  // set element and boundary attributes to proc+1
1664  for (int i = 0; i < mesh_array[p]->GetNE(); i++)
1665  {
1666  mesh_array[p]->GetElement(i)->SetAttribute(p+1);
1667  }
1668  for (int i = 0; i < mesh_array[p]->GetNBE(); i++)
1669  {
1670  mesh_array[p]->GetBdrElement(i)->SetAttribute(p+1);
1671  }
1672  }
1673  gf_array[p] = NULL;
1674  if (data_type != "mesh")
1675  {
1676  gf_array[p] = new GridFunction(mesh_array[p], isock);
1677  gf_count++;
1678  }
1679 #ifdef GLVIS_DEBUG
1680  cout << "done." << endl;
1681 #endif
1682  }
1683 
1684  if (gf_count > 0 && gf_count != nproc)
1685  {
1686  mfem_error("Input streams contain a mixture of data types!");
1687  }
1688 
1689  state.mesh.reset(new Mesh(mesh_array, nproc));
1690  if (gf_count == 0)
1691  {
1692  state.SetMeshSolution();
1693  field_type = 2;
1694  }
1695  else
1696  {
1697  state.grid_f.reset(new GridFunction(state.mesh.get(), gf_array, nproc));
1698  field_type = (state.grid_f->VectorDim() == 1) ? 0 : 1;
1699  }
1700 
1701  for (int p = 0; p < nproc; p++)
1702  {
1703  delete mesh_array[nproc-1-p];
1704  delete gf_array[nproc-1-p];
1705  }
1706 
1707  state.Extrude1DMeshAndSolution();
1708 
1709  return field_type;
1710 }
void Terminate()
Definition: threads.cpp:673
int input
Definition: glvis.cpp:65
std::unique_ptr< GridFunction > ProjectVectorFEGridFunction(std::unique_ptr< GridFunction > gf)
const char * vec_sol_file
Definition: glvis.cpp:48
thread_local GeometryRefiner GLVisGeometryRefiner
Definition: glvis.cpp:71
void PlayScript(istream &scr)
Definition: glvis.cpp:783
void SetValueRange(double, double)
Definition: vsdata.cpp:1305
double scr_min_val
Definition: glvis.cpp:80
void Extrude1DMeshAndSolution()
Helper function for visualizing 1D data.
float GetLineWidth()
Definition: aux_vis.cpp:1609
int scr_running
Definition: glvis.cpp:77
int Screenshot(const char *fname, bool convert)
Take a screenshot using libtiff, libpng or sdl2.
Definition: aux_vis.cpp:970
thread_local communication_thread * comm_thread
Definition: glvis.cpp:69
void Set(const double cam[])
Definition: openglvis.cpp:37
float GetLineWidthMS()
Definition: aux_vis.cpp:1614
void SetLineWidthMS(float width_ms)
Definition: aux_vis.cpp:1599
void SetGridFunction(StreamState &state)
Definition: glvis.cpp:1484
int pad_digits
Definition: glvis.cpp:51
virtual void AutoRefine()=0
char ** environ
void Translate(double x, double y, double z=0.0)
Definition: openglvis.cpp:1078
void Zoom(double factor)
Definition: openglvis.cpp:1125
bool SetFont(const vector< std::string > &font_patterns, int height)
Definition: aux_vis.cpp:1683
PaletteState palette
Definition: openglvis.hpp:178
int ScriptReadParSolution(istream &scr, StreamState &state)
Definition: glvis.cpp:309
void ExecuteScriptCommand()
Definition: glvis.cpp:404
mfem::Vector solv
const char * arg_keys
Definition: glvis.cpp:50
void MyExpose(GLsizei w, GLsizei h)
Definition: aux_vis.cpp:389
void ThreadsPauseFunc(GLenum state)
Definition: aux_vis.cpp:1247
void SetVisualizationScene(VisualizationScene *scene, int view, const char *keys)
Definition: aux_vis.cpp:307
const char * gfunc_file
Definition: glvis.cpp:49
virtual void SetShading(int, bool)=0
double scr_max_val
Definition: glvis.cpp:80
int window_x
Definition: glvis.cpp:54
int window_y
Definition: glvis.cpp:55
void AddIdleFunc(void(*Func)(void))
Definition: aux_vis.cpp:491
std::unique_ptr< mfem::GridFunction > grid_f
const char * c_plot_caption
Definition: glvis.cpp:59
const char * mesh_file
Definition: glvis.cpp:46
int ScriptReadSolution(istream &scr, StreamState &state)
Definition: glvis.cpp:269
void SetRepeatTimes(int rpt)
Definition: palettes.hpp:47
int scr_level
Definition: glvis.cpp:78
thread_local string plot_caption
Definition: glvis.cpp:60
void SDLMainLoop(bool server_mode)
Definition: aux_vis.cpp:53
int GetMultisample()
Definition: aux_vis.cpp:1573
vector< unique_ptr< istream >> StreamCollection
Definition: glvis.cpp:84
void SetLight(bool light_set)
Definition: vsdata.hpp:238
int ReadInputStreams(StreamState &state, const StreamCollection &input_streams)
Definition: glvis.cpp:1639
mfem::Vector solu
thread_local VisualizationSceneScalarData * vs
Definition: glvis.cpp:67
const char * sol_file
Definition: glvis.cpp:47
const char * string_none
Definition: glvis.cpp:42
Vector * init_nodes
Definition: glvis.cpp:79
thread_local StreamState stream_state
Definition: glvis.cpp:66
mfem::Vector solw
const char * window_titles[]
Definition: glvis.cpp:73
void SetMeshSolution()
Set a (checkerboard) solution when only the mesh is given.
int window_h
Definition: glvis.cpp:57
int gf_component
Definition: glvis.cpp:52
std::string keys
bool SetNewMeshAndSolution(StreamState new_state, VisualizationScene *vs)
int main(int argc, char *argv[])
Definition: glvis.cpp:1140
void SetIndex(int num)
Sets the palette texture to bind.
Definition: palettes.hpp:31
void RemoveIdleFunc(void(*Func)(void))
Definition: aux_vis.cpp:497
void SetView(double theta, double phi)
Definition: openglvis.cpp:1115
void ScriptIdleFunc()
Definition: glvis.cpp:760
void Scale(double s)
Definition: openglvis.cpp:1087
std::unique_ptr< mfem::Mesh > mesh
void SetLineWidth(float width)
Definition: aux_vis.cpp:1590
void SetLightMatIdx(unsigned i)
Definition: openglvis.cpp:1020
SdlWindow * GetAppWindow()
Definition: aux_vis.cpp:58
bool secure
Definition: glvis.cpp:62
void MoveResizeWindow(int x, int y, int w, int h)
Definition: aux_vis.cpp:1540
void GLVisStartVis()
Definition: glvis.cpp:255
void Init()
Initializes the palette textures.
Definition: palettes.cpp:7694
void SetGridFunction(GridFunction &u)
Definition: vssolution.hpp:95
void SetLegacyGLOnly(bool status)
Definition: aux_vis.cpp:68
virtual void ToggleAttributes(Array< int > &attr_list)=0
thread_local string extra_caption
Definition: glvis.cpp:61
virtual void SetRefineFactors(int, int)=0
bool GLVisInitVis(int field_type, StreamCollection input_streams)
Definition: glvis.cpp:105
thread_local GLVisCommand * glvis_command
Definition: aux_vis.cpp:39
bool fix_elem_orient
void SetAutoscale(int _autoscale)
Definition: vsdata.cpp:1141
istream * script
Definition: glvis.cpp:76
const char * window_title
Definition: glvis.cpp:58
void GLVisServer(int portnum, bool save_stream, bool fix_elem_orient, bool save_coloring)
Definition: glvis.cpp:944
int InitVisualization(const char name[], int x, int y, int w, int h)
Initializes the visualization and some keys.
Definition: aux_vis.cpp:81
void RunVisualization()
Start the infinite visualization loop.
Definition: aux_vis.cpp:334
const char * string_default
Definition: glvis.cpp:43
int window_w
Definition: glvis.cpp:56
void SetMultisample(int m)
Definition: aux_vis.cpp:1578
void setOnKeyDown(int key, Delegate func)
Definition: sdl.hpp:188
int ScriptReadDisplMesh(istream &scr, StreamState &state)
Definition: glvis.cpp:343
mfem::Vector normals
void ReadSerial(StreamState &state)
Definition: glvis.cpp:1417
int ReadParMeshAndGridFunction(int np, const char *mesh_prefix, const char *sol_prefix, StreamState &state, int keep_attr)
Definition: glvis.cpp:1548
const float LINE_WIDTH_AA
Definition: renderer.hpp:32
void ScriptControl()
Definition: glvis.cpp:769
bool keep_attr
Definition: glvis.cpp:53
void CallKeySequence(const char *seq)
Definition: aux_vis.cpp:253
void PrintSampleUsage(ostream &out)
Definition: glvis.cpp:1402
void SetUseHiDPI(bool status)
Definition: aux_vis.cpp:73
void ReadParallel(int np, StreamState &state)
Definition: glvis.cpp:1517
void SetGridFunction(GridFunction *gf)
mfem::Vector sol