@@ -222,111 +222,118 @@ namespace hemelb::extraction
222222      }
223223    }
224224
225-     void  LocalPropertyOutput::Write (unsigned  long  timestepNumber, unsigned  long  totalSteps)
225+     std::optional<std::filesystem::path>
226+     LocalPropertyOutput::Write (unsigned  long  timestepNumber, unsigned  long  totalSteps)
226227    {
227228        //  Don't write if we shouldn't this iteration.
228229        if  (!ShouldWrite (timestepNumber))
229230        {
230-             return ;
231+             return  std:: nullopt ;
231232        }
232233
234+         std::filesystem::path ans;
233235        if  (std::holds_alternative<single_timestep_files>(outputSpec.ts_mode )) {
234236            std::string fn = output_file_pattern.Format (timestepNumber, totalSteps);
235237            StartFile (fn);
238+             ans = fn;
239+         } else  {
240+             ans = outputSpec.filename ;
236241        }
237242
238243        //  Don't write if this core doesn't do anything.
239-       if  (local_data_write_length > 0 )
240-       {
241- 	 //  Create the buffer.
242- 	 auto  xdrWriter = io::MakeXdrWriter (buffer.begin (), buffer.end ());
243- 
244- 	 //  Firstly, the IO proc must write the iteration number.
245- 	 if  (comms.OnIORank ())
246- 	 {
247- 	   xdrWriter << (uint64_t ) timestepNumber;
248- 	 }
249- 
250- 	 dataSource->Reset ();
251- 
252- 	 while  (dataSource->ReadNext ())
253- 	 {
254- 	   const  util::Vector3D<site_t >& position = dataSource->GetPosition ();
255- 	   if  (outputSpec.geometry ->Include (*dataSource, position))
256- 	   {
257- 	     //  Write the position
258- 	     xdrWriter << (uint32_t ) position.x () << (uint32_t ) position.y () << (uint32_t ) position.z ();
259- 
260- 	     //  Write for each field.
261- 	     for  (auto & fieldSpec: outputSpec.fields )
262- 	     {
263- 	       overload_visit (
264- 	         fieldSpec.src ,
265- 		 [&](source::Pressure) {
266- 		   write (xdrWriter, fieldSpec.typecode , dataSource->GetPressure () - fieldSpec.offset [0 ]);
267- 		 },
268- 		 [&](source::Velocity) {
269- 		   auto && v = dataSource->GetVelocity ();
270- 		   write (xdrWriter, fieldSpec.typecode , v.x (), v.y (), v.z ());
271- 		 },
272- 		 // ! @TODO: Work out how to handle the different stresses.
273- 		 [&](source::VonMisesStress) {
274- 		   write (xdrWriter, fieldSpec.typecode , dataSource->GetVonMisesStress ());
275- 		 },
276- 		 [&](source::ShearStress) {
277- 		   write (xdrWriter, fieldSpec.typecode , dataSource->GetShearStress ());
278- 		 },
279- 		 [&](source::ShearRate) {
280- 		   write (xdrWriter, fieldSpec.typecode , dataSource->GetShearRate ());
281- 		 },
282- 		 [&](source::StressTensor) {
283- 		   util::Matrix3D tensor = dataSource->GetStressTensor ();
284- 		   //  Only the upper triangular part of the symmetric
285- 		   //  tensor is stored. Storage is row-wise.
286- 		   write (xdrWriter, fieldSpec.typecode ,
287- 			 tensor[0 ][0 ], tensor[0 ][1 ], tensor[0 ][2 ],
288-                                       tensor[1 ][1 ], tensor[1 ][2 ],
289-                                                      tensor[2 ][2 ]);
290- 		 },
291- 		 [&](source::Traction) {
292- 		   auto && t = dataSource->GetTraction ();
293- 		   write (xdrWriter, fieldSpec.typecode , t.x (), t.y (), t.z ());
294- 		 },
295- 		 [&](source::TangentialProjectionTraction) {
296- 		   auto && t = dataSource->GetTangentialProjectionTraction ();
297- 		   write (xdrWriter, fieldSpec.typecode , t.x (), t.y (), t.z ());
298- 		 },
299- 		 [&](source::Distributions) {
300- 		   unsigned  numComponents = dataSource->GetNumVectors ();
301- 		   distribn_t  const * d_ptr = dataSource->GetDistribution ();
302- 		   for  (auto  i = 0U ; i < numComponents; i++)
303- 		   {
304- 		     write (xdrWriter, fieldSpec.typecode , d_ptr[i]);
305- 		   }
306- 		 },
307- 		 [&](source::MpiRank) {
308- 		   write (xdrWriter, fieldSpec.typecode , comms.Rank ());
309- 		 }
310-               );
311- 	     }
312- 	   }
313- 	 }
314- 
315- 	 //  Actually do the MPI writing.
316- 	 outputFile.WriteAt (local_write_start, buffer);
317-       }
244+          if  (local_data_write_length > 0 )
245+          {
246+              //  Create the buffer.
247+              auto  xdrWriter = io::MakeXdrWriter (buffer.begin (), buffer.end ());
248+ 
249+              //  Firstly, the IO proc must write the iteration number.
250+              if  (comms.OnIORank ())
251+              {
252+                  xdrWriter << (uint64_t ) timestepNumber;
253+              }
254+ 
255+              dataSource->Reset ();
256+ 
257+              while  (dataSource->ReadNext ())
258+              {
259+                  const  util::Vector3D<site_t >& position = dataSource->GetPosition ();
260+                  if  (outputSpec.geometry ->Include (*dataSource, position))
261+                  {
262+                      //  Write the position
263+                      xdrWriter << (uint32_t ) position.x () << (uint32_t ) position.y () << (uint32_t ) position.z ();
264+ 
265+                      //  Write for each field.
266+                      for  (auto & fieldSpec: outputSpec.fields )
267+                      {
268+                          overload_visit (
269+                                  fieldSpec.src ,
270+                                  [&](source::Pressure) {
271+                                      write (xdrWriter, fieldSpec.typecode , dataSource->GetPressure () - fieldSpec.offset [0 ]);
272+                                  },
273+                                  [&](source::Velocity) {
274+                                      auto && v = dataSource->GetVelocity ();
275+                                      write (xdrWriter, fieldSpec.typecode , v.x (), v.y (), v.z ());
276+                                  },
277+                                  // ! @TODO: Work out how to handle the different stresses.
278+                                  [&](source::VonMisesStress) {
279+                                      write (xdrWriter, fieldSpec.typecode , dataSource->GetVonMisesStress ());
280+                                  },
281+                                  [&](source::ShearStress) {
282+                                      write (xdrWriter, fieldSpec.typecode , dataSource->GetShearStress ());
283+                                  },
284+                                  [&](source::ShearRate) {
285+                                      write (xdrWriter, fieldSpec.typecode , dataSource->GetShearRate ());
286+                                  },
287+                                  [&](source::StressTensor) {
288+                                      util::Matrix3D tensor = dataSource->GetStressTensor ();
289+                                      //  Only the upper triangular part of the symmetric
290+                                      //  tensor is stored. Storage is row-wise.
291+                                      write (xdrWriter, fieldSpec.typecode ,
292+                                            tensor[0 ][0 ], tensor[0 ][1 ], tensor[0 ][2 ],
293+                                            tensor[1 ][1 ], tensor[1 ][2 ],
294+                                           tensor[2 ][2 ]);
295+                                  },
296+                                  [&](source::Traction) {
297+                                      auto && t = dataSource->GetTraction ();
298+                                      write (xdrWriter, fieldSpec.typecode , t.x (), t.y (), t.z ());
299+                                  },
300+                                  [&](source::TangentialProjectionTraction) {
301+                                      auto && t = dataSource->GetTangentialProjectionTraction ();
302+                                      write (xdrWriter, fieldSpec.typecode , t.x (), t.y (), t.z ());
303+                                  },
304+                                  [&](source::Distributions) {
305+                                      unsigned  numComponents = dataSource->GetNumVectors ();
306+                                      distribn_t  const * d_ptr = dataSource->GetDistribution ();
307+                                      for  (auto  i = 0U ; i < numComponents; i++)
308+                                      {
309+                                          write (xdrWriter, fieldSpec.typecode , d_ptr[i]);
310+                                      }
311+                                  },
312+                                  [&](source::MpiRank) {
313+                                      write (xdrWriter, fieldSpec.typecode , comms.Rank ());
314+                                  }
315+                          );
316+                      }
317+                  }
318+              }
319+ 
320+              //  Actually do the MPI writing.
321+              outputFile.WriteAt (local_write_start, buffer);
322+          }
318323
319-       overload_visit (
320-         outputSpec.ts_mode ,
321- 	[this ](multi_timestep_file) {
322- 	  //  Set the offset to the right place for writing on the next
323- 	  //  iteration.
324- 	  local_write_start += global_data_write_length;
325- 	},
326- 	[this ](single_timestep_files) {
327- 	  outputFile.Close ();
328- 	}
329-       );
324+         overload_visit (
325+                 outputSpec.ts_mode ,
326+                 [this ](multi_timestep_file) {
327+                     //  Set the offset to the right place for writing on the next
328+                     //  iteration.
329+                     local_write_start += global_data_write_length;
330+                 },
331+                 [this ](single_timestep_files) {
332+                     outputFile.Close ();
333+                 }
334+         );
335+ 
336+         return  ans;
330337    }
331338
332339    //  Write the offset file.
0 commit comments