1#if BITPIT_ENABLE_MPI==1
5#include "bitpit_surfunstructured.hpp"
6#include "bitpit_voloctree.hpp"
7#include "bitpit_levelset.hpp"
8#include "bitpit_LA.hpp"
9#include "bitpit_operators.hpp"
10#include "bitpit_IO.hpp"
11#include "bitpit_RBF.hpp"
12#include "bitpit_common.hpp"
24using namespace bitpit;
68parse_parameters(std::map<std::string, std::vector<double>> &map,
70 const std::string delimiter)
74 std::ifstream myfile(file);
79 std::vector<std::string> column_names;
80 std::vector<double> line_of_data;
81 unsigned int line_count = 0;
83 while (std::getline(myfile, line))
86 std::vector<std::string> list_of_words_base;
91 while ((pos = s.find(delimiter)) != std::string::npos) {
92 token = s.substr(0, pos);
93 list_of_words_base.push_back(token);
94 s.erase(0, pos + delimiter.length());
96 std::vector<std::string> list_of_words_clean;
97 for (std::size_t i = 0; i < list_of_words_base.size(); ++i)
99 if (list_of_words_base[i] !=
"")
101 list_of_words_clean.push_back(list_of_words_base[i]);
107 line_of_data.resize(list_of_words_clean.size());
108 for (std::size_t i = 0; i < line_of_data.size(); i++)
110 line_of_data[i] = std::stod(list_of_words_clean[i]);
112 for (std::size_t i = 0; i < line_of_data.size(); ++i)
114 map[column_names[i]].push_back(line_of_data[i]);
120 column_names = list_of_words_clean;
121 for (std::size_t i = 0; i < list_of_words_clean.size(); ++i)
123 std::vector<double> base_vector;
124 map[column_names[i]] = base_vector;
132 std::cout <<
"Unable to open file";
135 std::vector<std::string> names = {
"nb_subdivision",
142 std::vector<double> values = {16,
149 for (std::size_t i = 0; i < names.size(); i++)
151 if (map.find(
"f") == map.end())
152 map[names[i]].push_back(values[i]);
156void run(std::string filename,
157 std::string data_path,
158 std::string parameter_file) {
159 constexpr int dimensions(3);
162 std::map<std::string, std::vector<double>> parameters;
163 parse_parameters(parameters, parameter_file,
" ");
164 int nb_subdivision =
static_cast<int>(parameters[
"nb_subdivision"][0]);
165 int nb_adaptions =
static_cast<int>(parameters[
"nb_adaptions"][0]);
166 double radius_ratio = parameters[
"radius_ratio"][0];
167 int base_function =
static_cast<int>(parameters[
"base_function"][0]);
168 double mesh_range = parameters[
"mesh_range"][0];
169 double TOL = parameters[
"tolerance"][0];
170 double scaling = parameters[
"scaling"][0];
172 std::vector<std::string> timers_name;
173 std::vector<double> timers_values;
175 timers_name.push_back(
"load_geometry");
176 double time_start = MPI_Wtime();
188 STL0->importSTL(data_path + filename +
".stl",
true);
190 catch (
const std::bad_alloc &) {
191 STL0->importSTL(data_path + filename +
".stl",
false);
193 STL0->deleteCoincidentVertices();
194 STL0->initializeAdjacencies();
195 STL0->getVTK().setName(
"levelset");
196 std::array<double, dimensions> center{};
197 STL0->scale(scaling,scaling,scaling,center);
202 std::array<double, dimensions> stlMin, stlMax, meshMin, meshMax, delta;
204 STL0->getBoundingBox(stlMin, stlMax);
212 delta = stlMax - stlMin;
213 meshMin = stlMin - mesh_range * delta;
214 meshMax = stlMax + mesh_range * delta;
215 for (
int i = 0; i < dimensions; ++i) {
216 h = std::max(h, meshMax[i] - meshMin[i]);
218 dh = h / nb_subdivision;
224 mesh.initializeAdjacencies();
225 mesh.initializeInterfaces();
227 mesh.getVTK().setName(
"RBF_" + filename);
229 mesh.setVTKWriteTarget(PatchKernel::WriteTarget::WRITE_TARGET_CELLS_INTERNAL);
232 timers_values.push_back(MPI_Wtime() - time_start);
233 timers_name.push_back(
"compute_levelset");
234 time_start = MPI_Wtime();
242 int id0 = levelset.
addObject(std::move(STL0), 0);
249 bitpit::log::cout() <<
"Computed levelset within the narrow band... " << std::endl;
253 std::vector<bitpit::adaption::Info> adaptionData_levelset;
254 for (
int r = 0; r < nb_adaptions; ++r) {
255 for (
auto &cell: mesh.getCells()) {
256 long cellId = cell.getId();
257 if (object0.
evalCellValue(cellId,
false) < mesh.evalCellSize(cellId))
258 mesh.markCellForRefinement(cellId);
260 adaptionData_levelset = mesh.update(
true);
261 levelset.
update(adaptionData_levelset);
264 unsigned long nP_total = mesh.getCellCount();
267 timers_values.push_back(MPI_Wtime() - time_start);
268 timers_name.push_back(
"add_nodes_to_RBF");
269 time_start = MPI_Wtime();
274 switch (base_function) {
324 std::vector<double> values;
325 std::vector<double> weights;
326 std::vector<double> radii;
327 std::vector<std::array<double, dimensions>> nodes;
328 values.resize(nP_total);
329 weights.resize(nP_total);
330 nodes.resize(nP_total);
331 radii.resize(nP_total);
338 for (
size_t it_RBF = 0; it_RBF < nP_total; it_RBF++) {
339 nodes[it_RBF] = mesh.evalCellCentroid(it_RBF);
341 RBFObject.
addNode(nodes[it_RBF]);
342 radii[it_RBF] = mesh.evalCellSize(it_RBF) * radius_ratio;
346 timers_values.push_back(MPI_Wtime() - time_start);
347 timers_name.push_back(
"fill_matrix");
348 time_start = MPI_Wtime();
353 int nNZ = nP_total*(1+(2*(int)ceil(radius_ratio)^dimensions));
354#if BITPIT_ENABLE_MPI==1
355 SparseMatrix A(MPI_COMM_WORLD,
true, nP_total, nP_total, nNZ);
360 std::vector<long> rowPattern;
361 std::vector<double> rowValues;
364 for (
unsigned long i = 0; i < nP_total; i++) {
365 for (
unsigned long j = 0; j < nP_total; j++) {
367 if (
abs(v_ij) > TOL) {
368 rowPattern.push_back(j);
369 rowValues.push_back(v_ij);
372 A.addRow(rowPattern, rowValues);
381 timers_values.push_back(MPI_Wtime() - time_start);
382 timers_name.push_back(
"fill_RHS");
383 time_start = MPI_Wtime();
388 for (
unsigned long i = 0; i < nP_total; ++i) {
393 timers_values.push_back(MPI_Wtime() - time_start);
394 timers_name.push_back(
"solve_system");
395 time_start = MPI_Wtime();
400 for (
unsigned long i = 0; i < nP_total; ++i) {
401 initialSolution[i] = values[i];
409 timers_values.push_back(MPI_Wtime() - time_start);
410 timers_name.push_back(
"add_weights_to_RBFObject");
411 time_start = MPI_Wtime();
414 for (
unsigned long i = 0; i < nP_total; i++) {
422 std::size_t nMaxCellVertices = mesh.getCell(0).getVertexIds().size();
424 timers_values.push_back(MPI_Wtime()-time_start);
425 timers_name.push_back(
"output_RBF_and_analytical");
426 time_start = MPI_Wtime();
430 std::vector<double> display_values;
431 display_values.resize(nP_total);
434 ReferenceElementInfo::MAX_ELEM_VERTICES)
436 for (
const Cell &cell:cellWriteRange){
437 const unsigned long global_id = cell.getId();
438 mesh.getCellVertexCoordinates(global_id, vertexCoordinates);
439 std::array<double, dimensions> point = cell.evalCentroid(vertexCoordinates);
440 std::vector<double> temp_disp = RBFObject.
evalRBF(point);
441 display_values[global_id] = temp_disp[0];
443 mesh.getVTK().addData<
double>(
"RBF", VTKFieldType::SCALAR, VTKLocation::CELL, display_values);
446 timers_values.push_back(MPI_Wtime()-time_start);
447 timers_name.push_back(
"output_RBF_to_file");
448 time_start = MPI_Wtime();
451 ofstream fw(
"RBF_" + filename +
".output", std::ofstream::ate);
453 fw <<
"support_radius basis_function node_x node_y ";
459 for (
unsigned long line = 0; line < nP_total; line++) {
462 std::ostringstream streamObj_support_radius;
463 std::ostringstream streamObj_x;
464 std::ostringstream streamObj_y;
465 std::ostringstream streamObj_z;
466 std::ostringstream streamObj_weight;
467 streamObj_support_radius << std::fixed;
468 streamObj_x << std::fixed;
469 streamObj_y << std::fixed;
470 streamObj_z << std::fixed;
471 streamObj_weight << std::fixed;
472 streamObj_support_radius << std::setprecision(PRECISION);
473 streamObj_x << std::setprecision(PRECISION);
474 streamObj_y << std::setprecision(PRECISION);
475 streamObj_z << std::setprecision(PRECISION);
476 streamObj_weight << std::setprecision(PRECISION);
477 streamObj_support_radius << radii[line];
478 streamObj_x << nodes[line][0];
479 streamObj_y << nodes[line][1];
480 streamObj_z << nodes[line][2];
481 streamObj_weight << weights[line];
482 std::string strObj_support_radius = streamObj_support_radius.str();
483 std::string strObj_x = streamObj_x.str();
484 std::string strObj_y = streamObj_y.str();
485 std::string strObj_z = streamObj_z.str();
486 std::string strObj_weight = streamObj_weight.str();
487 fw << strObj_support_radius <<
" " << base_function <<
" "<<
488 strObj_x <<
" " << strObj_y <<
" ";
491 fw << strObj_z <<
" ";
493 fw << strObj_weight <<
" ";
494 if (line < nP_total -1)
501 timers_values.push_back(MPI_Wtime()-time_start);
503 int nb_timers = timers_name.size();
505 for (
int t = 0; t < nb_timers; t++)
507 bitpit::log::cout() << timers_name.at(t) <<
":" << timers_values.at(t) << std::endl;
514int main(
int argc,
char *argv[])
519#if BITPIT_ENABLE_MPI==1
520 MPI_Init(&argc,&argv);
521 MPI_Comm_size(MPI_COMM_WORLD, &nProcs);
522 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
531 std::vector<std::string> argList;
532 for(
int i=0;i<argc;i++)
533 argList.emplace_back(argv[i]);
536 std::string data_path =
"../test/integration_tests/levelset/data/";
537 std::string filename =
"cube";
538 std::string parameter_file =
"RBF_example_00001.param";
541 data_path = argList[1];
542 filename = argList[2];
543 parameter_file = argList[3];
557 catch (
const std::exception &exception) {
562#if BITPIT_ENABLE_MPI==1
The Cell class defines the cells.
Interface class for all objects with respect to whom the levelset function may be computed.
void setCellBulkEvaluationMode(LevelSetBulkEvaluationMode evaluationMode)
virtual double evalCellValue(long id, bool signedLevelSet) const
void enableVTKOutput(const LevelSetFieldset &fieldset, bool enable=true)
LevelSetObject & getObject(int) const
void setNarrowBandSize(double size=0)
void setMesh(VolumeKernel *mesh)
void update(const std::vector< adaption::Info > &adaptionData)
int addObject(LevelSetBooleanOperation, int, int, int id=levelSetDefaults::OBJECT)
void initialize(log::Mode mode, bool reset, int nProcesses, int rank)
The PiercedStorageRange allow to iterate using range-based loops over a PiercedStorage.
void setMode(RBFMode mode)
void setSupportRadius(double)
void setFunction(RBFBasisFunction)
std::vector< double > evalRBF(const std::array< double, 3 > &)
double evalBasisPair(int i, int j)
Class to handle Radial Basis Function with a large set of 3D points as nodes.
int addNode(const std::array< double, 3 > &)
The SurfUnstructured class defines an unstructured surface triangulation.
The SystemSolver class provides methods for building and solving large linear systems.
double * getSolutionRawPtr()
void restoreSolutionRawPtr(double *raw_solution)
const double * getSolutionRawReadPtr() const
void restoreRHSRawPtr(double *raw_rhs)
void assembly(const SparseMatrix &matrix)
The VolOctree defines a Octree patch.
std::array< T, d > abs(const std::array< T, d > &x)
RBFBasisFunction
Enum class defining types of RBF kernel functions that could be used in bitpit::RBF class.
#define BITPIT_CREATE_WORKSPACE(workspace, item_type, size, stack_size)
@ SIGN_PROPAGATION
Sign is propagated from the narrow band, no other data will be evaluated.
Logger & cout(log::Level defaultSeverity, log::Visibility defaultVisibility)
LoggerManipulator< log::Level > fileVerbosity(const log::Level &threshold)
Logger & disableConsole(Logger &logger, const log::Level &level)
LoggerManager & manager()