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