Chi-Tech
lbs_04a_restartdata.cc
Go to the documentation of this file.
1#include "lbs_solver.h"
2
3#include "chi_runtime.h"
4#include "chi_log.h"
5#include "chi_mpi.h"
6
7#include <sys/stat.h>
8#include <fstream>
9#include <cstring>
10
11//###################################################################
12/**Writes phi_old to restart file.*/
13void lbs::LBSSolver::WriteRestartData(const std::string& folder_name,
14 const std::string& file_base)
15{
16 typedef struct stat Stat;
17 Stat st;
18
19 //======================================== Make sure folder exists
20 if (Chi::mpi.location_id == 0)
21 {
22 if (stat(folder_name.c_str(),&st) != 0) //if not exist, make it
23 if ( (mkdir(folder_name.c_str(),S_IRWXU | S_IRWXG | S_IRWXO) != 0) and
24 (errno != EEXIST) )
25 {
27 << "Failed to create restart directory: " << folder_name;
28 return;
29 }
30 }
31
33
34 //======================================== Create files
35 //This step might fail for specific locations and
36 //can create quite a messy output if we print it all.
37 //We also need to consolidate the error to determine if
38 //the process as whole succeeded.
39 bool location_succeeded = true;
40 char location_cstr[20];
41 snprintf(location_cstr,20,"%d.r", Chi::mpi.location_id);
42
43 std::string file_name = folder_name + std::string("/") +
44 file_base + std::string(location_cstr);
45
46 std::ofstream ofile;
47 ofile.open(file_name, std::ios::out | std::ios::binary | std::ios::trunc);
48
49 if (not ofile.is_open())
50 {
52 << "Failed to create restart file: " << file_name;
53 ofile.close();
54 location_succeeded = false;
55 }
56 else
57 {
58 size_t phi_old_size = phi_old_local_.size();
59 ofile.write((char*)&phi_old_size, sizeof(size_t));
60 for (auto val : phi_old_local_)
61 ofile.write((char*)&val, sizeof(double));
62
63 ofile.close();
64 }
65
66 //======================================== Wait for all processes
67 // then check success status
69 bool global_succeeded = true;
70 MPI_Allreduce(&location_succeeded, //Send buffer
71 &global_succeeded, //Recv buffer
72 1, //count
73 MPI_CXX_BOOL, //Data type
74 MPI_LAND, //Operation - Logical and
75 Chi::mpi.comm); //Communicator
76
77 //======================================== Write status message
78 if (global_succeeded)
80 << "Successfully wrote restart data: "
81 << folder_name + std::string("/") +
82 file_base + std::string("X.r");
83 else
85 << "Failed to write restart data: "
86 << folder_name + std::string("/") +
87 file_base + std::string("X.r");
88}
89
90//###################################################################
91/**Read phi_old from restart file.*/
92void lbs::LBSSolver::ReadRestartData(const std::string& folder_name,
93 const std::string& file_base)
94{
96
97 //======================================== Open files
98 //This step might fail for specific locations and
99 //can create quite a messy output if we print it all.
100 //We also need to consolidate the error to determine if
101 //the process as whole succeeded.
102 bool location_succeeded = true;
103 char location_cstr[20];
104 snprintf(location_cstr,20,"%d.r", Chi::mpi.location_id);
105
106 std::string file_name = folder_name + std::string("/") +
107 file_base + std::string(location_cstr);
108
109 std::ifstream ifile;
110 ifile.open(file_name, std::ios::in | std::ios::binary );
111
112 if (not ifile.is_open())
113 {
114 ifile.close();
115 location_succeeded = false;
116 }
117 else
118 {
119 size_t number_of_unknowns;
120 ifile.read((char*)&number_of_unknowns, sizeof(size_t));
121
122 if (number_of_unknowns != phi_old_local_.size())
123 {
124 location_succeeded = false;
125 ifile.close();
126 }
127 else
128 {
129 std::vector<double> temp_phi_old(phi_old_local_.size(), 0.0);
130
131 size_t v=0;
132 while (not ifile.eof())
133 {
134 ifile.read((char*)&temp_phi_old[v], sizeof(double));
135 ++v;
136 }
137
138 if (v != (number_of_unknowns+1))
139 {
140 location_succeeded = false;
141 ifile.close();
142 }
143 else
144 phi_old_local_ = std::move(temp_phi_old);
145
146 ifile.close();
147 }
148 }
149
150 //======================================== Wait for all processes
151 // then check success status
153 bool global_succeeded = true;
154 MPI_Allreduce(&location_succeeded, //Send buffer
155 &global_succeeded, //Recv buffer
156 1, //count
157 MPI_CXX_BOOL, //Data type
158 MPI_LAND, //Operation - Logical and
159 Chi::mpi.comm); //Communicator
160
161 //======================================== Write status message
162 if (global_succeeded) Chi::log.Log() << "Successfully read restart data";
163 else
165 << "Failed to read restart data: "
166 << folder_name + std::string("/") +
167 file_base + std::string("X.r");
168}
static chi::ChiLog & log
Definition: chi_runtime.h:81
static chi::MPI_Info & mpi
Definition: chi_runtime.h:78
LogStream LogAllError()
Definition: chi_log.h:239
LogStream Log0Warning()
Definition: chi_log.h:231
LogStream Log0Error()
Definition: chi_log.h:232
LogStream Log(LOG_LVL level=LOG_0)
Definition: chi_log.cc:35
void Barrier() const
Definition: mpi_info.cc:38
void WriteRestartData(const std::string &folder_name, const std::string &file_base)
std::vector< double > phi_old_local_
Definition: lbs_solver.h:95
void ReadRestartData(const std::string &folder_name, const std::string &file_base)