1 //============================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 // This software is distributed WITHOUT ANY WARRANTY; without even
6 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
7 // PURPOSE. See the above copyright notice for more information.
8 //
9 //============================================================================
10
11 #include <fides/FidesTypes.h>
12 #include <fides/predefined/DataModelFactory.h>
13 #include <fides/predefined/DataModelHelperFunctions.h>
14 #include <fides/predefined/InternalMetadataSource.h>
15 #include <fides/predefined/PredefinedDataModel.h>
16 #include <fides/predefined/SupportedDataModels.h>
17
18 #include <fides_rapidjson.h>
19 // clang-format off
20 #include FIDES_RAPIDJSON(rapidjson/document.h)
21 #include FIDES_RAPIDJSON(rapidjson/prettywriter.h)
22 #include FIDES_RAPIDJSON(rapidjson/stringbuffer.h)
23 // clang-format on
24
25 #include <iostream>
26
27 namespace fides
28 {
29 namespace predefined
30 {
31
32 namespace
33 {
34
35 // Registration callbacks for DataModelFactory
CreateUniform(std::shared_ptr<InternalMetadataSource> source)36 std::shared_ptr<PredefinedDataModel> CreateUniform(std::shared_ptr<InternalMetadataSource> source)
37 {
38 return std::shared_ptr<PredefinedDataModel>(new UniformDataModel(source));
39 }
40
CreateUniformFromDataSet(const vtkm::cont::DataSet & dataSet)41 std::shared_ptr<PredefinedDataModel> CreateUniformFromDataSet(const vtkm::cont::DataSet& dataSet)
42 {
43 return std::shared_ptr<PredefinedDataModel>(new UniformDataModel(dataSet));
44 }
45
CreateRectilinearFromDataSet(const vtkm::cont::DataSet & dataSet)46 std::shared_ptr<PredefinedDataModel> CreateRectilinearFromDataSet(
47 const vtkm::cont::DataSet& dataSet)
48 {
49 return std::shared_ptr<PredefinedDataModel>(new RectilinearDataModel(dataSet));
50 }
51
CreateUnstructuredSingleTypeFromDataSet(const vtkm::cont::DataSet & dataSet)52 std::shared_ptr<PredefinedDataModel> CreateUnstructuredSingleTypeFromDataSet(
53 const vtkm::cont::DataSet& dataSet)
54 {
55 return std::shared_ptr<PredefinedDataModel>(new UnstructuredSingleTypeDataModel(dataSet));
56 }
57
CreateUnstructuredFromDataSet(const vtkm::cont::DataSet & dataSet)58 std::shared_ptr<PredefinedDataModel> CreateUnstructuredFromDataSet(
59 const vtkm::cont::DataSet& dataSet)
60 {
61 return std::shared_ptr<PredefinedDataModel>(new UnstructuredDataModel(dataSet));
62 }
63
64
CreateRectilinear(std::shared_ptr<InternalMetadataSource> source)65 std::shared_ptr<PredefinedDataModel> CreateRectilinear(
66 std::shared_ptr<InternalMetadataSource> source)
67 {
68 return std::shared_ptr<PredefinedDataModel>(new RectilinearDataModel(source));
69 }
70
CreateUnstructured(std::shared_ptr<InternalMetadataSource> source)71 std::shared_ptr<PredefinedDataModel> CreateUnstructured(
72 std::shared_ptr<InternalMetadataSource> source)
73 {
74 return std::shared_ptr<PredefinedDataModel>(new UnstructuredDataModel(source));
75 }
76
CreateUnstructuredSingleType(std::shared_ptr<InternalMetadataSource> source)77 std::shared_ptr<PredefinedDataModel> CreateUnstructuredSingleType(
78 std::shared_ptr<InternalMetadataSource> source)
79 {
80 return std::shared_ptr<PredefinedDataModel>(new UnstructuredSingleTypeDataModel(source));
81 }
82
CreateXGC(std::shared_ptr<InternalMetadataSource> source)83 std::shared_ptr<PredefinedDataModel> CreateXGC(std::shared_ptr<InternalMetadataSource> source)
84 {
85 return std::shared_ptr<PredefinedDataModel>(new XGCDataModel(source));
86 }
87
88 // registering data models with the factory
89 const bool uniformRegistered =
90 DataModelFactory::GetInstance().RegisterDataModel(DataModelTypes::UNIFORM, CreateUniform);
91 const bool rectilinearRegistered =
92 DataModelFactory::GetInstance().RegisterDataModel(DataModelTypes::RECTILINEAR, CreateRectilinear);
93 const bool unstructuredRegistered =
94 DataModelFactory::GetInstance().RegisterDataModel(DataModelTypes::UNSTRUCTURED,
95 CreateUnstructured);
96 const bool unstructuredSingleRegistered =
97 DataModelFactory::GetInstance().RegisterDataModel(DataModelTypes::UNSTRUCTURED_SINGLE,
98 CreateUnstructuredSingleType);
99 const bool xgcRegistered =
100 DataModelFactory::GetInstance().RegisterDataModel(DataModelTypes::XGC, CreateXGC);
101
102 const bool uniformDSRegistered =
103 DataModelFactory::GetInstance().RegisterDataModelFromDS(DataModelTypes::UNIFORM,
104 CreateUniformFromDataSet);
105 const bool rectilinearDSRegistered =
106 DataModelFactory::GetInstance().RegisterDataModelFromDS(DataModelTypes::RECTILINEAR,
107 CreateRectilinearFromDataSet);
108 const bool unstructuredSingleDSRegistered =
109 DataModelFactory::GetInstance().RegisterDataModelFromDS(DataModelTypes::UNSTRUCTURED_SINGLE,
110 CreateUnstructuredSingleTypeFromDataSet);
111 const bool unstructuredDSRegistered =
112 DataModelFactory::GetInstance().RegisterDataModelFromDS(DataModelTypes::UNSTRUCTURED,
113 CreateUnstructuredFromDataSet);
114
115 // some helper functions that are used by different data model classes
116
GetOptionalVariableName(std::shared_ptr<InternalMetadataSource> source,const std::string & attrName,const std::string & defaultValue)117 std::string GetOptionalVariableName(std::shared_ptr<InternalMetadataSource> source,
118 const std::string& attrName,
119 const std::string& defaultValue)
120 {
121 if (!source)
122 {
123 return defaultValue;
124 }
125
126 auto vec = source->GetAttribute<std::string>(attrName);
127 if (vec.empty())
128 {
129 return defaultValue;
130 }
131 return vec[0];
132 }
133
GetOptionalVariableName(std::shared_ptr<InternalMetadataSource> source,const std::string & attrName)134 std::pair<bool, std::string> GetOptionalVariableName(std::shared_ptr<InternalMetadataSource> source,
135 const std::string& attrName)
136 {
137 if (!source)
138 {
139 return std::make_pair(false, "");
140 }
141
142 auto vec = source->GetAttribute<std::string>(attrName);
143 if (vec.empty())
144 {
145 return std::make_pair(false, "");
146 }
147 return std::make_pair(true, vec[0]);
148 }
149
GetRequiredVariableName(std::shared_ptr<InternalMetadataSource> source,const std::string & attrName)150 std::string GetRequiredVariableName(std::shared_ptr<InternalMetadataSource> source,
151 const std::string& attrName)
152 {
153 auto dimVarName = source->GetAttribute<std::string>(attrName);
154 if (dimVarName.empty())
155 {
156 throw std::runtime_error(attrName + " must be set for this data model");
157 }
158 return dimVarName[0];
159 }
160
161 const std::string DataModelAttrName = "Fides_Data_Model";
162 const std::string OriginAttrName = "Fides_Origin";
163 const std::string SpacingAttrName = "Fides_Spacing";
164 const std::string DimensionsAttrName = "Fides_Dimensions";
165 const std::string DimensionsVarAttrName = "Fides_Dimension_Variable";
166 const std::string XVarAttrName = "Fides_X_Variable";
167 const std::string YVarAttrName = "Fides_Y_Variable";
168 const std::string ZVarAttrName = "Fides_Z_Variable";
169 const std::string CoordinatesAttrName = "Fides_Coordinates_Variable";
170 const std::string ConnectivityAttrName = "Fides_Connectivity_Variable";
171 const std::string CellTypesAttrName = "Fides_Cell_Types_Variable";
172 const std::string CellTypeAttrName = "Fides_Cell_Type";
173 const std::string NumVertsAttrName = "Fides_Num_Vertices_Variable";
174
175 const std::string VarListAttrName = "Fides_Variable_List";
176 const std::string AssocListAttrName = "Fides_Variable_Associations";
177 const std::string VectorListAttrName = "Fides_Variable_Vectors";
178 const std::string VarSourcesAttrName = "Fides_Variable_Sources";
179 const std::string VarArrayTypesAttrName = "Fides_Variable_Array_Types";
180
181 const std::string XGCNumPlanesAttrName = "Fides_Number_Of_Planes_Variable";
182 const std::string XGCMeshAttrName = "Fides_XGC_Mesh_Filename";
183 const std::string XGC3dAttrName = "Fides_XGC_3d_Filename";
184 const std::string XGCDiagAttrName = "Fides_XGC_Diag_Filename";
185 const std::string XGCTriConnAttrName = "Fides_Triangle_Connectivity_Variable";
186 const std::string XGCPlaneConnAttrName = "Fides_Plane_Connectivity_Variable";
187
createDimensionsJSON(std::shared_ptr<InternalMetadataSource> mdSource,rapidjson::Document::AllocatorType & allocator,rapidjson::Value & arrObj,const std::string & dataSourceName)188 void createDimensionsJSON(std::shared_ptr<InternalMetadataSource> mdSource,
189 rapidjson::Document::AllocatorType& allocator,
190 rapidjson::Value& arrObj,
191 const std::string& dataSourceName)
192 {
193 auto retVal = GetOptionalVariableName(mdSource, DimensionsVarAttrName);
194 std::string dimVarName;
195 if (retVal.first)
196 {
197 dimVarName = retVal.second;
198 CreateValueVariableDimensions(
199 allocator, arrObj, "variable_dimensions", dataSourceName, dimVarName);
200 }
201 else
202 {
203 retVal = GetOptionalVariableName(mdSource, DimensionsAttrName);
204 if (!retVal.first)
205 {
206 throw std::runtime_error(DimensionsAttrName + " or " + DimensionsVarAttrName + " required");
207 }
208 CreateValueArrayVariable(allocator, arrObj, retVal.second, dataSourceName, "dimensions");
209 }
210 }
211
212 } // end anonymous namespace
213
214 //-----------------------------------------------------------------------------
PredefinedDataModel(std::shared_ptr<InternalMetadataSource> source)215 PredefinedDataModel::PredefinedDataModel(std::shared_ptr<InternalMetadataSource> source)
216 : MetadataSource(source)
217 , FieldsToWriteSet(false)
218 {
219 }
220
PredefinedDataModel(const vtkm::cont::DataSet & dataSet)221 PredefinedDataModel::PredefinedDataModel(const vtkm::cont::DataSet& dataSet)
222 : MetadataSource(nullptr)
223 , DataSetSource(dataSet)
224 , FieldsToWriteSet(false)
225 {
226 }
227
GetDOM(bool print)228 rapidjson::Document& PredefinedDataModel::GetDOM(bool print /* = false*/)
229 {
230 this->Doc.SetObject();
231 rapidjson::Value root(rapidjson::kObjectType);
232 this->CreateDataSources(root);
233 this->CreateCoordinateSystem(root);
234 this->CreateCellSet(root);
235 this->CreateFields(root);
236 this->AddStepInformation(root);
237 this->AddRootToDocument(root);
238
239 if (print)
240 {
241 this->PrintJSON();
242 }
243
244 return this->Doc;
245 }
246
CreateDataSources(rapidjson::Value & parent)247 void PredefinedDataModel::CreateDataSources(rapidjson::Value& parent)
248 {
249 rapidjson::Value allSources(rapidjson::kArrayType);
250 this->CreateDataSource(allSources, this->DataSourceName, "input");
251 parent.AddMember("data_sources", allSources, this->Doc.GetAllocator());
252 }
253
CreateDataSource(rapidjson::Value & parent,const std::string & name,const std::string & mode,const std::string & filename)254 void PredefinedDataModel::CreateDataSource(rapidjson::Value& parent,
255 const std::string& name,
256 const std::string& mode,
257 const std::string& filename /*=""*/)
258 {
259 rapidjson::Value source(rapidjson::kObjectType);
260 rapidjson::Value n = SetString(this->Doc.GetAllocator(), name);
261 source.AddMember("name", n, this->Doc.GetAllocator());
262
263 rapidjson::Value m = SetString(this->Doc.GetAllocator(), mode);
264 source.AddMember("filename_mode", m, this->Doc.GetAllocator());
265
266 if (mode == "relative")
267 {
268 rapidjson::Value fn = SetString(this->Doc.GetAllocator(), filename);
269 source.AddMember("filename", fn, this->Doc.GetAllocator());
270 }
271 parent.PushBack(source, this->Doc.GetAllocator());
272 }
273
AddStepInformation(rapidjson::Value & parent)274 void PredefinedDataModel::AddStepInformation(rapidjson::Value& parent)
275 {
276 rapidjson::Value stepInfo(rapidjson::kObjectType);
277 auto srcName = SetString(this->Doc.GetAllocator(), this->DataSourceName);
278 stepInfo.AddMember("data_source", srcName, this->Doc.GetAllocator());
279 parent.AddMember("step_information", stepInfo, this->Doc.GetAllocator());
280 }
281
AddFieldAttributes(std::unordered_map<std::string,std::vector<std::string>> & attrMap)282 void PredefinedDataModel::AddFieldAttributes(
283 std::unordered_map<std::string, std::vector<std::string>>& attrMap)
284 {
285 vtkm::Id numFields = this->DataSetSource.GetNumberOfFields();
286 attrMap[VarListAttrName] = std::vector<std::string>();
287 attrMap[AssocListAttrName] = std::vector<std::string>();
288 attrMap[VectorListAttrName] = std::vector<std::string>();
289 for (vtkm::Id i = 0; i < numFields; i++)
290 {
291 auto field = this->DataSetSource.GetField(i);
292 //If field restriction is turned on, then skip those fields.
293 if (this->FieldsToWriteSet &&
294 this->FieldsToWrite.find(field.GetName()) == this->FieldsToWrite.end())
295 {
296 continue;
297 }
298
299 std::string assoc;
300 if (field.IsFieldCell())
301 {
302 assoc = "cell_set";
303 }
304 else if (field.IsFieldPoint())
305 {
306 assoc = "points";
307 }
308 else
309 {
310 throw std::runtime_error("Unsupported field association");
311 }
312
313 // we handle isVector as string instead of bool, because there's also a
314 // case where it could be "auto", but in this case it's always true or false
315 std::string isVector = "false";
316 if (field.GetData().GetNumberOfComponents() > 1)
317 isVector = "true";
318
319 attrMap[VarListAttrName].push_back(field.GetName());
320 attrMap[AssocListAttrName].push_back(assoc);
321 attrMap[VectorListAttrName].push_back(isVector);
322 }
323 }
324
CreateFields(rapidjson::Value & parent)325 void PredefinedDataModel::CreateFields(rapidjson::Value& parent)
326 {
327 if (this->MetadataSource == nullptr)
328 {
329 vtkm::Id numFields = this->DataSetSource.GetNumberOfFields();
330 rapidjson::Value fieldArr(rapidjson::kArrayType);
331 for (vtkm::Id i = 0; i < numFields; i++)
332 {
333 auto field = this->DataSetSource.GetField(i);
334 //If field restriction is turned on, then skip those fields.
335 if (this->FieldsToWriteSet &&
336 this->FieldsToWrite.find(field.GetName()) == this->FieldsToWrite.end())
337 {
338 continue;
339 }
340
341 rapidjson::Value fieldObj(rapidjson::kObjectType);
342 auto fieldName = SetString(this->Doc.GetAllocator(), field.GetName());
343 fieldObj.AddMember("name", fieldName, this->Doc.GetAllocator());
344 std::string assoc = "unknown";
345 if (field.IsFieldCell())
346 assoc = "cell_set";
347 else if (field.IsFieldPoint())
348 assoc = "points";
349 else
350 throw std::runtime_error("Unsupported field association");
351
352 bool isVector = false;
353 if (field.GetData().GetNumberOfComponents() > 1)
354 isVector = true;
355
356 auto assocStr = SetString(this->Doc.GetAllocator(), assoc);
357 fieldObj.AddMember("association", assocStr, this->Doc.GetAllocator());
358
359 rapidjson::Value arrObj(rapidjson::kObjectType);
360 arrObj.AddMember("array_type", "basic", this->Doc.GetAllocator());
361 auto srcName = SetString(this->Doc.GetAllocator(), this->DataSourceName);
362 arrObj.AddMember("data_source", srcName, this->Doc.GetAllocator());
363 if (isVector)
364 arrObj.AddMember("is_vector", "true", this->Doc.GetAllocator());
365 else
366 arrObj.AddMember("is_vector", "false", this->Doc.GetAllocator());
367
368 arrObj.AddMember(
369 "variable", SetString(this->Doc.GetAllocator(), field.GetName()), this->Doc.GetAllocator());
370 fieldObj.AddMember("array", arrObj, this->Doc.GetAllocator());
371
372 fieldArr.PushBack(fieldObj, this->Doc.GetAllocator());
373 }
374
375 parent.AddMember("fields", fieldArr, this->Doc.GetAllocator());
376 return;
377 }
378
379 auto varList = this->MetadataSource->GetAttribute<std::string>(VarListAttrName);
380 if (varList.empty())
381 {
382 // In this case there are no fields specified in an ADIOS attribute
383 return;
384 }
385 rapidjson::Value fields(rapidjson::kArrayType);
386 rapidjson::Value field(rapidjson::kObjectType);
387 auto varListName = SetString(this->Doc.GetAllocator(), VarListAttrName);
388 field.AddMember("variable_list_attribute_name", varListName, this->Doc.GetAllocator());
389 auto assocListName = SetString(this->Doc.GetAllocator(), AssocListAttrName);
390 field.AddMember("variable_association_attribute_name", assocListName, this->Doc.GetAllocator());
391 auto vecListName = SetString(this->Doc.GetAllocator(), VectorListAttrName);
392 field.AddMember("variable_vector_attribute_name", vecListName, this->Doc.GetAllocator());
393 rapidjson::Value arrObj(rapidjson::kObjectType);
394 CreateArrayBasic(this->Doc.GetAllocator(), arrObj, this->DataSourceName, "");
395 field.AddMember("array", arrObj, this->Doc.GetAllocator());
396 fields.PushBack(field, this->Doc.GetAllocator());
397 parent.AddMember("fields", fields, this->Doc.GetAllocator());
398 }
399
PrintJSON()400 void PredefinedDataModel::PrintJSON()
401 {
402 rapidjson::StringBuffer buf;
403 rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf);
404 this->Doc.Accept(writer);
405 std::cout << buf.GetString() << std::endl;
406 }
407
408 //-----------------------------------------------------------------------------
UniformDataModel(std::shared_ptr<InternalMetadataSource> source)409 UniformDataModel::UniformDataModel(std::shared_ptr<InternalMetadataSource> source)
410 : PredefinedDataModel(source)
411 {
412 }
413
UniformDataModel(const vtkm::cont::DataSet & dataSet)414 UniformDataModel::UniformDataModel(const vtkm::cont::DataSet& dataSet)
415 : PredefinedDataModel(dataSet)
416 {
417 }
418
GetAttributes()419 std::unordered_map<std::string, std::vector<std::string>> UniformDataModel::GetAttributes()
420 {
421 std::unordered_map<std::string, std::vector<std::string>> attrMap;
422 attrMap[DataModelAttrName] = std::vector<std::string>(1, "uniform");
423 attrMap[OriginAttrName] = std::vector<std::string>(1, "origin");
424 attrMap[SpacingAttrName] = std::vector<std::string>(1, "spacing");
425 attrMap[DimensionsAttrName] = std::vector<std::string>(1, "dims");
426 this->AddFieldAttributes(attrMap);
427 return attrMap;
428 }
429
CreateCoordinateSystem(rapidjson::Value & parent)430 void UniformDataModel::CreateCoordinateSystem(rapidjson::Value& parent)
431 {
432 if (this->MetadataSource == nullptr)
433 {
434 auto dcellSet = this->DataSetSource.GetCellSet();
435 if (!dcellSet.IsType<StructuredCell3DType>())
436 {
437 throw "Cellset not uniform 3D.";
438 }
439
440 CreateArrayUniformPointCoordinates(
441 this->Doc.GetAllocator(), parent, "dims", "origin", "spacing");
442 return;
443 }
444
445 rapidjson::Value coordSys(rapidjson::kObjectType);
446 rapidjson::Value arrObj(rapidjson::kObjectType);
447 arrObj.AddMember("array_type", "uniform_point_coordinates", this->Doc.GetAllocator());
448 createDimensionsJSON(
449 this->MetadataSource, this->Doc.GetAllocator(), arrObj, this->DataSourceName);
450
451 CreateValueArray(this->Doc.GetAllocator(),
452 arrObj,
453 this->MetadataSource,
454 OriginAttrName,
455 "origin",
456 this->DataSourceName);
457 CreateValueArray(this->Doc.GetAllocator(),
458 arrObj,
459 this->MetadataSource,
460 SpacingAttrName,
461 "spacing",
462 this->DataSourceName);
463
464 coordSys.AddMember("array", arrObj, this->Doc.GetAllocator());
465 parent.AddMember("coordinate_system", coordSys, this->Doc.GetAllocator());
466 }
467
CreateCellSet(rapidjson::Value & parent)468 void UniformDataModel::CreateCellSet(rapidjson::Value& parent)
469 {
470 if (this->MetadataSource == nullptr)
471 {
472 CreateStructuredCellset(this->Doc.GetAllocator(), parent, "dims");
473 return;
474 }
475 rapidjson::Value cellSet(rapidjson::kObjectType);
476 cellSet.AddMember("cell_set_type", "structured", this->Doc.GetAllocator());
477 createDimensionsJSON(
478 this->MetadataSource, this->Doc.GetAllocator(), cellSet, this->DataSourceName);
479 parent.AddMember("cell_set", cellSet, this->Doc.GetAllocator());
480 }
481
AddRootToDocument(rapidjson::Value & root)482 void UniformDataModel::AddRootToDocument(rapidjson::Value& root)
483 {
484 this->Doc.AddMember("uniform_grid", root, this->Doc.GetAllocator());
485 }
486
487 //-----------------------------------------------------------------------------
RectilinearDataModel(std::shared_ptr<InternalMetadataSource> source)488 RectilinearDataModel::RectilinearDataModel(std::shared_ptr<InternalMetadataSource> source)
489 : PredefinedDataModel(source)
490 {
491 }
492
RectilinearDataModel(const vtkm::cont::DataSet & dataSet)493 RectilinearDataModel::RectilinearDataModel(const vtkm::cont::DataSet& dataSet)
494 : PredefinedDataModel(dataSet)
495 {
496 }
497
GetAttributes()498 std::unordered_map<std::string, std::vector<std::string>> RectilinearDataModel::GetAttributes()
499 {
500 std::unordered_map<std::string, std::vector<std::string>> attrMap;
501 attrMap[DataModelAttrName] = std::vector<std::string>(1, "rectilinear");
502 attrMap[XVarAttrName] = std::vector<std::string>(1, "x_array");
503 attrMap[YVarAttrName] = std::vector<std::string>(1, "y_array");
504 attrMap[ZVarAttrName] = std::vector<std::string>(1, "z_array");
505 attrMap[DimensionsAttrName] = std::vector<std::string>(1, "dims");
506 this->AddFieldAttributes(attrMap);
507 return attrMap;
508 }
509
CreateCoordinateSystem(rapidjson::Value & parent)510 void RectilinearDataModel::CreateCoordinateSystem(rapidjson::Value& parent)
511 {
512 if (this->MetadataSource == nullptr)
513 {
514 auto dcellSet = this->DataSetSource.GetCellSet();
515 if (!dcellSet.IsType<StructuredCell3DType>())
516 {
517 throw "Cellset not structured 3D.";
518 }
519
520 CreateArrayRectilinearPointCoordinates(
521 this->Doc.GetAllocator(), parent, "x_array", "y_array", "z_array");
522 return;
523 }
524
525 rapidjson::Value coordSys(rapidjson::kObjectType);
526 rapidjson::Value arrObj(rapidjson::kObjectType);
527 CreateArrayCartesianProduct(
528 this->Doc.GetAllocator(), arrObj, this->MetadataSource, this->DataSourceName);
529 coordSys.AddMember("array", arrObj, this->Doc.GetAllocator());
530 parent.AddMember("coordinate_system", coordSys, this->Doc.GetAllocator());
531 }
532
CreateCellSet(rapidjson::Value & parent)533 void RectilinearDataModel::CreateCellSet(rapidjson::Value& parent)
534 {
535 if (this->MetadataSource == nullptr)
536 {
537 CreateStructuredCellset(this->Doc.GetAllocator(), parent, "dims");
538 return;
539 }
540
541 rapidjson::Value cellSet(rapidjson::kObjectType);
542 cellSet.AddMember("cell_set_type", "structured", this->Doc.GetAllocator());
543 createDimensionsJSON(
544 this->MetadataSource, this->Doc.GetAllocator(), cellSet, this->DataSourceName);
545 parent.AddMember("cell_set", cellSet, this->Doc.GetAllocator());
546 }
547
AddRootToDocument(rapidjson::Value & root)548 void RectilinearDataModel::AddRootToDocument(rapidjson::Value& root)
549 {
550 this->Doc.AddMember("rectilinear_grid", root, this->Doc.GetAllocator());
551 }
552
553 //-----------------------------------------------------------------------------
UnstructuredDataModel(std::shared_ptr<InternalMetadataSource> source)554 UnstructuredDataModel::UnstructuredDataModel(std::shared_ptr<InternalMetadataSource> source)
555 : PredefinedDataModel(source)
556 {
557 }
558
UnstructuredDataModel(const vtkm::cont::DataSet & dataSet)559 UnstructuredDataModel::UnstructuredDataModel(const vtkm::cont::DataSet& dataSet)
560 : PredefinedDataModel(dataSet)
561 {
562 }
563
GetAttributes()564 std::unordered_map<std::string, std::vector<std::string>> UnstructuredDataModel::GetAttributes()
565 {
566 std::unordered_map<std::string, std::vector<std::string>> attrMap;
567 attrMap[DataModelAttrName] = std::vector<std::string>(1, "unstructured");
568 attrMap[CoordinatesAttrName] = std::vector<std::string>(1, "coordinates");
569 attrMap[ConnectivityAttrName] = std::vector<std::string>(1, "connectivity");
570 attrMap[CellTypesAttrName] = std::vector<std::string>(1, "cell_types");
571 attrMap[NumVertsAttrName] = std::vector<std::string>(1, "num_verts");
572 this->AddFieldAttributes(attrMap);
573 return attrMap;
574 }
575
CreateCoordinateSystem(rapidjson::Value & parent)576 void UnstructuredDataModel::CreateCoordinateSystem(rapidjson::Value& parent)
577 {
578 if (this->MetadataSource == nullptr)
579 {
580 auto dcellSet = this->DataSetSource.GetCellSet();
581 if (!dcellSet.IsType<UnstructuredSingleType>() && !dcellSet.IsType<UnstructuredType>())
582 {
583 throw std::runtime_error("Cellset is not UnstructuredSingleType.");
584 }
585
586 CreateArrayUnstructuredPointCoordinates(this->Doc.GetAllocator(), parent, "coordinates");
587 return;
588 }
589
590 rapidjson::Value coordSys(rapidjson::kObjectType);
591 rapidjson::Value arrObj(rapidjson::kObjectType);
592 auto varName = GetOptionalVariableName(this->MetadataSource, CoordinatesAttrName, "points");
593 CreateArrayBasic(this->Doc.GetAllocator(), arrObj, this->DataSourceName, varName, false);
594 coordSys.AddMember("array", arrObj, this->Doc.GetAllocator());
595 parent.AddMember("coordinate_system", coordSys, this->Doc.GetAllocator());
596 }
597
CreateCellSet(rapidjson::Value & parent)598 void UnstructuredDataModel::CreateCellSet(rapidjson::Value& parent)
599 {
600 rapidjson::Value cellSet(rapidjson::kObjectType);
601 cellSet.AddMember("cell_set_type", "explicit", this->Doc.GetAllocator());
602
603 rapidjson::Value connectivity(rapidjson::kObjectType);
604 std::string connName =
605 GetOptionalVariableName(this->MetadataSource, ConnectivityAttrName, "connectivity");
606 CreateArrayBasic(this->Doc.GetAllocator(), connectivity, this->DataSourceName, connName);
607 cellSet.AddMember("connectivity", connectivity, this->Doc.GetAllocator());
608
609 rapidjson::Value cellTypes(rapidjson::kObjectType);
610 std::string ctName =
611 GetOptionalVariableName(this->MetadataSource, CellTypesAttrName, "cell_types");
612 CreateArrayBasic(this->Doc.GetAllocator(), cellTypes, this->DataSourceName, ctName);
613 cellSet.AddMember("cell_types", cellTypes, this->Doc.GetAllocator());
614
615 rapidjson::Value numVertices(rapidjson::kObjectType);
616 std::string vertName =
617 GetOptionalVariableName(this->MetadataSource, NumVertsAttrName, "num_verts");
618 CreateArrayBasic(this->Doc.GetAllocator(), numVertices, this->DataSourceName, vertName);
619 cellSet.AddMember("number_of_vertices", numVertices, this->Doc.GetAllocator());
620
621 parent.AddMember("cell_set", cellSet, this->Doc.GetAllocator());
622 }
623
AddRootToDocument(rapidjson::Value & root)624 void UnstructuredDataModel::AddRootToDocument(rapidjson::Value& root)
625 {
626 this->Doc.AddMember("unstructured_grid", root, this->Doc.GetAllocator());
627 }
628
629 //-----------------------------------------------------------------------------
UnstructuredSingleTypeDataModel(std::shared_ptr<InternalMetadataSource> source)630 UnstructuredSingleTypeDataModel::UnstructuredSingleTypeDataModel(
631 std::shared_ptr<InternalMetadataSource> source)
632 : UnstructuredDataModel(source)
633 {
634 }
635
UnstructuredSingleTypeDataModel(const vtkm::cont::DataSet & dataSet)636 UnstructuredSingleTypeDataModel::UnstructuredSingleTypeDataModel(const vtkm::cont::DataSet& dataSet)
637 : UnstructuredDataModel(dataSet)
638 {
639 }
640
641 std::unordered_map<std::string, std::vector<std::string>>
GetAttributes()642 UnstructuredSingleTypeDataModel::GetAttributes()
643 {
644 std::unordered_map<std::string, std::vector<std::string>> attrMap;
645 attrMap[DataModelAttrName] = std::vector<std::string>(1, "unstructured_single");
646 attrMap[CoordinatesAttrName] = std::vector<std::string>(1, "coordinates");
647 attrMap[ConnectivityAttrName] = std::vector<std::string>(1, "connectivity");
648
649 const auto& cellSet = this->DataSetSource.GetCellSet().Cast<UnstructuredSingleType>();
650 vtkm::UInt8 shapeId = cellSet.GetCellShape(0);
651 std::string cellType = fides::ConvertVTKmCellTypeToFides(shapeId);
652 attrMap[CellTypeAttrName] = std::vector<std::string>(1, cellType);
653 this->AddFieldAttributes(attrMap);
654 return attrMap;
655 }
656
CreateCellSet(rapidjson::Value & parent)657 void UnstructuredSingleTypeDataModel::CreateCellSet(rapidjson::Value& parent)
658 {
659 if (this->MetadataSource == nullptr)
660 {
661 auto dcellSet = this->DataSetSource.GetCellSet();
662 if (!dcellSet.IsType<UnstructuredSingleType>())
663 {
664 throw std::runtime_error("Cellset is not UnstructuredSingleType");
665 }
666 const auto& cellSet = this->DataSetSource.GetCellSet().Cast<UnstructuredSingleType>();
667 vtkm::UInt8 shapeId = cellSet.GetCellShape(0);
668 std::string cellType = fides::ConvertVTKmCellTypeToFides(shapeId);
669
670 CreateUnstructuredSingleTypeCellset(this->Doc.GetAllocator(), parent, "connectivity", cellType);
671 return;
672 }
673
674 // structured
675 rapidjson::Value cellSet(rapidjson::kObjectType);
676 cellSet.AddMember("cell_set_type", "single_type", this->Doc.GetAllocator());
677
678 std::string cellType = this->MetadataSource->GetDataModelCellType();
679 rapidjson::Value ct = SetString(this->Doc.GetAllocator(), cellType);
680 cellSet.AddMember("cell_type", ct, this->Doc.GetAllocator());
681 auto srcName = SetString(this->Doc.GetAllocator(), this->DataSourceName);
682 cellSet.AddMember("data_source", srcName, this->Doc.GetAllocator());
683
684 auto connName =
685 GetOptionalVariableName(this->MetadataSource, ConnectivityAttrName, "connectivity");
686 auto conn = SetString(this->Doc.GetAllocator(), connName);
687 cellSet.AddMember("variable", conn, this->Doc.GetAllocator());
688
689 parent.AddMember("cell_set", cellSet, this->Doc.GetAllocator());
690 }
691
AddRootToDocument(rapidjson::Value & root)692 void UnstructuredSingleTypeDataModel::AddRootToDocument(rapidjson::Value& root)
693 {
694 this->Doc.AddMember("unstructured_grid_single_cell_type", root, this->Doc.GetAllocator());
695 }
696
697 //-----------------------------------------------------------------------------
XGCDataModel(std::shared_ptr<InternalMetadataSource> source)698 XGCDataModel::XGCDataModel(std::shared_ptr<InternalMetadataSource> source)
699 : PredefinedDataModel(source)
700 {
701 }
702
GetAttributes()703 std::unordered_map<std::string, std::vector<std::string>> XGCDataModel::GetAttributes()
704 {
705 std::unordered_map<std::string, std::vector<std::string>> attrMap;
706 attrMap[DataModelAttrName] = std::vector<std::string>(1, "xgc");
707 this->AddFieldAttributes(attrMap);
708 return attrMap;
709 }
710
GetDOM(bool print)711 rapidjson::Document& XGCDataModel::GetDOM(bool print /* = false*/)
712 {
713 PredefinedDataModel::GetDOM();
714 if (!this->Doc.HasMember("xgc"))
715 {
716 throw std::runtime_error("doc doesn't have xgc member");
717 }
718 auto& root = this->Doc["xgc"];
719 auto nplanes = GetOptionalVariableName(this->MetadataSource, XGCNumPlanesAttrName, "nphi");
720 CreateValueScalar(this->Doc.GetAllocator(), root, "number_of_planes", "scalar", "3d", "nphi");
721
722 if (print)
723 {
724 this->PrintJSON();
725 }
726
727 return this->Doc;
728 }
729
CreateDataSources(rapidjson::Value & parent)730 void XGCDataModel::CreateDataSources(rapidjson::Value& parent)
731 {
732 rapidjson::Value allSources(rapidjson::kArrayType);
733 auto meshFilename = GetOptionalVariableName(this->MetadataSource, XGCMeshAttrName, "xgc.mesh.bp");
734 this->CreateDataSource(allSources, "mesh", "relative", meshFilename);
735 auto dFilename = GetOptionalVariableName(this->MetadataSource, XGC3dAttrName, "xgc.3d.bp");
736 this->CreateDataSource(allSources, "3d", "relative", dFilename);
737 auto diagFilename =
738 GetOptionalVariableName(this->MetadataSource, XGCDiagAttrName, "xgc.oneddiag.bp");
739 this->CreateDataSource(allSources, "diag", "relative", diagFilename);
740 parent.AddMember("data_sources", allSources, this->Doc.GetAllocator());
741 }
742
AddStepInformation(rapidjson::Value & parent)743 void XGCDataModel::AddStepInformation(rapidjson::Value& parent)
744 {
745 rapidjson::Value stepInfo(rapidjson::kObjectType);
746 stepInfo.AddMember("data_source", "3d", this->Doc.GetAllocator());
747 parent.AddMember("step_information", stepInfo, this->Doc.GetAllocator());
748 }
749
CreateCoordinateSystem(rapidjson::Value & parent)750 void XGCDataModel::CreateCoordinateSystem(rapidjson::Value& parent)
751 {
752 rapidjson::Value coordSys(rapidjson::kObjectType);
753 rapidjson::Value arrObj(rapidjson::kObjectType);
754 auto coords = GetOptionalVariableName(this->MetadataSource, CoordinatesAttrName, "rz");
755 CreateArrayXGCCoordinates(this->Doc.GetAllocator(), arrObj, "mesh", coords);
756 coordSys.AddMember("array", arrObj, this->Doc.GetAllocator());
757 parent.AddMember("coordinate_system", coordSys, this->Doc.GetAllocator());
758 }
759
CreateCellSet(rapidjson::Value & parent)760 void XGCDataModel::CreateCellSet(rapidjson::Value& parent)
761 {
762 rapidjson::Value cellSet(rapidjson::kObjectType);
763 cellSet.AddMember("cell_set_type", "xgc", this->Doc.GetAllocator());
764 cellSet.AddMember("periodic", true, this->Doc.GetAllocator());
765
766 auto triConn =
767 GetOptionalVariableName(this->MetadataSource, XGCTriConnAttrName, "nd_connect_list");
768 rapidjson::Value cells(rapidjson::kObjectType);
769 CreateArrayBasic(this->Doc.GetAllocator(), cells, "mesh", triConn);
770 cells.AddMember("static", true, this->Doc.GetAllocator());
771 cells.AddMember("is_vector", "false", this->Doc.GetAllocator());
772 cellSet.AddMember("cells", cells, this->Doc.GetAllocator());
773
774 auto planeConn = GetOptionalVariableName(this->MetadataSource, XGCPlaneConnAttrName, "nextnode");
775 rapidjson::Value conn(rapidjson::kObjectType);
776 CreateArrayBasic(this->Doc.GetAllocator(), conn, "mesh", planeConn);
777 conn.AddMember("static", true, this->Doc.GetAllocator());
778 conn.AddMember("is_vector", "false", this->Doc.GetAllocator());
779 cellSet.AddMember("plane_connectivity", conn, this->Doc.GetAllocator());
780
781 parent.AddMember("cell_set", cellSet, this->Doc.GetAllocator());
782 }
783
CreateFields(rapidjson::Value & parent)784 void XGCDataModel::CreateFields(rapidjson::Value& parent)
785 {
786 rapidjson::Value fields(rapidjson::kArrayType);
787 rapidjson::Value field(rapidjson::kObjectType);
788 auto varListName = SetString(this->Doc.GetAllocator(), VarListAttrName);
789 field.AddMember("variable_list_attribute_name", varListName, this->Doc.GetAllocator());
790 auto assocListName = SetString(this->Doc.GetAllocator(), AssocListAttrName);
791 field.AddMember("variable_association_attribute_name", assocListName, this->Doc.GetAllocator());
792 auto varSourcesName = SetString(this->Doc.GetAllocator(), VarSourcesAttrName);
793 field.AddMember("variable_sources_attribute_name", varSourcesName, this->Doc.GetAllocator());
794 auto varArrayTypesName = SetString(this->Doc.GetAllocator(), VarArrayTypesAttrName);
795 field.AddMember("variable_arrays_attribute_name", varArrayTypesName, this->Doc.GetAllocator());
796
797 rapidjson::Value arrObj(rapidjson::kObjectType);
798 CreateArrayBasic(this->Doc.GetAllocator(), arrObj, "", "", false, "");
799 field.AddMember("array", arrObj, this->Doc.GetAllocator());
800
801 fields.PushBack(field, this->Doc.GetAllocator());
802 parent.AddMember("fields", fields, this->Doc.GetAllocator());
803 }
804
AddRootToDocument(rapidjson::Value & root)805 void XGCDataModel::AddRootToDocument(rapidjson::Value& root)
806 {
807 this->Doc.AddMember("xgc", root, this->Doc.GetAllocator());
808 }
809
810 }
811 }
812