LCOV - code coverage report
Current view: top level - src/mesh - mesh_output.C (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4229 (6a9aeb) with base 727f46 Lines: 33 55 60.0 %
Date: 2025-08-19 19:27:09 Functions: 2 15 13.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // The libMesh Finite Element Library.
       2             : // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
       3             : 
       4             : // This library is free software; you can redistribute it and/or
       5             : // modify it under the terms of the GNU Lesser General Public
       6             : // License as published by the Free Software Foundation; either
       7             : // version 2.1 of the License, or (at your option) any later version.
       8             : 
       9             : // This library is distributed in the hope that it will be useful,
      10             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12             : // Lesser General Public License for more details.
      13             : 
      14             : // You should have received a copy of the GNU Lesser General Public
      15             : // License along with this library; if not, write to the Free Software
      16             : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      17             : 
      18             : 
      19             : // Local includes
      20             : #include "libmesh/distributed_mesh.h"
      21             : #include "libmesh/equation_systems.h"
      22             : #include "libmesh/libmesh_logging.h"
      23             : #include "libmesh/mesh_output.h"
      24             : #include "libmesh/unstructured_mesh.h"
      25             : #include "libmesh/numeric_vector.h"
      26             : 
      27             : namespace libMesh
      28             : {
      29             : 
      30             : template <class MT>
      31       79822 : void MeshOutput<MT>::write_equation_systems (const std::string & fname,
      32             :                                              const EquationSystems & es,
      33             :                                              const std::set<std::string> * system_names)
      34             : {
      35        4940 :   LOG_SCOPE("write_equation_systems()", "MeshOutput");
      36             : 
      37             :   // We may need to gather and/or renumber a DistributedMesh to output
      38             :   // it, making that const qualifier in our constructor a dirty lie
      39       79822 :   MT & my_mesh = const_cast<MT &>(*_obj);
      40             : 
      41             :   // If we're asked to write data that's associated with a different
      42             :   // mesh, output files full of garbage are the result.
      43        2470 :   libmesh_assert_equal_to(&es.get_mesh(), _obj);
      44             : 
      45             :   // A non-parallel format, non-renumbered mesh may not have a contiguous
      46             :   // numbering, and that needs to be fixed before we can build a solution vector.
      47      158936 :   if (!_is_parallel_format &&
      48      155778 :       (my_mesh.max_elem_id() != my_mesh.n_elem() ||
      49       79114 :        my_mesh.max_node_id() != my_mesh.n_nodes()))
      50             :     {
      51             :       // If we were allowed to renumber then we should have already
      52             :       // been properly renumbered...
      53           0 :       libmesh_assert(!my_mesh.allow_renumbering());
      54             : 
      55           0 :       libmesh_do_once(libMesh::out <<
      56             :                       "Warning:  This MeshOutput subclass only supports meshes which are contiguously renumbered!"
      57             :                       << std::endl;);
      58             : 
      59           0 :       my_mesh.allow_renumbering(true);
      60             : 
      61           0 :       my_mesh.renumber_nodes_and_elements();
      62             : 
      63             :       // Not sure what good going back to false will do here, the
      64             :       // renumbering horses have already left the barn...
      65           0 :       my_mesh.allow_renumbering(false);
      66             :     }
      67             : 
      68       79822 :   if (!_is_parallel_format)
      69             :     {
      70       84014 :       MeshSerializer serialize(const_cast<MT &>(*_obj), !_is_parallel_format, _serial_only_needed_on_proc_0);
      71             : 
      72             :       // Build the list of variable names that will be written.
      73        7350 :       std::vector<std::string> names;
      74       79114 :       es.build_variable_names  (names, nullptr, system_names);
      75             : 
      76             :       // Build the nodal solution values & get the variable
      77             :       // names from the EquationSystems object
      78        4900 :       std::vector<Number> soln;
      79       79114 :       es.build_solution_vector (soln, system_names,
      80       74214 :                                 this->get_add_sides());
      81             : 
      82       79114 :       this->write_nodal_data (fname, soln, names);
      83       74214 :     }
      84             :   else // _is_parallel_format
      85         708 :     this->write_nodal_data (fname, es, system_names);
      86       79822 : }
      87             : 
      88             : template <class MT>
      89        1207 : void MeshOutput<MT>::write_discontinuous_equation_systems (const std::string & fname,
      90             :                                                            const EquationSystems & es,
      91             :                                                            const std::set<std::string> * system_names)
      92             : {
      93          68 :   LOG_SCOPE("write_discontinuous_equation_systems()", "MeshOutput");
      94             : 
      95             :   // We may need to gather and/or renumber a DistributedMesh to output
      96             :   // it, making that const qualifier in our constructor a dirty lie
      97        1207 :   MT & my_mesh = const_cast<MT &>(*_obj);
      98             : 
      99             :   // If we're asked to write data that's associated with a different
     100             :   // mesh, output files full of garbage are the result.
     101          34 :   libmesh_assert_equal_to(&es.get_mesh(), _obj);
     102             : 
     103             :   // A non-renumbered mesh may not have a contiguous numbering, and
     104             :   // that needs to be fixed before we can build a solution vector.
     105        2414 :   if (my_mesh.max_elem_id() != my_mesh.n_elem() ||
     106        1207 :       my_mesh.max_node_id() != my_mesh.n_nodes())
     107             :     {
     108             :       // If we were allowed to renumber then we should have already
     109             :       // been properly renumbered...
     110           0 :       libmesh_assert(!my_mesh.allow_renumbering());
     111             : 
     112           0 :       libmesh_do_once(libMesh::out <<
     113             :                       "Warning:  This MeshOutput subclass only supports meshes which are contiguously renumbered!"
     114             :                       << std::endl;);
     115             : 
     116           0 :       my_mesh.allow_renumbering(true);
     117             : 
     118           0 :       my_mesh.renumber_nodes_and_elements();
     119             : 
     120             :       // Not sure what good going back to false will do here, the
     121             :       // renumbering horses have already left the barn...
     122           0 :       my_mesh.allow_renumbering(false);
     123             :     }
     124             : 
     125        1275 :   MeshSerializer serialize(const_cast<MT &>(*_obj), !_is_parallel_format, _serial_only_needed_on_proc_0);
     126             : 
     127             :   // Build the list of variable names that will be written.
     128         102 :   std::vector<std::string> names;
     129        1207 :   es.build_variable_names  (names, nullptr, system_names);
     130             : 
     131        1207 :   if (!_is_parallel_format)
     132             :     {
     133             :       // Build the nodal solution values & get the variable
     134             :       // names from the EquationSystems object
     135          68 :       std::vector<Number> soln;
     136        1207 :       es.build_discontinuous_solution_vector (soln, system_names,
     137             :                                               nullptr, false, /* defaults */
     138        1139 :                                               this->get_add_sides());
     139             : 
     140        1207 :       this->write_nodal_data_discontinuous (fname, soln, names);
     141             :     }
     142             :   else // _is_parallel_format
     143             :     {
     144           0 :       libmesh_not_implemented();
     145             :     }
     146        1207 : }
     147             : 
     148             : template <class MT>
     149           0 : void MeshOutput<MT>::write_nodal_data (const std::string & fname,
     150             :                                        const NumericVector<Number> & parallel_soln,
     151             :                                        const std::vector<std::string> & names)
     152             : {
     153             :   // This is the fallback implementation for parallel I/O formats that
     154             :   // do not yet implement proper writing in parallel, and instead rely
     155             :   // on the full solution vector being available on all processors.
     156           0 :   std::vector<Number> soln;
     157           0 :   parallel_soln.localize(soln);
     158           0 :   this->write_nodal_data(fname, soln, names);
     159           0 : }
     160             : 
     161             : template <class MT>
     162           0 : void MeshOutput<MT>::write_nodal_data (const std::string & fname,
     163             :                                        const EquationSystems & es,
     164             :                                        const std::set<std::string> * system_names)
     165             : {
     166           0 :   std::vector<std::string> names;
     167           0 :   es.build_variable_names  (names, nullptr, system_names);
     168             : 
     169           0 :   std::unique_ptr<NumericVector<Number>> parallel_soln =
     170             :     es.build_parallel_solution_vector(system_names);
     171             : 
     172           0 :   this->write_nodal_data (fname, *parallel_soln, names);
     173           0 : }
     174             : 
     175             : 
     176             : 
     177             : 
     178             : // Instantiate for our Mesh types.  If this becomes too cumbersome later,
     179             : // move any functions in this file to the header file instead.
     180             : template class LIBMESH_EXPORT MeshOutput<MeshBase>;
     181             : template class LIBMESH_EXPORT MeshOutput<UnstructuredMesh>;
     182             : template class LIBMESH_EXPORT MeshOutput<DistributedMesh>;
     183             : 
     184             : } // namespace libMesh

Generated by: LCOV version 1.14