MFEM v4.10.0
Finite element discretization library
Loading...
Searching...
No Matches
compare-dc.cpp
Go to the documentation of this file.
1// Copyright (c) 2010-2026, 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-806117.
4//
5// This file is part of the MFEM library. For more information and source code
6// availability visit https://mfem.org.
7//
8// MFEM 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// Compare DC Miniapp: Compare fields saved via DataCollection classes
14// -------------------------------------------------------------------
15//
16// This miniapp loads previously saved data and computes the l2 norm of the
17// difference. Currently, only the VisItDataCollection class is supported.
18//
19// Compile with: make compare-dc
20//
21// Serial sample runs:
22// > compare-dc -r0 ../../examples/Example5 -r1 ../../examples/alt/Example5
23// > compare-dc -r0 Example5 -r1 alt/Example5 -tol 1e-6
24//
25// Parallel sample runs:
26// > mpirun -np 4 compare-dc -r0 ../../examples/Example5-Parallel
27// -r1 ../../examples/alt/Example5-Parallel
28//
29// NB: when no tolerance is provided the difference is simple reported.
30// If a tolerance is provided this is compared with the symmetric
31// relative difference. An error is given if difference exceeds the tolerance.
32
33#include "mfem.hpp"
34
35using namespace std;
36using namespace mfem;
37
38int main(int argc, char *argv[])
39{
40#ifdef MFEM_USE_MPI
41 Mpi::Init();
44#endif
45
46 // Parse command-line options.
47 const char *coll_name0 = NULL;
48 const char *coll_name1 = NULL;
49 int cycle = 0;
50 int pad_digits_cycle = 6;
51 int pad_digits_rank = 6;
52 real_t tol = -1;
53
54 OptionsParser args(argc, argv);
55 args.AddOption(&coll_name0, "-r0", "--root-file_0",
56 "Set the VisIt data collection root file prefix.", true);
57 args.AddOption(&coll_name1, "-r1", "--root-file_1",
58 "Set the VisIt data collection root file prefix.", true);
59 args.AddOption(&cycle, "-c", "--cycle", "Set the cycle index to read.");
60 args.AddOption(&pad_digits_cycle, "-pdc", "--pad-digits-cycle",
61 "Number of digits in cycle.");
62 args.AddOption(&pad_digits_rank, "-pdr", "--pad-digits-rank",
63 "Number of digits in MPI rank.");
64 args.AddOption(&tol, "-tol", "--tolerance",
65 "Tolerance for checking the results.");
66 args.Parse();
67 if (!args.Good())
68 {
70 return 1;
71 }
73
74#ifdef MFEM_USE_MPI
75 VisItDataCollection dc0(MPI_COMM_WORLD, coll_name0);
76#else
77 VisItDataCollection dc0(coll_name0);
78#endif
79 dc0.SetPadDigitsCycle(pad_digits_cycle);
80 dc0.SetPadDigitsRank(pad_digits_rank);
81 dc0.Load(cycle);
82
84 {
85 mfem::out << "Error loading VisIt data collection: " << coll_name0 << endl;
86 return 1;
87 }
88
89#ifdef MFEM_USE_MPI
90 VisItDataCollection dc1(MPI_COMM_WORLD, coll_name1);
91#else
92 VisItDataCollection dc1(coll_name1);
93#endif
94 dc1.SetPadDigitsCycle(pad_digits_cycle);
95 dc1.SetPadDigitsRank(pad_digits_rank);
96 dc1.Load(cycle);
97
99 {
100 mfem::out << "Error loading VisIt data collection: " << coll_name1 << endl;
101 return 1;
102 }
103
104 typedef DataCollection::FieldMapType fields_t;
105 const fields_t &fields0 = dc0.GetFieldMap();
106 // Print the names of all fields.
107 bool error = false;
108 for (fields_t::const_iterator it0 = fields0.begin();
109 it0 != fields0.end() ; ++it0)
110 {
111 GridFunction *gf0 = dc0.GetField(it0->first);
112 if (!gf0)
113 {
114 mfem::out << "Error loading:"<<it0->first<< endl;
115 mfem::out << "From data collection: " << coll_name0 << endl;
116 return 1;
117 }
118
119 GridFunction *gf1 = dc1.GetField(it0->first);
120 if (!gf1)
121 {
122 mfem::out << "Error loading:"<<it0->first<< endl;
123 mfem::out << "From data collection: " << coll_name1 << endl;
124 return 1;
125 }
126 if (gf0->Size() != gf1->Size())
127 {
128 mfem::out << "Size error for:"<<it0->first<< endl;
129 mfem::out << "In data collection: " << coll_name0
130 <<" size is "<<gf0->Size()<< endl;
131 mfem::out << "In data collection: " << coll_name1
132 <<" size is "<<gf1->Size()<< endl;
133 return 1;
134 }
135
136 // Norm of vectors
137 real_t nrm0 = gf0->Norml2();
138 real_t nrm1 = gf1->Norml2();
139
140 // Difference
141 (*gf0) -= (*gf1);
142 real_t nrmd = gf0->Norml2();
143 real_t rel_sym = 2*nrmd/(nrm0 + nrm1);
144 if (gf0->Norml2() > rel_sym) { error = true; }
145
146 // Report
147 mfem::out <<"==========================================="<<std::endl;
148 mfem::out <<"|"<<it0->first<<"_0| = "<<nrm0<<std::endl;
149 mfem::out <<"|"<<it0->first<<"_1| = "<<nrm1<<std::endl;
150 mfem::out <<"\n|"<<it0->first<<"_0 - "<<it0->first<<"_1| = "<<nrmd <<std::endl;
151
152 mfem::out <<"\n2|"<<it0->first<<"_0 - "<<it0->first<<"_1|"<<std::endl;
153 mfem::out << std::setfill('-') << std::setw(15 + 2*it0->first.length())
154 <<" = "<<rel_sym<<std::endl;
155 mfem::out <<"(|"<<it0->first<<"_0| + |"<<it0->first<<"_1|)\n"<<std::endl;
156
157 }
158
159 if (error && tol > 0.0)
160 {
161 mfem::out << "Data collections: " << coll_name0
162 << " & " << coll_name1 << " are outside of the tolerance!\n";
163 return -1;
164 }
165 return 0;
166}
virtual void SetPadDigitsRank(int digits)
Set the number of digits used for the MPI rank in filenames.
int Error() const
Get the current error state.
GridFunction * GetField(const std::string &field_name)
Get a pointer to a grid function in the collection.
const FieldMapType & GetFieldMap() const
Get a const reference to the internal field map.
GFieldMap::MapType FieldMapType
virtual void SetPadDigitsCycle(int digits)
Set the number of digits used for the cycle.
Class for grid function - Vector with associated FE space.
Definition gridfunc.hpp:53
static void Init()
Initialize hypre by calling HYPRE_Init() and set default options. After calling Hypre::Init(),...
Definition hypre.cpp:33
static bool Root()
Return true if the rank in MPI_COMM_WORLD is zero.
static void Init(int &argc, char **&argv, int required=default_thread_required, int *provided=nullptr)
Singleton creation with Mpi::Init(argc, argv).
void Parse()
Parse the command-line options. Note that this function expects all the options provided through the ...
void PrintUsage(std::ostream &out) const
Print the usage message.
void PrintOptions(std::ostream &out) const
Print the options.
void AddOption(bool *var, const char *enable_short_name, const char *enable_long_name, const char *disable_short_name, const char *disable_long_name, const char *description, bool required=false)
Add a boolean option and set 'var' to receive the value. Enable/disable tags are used to set the bool...
Definition optparser.hpp:82
bool Good() const
Return true if the command line options were parsed successfully.
void Disable()
Disable output.
Definition globals.hpp:54
real_t Norml2() const
Returns the l2 norm of the vector.
Definition vector.cpp:968
int Size() const
Returns the size of the vector.
Definition vector.hpp:234
Data collection with VisIt I/O routines.
void Load(int cycle_=0) override
Load the collection based on its VisIt data (described in its root file)
int main()
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
Definition globals.hpp:66
OutStream err(std::cerr)
Global stream used by the library for standard error output. Initially it uses the same std::streambu...
Definition globals.hpp:71
float real_t
Definition config.hpp:46
STL namespace.