NEMoSys  0.63.0
A modular, extensible resource with robust automated mesh generation, mesh quality analysis, adaptive mesh refinement, and data transfer between arbitrary meshes.
ConservativeSurfaceTransfer.C
Go to the documentation of this file.
1 /*******************************************************************************
2 * Promesh *
3 * Copyright (C) 2022, IllinoisRocstar LLC. All rights reserved. *
4 * *
5 * Promesh is the property of IllinoisRocstar LLC. *
6 * *
7 * IllinoisRocstar LLC *
8 * Champaign, IL *
9 * www.illinoisrocstar.com *
10 * promesh@illinoisrocstar.com *
11 *******************************************************************************/
12 /*******************************************************************************
13 * This file is part of Promesh *
14 * *
15 * This version of Promesh is free software: you can redistribute it and/or *
16 * modify it under the terms of the GNU Lesser General Public License as *
17 * published by the Free Software Foundation, either version 3 of the License, *
18 * or (at your option) any later version. *
19 * *
20 * Promesh is distributed in the hope that it will be useful, but WITHOUT ANY *
21 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more *
23 * details. *
24 * *
25 * You should have received a copy of the GNU Lesser General Public License *
26 * along with this program. If not, see <https://www.gnu.org/licenses/>. *
27 * *
28 *******************************************************************************/
30 
31 #include <vtkDoubleArray.h>
32 #include <vtkPointData.h>
33 #include <vtkPolyData.h>
34 
35 #include <com.h>
36 
37 #include "AuxiliaryFunctions.H"
38 
39 // debug
40 #include <iostream>
41 
42 COM_EXTERN_MODULE(SurfX)
43 COM_EXTERN_MODULE(SimOut)
44 
46  meshBase *_target) {
47  source = _source;
48  target = _target;
49 }
50 
52  const std::vector<int> &arrayIds,
53  const std::vector<std::string> &newnames) {
54 
55  COM_init(NULL, NULL);
56  COM_set_profiling(1);
57  // COM_set_verbose(10);
58 
59  MPI_Comm comm = MPI_COMM_WORLD;
60 
61  COM_LOAD_MODULE_STATIC_DYNAMIC(SurfX, "RFC");
62 
63  RFC_clear = COM_get_function_handle("RFC.clear_overlay");
64  RFC_read = COM_get_function_handle("RFC.read_overlay");
65  RFC_write = COM_get_function_handle("RFC.write_overlay");
66  RFC_overlay = COM_get_function_handle("RFC.overlay");
67  RFC_transfer = COM_get_function_handle("RFC.least_squares_transfer");
68  RFC_interp = COM_get_function_handle("RFC.interpolate");
69 
70  vtkDataSet *sourceDataSet = source->getDataSet();
71  vtkDataSet *targetDataSet = target->getDataSet();
72 
73  std::vector<double> sourceCoords;
74  std::vector<int> sourceElems;
75  extractDataFromVTK(sourceDataSet, sourceCoords, sourceElems);
76 
77  // === SOURCE WINDOW ===
78 
79  COM_new_window("sourceWindow");
80 
81  // set source nodal coordinates (nc)
82  COM_set_size("sourceWindow.nc", 1, sourceCoords.size() / 3);
83  COM_set_array("sourceWindow.nc", 1, &sourceCoords[0], 3);
84  // set source element node ids (:t3:)
85  COM_set_size("sourceWindow.:t3:", 1, sourceElems.size() / 3);
86  COM_set_array("sourceWindow.:t3:", 1, &sourceElems[0], 3);
87 
88  // initialize source soln array - this is reused
89  COM_new_dataitem("sourceWindow.soln", 'n', COM_DOUBLE, 1, "");
90 
91  COM_window_init_done("sourceWindow");
92 
93  // === TARGET WINDOW ===
94 
95  std::vector<double> targetCoords;
96  std::vector<int> targetElems;
97  extractDataFromVTK(target->getDataSet(), targetCoords, targetElems);
98 
99  COM_new_window("targetWindow");
100  // set target nodal coordinates (nc)
101  COM_set_size("targetWindow.nc", 1, targetCoords.size() / 3);
102  COM_set_array("targetWindow.nc", 1, &targetCoords[0], 3);
103  // set target element node ids (:t3:)
104  COM_set_size("targetWindow.:t3:", 1, targetElems.size() / 3);
105  COM_set_array("targetWindow.:t3:", 1, &targetElems[0], 3);
106 
107  // initialize target soln array - this is reused
108  std::vector<double> targetData(targetCoords.size(), -1.);
109  COM_new_dataitem("targetWindow.soln", 'n', COM_DOUBLE, 1, "m/s");
110  COM_resize_array("targetWindow.soln");
111 
112  COM_window_init_done("targetWindow");
113 
114  // === OVERLAY ===
115  int srcMesh = COM_get_dataitem_handle("sourceWindow.mesh");
116  int tgtMesh = COM_get_dataitem_handle("targetWindow.mesh");
117  COM_call_function(RFC_overlay, &srcMesh, &tgtMesh);
118 
119  // === TRANSFER ===
120  // set source data and transfer
121  int srcData = COM_get_dataitem_handle("sourceWindow.soln");
122  int tgtData = COM_get_dataitem_handle("targetWindow.soln");
123 
124  // source data buffer
125  std::vector<double> sourceData(sourceCoords.size());
126  // transfer specified arrays
127  for (const int &arrayId : arrayIds) {
128  vtkSmartPointer<vtkDataArray> sourceArray =
129  sourceDataSet->GetPointData()->GetArray(arrayId);
130 
131  auto targetPointValues = vtkSmartPointer<vtkDoubleArray>::New();
132  targetPointValues->SetName(sourceArray->GetName());
133  targetPointValues->SetNumberOfComponents(
134  sourceArray->GetNumberOfComponents());
135 
136  for (int componentId = 0;
137  componentId < sourceArray->GetNumberOfComponents(); ++componentId) {
138  auto sourcePointValues = vtkDoubleArray::SafeDownCast(
139  sourceDataSet->GetPointData()->GetArray(arrayId));
140 
141  for (int srcNodeId = 0; srcNodeId < sourceCoords.size() / 3;
142  ++srcNodeId) {
143  sourceData[srcNodeId] =
144  sourcePointValues->GetComponent(srcNodeId, componentId);
145  }
146 
147  COM_set_array("sourceWindow.soln", 1, &sourceData[0]);
148 
149  // transfer
150  COM_call_function(RFC_transfer, &srcData, &tgtData);
151 
152  void *addr;
153  double *data;
154 
155  // window var, pane number, addr
156  COM_get_array("targetWindow.soln", 1, &addr);
157  data = (double *)addr;
158 
159  for (int trgNodeId = 0; trgNodeId < targetCoords.size() / 3;
160  ++trgNodeId) {
161  targetPointValues->InsertComponent(trgNodeId, componentId,
162  data[trgNodeId]);
163  }
164  }
165 
166  targetDataSet->GetPointData()->AddArray(targetPointValues);
167  }
168 
169  COM_finalize();
170 
171  return 0;
172 }
173 
175 {
176  // TODO Find a way to resolve scoping with COM
177  // this initialization should not need to happen in more than one function
178  COM_init(NULL, NULL);
179  COM_set_profiling(1);
180  // COM_set_verbose(10);
181 
182  MPI_Comm comm = MPI_COMM_WORLD;
183 
184  COM_LOAD_MODULE_STATIC_DYNAMIC(SurfX, "RFC");
185 
186  RFC_write = COM_get_function_handle("RFC.write_overlay");
187  RFC_overlay = COM_get_function_handle("RFC.overlay");
188 
189  vtkDataSet *sourceDataSet = source->getDataSet();
190  vtkDataSet *targetDataSet = target->getDataSet();
191 
192  std::vector<double> sourceCoords;
193  std::vector<int> sourceElems;
194  extractDataFromVTK(sourceDataSet, sourceCoords, sourceElems);
195 
196  // === SOURCE WINDOW ===
197  COM_new_window("sourceWindow");
198 
199  // set source nodal coordinates (nc)
200  COM_set_size("sourceWindow.nc", 1, sourceCoords.size() / 3);
201  COM_set_array("sourceWindow.nc", 1, &sourceCoords[0], 3);
202  // set source element node ids (:t3:)
203  COM_set_size("sourceWindow.:t3:", 1, sourceElems.size() / 3);
204  COM_set_array("sourceWindow.:t3:", 1, &sourceElems[0], 3);
205 
206  // initialize source soln array - this is reused
207  COM_new_dataitem("sourceWindow.soln", 'n', COM_DOUBLE, 1, "");
208 
209  COM_window_init_done("sourceWindow");
210 
211  // === TARGET WINDOW ===
212  std::vector<double> targetCoords;
213  std::vector<int> targetElems;
214  extractDataFromVTK(target->getDataSet(), targetCoords, targetElems);
215 
216  COM_new_window("targetWindow");
217  // set target nodal coordinates (nc)
218  COM_set_size("targetWindow.nc", 1, targetCoords.size() / 3);
219  COM_set_array("targetWindow.nc", 1, &targetCoords[0], 3);
220  // set target element node ids (:t3:)
221  COM_set_size("targetWindow.:t3:", 1, targetElems.size() / 3);
222  COM_set_array("targetWindow.:t3:", 1, &targetElems[0], 3);
223 
224  // initialize target soln array - this is reused
225  std::vector<double> targetData(targetCoords.size(), -1.);
226  COM_new_dataitem("targetWindow.soln", 'n', COM_DOUBLE, 1, "m/s");
227  COM_resize_array("targetWindow.soln");
228 
229  COM_window_init_done("targetWindow");
230 
231  int srcMesh = COM_get_dataitem_handle("sourceWindow.mesh");
232  int tgtMesh = COM_get_dataitem_handle("targetWindow.mesh");
233  COM_call_function(RFC_overlay, &srcMesh, &tgtMesh);
234 
235  COM_call_function(RFC_write, &srcMesh, &tgtMesh, "srcMesh", "tgtMesh", "CGNS");
236 
237  COM_finalize();
238 
239  return 0;
240 }
241 
243  vtkDataSet *data, std::vector<double> &coords, std::vector<int> &elems) {
244  for (int ptId = 0; ptId < data->GetNumberOfPoints(); ++ptId) {
245  double x[3];
246 
247  data->GetPoint(ptId, x);
248 
249  coords.push_back(x[0]);
250  coords.push_back(x[1]);
251  coords.push_back(x[2]);
252  }
253 
254  for (int cellId = 0; cellId < data->GetNumberOfCells(); ++cellId) {
255  if (data->GetCellType(cellId) != VTK_TRIANGLE)
256  continue;
257 
258  vtkCell *cell = data->GetCell(cellId);
259 
260  elems.push_back(cell->GetPointId(0) + 1);
261  elems.push_back(cell->GetPointId(1) + 1);
262  elems.push_back(cell->GetPointId(2) + 1);
263  }
264 }
data_type data
Edge/face with sorted point ids (a, b, c, ...) is located at some index i in data[b], with data[b][i].first == [a, c] (for edges, third point id treated as -1).
A brief description of meshBase.
Definition: meshBase.H:64
geoMeshBase * New(MeshType meshType)
Create a new mesh object.
void extractDataFromVTK(vtkDataSet *data, std::vector< double > &coords, std::vector< int > &elems)
meshBase * target
Definition: TransferBase.H:106
vtkSmartPointer< vtkDataSet > getDataSet() const
get this meshes&#39; dataSet
Definition: meshBase.H:308
std::map< std::string, std::vector< Elem > > elems
If the ELEMENT keyword line contains ELSET=name, then the element is stored in elems[name], otherwise, stored in elems[std::string{}].
Definition: inpGeoMesh.C:144
int transferPointData(const std::vector< int > &arrayIDs=std::vector< int >(), const std::vector< std::string > &newnames=std::vector< std::string >())
Transfer point data with given ids from source to target.
meshBase * source
Definition: TransferBase.H:105