Skip to content

Commit e709559

Browse files
committed
SAR: refactor and improve SAR calculations
* new range limit with auto range option to reduce required computation * averaging done only once for all frequencies (massive speedup) * split read and write hdf5 into separate functions * use the (now separate) hdf5 write in the openEMS field proc to reduce redundancy Signed-off-by: Thorsten Liebig <Thorsten.Liebig@gmx.de>
1 parent 52c688d commit e709559

6 files changed

Lines changed: 566 additions & 281 deletions

File tree

Common/processfields_sar.cpp

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -272,46 +272,36 @@ void ProcessFieldsSAR::DumpFDData()
272272
SAR_Calc.SetCellDensities(&cell_density);
273273
SAR_Calc.SetCellWidth(cellWidth);
274274
SAR_Calc.SetCellVolumes(&cell_volume);
275-
SAR_Calc.SetCellCondictivity(&cell_kappa); // cell_kappa will be NULL if m_UseCellKappa is false
276-
double mass = SAR_Calc.CalcTotalMass();
277275

278276
for (size_t n = 0; n<m_FD_Samples.size(); ++n)
279277
{
280-
SAR_Calc.SetEField(m_E_FD_Fields.at(n));
281278
if (!m_UseCellKappa)
282-
SAR_Calc.SetJField(m_J_FD_Fields.at(n));
283-
power = SAR_Calc.CalcSARPower();
284-
SAR_Calc.SetCellVolumes(&cell_volume);
285-
power = SAR_Calc.CalcSARPower();
286-
SAR_Calc.CalcSAR(SAR);
279+
SAR_Calc.AddEFieldAndJField(m_FD_Samples.at(n), m_E_FD_Fields.at(n), m_J_FD_Fields.at(n));
280+
else
281+
SAR_Calc.AddEFieldAndCondictivity(m_FD_Samples.at(n), m_E_FD_Fields.at(n), &cell_kappa);
282+
}
283+
SAR_Calc.CalcSAR();
287284

288-
if (m_fileType==VTK_FILETYPE)
285+
if (m_fileType==VTK_FILETYPE)
286+
{
287+
for (size_t n = 0; n<m_FD_Samples.size(); ++n)
289288
{
290289
stringstream ss;
291290
ss << m_filename << fixed << "_f=" << m_FD_Samples.at(n);
292-
293291
m_Vtk_Dump_File->SetFilename(ss.str());
294292
m_Vtk_Dump_File->ClearAllFields();
295-
m_Vtk_Dump_File->AddScalarField(GetFieldNameByType(m_DumpType),SAR);
293+
m_Vtk_Dump_File->AddScalarField(GetFieldNameByType(m_DumpType), *SAR_Calc.GetSAR(n));
296294
if (m_Vtk_Dump_File->Write()==false)
297295
cerr << "ProcessFieldsSAR::DumpFDData: can't dump to file...! " << endl;
298296
}
299-
else if (m_fileType==HDF5_FILETYPE)
300-
{
301-
stringstream ss;
302-
ss << "f" << n;
303-
if (m_HDF5_Dump_File->WriteScalarField<float>(ss.str(), SAR, g_settings.GetLegacyHFD5Dumps())==false)
304-
cerr << "ProcessFieldsSAR::DumpFDData: can't dump to file...! " << endl;
305-
if (m_HDF5_Dump_File->WriteAtrribute("/FieldData/FD/"+ss.str(),"frequency",(float)m_FD_Samples.at(n))==false)
306-
cerr << "ProcessFieldsSAR::DumpFDData: can't dump to file...! " << endl;
307-
if (m_HDF5_Dump_File->WriteAtrribute("/FieldData/FD/"+ss.str(),"mass",mass)==false)
308-
cerr << "ProcessFieldsSAR::DumpFDData: can't dump mass to file...! " << endl;
309-
if (m_HDF5_Dump_File->WriteAtrribute("/FieldData/FD/"+ss.str(),"power",power)==false)
310-
cerr << "ProcessFieldsSAR::DumpFDData: can't dump power to file...! " << endl;
311-
}
312-
else
313-
cerr << "ProcessFieldsSAR::DumpFDData: unknown File-Type" << endl;
314297
}
298+
else if (m_fileType==HDF5_FILETYPE)
299+
{
300+
if (SAR_Calc.WriteToHDF5(*m_HDF5_Dump_File, g_settings.GetLegacyHFD5Dumps())==false)
301+
cerr << "ProcessFieldsSAR::DumpFDData: can't dump to file...! " << endl;
302+
}
303+
else
304+
cerr << "ProcessFieldsSAR::DumpFDData: unknown File-Type" << endl;
315305
}
316306
for (int n=0;n<3;++n)
317307
delete[] cellWidth[n];

tools/hdf5_file_writer.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -420,15 +420,15 @@ bool HDF5_File_Writer::WriteAtrribute(hid_t loc, std::string attr_name, void con
420420
hid_t attribute_id = H5Acreate(loc, attr_name.c_str(), mem_type, dataspace_id, H5P_DEFAULT, H5P_DEFAULT);
421421
if (attribute_id<0)
422422
{
423-
cerr << "HDF5_File_Writer::WriteAtrribute: Error, failed to create the attribute" << endl;
423+
cerr << "HDF5_File_Writer::WriteAtrribute: Error, failed to create the attribute: " << attr_name << endl;
424424
H5Sclose(dataspace_id);
425425
return false;
426426
}
427427

428428
/* Write the attribute data. */
429429
if (H5Awrite(attribute_id, mem_type, value)<0)
430430
{
431-
cerr << "HDF5_File_Writer::WriteAtrribute: Error, failed to write the attribute" << endl;
431+
cerr << "HDF5_File_Writer::WriteAtrribute: Error, failed to write the attribute" << attr_name << endl;
432432
H5Aclose(attribute_id);
433433
H5Sclose(dataspace_id);
434434
return false;
@@ -468,6 +468,26 @@ bool HDF5_File_Writer::WriteAtrribute(std::string locName, std::string attr_name
468468
return ok;
469469
}
470470

471+
bool HDF5_File_Writer::WriteAtrribute(std::string locName, std::string attr_name, vector<int> values)
472+
{
473+
int* val = new int[values.size()];
474+
for (size_t n=0;n<values.size();++n)
475+
val[n]=values.at(n);
476+
bool ok = HDF5_File_Writer::WriteAtrribute(locName, attr_name, val, values.size(), H5T_NATIVE_INT);
477+
delete[] val; val=NULL;
478+
return ok;
479+
}
480+
481+
bool HDF5_File_Writer::WriteAtrribute(std::string locName, std::string attr_name, vector<unsigned int> values)
482+
{
483+
unsigned int* val = new unsigned int[values.size()];
484+
for (size_t n=0;n<values.size();++n)
485+
val[n]=values.at(n);
486+
bool ok = HDF5_File_Writer::WriteAtrribute(locName, attr_name, val, values.size(), H5T_NATIVE_UINT);
487+
delete[] val; val=NULL;
488+
return ok;
489+
}
490+
471491
bool HDF5_File_Writer::WriteAtrribute(std::string locName, std::string attr_name, float value)
472492
{
473493
return HDF5_File_Writer::WriteAtrribute(locName, attr_name, &value, 0, H5T_NATIVE_FLOAT);

tools/hdf5_file_writer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ class HDF5_File_Writer
5353
bool WriteAtrribute(std::string locName, std::string attr_name, double const* value, hsize_t size);
5454
bool WriteAtrribute(std::string locName, std::string attr_name, std::vector<float> values);
5555
bool WriteAtrribute(std::string locName, std::string attr_name, std::vector<double> values);
56+
bool WriteAtrribute(std::string locName, std::string attr_name, std::vector<int> values);
57+
bool WriteAtrribute(std::string locName, std::string attr_name, std::vector<unsigned int> values);
5658
bool WriteAtrribute(std::string locName, std::string attr_name, float value);
5759
bool WriteAtrribute(std::string locName, std::string attr_name, double value);
5860
bool WriteAtrribute(std::string locName, std::string attr_name, int value);

tools/sar_calc.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,15 @@ int main(int argc, char *argv[])
2727
{
2828
cout << " ---------------------------------------------------------------------- " << endl;
2929
cout << " | SAR calculation for openEMS " << endl;
30-
cout << " | (C) 2012-2025 Thorsten Liebig <thorsten.liebig@gmx.de> GPL license" << endl;
30+
cout << " | (C) 2012-2026 Thorsten Liebig <thorsten.liebig@gmx.de> GPL license" << endl;
3131
cout << " ---------------------------------------------------------------------- " << endl;
3232

3333
options_description desc("Options");
3434
variables_map vm;
3535
try {
3636
string ifile, ofile, method;
3737
double m_avg = 0;
38+
double auto_range=0;
3839
bool debug = false;
3940
bool export_cube_stats = false;
4041
bool legacyHDF5 = false;
@@ -46,6 +47,7 @@ int main(int argc, char *argv[])
4647
("output,o", value(&ofile)->required(), "pathname for output hdf5 file")
4748
("method", value(&method)->default_value("SIMPLE"), "set SAR method: IEEE_C95_3, IEEE_62704, SIMPLE")
4849
("mass,m" , value(&m_avg), "averaging mass in g")
50+
("autorange,a" , value(&auto_range), "autorange, value limit in dB from max. (>0)")
4951
("verbose,v", bool_switch(&debug), "verbose")
5052
("progress,p", bool_switch(&progress), "show progress")
5153
("export_cube_stats,e", bool_switch(&export_cube_stats), "Export Cube Statistics")
@@ -64,11 +66,17 @@ int main(int argc, char *argv[])
6466
sar_calc.SetDebugLevel(int(debug));
6567
sar_calc.EnableProgress(progress);
6668
sar_calc.SetAveragingMass(m_avg/1000);
69+
sar_calc.EnableAutoRange(auto_range);
70+
if (export_cube_stats)
71+
sar_calc.EnableCubeStats();
6772
//sar_calc.SetAveragingMethod(SAR_Calculation::IEEE_62704);
6873
if (!sar_calc.SetAveragingMethod(method, !debug))
6974
return -1;
70-
sar_calc.CalcFromHDF5(ifile, ofile, export_cube_stats, legacyHDF5);
71-
return 0;
75+
if (!sar_calc.ReadFromHDF5(ifile))
76+
return -1;
77+
if (!sar_calc.CalcSAR())
78+
return -1;
79+
return sar_calc.WriteToHDF5(ofile, legacyHDF5);
7280
}
7381
catch(exception& e) {
7482
cerr << e.what() << "\n";

0 commit comments

Comments
 (0)