Skip to content

Commit cd648a8

Browse files
authored
Merge pull request #59 from LLNL/bugfix-output
Bugfix output
2 parents 7a54428 + 8414cc2 commit cd648a8

File tree

9 files changed

+1116
-103
lines changed

9 files changed

+1116
-103
lines changed

include/output.hpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,19 @@ class Output{
1919
int output_frequency; /* Output frequency in time domain: write output at every <num> time step. */
2020
std::vector<std::vector<std::string> > outputstr; // List of outputs for each oscillator
2121

22-
bool writefullstate; /* Flag to determin if full state vector should be written to file */
22+
bool writeFullState; /* Flag to determine if full state vector should be written to file */
2323
FILE *ufile; /* File for writing real part of solution vector */
2424
FILE *vfile; /* File for writing imaginary part of solution vector */
25-
std::vector<FILE *>expectedfile; /* Files for writing the evolution of the expected energy levels per oscillator */
26-
FILE *expectedfile_comp; /* File for writing the evolution of the expected energy level of the composite system */
27-
FILE *populationfile_comp; /* File for writing the evolution of the population of the composite system */
25+
26+
std::vector<bool> writeExpectedEnergy; ///< Flag to determine if the evolution of the expected energy per oscillator should be written to files.
27+
bool writeExpectedEnergy_comp; ///< Flag to determine if the evolution of the expected energy of the full composite system should be written to file
28+
std::vector<FILE *>expectedfile; /* Files for writing the evolution of the expected energy per oscillator */
29+
FILE *expectedfile_comp; /* File for writing the evolution of the expected energy level of the full composite system */
30+
31+
std::vector<bool> writePopulation; ///< Flag to determine if the evolution of the energy level occupations per oscillator should be written to files.
32+
bool writePopulation_comp; ///< Flag to determine if the evolution of the energy level occupations of the full composite system should be written to file
2833
std::vector<FILE *>populationfile; /* Files for writing population over time */
34+
FILE *populationfile_comp; /* File for writing the evolution of the population of the composite system */
2935

3036
// VecScatter scat; /* Petsc's scatter context to communicate a state across petsc's cores */
3137
// Vec xseq; /* A sequential vector for IO. */
@@ -49,8 +55,8 @@ class Output{
4955
void writeGradient(Vec grad);
5056

5157
/* Open, write and close files for fullstate and expected energy levels over time */
52-
void openDataFiles(std::string prefix, int initid);
53-
void writeDataFiles(int timestep, double time, const Vec state, MasterEq* mastereq);
54-
void closeDataFiles();
58+
void openTrajectoryDataFiles(std::string prefix, int initid);
59+
void writeTrajectoryDataFiles(int timestep, double time, const Vec state, MasterEq* mastereq);
60+
void closeTrajectoryDataFiles();
5561

5662
};

include/timestepper.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class TimeStepper{
2828
int ntime; // number of time steps
2929
double total_time; // final time
3030
double dt; // time step size
31-
bool writeDataFiles; /* Flag to determine whether or not trajectory data will be written to files during forward simulation */
31+
bool writeTrajectoryDataFiles; /* Flag to determine whether or not trajectory data will be written to files during forward simulation */
3232

3333
Vec redgrad; /* Reduced gradient */
3434

src/main.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ int main(int argc,char **argv)
413413
optimctx->getStartingPoint(xinit);
414414
VecCopy(xinit, optimctx->xinit); // Store the initial guess
415415
if (mpirank_world == 0 && !quietmode) printf("\nStarting primal solver... \n");
416-
optimctx->timestepper->writeDataFiles = true;
416+
optimctx->timestepper->writeTrajectoryDataFiles = true;
417417
objective = optimctx->evalF(xinit);
418418
if (mpirank_world == 0 && !quietmode) printf("\nTotal objective = %1.14e, \n", objective);
419419
optimctx->getSolution(&opt);
@@ -424,7 +424,7 @@ int main(int argc,char **argv)
424424
optimctx->getStartingPoint(xinit);
425425
VecCopy(xinit, optimctx->xinit); // Store the initial guess
426426
if (mpirank_world == 0 && !quietmode) printf("\nStarting adjoint solver...\n");
427-
optimctx->timestepper->writeDataFiles = true;
427+
optimctx->timestepper->writeTrajectoryDataFiles = true;
428428
optimctx->evalGradF(xinit, grad);
429429
VecNorm(grad, NORM_2, &gnorm);
430430
// VecView(grad, PETSC_VIEWER_STDOUT_WORLD);
@@ -440,7 +440,7 @@ int main(int argc,char **argv)
440440
optimctx->getStartingPoint(xinit);
441441
VecCopy(xinit, optimctx->xinit); // Store the initial guess
442442
if (mpirank_world == 0 && !quietmode) printf("\nStarting Optimization solver ... \n");
443-
optimctx->timestepper->writeDataFiles = false;
443+
optimctx->timestepper->writeTrajectoryDataFiles = false;
444444
optimctx->solve(xinit);
445445
optimctx->getSolution(&opt);
446446
}

src/optimproblem.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,7 @@ PetscErrorCode TaoMonitor(Tao tao,void*ptr){
633633
ctx->output->writeControls(params, ctx->timestepper->mastereq, ctx->timestepper->ntime, ctx->timestepper->dt);
634634

635635
// do one last forward evaluation while writing trajectory files
636-
ctx->timestepper->writeDataFiles = true;
636+
ctx->timestepper->writeTrajectoryDataFiles = true;
637637
ctx->evalF(params);
638638

639639
// Print stopping reason to screen

src/output.cpp

Lines changed: 85 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -36,35 +36,44 @@ Output::Output(MapParam& config, MPI_Comm comm_petsc, MPI_Comm comm_init, int no
3636
fprintf(optimfile, "#\"iter\" \"Objective\" \"||Pr(grad)||\" \"LS step\" \"F_avg\" \"Terminal cost\" \"Tikhonov-regul\" \"Penalty-term\" \"State variation\" \"Energy-term\" \"Control variation\"\n");
3737
}
3838

39-
/* Read from config what output is desired */
39+
/* Reset flags and data file pointers */
40+
ufile = NULL;
41+
vfile = NULL;
42+
for (int i=0; i< noscillators; i++) expectedfile.push_back (NULL);
43+
for (int i=0; i< noscillators; i++) populationfile.push_back (NULL);
44+
expectedfile_comp=NULL;
45+
populationfile_comp=NULL;
46+
writeFullState = false;
47+
writeExpectedEnergy_comp = false;
48+
writePopulation_comp = false;
49+
for (int i=0; i<noscillators; i++) writeExpectedEnergy.push_back(false);
50+
for (int i=0; i<noscillators; i++) writePopulation.push_back(false);
51+
52+
/* Parse configuration output strings for each oscillator and set defaults. */
4053
for (int i = 0; i < noscillators; i++){
4154
std::vector<std::string> fillme;
4255
config.GetVecStrParam("output" + std::to_string(i), fillme, "none");
4356
outputstr.push_back(fillme);
4457
}
4558

46-
/* Search through outputstrings to see if any oscillator contains "fullstate" */
47-
writefullstate = false;
48-
for (size_t i=0; i<outputstr.size(); i++) {
49-
for (size_t j=0; j<outputstr[i].size(); j++) {
50-
if (outputstr[i][j].compare("fullstate") == 0 ) writefullstate = true;
59+
/* Check the output strings for each oscillator to determine which files should be written */
60+
for (int i=0; i<noscillators; i++) { // iterates over oscillators
61+
for (size_t j=0; j<outputstr[i].size(); j++) { // iterates over output stings for this oscillator
62+
if (outputstr[i][j].compare("expectedEnergy") == 0) writeExpectedEnergy[i] = true;
63+
if (outputstr[i][j].compare("expectedEnergyComposite") == 0) writeExpectedEnergy_comp = true;
64+
if (outputstr[i][j].compare("population") == 0) writePopulation[i] = true;
65+
if (outputstr[i][j].compare("populationComposite") == 0) writePopulation_comp = true;
66+
if (outputstr[i][j].compare("fullstate") == 0 ) writeFullState = true;
5167
}
5268
}
53-
54-
/* Prepare data output files */
55-
ufile = NULL;
56-
vfile = NULL;
57-
for (size_t i=0; i< outputstr.size(); i++) expectedfile.push_back (NULL);
58-
for (size_t i=0; i< outputstr.size(); i++) populationfile.push_back (NULL);
59-
expectedfile_comp=NULL;
60-
populationfile_comp=NULL;
61-
6269
}
6370

6471

6572
Output::~Output(){
6673
if (mpirank_world == 0 && !quietmode) printf("Output directory: %s\n", datadir.c_str());
6774
if (mpirank_world == 0) fclose(optimfile);
75+
writeExpectedEnergy.clear();
76+
writePopulation.clear();
6877
}
6978

7079

@@ -74,7 +83,6 @@ void Output::writeOptimFile(int optim_iter, double objective, double gnorm, doub
7483
fprintf(optimfile, "%05d %1.14e %1.14e %.8f %1.14e %1.14e %1.14e %1.14e %1.14e %1.14e %1.14e\n", optim_iter, objective, gnorm, stepsize, Favg, costT, tikh_regul, penalty, penalty_dpdm, penalty_energy, penalty_variation);
7584
fflush(optimfile);
7685
}
77-
7886
}
7987

8088
void Output::writeGradient(Vec grad){
@@ -148,110 +156,105 @@ void Output::writeControls(Vec params, MasterEq* mastereq, int ntime, double dt)
148156
}
149157

150158

151-
void Output::openDataFiles(std::string prefix, int initid){
159+
void Output::openTrajectoryDataFiles(std::string prefix, int initid){
152160
char filename[255];
153161

154-
/* Flag to determine if this optimization iteration will write data output */
155-
156-
/* Open files for state vector */
157-
if (mpirank_petsc == 0 && writefullstate ) {
158-
snprintf(filename, 254, "%s/%s_Re.iinit%04d.dat", datadir.c_str(), prefix.c_str(), initid);
159-
ufile = fopen(filename, "w");
160-
snprintf(filename, 254, "%s/%s_Im.iinit%04d.dat", datadir.c_str(), prefix.c_str(), initid);
161-
vfile = fopen(filename, "w");
162-
}
163-
164-
/* Open files for expected energy */
165-
bool writeExpComp = false;
166-
bool writePopComp = false;
162+
// On the first petsc rank, open required files and print header information
167163
if (mpirank_petsc == 0) {
168-
for (size_t i=0; i<outputstr.size(); i++) {
169-
for (size_t j=0; j<outputstr[i].size(); j++) {
170-
if (outputstr[i][j].compare("expectedEnergy") == 0) {
171-
snprintf(filename, 254, "%s/expected%zu.iinit%04d.dat", datadir.c_str(), i, initid);
172-
expectedfile[i] = fopen(filename, "w");
173-
fprintf(expectedfile[i], "#\"time\" \"expected energy level\"\n");
174-
}
175-
if (outputstr[i][j].compare("expectedEnergyComposite") == 0) writeExpComp = true;
176-
if (outputstr[i][j].compare("population") == 0) {
177-
snprintf(filename, 254, "%s/population%zu.iinit%04d.dat", datadir.c_str(), i, initid);
178-
populationfile[i] = fopen(filename, "w");
179-
fprintf(populationfile[i], "#\"time\" \"diagonal of the density matrix\"\n");
180-
}
181-
if (outputstr[i][j].compare("populationComposite") == 0) writePopComp = true;
164+
165+
// Expected energy per oscillator
166+
for (size_t i=0; i<outputstr.size(); i++) { // iterates over oscillators
167+
if (writeExpectedEnergy[i]) {
168+
snprintf(filename, 254, "%s/expected%zu.iinit%04d.dat", datadir.c_str(), i, initid);
169+
expectedfile[i] = fopen(filename, "w");
170+
fprintf(expectedfile[i], "#\"time\" \"expected energy level\"\n");
182171
}
183172
}
184-
if (writeExpComp){
173+
// Expected energy for full composite system
174+
if (writeExpectedEnergy_comp) {
185175
snprintf(filename, 254, "%s/expected_composite.iinit%04d.dat", datadir.c_str(), initid);
186176
expectedfile_comp = fopen(filename, "w");
187177
fprintf(expectedfile_comp, "#\"time\" \"expected energy level\"\n");
188178
}
189-
if (writePopComp){
179+
// Populations per oscillator
180+
for (size_t i=0; i<outputstr.size(); i++) { // iterates over oscillators
181+
if (writePopulation[i]) {
182+
snprintf(filename, 254, "%s/population%zu.iinit%04d.dat", datadir.c_str(), i, initid);
183+
populationfile[i] = fopen(filename, "w");
184+
fprintf(populationfile[i], "#\"time\" \"diagonal of the density matrix\"\n");
185+
}
186+
}
187+
// Population for full composite system
188+
if (writePopulation_comp) {
190189
snprintf(filename, 254, "%s/population_composite.iinit%04d.dat", datadir.c_str(), initid);
191190
populationfile_comp = fopen(filename, "w");
192191
fprintf(populationfile_comp, "#\"time\" \"population\"\n");
193192
}
194-
193+
// Full vectorized state
194+
if (writeFullState ) {
195+
snprintf(filename, 254, "%s/%s_Re.iinit%04d.dat", datadir.c_str(), prefix.c_str(), initid);
196+
ufile = fopen(filename, "w");
197+
snprintf(filename, 254, "%s/%s_Im.iinit%04d.dat", datadir.c_str(), prefix.c_str(), initid);
198+
vfile = fopen(filename, "w");
199+
}
195200
}
196-
197201
}
198202

199-
void Output::writeDataFiles(int timestep, double time, const Vec state, MasterEq* mastereq){
203+
void Output::writeTrajectoryDataFiles(int timestep, double time, const Vec state, MasterEq* mastereq){
200204

201205
/* Write output only every <num> time-steps */
202206
if (timestep % output_frequency == 0) {
203207

204-
205208
/* Write expected energy levels to file */
206209
for (size_t iosc = 0; iosc < expectedfile.size(); iosc++) {
207-
double expected = mastereq->getOscillator(iosc)->expectedEnergy(state);
208-
if (expectedfile[iosc] != NULL) {
209-
fprintf(expectedfile[iosc], "%.8f %1.14e\n", time, expected);
210+
if (writeExpectedEnergy[iosc]) {
211+
double expected = mastereq->getOscillator(iosc)->expectedEnergy(state);
212+
if (mpirank_petsc==0) fprintf(expectedfile[iosc], "%.8f %1.14e\n", time, expected);
210213
}
211214
}
212-
213-
double expected_comp = mastereq->expectedEnergy(state);
214-
if (expectedfile_comp != NULL) {
215-
fprintf(expectedfile_comp, "%.8f %1.14e\n", time, expected_comp);
215+
if (writeExpectedEnergy_comp) {
216+
double expected_comp = mastereq->expectedEnergy(state);
217+
if (mpirank_petsc==0) fprintf(expectedfile_comp, "%.8f %1.14e\n", time, expected_comp);
216218
}
217219

218220
/* Write population to file */
219221
for (size_t iosc = 0; iosc < populationfile.size(); iosc++) {
220-
std::vector<double> pop (mastereq->getOscillator(iosc)->getNLevels(), 0.0);
221-
mastereq->getOscillator(iosc)->population(state, pop);
222-
if (populationfile[iosc] != NULL) {
223-
fprintf(populationfile[iosc], "%.8f ", time);
224-
for (size_t i = 0; i<pop.size(); i++) {
225-
fprintf(populationfile[iosc], " %1.14e", pop[i]);
222+
if (writePopulation[iosc]) {
223+
std::vector<double> pop (mastereq->getOscillator(iosc)->getNLevels(), 0.0);
224+
mastereq->getOscillator(iosc)->population(state, pop);
225+
if (mpirank_petsc == 0) {
226+
fprintf(populationfile[iosc], "%.8f ", time);
227+
for (size_t i = 0; i<pop.size(); i++) {
228+
fprintf(populationfile[iosc], " %1.14e", pop[i]);
229+
}
230+
fprintf(populationfile[iosc], "\n");
226231
}
227-
fprintf(populationfile[iosc], "\n");
228232
}
229233
}
230-
231-
std::vector<double> population_comp;
232-
mastereq->population(state, population_comp);
233-
if (populationfile_comp != NULL) {
234-
fprintf(populationfile_comp, "%.8f ", time);
235-
for (size_t i=0; i<population_comp.size(); i++){
236-
fprintf(populationfile_comp, "%1.14e ", population_comp[i]);
234+
if (writePopulation_comp) {
235+
std::vector<double> population_comp;
236+
mastereq->population(state, population_comp);
237+
if (mpirank_petsc == 0) {
238+
fprintf(populationfile_comp, "%.8f ", time);
239+
for (size_t i=0; i<population_comp.size(); i++){
240+
fprintf(populationfile_comp, "%1.14e ", population_comp[i]);
241+
}
242+
fprintf(populationfile_comp, "\n");
237243
}
238-
fprintf(populationfile_comp, "\n");
239244
}
240245

241-
/* Write full state to file */
242-
if (writefullstate && mpisize_petsc == 1) {
243-
246+
/* Write full state to file. Currently not available if Petsc-parallel */
247+
if (writeFullState && mpisize_petsc == 1) {
244248
/* TODO: Make this work in parallel! */
245249
/* Gather the vector from all petsc processors onto the first one */
246250
// VecScatterCreateToZero(x, &scat, &xseq);
247251
// VecScatterBegin(scat, u->x, xseq, INSERT_VALUES, SCATTER_FORWARD);
248252
// VecScatterEnd(scat, u->x, xseq, INSERT_VALUES, SCATTER_FORWARD);
249253

250-
/* Write full state vector to file */
251-
if (ufile != NULL && vfile != NULL) {
254+
/* On first petsc rank, write full state vector to file */
255+
if (mpirank_petsc == 0) {
252256
fprintf(ufile, "%.8f ", time);
253257
fprintf(vfile, "%.8f ", time);
254-
255258
const PetscScalar *x;
256259
VecGetArrayRead(state, &x);
257260
for (int i=0; i<mastereq->getDim(); i++) {
@@ -262,14 +265,14 @@ void Output::writeDataFiles(int timestep, double time, const Vec state, MasterEq
262265
fprintf(vfile, "\n");
263266
VecRestoreArrayRead(state, &x);
264267
}
265-
/* Destroy scatter context and vector */
266-
// VecScatterDestroy(&scat);
267-
// VecDestroy(&xseq); // TODO create and destroy scatter and xseq in contructor/destructor
268+
/* Destroy scatter context and vector */
269+
// VecScatterDestroy(&scat);
270+
// VecDestroy(&xseq); // TODO create and destroy scatter and xseq in contructor/destructor
268271
}
269272
}
270273
}
271274

272-
void Output::closeDataFiles(){
275+
void Output::closeTrajectoryDataFiles(){
273276

274277
/* Close output data files */
275278
if (ufile != NULL) {

src/timestepper.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ TimeStepper::TimeStepper() {
99
dt = 0.0;
1010
storeFWD = false;
1111
MPI_Comm_rank(MPI_COMM_WORLD, &mpirank_world);
12-
writeDataFiles = false;
12+
writeTrajectoryDataFiles = false;
1313
}
1414

1515
TimeStepper::TimeStepper(MasterEq* mastereq_, int ntime_, double total_time_, Output* output_, bool storeFWD_) : TimeStepper() {
@@ -86,8 +86,8 @@ Vec TimeStepper::getState(size_t tindex){
8686
Vec TimeStepper::solveODE(int initid, Vec rho_t0){
8787

8888
/* Open output files */
89-
if (writeDataFiles) {
90-
output->openDataFiles("rho", initid);
89+
if (writeTrajectoryDataFiles) {
90+
output->openTrajectoryDataFiles("rho", initid);
9191
}
9292

9393
/* Set initial condition */
@@ -118,8 +118,8 @@ Vec TimeStepper::solveODE(int initid, Vec rho_t0){
118118

119119
/* store and write current state. */
120120
if (storeFWD) VecCopy(x, store_states[n]);
121-
if (writeDataFiles) {
122-
output->writeDataFiles(n, tstart, x, mastereq);
121+
if (writeTrajectoryDataFiles) {
122+
output->writeTrajectoryDataFiles(n, tstart, x, mastereq);
123123
}
124124

125125
/* Take one time step */
@@ -159,9 +159,9 @@ Vec TimeStepper::solveODE(int initid, Vec rho_t0){
159159
}
160160

161161
/* Write last time step and close files */
162-
if (writeDataFiles) {
163-
output->writeDataFiles(ntime, ntime*dt, x, mastereq);
164-
output->closeDataFiles();
162+
if (writeTrajectoryDataFiles) {
163+
output->writeTrajectoryDataFiles(ntime, ntime*dt, x, mastereq);
164+
output->closeTrajectoryDataFiles();
165165
}
166166

167167

0 commit comments

Comments
 (0)