diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..308936f --- /dev/null +++ b/.clang-format @@ -0,0 +1,124 @@ +# -*- mode: yaml -*- +--- +Language: Cpp +AccessModifierOffset: -4 +AlignAfterOpenBracket: AlwaysBreak +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Right +AlignOperands: true +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: true +AllowAllConstructorInitializersOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: WithoutElse +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: true +BinPackArguments: true +BinPackParameters: false +BraceWrapping: + AfterCaseLabel: false + AfterClass: true + AfterControlStatement: false + AfterEnum: false + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: true + AfterUnion: true + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyRecord: false + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Custom +BreakInheritanceList: BeforeComma +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeComma +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 80 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + - Regex: '.*' + Priority: 1 +IncludeIsMainRegex: '(Test)?$' +IndentCaseLabels: false +IndentPPDirectives: None +IndentWidth: 4 +IndentWrappedFunctionNames: false +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Left +ReflowComments: true +SortIncludes: false +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 8 +UseTab: Never +... + diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 450b825..fb3cc42 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,12 +19,12 @@ jobs: - name: Clone uses: actions/checkout@v4 - name: Check formatting - uses: DoozyX/clang-format-lint-action@v0.16.2 + uses: DoozyX/clang-format-lint-action@v0.17 with: - source: './src' + source: './driver ./src' exclude: '.' - extensions: 'h,cpp' - clangFormatVersion: 16 + extensions: 'h,H,cpp,C' + clangFormatVersion: 17 CPU: needs: Formatting runs-on: ${{matrix.os}} diff --git a/driver/gmsh_io.C b/driver/gmsh_io.C index 2478ce8..b652097 100644 --- a/driver/gmsh_io.C +++ b/driver/gmsh_io.C @@ -6,7 +6,7 @@ using namespace std; /* header files */ -# include "gmsh_io.hpp" +#include "gmsh_io.hpp" #define BASE 1 #define _X 0 @@ -17,87 +17,112 @@ using namespace std; /* GMSH INTERFACE */ /* ========================================================================== */ extern "C" { - void tioga_gmsh_reader_(int *nnodes,double **xyz, - int *nwbc, int *nobc, - int **wbc_t,int **obc_t, - int *n4,int *n5,int *n6,int *n8, - int **ndc4,int **ndc5,int **ndc6,int **ndc8){ +void tioga_gmsh_reader_( + int* nnodes, + double** xyz, + int* nwbc, + int* nobc, + int** wbc_t, + int** obc_t, + int* n4, + int* n5, + int* n6, + int* n8, + int** ndc4, + int** ndc5, + int** ndc6, + int** ndc8) +{ std::string gmsh_filename = "billet-cap-big.3D.Q1.60K.tet.msh"; - int dim,node_num; + int dim, node_num; int element_num; - double eps=1.0E-12; - double x,y,z; + double eps = 1.0E-12; + double x, y, z; // remove excess memory obc.clear(); wbc.clear(); node_x.clear(); - for(int i = 0; i < TYPE_NUM_MAX; i++) element_node[i].clear(); + for (int i = 0; i < TYPE_NUM_MAX; i++) element_node[i].clear(); cout << "\nGMSH:\n Read data from a file.\n"; // Get the data size. - std::vector elem_counts(TYPE_NUM_MAX,0); - gmsh_size_read(gmsh_filename,node_num,dim,element_num,elem_counts.data()); + std::vector elem_counts(TYPE_NUM_MAX, 0); + gmsh_size_read( + gmsh_filename, node_num, dim, element_num, elem_counts.data()); cout << " Node data read from file \"" << gmsh_filename << "\"\n\n"; - cout << " Number of nodes = " << node_num << "\n"; - cout << " Spatial dimension = " << dim << "\n"; - cout << " Elements counts: " << "\n"; - for(int i = 1; i < TYPE_NUM_MAX; i++) printf(" %s %d\n",TYPE_NAME[i],elem_counts[i]); + cout << " Number of nodes = " << node_num << "\n"; + cout << " Spatial dimension = " << dim << "\n"; + cout << " Elements counts: " + << "\n"; + for (int i = 1; i < TYPE_NUM_MAX; i++) + printf(" %s %d\n", TYPE_NAME[i], elem_counts[i]); cout << endl; // allocate memory - node_x.resize(dim*node_num); - for(int i = 1; i < TYPE_NUM_MAX; i++){ - element_node[i].resize(elem_counts[i]*TYPE_NNODES[i]); - //printf("ALLOCATING %d %d %d\n",i,elem_counts[i],TYPE_NNODES[i]); + node_x.resize(dim * node_num); + for (int i = 1; i < TYPE_NUM_MAX; i++) { + element_node[i].resize(elem_counts[i] * TYPE_NNODES[i]); + // printf("ALLOCATING %d %d %d\n",i,elem_counts[i],TYPE_NNODES[i]); } // read gmsh mesh data - gmsh_data_read(gmsh_filename,dim,node_x,element_node); + gmsh_data_read(gmsh_filename, dim, node_x, element_node); // fixed geometry boundaries for msh: DO NOT CHANGE - double outerboxTop = 1.60; //y-direction - double innerboxTop = 1.30; //y-direction + double outerboxTop = 1.60; // y-direction + double innerboxTop = 1.30; // y-direction double outerboxh = 0.6; double ibh = 0.3; double rad = 1.0; // count overset bc nodes - std::vector bcall(node_num,0); - for(int i=0;i= outerboxTop-eps);// top overset face - for(int i=0;i= outerboxh-eps); // xhi overset face - for(int i=0;i= outerboxh-eps); // zhi overset face + std::vector bcall(node_num, 0); + for (int i = 0; i < node_num; i++) + bcall[i] = + (node_x[3 * i + _Y] >= outerboxTop - eps); // top overset face + for (int i = 0; i < node_num; i++) + bcall[i] += + (node_x[3 * i + _X] <= -outerboxh + eps); // xlo overset face + for (int i = 0; i < node_num; i++) + bcall[i] += (node_x[3 * i + _X] >= outerboxh - eps); // xhi overset face + for (int i = 0; i < node_num; i++) + bcall[i] += + (node_x[3 * i + _Z] <= -outerboxh + eps); // zlo overset face + for (int i = 0; i < node_num; i++) + bcall[i] += (node_x[3 * i + _Z] >= outerboxh - eps); // zhi overset face // fill overset bc nodes int nobc_ = 0; - for(int i=0;i 0); + for (int i = 0; i < node_num; i++) nobc_ += (bcall[i] > 0); - obc.resize(nobc_); nobc_ = 0; - for(int i=0;i 0) obc[nobc_++] = i+BASE; + obc.resize(nobc_); + nobc_ = 0; + for (int i = 0; i < node_num; i++) { + if (bcall[i] > 0) obc[nobc_++] = i + BASE; } // count wall bc nodes std::fill(bcall.begin(), bcall.end(), 0); - for(int i=0;i= -1.5*ibh-eps && x <= 1.5*ibh+eps){ -// if(z >= -1.5*ibh-eps && z <= 1.5*ibh+eps){ -// bcall[i] = (radiusSqr <= rad+eps); -// } -// } - - if(y <= innerboxTop+eps){ - if(x >= -ibh-eps && x <= ibh+eps){ - if(z >= -ibh-eps && z <= ibh+eps){ + for (int i = 0; i < node_num; i++) { + x = node_x[3 * i + _X]; + y = node_x[3 * i + _Y]; + z = node_x[3 * i + _Z]; + double radiusSqr = x * x + y * y + z * z; + + // sphere surface + bcall[i] = (radiusSqr <= rad + eps); + // if(x >= -1.5*ibh-eps && x <= 1.5*ibh+eps){ + // if(z >= -1.5*ibh-eps && z <= 1.5*ibh+eps){ + // bcall[i] = (radiusSqr <= rad+eps); + // } + // } + + if (y <= innerboxTop + eps) { + if (x >= -ibh - eps && x <= ibh + eps) { + if (z >= -ibh - eps && z <= ibh + eps) { bcall[i] = 1; } } @@ -106,11 +131,12 @@ extern "C" { // fill wall bc nodes int nwbc_ = 0; - for(int i=0;i 0); + for (int i = 0; i < node_num; i++) nwbc_ += (bcall[i] > 0); - wbc.resize(nwbc_); nwbc_ = 0; - for(int i=0;i 0) wbc[nwbc_++] = i+BASE; + wbc.resize(nwbc_); + nwbc_ = 0; + for (int i = 0; i < node_num; i++) { + if (bcall[i] > 0) wbc[nwbc_++] = i + BASE; } // assign mesh statistics @@ -128,29 +154,30 @@ extern "C" { *ndc5 = element_node[TYPE_PYR].data(); *ndc6 = element_node[TYPE_PRI].data(); *ndc8 = element_node[TYPE_HEX].data(); - } +} } /* ========================================================================== */ - -char ch_cap(char ch){ - if(97 <= ch && ch <= 122) ch -= 32; +char ch_cap(char ch) +{ + if (97 <= ch && ch <= 122) ch -= 32; return ch; } -bool ch_eqi(char ch1, char ch2){ - if(97 <= ch1 && ch1 <= 122) ch1 -= 32; - if(97 <= ch2 && ch2 <= 122) ch2 -= 32; +bool ch_eqi(char ch1, char ch2) +{ + if (97 <= ch1 && ch1 <= 122) ch1 -= 32; + if (97 <= ch2 && ch2 <= 122) ch2 -= 32; return (ch1 == ch2); } -int ch_to_digit(char ch){ +int ch_to_digit(char ch) +{ int digit; - if('0' <= ch && ch <= '9'){ + if ('0' <= ch && ch <= '9') { digit = ch - '0'; - } else - if(ch == ' '){ + } else if (ch == ' ') { digit = 0; } else { digit = -1; @@ -189,14 +216,17 @@ int ch_to_digit(char ch){ // // Input, int ELEMENT_NUM, the number of elements. // -// Input, int ELEMENT_NODE[ELEMENT_ORDER*ELEMENT_NUM], +// Input, int ELEMENT_NODE[ELEMENT_ORDER*ELEMENT_NUM], // the nodes that make up each element. // //****************************************************************************80 -void gmsh_data_read(string gmsh_filename, int node_dim, - std::vector &node_x, - std::vector element_nodes[]){ - int i,j,k; +void gmsh_data_read( + string gmsh_filename, + int node_dim, + std::vector& node_x, + std::vector element_nodes[]) +{ + int i, j, k; int level; int length; int elem_type; @@ -219,26 +249,26 @@ void gmsh_data_read(string gmsh_filename, int node_dim, // read node information // level = 0; - for(;;){ - getline(input,text); - if(input.eof()) break; + for (;;) { + getline(input, text); + if (input.eof()) break; - if(level == 0){ - if(s_begin(text, "$Nodes")) level = 1; - } else if(level == 1){ + if (level == 0) { + if (s_begin(text, "$Nodes")) level = 1; + } else if (level == 1) { s_to_i4(text, length, ierror); level = 2; j = 0; - } else if(level == 2) { - if(s_begin(text, "$EndNodes")){ + } else if (level == 2) { + if (s_begin(text, "$EndNodes")) { break; } else { s_to_i4(text, length, ierror); text.erase(0, length); - for(i = 0; i < node_dim; i++) { + for (i = 0; i < node_dim; i++) { x = s_to_r8(text, length, ierror); text.erase(0, length); - node_x[i+j*node_dim] = x; + node_x[i + j * node_dim] = x; } j++; } @@ -249,38 +279,47 @@ void gmsh_data_read(string gmsh_filename, int node_dim, // read element information. // level = 0; - for(;;){ - getline(input,text); - if(input.eof()) break; + for (;;) { + getline(input, text); + if (input.eof()) break; - if(level == 0){ - if(s_begin(text, "$Elements")) level = 1; - } else if(level == 1){ + if (level == 0) { + if (s_begin(text, "$Elements")) level = 1; + } else if (level == 1) { // read element number s_to_i4(text, length, ierror); level = 2; - } else if(level == 2){ - if(s_begin(text, "$EndElements")){ + } else if (level == 2) { + if (s_begin(text, "$EndElements")) { break; } else { // read element preamble info - int em_id = s_to_i4(text,length,ierror); text.erase(0,length); // element id - elem_type = s_to_i4(text,length,ierror); text.erase(0,length); // element type - s_to_i4(text,length,ierror); text.erase(0,length); // number of tags (2) - s_to_i4(text,length,ierror); text.erase(0,length); // phys tag - s_to_i4(text,length,ierror); text.erase(0,length); // entity tag + int em_id = s_to_i4(text, length, ierror); + text.erase(0, length); // element id + elem_type = s_to_i4(text, length, ierror); + text.erase(0, length); // element type + s_to_i4(text, length, ierror); + text.erase(0, length); // number of tags (2) + s_to_i4(text, length, ierror); + text.erase(0, length); // phys tag + s_to_i4(text, length, ierror); + text.erase(0, length); // entity tag int element_count = element_counts[getElementType(elem_type)]; int num_nodes = getElementNumNodes(elem_type); - //printf("Filling Elem %d of type %d: count %d, num_nodes %d\n",em_id,elem_type,element_count,num_nodes); - int * const elem_nodes = &(element_nodes[getElementType(elem_type)][num_nodes*element_count]); + // printf("Filling Elem %d of type %d: count %d, num_nodes + // %d\n",em_id,elem_type,element_count,num_nodes); + int* const elem_nodes = + &(element_nodes[getElementType(elem_type)] + [num_nodes * element_count]); // read element nodes - for(i = 0; i < num_nodes; i++){ + for (i = 0; i < num_nodes; i++) { k = s_to_i4(text, length, ierror); text.erase(0, length); - //element_nodes[getElementType(elem_type)][element_order*element_count+i] = k; + // element_nodes[getElementType(elem_type)][element_order*element_count+i] + // = k; elem_nodes[i] = k; } // increase element counter @@ -322,8 +361,13 @@ void gmsh_data_read(string gmsh_filename, int node_dim, // Output, int &ELEMENT_ORDER, the order of the elements. // //****************************************************************************80 -void gmsh_size_read(string gmsh_filename, int &node_num, int &node_dim, - int &element_num, int elem_counts[]){ +void gmsh_size_read( + string gmsh_filename, + int& node_num, + int& node_dim, + int& element_num, + int elem_counts[]) +{ int elem_type; int level; int length; @@ -331,7 +375,7 @@ void gmsh_size_read(string gmsh_filename, int &node_num, int &node_dim, string text; ifstream input; const double r8_big = 1.0E+30; - double x,y,z; + double x, y, z; double x_max; double x_min; double y_max; @@ -342,16 +386,16 @@ void gmsh_size_read(string gmsh_filename, int &node_num, int &node_dim, node_num = 0; node_dim = 0; - x_max = - r8_big; - x_min = + r8_big; - y_max = - r8_big; - y_min = + r8_big; - z_max = - r8_big; - z_min = + r8_big; + x_max = -r8_big; + x_min = +r8_big; + y_max = -r8_big; + y_min = +r8_big; + z_max = -r8_big; + z_min = +r8_big; input.open(gmsh_filename.c_str()); - if(!input){ + if (!input) { cerr << "\n"; cerr << "GMSH_SIZE_READ - Fatal error!\n"; cerr << " Could not open input file \"" << gmsh_filename << "\"\n"; @@ -359,21 +403,22 @@ void gmsh_size_read(string gmsh_filename, int &node_num, int &node_dim, } level = 0; - for(;;){ + for (;;) { getline(input, text); - if(input.eof()) break; + if (input.eof()) break; - if(level == 0){ - if(s_begin(text, "$MeshFormat")) level = 1; - } else if(level == 1){ - if(s_begin(text, "$EndMeshFormat")) { + if (level == 0) { + if (s_begin(text, "$MeshFormat")) level = 1; + } else if (level == 1) { + if (s_begin(text, "$EndMeshFormat")) { break; } else { double fmt_a = s_to_r8(text, length, ierror); text.erase(0, length); - if((int) 10*fmt_a >= 30){ - cout << "ERROR - GMSH FORMAT 2.X ONLY: read format=" << fmt_a << endl; + if ((int)10 * fmt_a >= 30) { + cout << "ERROR - GMSH FORMAT 2.X ONLY: read format=" + << fmt_a << endl; exit(1); } } @@ -381,17 +426,17 @@ void gmsh_size_read(string gmsh_filename, int &node_num, int &node_dim, } level = 0; - for(;;){ + for (;;) { getline(input, text); - if(input.eof()) break; + if (input.eof()) break; - if(level == 0){ - if(s_begin(text, "$Nodes")) level = 1;\ - } else if(level == 1){ + if (level == 0) { + if (s_begin(text, "$Nodes")) level = 1; + } else if (level == 1) { node_num = s_to_i4(text, length, ierror); level = 2; - } else if(level == 2){ - if(s_begin(text, "$EndNodes")) { + } else if (level == 2) { + if (s_begin(text, "$EndNodes")) { break; } else { s_to_i4(text, length, ierror); @@ -418,40 +463,42 @@ void gmsh_size_read(string gmsh_filename, int &node_num, int &node_dim, // Make a very simple guess as to the dimensionality of the data. // node_dim = 3; - if(z_max == z_min){ + if (z_max == z_min) { node_dim = 2; - if(y_max == y_min) node_dim = 1; + if (y_max == y_min) node_dim = 1; } // // Now read element information. // level = 0; - for(;;){ + for (;;) { getline(input, text); - if(input.eof()) break; + if (input.eof()) break; - if(level == 0){ - if(s_begin(text, "$Elements")) level = 1; - } else if(level == 1){ + if (level == 0) { + if (s_begin(text, "$Elements")) level = 1; + } else if (level == 1) { // read element number element_num = s_to_i4(text, length, ierror); level = 2; - } else if(level == 2){ - if(s_begin(text, "$EndElements")) { + } else if (level == 2) { + if (s_begin(text, "$EndElements")) { break; } else { // read element info: elem_id elem_type - s_to_i4(text, length, ierror); text.erase(0, length); - elem_type = s_to_i4(text, length, ierror); text.erase(0, length); + s_to_i4(text, length, ierror); + text.erase(0, length); + elem_type = s_to_i4(text, length, ierror); + text.erase(0, length); // increase element type counter elem_counts[getElementType(elem_type)]++; - for(;;){ + for (;;) { s_to_i4(text, length, ierror); text.erase(0, length); - if(ierror != 0) break; + if (ierror != 0) break; } } } @@ -459,7 +506,6 @@ void gmsh_size_read(string gmsh_filename, int &node_num, int &node_dim, input.close(); } - //****************************************************************************80 // // Purpose: @@ -486,27 +532,25 @@ void gmsh_size_read(string gmsh_filename, int &node_num, int &node_dim, // the end of S2, and false otherwise. // //****************************************************************************80 -bool s_begin(string s1, string s2){ - int i; - int n1; - int n2; - - n1 = s1.length(); - n2 = s2.length(); - - if(n1 < n2) - { - return false; - } - - for(i = 0; i < n2; i++) - { - if(ch_cap(s1[i]) != ch_cap(s2[i])) - { - return false; +bool s_begin(string s1, string s2) +{ + int i; + int n1; + int n2; + + n1 = s1.length(); + n2 = s2.length(); + + if (n1 < n2) { + return false; + } + + for (i = 0; i < n2; i++) { + if (ch_cap(s1[i]) != ch_cap(s2[i])) { + return false; + } } - } - return true; + return true; } //****************************************************************************80 @@ -518,7 +562,7 @@ bool s_begin(string s1, string s2){ // // Licensing: // -// This code is distributed under the GNU LGPL license. +// This code is distributed under the GNU LGPL license. // // Modified: // @@ -536,21 +580,20 @@ bool s_begin(string s1, string s2){ // If S_LEN_TRIM is 0, then the string is entirely blank. // //****************************************************************************80 -int s_len_trim(string s){ - int n; +int s_len_trim(string s) +{ + int n; - n = s.length(); + n = s.length(); - while(0 < n) - { - if(s[n-1] != ' ' && s[n-1] != '\n') - { - return n; + while (0 < n) { + if (s[n - 1] != ' ' && s[n - 1] != '\n') { + return n; + } + n = n - 1; } - n = n - 1; - } - return n; + return n; } //****************************************************************************80 @@ -561,7 +604,7 @@ int s_len_trim(string s){ // // Licensing: // -// This code is distributed under the GNU LGPL license. +// This code is distributed under the GNU LGPL license. // // Modified: // @@ -583,104 +626,80 @@ int s_len_trim(string s){ // If the string is blank, then IVAL will be returned 0. // //****************************************************************************80 -int s_to_i4(string s, int &last, bool &error){ - char c; - int i; - int isgn; - int istate; - int ival; - - error = false; - istate = 0; - isgn = 1; - i = 0; - ival = 0; - - for(; ;) - { - c = s[i]; - i = i + 1; -// -// Haven't read anything. -// - if(istate == 0) - { - if(c == ' ') - { - } - else if(c == '-') - { - istate = 1; - isgn = -1; - } - else if(c == '+') - { - istate = 1; - isgn = + 1; - } - else if('0' <= c && c <= '9') - { - istate = 2; - ival = c - '0'; - } - else - { - error = true; - return ival; - } +int s_to_i4(string s, int& last, bool& error) +{ + char c; + int i; + int isgn; + int istate; + int ival; + + error = false; + istate = 0; + isgn = 1; + i = 0; + ival = 0; + + for (;;) { + c = s[i]; + i = i + 1; + // + // Haven't read anything. + // + if (istate == 0) { + if (c == ' ') { + } else if (c == '-') { + istate = 1; + isgn = -1; + } else if (c == '+') { + istate = 1; + isgn = +1; + } else if ('0' <= c && c <= '9') { + istate = 2; + ival = c - '0'; + } else { + error = true; + return ival; + } + } + // + // Have read the sign, expecting digits. + // + else if (istate == 1) { + if (c == ' ') { + } else if ('0' <= c && c <= '9') { + istate = 2; + ival = c - '0'; + } else { + error = true; + return ival; + } + } + // + // Have read at least one digit, expecting more. + // + else if (istate == 2) { + if ('0' <= c && c <= '9') { + ival = 10 * ival + c - '0'; + } else { + ival = isgn * ival; + last = i - 1; + return ival; + } + } } -// -// Have read the sign, expecting digits. -// - else if(istate == 1) - { - if(c == ' ') - { - } - else if('0' <= c && c <= '9') - { - istate = 2; - ival = c - '0'; - } - else - { + // + // If we read all the characters in the string, see if we're OK. + // + if (istate == 2) { + ival = isgn * ival; + last = s_len_trim(s); + } else { error = true; - return ival; - } + last = 0; } -// -// Have read at least one digit, expecting more. -// - else if(istate == 2) - { - if('0' <= c && c <= '9') - { - ival = 10 * ival + c - '0'; - } - else - { - ival = isgn * ival; - last = i - 1; - return ival; - } - } - } -// -// If we read all the characters in the string, see if we're OK. -// - if(istate == 2) - { - ival = isgn * ival; - last = s_len_trim(s); - } - else - { - error = true; - last = 0; - } - - return ival; + return ival; } //****************************************************************************80 @@ -734,7 +753,7 @@ int s_to_i4(string s, int &last, bool &error){ // // Licensing: // -// This code is distributed under the GNU LGPL license. +// This code is distributed under the GNU LGPL license. // // Modified: // @@ -762,241 +781,184 @@ int s_to_i4(string s, int &last, bool &error){ // Output, double S_TO_R8, the real value that was read from the string. // //********************************************************************** -double s_to_r8(string s, int &lchar, bool &error){ - char c; - int ihave; - int isgn; - int iterm; - int jbot; - int jsgn; - int jtop; - int nchar; - int ndig; - double r; - double rbot; - double rexp; - double rtop; - char TAB = 9; - - nchar = s_len_trim(s); - error = false; - r = 0.0; - lchar = -1; - isgn = 1; - rtop = 0.0; - rbot = 1.0; - jsgn = 1; - jtop = 0; - jbot = 1; - ihave = 1; - iterm = 0; - - for(; ;) - { - c = s[lchar+1]; - lchar = lchar + 1; -// -// Blank or TAB character. -// - if(c == ' ' || c == TAB) - { - if(ihave == 2) - { - } - else if(ihave == 6 || ihave == 7) - { - iterm = 1; - } - else if(1 < ihave) - { - ihave = 11; - } - } -// -// Comma. -// - else if(c == ',' || c == ';') - { - if(ihave != 1) - { - iterm = 1; - ihave = 12; +double s_to_r8(string s, int& lchar, bool& error) +{ + char c; + int ihave; + int isgn; + int iterm; + int jbot; + int jsgn; + int jtop; + int nchar; + int ndig; + double r; + double rbot; + double rexp; + double rtop; + char TAB = 9; + + nchar = s_len_trim(s); + error = false; + r = 0.0; + lchar = -1; + isgn = 1; + rtop = 0.0; + rbot = 1.0; + jsgn = 1; + jtop = 0; + jbot = 1; + ihave = 1; + iterm = 0; + + for (;;) { + c = s[lchar + 1]; lchar = lchar + 1; - } - } -// -// Minus sign. -// - else if(c == '-') - { - if(ihave == 1) - { - ihave = 2; - isgn = -1; - } - else if(ihave == 6) - { - ihave = 7; - jsgn = -1; - } - else - { - iterm = 1; - } - } -// -// Plus sign. -// - else if(c == '+') - { - if(ihave == 1) - { - ihave = 2; - } - else if(ihave == 6) - { - ihave = 7; - } - else - { - iterm = 1; - } - } -// -// Decimal point. -// - else if(c == '.') - { - if(ihave < 4) - { - ihave = 4; - } - else if(6 <= ihave && ihave <= 8) - { - ihave = 9; - } - else - { - iterm = 1; - } - } -// -// Exponent marker. -// - else if(ch_eqi(c, 'E') || ch_eqi(c, 'D')) - { - if(ihave < 6) - { - ihave = 6; - } - else - { - iterm = 1; - } - } -// -// Digit. -// - else if(ihave < 11 && '0' <= c && c <= '9') - { - if(ihave <= 2) - { - ihave = 3; - } - else if(ihave == 4) - { - ihave = 5; - } - else if(ihave == 6 || ihave == 7) - { - ihave = 8; - } - else if(ihave == 9) - { - ihave = 10; - } - - ndig = ch_to_digit(c); - - if(ihave == 3) - { - rtop = 10.0 * rtop +(double) ndig; - } - else if(ihave == 5) - { - rtop = 10.0 * rtop +(double) ndig; - rbot = 10.0 * rbot; - } - else if(ihave == 8) - { - jtop = 10 * jtop + ndig; - } - else if(ihave == 10) - { - jtop = 10 * jtop + ndig; - jbot = 10 * jbot; - } + // + // Blank or TAB character. + // + if (c == ' ' || c == TAB) { + if (ihave == 2) { + } else if (ihave == 6 || ihave == 7) { + iterm = 1; + } else if (1 < ihave) { + ihave = 11; + } + } + // + // Comma. + // + else if (c == ',' || c == ';') { + if (ihave != 1) { + iterm = 1; + ihave = 12; + lchar = lchar + 1; + } + } + // + // Minus sign. + // + else if (c == '-') { + if (ihave == 1) { + ihave = 2; + isgn = -1; + } else if (ihave == 6) { + ihave = 7; + jsgn = -1; + } else { + iterm = 1; + } + } + // + // Plus sign. + // + else if (c == '+') { + if (ihave == 1) { + ihave = 2; + } else if (ihave == 6) { + ihave = 7; + } else { + iterm = 1; + } + } + // + // Decimal point. + // + else if (c == '.') { + if (ihave < 4) { + ihave = 4; + } else if (6 <= ihave && ihave <= 8) { + ihave = 9; + } else { + iterm = 1; + } + } + // + // Exponent marker. + // + else if (ch_eqi(c, 'E') || ch_eqi(c, 'D')) { + if (ihave < 6) { + ihave = 6; + } else { + iterm = 1; + } + } + // + // Digit. + // + else if (ihave < 11 && '0' <= c && c <= '9') { + if (ihave <= 2) { + ihave = 3; + } else if (ihave == 4) { + ihave = 5; + } else if (ihave == 6 || ihave == 7) { + ihave = 8; + } else if (ihave == 9) { + ihave = 10; + } + ndig = ch_to_digit(c); + + if (ihave == 3) { + rtop = 10.0 * rtop + (double)ndig; + } else if (ihave == 5) { + rtop = 10.0 * rtop + (double)ndig; + rbot = 10.0 * rbot; + } else if (ihave == 8) { + jtop = 10 * jtop + ndig; + } else if (ihave == 10) { + jtop = 10 * jtop + ndig; + jbot = 10 * jbot; + } + + } + // + // Anything else is regarded as a terminator. + // + else { + iterm = 1; + } + // + // If we haven't seen a terminator, and we haven't examined the + // entire string, go get the next character. + // + if (iterm == 1 || nchar <= lchar + 1) { + break; + } } -// -// Anything else is regarded as a terminator. -// - else - { - iterm = 1; - } -// -// If we haven't seen a terminator, and we haven't examined the -// entire string, go get the next character. -// - if(iterm == 1 || nchar <= lchar + 1) - { - break; + // + // If we haven't seen a terminator, and we have examined the + // entire string, then we're done, and LCHAR is equal to NCHAR. + // + if (iterm != 1 && lchar + 1 == nchar) { + lchar = nchar; } - - } -// -// If we haven't seen a terminator, and we have examined the -// entire string, then we're done, and LCHAR is equal to NCHAR. -// - if(iterm != 1 && lchar + 1 == nchar) - { - lchar = nchar; - } -// -// Number seems to have terminated. Have we got a legal number? -// Not if we terminated in states 1, 2, 6 or 7! -// - if(ihave == 1 || ihave == 2 || ihave == 6 || ihave == 7) - { - error = true; - return r; - } -// -// Number seems OK. Form it. -// - if(jtop == 0) - { - rexp = 1.0; - } - else - { - if(jbot == 1) - { - rexp = pow(10.0, jsgn * jtop); + // + // Number seems to have terminated. Have we got a legal number? + // Not if we terminated in states 1, 2, 6 or 7! + // + if (ihave == 1 || ihave == 2 || ihave == 6 || ihave == 7) { + error = true; + return r; } - else - { - rexp = jsgn * jtop; - rexp = rexp / jbot; - rexp = pow(10.0, rexp); + // + // Number seems OK. Form it. + // + if (jtop == 0) { + rexp = 1.0; + } else { + if (jbot == 1) { + rexp = pow(10.0, jsgn * jtop); + } else { + rexp = jsgn * jtop; + rexp = rexp / jbot; + rexp = pow(10.0, rexp); + } } - } + r = isgn * rexp * rtop / rbot; - r = isgn * rexp * rtop / rbot; - - return r; + return r; } //********************************************************************** @@ -1011,7 +973,7 @@ double s_to_r8(string s, int &lchar, bool &error){ // // Licensing: // -// This code is distributed under the GNU LGPL license. +// This code is distributed under the GNU LGPL license. // // Modified: // @@ -1026,20 +988,21 @@ double s_to_r8(string s, int &lchar, bool &error){ // None // //********************************************************************** -void timestamp(){ -# define TIME_SIZE 40 +void timestamp() +{ +#define TIME_SIZE 40 - static char time_buffer[TIME_SIZE]; - const struct tm *tm; - time_t now; + static char time_buffer[TIME_SIZE]; + const struct tm* tm; + time_t now; - now = time(NULL); - tm = localtime(&now); + now = time(NULL); + tm = localtime(&now); - strftime(time_buffer, TIME_SIZE, "%d %B %Y %I:%M:%S %p", tm); + strftime(time_buffer, TIME_SIZE, "%d %B %Y %I:%M:%S %p", tm); - cout << time_buffer << "\n"; + cout << time_buffer << "\n"; - return; -# undef TIME_SIZE + return; +#undef TIME_SIZE } \ No newline at end of file diff --git a/driver/gmsh_test.C b/driver/gmsh_test.C index f31221f..32aefb0 100644 --- a/driver/gmsh_test.C +++ b/driver/gmsh_test.C @@ -5,23 +5,24 @@ */ /* system header files */ -# include -# include -# include -# include -# include -# include +#include +#include +#include +#include +#include +#include #include /* name space */ using namespace std; /* header files */ -# include "gmsh_io.hpp" +#include "gmsh_io.hpp" void test(); -int main(){ +int main() +{ timestamp(); cout << "\n"; cout << "GMSH_IO_TEST\n"; @@ -38,45 +39,47 @@ int main(){ return 0; } -void test(){ +void test() +{ string gmsh_filename = "billet-cap.3D.Q1.12K.msh"; - int dim,node_num; + int dim, node_num; int element_num; cout << "\nTEST:\n Read data from a file.\n"; // Get the data size. - std::vector elem_counts(TYPE_NUM_MAX,0); - gmsh_size_read(gmsh_filename,node_num,dim,element_num,elem_counts.data()); + std::vector elem_counts(TYPE_NUM_MAX, 0); + gmsh_size_read( + gmsh_filename, node_num, dim, element_num, elem_counts.data()); cout << " \n Node data read from file \"" << gmsh_filename << "\"\n\n"; - cout << " Number of nodes = " << node_num << "\n"; - cout << " Spatial dimension = " << dim << "\n"; - cout << " Number of elements: " << "\n"; - for(int i = 1; i < TYPE_NUM_MAX; i++){ - printf(" %s %d\n", TYPE_NAME[i],elem_counts[i]); + cout << " Number of nodes = " << node_num << "\n"; + cout << " Spatial dimension = " << dim << "\n"; + cout << " Number of elements: " + << "\n"; + for (int i = 1; i < TYPE_NUM_MAX; i++) { + printf(" %s %d\n", TYPE_NAME[i], elem_counts[i]); } cout << endl; // Allocate memory. - std::vector node_x(dim*node_num); + std::vector node_x(dim * node_num); std::vector element_node[TYPE_NUM_MAX]; - for(int i = 1; i < TYPE_NUM_MAX; i++){ - element_node[i].resize(elem_counts[i]*TYPE_NNODES[i]); - //printf("ALLOCATING %d %d %d\n",i,elem_counts[i],TYPE_NNODES[i]); + for (int i = 1; i < TYPE_NUM_MAX; i++) { + element_node[i].resize(elem_counts[i] * TYPE_NNODES[i]); + // printf("ALLOCATING %d %d %d\n",i,elem_counts[i],TYPE_NNODES[i]); } // Get the data. - gmsh_data_read(gmsh_filename,dim, - node_x,element_node); + gmsh_data_read(gmsh_filename, dim, node_x, element_node); -// for(int i = 1; i < TYPE_NUM_MAX; i++){ -// printf("ELEMENT TYPE %s\n",TYPE_NAME[i]); -// for(int j = 0; j < elem_counts[i]; j++){ -// for(int k = 0; k < TYPE_NNODES[i]; k++){ -// cout << " " << element_node[i][TYPE_NNODES[i]*j + k]; -// } -// cout << endl; -// } -// } + // for(int i = 1; i < TYPE_NUM_MAX; i++){ + // printf("ELEMENT TYPE %s\n",TYPE_NAME[i]); + // for(int j = 0; j < elem_counts[i]; j++){ + // for(int k = 0; k < TYPE_NNODES[i]; k++){ + // cout << " " << element_node[i][TYPE_NNODES[i]*j + k]; + // } + // cout << endl; + // } + // } } \ No newline at end of file diff --git a/driver/gpu_test.C b/driver/gpu_test.C index 5cc81a2..980c4ad 100644 --- a/driver/gpu_test.C +++ b/driver/gpu_test.C @@ -10,9 +10,8 @@ void print_gpu_info() #ifdef TIOGA_HAS_GPU #if defined(CUDA_VERSION) std::cout << "CUDA configuration: " - << "CUDA_VERSION: " << CUDA_VERSION - << " " << CUDA_VERSION / 1000 << " " - << (CUDA_VERSION % 1000) / 10 << std::endl; + << "CUDA_VERSION: " << CUDA_VERSION << " " << CUDA_VERSION / 1000 + << " " << (CUDA_VERSION % 1000) / 10 << std::endl; #endif int ndevices; gpu::gpuDeviceProp_t dev; @@ -25,10 +24,8 @@ void print_gpu_info() TIOGA_GPU_CALL_CHECK(GetDeviceProperties(&dev, rankDevice)); char busid[512]; TIOGA_GPU_CALL_CHECK(DeviceGetPCIBusId(busid, 512, rankDevice)); - std::cout << "[" << rankDevice << "] " - << dev.name << " CC: " << dev.major << "." << dev.minor - << " ID: " << busid - << " GM: " + std::cout << "[" << rankDevice << "] " << dev.name << " CC: " << dev.major + << "." << dev.minor << " ID: " << busid << " GM: " << (static_cast(dev.totalGlobalMem) / (1 << 30)) << "GB" << " ShMem/Blk: " << (dev.sharedMemPerBlock / (1 << 10)) << "KB" << std::endl; @@ -46,7 +43,8 @@ void test_gpu_send_recv() std::cout << "BEGIN TEST gpu_send_recv" << std::endl; std::vector hvec(10, 10); - int* dptr = gpu::push_to_device(hvec.data(), hvec.size() * sizeof(int)); + int* dptr = + gpu::push_to_device(hvec.data(), hvec.size() * sizeof(int)); if (dptr == nullptr) { std::cerr << "FAIL TEST gpu_send_recv" << std::endl; @@ -59,7 +57,7 @@ void test_gpu_send_recv() int max_val = std::numeric_limits::lowest(); int min_val = std::numeric_limits::max(); - for (int i=0; i < 10; ++i) { + for (int i = 0; i < 10; ++i) { max_val = std::max(hvec[i], max_val); min_val = std::min(hvec[i], min_val); } @@ -68,16 +66,14 @@ void test_gpu_send_recv() TIOGA_FREE_DEVICE(dptr); - if (dptr != nullptr) - std::cout << "ERROR deallocating memory" << std::endl; + if (dptr != nullptr) std::cout << "ERROR deallocating memory" << std::endl; std::cout << "END TEST gpu_send_recv" << std::endl << std::endl; } #ifdef TIOGA_HAS_GPU TIOGA_GPU_GLOBAL void vec_add(double* out, double* a, double* b, int n) { - for (int i=0; i < n; ++i) - out[i] = a[i] + b[i]; + for (int i = 0; i < n; ++i) out[i] = a[i] + b[i]; } void test_cuda_vec_add() @@ -96,10 +92,10 @@ void test_cuda_vec_add() constexpr double csum_exact = 30.0 * N; double sum = 0.0; - for (int i=0; i < N; ++i) - sum += cvec[i]; + for (int i = 0; i < N; ++i) sum += cvec[i]; - std::cout << "Expected = " << csum_exact << "; actual = " << sum << std::endl; + std::cout << "Expected = " << csum_exact << "; actual = " << sum + << std::endl; TIOGA_FREE_DEVICE(da); TIOGA_FREE_DEVICE(db); diff --git a/driver/kokkos.C b/driver/kokkos.C index ec2e096..c2b4852 100644 --- a/driver/kokkos.C +++ b/driver/kokkos.C @@ -1,7 +1,6 @@ #include -extern "C" -{ - void c_kokkos_initialize() { Kokkos::initialize(); } - void c_kokkos_finalize() { Kokkos::finalize(); } +extern "C" { +void c_kokkos_initialize() { Kokkos::initialize(); } +void c_kokkos_finalize() { Kokkos::finalize(); } } diff --git a/src/ADT.C b/src/ADT.C index dd3c4bc..55f9b4d 100644 --- a/src/ADT.C +++ b/src/ADT.C @@ -16,9 +16,9 @@ // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /** - * Build an alternating digital tree + * Build an alternating digital tree */ #include #include @@ -26,105 +26,101 @@ #include "ADT.h" #include "buildADTrecursion.h" -void ADT::buildADT(int d, int nelements,double *elementBbox) +void ADT::buildADT(int d, int nelements, double* elementBbox) { - int i,i2,j6,j,i4; - int *elementsAvailable; - double *adtWork; - int adtCount,parent,level,nav; - int side; - double tolerance,delta; - FILE *fp,*fp1; - // - /* set dimensions and number of elements */ - // - ndim=d; - nelem=nelements; - /* set element bbox pointer */ - coord=elementBbox; - /* - * Allocate work arrays - */ - elementsAvailable=(int *) malloc(sizeof(int)*nelem); - adtWork=(double *) malloc(sizeof(double)*nelem); - /* - * Allocate arrays in the class - */ - if (adtExtents) TIOGA_FREE(adtExtents); - adtExtents=(double *) malloc(sizeof(double)*ndim); - if (adtIntegers) TIOGA_FREE(adtIntegers); - adtIntegers=(int *) malloc(sizeof(int)*4*nelem); - if (adtReals) TIOGA_FREE(adtReals); - adtReals=(double *) malloc(sizeof(double)*nelem*ndim); - /* - * Determine extent of elements - */ - for(i=0;i #include "TiogaMeshInfo.h" #include "codetypes.h" @@ -29,740 +29,715 @@ void CartBlock::registerData(int lid, TIOGA::AMRMeshInfo* minfo) { - local_id = lid; - global_id = minfo->global_idmap.hptr[lid]; - ibl_cell = minfo->iblank_cell.hptr[lid]; - ibl_node = minfo->iblank_node.hptr[lid]; + local_id = lid; + global_id = minfo->global_idmap.hptr[lid]; + ibl_cell = minfo->iblank_cell.hptr[lid]; + ibl_node = minfo->iblank_node.hptr[lid]; - registerSolution(lid, minfo); + registerSolution(lid, minfo); } void CartBlock::registerSolution(int lid, TIOGA::AMRMeshInfo* minfo) { - nvar_cell = minfo->nvar_cell; - nvar_node = minfo->nvar_node; - qcell = minfo->qcell.hptr[lid]; - qnode = minfo->qnode.hptr[lid]; + nvar_cell = minfo->nvar_cell; + nvar_node = minfo->nvar_node; + qcell = minfo->qcell.hptr[lid]; + qnode = minfo->qnode.hptr[lid]; } -void CartBlock::getInterpolatedData(int *nints,int *nreals,int **intData, - double **realData) +void CartBlock::getInterpolatedData( + int* nints, int* nreals, int** intData, double** realData) { - int i,n; - double *qq; - int *tmpint; - double *tmpreal; - int icount,dcount; - int nintold,nrealold; - int interpCount=0; - double weight; - listptr=interpList; - while(listptr!=NULL) - { - interpCount++; - listptr=listptr->next; + int i, n; + double* qq; + int* tmpint; + double* tmpreal; + int icount, dcount; + int nintold, nrealold; + int interpCount = 0; + double weight; + listptr = interpList; + while (listptr != NULL) { + interpCount++; + listptr = listptr->next; } - if (interpCount > 0) - { - nintold=(*nints); - nrealold=(*nreals); - if (nintold > 0) { - tmpint=(int *)malloc(sizeof(int)*3*(*nints)); - tmpreal=(double *)malloc(sizeof(double)*(*nreals)); - for(i=0;i<(*nints)*3;i++) tmpint[i]=(*intData)[i]; - for(i=0;i<(*nreals);i++) tmpreal[i]=(*realData)[i]; - // - TIOGA_FREE((*intData)); - TIOGA_FREE((*realData)); // didn't free this before ?? - // - } - (*nints)+=interpCount; - (*nreals)+=(interpCount*(nvar_cell+nvar_node)); - (*intData)=(int *)malloc(sizeof(int)*3*(*nints)); - (*realData)=(double *)malloc(sizeof(double)*(*nreals)); - if (nintold > 0) { - for(i=0;ireceptorInfo[0]; - (*intData)[icount++]=-1-listptr->receptorInfo[2]; - (*intData)[icount++]=listptr->receptorInfo[1]; - - for(n=0;n<(nvar_cell+nvar_node);n++) qq[n]=0; // zero out solution - - for(i=0;inweights;i++) - { - int cell_index = cart_utils::get_cell_index(dims[0],dims[1],nf, - listptr->inode[3*i],listptr->inode[3*i+1],listptr->inode[3*i+2]); - for(n=0;nweights[i]; - qq[n]+=qcell[cell_index+ncell_nf*n]*weight; - } - - int ind_offset = 3*(listptr->nweights+i); - int node_index = cart_utils::get_node_index(dims[0],dims[1],nf, - listptr->inode[ind_offset],listptr->inode[ind_offset+1],listptr->inode[ind_offset+2]); - for(n=0;nweights[listptr->nweights+i]; - qq[nvar_cell+n]+=qnode[node_index+nnode_nf*n]*weight; - } + if (interpCount > 0) { + nintold = (*nints); + nrealold = (*nreals); + if (nintold > 0) { + tmpint = (int*)malloc(sizeof(int) * 3 * (*nints)); + tmpreal = (double*)malloc(sizeof(double) * (*nreals)); + for (i = 0; i < (*nints) * 3; i++) tmpint[i] = (*intData)[i]; + for (i = 0; i < (*nreals); i++) tmpreal[i] = (*realData)[i]; + // + TIOGA_FREE((*intData)); + TIOGA_FREE((*realData)); // didn't free this before ?? + // + } + (*nints) += interpCount; + (*nreals) += (interpCount * (nvar_cell + nvar_node)); + (*intData) = (int*)malloc(sizeof(int) * 3 * (*nints)); + (*realData) = (double*)malloc(sizeof(double) * (*nreals)); + if (nintold > 0) { + for (i = 0; i < nintold * 3; i++) (*intData)[i] = tmpint[i]; + for (i = 0; i < nrealold; i++) (*realData)[i] = tmpreal[i]; + TIOGA_FREE(tmpint); + TIOGA_FREE(tmpreal); } + listptr = interpList; + icount = 3 * nintold; + dcount = nrealold; + qq = (double*)malloc(sizeof(double) * (nvar_cell + nvar_node)); + while (listptr != NULL) { + (*intData)[icount++] = listptr->receptorInfo[0]; + (*intData)[icount++] = -1 - listptr->receptorInfo[2]; + (*intData)[icount++] = listptr->receptorInfo[1]; + + for (n = 0; n < (nvar_cell + nvar_node); n++) + qq[n] = 0; // zero out solution + + for (i = 0; i < listptr->nweights; i++) { + int cell_index = cart_utils::get_cell_index( + dims[0], dims[1], nf, listptr->inode[3 * i], + listptr->inode[3 * i + 1], listptr->inode[3 * i + 2]); + for (n = 0; n < nvar_cell; n++) { + weight = listptr->weights[i]; + qq[n] += qcell[cell_index + ncell_nf * n] * weight; + } + + int ind_offset = 3 * (listptr->nweights + i); + int node_index = cart_utils::get_node_index( + dims[0], dims[1], nf, listptr->inode[ind_offset], + listptr->inode[ind_offset + 1], + listptr->inode[ind_offset + 2]); + for (n = 0; n < nvar_node; n++) { + weight = listptr->weights[listptr->nweights + i]; + qq[nvar_cell + n] += + qnode[node_index + nnode_nf * n] * weight; + } + } - for(n=0;n<(nvar_cell+nvar_node);n++) (*realData)[dcount++]=qq[n]; // update solution + for (n = 0; n < (nvar_cell + nvar_node); n++) + (*realData)[dcount++] = qq[n]; // update solution - listptr=listptr->next; - } - TIOGA_FREE(qq); + listptr = listptr->next; + } + TIOGA_FREE(qq); } } - -void CartBlock::update(double *qval,int index) +void CartBlock::update(double* qval, int index) { - if(index >= ncell_nf) { - if(nvar_node == 0) return; - for(int i=0;i= ncell_nf) { + if (nvar_node == 0) return; + for (int i = 0; i < nvar_node; i++) + qnode[index - ncell_nf + nnode_nf * i] = qval[nvar_cell + i]; + } else { + if (nvar_cell == 0) return; + for (int i = 0; i < nvar_cell; i++) + qcell[index + ncell_nf * i] = qval[i]; + } } - -void CartBlock::preprocess(CartGrid *cg) - { +void CartBlock::preprocess(CartGrid* cg) +{ int nfrac; - for(int n=0;n<3;n++) xlo[n]=cg->xlo[3*global_id+n]; - for(int n=0;n<3;n++) dx[n]=cg->dx[3*global_id+n]; - dims[0]=cg->ihi[3*global_id] -cg->ilo[3*global_id ]+1; - dims[1]=cg->ihi[3*global_id+1]-cg->ilo[3*global_id+1]+1; - dims[2]=cg->ihi[3*global_id+2]-cg->ilo[3*global_id+2]+1; - nf=cg->nf; - myid=cg->myid; - donor_frac=cg->donor_frac; - ncell=dims[0]*dims[1]*dims[2]; - ncell_nf=(dims[0]+2*nf)*(dims[1]+2*nf)*(dims[2]+2*nf); - nnode=(dims[0]+1)*(dims[1]+1)*(dims[2]+1); - nnode_nf=(dims[0]+1+2*nf)*(dims[1]+1+2*nf)*(dims[2]+1+2*nf); - }; + for (int n = 0; n < 3; n++) xlo[n] = cg->xlo[3 * global_id + n]; + for (int n = 0; n < 3; n++) dx[n] = cg->dx[3 * global_id + n]; + dims[0] = cg->ihi[3 * global_id] - cg->ilo[3 * global_id] + 1; + dims[1] = cg->ihi[3 * global_id + 1] - cg->ilo[3 * global_id + 1] + 1; + dims[2] = cg->ihi[3 * global_id + 2] - cg->ilo[3 * global_id + 2] + 1; + nf = cg->nf; + myid = cg->myid; + donor_frac = cg->donor_frac; + ncell = dims[0] * dims[1] * dims[2]; + ncell_nf = (dims[0] + 2 * nf) * (dims[1] + 2 * nf) * (dims[2] + 2 * nf); + nnode = (dims[0] + 1) * (dims[1] + 1) * (dims[2] + 1); + nnode_nf = (dims[0] + 1 + 2 * nf) * (dims[1] + 1 + 2 * nf) * + (dims[2] + 1 + 2 * nf); +}; void CartBlock::initializeLists(void) { - donorList=(DONORLIST **)malloc(sizeof(DONORLIST *)*(ncell+nnode)); - for(int i=0;i<(ncell+nnode);i++) donorList[i]=NULL; + donorList = (DONORLIST**)malloc(sizeof(DONORLIST*) * (ncell + nnode)); + for (int i = 0; i < (ncell + nnode); i++) donorList[i] = NULL; } void CartBlock::clearLists(void) { - int i; - if (donorList) { - for(i=0;inext = (INTERPLIST2*)malloc(sizeof(INTERPLIST2)); + listptr = listptr->next; } - else - { - listptr->next=(INTERPLIST2 *)malloc(sizeof(INTERPLIST2)); - listptr=listptr->next; + listptr->next = NULL; + listptr->inode = NULL; + listptr->weights = NULL; + listptr->receptorInfo[0] = procid; + listptr->receptorInfo[1] = remoteid; + listptr->receptorInfo[2] = remoteblockid; + for (n = 0; n < 3; n++) { + ix[n] = (xtmp[n] - xlo[n]) / dx[n]; + rst[n] = (xtmp[n] - xlo[n] - ix[n] * dx[n]) / dx[n]; + if (ix[n] == dims[n]) { + if (fabs(rst[n]) < TOL) { + ix[n]--; + rst[n] = (xtmp[n] - xlo[n] - ix[n] * dx[n]) / dx[n]; + } + } + if (!(ix[n] >= 0 && ix[n] < dims[n])) { + TRACEI(procid); + TRACEI(global_id); + TRACEI(local_id); + TRACEI(remoteid); + TRACEI(myid); + TRACED(xtmp[0]); + TRACED(xtmp[1]); + TRACED(xtmp[2]); + TRACED(xlo[0]); + TRACED(xlo[1]); + TRACED(xlo[2]); + TRACED(dx[0]); + TRACED(dx[1]); + TRACED(dx[2]); + TRACEI(ix[n]); + TRACEI(n); + TRACEI(dims[n]); + printf("--------------------------\n"); + } + assert((ix[n] >= 0 && ix[n] < dims[n])); } - listptr->next=NULL; - listptr->inode=NULL; - listptr->weights=NULL; - listptr->receptorInfo[0]=procid; - listptr->receptorInfo[1]=remoteid; - listptr->receptorInfo[2]=remoteblockid; - for(n=0;n<3;n++) - { - ix[n]=(xtmp[n]-xlo[n])/dx[n]; - rst[n]=(xtmp[n]-xlo[n]-ix[n]*dx[n])/dx[n]; - if (ix[n]==dims[n]) - { - if (fabs(rst[n]) < TOL) - { - ix[n]--; - rst[n]=(xtmp[n]-xlo[n]-ix[n]*dx[n])/dx[n]; - } - } - if (!(ix[n] >=0 && ix[n] < dims[n])) { - TRACEI(procid); - TRACEI(global_id); - TRACEI(local_id); - TRACEI(remoteid); - TRACEI(myid); - TRACED(xtmp[0]); - TRACED(xtmp[1]); - TRACED(xtmp[2]); - TRACED(xlo[0]); - TRACED(xlo[1]); - TRACED(xlo[2]); - TRACED(dx[0]); - TRACED(dx[1]); - TRACED(dx[2]); - TRACEI(ix[n]); - TRACEI(n); - TRACEI(dims[n]); - printf("--------------------------\n"); - } - assert((ix[n] >=0 && ix[n] < dims[n])); + if (donor_frac == nullptr) { + listptr->nweights = 8; + listptr->weights = + (double*)malloc(sizeof(double) * (listptr->nweights * 2)); + listptr->inode = + (int*)malloc(sizeof(int) * (listptr->nweights * 2 * 3)); + + cart_interp::linear_interpolation( + nf, ix, dims, rst, &(listptr->nweights), listptr->inode, + listptr->weights, false); + + int ind_offset = 3 * listptr->nweights; + cart_interp::linear_interpolation( + nf, ix, dims, rst, &(listptr->nweights), + &(listptr->inode[ind_offset]), + &(listptr->weights[listptr->nweights]), true); } - if (donor_frac == nullptr) { - listptr->nweights=8; - listptr->weights=(double *)malloc(sizeof(double)*(listptr->nweights*2)); - listptr->inode=(int *)malloc(sizeof(int)*(listptr->nweights*2*3)); - - cart_interp::linear_interpolation(nf,ix,dims,rst,&(listptr->nweights), - listptr->inode,listptr->weights,false); - - int ind_offset = 3*listptr->nweights; - cart_interp::linear_interpolation(nf,ix,dims,rst,&(listptr->nweights), - &(listptr->inode[ind_offset]),&(listptr->weights[listptr->nweights]),true); - } - TIOGA_FREE(rst); + TIOGA_FREE(rst); } - -void CartBlock::insertInDonorList(int senderid,int index,int meshtagdonor,int remoteid,int remoteblockid, double cellRes) + +void CartBlock::insertInDonorList( + int senderid, + int index, + int meshtagdonor, + int remoteid, + int remoteblockid, + double cellRes) { - DONORLIST *temp1; - int i,j,k,x_stride,xy_stride; - int pointid; - temp1=(DONORLIST *)malloc(sizeof(DONORLIST)); - - // Get point-id accounting for nf - if(index < ncell_nf){ - x_stride = (dims[0]+2*nf); - xy_stride = x_stride*(dims[1]+2*nf); - k = index / xy_stride; - index %= xy_stride; - j = index / x_stride; - index %= x_stride; - i = index; - pointid=(k-nf)*(dims[0]*dims[1])+(j-nf)*dims[0]+(i-nf); - } - else{ - index = index-ncell_nf; - x_stride = (dims[0]+1+2*nf); - xy_stride = x_stride*(dims[1]+1+2*nf); - k = index / xy_stride; - index %= xy_stride; - j = index / x_stride; - index %= x_stride; - i = index; - pointid=(k-nf)*(dims[0]+1)*(dims[1]+1)+(j-nf)*(dims[0]+1)+(i-nf)+ncell; - } - - if (!(pointid >= 0 && pointid < ncell+nnode)) { - TRACEI(index); - TRACEI(nf); - TRACEI(dims[0]); - TRACEI(dims[1]); - TRACEI(dims[2]); - TRACEI(pointid); - } - assert((pointid >= 0 && pointid < ncell+nnode)); - - temp1->donorData[0]=senderid; - temp1->donorData[1]=meshtagdonor; - temp1->donorData[2]=remoteid; - temp1->donorData[3]=remoteblockid; - temp1->donorRes=cellRes; - temp1->cancel=0; - insertInList(&(donorList[pointid]),temp1); + DONORLIST* temp1; + int i, j, k, x_stride, xy_stride; + int pointid; + temp1 = (DONORLIST*)malloc(sizeof(DONORLIST)); + + // Get point-id accounting for nf + if (index < ncell_nf) { + x_stride = (dims[0] + 2 * nf); + xy_stride = x_stride * (dims[1] + 2 * nf); + k = index / xy_stride; + index %= xy_stride; + j = index / x_stride; + index %= x_stride; + i = index; + pointid = + (k - nf) * (dims[0] * dims[1]) + (j - nf) * dims[0] + (i - nf); + } else { + index = index - ncell_nf; + x_stride = (dims[0] + 1 + 2 * nf); + xy_stride = x_stride * (dims[1] + 1 + 2 * nf); + k = index / xy_stride; + index %= xy_stride; + j = index / x_stride; + index %= x_stride; + i = index; + pointid = (k - nf) * (dims[0] + 1) * (dims[1] + 1) + + (j - nf) * (dims[0] + 1) + (i - nf) + ncell; + } + + if (!(pointid >= 0 && pointid < ncell + nnode)) { + TRACEI(index); + TRACEI(nf); + TRACEI(dims[0]); + TRACEI(dims[1]); + TRACEI(dims[2]); + TRACEI(pointid); + } + assert((pointid >= 0 && pointid < ncell + nnode)); + + temp1->donorData[0] = senderid; + temp1->donorData[1] = meshtagdonor; + temp1->donorData[2] = remoteid; + temp1->donorData[3] = remoteblockid; + temp1->donorRes = cellRes; + temp1->cancel = 0; + insertInList(&(donorList[pointid]), temp1); } -void CartBlock::processDonors(HOLEMAP *holemap, int nmesh) +void CartBlock::processDonors(HOLEMAP* holemap, int nmesh) { - processIblank(holemap, nmesh, false); // for cell receptors - processIblank(holemap, nmesh, true); // for node receptors + processIblank(holemap, nmesh, false); // for cell receptors + processIblank(holemap, nmesh, true); // for node receptors } -void CartBlock::processDonors(ADAPTIVE_HOLEMAP *holemap, int nmesh) +void CartBlock::processDonors(ADAPTIVE_HOLEMAP* holemap, int nmesh) { - processIblank(holemap, nmesh, false); // for cell receptors - processIblank(holemap, nmesh, true); // for node receptors + processIblank(holemap, nmesh, false); // for cell receptors + processIblank(holemap, nmesh, true); // for node receptors } -void CartBlock::processIblank(HOLEMAP *holemap, int nmesh, bool isNodal) +void CartBlock::processIblank(HOLEMAP* holemap, int nmesh, bool isNodal) { - //FILE*fp; - char fname[80]; - char qstr[2]; - char intstring[7]; - int ni,nj,nk,ibcheck; - //sprintf(intstring,"%d",100000+myid); - //sprintf(fname,"fringes_%s.dat",&(intstring[1])); - //if (local_id==0) - // { - // fp=fopen(fname,"w"); - // } - //else - // { - // fp=fopen(fname,"a"); - // } - - DONORLIST *temp; - int* iflag=(int *)malloc(sizeof(int)*nmesh); - double* xtmp=(double *)malloc(sizeof(double)*3); - - // set variables based on isNodal flag - int idof = isNodal ? (ncell-1) : -1; - int* iblank = isNodal ? ibl_node : ibl_cell; - int nX = isNodal ? (dims[0]+1) : dims[0]; - int nY = isNodal ? (dims[1]+1) : dims[1]; - int nZ = isNodal ? (dims[2]+1) : dims[2]; - - // - // first mark hole points - // - for(int k=0;kdonorData[1] - BASE; + iflag[meshtagdonor] = 1; + temp = temp->next; + } + for (int h = 0; h < nmesh; h++) { + if (holemap[h].existWall) { + if (!iflag[h]) + if (checkHoleMap( + xtmp, holemap[h].nx, holemap[h].sam, + holemap[h].extents)) { + int ibindex = + isNodal + ? cart_utils::get_node_index( + dims[0], dims[1], nf, i, j, k) + : cart_utils::get_cell_index( + dims[0], dims[1], nf, i, j, + k); + iblank[ibindex] = 0; + break; + } + } + } + } } - } - else - { - temp=donorList[idof]; - for(int h=0;hdonorData[1]-BASE; - iflag[meshtagdonor]=1; - temp=temp->next; - } - for(int h=0;hcancel = 1; + temp = temp->next; + } + } + } else { + if ((temp = donorList[idof]) != NULL) { + // simplify logic here: the first one on the list is the + // best donor anyway, accept it if its not a mandatory + // receptor on the donor side + if (temp->donorRes < BIGVALUE) { + iblank[ibindex] = -1; + temp = temp->next; + } + // cancel other donors if some exist + while (temp != NULL) { + temp->cancel = 1; + temp = temp->next; + } + } } } - } - } - } - - // - // mark fringe points - // - idof = isNodal ? (ncell-1) : -1; - for(int k=0;k= dims[0]*dims[1]*dims[2])) + continue; ibcheck=ibcheck && (ibl_cell[ibindex]!=0); + } + if (!ibcheck) { - temp->cancel=1; - temp=temp->next; + printf("fixing orphan: myid/globalid/localid/(i,j,k)=%d %d %d %d + %d %d \n", myid,global_id,local_id,i,j,k); + ibindex=(k+nf)*(dims[1]+2*nf)*(dims[0]+2*nf)+(j+nf)*(dims[0]+2*nf)+i+nf; + ibl_cell[ibindex]=0; } } } - else - { - if ((temp=donorList[idof])!=NULL) - { - // simplify logic here: the first one on the list is the - // best donor anyway, accept it if its not a mandatory - // receptor on the donor side - if (temp->donorRes < BIGVALUE) - { - iblank[ibindex]=-1; - temp=temp->next; - } - // cancel other donors if some exist - while(temp!=NULL) - { - temp->cancel=1; - temp=temp->next; - } - } - } - } - - - /* FIXME: this piece of code needs to be modified to account for isNodal - for(k=0;k= dims[0]*dims[1]*dims[2])) continue; - ibcheck=ibcheck && (ibl_cell[ibindex]!=0); - } - if (!ibcheck) - { - printf("fixing orphan: myid/globalid/localid/(i,j,k)=%d %d %d %d %d %d \n", - myid,global_id,local_id,i,j,k); - ibindex=(k+nf)*(dims[1]+2*nf)*(dims[0]+2*nf)+(j+nf)*(dims[0]+2*nf)+i+nf; - ibl_cell[ibindex]=0; - } - } - } - */ + */ - if (iflag) TIOGA_FREE(iflag); - if (xtmp) TIOGA_FREE(xtmp); - // fclose(fp); + if (iflag) TIOGA_FREE(iflag); + if (xtmp) TIOGA_FREE(xtmp); + // fclose(fp); } -void CartBlock::processIblank(ADAPTIVE_HOLEMAP *holemap, int nmesh, bool isNodal) +void CartBlock::processIblank( + ADAPTIVE_HOLEMAP* holemap, int nmesh, bool isNodal) { - //FILE*fp; - char fname[80]; - char qstr[2]; - char intstring[7]; - int ni,nj,nk,ibcheck; - - DONORLIST *temp; - int* iflag=(int *)malloc(sizeof(int)*nmesh); - double* xtmp=(double *)malloc(sizeof(double)*3); - - // set variables based on isNodal flag - int idof = isNodal ? (ncell-1) : -1; - int* iblank = isNodal ? ibl_node : ibl_cell; - int nX = isNodal ? (dims[0]+1) : dims[0]; - int nY = isNodal ? (dims[1]+1) : dims[1]; - int nZ = isNodal ? (dims[2]+1) : dims[2]; - - // - // first mark hole points - // - for(int k=0;kdonorData[1] - BASE; + iflag[meshtagdonor] = 1; + temp = temp->next; + } + for (int h = 0; h < nmesh; h++) { + if (holemap[h].existWall) { + if (!iflag[h]) { + int SB_val = + checkAdaptiveHoleMap(&xtmp[0], &holemap[h]); + if (SB_val != OUTSIDE_SB) { + int ibindex = + isNodal + ? cart_utils::get_node_index( + dims[0], dims[1], nf, i, j, k) + : cart_utils::get_cell_index( + dims[0], dims[1], nf, i, j, + k); + iblank[ibindex] = 0; + break; + } + } + } + } + } } - } - else - { - temp=donorList[idof]; - for(int h=0;hdonorData[1]-BASE; - iflag[meshtagdonor]=1; - temp=temp->next; - } - for(int h=0;hcancel = 1; + temp = temp->next; + } + } + } else { + if ((temp = donorList[idof]) != NULL) { + // simplify logic here: the first one on the list is the + // best donor anyway, accept it if its not a mandatory + // receptor on the donor side + if (temp->donorRes < BIGVALUE) { + iblank[ibindex] = -1; + temp = temp->next; + } + // cancel other donors if some exist + while (temp != NULL) { + temp->cancel = 1; + temp = temp->next; + } + } } - } } - } - } - } - - // - // mark fringe points - // - idof = isNodal ? (ncell-1) : -1; - for(int k=0;k= dims[0]*dims[1]*dims[2])) + continue; ibcheck=ibcheck && (ibl_cell[ibindex]!=0); + } + if (!ibcheck) { - temp->cancel=1; - temp=temp->next; + printf("fixing orphan: myid/globalid/localid/(i,j,k)=%d %d %d %d + %d %d \n", myid,global_id,local_id,i,j,k); + ibindex=(k+nf)*(dims[1]+2*nf)*(dims[0]+2*nf)+(j+nf)*(dims[0]+2*nf)+i+nf; + ibl_cell[ibindex]=0; } } } - else - { - if ((temp=donorList[idof])!=NULL) - { - // simplify logic here: the first one on the list is the - // best donor anyway, accept it if its not a mandatory - // receptor on the donor side - if (temp->donorRes < BIGVALUE) - { - iblank[ibindex]=-1; - temp=temp->next; - } - // cancel other donors if some exist - while(temp!=NULL) - { - temp->cancel=1; - temp=temp->next; - } - } - } - } - - - /* FIXME: this piece of code needs to be modified to account for isNodal - for(k=0;k= dims[0]*dims[1]*dims[2])) continue; - ibcheck=ibcheck && (ibl_cell[ibindex]!=0); - } - if (!ibcheck) - { - printf("fixing orphan: myid/globalid/localid/(i,j,k)=%d %d %d %d %d %d \n", - myid,global_id,local_id,i,j,k); - ibindex=(k+nf)*(dims[1]+2*nf)*(dims[0]+2*nf)+(j+nf)*(dims[0]+2*nf)+i+nf; - ibl_cell[ibindex]=0; - } - } - } - */ + */ - if (iflag) TIOGA_FREE(iflag); - if (xtmp) TIOGA_FREE(xtmp); - // fclose(fp); + if (iflag) TIOGA_FREE(iflag); + if (xtmp) TIOGA_FREE(xtmp); + // fclose(fp); } -void CartBlock::getCancellationData(int *cancelledData, int *ncancel) +void CartBlock::getCancellationData(int* cancelledData, int* ncancel) { - int i,j,k,m,isNodal; - int idof; - DONORLIST *temp; - idof=-1; - m=0; - *ncancel=0; - for(isNodal=0;isNodal<2;isNodal++) - for(k=0;kcancel==1) { - (*ncancel)++; - cancelledData[m++]=temp->donorData[0]; - cancelledData[m++]=1; - cancelledData[m++]=temp->donorData[2]; - cancelledData[m++]=temp->donorData[3]; - } - temp=temp->next; - } - } - } + int i, j, k, m, isNodal; + int idof; + DONORLIST* temp; + idof = -1; + m = 0; + *ncancel = 0; + for (isNodal = 0; isNodal < 2; isNodal++) + for (k = 0; k < dims[2] + isNodal; k++) + for (j = 0; j < dims[1] + isNodal; j++) + for (i = 0; i < dims[0] + isNodal; i++) { + idof++; + if (donorList[idof] != NULL) { + temp = donorList[idof]; + while (temp != NULL) { + if (temp->cancel == 1) { + (*ncancel)++; + cancelledData[m++] = temp->donorData[0]; + cancelledData[m++] = 1; + cancelledData[m++] = temp->donorData[2]; + cancelledData[m++] = temp->donorData[3]; + } + temp = temp->next; + } + } + } } - void CartBlock::writeCellFile(int bid) { - int ibmin,ibmax; - char fname[80]; - char qstr[2]; - char intstring[12]; - char hash,c; - int i,n,j,k,ibindex; - int bodytag; - FILE *fp; - int ba,id; - int nvert; - int nnodes,ncells; - int dd1,dd2; - - ibmin=30000000; - ibmax=-30000000; - nnodes=(dims[1]+1)*(dims[0]+1)*(dims[2]+1); - ncells=dims[0]*dims[1]*dims[2]; - sprintf(intstring,"%d",100000+myid); - sprintf(fname,"cart_cell%s.dat",&(intstring[1])); - if (bid==0) - { - fp=fopen(fname,"w"); + int ibmin, ibmax; + char fname[80]; + char qstr[2]; + char intstring[12]; + char hash, c; + int i, n, j, k, ibindex; + int bodytag; + FILE* fp; + int ba, id; + int nvert; + int nnodes, ncells; + int dd1, dd2; + + ibmin = 30000000; + ibmax = -30000000; + nnodes = (dims[1] + 1) * (dims[0] + 1) * (dims[2] + 1); + ncells = dims[0] * dims[1] * dims[2]; + snprintf(intstring, sizeof(intstring), "%d", 100000 + myid); + snprintf(fname, sizeof(fname), "cart_cell%s.dat", &(intstring[1])); + if (bid == 0) { + fp = fopen(fname, "w"); + } else { + fp = fopen(fname, "a"); } - else - { - fp=fopen(fname,"a"); + if (bid == 0) { + fprintf(fp, "TITLE =\"Tioga output\"\n"); + fprintf(fp, "VARIABLES=\"X\",\"Y\",\"Z\",\"IBLANK_CELL\" "); + fprintf(fp, "\n"); } - if (bid==0) { - fprintf(fp,"TITLE =\"Tioga output\"\n"); - fprintf(fp,"VARIABLES=\"X\",\"Y\",\"Z\",\"IBLANK_CELL\" "); - fprintf(fp,"\n"); - } - fprintf(fp,"ZONE T=\"VOL_MIXED\",N=%d E=%d ET=BRICK, F=FEBLOCK\n",nnodes, - ncells); - fprintf(fp,"VARLOCATION = (1=NODAL, 2=NODAL, 3=NODAL, 4=CELLCENTERED)\n"); - - for(k=0;k 0) && !((nq_cell > 0) && (nq_node > 0))); - if (nq_node > 0) { - nvar_node = nq_node; - qnode = qin; - } else if (nq_cell > 0) { - nvar_cell = nq_cell; - qcell = qin; - } - }; - int num_cell_var() const { return nvar_cell; } - int num_node_var() const { return nvar_node; } - void preprocess(CartGrid *cg); - void getInterpolatedData(int *nints, int *nreals, int **intData, - double **realData); - void update(double *qval, int index); - void getCancellationData(int *cancelledData, int *ncancel); - void processDonors(HOLEMAP *holemap, int nmesh); - void processDonors(ADAPTIVE_HOLEMAP *holemap, int nmesh); - void processIblank(HOLEMAP *holemap, int nmesh, bool isNodal); - void processIblank(ADAPTIVE_HOLEMAP *holemap, int nmesh, bool isNodal); - void insertInDonorList(int senderid, int index, int meshtagdonor, - int remoteid, int remoteblockid, double cellRes); - void insertInInterpList(int procid, int remoteid, int remoteblockid, - double *xtmp); - void writeCellFile(int bid); - void clearLists(void); - void initializeLists(void); + void registerData( + int local_id_in, int global_id_in, int* iblankin, int* iblanknin) + { + local_id = local_id_in; + global_id = global_id_in; + ibl_cell = iblankin; + ibl_node = iblanknin; + }; + void registerSolution(double* qin, int nq_cell, int nq_node) + { + assert((nq_cell + nq_node > 0) && !((nq_cell > 0) && (nq_node > 0))); + if (nq_node > 0) { + nvar_node = nq_node; + qnode = qin; + } else if (nq_cell > 0) { + nvar_cell = nq_cell; + qcell = qin; + } + }; + int num_cell_var() const { return nvar_cell; } + int num_node_var() const { return nvar_node; } + void preprocess(CartGrid* cg); + void getInterpolatedData( + int* nints, int* nreals, int** intData, double** realData); + void update(double* qval, int index); + void getCancellationData(int* cancelledData, int* ncancel); + void processDonors(HOLEMAP* holemap, int nmesh); + void processDonors(ADAPTIVE_HOLEMAP* holemap, int nmesh); + void processIblank(HOLEMAP* holemap, int nmesh, bool isNodal); + void processIblank(ADAPTIVE_HOLEMAP* holemap, int nmesh, bool isNodal); + void insertInDonorList( + int senderid, + int index, + int meshtagdonor, + int remoteid, + int remoteblockid, + double cellRes); + void insertInInterpList( + int procid, int remoteid, int remoteblockid, double* xtmp); + void writeCellFile(int bid); + void clearLists(void); + void initializeLists(void); }; #endif /* CARTBLOCK_H */ diff --git a/src/CartGrid.C b/src/CartGrid.C index d41b3f5..f9d319c 100644 --- a/src/CartGrid.C +++ b/src/CartGrid.C @@ -16,7 +16,7 @@ // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include "tioga_gpu.h" #include "TiogaMeshInfo.h" #include "codetypes.h" @@ -27,107 +27,107 @@ CartGrid::~CartGrid() { - if (own_data_ptrs) { - if (global_id) TIOGA_FREE(global_id); - if (level_num) TIOGA_FREE(level_num); - if (proc_id) TIOGA_FREE(proc_id); - if (local_id) TIOGA_FREE(local_id); - if (ilo) TIOGA_FREE(ilo); - if (ihi) TIOGA_FREE(ihi); - if (dims) TIOGA_FREE(dims); - if (xlo) TIOGA_FREE(xlo); - if (dx) TIOGA_FREE(dx); - } + if (own_data_ptrs) { + if (global_id) TIOGA_FREE(global_id); + if (level_num) TIOGA_FREE(level_num); + if (proc_id) TIOGA_FREE(proc_id); + if (local_id) TIOGA_FREE(local_id); + if (ilo) TIOGA_FREE(ilo); + if (ihi) TIOGA_FREE(ihi); + if (dims) TIOGA_FREE(dims); + if (xlo) TIOGA_FREE(xlo); + if (dx) TIOGA_FREE(dx); + } - if (own_amr_mesh_info && (m_info != nullptr)) { - TIOGA_FREE_DEVICE(m_info->level.dptr); - TIOGA_FREE_DEVICE(m_info->mpi_rank.dptr); - TIOGA_FREE_DEVICE(m_info->local_id.dptr); - TIOGA_FREE_DEVICE(m_info->ilow.dptr); - TIOGA_FREE_DEVICE(m_info->ihigh.dptr); - TIOGA_FREE_DEVICE(m_info->dims.dptr); - TIOGA_FREE_DEVICE(m_info->xlo.dptr); - TIOGA_FREE_DEVICE(m_info->dx.dptr); + if (own_amr_mesh_info && (m_info != nullptr)) { + TIOGA_FREE_DEVICE(m_info->level.dptr); + TIOGA_FREE_DEVICE(m_info->mpi_rank.dptr); + TIOGA_FREE_DEVICE(m_info->local_id.dptr); + TIOGA_FREE_DEVICE(m_info->ilow.dptr); + TIOGA_FREE_DEVICE(m_info->ihigh.dptr); + TIOGA_FREE_DEVICE(m_info->dims.dptr); + TIOGA_FREE_DEVICE(m_info->xlo.dptr); + TIOGA_FREE_DEVICE(m_info->dx.dptr); - delete m_info; - } + delete m_info; + } - if (lcount) TIOGA_FREE(lcount); - if (dxlvl) TIOGA_FREE(dxlvl); + if (lcount) TIOGA_FREE(lcount); + if (dxlvl) TIOGA_FREE(dxlvl); - if (m_info_device != nullptr) TIOGA_FREE_DEVICE(m_info_device); + if (m_info_device != nullptr) TIOGA_FREE_DEVICE(m_info_device); }; void CartGrid::registerData(TIOGA::AMRMeshInfo* minfo) { - own_data_ptrs = false; - own_amr_mesh_info = false; - m_info = minfo; - ngrids = minfo->ngrids_global; - global_id = nullptr; // unused - level_num = minfo->level.hptr; - proc_id = minfo->mpi_rank.hptr; - local_id = minfo->local_id.hptr; - ilo = minfo->ilow.hptr; - ihi = minfo->ihigh.hptr; - dims = minfo->dims.hptr; - xlo = minfo->xlo.hptr; - dx = minfo->dx.hptr; - nf = minfo->num_ghost; + own_data_ptrs = false; + own_amr_mesh_info = false; + m_info = minfo; + ngrids = minfo->ngrids_global; + global_id = nullptr; // unused + level_num = minfo->level.hptr; + proc_id = minfo->mpi_rank.hptr; + local_id = minfo->local_id.hptr; + ilo = minfo->ilow.hptr; + ihi = minfo->ihigh.hptr; + dims = minfo->dims.hptr; + xlo = minfo->xlo.hptr; + dx = minfo->dx.hptr; + nf = minfo->num_ghost; - if (m_info_device == nullptr) { - m_info_device = TIOGA::gpu::allocate_on_device( - sizeof(TIOGA::AMRMeshInfo)); - } - TIOGA::gpu::copy_to_device(m_info_device, m_info, sizeof(TIOGA::AMRMeshInfo)); + if (m_info_device == nullptr) { + m_info_device = TIOGA::gpu::allocate_on_device( + sizeof(TIOGA::AMRMeshInfo)); + } + TIOGA::gpu::copy_to_device( + m_info_device, m_info, sizeof(TIOGA::AMRMeshInfo)); } -void CartGrid::registerData(int nfin,int *idata,double *rdata,int ngridsin) +void CartGrid::registerData(int nfin, int* idata, double* rdata, int ngridsin) { - int i,i3,i6,iloc,n; - FILE *fp; - ngrids = ngridsin; - global_id=(int *) malloc(sizeof(int)*ngrids); - level_num=(int *) malloc(sizeof(int)*ngrids); - proc_id=(int *) malloc(sizeof(int)*ngrids); - ilo=(int *) malloc(sizeof(int)*3*ngrids); - ihi=(int *) malloc(sizeof(int)*3*ngrids); - xlo=(double *) malloc(sizeof(double)*3*ngrids); - dx=(double *) malloc(sizeof(double)*3*ngrids); - local_id=(int *)malloc(sizeof(int)*ngrids); - dims=(int *)malloc(sizeof(dims)*3*ngrids); - nf=nfin; - if (myid==0) fp=fopen("cartGrid.dat","w"); - for(i=0;i= level_num[i]) ? maxlevel: level_num[i]); + int i, n; + // + // find the global minimum coord location + // + xlosup[0] = xlosup[1] = xlosup[2] = BIGVALUE; + maxlevel = -1; + for (i = 0; i < ngrids; i++) { + for (n = 0; n < 3; n++) + xlosup[n] = + ((xlosup[n] <= xlo[3 * i + n]) ? xlosup[n] : xlo[3 * i + n]); + maxlevel = ((maxlevel >= level_num[i]) ? maxlevel : level_num[i]); } maxlevel++; - lcount=(int *)malloc(sizeof(int)*maxlevel); - dxlvl=(double *)malloc(sizeof(double)*3*maxlevel); - for(i=0;i=0 && flag==0;l--) - { - for(n=0;n<3;n++) - il[n]=floor((x[3*i+n]-xlosup[n])/dxlvl[3*l+n]); - for(j=0;j=xlo[3*j+n]); - // for(n=0;n<3;n++) flag=flag && (x[3*i+n] <=xlo[3*j+n]+ - // dx[3*j+n]*(dims[3*j+n])); - //for(n=0;n<3;n++) flag = flag && (il[n] >=ilo[3*j+n]); - //for(n=0;n<3;n++) flag = flag && (il[n] <=ihi[3*j+n]); - for(n=0;n<3;n++) flag=flag && ((x[3*i+n]-xlo[3*j+n]) > -TOL); - for(n=0;n<3;n++) flag=flag && ((x[3*i+n]- (xlo[3*j+n]+ - dx[3*j+n]*(dims[3*j+n]))) < TOL); - if (flag) { - dcount++; - donorid[i]=j; - } - } - } + int i, j, k, l, n, il[3]; + bool flag; + int dcount; + dcount = 0; + for (i = 0; i < npts; i++) { + flag = 0; + donorid[i] = -1; + for (l = maxlevel - 1; l >= 0 && flag == 0; l--) { + for (n = 0; n < 3; n++) + il[n] = floor((x[3 * i + n] - xlosup[n]) / dxlvl[3 * l + n]); + for (j = 0; j < ngrids && flag == 0; j++) { + if (level_num[j] == l) { + flag = 1; + // for(n=0;n<3;n++) flag=flag && (x[3*i+n] >=xlo[3*j+n]); + // for(n=0;n<3;n++) flag=flag && (x[3*i+n] <=xlo[3*j+n]+ + // dx[3*j+n]*(dims[3*j+n])); + // for(n=0;n<3;n++) flag = flag && (il[n] >=ilo[3*j+n]); + // for(n=0;n<3;n++) flag = flag && (il[n] <=ihi[3*j+n]); + for (n = 0; n < 3; n++) + flag = flag && ((x[3 * i + n] - xlo[3 * j + n]) > -TOL); + for (n = 0; n < 3; n++) + flag = flag && + ((x[3 * i + n] - + (xlo[3 * j + n] + + dx[3 * j + n] * (dims[3 * j + n]))) < TOL); + if (flag) { + dcount++; + donorid[i] = j; + } + } + } + } + if (myid == 2 && abs(x[3 * i] - 0.739573) < 1e-5 && + abs(x[3 * i + 1] + 0.259310) < 1e-5 && + abs(x[3 * i + 2] + 0.639614) < 1e-5) { + printf( + "%d %d %f %f %f %d\n", myid, i, x[3 * i], x[3 * i + 1], + x[3 * i + 2], donorid[i]); + } + if (donorid[i] == -1) + printf("%d %f %f %f\n", myid, x[3 * i], x[3 * i + 1], x[3 * i + 2]); } - if (myid==2 && abs(x[3*i]-0.739573) < 1e-5 && abs(x[3*i+1]+0.259310) < 1e-5 && - abs(x[3*i+2]+0.639614) < 1e-5) { - printf("%d %d %f %f %f %d\n",myid,i,x[3*i],x[3*i+1],x[3*i+2],donorid[i]); - } - if (donorid[i]==-1) printf("%d %f %f %f\n",myid,x[3*i],x[3*i+1],x[3*i+2]); - } - //printf("CartGrid::search Processor %d located %d of %d points\n",myid,dcount,npts); + // printf("CartGrid::search Processor %d located %d of %d + // points\n",myid,dcount,npts); } namespace { -template +template inline void create_view(TIOGA::TiogaView tv, T* sptr, int sz) { - tv.sz = sz; - tv.hptr = sptr; - tv.dptr = TIOGA::gpu::push_to_device(tv.hptr, sizeof(T) * sz); + tv.sz = sz; + tv.hptr = sptr; + tv.dptr = TIOGA::gpu::push_to_device(tv.hptr, sizeof(T) * sz); } -} +} // namespace /** Create AMRMeshInfo objects that can be accessed on host and device * @@ -231,33 +234,34 @@ inline void create_view(TIOGA::TiogaView tv, T* sptr, int sz) */ void CartGrid::create_mesh_info() { - assert(proc_id != nullptr); + assert(proc_id != nullptr); - if (m_info == nullptr) m_info = new TIOGA::AMRMeshInfo; - m_info->ngrids_global = ngrids; - m_info->num_ghost = nf; - create_view(m_info->level, level_num, ngrids); - create_view(m_info->mpi_rank, proc_id, ngrids); - create_view(m_info->local_id, local_id, ngrids); - create_view(m_info->ilow, ilo, ngrids * 3); - create_view(m_info->ihigh, ihi, ngrids * 3); - create_view(m_info->dims, dims, ngrids * 3); - create_view(m_info->xlo, xlo, ngrids * 3); - create_view(m_info->dx, dx, ngrids * 3); + if (m_info == nullptr) m_info = new TIOGA::AMRMeshInfo; + m_info->ngrids_global = ngrids; + m_info->num_ghost = nf; + create_view(m_info->level, level_num, ngrids); + create_view(m_info->mpi_rank, proc_id, ngrids); + create_view(m_info->local_id, local_id, ngrids); + create_view(m_info->ilow, ilo, ngrids * 3); + create_view(m_info->ihigh, ihi, ngrids * 3); + create_view(m_info->dims, dims, ngrids * 3); + create_view(m_info->xlo, xlo, ngrids * 3); + create_view(m_info->dx, dx, ngrids * 3); - int iproc = myid; - int nplocal = std::accumulate( - proc_id, proc_id + ngrids, 0, - [iproc](int x, int y) -> int { return x + ((iproc == y) ? 1 : 0); }); + int iproc = myid; + int nplocal = std::accumulate( + proc_id, proc_id + ngrids, 0, + [iproc](int x, int y) -> int { return x + ((iproc == y) ? 1 : 0); }); - m_info->ngrids_local = nplocal; + m_info->ngrids_local = nplocal; - if (m_info_device == nullptr) { - m_info_device = TIOGA::gpu::allocate_on_device( - sizeof(TIOGA::AMRMeshInfo)); - } - TIOGA::gpu::copy_to_device(m_info_device, m_info, sizeof(TIOGA::AMRMeshInfo)); + if (m_info_device == nullptr) { + m_info_device = TIOGA::gpu::allocate_on_device( + sizeof(TIOGA::AMRMeshInfo)); + } + TIOGA::gpu::copy_to_device( + m_info_device, m_info, sizeof(TIOGA::AMRMeshInfo)); - own_data_ptrs = true; - own_amr_mesh_info = true; + own_data_ptrs = true; + own_amr_mesh_info = true; } diff --git a/src/CartGrid.h b/src/CartGrid.h index 5da1369..b8b2f82 100644 --- a/src/CartGrid.h +++ b/src/CartGrid.h @@ -27,46 +27,48 @@ namespace TIOGA { struct AMRMeshInfo; } -class CartGrid { +class CartGrid +{ private: - double xlosup[3]; - double *dxlvl{nullptr}; - int *lcount{nullptr}; - int maxlevel; + double xlosup[3]; + double* dxlvl{nullptr}; + int* lcount{nullptr}; + int maxlevel; - bool own_data_ptrs{true}; - bool own_amr_mesh_info{false}; + bool own_data_ptrs{true}; + bool own_amr_mesh_info{false}; public: - TIOGA::AMRMeshInfo *m_info{nullptr}; - TIOGA::AMRMeshInfo *m_info_device{nullptr}; + TIOGA::AMRMeshInfo* m_info{nullptr}; + TIOGA::AMRMeshInfo* m_info_device{nullptr}; - int *global_id{nullptr}; - int *level_num{nullptr}; - int *proc_id{nullptr}; - int *local_id{nullptr}; - int *ilo{nullptr}; - int *ihi{nullptr}; - int *dims{nullptr}; - int myid{0}; - int nf{0}; - double *xlo{nullptr}; - double *dx{nullptr}; - int ngrids{0}; - void (*donor_frac)(int *, double *, int *, double *) = nullptr; + int* global_id{nullptr}; + int* level_num{nullptr}; + int* proc_id{nullptr}; + int* local_id{nullptr}; + int* ilo{nullptr}; + int* ihi{nullptr}; + int* dims{nullptr}; + int myid{0}; + int nf{0}; + double* xlo{nullptr}; + double* dx{nullptr}; + int ngrids{0}; + void (*donor_frac)(int*, double*, int*, double*) = nullptr; - CartGrid() = default; - ~CartGrid(); + CartGrid() = default; + ~CartGrid(); - void registerData(TIOGA::AMRMeshInfo *m_info); - void registerData(int nf, int *idata, double *rdata, int ngridsin); - void preprocess(void); - void search(double *x, int *donorid, int nsearch); - void setcallback(void (*f1)(int *, double *, int *, double *)) { - donor_frac = f1; - } + void registerData(TIOGA::AMRMeshInfo* m_info); + void registerData(int nf, int* idata, double* rdata, int ngridsin); + void preprocess(void); + void search(double* x, int* donorid, int nsearch); + void setcallback(void (*f1)(int*, double*, int*, double*)) + { + donor_frac = f1; + } - void create_mesh_info(); + void create_mesh_info(); }; #endif /* CARTGRID_H */ diff --git a/src/MeshBlock.C b/src/MeshBlock.C index f6976da..cd43f3f 100644 --- a/src/MeshBlock.C +++ b/src/MeshBlock.C @@ -16,7 +16,7 @@ // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include #include #include "codetypes.h" @@ -27,1717 +27,1696 @@ #include "tioga_math.h" #include "tioga_utils.h" -void MeshBlock::setData(int btag,int nnodesi,double *xyzi, int *ibli,int nwbci, int nobci, - int *wbcnodei,int *obcnodei, - int ntypesi,int *nvi,int *nci,int **vconni, - uint64_t* cell_gid, uint64_t* node_gid) +void MeshBlock::setData( + int btag, + int nnodesi, + double* xyzi, + int* ibli, + int nwbci, + int nobci, + int* wbcnodei, + int* obcnodei, + int ntypesi, + int* nvi, + int* nci, + int** vconni, + uint64_t* cell_gid, + uint64_t* node_gid) { - int i; - // - // set internal pointers - // - meshtag=btag; - nnodes=nnodesi; - x=xyzi; - iblank=ibli; - nwbc=nwbci; - nobc=nobci; - wbcnode=wbcnodei; - obcnode=obcnodei; - // - ntypes=ntypesi; - // - nv=nvi; - nc=nci; - vconn=vconni; - cellGID = cell_gid; - nodeGID = node_gid; - // - //TRACEI(nnodes); - //for(i=0;imeshtag; - nnodes = m_info->num_nodes; - x = m_info->xyz.hptr; - iblank = m_info->iblank_node.hptr; - iblank_cell = m_info->iblank_cell.hptr; - nwbc = m_info->wall_ids.sz; - nobc = m_info->overset_ids.sz; - wbcnode = m_info->wall_ids.hptr; - obcnode = m_info->overset_ids.hptr; - - ntypes = m_info->num_vert_per_elem.sz; - nv = m_info->num_vert_per_elem.hptr; - nc = m_info->num_cells_per_elem.hptr; - - ncells=0; - for(int i=0;ivertex_conn[i].hptr; - } - vconn = &vconn_ptrs[0]; + m_info = minfo; + + // Populate legacy data + meshtag = m_info->meshtag; + nnodes = m_info->num_nodes; + x = m_info->xyz.hptr; + iblank = m_info->iblank_node.hptr; + iblank_cell = m_info->iblank_cell.hptr; + nwbc = m_info->wall_ids.sz; + nobc = m_info->overset_ids.sz; + wbcnode = m_info->wall_ids.hptr; + obcnode = m_info->overset_ids.hptr; + + ntypes = m_info->num_vert_per_elem.sz; + nv = m_info->num_vert_per_elem.hptr; + nc = m_info->num_cells_per_elem.hptr; + + ncells = 0; + for (int i = 0; i < ntypes; i++) ncells += nc[i]; + + for (int i = 0; i < TIOGA::MeshBlockInfo::max_vertex_types; ++i) { + vconn_ptrs[i] = m_info->vertex_conn[i].hptr; + } + vconn = &vconn_ptrs[0]; - cellGID = m_info->cell_gid.hptr; - nodeGID = m_info->node_gid.hptr; + cellGID = m_info->cell_gid.hptr; + nodeGID = m_info->node_gid.hptr; - userSpecifiedNodeRes = m_info->node_res.hptr; - userSpecifiedCellRes = m_info->cell_res.hptr; + userSpecifiedNodeRes = m_info->node_res.hptr; + userSpecifiedCellRes = m_info->cell_res.hptr; - interptype = m_info->qtype; + interptype = m_info->qtype; #ifdef TIOGA_HAS_NODEGID - if (nodeGID == nullptr) - throw std::runtime_error("#tioga: global IDs for nodes not provided"); + if (nodeGID == nullptr) + throw std::runtime_error("#tioga: global IDs for nodes not provided"); #endif - if (m_info_device == nullptr) { - m_info_device = TIOGA::gpu::allocate_on_device( - sizeof(TIOGA::MeshBlockInfo)); - } - TIOGA::gpu::copy_to_device(m_info_device, m_info, sizeof(TIOGA::MeshBlockInfo)); + if (m_info_device == nullptr) { + m_info_device = TIOGA::gpu::allocate_on_device( + sizeof(TIOGA::MeshBlockInfo)); + } + TIOGA::gpu::copy_to_device( + m_info_device, m_info, sizeof(TIOGA::MeshBlockInfo)); } void MeshBlock::preprocess(int use_adaptholemap) { - int i; - // - // set all iblanks = 1 - // - for(i=0;ixc,obb->dxc,obb->vec,nnodes); - if(use_adaptholemap==1) tagBoundaryFaces(); // call before tagBoundary (may convert WBC nodes to OBC) - tagBoundary(); + int i; + // + // set all iblanks = 1 + // + for (i = 0; i < nnodes; i++) iblank[i] = 1; + // + // find oriented bounding boxes + // + if (check_uniform_hex_flag) { + check_for_uniform_hex(); + if (uniform_hex) create_hex_cell_map(); + } + if (obb) TIOGA_FREE(obb); + obb = (OBB*)malloc(sizeof(OBB)); + findOBB(x, obb->xc, obb->dxc, obb->vec, nnodes); + if (use_adaptholemap == 1) + tagBoundaryFaces(); // call before tagBoundary (may convert WBC nodes to + // OBC) + tagBoundary(); } void MeshBlock::tagBoundary(void) { - int i,j,k,n,m,ii; - int itag; - int inode[8]; - double xv[8][3]; - double vol; - int nvert,i3; - FILE *fp; - char intstring[12]; - char fname[80]; - int *iextmp,*iextmp1; - int iex; - // - // do this only once - // i.e. when the meshblock is first - // initialized, cellRes would be NULL in this case - // - - if(cellRes) TIOGA_FREE(cellRes); - if(nodeRes) TIOGA_FREE(nodeRes); - - // - cellRes=(double *) malloc(sizeof(double)*ncells); - nodeRes=(double *) malloc(sizeof(double)*nnodes); - - /* =========================== */ - /* MARK MANDOTORY FRINGE NODES */ - /* =========================== */ - std::vector iflag(nnodes,0); // fill 0 - - // - // this is a local array - // - iextmp=(int *) malloc(sizeof(double)*nnodes); - iextmp1=(int *) malloc(sizeof(double)*nnodes); - // - //printf("%p %p\n",userSpecifiedNodeRes,userSpecifiedCellRes); - //if (myid==2) { - // printf("myid,x=%d %d %f %f %f \n",myid,nodeGID[12058],x[12058*3],x[12058*3+1],x[12058*3+2]); - // TRACED( userSpecifiedNodeRes[12058]); - //} - //if (myid==3) { - // printf("myid,x=%d %d %f %f %f \n",myid,nodeGID[11316],x[11316*3],x[11316*3+1],x[11316*3+2]); - // TRACED(userSpecifiedNodeRes[11316]); - //} - //userSpecifiedNodeRes=NULL; - //userSpecifiedCellRes=NULL; - - // - if(userSpecifiedNodeRes ==NULL && userSpecifiedCellRes ==NULL){ - for(i=0;i iflag(nnodes, 0); // fill 0 + + // + // this is a local array + // + iextmp = (int*)malloc(sizeof(double) * nnodes); + iextmp1 = (int*)malloc(sizeof(double) * nnodes); + // + // printf("%p %p\n",userSpecifiedNodeRes,userSpecifiedCellRes); + // if (myid==2) { + // printf("myid,x=%d %d %f %f %f + // \n",myid,nodeGID[12058],x[12058*3],x[12058*3+1],x[12058*3+2]); TRACED( + // userSpecifiedNodeRes[12058]); + //} + // if (myid==3) { + // printf("myid,x=%d %d %f %f %f + // \n",myid,nodeGID[11316],x[11316*3],x[11316*3+1],x[11316*3+2]); + // TRACED(userSpecifiedNodeRes[11316]); + //} + // userSpecifiedNodeRes=NULL; + // userSpecifiedCellRes=NULL; + + // + if (userSpecifiedNodeRes == NULL && userSpecifiedCellRes == NULL) { + for (i = 0; i < nnodes; i++) nodeRes[i] = 0.0; + + if (!dominanceFlag) { + k = 0; + for (n = 0; n < ntypes; n++) { + nvert = nv[n]; + for (i = 0; i < nc[n]; i++) { + for (m = 0; m < nvert; m++) { + inode[m] = vconn[n][nvert * i + m] - BASE; + i3 = 3 * inode[m]; + for (j = 0; j < 3; j++) xv[m][j] = x[i3 + j]; + } + vol = computeCellVolume(xv, nvert); + cellRes[k++] = (vol * resolutionScale); + for (m = 0; m < nvert; m++) { + iflag[inode[m]]++; + nodeRes[inode[m]] += (vol * resolutionScale); + } + } + } + } else { + // fill dominant composite mesh body cellRes with small number + for (i = 0; i < ncells; i++) cellRes[i] = 0.0; } - } } else { - // fill dominant composite mesh body cellRes with small number - for(i=0;i=BIGVALUE) nmandatory++; + // MPI_Reduce(&nmandatory,&nman_global,1,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD); + // if (myid==0) printf("Total mandatory receptors :%d\n",nman_global); } - } else { - k=0; - for(n=0;ndxc[j] / mapdims[j]; } - for(k=0;k=BIGVALUE) nmandatory++; - //MPI_Reduce(&nmandatory,&nman_global,1,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD); - //if (myid==0) printf("Total mandatory receptors :%d\n",nman_global); - } - - for(int j=0;j<3;j++) - { - mapdims[j]=10; - mapdx[j]=2*obb->dxc[j]/mapdims[j]; + // + // compute nodal resolution as the average of + // all the cells associated with it. This takes care + // of partition boundaries as well. + // + // Also create the inverse map of nodes + // + if (icft) TIOGA_FREE(icft); + icft = + (int*)malloc(sizeof(int) * (mapdims[2] * mapdims[1] * mapdims[0] + 1)); + if (invmap) TIOGA_FREE(invmap); + invmap = (int*)malloc(sizeof(int) * nnodes); + for (int i = 0; i < mapdims[2] * mapdims[1] * mapdims[0] + 1; i++) + icft[i] = -1; + icft[0] = 0; + int* iptr; + iptr = (int*)malloc(sizeof(int) * nnodes); + // + for (i = 0; i < nnodes; i++) { + double xd[3]; + int idx[3]; + if (iflag[i] != 0) nodeRes[i] /= iflag[i]; + iflag[i] = 0; + iextmp[i] = iextmp1[i] = 0; + + for (int j = 0; j < 3; j++) { + xd[j] = obb->dxc[j]; + for (int k = 0; k < 3; k++) + xd[j] += (x[3 * i + k] - obb->xc[k]) * obb->vec[j][k]; + idx[j] = xd[j] / mapdx[j]; + } + int indx = + idx[2] * mapdims[1] * mapdims[0] + idx[1] * mapdims[0] + idx[0]; + iptr[i] = icft[indx + 1]; + icft[indx + 1] = i; } - // - // compute nodal resolution as the average of - // all the cells associated with it. This takes care - // of partition boundaries as well. - // - // Also create the inverse map of nodes - // - if (icft) TIOGA_FREE(icft); - icft=(int *)malloc(sizeof(int)*(mapdims[2]*mapdims[1]*mapdims[0]+1)); - if (invmap) TIOGA_FREE(invmap); - invmap=(int *)malloc(sizeof(int)*nnodes); - for(int i=0;idxc[j]; - for(int k=0;k<3;k++) - xd[j]+=(x[3*i+k]-obb->xc[k])*obb->vec[j][k]; - idx[j]=xd[j]/mapdx[j]; - } - int indx=idx[2]*mapdims[1]*mapdims[0]+idx[1]*mapdims[0]+idx[0]; - iptr[i]=icft[indx+1]; - icft[indx+1]=i; + + int kc = 0; + for (int i = 0; i < mapdims[2] * mapdims[1] * mapdims[0]; i++) { + int ip = icft[i + 1]; + int m = 0; + while (ip != -1) { + invmap[kc++] = ip; + ip = iptr[ip]; + m++; + } + icft[i + 1] = icft[i] + m; } - int kc=0; - for(int i=0;idxc[j]; - for(int k=0;k<3;k++) - xd[j]+=(x[3*inode[m]+k]-obb->xc[k])*obb->vec[j][k]; - xmin[j]=std::min(xd[j],xmin[j]); - xmax[j]=std::max(xd[j],xmax[j]); - } - } - for(int j=0;j<3;j++) { xmin[j]-=TOL; xmax[j]+=TOL;} - for(int j=xmin[0]/mapdx[0];j<=xmax[0]/mapdx[0];j++) - for(int k=xmin[1]/mapdx[1];k<=xmax[1]/mapdx[1];k++) - for(int l=xmin[2]/mapdx[2];l<=xmax[2]/mapdx[2];l++) - { - idx[0]=std::max(std::min(j,mapdims[0]-1),0); - idx[1]=std::max(std::min(k,mapdims[1]-1),0); - idx[2]=std::max(std::min(l,mapdims[2]-1),0); - mapmask[idx[2]*mapdims[1]*mapdims[0]+idx[1]*mapdims[0]+idx[0]]=1; + // + // now tag all the nodes of boundary cells + // to be mandatory receptors + // also make the inverse map mask + if (mapmask) TIOGA_FREE(mapmask); + mapmask = (int*)malloc(sizeof(int) * mapdims[2] * mapdims[1] * mapdims[0]); + for (int i = 0; i < mapdims[2] * mapdims[1] * mapdims[0]; i++) + mapmask[i] = 0; + for (n = 0; n < ntypes; n++) { + nvert = nv[n]; + for (i = 0; i < nc[n]; i++) { + double xd[3], xc[3], xmin[3], xmax[3]; + int idx[3]; + itag = 0; + for (int j = 0; j < 3; j++) { + xmin[j] = BIGVALUE; + xmax[j] = -BIGVALUE; + } + for (m = 0; m < nvert; m++) { + inode[m] = vconn[n][nvert * i + m] - BASE; + if (iflag[inode[m]]) itag = 1; + for (int j = 0; j < 3; j++) { + xd[j] = obb->dxc[j]; + for (int k = 0; k < 3; k++) + xd[j] += + (x[3 * inode[m] + k] - obb->xc[k]) * obb->vec[j][k]; + xmin[j] = std::min(xd[j], xmin[j]); + xmax[j] = std::max(xd[j], xmax[j]); } - if (itag) - { - for(m=0;m iflagwbc(nnodes,0); - std::vector iflagobc(nnodes,0); - std::vector iflagduplicates(nnodes,0); - - // input=[cell type]: [0] tetrahedron, [1] pyramid, [2] prism, [3] hexahedron - const int nfaces[4] = {4,5,5,6}; - - // numfaceverts[cell type][face id]: number of vertices on each face - const int numfaceverts[4][6]={3,3,3,3,0,0, // tetrahedron - 4,3,3,3,3,0, // pyramid - 3,4,4,4,3,0, // prism - 4,4,4,4,4,4};// hexahedron - - // faceInfo[cell type][face id][vertices]: vertex id for each face (NOTE: BASE 1) - const int faceInfo[4][6][4]={1,2,3,0,1,4,2,0,2,4,3,0,1,3,4,0,0,0,0,0,0,0,0,0, // tetrahedron - 1,2,3,4,1,5,2,0,2,5,3,0,4,3,5,0,1,4,5,0,0,0,0,0, // pyramid - 1,2,3,0,1,4,5,2,2,5,6,3,1,3,6,4,4,6,5,0,0,0,0,0, // prism - 1,2,3,4,1,5,6,2,2,6,7,3,3,7,8,4,1,4,8,5,5,8,7,6};// hexahedron - - const int celltypes[9]={-1,-1,-1,-1, // input=[#vertices] - 0, 1, 2,-1, 3}; // [4]: type=0, tetrahedron - // [5]: type=1, pyramid - // [6]: type=2, prism - // [8]: type=3, hexahedron - - /* ====================================== */ - /* 1. SEARCH DUPLICATE WBC/OBC NODES: */ - /* find duplicate nodes and turn off */ - /* near-by neighbor wbc and set to obc */ - /* ====================================== */ - // tag BC nodes - for(i=0;i iflagwbc(nnodes, 0); + std::vector iflagobc(nnodes, 0); + std::vector iflagduplicates(nnodes, 0); + + // input=[cell type]: [0] tetrahedron, [1] pyramid, [2] prism, [3] + // hexahedron + const int nfaces[4] = {4, 5, 5, 6}; + + // numfaceverts[cell type][face id]: number of vertices on each face + const int numfaceverts[4][6] = {3, 3, 3, 3, 0, 0, // tetrahedron + 4, 3, 3, 3, 3, 0, // pyramid + 3, 4, 4, 4, 3, 0, // prism + 4, 4, 4, 4, 4, 4}; // hexahedron + + // faceInfo[cell type][face id][vertices]: vertex id for each face (NOTE: + // BASE 1) + const int faceInfo[4][6][4] = { + 1, 2, 3, 0, 1, 4, 2, 0, 2, 4, 3, 0, + 1, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, // tetrahedron + 1, 2, 3, 4, 1, 5, 2, 0, 2, 5, 3, 0, + 4, 3, 5, 0, 1, 4, 5, 0, 0, 0, 0, 0, // pyramid + 1, 2, 3, 0, 1, 4, 5, 2, 2, 5, 6, 3, + 1, 3, 6, 4, 4, 6, 5, 0, 0, 0, 0, 0, // prism + 1, 2, 3, 4, 1, 5, 6, 2, 2, 6, 7, 3, + 3, 7, 8, 4, 1, 4, 8, 5, 5, 8, 7, 6}; // hexahedron + + const int celltypes[9] = {-1, -1, -1, -1, // input=[#vertices] + 0, 1, 2, -1, 3}; // [4]: type=0, tetrahedron + // [5]: type=1, pyramid + // [6]: type=2, prism + // [8]: type=3, hexahedron + + /* ====================================== */ + /* 1. SEARCH DUPLICATE WBC/OBC NODES: */ + /* find duplicate nodes and turn off */ + /* near-by neighbor wbc and set to obc */ + /* ====================================== */ + // tag BC nodes + for (i = 0; i < nwbc; i++) iflagwbc[wbcnode[i] - BASE] = 1; + for (i = 0; i < nobc; i++) iflagobc[obcnode[i] - BASE] = 1; #ifdef NON_UNIQUE_NODES - // 1. make WBC hash set and track duplicate WBC nodes - std::unordered_set WBC_nodes; - std::vector WBC_unique_map(nwbc); - char wbc_nonunique_flag = 0; - - for(i=0;i WBC_nodes; + std::vector WBC_unique_map(nwbc); + char wbc_nonunique_flag = 0; + + for (i = 0; i < nwbc; i++) { + int nodei = wbcnode[i] - BASE; + WBC_unique_map[i] = nodei; + + auto node_found = WBC_nodes.insert(Node(nodei, &x[3 * nodei])); + if (node_found.second == false) { + // duplicates exist + const Node n = *node_found.first; + WBC_unique_map[i] = n.id; + wbc_nonunique_flag = 1; + } } - } - - // 2. check for WBC/OBC duplicates - flagduplicate = 0; - for(i=0;iid] = 1; - iflagwbc[nodei] = 0; // turn off wbc node - iflagobc[nodei] = 1; // turn on obc node - flagduplicate = 1; + + // 2. check for WBC/OBC duplicates + flagduplicate = 0; + for (i = 0; i < nobc; i++) { + int nodei = obcnode[i] - BASE; + auto node_found = WBC_nodes.find(Node(nodei, &x[3 * nodei])); + + if (node_found != WBC_nodes.end()) { + // duplicates exit + iflagduplicates[nodei] = iflagduplicates[node_found->id] = 1; + iflagwbc[nodei] = 0; // turn off wbc node + iflagobc[nodei] = 1; // turn on obc node + flagduplicate = 1; + } } - } - - // 3. loop WBC unique map and set WBC duplicate flags - if(wbc_nonunique_flag){ - for(i=0;i iflag(ncells,0); // fill 0 - std::vector inode(nnodes,0); // fill 0 - // - /// - //sprintf(intstring,"%d",100000+myid); - //sprintf(fname,"wbc%s.dat",&(intstring[1])); - //fp=fopen(fname,"w"); - // - for(i=0;i iflag(ncells, 0); // fill 0 + std::vector inode(nnodes, 0); // fill 0 + // + /// + // sprintf(intstring,"%d",100000+myid); + // sprintf(fname,"wbc%s.dat",&(intstring[1])); + // fp=fopen(fname,"w"); + // + for (i = 0; i < nwbc; i++) { + ii = wbcnode[i] - BASE; + // fprintf(fp,"%e %e %e\n",x[3*ii],x[3*ii+1],x[3*ii+2]); + inode[ii] = 1; + } + // fclose(fp); + // + // mark wall boundary cells + // + m = 0; + for (n = 0; n < ntypes; n++) { + nvert = nv[n]; + for (i = 0; i < nc[n]; i++) { + for (j = 0; j < nvert; j++) { + ii = vconn[n][nvert * i + j] - BASE; + if (inode[ii] == 1) { + iflag[m] = 1; + break; + } + } + m++; + } + } + // + // find delta's in each directions + // + for (k = 0; k < 3; k++) ds[k] = (extents[k + 3] - extents[k]) / nx[k]; + // + // mark sam cells with wall boundary cells now + // + m = 0; + for (n = 0; n < ntypes; n++) { + nvert = nv[n]; + for (i = 0; i < nc[n]; i++) { + if (iflag[m] == 1) { + // + // find the index bounds of each wall boundary cell + // bounding box + // + imin[0] = imin[1] = imin[2] = BIGINT; + imax[0] = imax[1] = imax[2] = -BIGINT; + for (j = 0; j < nvert; j++) { + i3 = 3 * (vconn[n][nvert * i + j] - BASE); + for (k = 0; k < 3; k++) { + xv = x[i3 + k]; + iv = floor((xv - extents[k]) / ds[k]); + imin[k] = std::min(imin[k], iv); + imax[k] = std::max(imax[k], iv); + } + } + for (j = 0; j < 3; j++) { + imin[j] = std::max(imin[j], 0); + imax[j] = std::min(imax[j], nx[j] - 1); + } + // + // mark sam to 1 + // + for (kk = imin[2]; kk < imax[2] + 1; kk++) + for (jj = imin[1]; jj < imax[1] + 1; jj++) + for (ii = imin[0]; ii < imax[0] + 1; ii++) { + mm = kk * nx[1] * nx[0] + jj * nx[0] + ii; + sam[mm] = 2; + } + } + m++; + } } - // - // find delta's in each directions - // - for(k=0;k<3;k++) ds[k]=(extents[k+3]-extents[k])/nx[k]; - // - // mark sam cells with wall boundary cells now - // - m=0; - for(n=0;n 0){ - MPI_Recv(&rbuffer,1,MPI_INT,blockcomm_id-1,0,blockcomm,MPI_STATUSES_IGNORE); + if (blockcomm_id > 0) { + MPI_Recv( + &rbuffer, 1, MPI_INT, blockcomm_id - 1, 0, blockcomm, + MPI_STATUSES_IGNORE); } fp = fopen(filename, "a"); // loop all boundary nodes and tag octants - for(i=0; ielem_count; - const qcoord_t levelh = OCTANT_LEN(level->level_id); // integer length of octant - - // set node type data - int nbc = (nodetype2tag == WALLNODETYPE) ? nwbc:nobc; - int *bcnode = (nodetype2tag == WALLNODETYPE) ? wbcnode:obcnode; - - // octree physical lengths - ds[0] = extents_hi[0] - extents_lo[0]; - ds[1] = extents_hi[1] - extents_lo[1]; - ds[2] = extents_hi[2] - extents_lo[2]; - - // rescale ds: embed integer to double conversion - ds[0] *= INT2DBL; - ds[1] *= INT2DBL; - ds[2] *= INT2DBL; - - // octant physical length - dx[0] = ds[0]*levelh; - dx[1] = ds[1]*levelh; - dx[2] = ds[2]*levelh; - - // loop all boundary nodes and tag octants - for(i=0; ioctants[j]; - - /* check intersection */ - // x octant bounds - xlo = extents_lo[0] + ds[0]*oct.x; - xhi = xlo + dx[0]; - if(xlo <= xc && xc <= xhi){ - - // y octant bounds - ylo = extents_lo[1] + ds[1]*oct.y; - yhi = ylo + dx[1]; - if(ylo <= yc && yc <= yhi){ - - // z octant bounds - zlo = extents_lo[2] + ds[2]*oct.z; - zhi = zlo + dx[2]; - if(zlo <= zc && zc <= zhi){ - tagList[j] = 1; - break; // skip remaining octants for this point (uniqueness on level) - } +void MeshBlock::markBoundaryAdaptiveMap( + char nodetype2tag, + double extents_lo[3], + double extents_hi[3], + level_octant_t* level, + uint8_t* taggedList, + uint8_t* tagList) +{ + int i, j; + int ii; + int i3; + + double xc, yc, zc; + double xlo, ylo, zlo; + double xhi, yhi, zhi; + double ds[3], dx[3]; + + const uint32_t noctants = level->elem_count; + const qcoord_t levelh = + OCTANT_LEN(level->level_id); // integer length of octant + + // set node type data + int nbc = (nodetype2tag == WALLNODETYPE) ? nwbc : nobc; + int* bcnode = (nodetype2tag == WALLNODETYPE) ? wbcnode : obcnode; + + // octree physical lengths + ds[0] = extents_hi[0] - extents_lo[0]; + ds[1] = extents_hi[1] - extents_lo[1]; + ds[2] = extents_hi[2] - extents_lo[2]; + + // rescale ds: embed integer to double conversion + ds[0] *= INT2DBL; + ds[1] *= INT2DBL; + ds[2] *= INT2DBL; + + // octant physical length + dx[0] = ds[0] * levelh; + dx[1] = ds[1] * levelh; + dx[2] = ds[2] * levelh; + + // loop all boundary nodes and tag octants + for (i = 0; i < nbc; i++) { + ii = bcnode[i] - BASE; + i3 = 3 * ii; + + // boundary point coordinates + xc = x[i3 + 0]; + yc = x[i3 + 1]; + zc = x[i3 + 2]; + + // mark octant containing point + for (j = 0; j < noctants; j++) { + // check if tagged already OR + // if taggedList provided, then octant must also be tagged in other + // list + if (tagList[j] || (taggedList && taggedList[j] == 0)) continue; + + octant_full_t& oct = level->octants[j]; + + /* check intersection */ + // x octant bounds + xlo = extents_lo[0] + ds[0] * oct.x; + xhi = xlo + dx[0]; + if (xlo <= xc && xc <= xhi) { + + // y octant bounds + ylo = extents_lo[1] + ds[1] * oct.y; + yhi = ylo + dx[1]; + if (ylo <= yc && yc <= yhi) { + + // z octant bounds + zlo = extents_lo[2] + ds[2] * oct.z; + zhi = zlo + dx[2]; + if (zlo <= zc && zc <= zhi) { + tagList[j] = 1; + break; // skip remaining octants for this point + // (uniqueness on level) + } + } + } } - } } - } } -void MeshBlock::markBoundaryAdaptiveMapSurfaceIntersect(char nodetype2tag, - double extents_lo[3], - double extents_hi[3], - level_octant_t *level, - uint8_t *taggedList, - uint8_t *tagList){ - int *inode; - int nvert; - int i,j; - int d; - - double boxcenter[3]; - double ds[3],dx[3],halfdx[3]; - double xlo[3]; - box_t box2; - - const uint32_t noctants = level->elem_count; - const qcoord_t levelh = OCTANT_LEN(level->level_id); // integer length of octant - - // set node type data - int nbcface = (nodetype2tag == WALLNODETYPE) ? nwbcface:nobcface; - std::vector &bcfacenode = (nodetype2tag == WALLNODETYPE) ? wbcfacenode:obcfacenode; - std::vector &bcfacebox = (nodetype2tag == WALLNODETYPE) ? wbcfacebox:obcfacebox; - - // octree physical lengths - ds[0] = extents_hi[0] - extents_lo[0]; - ds[1] = extents_hi[1] - extents_lo[1]; - ds[2] = extents_hi[2] - extents_lo[2]; - - // rescale ds: embed integer to double conversion - ds[0] *= INT2DBL; - ds[1] *= INT2DBL; - ds[2] *= INT2DBL; - - // octant physical length - dx[0] = ds[0]*levelh; - dx[1] = ds[1]*levelh; - dx[2] = ds[2]*levelh; - - halfdx[0] = 0.5*dx[0]; - halfdx[1] = 0.5*dx[1]; - halfdx[2] = 0.5*dx[2]; - - // mark octant intersecting boundary face - for(j=0; joctants[j]; - - // octant bounds: x - xlo[0] = extents_lo[0] + ds[0]*oct.x; - xlo[1] = extents_lo[1] + ds[1]*oct.y; - xlo[2] = extents_lo[2] + ds[2]*oct.z; - - box2.x.lo = xlo[0]; box2.x.hi = xlo[0] + dx[0]; - box2.y.lo = xlo[1]; box2.y.hi = xlo[1] + dx[1]; - box2.z.lo = xlo[2]; box2.z.hi = xlo[2] + dx[2]; - - // possible overlap: use face intersection test - for(d=0; d<3; d++) boxcenter[d] = xlo[d] + halfdx[d]; - - // loop all boundary faces - for(i=0; ielem_count; + const qcoord_t levelh = + OCTANT_LEN(level->level_id); // integer length of octant + + // set node type data + int nbcface = (nodetype2tag == WALLNODETYPE) ? nwbcface : nobcface; + std::vector& bcfacenode = + (nodetype2tag == WALLNODETYPE) ? wbcfacenode : obcfacenode; + std::vector& bcfacebox = + (nodetype2tag == WALLNODETYPE) ? wbcfacebox : obcfacebox; + + // octree physical lengths + ds[0] = extents_hi[0] - extents_lo[0]; + ds[1] = extents_hi[1] - extents_lo[1]; + ds[2] = extents_hi[2] - extents_lo[2]; + + // rescale ds: embed integer to double conversion + ds[0] *= INT2DBL; + ds[1] *= INT2DBL; + ds[2] *= INT2DBL; + + // octant physical length + dx[0] = ds[0] * levelh; + dx[1] = ds[1] * levelh; + dx[2] = ds[2] * levelh; + + halfdx[0] = 0.5 * dx[0]; + halfdx[1] = 0.5 * dx[1]; + halfdx[2] = 0.5 * dx[2]; + + // mark octant intersecting boundary face + for (j = 0; j < noctants; j++) { + // check if tagged already OR + // if taggedList provided, then octant must also be tagged in other list + if (tagList[j] || (taggedList && taggedList[j] == 0)) continue; + + // get octant since it hasn't been tagged + octant_full_t& oct = level->octants[j]; + + // octant bounds: x + xlo[0] = extents_lo[0] + ds[0] * oct.x; + xlo[1] = extents_lo[1] + ds[1] * oct.y; + xlo[2] = extents_lo[2] + ds[2] * oct.z; + + box2.x.lo = xlo[0]; + box2.x.hi = xlo[0] + dx[0]; + box2.y.lo = xlo[1]; + box2.y.hi = xlo[1] + dx[1]; + box2.z.lo = xlo[2]; + box2.z.hi = xlo[2] + dx[2]; + + // possible overlap: use face intersection test + for (d = 0; d < 3; d++) boxcenter[d] = xlo[d] + halfdx[d]; + + // loop all boundary faces + for (i = 0; i < nbcface; i++) { + + // box of face + box_t& box1 = bcfacebox[i]; + + // test bounds of octant + if (overlapping1D(box1.x, box2.x) && + overlapping1D(box1.y, box2.y) && + overlapping1D(box1.z, box2.z)) { + /* possible overlap: use face intersection test */ + + // load face boundary nodes: set pointer to nodes + inode = &bcfacenode[4 * i]; // last node may be -1 + + // get node indices and coordinates for this boundary face + // load 1st three nodes + double* pt1 = &x[3 * inode[0]]; + double* pt2 = &x[3 * inode[1]]; + double* pt3 = &x[3 * inode[2]]; + + // test triangle 1: pass first 3 triangles + if (triBoxOverlap(boxcenter, halfdx, pt1, pt2, pt3)) { + tagList[j] = 1; + break; // jump to next octant (break from inner BC loop) + } - // if quad, test second triangle using last node - nvert = (inode[3] == -1) ? 3:4; // number of face vertices - if(nvert == 4){ - double *pt4 = &x[3*inode[3]]; - if(triBoxOverlap(boxcenter,halfdx,pt1,pt2,pt4)){ - tagList[j] = 1; - break; // jump to next octant (break from inner BC loop) - } + // if quad, test second triangle using last node + nvert = (inode[3] == -1) ? 3 : 4; // number of face vertices + if (nvert == 4) { + double* pt4 = &x[3 * inode[3]]; + if (triBoxOverlap(boxcenter, halfdx, pt1, pt2, pt4)) { + tagList[j] = 1; + break; // jump to next octant (break from inner BC loop) + } + } + } } - } } - } } -void MeshBlock::markBoundaryAdaptiveMapSurfaceIntersect(char nodetype2tag, - double extents_lo[3], - double extents_hi[3], - uint8_t level_id, - uint32_t noctants, - octant_coordinates_t *octants, - uint8_t *taggedList, - uint8_t *tagList){ - int *inode; - int nvert; - int i,j; - int d; - - double boxcenter[3]; - double ds[3],dx[3],halfdx[3]; - double xlo[3]; - box_t box2; - - const qcoord_t levelh = OCTANT_LEN(level_id); // integer length of octant - - // set node type data - int nbcface = (nodetype2tag == WALLNODETYPE) ? nwbcface:nobcface; - std::vector &bcfacenode = (nodetype2tag == WALLNODETYPE) ? wbcfacenode:obcfacenode; - std::vector &bcfacebox = (nodetype2tag == WALLNODETYPE) ? wbcfacebox:obcfacebox; - - // octree physical lengths - ds[0] = extents_hi[0] - extents_lo[0]; - ds[1] = extents_hi[1] - extents_lo[1]; - ds[2] = extents_hi[2] - extents_lo[2]; - - // rescale ds: embed integer to double conversion - ds[0] *= INT2DBL; - ds[1] *= INT2DBL; - ds[2] *= INT2DBL; - - // octant physical length - dx[0] = ds[0]*levelh; - dx[1] = ds[1]*levelh; - dx[2] = ds[2]*levelh; - - halfdx[0] = 0.5*dx[0]; - halfdx[1] = 0.5*dx[1]; - halfdx[2] = 0.5*dx[2]; - - // mark octant intersecting boundary face - for(j=0; j& bcfacenode = + (nodetype2tag == WALLNODETYPE) ? wbcfacenode : obcfacenode; + std::vector& bcfacebox = + (nodetype2tag == WALLNODETYPE) ? wbcfacebox : obcfacebox; + + // octree physical lengths + ds[0] = extents_hi[0] - extents_lo[0]; + ds[1] = extents_hi[1] - extents_lo[1]; + ds[2] = extents_hi[2] - extents_lo[2]; + + // rescale ds: embed integer to double conversion + ds[0] *= INT2DBL; + ds[1] *= INT2DBL; + ds[2] *= INT2DBL; + + // octant physical length + dx[0] = ds[0] * levelh; + dx[1] = ds[1] * levelh; + dx[2] = ds[2] * levelh; + + halfdx[0] = 0.5 * dx[0]; + halfdx[1] = 0.5 * dx[1]; + halfdx[2] = 0.5 * dx[2]; + + // mark octant intersecting boundary face + for (j = 0; j < noctants; j++) { + // check if tagged already OR + // if taggedList provided, then octant must also be tagged in other list + if (tagList[j] || (taggedList && taggedList[j] == 0)) continue; + + // get octant since it hasn't been tagged + octant_coordinates_t& oct = octants[j]; + + // octant bounds: x + xlo[0] = extents_lo[0] + ds[0] * oct.x; + xlo[1] = extents_lo[1] + ds[1] * oct.y; + xlo[2] = extents_lo[2] + ds[2] * oct.z; + + box2.x.lo = xlo[0]; + box2.x.hi = xlo[0] + dx[0]; + box2.y.lo = xlo[1]; + box2.y.hi = xlo[1] + dx[1]; + box2.z.lo = xlo[2]; + box2.z.hi = xlo[2] + dx[2]; + + // possible overlap: use face intersection test + for (d = 0; d < 3; d++) boxcenter[d] = xlo[d] + halfdx[d]; + + // loop all boundary faces + for (i = 0; i < nbcface; i++) { + + // box of face + box_t& box1 = bcfacebox[i]; + + // test bounds of octant + if (overlapping1D(box1.x, box2.x) && + overlapping1D(box1.y, box2.y) && + overlapping1D(box1.z, box2.z)) { + /* possible overlap: use face intersection test */ + + // load face boundary nodes: set pointer to nodes + inode = &bcfacenode[4 * i]; // last node may be -1 + + // get node indices and coordinates for this boundary face + // load 1st three nodes + double* pt1 = &x[3 * inode[0]]; + double* pt2 = &x[3 * inode[1]]; + double* pt3 = &x[3 * inode[2]]; + + // test triangle 1: pass first 3 triangles + if (triBoxOverlap(boxcenter, halfdx, pt1, pt2, pt3)) { + tagList[j] = 1; + break; // jump to next octant (break from inner BC loop) + } - // if quad, test second triangle using last node - nvert = (inode[3] == -1) ? 3:4; // number of face vertices - if(nvert == 4){ - double *pt4 = &x[3*inode[3]]; - if(triBoxOverlap(boxcenter,halfdx,pt1,pt2,pt4)){ - tagList[j] = 1; - break; // jump to next octant (break from inner BC loop) - } + // if quad, test second triangle using last node + nvert = (inode[3] == -1) ? 3 : 4; // number of face vertices + if (nvert == 4) { + double* pt4 = &x[3 * inode[3]]; + if (triBoxOverlap(boxcenter, halfdx, pt1, pt2, pt4)) { + tagList[j] = 1; + break; // jump to next octant (break from inner BC loop) + } + } + } } - } } - } } -void MeshBlock::markBoundaryMapSurface(char nodetype2tag, - double extents_lo[3], - double extents_hi[3], - level_octant_t *level, - uint8_t *taggedList, - uint8_t *tagList){ -#if (INTERSECT_ALG==1) - markBoundaryAdaptiveMapSurfaceIntersect(nodetype2tag, - extents_lo,extents_hi, - level,taggedList,tagList); +void MeshBlock::markBoundaryMapSurface( + char nodetype2tag, + double extents_lo[3], + double extents_hi[3], + level_octant_t* level, + uint8_t* taggedList, + uint8_t* tagList) +{ +#if (INTERSECT_ALG == 1) + markBoundaryAdaptiveMapSurfaceIntersect( + nodetype2tag, extents_lo, extents_hi, level, taggedList, tagList); #else - markBoundaryAdaptiveMap(nodetype2tag, - extents_lo,extents_hi, - level,taggedList,tagList); + markBoundaryAdaptiveMap( + nodetype2tag, extents_lo, extents_hi, level, taggedList, tagList); #endif } -void MeshBlock::getReducedOBB(OBB *obc,double *realData) +void MeshBlock::getReducedOBB(OBB* obc, double* realData) { - int i,j,k,m,n,i3; - int nvert; - bool iflag; - double bbox[6],xd[3]; - /* - for(j=0;j<3;j++) - { - realData[j]=obb->xc[j]; - realData[j+3]=obb->dxc[j]; - } - return; - */ - for(j=0;j<3;j++) - { - realData[j]=BIGVALUE; - realData[j+3]=-BIGVALUE; + int i, j, k, m, n, i3; + int nvert; + bool iflag; + double bbox[6], xd[3]; + /* + for(j=0;j<3;j++) + { + realData[j]=obb->xc[j]; + realData[j+3]=obb->dxc[j]; + } + return; + */ + for (j = 0; j < 3; j++) { + realData[j] = BIGVALUE; + realData[j + 3] = -BIGVALUE; } - for(n=0;nxc[k])*obc->vec[j][k]; - for(j=0;j<3;j++) bbox[j]=std::min(bbox[j],xd[j]); - for(j=0;j<3;j++) bbox[j+3]=std::max(bbox[j+3],xd[j]); - } - iflag=0; - for(j=0;j<3;j++) iflag=(iflag || (bbox[j] > obc->dxc[j])); - if (iflag) continue; - iflag=0; - for(j=0;j<3;j++) iflag=(iflag || (bbox[j+3] < -obc->dxc[j])); - if (iflag) continue; - for (m=0;mxc[k])*obb->vec[j][k]; - for(j=0;j<3;j++) realData[j]=std::min(realData[j],xd[j]); - for(j=0;j<3;j++) realData[j+3]=std::max(realData[j+3],xd[j]); - } - } + for (n = 0; n < ntypes; n++) { + nvert = nv[n]; + for (i = 0; i < nc[n]; i++) { + bbox[0] = bbox[1] = bbox[2] = BIGVALUE; + bbox[3] = bbox[4] = bbox[5] = -BIGVALUE; + + for (m = 0; m < nvert; m++) { + i3 = 3 * (vconn[n][nvert * i + m] - BASE); + for (j = 0; j < 3; j++) xd[j] = 0; + for (j = 0; j < 3; j++) + for (k = 0; k < 3; k++) + xd[j] += (x[i3 + k] - obc->xc[k]) * obc->vec[j][k]; + for (j = 0; j < 3; j++) bbox[j] = std::min(bbox[j], xd[j]); + for (j = 0; j < 3; j++) + bbox[j + 3] = std::max(bbox[j + 3], xd[j]); + } + iflag = 0; + for (j = 0; j < 3; j++) iflag = (iflag || (bbox[j] > obc->dxc[j])); + if (iflag) continue; + iflag = 0; + for (j = 0; j < 3; j++) + iflag = (iflag || (bbox[j + 3] < -obc->dxc[j])); + if (iflag) continue; + for (m = 0; m < nvert; m++) { + i3 = 3 * (vconn[n][nvert * i + m] - BASE); + for (j = 0; j < 3; j++) xd[j] = 0; + for (j = 0; j < 3; j++) + for (k = 0; k < 3; k++) + xd[j] += (x[i3 + k] - obb->xc[k]) * obb->vec[j][k]; + for (j = 0; j < 3; j++) + realData[j] = std::min(realData[j], xd[j]); + for (j = 0; j < 3; j++) + realData[j + 3] = std::max(realData[j + 3], xd[j]); + } + } } - for(j=0;j<6;j++) bbox[j]=realData[j]; - for(j=0;j<3;j++) - { - realData[j]=obb->xc[j]; - for(k=0;k<3;k++) - realData[j]+=((bbox[k]+bbox[k+3])*0.5)*obb->vec[k][j]; - realData[j+3]=(bbox[j+3]-bbox[j])*0.51; + for (j = 0; j < 6; j++) bbox[j] = realData[j]; + for (j = 0; j < 3; j++) { + realData[j] = obb->xc[j]; + for (k = 0; k < 3; k++) + realData[j] += ((bbox[k] + bbox[k + 3]) * 0.5) * obb->vec[k][j]; + realData[j + 3] = (bbox[j + 3] - bbox[j]) * 0.51; } - return; + return; } - -void MeshBlock::getReducedOBB2(OBB *obc,double *realData) +void MeshBlock::getReducedOBB2(OBB* obc, double* realData) { - int i,j,k,l,m,n,i3,jmin,kmin,lmin,jmax,kmax,lmax,indx; - double bbox[6],xd[3]; - double xmin[3],xmax[3],xv[8][3]; - double delta; - int imin[3],imax[3]; - - getobbcoords(obc->xc,obc->dxc,obc->vec,xv); - for(j=0;j<3;j++) {xmin[j]=BIGVALUE;xmax[j]=-BIGVALUE;}; - for(n=0;n<8;n++) - { - transform2OBB(xv[n],obb->xc,obb->vec,xd); - for(j=0;j<3;j++) - { - xmin[j]=std::min(xmin[j],xd[j]+obb->dxc[j]); - xmax[j]=std::max(xmax[j],xd[j]+obb->dxc[j]); + int i, j, k, l, m, n, i3, jmin, kmin, lmin, jmax, kmax, lmax, indx; + double bbox[6], xd[3]; + double xmin[3], xmax[3], xv[8][3]; + double delta; + int imin[3], imax[3]; + + getobbcoords(obc->xc, obc->dxc, obc->vec, xv); + for (j = 0; j < 3; j++) { + xmin[j] = BIGVALUE; + xmax[j] = -BIGVALUE; + }; + for (n = 0; n < 8; n++) { + transform2OBB(xv[n], obb->xc, obb->vec, xd); + for (j = 0; j < 3; j++) { + xmin[j] = std::min(xmin[j], xd[j] + obb->dxc[j]); + xmax[j] = std::max(xmax[j], xd[j] + obb->dxc[j]); } } - for(j=0;j<3;j++) - { - delta=0.01*(xmax[j]-xmin[j]); - xmin[j]-=delta; - xmax[j]+=delta; - imin[j]=std::max(xmin[j]/mapdx[j],0.0); - imax[j]=std::min(xmax[j]/mapdx[j],static_cast(mapdims[j]-1)); + for (j = 0; j < 3; j++) { + delta = 0.01 * (xmax[j] - xmin[j]); + xmin[j] -= delta; + xmax[j] += delta; + imin[j] = std::max(xmin[j] / mapdx[j], 0.0); + imax[j] = + std::min(xmax[j] / mapdx[j], static_cast(mapdims[j] - 1)); } - lmin=mapdims[2]-1; - kmin=mapdims[1]-1; - jmin=mapdims[0]-1; - lmax=kmax=jmax=0; - for(l=imin[2];l<=imax[2];l++) - for(k=imin[1];k<=imax[1];k++) - for(j=imin[0];j<=imax[0];j++) - { - indx=l*mapdims[1]*mapdims[0]+k*mapdims[0]+j; - if (mapmask[indx]) { - lmin=std::min(lmin,l); - kmin=std::min(kmin,k); - jmin=std::min(jmin,j); - lmax=std::max(lmax,l); - kmax=std::max(kmax,k); - jmax=std::max(jmax,j); - } - } - bbox[0]=-obb->dxc[0]+jmin*mapdx[0]; - bbox[1]=-obb->dxc[1]+kmin*mapdx[1]; - bbox[2]=-obb->dxc[2]+lmin*mapdx[2]; - bbox[3]=-obb->dxc[0]+(jmax+1)*mapdx[0]; - bbox[4]=-obb->dxc[1]+(kmax+1)*mapdx[1]; - bbox[5]=-obb->dxc[2]+(lmax+1)*mapdx[2]; - for(j=0;j<3;j++) - { - realData[j]=obb->xc[j]; - for(k=0;k<3;k++) - realData[j]+=((bbox[k]+bbox[k+3])*0.5)*obb->vec[k][j]; - realData[j+3]=(bbox[j+3]-bbox[j])*0.5; + lmin = mapdims[2] - 1; + kmin = mapdims[1] - 1; + jmin = mapdims[0] - 1; + lmax = kmax = jmax = 0; + for (l = imin[2]; l <= imax[2]; l++) + for (k = imin[1]; k <= imax[1]; k++) + for (j = imin[0]; j <= imax[0]; j++) { + indx = l * mapdims[1] * mapdims[0] + k * mapdims[0] + j; + if (mapmask[indx]) { + lmin = std::min(lmin, l); + kmin = std::min(kmin, k); + jmin = std::min(jmin, j); + lmax = std::max(lmax, l); + kmax = std::max(kmax, k); + jmax = std::max(jmax, j); + } + } + bbox[0] = -obb->dxc[0] + jmin * mapdx[0]; + bbox[1] = -obb->dxc[1] + kmin * mapdx[1]; + bbox[2] = -obb->dxc[2] + lmin * mapdx[2]; + bbox[3] = -obb->dxc[0] + (jmax + 1) * mapdx[0]; + bbox[4] = -obb->dxc[1] + (kmax + 1) * mapdx[1]; + bbox[5] = -obb->dxc[2] + (lmax + 1) * mapdx[2]; + for (j = 0; j < 3; j++) { + realData[j] = obb->xc[j]; + for (k = 0; k < 3; k++) + realData[j] += ((bbox[k] + bbox[k + 3]) * 0.5) * obb->vec[k][j]; + realData[j + 3] = (bbox[j + 3] - bbox[j]) * 0.5; } - return; + return; } - - -void MeshBlock::getQueryPoints(OBB *obc, - int *nints,int **intData, - int *nreals, double **realData) +void MeshBlock::getQueryPoints( + OBB* obc, int* nints, int** intData, int* nreals, double** realData) { - int i,j,k; - int i3; - double xd[3]; - int *inode; - int iptr; - int m; - - inode=(int *)malloc(sizeof(int)*nnodes); - *nints=*nreals=0; - for(i=0;ixc[k])*obc->vec[j][k]; - - if (fabs(xd[0]) <= obc->dxc[0] && - fabs(xd[1]) <= obc->dxc[1] && - fabs(xd[2]) <= obc->dxc[2]) - { - inode[*nints]=i; - (*nints)++; - (*nreals)+=4; - + int i, j, k; + int i3; + double xd[3]; + int* inode; + int iptr; + int m; + + inode = (int*)malloc(sizeof(int) * nnodes); + *nints = *nreals = 0; + for (i = 0; i < nnodes; i++) { + i3 = 3 * i; + for (j = 0; j < 3; j++) xd[j] = 0; + for (j = 0; j < 3; j++) + for (k = 0; k < 3; k++) + xd[j] += (x[i3 + k] - obc->xc[k]) * obc->vec[j][k]; + + if (fabs(xd[0]) <= obc->dxc[0] && fabs(xd[1]) <= obc->dxc[1] && + fabs(xd[2]) <= obc->dxc[2]) { + inode[*nints] = i; + (*nints)++; + (*nreals) += 4; } } - if (myid==0 && meshtag==1) {TRACEI(*nints);} - (*intData)=(int *)malloc(sizeof(int)*(*nints)); - (*realData)=(double *)malloc(sizeof(double)*(*nreals)); - // - m=0; - for(i=0;i<*nints;i++) - { - i3=3*inode[i]; - (*intData)[i]=inode[i]; - (*realData)[m++]=x[i3]; - (*realData)[m++]=x[i3+1]; - (*realData)[m++]=x[i3+2]; - (*realData)[m++]=nodeRes[inode[i]]; - } - // - TIOGA_FREE(inode); + if (myid == 0 && meshtag == 1) { + TRACEI(*nints); + } + (*intData) = (int*)malloc(sizeof(int) * (*nints)); + (*realData) = (double*)malloc(sizeof(double) * (*nreals)); + // + m = 0; + for (i = 0; i < *nints; i++) { + i3 = 3 * inode[i]; + (*intData)[i] = inode[i]; + (*realData)[m++] = x[i3]; + (*realData)[m++] = x[i3 + 1]; + (*realData)[m++] = x[i3 + 2]; + (*realData)[m++] = nodeRes[inode[i]]; + } + // + TIOGA_FREE(inode); } -void MeshBlock::getQueryPoints2(OBB *obc, - int *nints,int **intData, - int *nreals, double **realData) +void MeshBlock::getQueryPoints2( + OBB* obc, int* nints, int** intData, int* nreals, double** realData) { - int i,j,k,l,il,ik,ij,n,m,i3,iflag; - int indx,iptr; - int *inode; - double delta; - double xv[8][3],mdx[3],xd[3],xc[3]; - double xmax[3],xmin[3]; - int imin[3],imax[3]; - // - inode=(int *)malloc(sizeof(int)*nnodes); - *nints=*nreals=0; - getobbcoords(obc->xc,obc->dxc,obc->vec,xv); - for(j=0;j<3;j++) {xmin[j]=BIGVALUE;xmax[j]=-BIGVALUE;}; - //writebbox(obc,1); - //writebbox(obb,2); - //writebboxdiv(obb,1); - // - for(n=0;n<8;n++) - { - transform2OBB(xv[n],obb->xc,obb->vec,xd); - for(j=0;j<3;j++) - { - xmin[j]=std::min(xmin[j],xd[j]+obb->dxc[j]); - xmax[j]=std::max(xmax[j],xd[j]+obb->dxc[j]); + int i, j, k, l, il, ik, ij, n, m, i3, iflag; + int indx, iptr; + int* inode; + double delta; + double xv[8][3], mdx[3], xd[3], xc[3]; + double xmax[3], xmin[3]; + int imin[3], imax[3]; + // + inode = (int*)malloc(sizeof(int) * nnodes); + *nints = *nreals = 0; + getobbcoords(obc->xc, obc->dxc, obc->vec, xv); + for (j = 0; j < 3; j++) { + xmin[j] = BIGVALUE; + xmax[j] = -BIGVALUE; + }; + // writebbox(obc,1); + // writebbox(obb,2); + // writebboxdiv(obb,1); + // + for (n = 0; n < 8; n++) { + transform2OBB(xv[n], obb->xc, obb->vec, xd); + for (j = 0; j < 3; j++) { + xmin[j] = std::min(xmin[j], xd[j] + obb->dxc[j]); + xmax[j] = std::max(xmax[j], xd[j] + obb->dxc[j]); } } - for(j=0;j<3;j++) - { - delta=0.01*(xmax[j]-xmin[j]); - xmin[j]-=delta; - xmax[j]+=delta; - imin[j]=std::max(xmin[j]/mapdx[j],0.0); - imax[j]=std::min(xmax[j]/mapdx[j],static_cast(mapdims[j]-1)); - mdx[j]=0.5*mapdx[j]; + for (j = 0; j < 3; j++) { + delta = 0.01 * (xmax[j] - xmin[j]); + xmin[j] -= delta; + xmax[j] += delta; + imin[j] = std::max(xmin[j] / mapdx[j], 0.0); + imax[j] = + std::min(xmax[j] / mapdx[j], static_cast(mapdims[j] - 1)); + mdx[j] = 0.5 * mapdx[j]; } - // - // find min/max extends of a single sub-block - // in OBC axes - // - getobbcoords(obc->xc,mdx,obb->vec,xv); - for(j=0;j<3;j++) {xmin[j]=BIGVALUE;xmax[j]=-BIGVALUE;} - for(m=0;m<8;m++) - { - transform2OBB(xv[m],obc->xc,obc->vec,xd); - for(j=0;j<3;j++) - { - xmin[j]=std::min(xmin[j],xd[j]); - xmax[j]=std::max(xmax[j],xd[j]); - } + // + // find min/max extends of a single sub-block + // in OBC axes + // + getobbcoords(obc->xc, mdx, obb->vec, xv); + for (j = 0; j < 3; j++) { + xmin[j] = BIGVALUE; + xmax[j] = -BIGVALUE; + } + for (m = 0; m < 8; m++) { + transform2OBB(xv[m], obc->xc, obc->vec, xd); + for (j = 0; j < 3; j++) { + xmin[j] = std::min(xmin[j], xd[j]); + xmax[j] = std::max(xmax[j], xd[j]); + } } - //printf("xmin :%f %f %f\n",xmin[0],xmin[1],xmin[2]); - //printf("xmax :%f %f %f\n",xmax[0],xmax[1],xmax[2]); - // - // now find the actual number of points - // that are within OBC using only the - // sub-blocks with potential bbox overlap - // - //FILE *fp,*fp2,*fp3,*fp4; - //fp=fopen("v.dat","w"); - //fp2=fopen("v2.dat","w"); - //fp3=fopen("v3.dat","w"); - //fp4=fopen("v4.dat","w"); - for(l=imin[2];l<=imax[2];l++) - for(k=imin[1];k<=imax[1];k++) - for(j=imin[0];j<=imax[0];j++) - { - // - // centroid of each sub-block - // in OBC axes - // - xd[0]=-obb->dxc[0]+j*mapdx[0]+mapdx[0]*0.5; - xd[1]=-obb->dxc[1]+k*mapdx[1]+mapdx[1]*0.5; - xd[2]=-obb->dxc[2]+l*mapdx[2]+mapdx[2]*0.5; - for(n=0;n<3;n++) - { - xc[n]=obb->xc[n]; - for(ij=0;ij<3;ij++) - xc[n]+=(xd[ij]*obb->vec[ij][n]); - } - //if (j==0 && k==0 & l==0) { - //printf("%f %f %f\n",obc->vec[0][0],obc->vec[1][0],obc->vec[2][0]); - //printf("%f %f %f\n",obc->vec[0][1],obc->vec[1][1],obc->vec[2][1]); - //printf("%f %f %f\n",obc->vec[0][2],obc->vec[1][2],obc->vec[2][2]); - //printf("%f %f %f\n",obc->xc[0],obc->xc[1],obc->xc[2]); - //} - //fprintf(fp,"%f %f %f\n",xc[0],xc[1],xc[2]); - transform2OBB(xc,obc->xc,obc->vec,xd); - //fprintf(fp2,"%f %f %f\n",xd[0],xd[1],xd[2]); - //if (fabs(xd[0]) <= obc->dxc[0] && - // fabs(xd[1]) <= obc->dxc[1] && - // fabs(xd[2]) <= obc->dxc[2]) -// { -// fprintf(fp3,"%f %f %f\n",xc[0],xc[1],xc[2]); -// } - // - // check if this sub-block overlaps OBC - // - iflag=0; - for(ij=0;ij<3 && !iflag;ij++) iflag=(iflag || (xmin[ij]+xd[ij] > obc->dxc[ij])); - if (iflag) continue; - iflag=0; - for(ij=0;ij<3 && !iflag;ij++) iflag=(iflag || (xmax[ij]+xd[ij] < -obc->dxc[ij])); - if (iflag) continue; - //fprintf(fp4,"%f %f %f\n",xc[0],xc[1],xc[2]); - // - // if there overlap - // go through points within the sub-block - // to figure out what needs to be send - // - indx=l*mapdims[1]*mapdims[0]+k*mapdims[0]+j; - for(m=icft[indx];mxc,obc->vec,xd); - if (fabs(xd[0]) <= obc->dxc[0] && - fabs(xd[1]) <= obc->dxc[1] && - fabs(xd[2]) <= obc->dxc[2]) - { - inode[*nints]=invmap[m]; - (*nints)++; - (*nreals)+=4; - } - } - } + // printf("xmin :%f %f %f\n",xmin[0],xmin[1],xmin[2]); + // printf("xmax :%f %f %f\n",xmax[0],xmax[1],xmax[2]); + // + // now find the actual number of points + // that are within OBC using only the + // sub-blocks with potential bbox overlap + // + // FILE *fp,*fp2,*fp3,*fp4; + // fp=fopen("v.dat","w"); + // fp2=fopen("v2.dat","w"); + // fp3=fopen("v3.dat","w"); + // fp4=fopen("v4.dat","w"); + for (l = imin[2]; l <= imax[2]; l++) + for (k = imin[1]; k <= imax[1]; k++) + for (j = imin[0]; j <= imax[0]; j++) { + // + // centroid of each sub-block + // in OBC axes + // + xd[0] = -obb->dxc[0] + j * mapdx[0] + mapdx[0] * 0.5; + xd[1] = -obb->dxc[1] + k * mapdx[1] + mapdx[1] * 0.5; + xd[2] = -obb->dxc[2] + l * mapdx[2] + mapdx[2] * 0.5; + for (n = 0; n < 3; n++) { + xc[n] = obb->xc[n]; + for (ij = 0; ij < 3; ij++) + xc[n] += (xd[ij] * obb->vec[ij][n]); + } + // if (j==0 && k==0 & l==0) { + // printf("%f %f + // %f\n",obc->vec[0][0],obc->vec[1][0],obc->vec[2][0]); + // printf("%f %f + // %f\n",obc->vec[0][1],obc->vec[1][1],obc->vec[2][1]); + // printf("%f %f + // %f\n",obc->vec[0][2],obc->vec[1][2],obc->vec[2][2]); + // printf("%f %f %f\n",obc->xc[0],obc->xc[1],obc->xc[2]); + // } + // fprintf(fp,"%f %f %f\n",xc[0],xc[1],xc[2]); + transform2OBB(xc, obc->xc, obc->vec, xd); + // fprintf(fp2,"%f %f %f\n",xd[0],xd[1],xd[2]); + // if (fabs(xd[0]) <= obc->dxc[0] && + // fabs(xd[1]) <= obc->dxc[1] && + // fabs(xd[2]) <= obc->dxc[2]) + // { + // fprintf(fp3,"%f %f %f\n",xc[0],xc[1],xc[2]); + // } + // + // check if this sub-block overlaps OBC + // + iflag = 0; + for (ij = 0; ij < 3 && !iflag; ij++) + iflag = (iflag || (xmin[ij] + xd[ij] > obc->dxc[ij])); + if (iflag) continue; + iflag = 0; + for (ij = 0; ij < 3 && !iflag; ij++) + iflag = (iflag || (xmax[ij] + xd[ij] < -obc->dxc[ij])); + if (iflag) continue; + // fprintf(fp4,"%f %f %f\n",xc[0],xc[1],xc[2]); + // + // if there overlap + // go through points within the sub-block + // to figure out what needs to be send + // + indx = l * mapdims[1] * mapdims[0] + k * mapdims[0] + j; + for (m = icft[indx]; m < icft[indx + 1]; m++) { + i3 = 3 * invmap[m]; + for (ik = 0; ik < 3; ik++) xc[ik] = x[i3 + ik]; + transform2OBB(xc, obc->xc, obc->vec, xd); + if (fabs(xd[0]) <= obc->dxc[0] && + fabs(xd[1]) <= obc->dxc[1] && + fabs(xd[2]) <= obc->dxc[2]) { + inode[*nints] = invmap[m]; + (*nints)++; + (*nreals) += 4; + } + } + } // TRACEI(*nints); // fclose(fp); // fclose(fp2); @@ -1745,76 +1724,73 @@ void MeshBlock::getQueryPoints2(OBB *obc, // fclose(fp4); // int ierr; // MPI_Abort(MPI_COMM_WORLD,ierr); - // +// #ifdef TIOGA_HAS_NODEGID - int nintsPerNode = 3; + int nintsPerNode = 3; #else - int nintsPerNode = 1; + int nintsPerNode = 1; #endif - (*intData)=(int *)malloc(sizeof(int)*(*nints) * nintsPerNode); - (*realData)=(double *)malloc(sizeof(double)*(*nreals)); - // - m=0; - int iidx = 0; - for(i=0;i<*nints;i++) { - i3=3*inode[i]; - (*intData)[iidx++]=inode[i]; + (*intData) = (int*)malloc(sizeof(int) * (*nints) * nintsPerNode); + (*realData) = (double*)malloc(sizeof(double) * (*nreals)); + // + m = 0; + int iidx = 0; + for (i = 0; i < *nints; i++) { + i3 = 3 * inode[i]; + (*intData)[iidx++] = inode[i]; #ifdef TIOGA_HAS_NODEGID - std::memcpy(&(*intData)[iidx],&nodeGID[inode[i]], sizeof(uint64_t)); - iidx += 2; + std::memcpy(&(*intData)[iidx], &nodeGID[inode[i]], sizeof(uint64_t)); + iidx += 2; #endif - (*realData)[m++]=x[i3]; - (*realData)[m++]=x[i3+1]; - (*realData)[m++]=x[i3+2]; - (*realData)[m++]=nodeRes[inode[i]]; - } - - // Adjust nints to the proper array size - *nints *= nintsPerNode; - // - TIOGA_FREE(inode); + (*realData)[m++] = x[i3]; + (*realData)[m++] = x[i3 + 1]; + (*realData)[m++] = x[i3 + 2]; + (*realData)[m++] = nodeRes[inode[i]]; + } + + // Adjust nints to the proper array size + *nints *= nintsPerNode; + // + TIOGA_FREE(inode); } void MeshBlock::writeOBB(int bid) { - FILE *fp; - char intstring[12]; - char fname[80]; - int l,k,j,m,il,ik,ij; - REAL xx[3]; - - sprintf(intstring,"%d",100000+bid); - sprintf(fname,"box%s.dat",&(intstring[1])); - fp=fopen(fname,"w"); - fprintf(fp,"TITLE =\"Box file\"\n"); - fprintf(fp,"VARIABLES=\"X\",\"Y\",\"Z\"\n"); - fprintf(fp,"ZONE T=\"VOL_MIXED\",N=%d E=%d ET=BRICK, F=FEPOINT\n",8, - 1); - - for(l=0;l<2;l++) - { - il=2*(l%2)-1; - for(k=0;k<2;k++) - { - ik=2*(k%2)-1; - for(j=0;j<2;j++) - { - ij=2*(j%2)-1; - xx[0]=xx[1]=xx[2]=0; - for(m=0;m<3;m++) - xx[m]=obb->xc[m]+ij*obb->vec[0][m]*obb->dxc[0] - +ik*obb->vec[1][m]*obb->dxc[1] - +il*obb->vec[2][m]*obb->dxc[2]; - fprintf(fp,"%f %f %f\n",xx[0],xx[1],xx[2]); - } - } + FILE* fp; + char intstring[12]; + char fname[80]; + int l, k, j, m, il, ik, ij; + REAL xx[3]; + + snprintf(intstring, sizeof(intstring), "%d", 100000 + bid); + snprintf(fname, sizeof(fname), "box%s.dat", &(intstring[1])); + fp = fopen(fname, "w"); + fprintf(fp, "TITLE =\"Box file\"\n"); + fprintf(fp, "VARIABLES=\"X\",\"Y\",\"Z\"\n"); + fprintf(fp, "ZONE T=\"VOL_MIXED\",N=%d E=%d ET=BRICK, F=FEPOINT\n", 8, 1); + + for (l = 0; l < 2; l++) { + il = 2 * (l % 2) - 1; + for (k = 0; k < 2; k++) { + ik = 2 * (k % 2) - 1; + for (j = 0; j < 2; j++) { + ij = 2 * (j % 2) - 1; + xx[0] = xx[1] = xx[2] = 0; + for (m = 0; m < 3; m++) + xx[m] = obb->xc[m] + ij * obb->vec[0][m] * obb->dxc[0] + + ik * obb->vec[1][m] * obb->dxc[1] + + il * obb->vec[2][m] * obb->dxc[2]; + fprintf(fp, "%f %f %f\n", xx[0], xx[1], xx[2]); + } + } } - fprintf(fp,"1 2 4 3 5 6 8 7\n"); - fprintf(fp,"%e %e %e\n",obb->xc[0],obb->xc[1],obb->xc[2]); - for(k=0;k<3;k++) - fprintf(fp,"%e %e %e\n",obb->vec[0][k],obb->vec[1][k],obb->vec[2][k]); - fprintf(fp,"%e %e %e\n",obb->dxc[0],obb->dxc[1],obb->dxc[2]); - fclose(fp); + fprintf(fp, "1 2 4 3 5 6 8 7\n"); + fprintf(fp, "%e %e %e\n", obb->xc[0], obb->xc[1], obb->xc[2]); + for (k = 0; k < 3; k++) + fprintf( + fp, "%e %e %e\n", obb->vec[0][k], obb->vec[1][k], obb->vec[2][k]); + fprintf(fp, "%e %e %e\n", obb->dxc[0], obb->dxc[1], obb->dxc[2]); + fclose(fp); } // // destructor that deallocates all the @@ -1822,91 +1798,89 @@ void MeshBlock::writeOBB(int bid) // MeshBlock::~MeshBlock() { - int i; - // - // TIOGA_FREE all data that is owned by this MeshBlock - // i.e not the pointers of the external code. - // - if (cellRes) TIOGA_FREE(cellRes); - if (nodeRes) TIOGA_FREE(nodeRes); - if (elementBbox) TIOGA_FREE(elementBbox); - if (elementList) TIOGA_FREE(elementList); - if (adt) delete[] adt; - if (donorList) { - for(i=0;i 1) return; - for(int n=0;n TOL) return; - if (fabs(tdot_product(xv[1],xv[3],xv[2])) > TOL) return; - // - // x=0 side - // - if (fabs(tdot_product(xv[3],xv[4],xv[0])) > TOL) return; - if (fabs(tdot_product(xv[3],xv[4],xv[7])) > TOL) return; - // - // y=0 side - // - if (fabs(tdot_product(xv[4],xv[1],xv[0])) > TOL) return; - if (fabs(tdot_product(xv[4],xv[1],xv[5])) > TOL) return; - // - // need to check just one more angle on - // on the corner against 0 (6) - // - if (fabs(tdot_product(xv[5],xv[7],xv[6])) > TOL) return; - // - // so this is a hex - // check if it has the same size as the previous hex - // if not return - // - if (i==0){ - dx[0]=tdot_product(xv[1],xv[1],xv[0]); - dx[1]=tdot_product(xv[3],xv[3],xv[0]); - dx[2]=tdot_product(xv[4],xv[4],xv[0]); - } - else { - if (fabs(dx[0]-tdot_product(xv[1],xv[1],xv[0])) > TOL) return; - if (fabs(dx[1]-tdot_product(xv[3],xv[3],xv[0])) > TOL) return; - if (fabs(dx[2]-tdot_product(xv[4],xv[4],xv[0])) > TOL) return; - } - } - } - } - if (hex_present) { - for(int j=0;j<3;j++) dx[j]=sqrt(dx[j]); - uniform_hex=1; - if (obh) TIOGA_FREE(obh); - obh=(OBB *) malloc(sizeof(OBB)); - for(int j=0;j<3;j++) - for(int k=0;k<3;k++) - obh->vec[j][k]=0; - for(int k=0;k<3;k++) - obh->vec[0][k]=(xv[1][k]-xv[0][k])/dx[0]; - for(int k=0;k<3;k++) - obh->vec[1][k]=(xv[3][k]-xv[0][k])/dx[1]; - for(int k=0;k<3;k++) - obh->vec[2][k]=(xv[4][k]-xv[0][k])/dx[2]; - //obh->vec[0][0]=obh->vec[1][1]=obh->vec[2][2]=1; - // - double xd[3]; - double xmax[3]; - double xmin[3]; - xmax[0]=xmax[1]=xmax[2]=-BIGVALUE; - xmin[0]=xmin[1]=xmin[2]=BIGVALUE; - // - for(int i=0;ivec[j][k]; - // - for(int j=0;j<3;j++) - { - xmax[j]=std::max(xmax[j],xd[j]); - xmin[j]=std::min(xmin[j],xd[j]); - } + double xv[8][3]; + int hex_present = 0; + if (ntypes > 1) return; + for (int n = 0; n < ntypes; n++) { + int nvert = nv[n]; + if (nvert == 8) { + hex_present = 1; + for (int i = 0; i < nc[n]; i++) { + int vold = -1; + for (int m = 0; m < nvert; m++) { + if (vconn[n][nvert * i + m] == vold) + return; // degenerated hex are not uniform + vold = vconn[n][nvert * i + m]; + int i3 = 3 * (vconn[n][nvert * i + m] - BASE); + for (int k = 0; k < 3; k++) xv[m][k] = x[i3 + k]; + } + // + // check angles to see if sides are + // rectangles + // + // z=0 side + // + if (fabs(tdot_product(xv[1], xv[3], xv[0])) > TOL) return; + if (fabs(tdot_product(xv[1], xv[3], xv[2])) > TOL) return; + // + // x=0 side + // + if (fabs(tdot_product(xv[3], xv[4], xv[0])) > TOL) return; + if (fabs(tdot_product(xv[3], xv[4], xv[7])) > TOL) return; + // + // y=0 side + // + if (fabs(tdot_product(xv[4], xv[1], xv[0])) > TOL) return; + if (fabs(tdot_product(xv[4], xv[1], xv[5])) > TOL) return; + // + // need to check just one more angle on + // on the corner against 0 (6) + // + if (fabs(tdot_product(xv[5], xv[7], xv[6])) > TOL) return; + // + // so this is a hex + // check if it has the same size as the previous hex + // if not return + // + if (i == 0) { + dx[0] = tdot_product(xv[1], xv[1], xv[0]); + dx[1] = tdot_product(xv[3], xv[3], xv[0]); + dx[2] = tdot_product(xv[4], xv[4], xv[0]); + } else { + if (fabs(dx[0] - tdot_product(xv[1], xv[1], xv[0])) > TOL) + return; + if (fabs(dx[1] - tdot_product(xv[3], xv[3], xv[0])) > TOL) + return; + if (fabs(dx[2] - tdot_product(xv[4], xv[4], xv[0])) > TOL) + return; + } + } + } } + if (hex_present) { + for (int j = 0; j < 3; j++) dx[j] = sqrt(dx[j]); + uniform_hex = 1; + if (obh) TIOGA_FREE(obh); + obh = (OBB*)malloc(sizeof(OBB)); + for (int j = 0; j < 3; j++) + for (int k = 0; k < 3; k++) obh->vec[j][k] = 0; + for (int k = 0; k < 3; k++) + obh->vec[0][k] = (xv[1][k] - xv[0][k]) / dx[0]; + for (int k = 0; k < 3; k++) + obh->vec[1][k] = (xv[3][k] - xv[0][k]) / dx[1]; + for (int k = 0; k < 3; k++) + obh->vec[2][k] = (xv[4][k] - xv[0][k]) / dx[2]; + // obh->vec[0][0]=obh->vec[1][1]=obh->vec[2][2]=1; // - // find the extents of the box - // and coordinates of the center w.r.t. xc - // increase extents by 1% for tolerance - // - for(int j=0;j<3;j++) - { - xmax[j]+=TOL; - xmin[j]-=TOL; - obh->dxc[j]=(xmax[j]-xmin[j])*0.5; - xd[j]=(xmax[j]+xmin[j])*0.5; - } - // - // find the center of the box in - // actual cartesian coordinates - // - for(int j=0;j<3;j++) - { - obh->xc[j]=0.0; - for(int k=0;k<3;k++) - obh->xc[j]+=(xd[k]*obh->vec[k][j]); - } - } - return; + double xd[3]; + double xmax[3]; + double xmin[3]; + xmax[0] = xmax[1] = xmax[2] = -BIGVALUE; + xmin[0] = xmin[1] = xmin[2] = BIGVALUE; + // + for (int i = 0; i < nnodes; i++) { + int i3 = 3 * i; + for (int j = 0; j < 3; j++) xd[j] = 0; + // + for (int j = 0; j < 3; j++) + for (int k = 0; k < 3; k++) xd[j] += x[i3 + k] * obh->vec[j][k]; + // + for (int j = 0; j < 3; j++) { + xmax[j] = std::max(xmax[j], xd[j]); + xmin[j] = std::min(xmin[j], xd[j]); + } + } + // + // find the extents of the box + // and coordinates of the center w.r.t. xc + // increase extents by 1% for tolerance + // + for (int j = 0; j < 3; j++) { + xmax[j] += TOL; + xmin[j] -= TOL; + obh->dxc[j] = (xmax[j] - xmin[j]) * 0.5; + xd[j] = (xmax[j] + xmin[j]) * 0.5; + } + // + // find the center of the box in + // actual cartesian coordinates + // + for (int j = 0; j < 3; j++) { + obh->xc[j] = 0.0; + for (int k = 0; k < 3; k++) obh->xc[j] += (xd[k] * obh->vec[k][j]); + } + } + return; } void MeshBlock::create_hex_cell_map(void) { - for(int j=0;j<3;j++) - { - xlow[j]=obh->xc[j]; - for (int k=0;k<3;k++) - xlow[j]-=(obh->dxc[k]*obh->vec[k][j]); - idims[j]=round(2*obh->dxc[j]/dx[j]); - dx[j]=(2*obh->dxc[j])/idims[j]; + for (int j = 0; j < 3; j++) { + xlow[j] = obh->xc[j]; + for (int k = 0; k < 3; k++) xlow[j] -= (obh->dxc[k] * obh->vec[k][j]); + idims[j] = round(2 * obh->dxc[j] / dx[j]); + dx[j] = (2 * obh->dxc[j]) / idims[j]; } - // - if (uindx) TIOGA_FREE(uindx); - uindx=(int *)malloc(sizeof(int)*idims[0]*idims[1]*idims[2]); - for(int i=0;ivec[j][k]; - idx[j]=xd[j]/dx[j]; - } - uindx[idx[2]*idims[1]*idims[0]+idx[1]*idims[0]+idx[0]]=i; + // + if (uindx) TIOGA_FREE(uindx); + uindx = (int*)malloc(sizeof(int) * idims[0] * idims[1] * idims[2]); + for (int i = 0; i < idims[0] * idims[1] * idims[2]; uindx[i++] = -1) + ; + // + for (int i = 0; i < nc[0]; i++) { + double xc[3]; + double xd[3]; + int idx[3]; + for (int j = 0; j < 3; j++) { + int lnode = vconn[0][8 * i] - BASE; + int tnode = vconn[0][8 * i + 6] - BASE; + xc[j] = 0.5 * (x[3 * lnode + j] + x[3 * tnode + j]); + } + for (int j = 0; j < 3; j++) { + xd[j] = 0; + for (int k = 0; k < 3; k++) + xd[j] += (xc[k] - xlow[k]) * obh->vec[j][k]; + idx[j] = xd[j] / dx[j]; + } + uindx[idx[2] * idims[1] * idims[0] + idx[1] * idims[0] + idx[0]] = i; } } void MeshBlock::checkOrphans(void) { - int norphan=0; - char fname[80]; - //sprintf(fname,"nodeRes%d.dat",myid); - //FILE *fp=fopen(fname,"w"); - for (int i=0;i=BIGVALUE) { - if (iblank[i]==1) { - norphan++; + int norphan = 0; + char fname[80]; + // sprintf(fname,"nodeRes%d.dat",myid); + // FILE *fp=fopen(fname,"w"); + for (int i = 0; i < nnodes; i++) { + if (nodeRes[i] >= BIGVALUE) { + if (iblank[i] == 1) { + norphan++; + } + // if (nodeRes[i] > BIGVALUE) printf("%d %d + // %e\n",myid,i,nodeRes[i]); } - //if (nodeRes[i] > BIGVALUE) printf("%d %d %e\n",myid,i,nodeRes[i]); - } - //fprintf(fp,"%d %e %d %d\n",i,nodeRes[i],iblank[i],nodeRes[i]>=BIGVALUE); + // fprintf(fp,"%d %e %d + // %d\n",i,nodeRes[i],iblank[i],nodeRes[i]>=BIGVALUE); } - //fclose(fp); - if (norphan > 0) { - char intstring[12]; - char fname[80]; - printf("myid/meshtag/norphan/nnodes/nobc=%d %d %d %d %d\n",myid,meshtag,norphan,nnodes,nobc); - sprintf(intstring,"%d",100000+myid); - sprintf(fname,"orphan%s.dat",&(intstring[1])); - FILE *fp=fopen(fname,"w"); - for (int i=0;i=BIGVALUE) { - if (iblank[i]==1) { - fprintf(fp,"%f %f %f %f\n",x[3*i],x[3*i+1],x[3*i+2],nodeRes[i]); - norphan++; + // fclose(fp); + if (norphan > 0) { + char intstring[12]; + char fname[80]; + printf( + "myid/meshtag/norphan/nnodes/nobc=%d %d %d %d %d\n", myid, meshtag, + norphan, nnodes, nobc); + snprintf(intstring, sizeof(intstring), "%d", 100000 + myid); + snprintf(fname, sizeof(fname), "orphan%s.dat", &(intstring[1])); + FILE* fp = fopen(fname, "w"); + for (int i = 0; i < nnodes; i++) { + if (nodeRes[i] >= BIGVALUE) { + if (iblank[i] == 1) { + fprintf( + fp, "%f %f %f %f\n", x[3 * i], x[3 * i + 1], + x[3 * i + 2], nodeRes[i]); + norphan++; + } + } } - } + fclose(fp); } - fclose(fp); - } } diff --git a/src/MeshBlock.h b/src/MeshBlock.h index 8b04b92..10cd832 100644 --- a/src/MeshBlock.h +++ b/src/MeshBlock.h @@ -45,451 +45,527 @@ class CartGrid; #define HOLE 0 #define FIELD 1 -class MeshBlock { +class MeshBlock +{ private: - /** Mesh block info provided by the application code - * - * This is a non-owning pointer whose lifetime is controlled by the - * application. - */ - TIOGA::MeshBlockInfo *m_info{nullptr}; - - /** Device copy of the mesh block info registered by the application code - * - * This pointer is owned by MeshBlock - */ - TIOGA::MeshBlockInfo *m_info_device{nullptr}; - - int nnodes; /** < number of grid nodes */ - int ncells; /** < total number of cells */ - int ntypes; /** < number of different types of cells */ - int *nv; /** < number of vertices for each types of cell */ - int *nc; /** < number of each of different kinds of cells (tets, prism, - pyramids, hex etc) */ - int nobc; /** < number of overset boundary nodes */ - int nwbc; /** < number of wall boundary nodes */ - int nvar; /** < Number of variables */ - // - double *x; /** < grid nodes x[3*nnodes] */ - int *iblank_cell; /** < iblank value at each grid cell */ - // - int **vconn; /** < connectivity of each kind of cell */ - int *wbcnode; /** < wall boundary node indices */ - int *obcnode; /** < overset boundary node indices */ - uint64_t *cellGID; /** < Global ID of the cell */ - uint64_t *nodeGID; /** < Global ID for the nodes */ - // - int nwbcface; /** < number of wall boundary faces */ - int nobcface; /** < number of outer boundary faces */ - std::vector wbcfacenode; /** < [4*nwbcface] wall face boundary nodes (-1 - node: triangle face) */ - std::vector obcfacenode; /** < [4*nobcface] outer face boundary nodes (-1 - node: triangle face) */ - std::vector wbcfacebox; /** < [nwbcface] wall face bounding boxes */ - std::vector obcfacebox; /** < [nobcface] outer face bounding boxes */ - // - double *nodeRes; /** < node resolution */ - double *userSpecifiedNodeRes; - double *userSpecifiedCellRes; - double *elementBbox; /** < bounding box of the elements */ - int *elementList; /** < list of elements in */ - // - // Alternating digital tree library - // - ADT *adt; /** < Digital tree for searching this block */ - // - DONORLIST **donorList; /**< list of donors for the nodes of this mesh */ - // - int ninterp; /**< number of interpolations to be performed */ - int interpListSize; - int interptype; - INTERPLIST *interpList; /**< list of donor nodes in my grid, with fractions - and information of who they donate to */ - int *interp2donor; - - INTEGERLIST *cancelList; /** receptors that need to be canceled because of */ - int ncancel; /** conflicts with the state of their donors */ - void (*get_nodes_per_cell)(int *, int *); - void (*get_receptor_nodes)(int *, int *, double *); - void (*donor_inclusion_test)(int *, double *, int *, double *); - void (*donor_frac)(int *, double *, int *, int *, double *, double *, int *); - void (*convert_to_modal)(int *, int *, double *, int *, int *, double *); - - int nreceptorCells; /** number of receptor cells */ - int *ctag; /** index of receptor cells */ - int *pointsPerCell; /** number of receptor points per cell */ - int maxPointsPerCell; /** max of pointsPerCell vector */ - double *rxyz; /** point coordinates */ - int ipoint; - int *picked; /** < flag specifying if a node has been selected for high-order - interpolation */ - - int nreceptorCellsCart; - int *ctag_cart; - int *pickedCart; - int uniform_hex; - double dx[3]; - double xlow[3]; - int idims[3]; - int *uindx; - int *invmap; // inverse map - int *mapmask; // mask - int *icft; // frequency table for nodal containment - int mapdims[3]; // dimensions of the map - double mapdx[3]; // sides of the map + /** Mesh block info provided by the application code + * + * This is a non-owning pointer whose lifetime is controlled by the + * application. + */ + TIOGA::MeshBlockInfo* m_info{nullptr}; + + /** Device copy of the mesh block info registered by the application code + * + * This pointer is owned by MeshBlock + */ + TIOGA::MeshBlockInfo* m_info_device{nullptr}; + + int nnodes; /** < number of grid nodes */ + int ncells; /** < total number of cells */ + int ntypes; /** < number of different types of cells */ + int* nv; /** < number of vertices for each types of cell */ + int* nc; /** < number of each of different kinds of cells (tets, prism, + pyramids, hex etc) */ + int nobc; /** < number of overset boundary nodes */ + int nwbc; /** < number of wall boundary nodes */ + int nvar; /** < Number of variables */ + // + double* x; /** < grid nodes x[3*nnodes] */ + int* iblank_cell; /** < iblank value at each grid cell */ + // + int** vconn; /** < connectivity of each kind of cell */ + int* wbcnode; /** < wall boundary node indices */ + int* obcnode; /** < overset boundary node indices */ + uint64_t* cellGID; /** < Global ID of the cell */ + uint64_t* nodeGID; /** < Global ID for the nodes */ + // + int nwbcface; /** < number of wall boundary faces */ + int nobcface; /** < number of outer boundary faces */ + std::vector wbcfacenode; /** < [4*nwbcface] wall face boundary nodes + (-1 node: triangle face) */ + std::vector obcfacenode; /** < [4*nobcface] outer face boundary nodes + (-1 node: triangle face) */ + std::vector wbcfacebox; /** < [nwbcface] wall face bounding boxes */ + std::vector obcfacebox; /** < [nobcface] outer face bounding boxes */ + // + double* nodeRes; /** < node resolution */ + double* userSpecifiedNodeRes; + double* userSpecifiedCellRes; + double* elementBbox; /** < bounding box of the elements */ + int* elementList; /** < list of elements in */ + // + // Alternating digital tree library + // + ADT* adt; /** < Digital tree for searching this block */ + // + DONORLIST** donorList; /**< list of donors for the nodes of this mesh */ + // + int ninterp; /**< number of interpolations to be performed */ + int interpListSize; + int interptype; + INTERPLIST* interpList; /**< list of donor nodes in my grid, with fractions + and information of who they donate to */ + int* interp2donor; + + INTEGERLIST* + cancelList; /** receptors that need to be canceled because of */ + int ncancel; /** conflicts with the state of their donors */ + void (*get_nodes_per_cell)(int*, int*); + void (*get_receptor_nodes)(int*, int*, double*); + void (*donor_inclusion_test)(int*, double*, int*, double*); + void (*donor_frac)(int*, double*, int*, int*, double*, double*, int*); + void (*convert_to_modal)(int*, int*, double*, int*, int*, double*); + + int nreceptorCells; /** number of receptor cells */ + int* ctag; /** index of receptor cells */ + int* pointsPerCell; /** number of receptor points per cell */ + int maxPointsPerCell; /** max of pointsPerCell vector */ + double* rxyz; /** point coordinates */ + int ipoint; + int* picked; /** < flag specifying if a node has been selected for + high-order interpolation */ + + int nreceptorCellsCart; + int* ctag_cart; + int* pickedCart; + int uniform_hex; + double dx[3]; + double xlow[3]; + int idims[3]; + int* uindx; + int* invmap; // inverse map + int* mapmask; // mask + int* icft; // frequency table for nodal containment + int mapdims[3]; // dimensions of the map + double mapdx[3]; // sides of the map public: - int *iblank; /** < iblank value for each grid node */ - int *iblank_reduced; - int ntotalPointsCart; - double *rxyzCart; - int *donorIdCart; - int donorListLength; - - int nfringe; - int mexclude; - int meshtag; /** < tag of the mesh that this block belongs to */ - int check_uniform_hex_flag; - double resolutionScale; - double searchTol; - int dominanceFlag; /**< if dominanceflag=1: set noderes to tiny number */ - // - // oriented bounding box of this partition - // - OBB *obb; - OBB *obh; - // - int nsearch; /** < number of query points to search in this block */ - int *isearch; /** < index of query points in the remote process */ - int *tagsearch; /** < index of query points in the remote process */ - double *res_search; /** < resolution of search points */ - int *xtag; /** < hash to determine if there are duplicates */ - double *xsearch; /** < coordinates of the query points */ - double *rst; /** < natural coordinates */ - int *donorId; /** < donor indices for those found */ - std::vector gid_search; /** < Global node ID for the query points */ - int donorCount; - - int myid; /** < global mpi rank */ - int blockcomm_id; /** < mpi rank within this block */ - int blockcomm_numprocs; /** < number of mpi ranks within this blocks */ - MPI_Comm blockcomm; /** < subgroup communicator for this mesh block */ - char composite; /** < mesh block composite body flag */ - char meshMaster; /** < master rank for each body flag: [0] subordinate rank, - [1] master rank */ - double bboxLocalAHM[6]; /** < wall bc node bounding box (without duplicate - obc/wbc nodes) */ - - double *cellRes; /** < resolution for each cell */ - int ntotalPoints; /** total number of extra points to interpolate */ - int ihigh; - int ninterp2; /** < number of interpolants for high-order points */ - int interp2ListSize; - INTERPLIST *interpList2; /** < list for high-interpolation points */ - int ninterpCart; - int interpListCartSize; - INTERPLIST *interpListCart; - int *receptorIdCart; - - int *vconn_ptrs[TIOGA::MeshBlockInfo::max_vertex_types]; - - // - // call back functions to use p4est to search - // its own internal data - // - void (*p4estsearchpt)(double *, int *, int *, int *); - void (*check_intersect_p4est)(int *, int *); - - /** basic constructor */ - MeshBlock() { - nv = NULL; - nc = NULL; - x = NULL; - iblank = NULL; - iblank_cell = NULL; - vconn = NULL; - wbcnode = NULL; - obcnode = NULL; - cellRes = NULL; - nodeRes = NULL; - elementBbox = NULL; - elementList = NULL; - adt = NULL; - donorList = NULL; - interpList = NULL; - interp2donor = NULL; - obb = NULL; - nsearch = 0; - isearch = NULL; - tagsearch = NULL; - res_search = NULL; - xsearch = NULL; - donorId = NULL; - xtag = NULL; - adt = NULL; - cancelList = NULL; - userSpecifiedNodeRes = NULL; - userSpecifiedCellRes = NULL; - nfringe = 1; - composite = 0; - mexclude = 3; - nvar = 0; - interptype = 0; - blockcomm = MPI_COMM_NULL; - // new vars - ninterp = ninterp2 = interpListSize = interp2ListSize = 0; - ctag = NULL; - pointsPerCell = NULL; - maxPointsPerCell = 0; - rxyz = NULL; - ntotalPoints = 0; - rst = NULL; - ihigh = 0; - ipoint = 0; - interpList2 = NULL; - picked = NULL; - ctag_cart = NULL; - rxyzCart = NULL; - donorIdCart = NULL; - pickedCart = NULL; - ntotalPointsCart = 0; - nreceptorCellsCart = 0; - ninterpCart = 0; - interpListCartSize = 0; - interpListCart = NULL; - resolutionScale = 1.0; - receptorIdCart = NULL; - searchTol = TOL; - dominanceFlag = 0; - - cellGID = NULL; - iblank_reduced = NULL; - uniform_hex = 0; - check_uniform_hex_flag = 0; - uindx = NULL; - obh = NULL; - invmap = NULL; - icft = NULL; - mapmask = NULL; - }; - - /** basic destructor */ - ~MeshBlock(); - - void preprocess(int use_adaptholemap); - - void tagBoundary(void); - - void tagBoundaryFaces(void); - - void writeGridFile(int bid); - - void writeFlowFile(int bid, double *q, int nvar, int type); - - void setData(TIOGA::MeshBlockInfo *minfo); - - void setData(int btag, int nnodesi, double *xyzi, int *ibli, int nwbci, - int nobci, int *wbcnodei, int *obcnodei, int ntypesi, int *nvi, - int *nci, int **vconni, uint64_t *cell_gid = NULL, - uint64_t *node_gid = NULL); - - void setResolutions(double *nres, double *cres); - - void search(); - void search_uniform_hex(); - void writeOBB(int bid); - - void writeOBB2(OBB *obc, int bid); - - void updateSolnData(int inode, double *qvar, double *q); - - int getNinterp(void) { return ninterp; }; - - void getInterpolatedSolution(int *nints, int *nreals, int **intData, - double **realData, double *q, int nvar, - int interptype); - - void getInterpolatedSolutionAMR(int *nints, int *nreals, int **intData, - double **realData, double *q, int *); - - void checkContainment(int *cellIndex, int adtElement, double *xsearch); - - void getWallBounds(int *mtag, int *existWall, double wbox[6]); - - void markWallBoundary(int *sam, int nx[3], double extents[6]); - - void markBoundaryAdaptiveMap(char nodetype2tag, double extents_lo[3], - double extents_hi[3], level_octant_t *level, - uint8_t *taggedList, uint8_t *tagList); - - void markBoundaryAdaptiveMapSurfaceIntersect( - char nodetype2tag, double extents_lo[3], double extents_hi[3], - level_octant_t *level, uint8_t *taggedList, uint8_t *tagList); - - void markBoundaryAdaptiveMapSurfaceIntersect( - char nodetype2tag, double extents_lo[3], double extents_hi[3], - uint8_t level_id, uint32_t noctants, octant_coordinates_t *octants, - uint8_t *taggedList, uint8_t *tagList); - - void markBoundaryMapSurface(char nodetype2tag, double extents_lo[3], - double extents_hi[3], level_octant_t *level, - uint8_t *taggedList, uint8_t *tagList); - - void getQueryPoints(OBB *obb, int *nints, int **intData, int *nreals, - double **realData); - - void getQueryPoints2(OBB *obb, int *nints, int **intData, int *nreals, - double **realData); + int* iblank; /** < iblank value for each grid node */ + int* iblank_reduced; + int ntotalPointsCart; + double* rxyzCart; + int* donorIdCart; + int donorListLength; + + int nfringe; + int mexclude; + int meshtag; /** < tag of the mesh that this block belongs to */ + int check_uniform_hex_flag; + double resolutionScale; + double searchTol; + int dominanceFlag; /**< if dominanceflag=1: set noderes to tiny number */ + // + // oriented bounding box of this partition + // + OBB* obb; + OBB* obh; + // + int nsearch; /** < number of query points to search in this block */ + int* isearch; /** < index of query points in the remote process */ + int* tagsearch; /** < index of query points in the remote process */ + double* res_search; /** < resolution of search points */ + int* xtag; /** < hash to determine if there are duplicates */ + double* xsearch; /** < coordinates of the query points */ + double* rst; /** < natural coordinates */ + int* donorId; /** < donor indices for those found */ + std::vector + gid_search; /** < Global node ID for the query points */ + int donorCount; + + int myid; /** < global mpi rank */ + int blockcomm_id; /** < mpi rank within this block */ + int blockcomm_numprocs; /** < number of mpi ranks within this blocks */ + MPI_Comm blockcomm; /** < subgroup communicator for this mesh block */ + char composite; /** < mesh block composite body flag */ + char meshMaster; /** < master rank for each body flag: [0] subordinate rank, + [1] master rank */ + double bboxLocalAHM[6]; /** < wall bc node bounding box (without duplicate + obc/wbc nodes) */ + + double* cellRes; /** < resolution for each cell */ + int ntotalPoints; /** total number of extra points to interpolate */ + int ihigh; + int ninterp2; /** < number of interpolants for high-order points */ + int interp2ListSize; + INTERPLIST* interpList2; /** < list for high-interpolation points */ + int ninterpCart; + int interpListCartSize; + INTERPLIST* interpListCart; + int* receptorIdCart; + + int* vconn_ptrs[TIOGA::MeshBlockInfo::max_vertex_types]; + + // + // call back functions to use p4est to search + // its own internal data + // + void (*p4estsearchpt)(double*, int*, int*, int*); + void (*check_intersect_p4est)(int*, int*); + + /** basic constructor */ + MeshBlock() + { + nv = NULL; + nc = NULL; + x = NULL; + iblank = NULL; + iblank_cell = NULL; + vconn = NULL; + wbcnode = NULL; + obcnode = NULL; + cellRes = NULL; + nodeRes = NULL; + elementBbox = NULL; + elementList = NULL; + adt = NULL; + donorList = NULL; + interpList = NULL; + interp2donor = NULL; + obb = NULL; + nsearch = 0; + isearch = NULL; + tagsearch = NULL; + res_search = NULL; + xsearch = NULL; + donorId = NULL; + xtag = NULL; + adt = NULL; + cancelList = NULL; + userSpecifiedNodeRes = NULL; + userSpecifiedCellRes = NULL; + nfringe = 1; + composite = 0; + mexclude = 3; + nvar = 0; + interptype = 0; + blockcomm = MPI_COMM_NULL; + // new vars + ninterp = ninterp2 = interpListSize = interp2ListSize = 0; + ctag = NULL; + pointsPerCell = NULL; + maxPointsPerCell = 0; + rxyz = NULL; + ntotalPoints = 0; + rst = NULL; + ihigh = 0; + ipoint = 0; + interpList2 = NULL; + picked = NULL; + ctag_cart = NULL; + rxyzCart = NULL; + donorIdCart = NULL; + pickedCart = NULL; + ntotalPointsCart = 0; + nreceptorCellsCart = 0; + ninterpCart = 0; + interpListCartSize = 0; + interpListCart = NULL; + resolutionScale = 1.0; + receptorIdCart = NULL; + searchTol = TOL; + dominanceFlag = 0; + + cellGID = NULL; + iblank_reduced = NULL; + uniform_hex = 0; + check_uniform_hex_flag = 0; + uindx = NULL; + obh = NULL; + invmap = NULL; + icft = NULL; + mapmask = NULL; + }; + + /** basic destructor */ + ~MeshBlock(); + + void preprocess(int use_adaptholemap); + + void tagBoundary(void); + + void tagBoundaryFaces(void); + + void writeGridFile(int bid); + + void writeFlowFile(int bid, double* q, int nvar, int type); + + void setData(TIOGA::MeshBlockInfo* minfo); + + void setData( + int btag, + int nnodesi, + double* xyzi, + int* ibli, + int nwbci, + int nobci, + int* wbcnodei, + int* obcnodei, + int ntypesi, + int* nvi, + int* nci, + int** vconni, + uint64_t* cell_gid = NULL, + uint64_t* node_gid = NULL); + + void setResolutions(double* nres, double* cres); + + void search(); + void search_uniform_hex(); + void writeOBB(int bid); + + void writeOBB2(OBB* obc, int bid); + + void updateSolnData(int inode, double* qvar, double* q); + + int getNinterp(void) { return ninterp; }; + + void getInterpolatedSolution( + int* nints, + int* nreals, + int** intData, + double** realData, + double* q, + int nvar, + int interptype); + + void getInterpolatedSolutionAMR( + int* nints, + int* nreals, + int** intData, + double** realData, + double* q, + int*); + + void checkContainment(int* cellIndex, int adtElement, double* xsearch); + + void getWallBounds(int* mtag, int* existWall, double wbox[6]); + + void markWallBoundary(int* sam, int nx[3], double extents[6]); + + void markBoundaryAdaptiveMap( + char nodetype2tag, + double extents_lo[3], + double extents_hi[3], + level_octant_t* level, + uint8_t* taggedList, + uint8_t* tagList); + + void markBoundaryAdaptiveMapSurfaceIntersect( + char nodetype2tag, + double extents_lo[3], + double extents_hi[3], + level_octant_t* level, + uint8_t* taggedList, + uint8_t* tagList); + + void markBoundaryAdaptiveMapSurfaceIntersect( + char nodetype2tag, + double extents_lo[3], + double extents_hi[3], + uint8_t level_id, + uint32_t noctants, + octant_coordinates_t* octants, + uint8_t* taggedList, + uint8_t* tagList); - /** routines that do book keeping */ + void markBoundaryMapSurface( + char nodetype2tag, + double extents_lo[3], + double extents_hi[3], + level_octant_t* level, + uint8_t* taggedList, + uint8_t* tagList); - void getDonorPacket(PACKET *sndPack, int nsend); + void getQueryPoints( + OBB* obb, int* nints, int** intData, int* nreals, double** realData); - void initializeDonorList(); + void getQueryPoints2( + OBB* obb, int* nints, int** intData, int* nreals, double** realData); - void insertAndSort(int pointid, int senderid, int meshtag, int remoteid, - double donorRes, double receptorRes); + /** routines that do book keeping */ - void processDonors(HOLEMAP *holemap, int nmesh, int **donorRecords, - double **receptorResolution, int *nrecords); + void getDonorPacket(PACKET* sndPack, int nsend); - void processDonors(ADAPTIVE_HOLEMAP *holemap, int nmesh, int **donorRecords, - double **receptorResolution, int *nrecords); + void initializeDonorList(); + + void insertAndSort( + int pointid, + int senderid, + int meshtag, + int remoteid, + double donorRes, + double receptorRes); + + void processDonors( + HOLEMAP* holemap, + int nmesh, + int** donorRecords, + double** receptorResolution, + int* nrecords); - void initializeInterpList(int ninterp_input); + void processDonors( + ADAPTIVE_HOLEMAP* holemap, + int nmesh, + int** donorRecords, + double** receptorResolution, + int* nrecords); - void findInterpData(int *recid, int irecord, double receptorRes); + void initializeInterpList(int ninterp_input); - void findInterpListCart(); + void findInterpData(int* recid, int irecord, double receptorRes); - void set_ninterp(int); + void findInterpListCart(); - void getCancellationData(int *nints, int **intData); + void set_ninterp(int); - void cancelDonor(int irecord); + void getCancellationData(int* nints, int** intData); + + void cancelDonor(int irecord); - void getInterpData(int *nrecords, int **intData); + void getInterpData(int* nrecords, int** intData); - void clearIblanks(void); + void clearIblanks(void); - void getStats(int mstat[2]); + void getStats(int mstat[2]); - void setIblanks(int inode); + void setIblanks(int inode); - void getDonorCount(int *dcount, int *fcount); + void getDonorCount(int* dcount, int* fcount); - void getDonorInfo(int *receptors, int *indices, double *frac); + void getDonorInfo(int* receptors, int* indices, double* frac); - void getReceptorInfo(int *receptors); + void getReceptorInfo(int* receptors); - void getReducedOBB(OBB *, double *); - void getReducedOBB2(OBB *, double *); + void getReducedOBB(OBB*, double*); + void getReducedOBB2(OBB*, double*); - void resetCoincident(); - // - // routines for high order connectivity and interpolation - // - void getCellIblanks(void); - void getCellIblanks2(void); - void set_cell_iblank(int *iblank_cell_input) { - iblank_cell = iblank_cell_input; - } - void setcallback(void (*f1)(int *, int *), void (*f2)(int *, int *, double *), - void (*f3)(int *, double *, int *, double *), - void (*f4)(int *, double *, int *, int *, double *, double *, - int *), - void (*f5)(int *, int *, double *, int *, int *, double *)) { - get_nodes_per_cell = f1; - get_receptor_nodes = f2; - donor_inclusion_test = f3; - donor_frac = f4; - convert_to_modal = f5; - } - - void setp4estcallback(void (*f1)(double *, int *, int *, int *), - void (*f2)(int *, int *)) { - p4estsearchpt = f1; - check_intersect_p4est = f2; - } - - void setCompositeFlag(double tol, int dominanceflag) { - composite = 1; - searchTol = tol; - dominanceFlag = dominanceflag; - } - - void writeCellFile(int); - void writeBCnodes(char nodetype2tag, int bodyid); - void getInternalNodes(void); - void getExtraQueryPoints(OBB *obb, int *nints, int **intData, int *nreals, - double **realData); - void processPointDonors(void); - void getInterpolatedSolutionAtPoints(int *nints, int *nreals, int **intData, - double **realData, double *q, int nvar, - int interptype); - void updatePointData(double *q, double *qtmp, int nvar, int interptype); - void outputOrphan(FILE *fp, int i) { - fprintf(fp, "%f %f %f\n", rxyz[3 * i], rxyz[3 * i + 1], rxyz[3 * i + 2]); - } - void clearOrphans(HOLEMAP *holemap, int nmesh, int *itmp); - void clearOrphans(ADAPTIVE_HOLEMAP *holemap, int nmesh, int *itmp); - void getUnresolvedMandatoryReceptors(); - void getCartReceptors(CartGrid *cg, parallelComm *pc); - void fillReceptorDataPtr(CartGrid *cg, int cell_count, int c, int j, int k, - int l, int *pmap, double vol, double *xtm, - bool isNodal, INTEGERLIST2 *&dataPtr); - void setCartIblanks(void); - - // Getters - inline int getMeshTag() const { return meshtag + (1 - BASE); } - inline int getWallFlag() const { return (nwbc > 0); } - - /** - * Get donor packet for multi-block/partition setups - * - */ - void getMBDonorPktSizes(std::vector &, std::vector &); - - void getMBDonorPackets(std::vector &, std::vector &, PACKET *); - - /** Reset interpolation list data structure - * - * Reset the data structures in situations where the performConnectivity - * method is invoked at every timestep when meshes undergo relative motion. - */ - void resetInterpData() { - if (interpList) { - for (int i = 0; i < interpListSize; i++) { - if (interpList[i].inode) - TIOGA_FREE(interpList[i].inode); - if (interpList[i].weights) - TIOGA_FREE(interpList[i].weights); - } - TIOGA_FREE(interpList); + void resetCoincident(); + // + // routines for high order connectivity and interpolation + // + void getCellIblanks(void); + void getCellIblanks2(void); + void set_cell_iblank(int* iblank_cell_input) + { + iblank_cell = iblank_cell_input; + } + void setcallback( + void (*f1)(int*, int*), + void (*f2)(int*, int*, double*), + void (*f3)(int*, double*, int*, double*), + void (*f4)(int*, double*, int*, int*, double*, double*, int*), + void (*f5)(int*, int*, double*, int*, int*, double*)) + { + get_nodes_per_cell = f1; + get_receptor_nodes = f2; + donor_inclusion_test = f3; + donor_frac = f4; + convert_to_modal = f5; } - ninterp = 0; - interpListSize = 0; - } - void reduce_fringes(); - void check_for_uniform_hex(); + void setp4estcallback( + void (*f1)(double*, int*, int*, int*), void (*f2)(int*, int*)) + { + p4estsearchpt = f1; + check_intersect_p4est = f2; + } - void create_hex_cell_map(); + void setCompositeFlag(double tol, int dominanceflag) + { + composite = 1; + searchTol = tol; + dominanceFlag = dominanceflag; + } - int num_var() const { return nvar; } - int &num_var() { return nvar; } + void writeCellFile(int); + void writeBCnodes(char nodetype2tag, int bodyid); + void getInternalNodes(void); + void getExtraQueryPoints( + OBB* obb, int* nints, int** intData, int* nreals, double** realData); + void processPointDonors(void); + void getInterpolatedSolutionAtPoints( + int* nints, + int* nreals, + int** intData, + double** realData, + double* q, + int nvar, + int interptype); + void updatePointData(double* q, double* qtmp, int nvar, int interptype); + void outputOrphan(FILE* fp, int i) + { + fprintf( + fp, "%f %f %f\n", rxyz[3 * i], rxyz[3 * i + 1], rxyz[3 * i + 2]); + } + void clearOrphans(HOLEMAP* holemap, int nmesh, int* itmp); + void clearOrphans(ADAPTIVE_HOLEMAP* holemap, int nmesh, int* itmp); + void getUnresolvedMandatoryReceptors(); + void getCartReceptors(CartGrid* cg, parallelComm* pc); + void fillReceptorDataPtr( + CartGrid* cg, + int cell_count, + int c, + int j, + int k, + int l, + int* pmap, + double vol, + double* xtm, + bool isNodal, + INTEGERLIST2*& dataPtr); + void setCartIblanks(void); + + // Getters + inline int getMeshTag() const { return meshtag + (1 - BASE); } + inline int getWallFlag() const { return (nwbc > 0); } + + /** + * Get donor packet for multi-block/partition setups + * + */ + void getMBDonorPktSizes(std::vector&, std::vector&); + + void getMBDonorPackets(std::vector&, std::vector&, PACKET*); + + /** Reset interpolation list data structure + * + * Reset the data structures in situations where the performConnectivity + * method is invoked at every timestep when meshes undergo relative motion. + */ + void resetInterpData() + { + if (interpList) { + for (int i = 0; i < interpListSize; i++) { + if (interpList[i].inode) TIOGA_FREE(interpList[i].inode); + if (interpList[i].weights) TIOGA_FREE(interpList[i].weights); + } + TIOGA_FREE(interpList); + } + ninterp = 0; + interpListSize = 0; + } + void reduce_fringes(); - const TIOGA::MeshBlockInfo *mesh_info() const { return m_info; } - TIOGA::MeshBlockInfo *mesh_info() { return m_info; } + void check_for_uniform_hex(); - const TIOGA::MeshBlockInfo *d_mesh_info() const { return m_info_device; } - TIOGA::MeshBlockInfo *d_mesh_info() { return m_info_device; } + void create_hex_cell_map(); - void set_interptype(int type) { interptype = type; } - void checkOrphans(void); + int num_var() const { return nvar; } + int& num_var() { return nvar; } - static char overlapping1D(bound_t box1, bound_t box2) { - return ((box1.hi >= box2.lo) && (box2.hi >= box1.lo)); - } + const TIOGA::MeshBlockInfo* mesh_info() const { return m_info; } + TIOGA::MeshBlockInfo* mesh_info() { return m_info; } + + const TIOGA::MeshBlockInfo* d_mesh_info() const { return m_info_device; } + TIOGA::MeshBlockInfo* d_mesh_info() { return m_info_device; } + + void set_interptype(int type) { interptype = type; } + void checkOrphans(void); + + static char overlapping1D(bound_t box1, bound_t box2) + { + return ((box1.hi >= box2.lo) && (box2.hi >= box1.lo)); + } }; /* Mesh Block Complement Rank Data */ diff --git a/src/TiogaMeshInfo.h b/src/TiogaMeshInfo.h index fe3b727..164f732 100644 --- a/src/TiogaMeshInfo.h +++ b/src/TiogaMeshInfo.h @@ -6,73 +6,77 @@ namespace TIOGA { -template struct TiogaView { - T *hptr{nullptr}; - T *dptr{nullptr}; - - size_t sz{0}; - bool host_modified{false}; - bool device_modified{false}; +template +struct TiogaView +{ + T* hptr{nullptr}; + T* dptr{nullptr}; + + size_t sz{0}; + bool host_modified{false}; + bool device_modified{false}; }; /** Representation of an unstructured mesh */ -struct MeshBlockInfo { - static constexpr int max_vertex_types = 4; - using GlobalIDType = uint64_t; +struct MeshBlockInfo +{ + static constexpr int max_vertex_types = 4; + using GlobalIDType = uint64_t; - enum QVarType { ROW = 0, COL }; + enum QVarType { ROW = 0, COL }; - TiogaView wall_ids; - TiogaView overset_ids; - TiogaView num_vert_per_elem; - TiogaView num_cells_per_elem; - TiogaView vertex_conn[max_vertex_types]; + TiogaView wall_ids; + TiogaView overset_ids; + TiogaView num_vert_per_elem; + TiogaView num_cells_per_elem; + TiogaView vertex_conn[max_vertex_types]; - TiogaView xyz; - TiogaView iblank_node; - TiogaView iblank_cell; - TiogaView qnode; + TiogaView xyz; + TiogaView iblank_node; + TiogaView iblank_cell; + TiogaView qnode; - TiogaView cell_gid; - TiogaView node_gid; + TiogaView cell_gid; + TiogaView node_gid; - TiogaView node_res; - TiogaView cell_res; + TiogaView node_res; + TiogaView cell_res; - int meshtag{0}; - int num_nodes{0}; - int num_vars{0}; + int meshtag{0}; + int num_nodes{0}; + int num_vars{0}; - QVarType qtype{ROW}; + QVarType qtype{ROW}; }; /** Representation of an AMReX mesh */ -struct AMRMeshInfo { - // Patch info common to all MPI ranks [ngrids_global] - TiogaView level; - TiogaView mpi_rank; - TiogaView local_id; - TiogaView ilow; - TiogaView ihigh; - TiogaView dims; - TiogaView xlo; - TiogaView dx; - - // Patch data for all patches belonging to this MPI rank - // [ngrids_local] - TiogaView global_idmap; - TiogaView iblank_node; - TiogaView iblank_cell; - TiogaView qcell; - TiogaView qnode; - - int num_ghost{0}; - int ngrids_global{0}; - int ngrids_local{0}; - int nvar_cell{0}; - int nvar_node{0}; +struct AMRMeshInfo +{ + // Patch info common to all MPI ranks [ngrids_global] + TiogaView level; + TiogaView mpi_rank; + TiogaView local_id; + TiogaView ilow; + TiogaView ihigh; + TiogaView dims; + TiogaView xlo; + TiogaView dx; + + // Patch data for all patches belonging to this MPI rank + // [ngrids_local] + TiogaView global_idmap; + TiogaView iblank_node; + TiogaView iblank_cell; + TiogaView qcell; + TiogaView qnode; + + int num_ghost{0}; + int ngrids_global{0}; + int ngrids_local{0}; + int nvar_cell{0}; + int nvar_node{0}; }; } // namespace TIOGA diff --git a/src/bookKeeping.C b/src/bookKeeping.C index ca67636..6f1874b 100644 --- a/src/bookKeeping.C +++ b/src/bookKeeping.C @@ -16,961 +16,921 @@ // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include "codetypes.h" #include "MeshBlock.h" #include "linklist.h" #include "tioga_math.h" #include "tioga_utils.h" -void MeshBlock::getDonorPacket(PACKET *sndPack, int nsend) +void MeshBlock::getDonorPacket(PACKET* sndPack, int nsend) { - int i,k; - int *icount; - int *dcount; - - icount=(int *)malloc(sizeof(int)*nsend); - dcount=(int *)malloc(sizeof(int)*nsend); - // - // count numbers to send first - // - for(i=0;i -1) - { - k=isearch[2*i]; - sndPack[k].nints+=3; - sndPack[k].nreals++; + int i, k; + int* icount; + int* dcount; + + icount = (int*)malloc(sizeof(int) * nsend); + dcount = (int*)malloc(sizeof(int) * nsend); + // + // count numbers to send first + // + for (i = 0; i < nsearch; i++) { + if (donorId[i] > -1) { + k = isearch[2 * i]; + sndPack[k].nints += 3; + sndPack[k].nreals++; } } - for(k=0;k -1) - { - k=isearch[2*i]; - sndPack[k].intData[icount[k]++]=meshtag; // mesh tag - sndPack[k].intData[icount[k]++]=isearch[2*i+1]; // point id - sndPack[k].intData[icount[k]++]=i; // point id on the donor side - sndPack[k].realData[dcount[k]++]=cellRes[donorId[i]]; // donor resolution + for (i = 0; i < nsend; i++) { + icount[i] = dcount[i] = 0; + }; + // + for (i = 0; i < nsearch; i++) { + if (donorId[i] > -1) { + k = isearch[2 * i]; + sndPack[k].intData[icount[k]++] = meshtag; // mesh tag + sndPack[k].intData[icount[k]++] = isearch[2 * i + 1]; // point id + sndPack[k].intData[icount[k]++] = i; // point id on the donor side + sndPack[k].realData[dcount[k]++] = + cellRes[donorId[i]]; // donor resolution } } - TIOGA_FREE(icount); - TIOGA_FREE(dcount); + TIOGA_FREE(icount); + TIOGA_FREE(dcount); } -void MeshBlock::getMBDonorPktSizes -( - std::vector& nints, - std::vector& nreals -) +void MeshBlock::getMBDonorPktSizes( + std::vector& nints, std::vector& nreals) { - for(int i=0; i< nsearch; i++) { - if (donorId[i] > -1) { - int ii = isearch[3*i]; - nints[ii] += 4; - nreals[ii]+=2; + for (int i = 0; i < nsearch; i++) { + if (donorId[i] > -1) { + int ii = isearch[3 * i]; + nints[ii] += 4; + nreals[ii] += 2; + } } - } } -void MeshBlock::getMBDonorPackets -( - std::vector& ixOffset, - std::vector& rxOffset, - PACKET* sndPack -) +void MeshBlock::getMBDonorPackets( + std::vector& ixOffset, std::vector& rxOffset, PACKET* sndPack) { - for(int i=0; idonorData[0]=senderid; - temp1->donorData[1]=meshtagdonor; - temp1->donorData[2]=remoteid; - temp1->donorRes=donorRes; - temp1->receptorRes=receptorRes; - insertInList(&donorList[pointid],temp1); + donorListLength = nnodes; + donorList = (DONORLIST**)malloc(sizeof(DONORLIST*) * donorListLength); + for (i = 0; i < donorListLength; i++) donorList[i] = NULL; } -void MeshBlock::processDonors(HOLEMAP *holemap, int nmesh, int **donorRecords,double **receptorResolution, - int *nrecords) +void MeshBlock::insertAndSort( + int pointid, + int senderid, + int meshtagdonor, + int remoteid, + double donorRes, + double receptorRes) { - int i,j,k,m,n,mm,ii; - int nvert; - DONORLIST *temp; - int *iflag; - int meshtagdonor; - int *mtag,*mtag1; - int iter; - int verbose; - // - // first mark hole points - // - iflag=(int *)malloc(sizeof(int)*nmesh); - // - for(i=0;idonorData[1]-BASE; - iflag[meshtagdonor]=1; - if (verbose) { - TRACEI(meshtagdonor); - TRACED(temp->donorRes); - TRACEI(temp->donorData[0]); - TRACEI(temp->donorData[1]); - TRACEI(temp->donorData[2]); - } - nodeRes[i]=std::max(nodeRes[i],temp->receptorRes); - temp=temp->next; - } - for(j=0;jdonorRes); - if (temp->donorRes < nodeRes[i]) - { - iblank[i]=-temp->donorData[1]; - if (verbose) TRACEI(iblank[i]); - if (verbose) { - TRACEI(temp->donorData[0]); - TRACEI(temp->donorData[1]); - TRACEI(temp->donorData[2]);} - (*nrecords)++; - break; - } - temp=temp->next; - } - } - } - // - // set the records to send back to the donor - // process - // - (*donorRecords)=(int *)malloc(sizeof(int)*3*(*nrecords)); - (*receptorResolution)=(double *)malloc(sizeof(double)*(*nrecords)); - m=0; - k=0; - for(i=0;idonorRes < nodeRes[i]) - { - break; - } - temp=temp->next; - } - //if (temp->donorRes < 0) nodeRes[i]=BIGVALUE; - (*receptorResolution)[k++]=(resolutionScale > 1.0) ? -nodeRes[i]:nodeRes[i]; - (*donorRecords)[m++]=temp->donorData[0]; - (*donorRecords)[m++]=temp->donorData[2]; - (*donorRecords)[m++]=temp->donorData[1]; - if (verbose) { - TRACEI(iblank[i]); - TRACEI(m); - TRACEI((*donorRecords)[m-3]); - TRACEI((*donorRecords)[m-1]); - TRACEI((*donorRecords)[m-2]); - TRACED((*receptorResolution)[k-1]); - } - } - } - // - // release local memory - // - TIOGA_FREE(iflag); + DONORLIST* temp1; + temp1 = (DONORLIST*)malloc(sizeof(DONORLIST)); + temp1->donorData[0] = senderid; + temp1->donorData[1] = meshtagdonor; + temp1->donorData[2] = remoteid; + temp1->donorRes = donorRes; + temp1->receptorRes = receptorRes; + insertInList(&donorList[pointid], temp1); } -void MeshBlock::processDonors(ADAPTIVE_HOLEMAP *holemap,int nmesh, - int **donorRecords,double **receptorResolution, - int *nrecords){ - int i,j,k,m,n,mm,ii; - int nvert; - int meshtagdonor; - int iter; - int verbose; - DONORLIST *temp; - std::vector iflag(nmesh,0); - - /* =================== */ - /* 1. mark hole points */ - /* =================== */ - for(i=0;i hole point - if(verbose) printf("No donor found for %d\n",i); - - for(j=0;jdonorData[1] - BASE; + iflag[meshtagdonor] = 1; + if (verbose) { + TRACEI(meshtagdonor); + TRACED(temp->donorRes); + TRACEI(temp->donorData[0]); + TRACEI(temp->donorData[1]); + TRACEI(temp->donorData[2]); + } + nodeRes[i] = std::max(nodeRes[i], temp->receptorRes); + temp = temp->next; + } + for (j = 0; j < nmesh; j++) { + if (j != (meshtag - BASE) && holemap[j].existWall) { + if (!iflag[j]) + if (checkHoleMap( + &x[3 * i], holemap[j].nx, holemap[j].sam, + holemap[j].extents)) { + iblank[i] = 0; + break; + } + } + } } - } - } else { - /* potential donor cells */ - temp=donorList[i]; - for(j=0;jdonorData[1]-BASE; - iflag[meshtagdonor]=1; + if (!composite) { + for (i = 0; i < nwbc; i++) { + if (iblank[wbcnode[i] - BASE] == HOLE) { + printf( + "----------------------------------------------------------" + "----------\n"); + printf( + "Alarm from process %d : wall node is being tagged as a " + "hole %d %p\n", + myid, wbcnode[i] - BASE, donorList[wbcnode[i] - BASE]); + ii = wbcnode[i] - BASE; + printf( + "xloc=%e %e %e\n", x[3 * ii], x[3 * ii + 1], x[3 * ii + 2]); + printf( + "Computations will continue, but may suffer from accuracy " + "problems\n"); + printf("Please recheck positions of your grids\n"); + printf( + "----------------------------------------------------------" + "----------\n"); + } + } + } + // + // mark mandatory fringes as neighbors (up to nfringe depth) + // of hole points + // + mtag = (int*)malloc(sizeof(int) * nnodes); + mtag1 = (int*)malloc(sizeof(int) * nnodes); + + for (i = 0; i < nnodes; i++) { + mtag[i] = mtag1[i] = 0; + if (iblank[i] == 0) mtag[i] = mtag1[i] = 1; + } + for (iter = 0; iter < nfringe; iter++) { + for (n = 0; n < ntypes; n++) { + nvert = nv[n]; + for (i = 0; i < nc[n]; i++) { + for (m = 0; m < nvert; m++) { + if (mtag[(vconn[n][nvert * i + m] - BASE)] == 1) { + for (mm = 0; mm < nvert; mm++) + if (m != mm && + mtag[vconn[n][nvert * i + mm] - BASE] != 1) + mtag1[vconn[n][nvert * i + mm] - BASE] = 1; + } + } + } + } + for (i = 0; i < nnodes; i++) mtag[i] = mtag1[i]; + } + for (i = 0; i < nnodes; i++) + if (mtag1[i] && iblank[i]) nodeRes[i] = BIGVALUE; + TIOGA_FREE(mtag); + TIOGA_FREE(mtag1); + // + // now find fringes + // + *nrecords = 0; + for (i = 0; i < nnodes; i++) { + verbose = 0; + // if (meshtag==1 && myid==0 && i==76639) verbose=1; + // if (meshtag==2 && i==240304 && myid==1) verbose=1; + // if (meshtag==3 && i==241402 && myid==1) verbose=1; + // if (meshtag==3 && i==34299) verbose=1; if (verbose) { - TRACEI(meshtagdonor); - TRACED(temp->donorRes); - TRACEI(temp->donorData[0]); - TRACEI(temp->donorData[1]); - TRACEI(temp->donorData[2]); + TRACEI(i); + TRACEI(iblank[i]); + TRACED(nodeRes[i]); } - nodeRes[i]=std::max(nodeRes[i],temp->receptorRes); - temp=temp->next; - } - - // loop all bodies that do NOT have a candidate and check if pt is INSIDE/WALL - for(j=0;jdonorRes); + if (temp->donorRes < nodeRes[i]) { + iblank[i] = -temp->donorData[1]; + if (verbose) TRACEI(iblank[i]); + if (verbose) { + TRACEI(temp->donorData[0]); + TRACEI(temp->donorData[1]); + TRACEI(temp->donorData[2]); + } + (*nrecords)++; + break; + } + temp = temp->next; } - } } - } - } - } - - if(!composite){ - for(i=0;i mtag(nnodes,0); - std::vector mtag1(nnodes,0); - - for(i=0;idonorRes < nodeRes[i]) { + break; + } + temp = temp->next; + } + // if (temp->donorRes < 0) nodeRes[i]=BIGVALUE; + (*receptorResolution)[k++] = + (resolutionScale > 1.0) ? -nodeRes[i] : nodeRes[i]; + (*donorRecords)[m++] = temp->donorData[0]; + (*donorRecords)[m++] = temp->donorData[2]; + (*donorRecords)[m++] = temp->donorData[1]; + if (verbose) { + TRACEI(iblank[i]); + TRACEI(m); + TRACEI((*donorRecords)[m - 3]); + TRACEI((*donorRecords)[m - 1]); + TRACEI((*donorRecords)[m - 2]); + TRACED((*receptorResolution)[k - 1]); } - } } - } } - if(iter == (nfringe-1)) break; // skip last copy - for(i=0;i iflag(nmesh, 0); + + /* =================== */ + /* 1. mark hole points */ + /* =================== */ + for (i = 0; i < nnodes; i++) { + iblank[i] = 1; + + verbose = 0; + if (verbose) TRACEI(i); + + if (donorList[i] == NULL) { + // No Donor Cells Found: point is either a field or hole. + // Check the point is in any hole SB --> hole point + if (verbose) printf("No donor found for %d\n", i); + + for (j = 0; j < nmesh; j++) { + if (j != (meshtag - BASE) && holemap[j].existWall) { + int SB_val = checkAdaptiveHoleMap(&x[3 * i], &holemap[j]); + if (SB_val != OUTSIDE_SB) { + iblank[i] = 0; + break; + } + } + } + } else { + /* potential donor cells */ + temp = donorList[i]; + for (j = 0; j < nmesh; j++) iflag[j] = 0; + + // find mesh tags that have a candidate donor cell + while (temp != NULL) { + meshtagdonor = temp->donorData[1] - BASE; + iflag[meshtagdonor] = 1; + + if (verbose) { + TRACEI(meshtagdonor); + TRACED(temp->donorRes); + TRACEI(temp->donorData[0]); + TRACEI(temp->donorData[1]); + TRACEI(temp->donorData[2]); + } + nodeRes[i] = std::max(nodeRes[i], temp->receptorRes); + temp = temp->next; + } - for(i=0;i mtag(nnodes, 0); + std::vector mtag1(nnodes, 0); - while(temp!=NULL){ - if(verbose) TRACED(temp->donorRes); + for (i = 0; i < nnodes; i++) { + if (iblank[i] == 0) mtag[i] = mtag1[i] = 1; + } - if(temp->donorRes < nodeRes[i]){ - iblank[i]=-temp->donorData[1]; + for (iter = 0; iter < nfringe; iter++) { + for (n = 0; n < ntypes; n++) { + nvert = nv[n]; + for (i = 0; i < nc[n]; i++) { + for (m = 0; m < nvert; m++) { + if (mtag[(vconn[n][nvert * i + m] - BASE)] == 1) { + for (mm = 0; mm < nvert; mm++) { + if (m != mm && + mtag[vconn[n][nvert * i + mm] - BASE] != 1) { + mtag1[vconn[n][nvert * i + mm] - BASE] = 1; + } + } + } + } + } + } + if (iter == (nfringe - 1)) break; // skip last copy + for (i = 0; i < nnodes; i++) mtag[i] = mtag1[i]; + } + + for (i = 0; i < nnodes; i++) { + if (mtag1[i] && iblank[i]) nodeRes[i] = BIGVALUE; + } - if(verbose){ + /* =============== */ + /* 3. find fringes */ + /* =============== */ + *nrecords = 0; + for (i = 0; i < nnodes; i++) { + verbose = 0; + if (verbose) { + TRACEI(i); TRACEI(iblank[i]); - TRACEI(temp->donorData[0]); - TRACEI(temp->donorData[1]); - TRACEI(temp->donorData[2]); - } - (*nrecords)++; - break; } - temp=temp->next; - } - } - } - - /* ==================================================== */ - /* 4. set the records to send back to the donor process */ - /* ==================================================== */ - (*donorRecords)=(int *)malloc(sizeof(int)*3*(*nrecords)); - (*receptorResolution)=(double *)malloc(sizeof(double)*(*nrecords)); - - m=k=0; - for(i=0;idonorRes < nodeRes[i]) break; - temp=temp->next; - } - - (*receptorResolution)[k++] = (resolutionScale > 1.0) ? -nodeRes[i]:nodeRes[i]; - (*donorRecords)[m++]=temp->donorData[0]; - (*donorRecords)[m++]=temp->donorData[2]; - (*donorRecords)[m++]=temp->donorData[1]; - - if(verbose){ - TRACEI(iblank[i]); - TRACEI(m); - TRACEI((*donorRecords)[m-3]); - TRACEI((*donorRecords)[m-1]); - TRACEI((*donorRecords)[m-2]); - TRACED((*receptorResolution)[k-1]); - } - } - } -} -void MeshBlock::initializeInterpList(int ninterp_input) -{ - int i; - if (interpList) { - //for(i=0;idonorRes); + + if (temp->donorRes < nodeRes[i]) { + iblank[i] = -temp->donorData[1]; + + if (verbose) { + TRACEI(iblank[i]); + TRACEI(temp->donorData[0]); + TRACEI(temp->donorData[1]); + TRACEI(temp->donorData[2]); + } + (*nrecords)++; + break; + } + temp = temp->next; + } + } + } + /* ==================================================== */ + /* 4. set the records to send back to the donor process */ + /* ==================================================== */ + (*donorRecords) = (int*)malloc(sizeof(int) * 3 * (*nrecords)); + (*receptorResolution) = (double*)malloc(sizeof(double) * (*nrecords)); + + m = k = 0; + for (i = 0; i < nnodes; i++) { + verbose = 0; + if (iblank[i] < 0) { + temp = donorList[i]; + while (temp != NULL) { + if (temp->donorRes < nodeRes[i]) break; + temp = temp->next; + } + + (*receptorResolution)[k++] = + (resolutionScale > 1.0) ? -nodeRes[i] : nodeRes[i]; + (*donorRecords)[m++] = temp->donorData[0]; + (*donorRecords)[m++] = temp->donorData[2]; + (*donorRecords)[m++] = temp->donorData[1]; + + if (verbose) { + TRACEI(iblank[i]); + TRACEI(m); + TRACEI((*donorRecords)[m - 3]); + TRACEI((*donorRecords)[m - 1]); + TRACEI((*donorRecords)[m - 2]); + TRACED((*receptorResolution)[k - 1]); + } + } + } } -void MeshBlock::findInterpData(int *recid,int irecord,double receptorRes2) +void MeshBlock::initializeInterpList(int ninterp_input) { - int i,j,i3,m,n; - int nvert; - int isum; - int procid,pointid,blockid; - double xv[8][3]; - double xp[3]; - double frac[8]; - int inode[8]; - int acceptFlag; - double receptorRes; - int verbose; - int meshtagrecv; - - INTEGERLIST *clist; - // - verbose=0; - //if (myid==3 && irecord==4878 && meshtag==2) verbose=1; - //if (myid==63 && irecord==3224) verbose=1; - //if (myid==1 && irecord==158192 && meshtag==1) verbose=1; - receptorRes=fabs(receptorRes2); - procid=isearch[3*irecord]; - pointid=isearch[3*irecord+1]; - blockid=isearch[3*irecord+2]; - meshtagrecv=tagsearch[irecord]; - if (verbose) { - TRACEI(procid); - TRACEI(pointid); - TRACED(receptorRes); - TRACEI(meshtagrecv); - } - i3=3*irecord; - xp[0]=xsearch[i3]; - xp[1]=xsearch[i3+1]; - xp[2]=xsearch[i3+2]; - // - isum=0; - for(n=0;n 0.0) - { - if (nodeRes[inode[m]]==BIGVALUE) acceptFlag=0; - if (abs(iblank[inode[m]])==meshtagrecv) acceptFlag=0; + int i; + if (interpList) { + // for(i=0;inext !=NULL) clist=clist->next; - // - for(m=0;minode=inode[m]; - clist->next=NULL; - cancelList=clist; - } - else - { - clist->next=(INTEGERLIST *)malloc(sizeof(INTEGERLIST)); - clist->next->inode=inode[m]; - clist->next->next=NULL; - clist=clist->next; - } - ncancel++; - } - } - } - // - computeNodalWeights(xv,xp,frac,nvert); - // - interp2donor[irecord]=*recid; - interpList[*recid].cancel=0; - interpList[*recid].nweights=nvert; - interpList[*recid].receptorInfo[0]=procid; - interpList[*recid].receptorInfo[1]=pointid; - interpList[*recid].receptorInfo[2]=blockid; - if (verbose) { - TRACEI(*recid); - TRACEI(interpList[*recid].receptorInfo[0]); - TRACEI(interpList[*recid].receptorInfo[1]); - } - interpList[*recid].inode=(int *)malloc(sizeof(int)*(nvert+1)); - interpList[*recid].weights=(double *)malloc(sizeof(double)*(nvert+1)); - for(m=0;m 1.2) { - TRACEI(myid); - TRACEI(irecord); - TRACEI(meshtag); - TRACEI(donorId[irecord]); - TRACED(frac[m]); - int ierr; - MPI_Abort(MPI_COMM_WORLD,ierr); - } - } - interpList[*recid].inode[m]=donorId[irecord]; - interpList[*recid].weights[m]=0.0; - if (acceptFlag==0 && receptorRes!=BIGVALUE) interpList[*recid].cancel=1; - (*recid)++; + TIOGA_FREE(interpList); + } + ninterp = ninterp_input; + interpListSize = ninterp_input; + interpList = (INTERPLIST*)malloc(sizeof(INTERPLIST) * interpListSize); + for (i = 0; i < interpListSize; i++) { + interpList[i].inode = NULL; + interpList[i].weights = NULL; + } + if (cancelList) deallocateLinkList2(cancelList); + cancelList = NULL; + ncancel = 0; + if (interp2donor) TIOGA_FREE(interp2donor); + interp2donor = (int*)malloc(sizeof(int) * nsearch); + for (i = 0; i < nsearch; i++) interp2donor[i] = -1; } -void MeshBlock::set_ninterp(int ninterp_input) +void MeshBlock::findInterpData(int* recid, int irecord, double receptorRes2) { - ninterp=ninterp_input; + int i, j, i3, m, n; + int nvert; + int isum; + int procid, pointid, blockid; + double xv[8][3]; + double xp[3]; + double frac[8]; + int inode[8]; + int acceptFlag; + double receptorRes; + int verbose; + int meshtagrecv; + + INTEGERLIST* clist; + // + verbose = 0; + // if (myid==3 && irecord==4878 && meshtag==2) verbose=1; + // if (myid==63 && irecord==3224) verbose=1; + // if (myid==1 && irecord==158192 && meshtag==1) verbose=1; + receptorRes = fabs(receptorRes2); + procid = isearch[3 * irecord]; + pointid = isearch[3 * irecord + 1]; + blockid = isearch[3 * irecord + 2]; + meshtagrecv = tagsearch[irecord]; + if (verbose) { + TRACEI(procid); + TRACEI(pointid); + TRACED(receptorRes); + TRACEI(meshtagrecv); + } + i3 = 3 * irecord; + xp[0] = xsearch[i3]; + xp[1] = xsearch[i3 + 1]; + xp[2] = xsearch[i3 + 2]; + // + isum = 0; + for (n = 0; n < ntypes; n++) { + isum += nc[n]; + if (donorId[irecord] < isum) { + i = donorId[irecord] - (isum - nc[n]); + break; + } + } + nvert = nv[n]; + acceptFlag = 1; + if (verbose) TRACEI(donorId[irecord]) + if (verbose) TRACEI(n) + if (verbose) TRACEI(nvert) + if (verbose) TRACEI(i) + if (verbose) TRACED(nodeRes[241291]); + for (m = 0; m < nvert; m++) { + inode[m] = vconn[n][nvert * i + m] - BASE; + if (verbose) TRACEI(inode[m]); + if (verbose) TRACEI(iblank[inode[m]]) + if (verbose) TRACED(nodeRes[inode[m]]) + i3 = 3 * inode[m]; + if (iblank[inode[m]] <= 0 && receptorRes2 > 0.0) { + if (nodeRes[inode[m]] == BIGVALUE) acceptFlag = 0; + if (abs(iblank[inode[m]]) == meshtagrecv) acceptFlag = 0; + } + for (j = 0; j < 3; j++) xv[m][j] = x[i3 + j]; + } + // + if (verbose) TRACEI(acceptFlag); + if (receptorRes == BIGVALUE && resolutionScale == 1.0) { + clist = cancelList; + // + // go to the end of the list + // + if (clist != NULL) + while (clist->next != NULL) clist = clist->next; + // + for (m = 0; m < nvert; m++) { + verbose = 0; + inode[m] = vconn[n][nvert * i + m] - BASE; + // if (myid==763 && inode[m]==9515) verbose=1; + // if (myid==1 && meshtag==2 && inode[m]==240304) verbose=1; + if (verbose) TRACEI(inode[m]); + if (verbose) TRACED(nodeRes[inode[m]]); + if (verbose) { + TRACEI(procid); + TRACEI(pointid); + TRACED(receptorRes); + TRACEI(meshtagrecv); + TRACEI(irecord); + TRACEI(donorId[irecord]); + } + if (iblank[inode[m]] <= 0 && nodeRes[inode[m]] != BIGVALUE) { + if (iblank[inode[m]] < 0) iblank[inode[m]] = 1; + if (clist == NULL) { + clist = (INTEGERLIST*)malloc(sizeof(INTEGERLIST)); + clist->inode = inode[m]; + clist->next = NULL; + cancelList = clist; + } else { + clist->next = (INTEGERLIST*)malloc(sizeof(INTEGERLIST)); + clist->next->inode = inode[m]; + clist->next->next = NULL; + clist = clist->next; + } + ncancel++; + } + } + } + // + computeNodalWeights(xv, xp, frac, nvert); + // + interp2donor[irecord] = *recid; + interpList[*recid].cancel = 0; + interpList[*recid].nweights = nvert; + interpList[*recid].receptorInfo[0] = procid; + interpList[*recid].receptorInfo[1] = pointid; + interpList[*recid].receptorInfo[2] = blockid; + if (verbose) { + TRACEI(*recid); + TRACEI(interpList[*recid].receptorInfo[0]); + TRACEI(interpList[*recid].receptorInfo[1]); + } + interpList[*recid].inode = (int*)malloc(sizeof(int) * (nvert + 1)); + interpList[*recid].weights = (double*)malloc(sizeof(double) * (nvert + 1)); + for (m = 0; m < nvert; m++) { + interpList[*recid].inode[m] = inode[m]; + interpList[*recid].weights[m] = frac[m]; + if (frac[m] < -0.2 || frac[m] > 1.2) { + TRACEI(myid); + TRACEI(irecord); + TRACEI(meshtag); + TRACEI(donorId[irecord]); + TRACED(frac[m]); + int ierr; + MPI_Abort(MPI_COMM_WORLD, ierr); + } + } + interpList[*recid].inode[m] = donorId[irecord]; + interpList[*recid].weights[m] = 0.0; + if (acceptFlag == 0 && receptorRes != BIGVALUE) + interpList[*recid].cancel = 1; + (*recid)++; } -void MeshBlock::getCancellationData(int *nrecords,int **intData) +void MeshBlock::set_ninterp(int ninterp_input) { ninterp = ninterp_input; } + +void MeshBlock::getCancellationData(int* nrecords, int** intData) { - int i; - int inode; - INTEGERLIST *clist; - *nrecords=ncancel; - if (ncancel > 0) - { - (*intData)=(int *)malloc(sizeof(int)*(*nrecords)*3); - i=0; - for(clist=cancelList;clist!=NULL;clist=clist->next) - { - inode=clist->inode; - if (donorList[inode]!=NULL) { - (*intData)[i++]=donorList[inode]->donorData[0]; - (*intData)[i++]=donorList[inode]->donorData[2]; - (*intData)[i++]=donorList[inode]->donorData[1]; - } - } - *nrecords=i/3; + int i; + int inode; + INTEGERLIST* clist; + *nrecords = ncancel; + if (ncancel > 0) { + (*intData) = (int*)malloc(sizeof(int) * (*nrecords) * 3); + i = 0; + for (clist = cancelList; clist != NULL; clist = clist->next) { + inode = clist->inode; + if (donorList[inode] != NULL) { + (*intData)[i++] = donorList[inode]->donorData[0]; + (*intData)[i++] = donorList[inode]->donorData[2]; + (*intData)[i++] = donorList[inode]->donorData[1]; + } + } + *nrecords = i / 3; } } void MeshBlock::cancelDonor(int irecord) { - int iptr; - iptr=interp2donor[irecord]; - if (iptr > -1) interpList[iptr].cancel=1; + int iptr; + iptr = interp2donor[irecord]; + if (iptr > -1) interpList[iptr].cancel = 1; } void MeshBlock::resetCoincident(void) { - int i,iptr; - int *ireset; - - ireset=(int *)malloc(sizeof(int)*nsearch); - for(i=0;i -1) { - ireset[xtag[i]]=std::min(ireset[xtag[i]],interpList[iptr].cancel); - } - } - for(i=0;i -1) { - if (interpList[iptr].cancel==1) { - interpList[iptr].cancel=ireset[xtag[i]]; - } - } - } - TIOGA_FREE(ireset); + int i, iptr; + int* ireset; + + ireset = (int*)malloc(sizeof(int) * nsearch); + for (i = 0; i < nsearch; i++) ireset[i] = 1; + + for (i = 0; i < nsearch; i++) { + iptr = interp2donor[i]; + if (iptr > -1) { + ireset[xtag[i]] = + std::min(ireset[xtag[i]], interpList[iptr].cancel); + } + } + for (i = 0; i < nsearch; i++) { + iptr = interp2donor[i]; + if (iptr > -1) { + if (interpList[iptr].cancel == 1) { + interpList[iptr].cancel = ireset[xtag[i]]; + } + } + } + TIOGA_FREE(ireset); } -void MeshBlock::getInterpData(int *nrecords, int **intData) +void MeshBlock::getInterpData(int* nrecords, int** intData) { - int i,k; - // - *nrecords=0; - for(i=0;i 0 ? iblank[i]:0; - ibltmp=(int *)malloc(sizeof(int)*nnodes); - // - // make sure only partial iblank=1 + iblank=-1 - // cell nodes are tagged - // - //for(n=0;n 0 ? iblank[i] : 0; + ibltmp = (int*)malloc(sizeof(int) * nnodes); + // + // make sure only partial iblank=1 + iblank=-1 + // cell nodes are tagged + // + // for(n=0;n 0 && ncount < nvert) { + for (m = 0; m < nvert; m++) + if (ibltmp[inode[m]] == 0 && iblank[inode[m]] < 0) + ibltmp[inode[m]] = iblank[inode[m]]; + } } - if (ncount > 0 && ncount < nvert) { - for(m=0;minode=i; - clist->next=NULL; - cancelList=clist; - } - else - { - clist->next=(INTEGERLIST *)malloc(sizeof(INTEGERLIST)); - clist->next->inode=i; - clist->next->next=NULL; - clist=clist->next; - } - ncancel++; - } - } - - // int norph=0; - // for(n=0;ninode = i; + clist->next = NULL; + cancelList = clist; + } else { + clist->next = (INTEGERLIST*)malloc(sizeof(INTEGERLIST)); + clist->next->inode = i; + clist->next->next = NULL; + clist = clist->next; + } + ncancel++; + } + } + // int norph=0; + // for(n=0;n 1) { - // - // find the dimension to create the cut - // - dimcut=(level%ndim); - // - // collect coordinates along the dimension dimcut - // - for(i=0;i 0) - { - adtIntegers[4*parent+side]=elementsAvailable[nleft-1]; - } - parentToChild=*adtCount; - // - // build the left side of the tree - // - if (nleft > 1) { - buildADTrecursion(coord,adtReals,adtWork,adtIntegers,elementsAvailable, - adtCount,1,parentToChild,level+1,ndim,nelem,nleft-1); - } - // - // build the right side of the tree - // - buildADTrecursion(coord,adtReals,adtWork,adtIntegers,&(elementsAvailable[nleft]), - adtCount,2,parentToChild,level+1,ndim,nelem,nav-nleft); - } - else if (nav==1) { - (*adtCount)++; - ii=4*(*adtCount); - jj=ndim*(*adtCount); - adtIntegers[ii]=elementsAvailable[0]; - adtIntegers[ii+1]=-1; - adtIntegers[ii+2]=-1; - adtIntegers[ii+3]=-1; - for(j=0;j 0) { - adtIntegers[4*parent+side]=elementsAvailable[0]; + int nd = ndim / 2; + double coordmid; + int i, j; + int dimcut; + int nleft; + int ii, iip, jj, jjp; + int parentToChild; + + if (nav > 1) { + // + // find the dimension to create the cut + // + dimcut = (level % ndim); + // + // collect coordinates along the dimension dimcut + // + for (i = 0; i < nav; i++) + adtWork[i] = coord[ndim * elementsAvailable[i] + dimcut]; + // + // reorder elements with nleft elements to + // the left of median of adtWork + // + // Should be possible to do this in C++ but it doesn't sort exactly like + // Fortran std::nth_element(elementsAvailable, elementsAvailable + + // nleft, + // elementsAvailable + nav, [&](const int a, const int + // b) { + // return (adtWork[a] < adtWork[b]); + // }); + // However, we currently perform the previous Fortran sort routine + // verbatim + median(elementsAvailable, adtWork, nav, coordmid); + nleft = (nav + 1) / 2; + (*adtCount)++; + ii = (*adtCount) * 4; + adtIntegers[ii] = elementsAvailable[nleft - 1]; + adtIntegers[ii + 1] = -1; + adtIntegers[ii + 2] = -1; + adtIntegers[ii + 3] = -1; + // + // find minimum and maximum bounds of the elements + // contained in this leaf + // + for (i = 0; i < nd; i++) { + adtReals[ndim * (*adtCount) + i] = BIGVALUE; + adtReals[ndim * (*adtCount) + i + nd] = -BIGVALUE; + } + // + for (i = 0; i < nav; i++) + for (j = 0; j < nd; j++) { + ii = ndim * (*adtCount) + j; + iip = ii + nd; + jj = ndim * elementsAvailable[i] + j; + jjp = jj + nd; + // + adtReals[ii] = std::min(adtReals[ii], coord[jj]); + adtReals[iip] = std::max(adtReals[iip], coord[jjp]); + } + // + // specify that the new element is the child of parent + // unless root + // + if (side > 0) { + adtIntegers[4 * parent + side] = elementsAvailable[nleft - 1]; + } + parentToChild = *adtCount; + // + // build the left side of the tree + // + if (nleft > 1) { + buildADTrecursion( + coord, adtReals, adtWork, adtIntegers, elementsAvailable, + adtCount, 1, parentToChild, level + 1, ndim, nelem, nleft - 1); + } + // + // build the right side of the tree + // + buildADTrecursion( + coord, adtReals, adtWork, adtIntegers, &(elementsAvailable[nleft]), + adtCount, 2, parentToChild, level + 1, ndim, nelem, nav - nleft); + } else if (nav == 1) { + (*adtCount)++; + ii = 4 * (*adtCount); + jj = ndim * (*adtCount); + adtIntegers[ii] = elementsAvailable[0]; + adtIntegers[ii + 1] = -1; + adtIntegers[ii + 2] = -1; + adtIntegers[ii + 3] = -1; + for (j = 0; j < ndim; j++) + adtReals[jj + j] = coord[ndim * elementsAvailable[0] + j]; + if (side > 0) { + adtIntegers[4 * parent + side] = elementsAvailable[0]; + } } - } } diff --git a/src/buildADTrecursion.h b/src/buildADTrecursion.h index 1925291..3c0851e 100644 --- a/src/buildADTrecursion.h +++ b/src/buildADTrecursion.h @@ -1,7 +1,16 @@ #ifndef BUILDADTRECURSION_H #define BUILDADTRECURSION_H -void buildADTrecursion(double *coord, double *adtReals, double *adtWork, - int *adtIntegers, int *elementsAvailable, int *adtCount, - int side, int parent, int level, int ndim, int nelem, - int nav); +void buildADTrecursion( + double* coord, + double* adtReals, + double* adtWork, + int* adtIntegers, + int* elementsAvailable, + int* adtCount, + int side, + int parent, + int level, + int ndim, + int nelem, + int nav); #endif diff --git a/src/cartOps.C b/src/cartOps.C index b485f13..041639c 100644 --- a/src/cartOps.C +++ b/src/cartOps.C @@ -16,7 +16,7 @@ // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include "codetypes.h" #include "MeshBlock.h" #include "tioga_math.h" @@ -26,411 +26,363 @@ void MeshBlock::setCartIblanks(void) { - int i,j,m,icount; - if (ihigh) - { - m=0; - // - for(i=0;i=BIGVALUE) fcount++; - } - if (fcount==nvert && iblank_cell[k]==1) - { - iflag[k]=1; - } - k++; - } - } - // - if (ctag_cart!=NULL) TIOGA_FREE(ctag_cart); - ctag_cart=(int *)malloc(sizeof(int)*ncells); - nreceptorCellsCart=0; - for(i=0;i= BIGVALUE) fcount++; + } + if (fcount == nvert && iblank_cell[k] == 1) { + iflag[k] = 1; + } + k++; + } + } + // + if (ctag_cart != NULL) TIOGA_FREE(ctag_cart); + ctag_cart = (int*)malloc(sizeof(int) * ncells); + nreceptorCellsCart = 0; + for (i = 0; i < ncells; i++) + if (iflag[i] == -1) ctag_cart[nreceptorCellsCart++] = i + 1; - if (pointsPerCell!=NULL) TIOGA_FREE(pointsPerCell); - pointsPerCell=(int *)malloc(sizeof(int)*nreceptorCellsCart); - // - maxPointsPerCell=0; - ntotalPointsCart=0; - // - for(i=0;i=BIGVALUE && iblank[i]==1) - { - pickedCart[i]=1; - ntotalPointsCart++; - } - } - if (rxyzCart !=NULL) TIOGA_FREE(rxyzCart); - if (donorIdCart !=NULL) TIOGA_FREE(donorIdCart); - if (receptorIdCart !=NULL) TIOGA_FREE(receptorIdCart); - rxyzCart=(double *)malloc(sizeof(double)*ntotalPointsCart*3); - donorIdCart=(int *)malloc(sizeof(int)*ntotalPointsCart); - receptorIdCart=(int*)malloc(sizeof(int)*ntotalPointsCart); - m=0; - k=0; - for(i=0;i= BIGVALUE && iblank[i] == 1) { + pickedCart[i] = 1; + ntotalPointsCart++; + } + } + if (rxyzCart != NULL) TIOGA_FREE(rxyzCart); + if (donorIdCart != NULL) TIOGA_FREE(donorIdCart); + if (receptorIdCart != NULL) TIOGA_FREE(receptorIdCart); + rxyzCart = (double*)malloc(sizeof(double) * ntotalPointsCart * 3); + donorIdCart = (int*)malloc(sizeof(int) * ntotalPointsCart); + receptorIdCart = (int*)malloc(sizeof(int) * ntotalPointsCart); + m = 0; + k = 0; + for (i = 0; i < nnodes; i++) + if (pickedCart[i]) { + receptorIdCart[k++] = i; + i3 = 3 * i; + for (j = 0; j < 3; j++) rxyzCart[m++] = x[i3 + j]; + } } - } -void MeshBlock::writeOBB2(OBB * obc, int bid) +void MeshBlock::writeOBB2(OBB* obc, int bid) { - FILE *fp; - char intstring[12]; - char fname[80]; - int l,k,j,m,il,ik,ij; - REAL xx[3]; + FILE* fp; + char intstring[12]; + char fname[80]; + int l, k, j, m, il, ik, ij; + REAL xx[3]; - sprintf(intstring,"%d",100000+bid); - sprintf(fname,"cbox%s.dat",&(intstring[1])); - fp=fopen(fname,"w"); - fprintf(fp,"TITLE =\"Box file\"\n"); - fprintf(fp,"VARIABLES=\"X\",\"Y\",\"Z\"\n"); - fprintf(fp,"ZONE T=\"VOL_MIXED\",N=%d E=%d ET=BRICK, F=FEPOINT\n",8, - 1); + snprintf(intstring, sizeof(intstring), "%d", 100000 + bid); + snprintf(fname, sizeof(fname), "cbox%s.dat", &(intstring[1])); + fp = fopen(fname, "w"); + fprintf(fp, "TITLE =\"Box file\"\n"); + fprintf(fp, "VARIABLES=\"X\",\"Y\",\"Z\"\n"); + fprintf(fp, "ZONE T=\"VOL_MIXED\",N=%d E=%d ET=BRICK, F=FEPOINT\n", 8, 1); - for(l=0;l<2;l++) - { - il=2*(l%2)-1; - for(k=0;k<2;k++) - { - ik=2*(k%2)-1; - for(j=0;j<2;j++) - { - ij=2*(j%2)-1; - xx[0]=xx[1]=xx[2]=0; - for(m=0;m<3;m++) - xx[m]=obc->xc[m]+ij*obc->vec[0][m]*obc->dxc[0] - +ik*obc->vec[1][m]*obc->dxc[1] - +il*obc->vec[2][m]*obc->dxc[2]; - fprintf(fp,"%f %f %f\n",xx[0],xx[1],xx[2]); - } - } + for (l = 0; l < 2; l++) { + il = 2 * (l % 2) - 1; + for (k = 0; k < 2; k++) { + ik = 2 * (k % 2) - 1; + for (j = 0; j < 2; j++) { + ij = 2 * (j % 2) - 1; + xx[0] = xx[1] = xx[2] = 0; + for (m = 0; m < 3; m++) + xx[m] = obc->xc[m] + ij * obc->vec[0][m] * obc->dxc[0] + + ik * obc->vec[1][m] * obc->dxc[1] + + il * obc->vec[2][m] * obc->dxc[2]; + fprintf(fp, "%f %f %f\n", xx[0], xx[1], xx[2]); + } + } } - fprintf(fp,"1 2 4 3 5 6 8 7\n"); - fprintf(fp,"%e %e %e\n",obc->xc[0],obc->xc[1],obc->xc[2]); - for(k=0;k<3;k++) - fprintf(fp,"%e %e %e\n",obc->vec[0][k],obc->vec[1][k],obc->vec[2][k]); - fprintf(fp,"%e %e %e\n",obc->dxc[0],obc->dxc[1],obc->dxc[2]); - fclose(fp); + fprintf(fp, "1 2 4 3 5 6 8 7\n"); + fprintf(fp, "%e %e %e\n", obc->xc[0], obc->xc[1], obc->xc[2]); + for (k = 0; k < 3; k++) + fprintf( + fp, "%e %e %e\n", obc->vec[0][k], obc->vec[1][k], obc->vec[2][k]); + fprintf(fp, "%e %e %e\n", obc->dxc[0], obc->dxc[1], obc->dxc[2]); + fclose(fp); } - void MeshBlock::findInterpListCart(void) { - int irecord,i3,i,j,n,m; - double xp[3]; - double xv[8][3]; - double frac[8]; - int inode[8]; - int nvert; - int isum,interpCount; - int procid,pointid,localid; + int irecord, i3, i, j, n, m; + double xp[3]; + double xv[8][3]; + double frac[8]; + int inode[8]; + int nvert; + int isum, interpCount; + int procid, pointid, localid; - if (interpListCart) - { - for(i=0;i 0) { + tmpint = (int*)malloc(sizeof(int) * 3 * (*nints)); + tmpreal = (double*)malloc(sizeof(double) * (*nreals)); + for (i = 0; i < (*nints) * 3; i++) tmpint[i] = (*intData)[i]; + for (i = 0; i < (*nreals); i++) tmpreal[i] = (*realData)[i]; + // + TIOGA_FREE((*intData)); + TIOGA_FREE((*realData)); // didn't free this before ?? + // } - for(i=0;i 0) - { - tmpint=(int *)malloc(sizeof(int)*3*(*nints)); - tmpreal=(double *)malloc(sizeof(double)*(*nreals)); - for(i=0;i<(*nints)*3;i++) tmpint[i]=(*intData)[i]; - for(i=0;i<(*nreals);i++) tmpreal[i]=(*realData)[i]; - // - TIOGA_FREE((*intData)); - TIOGA_FREE((*realData)); // didn't free this before ?? - // - } - (*nints)+=interpCount; - (*nreals)+=(interpCount*nvar); - (*intData)=(int *)malloc(sizeof(int)*3*(*nints)); - (*realData)=(double *)malloc(sizeof(double)*(*nreals)); - if (nintold > 0) - { - for(i=0;i 1.0+TOL) { - TRACED(weight); - printf("warning: weights are not convex 3\n"); - } - for(k=0;k 1.0+TOL) { - TRACED(weight); - printf("warning: weights are not convex 4\n"); - } - for(k=0;k 0) { + for (i = 0; i < nintold * 3; i++) (*intData)[i] = tmpint[i]; + for (i = 0; i < nrealold; i++) (*realData)[i] = tmpreal[i]; + TIOGA_FREE(tmpint); + TIOGA_FREE(tmpreal); } - else if (interptype==COLUMN) - { - for(i=0;i 1.0 + TOL) { + TRACED(weight); + printf("warning: weights are not convex 3\n"); + } + for (k = 0; k < nvar; k++) + qq[k] += q[inode * nvar + k] * weight; + } + (*intData)[icount++] = sndMap[interpList[i].receptorInfo[0]]; + (*intData)[icount++] = -1 - interpList[i].receptorInfo[2]; + (*intData)[icount++] = interpList[i].receptorInfo[1]; + for (k = 0; k < nvar; k++) (*realData)[dcount++] = qq[k]; + } + } + for (i = 0; i < ninterpCart; i++) { + if (!interpListCart[i].cancel) { + for (k = 0; k < nvar; k++) qq[k] = 0; + for (m = 0; m < interpListCart[i].nweights; m++) { + inode = interpListCart[i].inode[m]; + weight = interpListCart[i].weights[m]; + if (weight < -TOL || weight > 1.0 + TOL) { + TRACED(weight); + printf("warning: weights are not convex 4\n"); + } + for (k = 0; k < nvar; k++) { + qq[k] += q[inode * nvar + k] * weight; + // if (myid==0 && dcount==0) { + // printf("nsu3d/interp: %d %d %f + // %f\n",k,inode,weight,q[inode*nvar+k]); + // } + } + } + // writeqnode_(&myid,qq,&nvar); + (*intData)[icount++] = interpListCart[i].receptorInfo[0]; + (*intData)[icount++] = 1 + interpListCart[i].receptorInfo[2]; + (*intData)[icount++] = interpListCart[i].receptorInfo[1]; + for (k = 0; k < nvar; k++) (*realData)[dcount++] = qq[k]; + } + } + } else if (interptype == COLUMN) { + for (i = 0; i < ninterp; i++) { + if (!interpList[i].cancel) { + for (k = 0; k < nvar; k++) qq[k] = 0; + for (m = 0; m < interpList[i].nweights; m++) { + inode = interpList[i].inode[m]; + weight = interpList[i].weights[m]; + for (k = 0; k < nvar; k++) + qq[k] += q[k * nnodes + inode] * weight; + } + (*intData)[icount++] = sndMap[interpList[i].receptorInfo[0]]; + (*intData)[icount++] = -1 - interpList[i].receptorInfo[2]; + (*intData)[icount++] = interpList[i].receptorInfo[1]; + for (k = 0; k < nvar; k++) (*realData)[dcount++] = qq[k]; + } + } + for (i = 0; i < ninterpCart; i++) { + if (!interpListCart[i].cancel) { + for (k = 0; k < nvar; k++) qq[k] = 0; + for (m = 0; m < interpListCart[i].nweights; m++) { + inode = interpListCart[i].inode[m]; + weight = interpListCart[i].weights[m]; + for (k = 0; k < nvar; k++) + qq[k] += q[k * nnodes + inode] * weight; + } + (*intData)[icount++] = interpListCart[i].receptorInfo[0]; + (*intData)[icount++] = 1 + interpListCart[i].receptorInfo[2]; + (*intData)[icount++] = interpListCart[i].receptorInfo[1]; + for (k = 0; k < nvar; k++) (*realData)[dcount++] = qq[k]; + } + } } - if (qq) TIOGA_FREE(qq); + if (qq) TIOGA_FREE(qq); } diff --git a/src/cartUtils.h b/src/cartUtils.h index 0a93434..6adb2cb 100644 --- a/src/cartUtils.h +++ b/src/cartUtils.h @@ -22,25 +22,28 @@ namespace cart_utils { // Q[nq,nZ+2*nf,nY+2*nf,nX+2*nf]--> C++ Cell storage -inline int get_cell_index(int nX, int nY, int nf, int i, int j, int k) { - return (nY + 2 * nf) * (nX + 2 * nf) * (k + nf) + (nX + 2 * nf) * (j + nf) + - (i + nf); +inline int get_cell_index(int nX, int nY, int nf, int i, int j, int k) +{ + return (nY + 2 * nf) * (nX + 2 * nf) * (k + nf) + (nX + 2 * nf) * (j + nf) + + (i + nf); } // Q[nq,nZ+1+2*nf,nY+1+2*nf,nX+1+2*nf]--> C++ node storage -inline int get_node_index(int nX, int nY, int nf, int i, int j, int k) { - return (nY + 1 + 2 * nf) * (nX + 1 + 2 * nf) * (k + nf) + - (nX + 1 + 2 * nf) * (j + nf) + (i + nf); +inline int get_node_index(int nX, int nY, int nf, int i, int j, int k) +{ + return (nY + 1 + 2 * nf) * (nX + 1 + 2 * nf) * (k + nf) + + (nX + 1 + 2 * nf) * (j + nf) + (i + nf); } // Q[nq,nZ+1+2*nf,nY+1+2*nf,nX+1+2*nf]--> C++ node storage // for arrays with both node and cell indices, // node index is assumed to follow cell index -inline int get_concatenated_node_index(int nX, int nY, int nZ, int nf, int i, - int j, int k) { - return (nY + 1 + 2 * nf) * (nX + 1 + 2 * nf) * (k + nf) + - (nX + 1 + 2 * nf) * (j + nf) + (i + nf) + - (nX + 2 * nf) * (nY + 2 * nf) * (nZ + 2 * nf); +inline int +get_concatenated_node_index(int nX, int nY, int nZ, int nf, int i, int j, int k) +{ + return (nY + 1 + 2 * nf) * (nX + 1 + 2 * nf) * (k + nf) + + (nX + 1 + 2 * nf) * (j + nf) + (i + nf) + + (nX + 2 * nf) * (nY + 2 * nf) * (nZ + 2 * nf); } } // namespace cart_utils diff --git a/src/cellVolume.C b/src/cellVolume.C index 1551800..502d8cf 100644 --- a/src/cellVolume.C +++ b/src/cellVolume.C @@ -1,32 +1,85 @@ #include "cellVolume.h" // Converted verbatim from cellVolume.f90 -double scalarProduct(double a1, double a2, double a3, double b1, double b2, double b3, double c1, double c2, double c3) { - return (a1 * b2 * c3 - a1 * b3 * c2 + a2 * b3 * c1 - a2 * b1 * c3 + a3 * b1 * c2 - a3 * b2 * c1); +double scalarProduct( + double a1, + double a2, + double a3, + double b1, + double b2, + double b3, + double c1, + double c2, + double c3) +{ + return ( + a1 * b2 * c3 - a1 * b3 * c2 + a2 * b3 * c1 - a2 * b1 * c3 + + a3 * b1 * c2 - a3 * b2 * c1); } -void cellVolume(double* vol, double xc[8][3], int numverts[6], int fconn[6][4], int nfaces, int nvert){ - *vol = 0.0; - for (int iface = 1; iface <= nfaces; iface++) { - if (numverts[iface-1] == 3) { - *vol=*vol-0.5* scalarProduct(xc[fconn[iface-1][1-1]-1][1-1], xc[fconn[iface-1][1-1]-1][2-1], xc[fconn[iface-1][1-1]-1][3-1], - xc[fconn[iface-1][2-1]-1][1-1], xc[fconn[iface-1][2-1]-1][2-1], xc[fconn[iface-1][2-1]-1][3-1], - xc[fconn[iface-1][3-1]-1][1-1], xc[fconn[iface-1][3-1]-1][2-1], xc[fconn[iface-1][3-1]-1][3-1]); - }else{ - *vol=*vol-0.25*scalarProduct(xc[fconn[iface-1][1-1]-1][1-1], xc[fconn[iface-1][1-1]-1][2-1], xc[fconn[iface-1][1-1]-1][3-1], - xc[fconn[iface-1][2-1]-1][1-1], xc[fconn[iface-1][2-1]-1][2-1], xc[fconn[iface-1][2-1]-1][3-1], - xc[fconn[iface-1][3-1]-1][1-1], xc[fconn[iface-1][3-1]-1][2-1], xc[fconn[iface-1][3-1]-1][3-1]); - *vol=*vol-0.25*scalarProduct(xc[fconn[iface-1][1-1]-1][1-1], xc[fconn[iface-1][1-1]-1][2-1], xc[fconn[iface-1][1-1]-1][3-1], - xc[fconn[iface-1][3-1]-1][1-1], xc[fconn[iface-1][3-1]-1][2-1], xc[fconn[iface-1][3-1]-1][3-1], - xc[fconn[iface-1][4-1]-1][1-1], xc[fconn[iface-1][4-1]-1][2-1], xc[fconn[iface-1][4-1]-1][3-1]); - *vol=*vol-0.25*scalarProduct(xc[fconn[iface-1][1-1]-1][1-1], xc[fconn[iface-1][1-1]-1][2-1], xc[fconn[iface-1][1-1]-1][3-1], - xc[fconn[iface-1][2-1]-1][1-1], xc[fconn[iface-1][2-1]-1][2-1], xc[fconn[iface-1][2-1]-1][3-1], - xc[fconn[iface-1][4-1]-1][1-1], xc[fconn[iface-1][4-1]-1][2-1], xc[fconn[iface-1][4-1]-1][3-1]); - *vol=*vol-0.25*scalarProduct(xc[fconn[iface-1][2-1]-1][1-1], xc[fconn[iface-1][2-1]-1][2-1], xc[fconn[iface-1][2-1]-1][3-1], - xc[fconn[iface-1][3-1]-1][1-1], xc[fconn[iface-1][3-1]-1][2-1], xc[fconn[iface-1][3-1]-1][3-1], - xc[fconn[iface-1][4-1]-1][1-1], xc[fconn[iface-1][4-1]-1][2-1], xc[fconn[iface-1][4-1]-1][3-1]); - +void cellVolume( + double* vol, + double xc[8][3], + int numverts[6], + int fconn[6][4], + int nfaces, + int nvert) +{ + *vol = 0.0; + for (int iface = 1; iface <= nfaces; iface++) { + if (numverts[iface - 1] == 3) { + *vol = *vol - 0.5 * scalarProduct( + xc[fconn[iface - 1][1 - 1] - 1][1 - 1], + xc[fconn[iface - 1][1 - 1] - 1][2 - 1], + xc[fconn[iface - 1][1 - 1] - 1][3 - 1], + xc[fconn[iface - 1][2 - 1] - 1][1 - 1], + xc[fconn[iface - 1][2 - 1] - 1][2 - 1], + xc[fconn[iface - 1][2 - 1] - 1][3 - 1], + xc[fconn[iface - 1][3 - 1] - 1][1 - 1], + xc[fconn[iface - 1][3 - 1] - 1][2 - 1], + xc[fconn[iface - 1][3 - 1] - 1][3 - 1]); + } else { + *vol = *vol - 0.25 * scalarProduct( + xc[fconn[iface - 1][1 - 1] - 1][1 - 1], + xc[fconn[iface - 1][1 - 1] - 1][2 - 1], + xc[fconn[iface - 1][1 - 1] - 1][3 - 1], + xc[fconn[iface - 1][2 - 1] - 1][1 - 1], + xc[fconn[iface - 1][2 - 1] - 1][2 - 1], + xc[fconn[iface - 1][2 - 1] - 1][3 - 1], + xc[fconn[iface - 1][3 - 1] - 1][1 - 1], + xc[fconn[iface - 1][3 - 1] - 1][2 - 1], + xc[fconn[iface - 1][3 - 1] - 1][3 - 1]); + *vol = *vol - 0.25 * scalarProduct( + xc[fconn[iface - 1][1 - 1] - 1][1 - 1], + xc[fconn[iface - 1][1 - 1] - 1][2 - 1], + xc[fconn[iface - 1][1 - 1] - 1][3 - 1], + xc[fconn[iface - 1][3 - 1] - 1][1 - 1], + xc[fconn[iface - 1][3 - 1] - 1][2 - 1], + xc[fconn[iface - 1][3 - 1] - 1][3 - 1], + xc[fconn[iface - 1][4 - 1] - 1][1 - 1], + xc[fconn[iface - 1][4 - 1] - 1][2 - 1], + xc[fconn[iface - 1][4 - 1] - 1][3 - 1]); + *vol = *vol - 0.25 * scalarProduct( + xc[fconn[iface - 1][1 - 1] - 1][1 - 1], + xc[fconn[iface - 1][1 - 1] - 1][2 - 1], + xc[fconn[iface - 1][1 - 1] - 1][3 - 1], + xc[fconn[iface - 1][2 - 1] - 1][1 - 1], + xc[fconn[iface - 1][2 - 1] - 1][2 - 1], + xc[fconn[iface - 1][2 - 1] - 1][3 - 1], + xc[fconn[iface - 1][4 - 1] - 1][1 - 1], + xc[fconn[iface - 1][4 - 1] - 1][2 - 1], + xc[fconn[iface - 1][4 - 1] - 1][3 - 1]); + *vol = *vol - 0.25 * scalarProduct( + xc[fconn[iface - 1][2 - 1] - 1][1 - 1], + xc[fconn[iface - 1][2 - 1] - 1][2 - 1], + xc[fconn[iface - 1][2 - 1] - 1][3 - 1], + xc[fconn[iface - 1][3 - 1] - 1][1 - 1], + xc[fconn[iface - 1][3 - 1] - 1][2 - 1], + xc[fconn[iface - 1][3 - 1] - 1][3 - 1], + xc[fconn[iface - 1][4 - 1] - 1][1 - 1], + xc[fconn[iface - 1][4 - 1] - 1][2 - 1], + xc[fconn[iface - 1][4 - 1] - 1][3 - 1]); + } } - } - *vol = *vol / 3.0; + *vol = *vol / 3.0; } diff --git a/src/cellVolume.h b/src/cellVolume.h index 3873893..a72dc5a 100644 --- a/src/cellVolume.h +++ b/src/cellVolume.h @@ -1,4 +1,4 @@ #ifndef CELLVOLUME_H #define CELLVOLUME_H -void cellVolume(double *, double[8][3], int[6], int[6][4], int, int); +void cellVolume(double*, double[8][3], int[6], int[6][4], int, int); #endif diff --git a/src/checkContainment.C b/src/checkContainment.C index ff67387..a754aed 100644 --- a/src/checkContainment.C +++ b/src/checkContainment.C @@ -16,78 +16,70 @@ // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include "codetypes.h" #include "MeshBlock.h" #include "tioga_math.h" -void MeshBlock::checkContainment(int *cellIndex, int adtElement, double *xsearch) +void MeshBlock::checkContainment( + int* cellIndex, int adtElement, double* xsearch) { - int i,j,k,m,n,i3; - int nvert; - int icell,icell1; - int passFlag; - int isum; - double xv[8][3]; - double frac[8]; - // - icell=elementList[adtElement]; - if (ihigh==0) - { - // - // locate the type of the cell - // - isum=0; - for(n=0;n 0) - { - cellIndex[0]=-1; - return; - } - if (fabs(frac[m]) < searchTol && cellRes[icell]==BIGVALUE) cellIndex[1]=1; - } - - return; - } - else - { - icell1=icell+BASE; - cellIndex[0]=-1; - cellIndex[1]=0; - donor_inclusion_test(&icell1,xsearch,&passFlag,&(rst[ipoint])); - if (passFlag) cellIndex[0]=icell; - return; - } + int i, j, k, m, n, i3; + int nvert; + int icell, icell1; + int passFlag; + int isum; + double xv[8][3]; + double frac[8]; + // + icell = elementList[adtElement]; + if (ihigh == 0) { + // + // locate the type of the cell + // + isum = 0; + for (n = 0; n < ntypes; n++) { + isum += nc[n]; + if (icell < isum) { + i = icell - (isum - nc[n]); + break; + } + } + // + // now collect all the vertices in the + // array xv + // + nvert = nv[n]; + for (m = 0; m < nvert; m++) { + i3 = 3 * (vconn[n][nvert * i + m] - BASE); + for (j = 0; j < 3; j++) xv[m][j] = x[i3 + j]; + } + // + computeNodalWeights(xv, xsearch, frac, nvert); + // + cellIndex[0] = icell; + cellIndex[1] = 0; + // + // if any of the nodal weights are + // not in between [-TOL 1+TOL] discard + // cell + // + for (m = 0; m < nvert; m++) { + if ((frac[m] + searchTol) * (frac[m] - 1.0 - searchTol) > 0) { + cellIndex[0] = -1; + return; + } + if (fabs(frac[m]) < searchTol && cellRes[icell] == BIGVALUE) + cellIndex[1] = 1; + } + return; + } else { + icell1 = icell + BASE; + cellIndex[0] = -1; + cellIndex[1] = 0; + donor_inclusion_test(&icell1, xsearch, &passFlag, &(rst[ipoint])); + if (passFlag) cellIndex[0] = icell; + return; + } } diff --git a/src/codetypes.h b/src/codetypes.h index dc65667..da4f70c 100644 --- a/src/codetypes.h +++ b/src/codetypes.h @@ -65,12 +65,12 @@ typedef int32_t qcoord_t; /* ADAPTIVE HOLE MAP OCTANT INFO */ /*==================================================================*/ #define INTERSECT_ALG \ - 1 // [0] point-box inclusion only - // [1] face-box intersection (water-tight) + 1 // [0] point-box inclusion only + // [1] face-box intersection (water-tight) #define NON_UNIQUE_NODES \ - 1 // [0] wbc nodes are NOT listed as obc nodes - // [1] wbc nodes may also be listed as obc nodes + 1 // [0] wbc nodes are NOT listed as obc nodes + // [1] wbc nodes may also be listed as obc nodes /* Fixed Octree Constraints: Do Not Change */ #define OCTANT_MAXLEVEL 30 // 32-bit integer @@ -92,10 +92,10 @@ typedef int32_t qcoord_t; #define TRACEI(x) printf("#tioga:\t" #x " =%d\n", x); #define TRACED(x) printf("#tioga:\t" #x " =%.16e\n", x); #define TIOGA_FREE(a1) \ - { \ - free(a1); \ - a1 = NULL; \ - } + { \ + free(a1); \ + a1 = NULL; \ + } // # define debug(x,y) printf("#tioga:\t"#x"=%d,"#y"=%d\n",x,y); // # define stdwrite(x) if (myid==0) printf("#tioga:\t"#x"\n"); // # define dstr(x) printf("#tioga:\t"#x"\n"); @@ -118,195 +118,219 @@ typedef int32_t qcoord_t; #define ZHI 5 /* Mesh Block Complement/Composite Rank Data */ -class meshblockCompInfo { +class meshblockCompInfo +{ public: - int nreq; - int id; - int nrank; - int masterID; /* master rank for distributing mesh block data */ - MPI_Comm comm; /* communicator containing all complement ranks + master */ - - /* constructor */ - meshblockCompInfo() { - nreq = 0; - id = -1; - nrank = 0; - masterID = -1; - comm = MPI_COMM_NULL; - }; - - /* destructor */ - ~meshblockCompInfo() { - // if(comm != MPI_COMM_NULL) MPI_Comm_free(&comm); - int sflag; - MPI_Finalized(&sflag); - if (!sflag) { - if (comm != MPI_COMM_NULL) - MPI_Comm_free(&comm); + int nreq; + int id; + int nrank; + int masterID; /* master rank for distributing mesh block data */ + MPI_Comm comm; /* communicator containing all complement ranks + master */ + + /* constructor */ + meshblockCompInfo() + { + nreq = 0; + id = -1; + nrank = 0; + masterID = -1; + comm = MPI_COMM_NULL; + }; + + /* destructor */ + ~meshblockCompInfo() + { + // if(comm != MPI_COMM_NULL) MPI_Comm_free(&comm); + int sflag; + MPI_Finalized(&sflag); + if (!sflag) { + if (comm != MPI_COMM_NULL) MPI_Comm_free(&comm); + }; }; - }; }; -typedef struct { - double lo; /**< lower bound */ - double hi; /**< upper bound */ +typedef struct +{ + double lo; /**< lower bound */ + double hi; /**< upper bound */ } bound_t; -typedef struct { - bound_t x; /**< x bounds */ - bound_t y; /**< y bounds */ - bound_t z; /**< z bounds */ +typedef struct +{ + bound_t x; /**< x bounds */ + bound_t y; /**< y bounds */ + bound_t z; /**< z bounds */ } box_t; /** The 3D full octant datatype: 130 bytes per octant */ -typedef struct octant_full { - qcoord_t x, y, z; /**< [12B] binary coordinates */ - uint32_t id; /**< [4B] element id on level */ - uint8_t filltype; /**< [1B] floodfill: [0] inside SB, [1] outside SB, [2] hole - SB */ - uint8_t refined; /**< [1B] flag if refined (i.e. is a parent) */ - struct octant_full *nhbr[6]; /**< [48B] neighbor octant list */ - struct octant_full *children[8]; /**< [64B] children octants if refined */ +typedef struct octant_full +{ + qcoord_t x, y, z; /**< [12B] binary coordinates */ + uint32_t id; /**< [4B] element id on level */ + uint8_t filltype; /**< [1B] floodfill: [0] inside SB, [1] outside SB, [2] + hole SB */ + uint8_t refined; /**< [1B] flag if refined (i.e. is a parent) */ + struct octant_full* nhbr[6]; /**< [48B] neighbor octant list */ + struct octant_full* children[8]; /**< [64B] children octants if refined */ } octant_full_t; -typedef struct octant_coordinates { - qcoord_t x, y, z; /**< [12B] binary coordinates */ +typedef struct octant_coordinates +{ + qcoord_t x, y, z; /**< [12B] binary coordinates */ } octant_coordinates_t; /** 3D octant datatype: 48 bytes per octant */ -typedef struct octant { - qcoord_t x, y, z; /**< [12B] binary coordinates */ - uint8_t filltype; /**< [1B] floodfill: [0] inside SB, [1] outside SB, [2] - hole SB */ - uint8_t leafflag; /**< [1B] flag if refined (i.e. is a parent) */ - uint8_t pad[2]; /**< [2B] padding */ - uint32_t children[8]; /**< [32B] children octant IDs */ +typedef struct octant +{ + qcoord_t x, y, z; /**< [12B] binary coordinates */ + uint8_t filltype; /**< [1B] floodfill: [0] inside SB, [1] outside SB, [2] + hole SB */ + uint8_t leafflag; /**< [1B] flag if refined (i.e. is a parent) */ + uint8_t pad[2]; /**< [2B] padding */ + uint32_t children[8]; /**< [32B] children octant IDs */ } octant_t; -typedef struct level_octant { - uint32_t elem_count; /**< number of octants in level */ - uint8_t level_id; /**< level number */ - std::vector - octants; /**< [elem_count] locally stored octants */ +typedef struct level_octant +{ + uint32_t elem_count; /**< number of octants in level */ + uint8_t level_id; /**< level number */ + std::vector + octants; /**< [elem_count] locally stored octants */ } level_octant_t; -typedef struct level_octant_coordinate { - uint8_t level_id; /**< level number */ - uint32_t elem_count; /**< number of octants in level */ - std::vector octants; /**< [elem_count] octant list */ +typedef struct level_octant_coordinate +{ + uint8_t level_id; /**< level number */ + uint32_t elem_count; /**< number of octants in level */ + std::vector octants; /**< [elem_count] octant list */ } level_octant_coordinate_t; -typedef struct level { - uint8_t level_id; /**< level number */ - uint32_t elem_count; /**< number of octants in level */ - std::vector octants; /**< [elem_count] octant list */ +typedef struct level +{ + uint8_t level_id; /**< level number */ + uint32_t elem_count; /**< number of octants in level */ + std::vector octants; /**< [elem_count] octant list */ } level_t; -typedef struct ADAPTIVE_HOLEMAP_OCTANT { - int8_t existWall; /**< flag to indicate map contains wall */ - double extents_lo[3]; /**< lower coordinates of tree */ - double extents_hi[3]; /**< upper coordinates of tree */ +typedef struct ADAPTIVE_HOLEMAP_OCTANT +{ + int8_t existWall; /**< flag to indicate map contains wall */ + double extents_lo[3]; /**< lower coordinates of tree */ + double extents_hi[3]; /**< upper coordinates of tree */ - uint8_t nlevel; /**< number of levels */ - level_octant_t levels[OCTANT_MAXLEVEL]; + uint8_t nlevel; /**< number of levels */ + level_octant_t levels[OCTANT_MAXLEVEL]; } ADAPTIVE_HOLEMAP_OCTANT; -typedef struct { - uint8_t nlevel; /**< number of levels in map */ - double extents_lo[3]; /**< lower coordinates of tree */ - double extents_hi[3]; /**< upper coordinates of tree */ - uint64_t leaf_count; /**< total leaf octant count */ - uint64_t elem_count; /**< total octant count */ +typedef struct +{ + uint8_t nlevel; /**< number of levels in map */ + double extents_lo[3]; /**< lower coordinates of tree */ + double extents_hi[3]; /**< upper coordinates of tree */ + uint64_t leaf_count; /**< total leaf octant count */ + uint64_t elem_count; /**< total octant count */ } ahm_meta_t; -typedef struct { - uint8_t nlevel; /**< number of levels in map */ - double extents_lo[3]; /**< lower coordinates of tree */ - double extents_hi[3]; /**< upper coordinates of tree */ - uint64_t elem_count; /**< total octant count */ +typedef struct +{ + uint8_t nlevel; /**< number of levels in map */ + double extents_lo[3]; /**< lower coordinates of tree */ + double extents_hi[3]; /**< upper coordinates of tree */ + uint64_t elem_count; /**< total octant count */ } ahm_meta_minimal_t; -typedef struct ADAPTIVE_HOLEMAP_COMPOSITE { - ahm_meta_minimal_t meta; /**< adaptive hole map meta data */ - level_octant_coordinate_t levels[OCTANT_MAXLEVEL]; +typedef struct ADAPTIVE_HOLEMAP_COMPOSITE +{ + ahm_meta_minimal_t meta; /**< adaptive hole map meta data */ + level_octant_coordinate_t levels[OCTANT_MAXLEVEL]; } ADAPTIVE_HOLEMAP_COMPOSITE; -typedef struct ADAPTIVE_HOLEMAP { - uint8_t existWall; /**< flag to indicate map contains wall */ - ahm_meta_t meta; /**< adaptive hole map meta data */ - level_t levels[OCTANT_MAXLEVEL]; +typedef struct ADAPTIVE_HOLEMAP +{ + uint8_t existWall; /**< flag to indicate map contains wall */ + ahm_meta_t meta; /**< adaptive hole map meta data */ + level_t levels[OCTANT_MAXLEVEL]; } ADAPTIVE_HOLEMAP; -typedef struct HOLEMAP { - int existWall; - int nx[3]; - int *samLocal; - int *sam; - double extents[6]; +typedef struct HOLEMAP +{ + int existWall; + int nx[3]; + int* samLocal; + int* sam; + double extents[6]; } HOLEMAP; -typedef struct OBB { - double xc[3]; - double dxc[3]; - double vec[3][3]; - - int comm_idx; /* Index in comm map for this OBB */ - int iblk_local; /* Index of this mesh block */ - int iblk_remote; /* Index of the remote mesh block (intersecting pair) */ - int tag_remote; - int send_tag; - int recv_tag; +typedef struct OBB +{ + double xc[3]; + double dxc[3]; + double vec[3][3]; + + int comm_idx; /* Index in comm map for this OBB */ + int iblk_local; /* Index of this mesh block */ + int iblk_remote; /* Index of the remote mesh block (intersecting pair) */ + int tag_remote; + int send_tag; + int recv_tag; } OBB; -typedef struct DONORLIST { - int donorData[4]; - double donorRes; - double receptorRes; - int cancel; - struct DONORLIST *next; +typedef struct DONORLIST +{ + int donorData[4]; + double donorRes; + double receptorRes; + int cancel; + struct DONORLIST* next; } DONORLIST; -typedef struct PACKET { - int nints; - int nreals; - int *intData; - REAL *realData; +typedef struct PACKET +{ + int nints; + int nreals; + int* intData; + REAL* realData; } PACKET; -typedef struct INTERPLIST { - int cancel; - int nweights; - int receptorInfo[3]; - double xtmp[3]; - int *inode; - double *weights; +typedef struct INTERPLIST +{ + int cancel; + int nweights; + int receptorInfo[3]; + double xtmp[3]; + int* inode; + double* weights; } INTERPLIST; -typedef struct INTERPLIST2 { - int cancel; - int nweights; - int receptorInfo[3]; - int *inode; - double *weights; - struct INTERPLIST2 *next; +typedef struct INTERPLIST2 +{ + int cancel; + int nweights; + int receptorInfo[3]; + int* inode; + double* weights; + struct INTERPLIST2* next; } INTERPLIST2; -typedef struct INTEGERLIST { - int inode; - struct INTEGERLIST *next; +typedef struct INTEGERLIST +{ + int inode; + struct INTEGERLIST* next; } INTEGERLIST; -typedef struct INTEGERLIST2 { - int intDataSize, realDataSize; - int *intData; - double *realData; - struct INTEGERLIST2 *next; +typedef struct INTEGERLIST2 +{ + int intDataSize, realDataSize; + int* intData; + double* realData; + struct INTEGERLIST2* next; } INTEGERLIST2; -typedef struct CompositeBody { - double searchTol; - std::vector bodyids; - std::vector dominanceflags; +typedef struct CompositeBody +{ + double searchTol; + std::vector bodyids; + std::vector dominanceflags; } CompositeBody; #endif /* CODETYPES_H */ diff --git a/src/dataUpdate.C b/src/dataUpdate.C index d97909c..51ba258 100644 --- a/src/dataUpdate.C +++ b/src/dataUpdate.C @@ -16,7 +16,7 @@ // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include "codetypes.h" #include "MeshBlock.h" #include @@ -24,157 +24,144 @@ #define ROW 0 #define COLUMN 1 -void MeshBlock::getInterpolatedSolution(int *nints,int *nreals,int **intData,double **realData,double *q, - int nvar, int interptype) +void MeshBlock::getInterpolatedSolution( + int* nints, + int* nreals, + int** intData, + double** realData, + double* q, + int nvar, + int interptype) { - int i; - int k,m,inode; - double weight; - double *qq = NULL; - int icount,dcount; - // - // - (*nints)=(*nreals)=0; - for(i=0;i 1.0+TOL) { - TRACED(weight); - printf("warning: weights are not convex 1\n"); - } - for(k=0;k 1.0 + TOL) { + TRACED(weight); + printf("warning: weights are not convex 1\n"); + } + for (k = 0; k < nvar; k++) + qq[k] += q[inode * nvar + k] * weight; + } + (*intData)[icount++] = interpList[i].receptorInfo[0]; + (*intData)[icount++] = interpList[i].receptorInfo[1]; + (*intData)[icount++] = interpList[i].receptorInfo[2]; + for (k = 0; k < nvar; k++) (*realData)[dcount++] = qq[k]; + } + } + } else if (interptype == COLUMN) { + for (i = 0; i < ninterp; i++) { + if (!interpList[i].cancel) { + for (k = 0; k < nvar; k++) qq[k] = 0; + for (m = 0; m < interpList[i].nweights; m++) { + inode = interpList[i].inode[m]; + weight = interpList[i].weights[m]; + for (k = 0; k < nvar; k++) + qq[k] += q[k * nnodes + inode] * weight; + } + (*intData)[icount++] = interpList[i].receptorInfo[0]; + (*intData)[icount++] = interpList[i].receptorInfo[1]; + (*intData)[icount++] = interpList[i].receptorInfo[2]; + for (k = 0; k < nvar; k++) (*realData)[dcount++] = qq[k]; + } + } } - if (qq) TIOGA_FREE(qq); + if (qq) TIOGA_FREE(qq); } - -void MeshBlock::updateSolnData(int inode,double *qvar,double *q) + +void MeshBlock::updateSolnData(int inode, double* qvar, double* q) { - int k; + int k; - if (interptype==ROW) - { - if (inode > nnodes) { TRACEI(inode); TRACEI(nnodes);} - assert(inode < nnodes); - for(k=0;k nnodes) { + TRACEI(inode); + TRACEI(nnodes); + } + assert(inode < nnodes); + for (k = 0; k < nvar; k++) q[inode * nvar + k] = qvar[k]; } - if (interptype==COLUMN) - { - for(k=0;k @@ -25,328 +25,318 @@ using namespace TIOGA; void tioga::exchangeAMRDonors(void) { - int i,j,k,l,m,n,i3; - int nsend_sav,nrecv_sav,nsend,nrecv; - PACKET *sndPack,*rcvPack; - int *sndMap,*rcvMap,*sndMapAll,*rcvMapAll; - int *imap,*icount,*intcount,*realcount; - int *obdonors,*obreceptors; - int *cancelledData; - int *bcount; - int gid,procid,localid,meshtag,remoteid,remoteblockid,id; - int interpCount,donorCount,index,ncancel,ctype; - double cellRes; - double xtmp[3]; - //FILE *fp; - //char fname[80]; - //char qstr[2]; - //char intstring[7]; + int i, j, k, l, m, n, i3; + int nsend_sav, nrecv_sav, nsend, nrecv; + PACKET *sndPack, *rcvPack; + int *sndMap, *rcvMap, *sndMapAll, *rcvMapAll; + int *imap, *icount, *intcount, *realcount; + int *obdonors, *obreceptors; + int* cancelledData; + int* bcount; + int gid, procid, localid, meshtag, remoteid, remoteblockid, id; + int interpCount, donorCount, index, ncancel, ctype; + double cellRes; + double xtmp[3]; + // FILE *fp; + // char fname[80]; + // char qstr[2]; + // char intstring[7]; - //sprintf(intstring,"%d",100000+myid); - //sprintf(fname,"ysearch_%s.dat",&(intstring[1])); - //fp=fopen(fname,"w"); - // - // setup communicator for all to all now - // since the receiver side is unknown - // - pc_cart->getMap(&nsend_sav,&nrecv_sav,&sndMap,&rcvMap); - sndMapAll=(int *)malloc(sizeof(int)*pc_cart->numprocs); - rcvMapAll=(int *)malloc(sizeof(int)*pc_cart->numprocs); - nsend=nrecv=pc_cart->numprocs; - imap=(int *)malloc(sizeof(int)*pc_cart->numprocs); - icount=(int *)malloc(sizeof(int)*pc_cart->numprocs); - for(i=0;inumprocs;i++) {sndMapAll[i]=rcvMapAll[i]=imap[i]=i; icount[i]=0;} - pc_cart->setMap(nsend,nrecv,sndMapAll,rcvMapAll); - // - // create packets to send and receive - // and initialize them to zero - // - sndPack=(PACKET *)malloc(sizeof(PACKET)*nsend); - rcvPack=(PACKET *)malloc(sizeof(PACKET)*nrecv); - obdonors=(int *)malloc(sizeof(int)*nsend); - obreceptors=(int *)malloc(sizeof(int)*nsend); - // - pc_cart->initPackets(sndPack,rcvPack); - // - for(i=0;i 0) - { - // - // count data to send - // - for(int ib=0;ibntotalPointsCart;i++) - { - if (mb->donorIdCart[i]!=-1) - { - gid=mb->donorIdCart[i]; - assert((cg->proc_id[gid] < nsend && cg->proc_id[gid]>=0)); - obdonors[imap[cg->proc_id[gid]]]++; - } - } - for(i=0;insearch;i++) - { - if (mb->donorId[i]!=-1) - { - assert((mb->isearch[3*i] < nsend && mb->isearch[3*i]>=0)); - obreceptors[imap[mb->isearch[3*i]]]++; - } - } - } + // sprintf(intstring,"%d",100000+myid); + // sprintf(fname,"ysearch_%s.dat",&(intstring[1])); + // fp=fopen(fname,"w"); + // + // setup communicator for all to all now + // since the receiver side is unknown + // + pc_cart->getMap(&nsend_sav, &nrecv_sav, &sndMap, &rcvMap); + sndMapAll = (int*)malloc(sizeof(int) * pc_cart->numprocs); + rcvMapAll = (int*)malloc(sizeof(int) * pc_cart->numprocs); + nsend = nrecv = pc_cart->numprocs; + imap = (int*)malloc(sizeof(int) * pc_cart->numprocs); + icount = (int*)malloc(sizeof(int) * pc_cart->numprocs); + for (i = 0; i < pc_cart->numprocs; i++) { + sndMapAll[i] = rcvMapAll[i] = imap[i] = i; + icount[i] = 0; } - // - // allocate data packets - // - for(i=0;isetMap(nsend, nrecv, sndMapAll, rcvMapAll); + // + // create packets to send and receive + // and initialize them to zero + // + sndPack = (PACKET*)malloc(sizeof(PACKET) * nsend); + rcvPack = (PACKET*)malloc(sizeof(PACKET) * nrecv); + obdonors = (int*)malloc(sizeof(int) * nsend); + obreceptors = (int*)malloc(sizeof(int) * nsend); + // + pc_cart->initPackets(sndPack, rcvPack); + // + for (i = 0; i < nsend; i++) obdonors[i] = obreceptors[i] = 0; + // + if (nblocks > 0) { + // + // count data to send + // + for (int ib = 0; ib < nblocks; ib++) { + auto& mb = mblocks[ib]; + for (i = 0; i < mb->ntotalPointsCart; i++) { + if (mb->donorIdCart[i] != -1) { + gid = mb->donorIdCart[i]; + assert((cg->proc_id[gid] < nsend && cg->proc_id[gid] >= 0)); + obdonors[imap[cg->proc_id[gid]]]++; + } + } + for (i = 0; i < mb->nsearch; i++) { + if (mb->donorId[i] != -1) { + assert(( + mb->isearch[3 * i] < nsend && mb->isearch[3 * i] >= 0)); + obreceptors[imap[mb->isearch[3 * i]]]++; + } + } + } } - // - // pack the data - // - intcount=(int *)malloc(sizeof(int)*nsend); - realcount=(int *)malloc(sizeof(int)*nsend); - for(i=0;i 0) - { - for(int ib=0;ibntotalPointsCart;i++) - { - if (mb->donorIdCart[i]!=-1) - { - gid=mb->donorIdCart[i]; - procid=imap[cg->proc_id[gid]]; - localid=cg->local_id[gid]; - sndPack[procid].intData[intcount[procid]++]=localid; - sndPack[procid].intData[intcount[procid]++]=mb->receptorIdCart[i]; - sndPack[procid].intData[intcount[procid]++]=ib; - sndPack[procid].realData[realcount[procid]++]=mb->rxyzCart[3*i]; - sndPack[procid].realData[realcount[procid]++]=mb->rxyzCart[3*i+1]; - sndPack[procid].realData[realcount[procid]++]=mb->rxyzCart[3*i+2]; - } - } - } - for(int ib=0;ibnsearch;i++) - { - if (mb->donorId[i]!=-1) - { - procid=imap[mb->isearch[3*i]]; - sndPack[procid].intData[intcount[procid]++]=mb->isearch[3*i+1]; - sndPack[procid].intData[intcount[procid]++]=mb->isearch[3*i+2]; - sndPack[procid].intData[intcount[procid]++]=mb->meshtag; - sndPack[procid].intData[intcount[procid]++]=i; - sndPack[procid].intData[intcount[procid]++]=ib; - sndPack[procid].realData[realcount[procid]++]=mb->cellRes[mb->donorId[i]]; - // fprintf(fp,"%lf %lf %lf\n",mb->xsearch[3*i],mb->xsearch[3*i+1],mb->xsearch[3*i+2]); - } - } - } + // + // allocate data packets + // + for (i = 0; i < nsend; i++) { + sndPack[i].nints = obdonors[i] * 3 + obreceptors[i] * 5 + 2; + sndPack[i].nreals = obdonors[i] * 3 + obreceptors[i]; + sndPack[i].intData = (int*)malloc(sizeof(int) * sndPack[i].nints); + sndPack[i].realData = + (double*)malloc(sizeof(double) * sndPack[i].nreals); + sndPack[i].intData[0] = obdonors[i]; + sndPack[i].intData[1] = obreceptors[i]; + } + // + // pack the data + // + intcount = (int*)malloc(sizeof(int) * nsend); + realcount = (int*)malloc(sizeof(int) * nsend); + for (i = 0; i < nsend; i++) { + intcount[i] = 2; + realcount[i] = 0; + } + if (nblocks > 0) { + for (int ib = 0; ib < nblocks; ib++) { + auto& mb = mblocks[ib]; + for (i = 0; i < mb->ntotalPointsCart; i++) { + if (mb->donorIdCart[i] != -1) { + gid = mb->donorIdCart[i]; + procid = imap[cg->proc_id[gid]]; + localid = cg->local_id[gid]; + sndPack[procid].intData[intcount[procid]++] = localid; + sndPack[procid].intData[intcount[procid]++] = + mb->receptorIdCart[i]; + sndPack[procid].intData[intcount[procid]++] = ib; + sndPack[procid].realData[realcount[procid]++] = + mb->rxyzCart[3 * i]; + sndPack[procid].realData[realcount[procid]++] = + mb->rxyzCart[3 * i + 1]; + sndPack[procid].realData[realcount[procid]++] = + mb->rxyzCart[3 * i + 2]; + } + } + } + for (int ib = 0; ib < nblocks; ib++) { + auto& mb = mblocks[ib]; + for (i = 0; i < mb->nsearch; i++) { + if (mb->donorId[i] != -1) { + procid = imap[mb->isearch[3 * i]]; + sndPack[procid].intData[intcount[procid]++] = + mb->isearch[3 * i + 1]; + sndPack[procid].intData[intcount[procid]++] = + mb->isearch[3 * i + 2]; + sndPack[procid].intData[intcount[procid]++] = mb->meshtag; + sndPack[procid].intData[intcount[procid]++] = i; + sndPack[procid].intData[intcount[procid]++] = ib; + sndPack[procid].realData[realcount[procid]++] = + mb->cellRes[mb->donorId[i]]; + // fprintf(fp,"%lf %lf + // %lf\n",mb->xsearch[3*i],mb->xsearch[3*i+1],mb->xsearch[3*i+2]); + } + } + } } - // Remove sends that won't be used. The first 2 ints are obdonors - // and obreceptors. If nothing else is being sent, then these won't - // be used so we can safely remove them and avoid unnecessary - // communication - for(int i=0;isendRecvPacketsAll(sndPack, rcvPack); + // + // decode the data now + // + bcount = (int*)malloc(sizeof(int) * ncart); + for (i = 0; i < ncart; i++) { + cb[i].clearLists(); + cb[i].initializeLists(); + bcount[i] = 0; } - } - //if (myid==0) { - //for(i=0;isendRecvPacketsAll(sndPack,rcvPack); - // - // decode the data now - // - bcount=(int *)malloc(sizeof(int)*ncart); - for(i=0;i 0) - { - m=2; - n=0; - interpCount=rcvPack[i].intData[0]; - donorCount=rcvPack[i].intData[1]; - icount[i]=interpCount+donorCount; - for(j=0;j 0) { + m = 2; + n = 0; + interpCount = rcvPack[i].intData[0]; + donorCount = rcvPack[i].intData[1]; + icount[i] = interpCount + donorCount; + for (j = 0; j < interpCount; j++) { + localid = rcvPack[i].intData[m++]; + remoteid = rcvPack[i].intData[m++]; + remoteblockid = rcvPack[i].intData[m++]; + xtmp[0] = rcvPack[i].realData[n++]; + xtmp[1] = rcvPack[i].realData[n++]; + xtmp[2] = rcvPack[i].realData[n++]; + cb[localid].insertInInterpList( + i, remoteid, remoteblockid, xtmp); + bcount[localid]++; + } + for (j = 0; j < donorCount; j++) { + localid = rcvPack[i].intData[m++]; + index = rcvPack[i].intData[m++]; + meshtag = rcvPack[i].intData[m++]; + remoteid = rcvPack[i].intData[m++]; + remoteblockid = rcvPack[i].intData[m++]; + cellRes = rcvPack[i].realData[n++]; + cb[localid].insertInDonorList( + i, index, meshtag, remoteid, remoteblockid, cellRes); + bcount[localid]++; + } + } } - if (USE_ADAPTIVE_HOLEMAP){ - for(i=0;iclearPackets(sndPack,rcvPack); - for(i=0;i 0) - { - sndPack[i].nints=3*icount[i]; - sndPack[i].nreals=0; - sndPack[i].intData=(int *) malloc(sizeof(int)*sndPack[i].nints); - } - intcount[i]=0; + if (USE_ADAPTIVE_HOLEMAP) { + for (i = 0; i < ncart; i++) cb[i].processDonors(adaptiveHoleMap, nmesh); + } else { + for (i = 0; i < ncart; i++) cb[i].processDonors(holeMap, nmesh); } - cancelledData=NULL; - //if (myid==30) { - for(i=0;i 0) { - cancelledData=(int *)malloc(sizeof(int)*4*ncancel); - cb[i].getCancellationData(cancelledData,&ncancel); - for(j=0;jclearPackets(sndPack, rcvPack); + for (i = 0; i < nsend; i++) { + if (icount[i] > 0) { + sndPack[i].nints = 3 * icount[i]; + sndPack[i].nreals = 0; + sndPack[i].intData = (int*)malloc(sizeof(int) * sndPack[i].nints); + } + intcount[i] = 0; } - for(i=0;i 0) { + cancelledData = (int*)malloc(sizeof(int) * 4 * ncancel); + cb[i].getCancellationData(cancelledData, &ncancel); + for (j = 0; j < ncancel; j++) { + procid = cancelledData[4 * j]; + ctype = cancelledData[4 * j + 1]; + remoteid = cancelledData[4 * j + 2]; + remoteblockid = cancelledData[4 * j + 3]; + sndPack[procid].intData[intcount[procid]++] = ctype; + sndPack[procid].intData[intcount[procid]++] = remoteid; + sndPack[procid].intData[intcount[procid]++] = remoteblockid; + // TRACEI(intcount[procid]); + // TRACEI(sndPack[procid].nints); + } + } + } + for (i = 0; i < nsend; i++) sndPack[i].nints = intcount[i]; + //} - pc_cart->sendRecvPacketsAll(sndPack,rcvPack); - for(i=0;i 0) - { - m=0; - for(j=0;jdonorIdCart[id]=-1; - } - else - { - mblocks[ib]->donorId[id]=-1; - } - } - } + pc_cart->sendRecvPacketsAll(sndPack, rcvPack); + for (i = 0; i < nrecv; i++) { + if (rcvPack[i].nints > 0) { + m = 0; + for (j = 0; j < rcvPack[i].nints / 3; j++) { + ctype = rcvPack[i].intData[m++]; + id = rcvPack[i].intData[m++]; + int ib = rcvPack[i].intData[m++]; + if (ctype == 0) { + mblocks[ib]->donorIdCart[id] = -1; + } else { + mblocks[ib]->donorId[id] = -1; + } + } + } } - for(int ib=0;ibsetCartIblanks(); - pc_cart->clearPackets(sndPack,rcvPack); - // - for(int ib=0;ibfindInterpListCart(); - if (cancelledData) TIOGA_FREE(cancelledData); - //fclose(fp); - TIOGA_FREE(bcount); - TIOGA_FREE(intcount); - TIOGA_FREE(sndMapAll); - TIOGA_FREE(rcvMapAll); - TIOGA_FREE(obdonors); - TIOGA_FREE(obreceptors); - TIOGA_FREE(imap); - TIOGA_FREE(icount); - TIOGA_FREE(sndPack); - TIOGA_FREE(rcvPack); + for (int ib = 0; ib < nblocks; ib++) mblocks[ib]->setCartIblanks(); + pc_cart->clearPackets(sndPack, rcvPack); + // + for (int ib = 0; ib < nblocks; ib++) mblocks[ib]->findInterpListCart(); + if (cancelledData) TIOGA_FREE(cancelledData); + // fclose(fp); + TIOGA_FREE(bcount); + TIOGA_FREE(intcount); + TIOGA_FREE(sndMapAll); + TIOGA_FREE(rcvMapAll); + TIOGA_FREE(obdonors); + TIOGA_FREE(obreceptors); + TIOGA_FREE(imap); + TIOGA_FREE(icount); + TIOGA_FREE(sndPack); + TIOGA_FREE(rcvPack); } void tioga::checkComm(void) { - int i; - int nsend,nrecv; - int *sndMap,*rcvMap; - PACKET *sndPack,*rcvPack; + int i; + int nsend, nrecv; + int *sndMap, *rcvMap; + PACKET *sndPack, *rcvPack; - nsend=nrecv=pc_cart->numprocs; - sndMap=(int *)malloc(sizeof(int)*nsend); - rcvMap=(int *)malloc(sizeof(int)*nrecv); - for(i=0;inumprocs;i++) {sndMap[i]=rcvMap[i]=i;} - pc_cart->setMap(nsend,nrecv,sndMap,rcvMap); - // - // create packets to send and receive - // and initialize them to zero - // - sndPack=(PACKET *)malloc(sizeof(PACKET)*nsend); - rcvPack=(PACKET *)malloc(sizeof(PACKET)*nrecv); - // - pc_cart->initPackets(sndPack,rcvPack); - // - // allocate data packets - // - for(i=0;inumprocs; + sndMap = (int*)malloc(sizeof(int) * nsend); + rcvMap = (int*)malloc(sizeof(int) * nrecv); + for (i = 0; i < pc_cart->numprocs; i++) { + sndMap[i] = rcvMap[i] = i; + } + pc_cart->setMap(nsend, nrecv, sndMap, rcvMap); + // + // create packets to send and receive + // and initialize them to zero + // + sndPack = (PACKET*)malloc(sizeof(PACKET) * nsend); + rcvPack = (PACKET*)malloc(sizeof(PACKET) * nrecv); + // + pc_cart->initPackets(sndPack, rcvPack); + // + // allocate data packets + // + for (i = 0; i < nsend; i++) { + sndPack[i].nints = 2; + sndPack[i].nreals = 2; // obdonors[i]*3+obreceptors[i]+1; + sndPack[i].intData = (int*)malloc(sizeof(int) * sndPack[i].nints); + sndPack[i].realData = + (double*)malloc(sizeof(double) * sndPack[i].nreals); + sndPack[i].intData[0] = 0; + sndPack[i].intData[1] = 1; } - // - pc_cart->sendRecvPackets(sndPack,rcvPack); - pc_cart->clearPackets(sndPack,rcvPack); - TIOGA_FREE(sndMap); - TIOGA_FREE(rcvMap); - TIOGA_FREE(sndPack); - TIOGA_FREE(rcvPack); - printf("checkComm complete in %d\n",myid); + // + pc_cart->sendRecvPackets(sndPack, rcvPack); + pc_cart->clearPackets(sndPack, rcvPack); + TIOGA_FREE(sndMap); + TIOGA_FREE(rcvMap); + TIOGA_FREE(sndPack); + TIOGA_FREE(rcvPack); + printf("checkComm complete in %d\n", myid); } diff --git a/src/exchangeBoxes.C b/src/exchangeBoxes.C index f3ad56b..38df1e8 100644 --- a/src/exchangeBoxes.C +++ b/src/exchangeBoxes.C @@ -16,7 +16,7 @@ // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include #include @@ -32,240 +32,242 @@ using namespace TIOGA; void tioga::exchangeBoxes(void) { - int *sndMap; - int *rcvMap; - int nsend; - int nrecv; - PACKET *sndPack,*rcvPack; - - std::vector nbPerProc(numprocs); // Number of chunks per processor - std::vector obSizePerProc(numprocs); // Number of real data (OBBs) per processor - - MPI_Allgather(&nblocks, 1, MPI_INT, nbPerProc.data(), 1, MPI_INT, scomm); - - // Total number mesh chunks across all procs - int ntotalblks = std::accumulate(nbPerProc.begin(),nbPerProc.end(),0); - - std::vector alltags(ntotalblks); // Mesh tags for all blocks across all procs - std::vector displs(numprocs+1); // Offsets for tags per proc - std::vector sendFlag(numprocs,false); // Flag indicating send/recv from this proc - - displs[0] = 0; - obSizePerProc[0]=nbPerProc[0]*16; - for (int i=1; i <= numprocs; i++) { - displs[i] = displs[i-1] + nbPerProc[i-1]; - if (i < numprocs) obSizePerProc[i]=nbPerProc[i]*16; - } - - MPI_Allgatherv(mytag.data(), nblocks, MPI_INT, alltags.data(), - nbPerProc.data(), displs.data(), MPI_INT, scomm); - - int maxtag = -1; - //for (auto itag: alltags) - for(int i=0;i myOBBdata(nblocks*16); - std::vector allOBBdata(ntotalblks*16); - - int m=0; - for (int ib=0; ib < nblocks; ib++) { - myOBBdata[m++] = (double)mytag[ib]; - for (int i=0; i < 3; i++) - for (int j=0; j< 3; j++) - myOBBdata[m++] = mblocks[ib]->obb->vec[i][j]; - for (int i=0; i< 3; i++) - myOBBdata[m++] = mblocks[ib]->obb->xc[i]; - for (int i=0; i< 3; i++) - myOBBdata[m++] = mblocks[ib]->obb->dxc[i]; - } - - MPI_Allgatherv(myOBBdata.data(), nblocks*16, MPI_DOUBLE, allOBBdata.data(), - obSizePerProc.data(), displs.data(), MPI_DOUBLE, scomm); - - // Determine total number of OBBs received - int nobb = ntotalblks; - - // Store all received OBBs in a temporary list - std::vector obbRecv(nobb); - std::vector obbID(nobb); // Mesh tag corresponding to the OBB - std::vector obbProc(nobb); // Proc ID corresponding to OBB - m=0; - for(int k=0,ix=0;k < numprocs;k++) { - for (int n=0;n < nbPerProc[k];n++) - { - obbProc[ix]=k; - obbID[ix]=(int)(allOBBdata[m++]+0.5); - for (int i=0; i<3; i++) - for (int j=0; j<3; j++) - obbRecv[ix].vec[i][j] = allOBBdata[m++]; - - for (int i=0; i<3; i++) - obbRecv[ix].xc[i] = allOBBdata[m++]; - - for (int i=0; i<3; i++) - obbRecv[ix].dxc[i] = allOBBdata[m++]; - - ix++; + int* sndMap; + int* rcvMap; + int nsend; + int nrecv; + PACKET *sndPack, *rcvPack; + + std::vector nbPerProc(numprocs); // Number of chunks per processor + std::vector obSizePerProc( + numprocs); // Number of real data (OBBs) per processor + + MPI_Allgather(&nblocks, 1, MPI_INT, nbPerProc.data(), 1, MPI_INT, scomm); + + // Total number mesh chunks across all procs + int ntotalblks = std::accumulate(nbPerProc.begin(), nbPerProc.end(), 0); + + std::vector alltags( + ntotalblks); // Mesh tags for all blocks across all procs + std::vector displs(numprocs + 1); // Offsets for tags per proc + std::vector sendFlag( + numprocs, false); // Flag indicating send/recv from this proc + + displs[0] = 0; + obSizePerProc[0] = nbPerProc[0] * 16; + for (int i = 1; i <= numprocs; i++) { + displs[i] = displs[i - 1] + nbPerProc[i - 1]; + if (i < numprocs) obSizePerProc[i] = nbPerProc[i] * 16; } - } - - // Mapping of (local block_id, remote OBB block_id) for every intersected pair - std::vector> intersectIDs; - // Counter tracking number of intersected blocks per partition - std::vector obPerProc(numprocs,0); - - // Reset sendflags - std::fill(sendFlag.begin(), sendFlag.end(), false); - // - // Check for intersection of OBBs - // - nsend=nrecv=numprocs; - for (int ob=0; ob < nobb; ob++) { - for (int ib=0; ib < nblocks; ib++) { - auto& mb = mblocks[ib]; - int meshtag = mb->getMeshTag(); - if (abs(obbID[ob]) == meshtag) continue; - - if ( obbIntersectCheck( - mb->obb->vec, mb->obb->xc, mb->obb->dxc, - obbRecv[ob].vec, obbRecv[ob].xc, obbRecv[ob].dxc) || - obbIntersectCheck( - obbRecv[ob].vec, obbRecv[ob].xc, obbRecv[ob].dxc, - mb->obb->vec, mb->obb->xc, mb->obb->dxc)) { - int overlap_present=1; - if (obbID[ob] < 0 || mytag[ib] < 0) { - mb->check_intersect_p4est(&obbProc[ob],&overlap_present); - } - // If there is an intersection, store the index pair, increment number - // of intersections for this processor, and activate send flag - if (overlap_present) { - intersectIDs.push_back(std::make_pair(ib, ob)); - obPerProc[obbProc[ob]]++; - sendFlag[obbProc[ob]] = true; - } - } + + MPI_Allgatherv( + mytag.data(), nblocks, MPI_INT, alltags.data(), nbPerProc.data(), + displs.data(), MPI_INT, scomm); + + int maxtag = -1; + // for (auto itag: alltags) + for (int i = 0; i < ntotalblks; i++) { + int itag = abs(alltags[i]); + if (maxtag < itag) maxtag = itag; + } + int mxtgsqr = maxtag * maxtag; + + displs[0] = 0; + for (int i = 1; i <= numprocs; i++) { + displs[i] = displs[i - 1] + nbPerProc[i - 1] * 16; + } + + std::vector myOBBdata(nblocks * 16); + std::vector allOBBdata(ntotalblks * 16); + + int m = 0; + for (int ib = 0; ib < nblocks; ib++) { + myOBBdata[m++] = (double)mytag[ib]; + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + myOBBdata[m++] = mblocks[ib]->obb->vec[i][j]; + for (int i = 0; i < 3; i++) myOBBdata[m++] = mblocks[ib]->obb->xc[i]; + for (int i = 0; i < 3; i++) myOBBdata[m++] = mblocks[ib]->obb->dxc[i]; + } + + MPI_Allgatherv( + myOBBdata.data(), nblocks * 16, MPI_DOUBLE, allOBBdata.data(), + obSizePerProc.data(), displs.data(), MPI_DOUBLE, scomm); + + // Determine total number of OBBs received + int nobb = ntotalblks; + + // Store all received OBBs in a temporary list + std::vector obbRecv(nobb); + std::vector obbID(nobb); // Mesh tag corresponding to the OBB + std::vector obbProc(nobb); // Proc ID corresponding to OBB + m = 0; + for (int k = 0, ix = 0; k < numprocs; k++) { + for (int n = 0; n < nbPerProc[k]; n++) { + obbProc[ix] = k; + obbID[ix] = (int)(allOBBdata[m++] + 0.5); + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + obbRecv[ix].vec[i][j] = allOBBdata[m++]; + + for (int i = 0; i < 3; i++) obbRecv[ix].xc[i] = allOBBdata[m++]; + + for (int i = 0; i < 3; i++) obbRecv[ix].dxc[i] = allOBBdata[m++]; + + ix++; + } + } + + // Mapping of (local block_id, remote OBB block_id) for every intersected + // pair + std::vector> intersectIDs; + // Counter tracking number of intersected blocks per partition + std::vector obPerProc(numprocs, 0); + + // Reset sendflags + std::fill(sendFlag.begin(), sendFlag.end(), false); + // + // Check for intersection of OBBs + // + nsend = nrecv = numprocs; + for (int ob = 0; ob < nobb; ob++) { + for (int ib = 0; ib < nblocks; ib++) { + auto& mb = mblocks[ib]; + int meshtag = mb->getMeshTag(); + if (abs(obbID[ob]) == meshtag) continue; + + if (obbIntersectCheck( + mb->obb->vec, mb->obb->xc, mb->obb->dxc, obbRecv[ob].vec, + obbRecv[ob].xc, obbRecv[ob].dxc) || + obbIntersectCheck( + obbRecv[ob].vec, obbRecv[ob].xc, obbRecv[ob].dxc, + mb->obb->vec, mb->obb->xc, mb->obb->dxc)) { + int overlap_present = 1; + if (obbID[ob] < 0 || mytag[ib] < 0) { + mb->check_intersect_p4est(&obbProc[ob], &overlap_present); + } + // If there is an intersection, store the index pair, increment + // number of intersections for this processor, and activate send + // flag + if (overlap_present) { + intersectIDs.push_back(std::make_pair(ib, ob)); + obPerProc[obbProc[ob]]++; + sendFlag[obbProc[ob]] = true; + } + } + } } - } - int new_send = std::count(sendFlag.begin(), sendFlag.end(), true); - assert(new_send <= nsend); - // Populate send and recv maps - std::map invMap; - nsend = nrecv = new_send; - - // allocate sndMap and rcvMap - sndMap = (int*)malloc(sizeof(int) * nsend); - rcvMap = (int*)malloc(sizeof(int) * nrecv); - sndPack=(PACKET *)malloc(sizeof(PACKET)*nsend); - rcvPack=(PACKET *)malloc(sizeof(PACKET)*nrecv); - - for (int p=0, ip=0; p < numprocs; p++) - if (sendFlag[p]) { - sndMap[ip] = p; - rcvMap[ip] = p; - invMap[p] = ip; - ip++; + int new_send = std::count(sendFlag.begin(), sendFlag.end(), true); + assert(new_send <= nsend); + // Populate send and recv maps + std::map invMap; + nsend = nrecv = new_send; + + // allocate sndMap and rcvMap + sndMap = (int*)malloc(sizeof(int) * nsend); + rcvMap = (int*)malloc(sizeof(int) * nrecv); + sndPack = (PACKET*)malloc(sizeof(PACKET) * nsend); + rcvPack = (PACKET*)malloc(sizeof(PACKET) * nrecv); + + for (int p = 0, ip = 0; p < numprocs; p++) + if (sendFlag[p]) { + sndMap[ip] = p; + rcvMap[ip] = p; + invMap[p] = ip; + ip++; + } + + // clear packets before nsend and nrecv are modified in pc->setMap + pc->setMap(nsend, nrecv, sndMap, rcvMap); + pc->initPackets(sndPack, rcvPack); + + // if (obblist) TIOGA_FREE(obblist); + // obblist = (OBB*) malloc(sizeof(OBB) * intersectIDs.size()); + intBoxMap.clear(); + ibsPerProc.clear(); + ibProcMap.clear(); + obblist.clear(); + obblist.resize(intersectIDs.size()); + ibsPerProc.resize(nsend); + ibProcMap.resize(nsend); + + // Determine packet sizes and reallocate arrays + for (int k = 0; k < nsend; k++) { + sndPack[k].nints = 3 * obPerProc[sndMap[k]]; + sndPack[k].nreals = sndPack[k].nints * 6; + sndPack[k].intData = (int*)malloc(sizeof(int) * sndPack[k].nints); + sndPack[k].realData = + (double*)malloc(sizeof(double) * sndPack[k].nreals); + ibsPerProc[k] = obPerProc[sndMap[k]]; + ibProcMap[k].resize(ibsPerProc[k]); } - // clear packets before nsend and nrecv are modified in pc->setMap - pc->setMap(nsend,nrecv,sndMap,rcvMap); - pc->initPackets(sndPack,rcvPack); - - - // if (obblist) TIOGA_FREE(obblist); - // obblist = (OBB*) malloc(sizeof(OBB) * intersectIDs.size()); - intBoxMap.clear(); - ibsPerProc.clear(); - ibProcMap.clear(); - obblist.clear(); - obblist.resize(intersectIDs.size()); - ibsPerProc.resize(nsend); - ibProcMap.resize(nsend); - - // Determine packet sizes and reallocate arrays - for(int k=0; k < nsend; k++) { - sndPack[k].nints = 3 * obPerProc[sndMap[k]]; - sndPack[k].nreals = sndPack[k].nints * 6; - sndPack[k].intData = (int*) malloc(sizeof(int)*sndPack[k].nints); - sndPack[k].realData = (double*) malloc(sizeof(double)*sndPack[k].nreals); - ibsPerProc[k] = obPerProc[sndMap[k]]; - ibProcMap[k].resize(ibsPerProc[k]); - } - - // Array tracking indices for populating reduced OBBs - std::vector idxOffset(nsend,0); - for (size_t i=0; igetMeshTag(); - sndPack[k].intData[3*ioff+1] = ib; - sndPack[k].intData[3*ioff+2] = mb->getMeshTag(); - //mb->getReducedOBB2(&obbRecv[ob], &(sndPack[k].realData[roff])); - mb->getReducedOBB(&obbRecv[ob], &(sndPack[k].realData[roff])); - - for(int ii=0; ii<3; ii++) - for(int j=0; j<3; j++) - obblist[i].vec[ii][j] = obbRecv[ob].vec[ii][j]; - - // Increment index offset for next fill - idxOffset[k]++; - // std::cout << "# " << myid << " " << obbProc[ob] << " " - // << mtags[ib] << " " << obbID[ob] << " " - // << std::setw(3) << key_recv << " " - // << std::setw(3) << key_send << std::endl; - } - pc->sendRecvPackets(sndPack,rcvPack); - - for (int k=0; k idxOffset(nsend, 0); + for (size_t i = 0; i < intersectIDs.size(); i++) { + auto ids = intersectIDs[i]; + int ib = ids.first; // Block ID of the local mesh block + int ob = ids.second; // Index of the intersected block in OBB list + int k = invMap[obbProc[ob]]; // Index in sndMap for this proc ID + auto& mb = mblocks[ib]; // Mesh block data object + int ip = obbProc[ob]; + + int ioff = idxOffset[k]; // Index to fill in sndPack + int roff = idxOffset[k] * 6; + + int key_recv = mxtgsqr * ip + maxtag * (mtags[ib] - 1) + obbID[ob] - 1; + int key_send = + mxtgsqr * myid + maxtag * (obbID[ob] - 1) + (mtags[ib] - 1); + intBoxMap[key_recv] = i; + ibProcMap[k][ioff] = i; + obblist[i].comm_idx = k; + obblist[i].iblk_local = ib; + // obblist[i].iblk_remote = obbID[ob]; + obblist[i].send_tag = key_send; + obblist[i].recv_tag = key_recv; + + sndPack[k].intData[3 * ioff] = key_send; // mb->getMeshTag(); + sndPack[k].intData[3 * ioff + 1] = ib; + sndPack[k].intData[3 * ioff + 2] = mb->getMeshTag(); + // mb->getReducedOBB2(&obbRecv[ob], &(sndPack[k].realData[roff])); + mb->getReducedOBB(&obbRecv[ob], &(sndPack[k].realData[roff])); + + for (int ii = 0; ii < 3; ii++) + for (int j = 0; j < 3; j++) + obblist[i].vec[ii][j] = obbRecv[ob].vec[ii][j]; + + // Increment index offset for next fill + idxOffset[k]++; + // std::cout << "# " << myid << " " << obbProc[ob] << " " + // << mtags[ib] << " " << obbID[ob] << " " + // << std::setw(3) << key_recv << " " + // << std::setw(3) << key_send << std::endl; + } + pc->sendRecvPackets(sndPack, rcvPack); + + for (int k = 0; k < nrecv; k++) { + int m = 0; + + for (int n = 0; n < rcvPack[k].nints; n += 3) { + int key = rcvPack[k].intData[n]; + int ii = intBoxMap[key]; + obblist[ii].iblk_remote = rcvPack[k].intData[n + 1]; + obblist[ii].tag_remote = rcvPack[k].intData[n + 2]; + for (int i = 0; i < 3; i++) + obblist[ii].xc[i] = rcvPack[k].realData[m++]; + + for (int i = 0; i < 3; i++) + obblist[ii].dxc[i] = rcvPack[k].realData[m++]; + } } - } - - pc->clearPackets(sndPack,rcvPack); - // - // Free local memory - // - TIOGA_FREE(sndMap); - TIOGA_FREE(rcvMap); - TIOGA_FREE(sndPack); - TIOGA_FREE(rcvPack); + + pc->clearPackets(sndPack, rcvPack); + // + // Free local memory + // + TIOGA_FREE(sndMap); + TIOGA_FREE(rcvMap); + TIOGA_FREE(sndPack); + TIOGA_FREE(rcvPack); } diff --git a/src/exchangeDonors.C b/src/exchangeDonors.C index 4e50f66..7da7888 100644 --- a/src/exchangeDonors.C +++ b/src/exchangeDonors.C @@ -16,7 +16,7 @@ // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include #include "codetypes.h" @@ -26,309 +26,303 @@ using namespace TIOGA; void tioga::exchangeDonors(void) { - int nsend,nrecv; - int *sndMap; - int *rcvMap; - PACKET *sndPack,*rcvPack; - // - // get the processor map for sending - // and receiving - // - pc->getMap(&nsend,&nrecv,&sndMap,&rcvMap); - if (nsend == 0) return; - // - // create packets to send and receive - // and initialize them to zero - // - sndPack=(PACKET *)malloc(sizeof(PACKET)*nsend); - rcvPack=(PACKET *)malloc(sizeof(PACKET)*nrecv); - // - pc->initPackets(sndPack,rcvPack); + int nsend, nrecv; + int* sndMap; + int* rcvMap; + PACKET *sndPack, *rcvPack; + // + // get the processor map for sending + // and receiving + // + pc->getMap(&nsend, &nrecv, &sndMap, &rcvMap); + if (nsend == 0) return; + // + // create packets to send and receive + // and initialize them to zero + // + sndPack = (PACKET*)malloc(sizeof(PACKET) * nsend); + rcvPack = (PACKET*)malloc(sizeof(PACKET) * nrecv); + // + pc->initPackets(sndPack, rcvPack); - std::vector nintsSend(nsend,0), nrealsSend(nsend,0); + std::vector nintsSend(nsend, 0), nrealsSend(nsend, 0); - // First pass through all mesh blocks and determine data sizes for each - // intersection pair - for (int ib=0;ibgetMBDonorPktSizes(nintsSend, nrealsSend); - } - // - // Allocate sndPack - // - for(int k=0;kgetMBDonorPktSizes(nintsSend, nrealsSend); } - // - // Populate send packets with data from each mesh block in this partition - // - std::vector ixOffset(nsend,0), rxOffset(nsend,0); - for (int ib=0;ibgetMBDonorPackets(ixOffset, rxOffset, sndPack); - } - // - // communicate donors (comm1) - // - pc->sendRecvPackets(sndPack,rcvPack); - // Initialize linked lists and populate donor data from rcvPack - for (int ib=0;ibinitializeDonorList(); - } - // - for (int k=0; kinsertAndSort(pointid, k, meshtag, remoteid, donorRes,receptorRes); - } - } - // - // Figure out the state of each point (i.e., if it is a hole, fringe, or a - // field point) - // - std::vector nrecords(nblocks,0); - int** donorRecords = (int**)malloc(sizeof(int*)*nblocks); - double** receptorResolution = (double**)malloc(sizeof(double*)*nblocks); - if (USE_ADAPTIVE_HOLEMAP) { - for (int ib=0; ibprocessDonors(adaptiveHoleMap, nmesh, &(donorRecords[ib]), - &(receptorResolution[ib]),&(nrecords[ib])); + // + // Allocate sndPack + // + for (int k = 0; k < nsend; k++) { + sndPack[k].nints = nintsSend[k]; + sndPack[k].nreals = nrealsSend[k]; + sndPack[k].intData = (int*)malloc(sizeof(int) * sndPack[k].nints); + sndPack[k].realData = + (double*)malloc(sizeof(double) * sndPack[k].nreals); } - } else { - for (int ib=0; ibprocessDonors(holeMap, nmesh, &(donorRecords[ib]), - &(receptorResolution[ib]),&(nrecords[ib])); + // + // Populate send packets with data from each mesh block in this partition + // + std::vector ixOffset(nsend, 0), rxOffset(nsend, 0); + for (int ib = 0; ib < nblocks; ib++) { + auto& mb = mblocks[ib]; + mb->getMBDonorPackets(ixOffset, rxOffset, sndPack); + } + // + // communicate donors (comm1) + // + pc->sendRecvPackets(sndPack, rcvPack); + // Initialize linked lists and populate donor data from rcvPack + for (int ib = 0; ib < nblocks; ib++) { + auto& mb = mblocks[ib]; + mb->initializeDonorList(); + } + // + for (int k = 0; k < nrecv; k++) { + int m = 0; + int l = 0; + for (int i = 0; i < rcvPack[k].nints / 4; i++) { + int meshtag = rcvPack[k].intData[m++]; + int pointid = rcvPack[k].intData[m++]; + int remoteid = rcvPack[k].intData[m++]; + int ib = rcvPack[k].intData[m++]; + double donorRes = rcvPack[k].realData[l++]; + double receptorRes = rcvPack[k].realData[l++]; + auto& mb = mblocks[ib]; + mb->insertAndSort( + pointid, k, meshtag, remoteid, donorRes, receptorRes); + } + } + // + // Figure out the state of each point (i.e., if it is a hole, fringe, or a + // field point) + // + std::vector nrecords(nblocks, 0); + int** donorRecords = (int**)malloc(sizeof(int*) * nblocks); + double** receptorResolution = (double**)malloc(sizeof(double*) * nblocks); + if (USE_ADAPTIVE_HOLEMAP) { + for (int ib = 0; ib < nblocks; ib++) { + auto& mb = mblocks[ib]; + mb->processDonors( + adaptiveHoleMap, nmesh, &(donorRecords[ib]), + &(receptorResolution[ib]), &(nrecords[ib])); + } + } else { + for (int ib = 0; ib < nblocks; ib++) { + auto& mb = mblocks[ib]; + mb->processDonors( + holeMap, nmesh, &(donorRecords[ib]), &(receptorResolution[ib]), + &(nrecords[ib])); + } } - } - // - // Reset all send/recv data structures - // - pc->clearPackets(sndPack, rcvPack); - for (int i=0; iclearPackets(sndPack, rcvPack); + for (int i = 0; i < nsend; i++) { + sndPack[i].nints = 0; + sndPack[i].nreals = 0; + nintsSend[i] = 0; + nrealsSend[i] = 0; + ixOffset[i] = 0; + rxOffset[i] = 0; + } - for (int n=0; nsendRecvPackets(sndPack,rcvPack); + // + // comm 2 + // notify donors that they are accepted (for now) + // + pc->sendRecvPackets(sndPack, rcvPack); - std::vector ninterp(nblocks,0); - for(int k=0;k ninterp(nblocks, 0); + for (int k = 0; k < nrecv; k++) { + int m = 0; + for (int j = 0; j < rcvPack[k].nints / 2; j++) { + m++; // skip over point id + int ib = tag_iblk_map[rcvPack[k].intData[m++]]; + ninterp[ib]++; + } } - for (int i=0; iinitializeInterpList(ninterp[i]); - } + for (int i = 0; i < nblocks; i++) { + mblocks[i]->initializeInterpList(ninterp[i]); + } - std::fill(ninterp.begin(), ninterp.end(), 0); + std::fill(ninterp.begin(), ninterp.end(), 0); - for(int k=0; k < nrecv;k++) - { - int l=0; - int m=0; - for(int j=0;j< rcvPack[k].nints/2;j++) - { - int recid=rcvPack[k].intData[m++]; - int ib = tag_iblk_map[rcvPack[k].intData[m++]]; - double receptorRes=rcvPack[k].realData[l++]; - mblocks[ib]->findInterpData(&(ninterp[ib]),recid,receptorRes); - } + for (int k = 0; k < nrecv; k++) { + int l = 0; + int m = 0; + for (int j = 0; j < rcvPack[k].nints / 2; j++) { + int recid = rcvPack[k].intData[m++]; + int ib = tag_iblk_map[rcvPack[k].intData[m++]]; + double receptorRes = rcvPack[k].realData[l++]; + mblocks[ib]->findInterpData(&(ninterp[ib]), recid, receptorRes); + } } - for (int ib=0; ibset_ninterp(ninterp[ib]); - } + for (int ib = 0; ib < nblocks; ib++) { + mblocks[ib]->set_ninterp(ninterp[ib]); + } - pc->clearPackets(sndPack, rcvPack); - // - // Find cancellation data (based on donor quality) - // - for (int i=0; iclearPackets(sndPack, rcvPack); + // + // Find cancellation data (based on donor quality) + // + for (int i = 0; i < nblocks; i++) { + if (donorRecords[i]) { + TIOGA_FREE(donorRecords[i]); + donorRecords[i] = NULL; + } + nrecords[i] = 0; + mblocks[i]->getCancellationData(&(nrecords[i]), &(donorRecords[i])); } - nrecords[i] = 0; - mblocks[i]->getCancellationData(&(nrecords[i]), - &(donorRecords[i])); - } - std::fill(nintsSend.begin(), nintsSend.end(), 0); - std::fill(ixOffset.begin(), ixOffset.end(), 0); + std::fill(nintsSend.begin(), nintsSend.end(), 0); + std::fill(ixOffset.begin(), ixOffset.end(), 0); - for (int n=0; n < nblocks; n++) { - for (int i=0; isendRecvPackets(sndPack,rcvPack); + // + // communciate cancellation data comm 3 + // + pc->sendRecvPackets(sndPack, rcvPack); - for (int k=0; kcancelDonor(recid); + for (int k = 0; k < nrecv; k++) { + int m = 0; + for (int j = 0; j < rcvPack[k].nints / 2; j++) { + int recid = rcvPack[k].intData[m++]; + int ib = tag_iblk_map[rcvPack[k].intData[m++]]; + mblocks[ib]->cancelDonor(recid); + } } - } - for (int ib=0;ibresetCoincident(); - } + for (int ib = 0; ib < nblocks; ib++) { + auto& mb = mblocks[ib]; + mb->resetCoincident(); + } - // - pc->clearPackets(sndPack, rcvPack); - // - // Find final interpolation data - // - for (int i=0; iclearPackets(sndPack, rcvPack); + // + // Find final interpolation data + // + for (int i = 0; i < nblocks; i++) { + if (donorRecords[i]) { + TIOGA_FREE(donorRecords[i]); + donorRecords[i] = NULL; + } + nrecords[i] = 0; + mblocks[i]->getInterpData(&(nrecords[i]), &(donorRecords[i])); } - nrecords[i] = 0; - mblocks[i]->getInterpData(&(nrecords[i]), - &(donorRecords[i])); - } - std::fill(nintsSend.begin(), nintsSend.end(), 0); - std::fill(ixOffset.begin(), ixOffset.end(), 0); - for (int n=0; n < nblocks; n++) { - for (int i=0; isendRecvPackets(sndPack,rcvPack); - // - for(int ib=0;ibclearIblanks(); + // + // comm 4 + // final receptor data to set iblanks + // + pc->sendRecvPackets(sndPack, rcvPack); + // + for (int ib = 0; ib < nblocks; ib++) mblocks[ib]->clearIblanks(); - for (int k=0; ksetIblanks(pointid); - } - } - pc->clearPackets(sndPack,rcvPack); - TIOGA_FREE(sndPack); - TIOGA_FREE(rcvPack); + for (int k = 0; k < nrecv; k++) { + int m = 0; + for (int j = 0; j < rcvPack[k].nints / 2; j++) { + int pointid = rcvPack[k].intData[m++]; + int ib = rcvPack[k].intData[m++]; + mblocks[ib]->setIblanks(pointid); + } + } + pc->clearPackets(sndPack, rcvPack); + TIOGA_FREE(sndPack); + TIOGA_FREE(rcvPack); - if (donorRecords) { - for (int i=0; igetStats(mstats); - mstats_sum[0] += mstats[0]; - mstats_sum[1] += mstats[1]; - } - MPI_Reduce(mstats_sum,mstats_global,2,MPI_INT,MPI_SUM,0,scomm); - if (myid==0) { - printf("#tioga -----------------------------------------\n"); - printf("#tioga : total receptors:\t%d\n",mstats_global[1]); - printf("#tioga : total holes :\t%d\n",mstats_global[0]); - printf("#tioga -----------------------------------------\n"); - } -//#endif + // #ifdef TIOGA_OUTPUT_STATS + int mstats[2], mstats_sum[2], mstats_global[2]; + mstats_sum[0] = 0; + mstats_sum[1] = 0; + for (int ib = 0; ib < nblocks; ib++) { + auto& mb = mblocks[ib]; + mb->getStats(mstats); + mstats_sum[0] += mstats[0]; + mstats_sum[1] += mstats[1]; + } + MPI_Reduce(mstats_sum, mstats_global, 2, MPI_INT, MPI_SUM, 0, scomm); + if (myid == 0) { + printf("#tioga -----------------------------------------\n"); + printf("#tioga : total receptors:\t%d\n", mstats_global[1]); + printf("#tioga : total holes :\t%d\n", mstats_global[0]); + printf("#tioga -----------------------------------------\n"); + } + // #endif } diff --git a/src/exchangeSearchData.C b/src/exchangeSearchData.C index cc661b5..5c8c37a 100644 --- a/src/exchangeSearchData.C +++ b/src/exchangeSearchData.C @@ -16,7 +16,7 @@ // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include #include @@ -28,238 +28,243 @@ using namespace TIOGA; void tioga::exchangeSearchData(int at_points) { - int i; - int nsend, nrecv; - PACKET *sndPack, *rcvPack; - int* sndMap; - int* rcvMap; - // - // get the processor map for sending - // and receiving - // - pc->getMap(&nsend, &nrecv, &sndMap, &rcvMap); - // - // create packets to send and receive - // and initialize them to zero - // - sndPack = (PACKET*)malloc(sizeof(PACKET) * nsend); - rcvPack = (PACKET*)malloc(sizeof(PACKET) * nrecv); - // - for (i = 0; i < nsend; i++) { - sndPack[i].nints = sndPack[i].nreals = 0; - sndPack[i].intData = NULL; - sndPack[i].realData = NULL; - } - // - for (i = 0; i < nrecv; i++) { - rcvPack[i].nints = rcvPack[i].nreals = 0; - rcvPack[i].intData = NULL; - rcvPack[i].realData = NULL; - } + int i; + int nsend, nrecv; + PACKET *sndPack, *rcvPack; + int* sndMap; + int* rcvMap; + // + // get the processor map for sending + // and receiving + // + pc->getMap(&nsend, &nrecv, &sndMap, &rcvMap); + // + // create packets to send and receive + // and initialize them to zero + // + sndPack = (PACKET*)malloc(sizeof(PACKET) * nsend); + rcvPack = (PACKET*)malloc(sizeof(PACKET) * nrecv); + // + for (i = 0; i < nsend; i++) { + sndPack[i].nints = sndPack[i].nreals = 0; + sndPack[i].intData = NULL; + sndPack[i].realData = NULL; + } + // + for (i = 0; i < nrecv; i++) { + rcvPack[i].nints = rcvPack[i].nreals = 0; + rcvPack[i].intData = NULL; + rcvPack[i].realData = NULL; + } - // Process each intersection pair and determine the total data that needs to - // be sent - int nobb = obblist.size(); - std::vector nintsSend(nobb); - std::vector nrealsSend(nobb); - int** int_data = (int**)malloc(sizeof(int*) * nobb); - double** real_data = (double**)malloc(sizeof(double*) * nobb); + // Process each intersection pair and determine the total data that needs to + // be sent + int nobb = obblist.size(); + std::vector nintsSend(nobb); + std::vector nrealsSend(nobb); + int** int_data = (int**)malloc(sizeof(int*) * nobb); + double** real_data = (double**)malloc(sizeof(double*) * nobb); - for (int ii=0; ii < nobb; ii++) { - int ib = obblist[ii].iblk_local; - auto& mb = mblocks[ib]; - if (at_points==0) - { - mb->getQueryPoints2( - &obblist[ii], &nintsSend[ii], &int_data[ii], &nrealsSend[ii], - &real_data[ii]); - } - else - { - mb->getExtraQueryPoints(&obblist[ii], - &nintsSend[ii],&int_data[ii], - &nrealsSend[ii],&real_data[ii]); + for (int ii = 0; ii < nobb; ii++) { + int ib = obblist[ii].iblk_local; + auto& mb = mblocks[ib]; + if (at_points == 0) { + mb->getQueryPoints2( + &obblist[ii], &nintsSend[ii], &int_data[ii], &nrealsSend[ii], + &real_data[ii]); + } else { + mb->getExtraQueryPoints( + &obblist[ii], &nintsSend[ii], &int_data[ii], &nrealsSend[ii], + &real_data[ii]); + } } - } - // Populate send packets and exchange data with other processors - for (int k=0; ksendRecvPackets(sndPack, rcvPack); + pc->sendRecvPackets(sndPack, rcvPack); - // Reset MeshBlock data structures - for (int ib=0;ibnsearch = 0; + // Reset MeshBlock data structures + for (int ib = 0; ib < nblocks; ib++) { + auto& mb = mblocks[ib]; + mb->nsearch = 0; - if (mb->xsearch) { - TIOGA_FREE(mb->xsearch); - mb->xsearch=NULL; - } - if (mb->isearch) { - TIOGA_FREE(mb->isearch); - mb->isearch=NULL; - } - if (mb->tagsearch) { - TIOGA_FREE(mb->tagsearch); - mb->tagsearch=NULL; - } - if (mb->donorId) { - TIOGA_FREE(mb->donorId); - mb->donorId=NULL; - } - if (mb->res_search) { - TIOGA_FREE(mb->res_search); - mb->res_search=NULL; - } - if (at_points==1) { - if (mb->rst) { - TIOGA_FREE(mb->rst); - mb->rst=NULL; - } - } + if (mb->xsearch) { + TIOGA_FREE(mb->xsearch); + mb->xsearch = NULL; + } + if (mb->isearch) { + TIOGA_FREE(mb->isearch); + mb->isearch = NULL; + } + if (mb->tagsearch) { + TIOGA_FREE(mb->tagsearch); + mb->tagsearch = NULL; + } + if (mb->donorId) { + TIOGA_FREE(mb->donorId); + mb->donorId = NULL; + } + if (mb->res_search) { + TIOGA_FREE(mb->res_search); + mb->res_search = NULL; + } + if (at_points == 1) { + if (mb->rst) { + TIOGA_FREE(mb->rst); + mb->rst = NULL; + } + } #ifdef TIOGA_HAS_NODEGID - mb->gid_search.clear(); + mb->gid_search.clear(); #endif - } + } #ifdef TIOGA_HAS_NODEGID - int nintsPerNode = 3; + int nintsPerNode = 3; #else - int nintsPerNode = 1; + int nintsPerNode = 1; #endif - // Loop through recv packets and estimate search array sizes in MeshBlock data - // structures - std::vector nintsRecv(nobb); - std::vector nrealsRecv(nobb); - for (int k=0; k nintsRecv(nobb); + std::vector nrealsRecv(nobb); + for (int k = 0; k < nrecv; k++) { + int m = 0; - for (int i=0; i < ibsPerProc[k]; i++) { - int key = rcvPack[k].intData[m++]; - int ii = intBoxMap[key]; - int ib = obblist[ii].iblk_local; - auto& mb = mblocks[ib]; + for (int i = 0; i < ibsPerProc[k]; i++) { + int key = rcvPack[k].intData[m++]; + int ii = intBoxMap[key]; + int ib = obblist[ii].iblk_local; + auto& mb = mblocks[ib]; - nintsRecv[ii] = rcvPack[k].intData[m++]; - nrealsRecv[ii] = rcvPack[k].intData[m++]; + nintsRecv[ii] = rcvPack[k].intData[m++]; + nrealsRecv[ii] = rcvPack[k].intData[m++]; - // Skip the nodal data (indices and global IDs) - m += nintsRecv[ii]; - // Adjust for node GIDs if available - nintsRecv[ii] /= nintsPerNode; - mb->nsearch += nintsRecv[ii]; + // Skip the nodal data (indices and global IDs) + m += nintsRecv[ii]; + // Adjust for node GIDs if available + nintsRecv[ii] /= nintsPerNode; + mb->nsearch += nintsRecv[ii]; + } } - } - // Resize MeshBlock array sizes - for (int ib=0;ibnsearch < 1) continue; - mb->xsearch = (double*)malloc(sizeof(double) * 3 * mb->nsearch); - mb->res_search = (double*)malloc(sizeof(double) * mb->nsearch); - mb->isearch = (int*)malloc(3 * sizeof(int) * mb->nsearch); - mb->tagsearch = (int*)malloc(sizeof(int) * mb->nsearch); - mb->donorId = (int*)malloc(sizeof(int) * mb->nsearch); + // Resize MeshBlock array sizes + for (int ib = 0; ib < nblocks; ib++) { + auto& mb = mblocks[ib]; + if (mb->nsearch < 1) continue; + mb->xsearch = (double*)malloc(sizeof(double) * 3 * mb->nsearch); + mb->res_search = (double*)malloc(sizeof(double) * mb->nsearch); + mb->isearch = (int*)malloc(3 * sizeof(int) * mb->nsearch); + mb->tagsearch = (int*)malloc(sizeof(int) * mb->nsearch); + mb->donorId = (int*)malloc(sizeof(int) * mb->nsearch); #ifdef TIOGA_HAS_NODEGID - mb->gid_search.resize(mb->nsearch); + mb->gid_search.resize(mb->nsearch); #endif - if (at_points==1) mb->rst = (double*)malloc(sizeof(double) * 3 * mb->nsearch); - } + if (at_points == 1) + mb->rst = (double*)malloc(sizeof(double) * 3 * mb->nsearch); + } - // - // Update search arrays in mesh blocks from recv packets - // - std::vector icOffset(nblocks,0); // Index of isearch arrays where next fill happens - std::vector dcOffset(nblocks, 0); // Index of xsearch arrays where next fill happens - std::vector rcOffset(nblocks, 0); // Index of res_search arrays where next fill happens - std::vector igOffset(nblocks, 0); // Index of gid_search where next fill happens - for (int k=0; k < nrecv; k++) { - int l = 0; - int m = 0; + // + // Update search arrays in mesh blocks from recv packets + // + std::vector icOffset( + nblocks, 0); // Index of isearch arrays where next fill happens + std::vector dcOffset( + nblocks, 0); // Index of xsearch arrays where next fill happens + std::vector rcOffset( + nblocks, 0); // Index of res_search arrays where next fill happens + std::vector igOffset( + nblocks, 0); // Index of gid_search where next fill happens + for (int k = 0; k < nrecv; k++) { + int l = 0; + int m = 0; - for (int i=0; i < ibsPerProc[k]; i++) { - int key = rcvPack[k].intData[m++]; - int ii = intBoxMap[key]; - int ib = obblist[ii].iblk_local; - auto& mb = mblocks[ib]; + for (int i = 0; i < ibsPerProc[k]; i++) { + int key = rcvPack[k].intData[m++]; + int ii = intBoxMap[key]; + int ib = obblist[ii].iblk_local; + auto& mb = mblocks[ib]; - int ioff = icOffset[ib]; - int doff = dcOffset[ib]; - int roff = rcOffset[ib]; - int goff = igOffset[ib]; + int ioff = icOffset[ib]; + int doff = dcOffset[ib]; + int roff = rcOffset[ib]; + int goff = igOffset[ib]; - m += 2; // Skip nints and nreals information - for (int j=0; j < nintsRecv[ii]; j++) { - mb->isearch[ioff++] = k; - mb->isearch[ioff++] = rcvPack[k].intData[m++]; - mb->isearch[ioff++] = obblist[ii].iblk_remote; - mb->tagsearch[ioff/3-1]=obblist[ii].tag_remote; + m += 2; // Skip nints and nreals information + for (int j = 0; j < nintsRecv[ii]; j++) { + mb->isearch[ioff++] = k; + mb->isearch[ioff++] = rcvPack[k].intData[m++]; + mb->isearch[ioff++] = obblist[ii].iblk_remote; + mb->tagsearch[ioff / 3 - 1] = obblist[ii].tag_remote; #ifdef TIOGA_HAS_NODEGID - std::memcpy(&(mb->gid_search[goff]), &(rcvPack[k].intData[m]), sizeof(uint64_t)); - m += 2; - goff++; + std::memcpy( + &(mb->gid_search[goff]), &(rcvPack[k].intData[m]), + sizeof(uint64_t)); + m += 2; + goff++; #endif - } + } - for (int j = 0; j < nrealsRecv[ii] / 4; j++) { - for (int mm = 0; mm < 3; mm++) - mb->xsearch[doff++] = rcvPack[k].realData[l++]; - mb->res_search[roff++] = rcvPack[k].realData[l++]; - } + for (int j = 0; j < nrealsRecv[ii] / 4; j++) { + for (int mm = 0; mm < 3; mm++) + mb->xsearch[doff++] = rcvPack[k].realData[l++]; + mb->res_search[roff++] = rcvPack[k].realData[l++]; + } - icOffset[ib] = ioff; - dcOffset[ib] = doff; - rcOffset[ib] = roff; - igOffset[ib] = goff; + icOffset[ib] = ioff; + dcOffset[ib] = doff; + rcOffset[ib] = roff; + igOffset[ib] = goff; + } } - } - pc->clearPackets(sndPack, rcvPack); - TIOGA_FREE(sndPack); - TIOGA_FREE(rcvPack); - // printf("%d %d\n",myid,mb->nsearch); + pc->clearPackets(sndPack, rcvPack); + TIOGA_FREE(sndPack); + TIOGA_FREE(rcvPack); + // printf("%d %d\n",myid,mb->nsearch); - if (int_data) { - for (int i=0; inumprocs); - for(int i=0;inumprocs;i++) pmap[i]=0; - // - OBB* obcart=(OBB *)malloc(sizeof(OBB)); - for(int j=0;j<3;j++) - for(int k=0;k<3;k++) - obcart->vec[j][k]=0; - obcart->vec[0][0]=obcart->vec[1][1]=obcart->vec[2][2]=1.0; - // - head=(INTEGERLIST2 *) malloc(sizeof(INTEGERLIST2)); - head->intData=NULL; - head->realData=NULL; - dataPtr=head; - dataPtr->next=NULL; - // - nsearch=0; - // - for(int c=0;cngrids;c++) - { - int cell_count = (cg->dims[3*c]+2*cg->nf) - * (cg->dims[3*c+1]+2*cg->nf) - * (cg->dims[3*c+2]+2*cg->nf); - - int vol = cg->dx[3*c]*cg->dx[3*c+1]*cg->dx[3*c+2]; - - for(int n=0;n<3;n++) - { - obcart->dxc[n]=cg->dx[3*c+n]*(cg->dims[3*c+n])*0.5; - obcart->xc[n]=cg->xlo[3*c+n]+obcart->dxc[n]; + INTEGERLIST2* head; + INTEGERLIST2* dataPtr; + // + // limit case we communicate to everybody + // + int* pmap = (int*)malloc(sizeof(int) * pc->numprocs); + for (int i = 0; i < pc->numprocs; i++) pmap[i] = 0; + // + OBB* obcart = (OBB*)malloc(sizeof(OBB)); + for (int j = 0; j < 3; j++) + for (int k = 0; k < 3; k++) obcart->vec[j][k] = 0; + obcart->vec[0][0] = obcart->vec[1][1] = obcart->vec[2][2] = 1.0; + // + head = (INTEGERLIST2*)malloc(sizeof(INTEGERLIST2)); + head->intData = NULL; + head->realData = NULL; + dataPtr = head; + dataPtr->next = NULL; + // + nsearch = 0; + // + for (int c = 0; c < cg->ngrids; c++) { + int cell_count = (cg->dims[3 * c] + 2 * cg->nf) * + (cg->dims[3 * c + 1] + 2 * cg->nf) * + (cg->dims[3 * c + 2] + 2 * cg->nf); + + int vol = cg->dx[3 * c] * cg->dx[3 * c + 1] * cg->dx[3 * c + 2]; + + for (int n = 0; n < 3; n++) { + obcart->dxc[n] = cg->dx[3 * c + n] * (cg->dims[3 * c + n]) * 0.5; + obcart->xc[n] = cg->xlo[3 * c + n] + obcart->dxc[n]; + } + + int intersectCount = 0; + if (obbIntersectCheck( + obb->vec, obb->xc, obb->dxc, obcart->vec, obcart->xc, + obcart->dxc) || + obbIntersectCheck( + obcart->vec, obcart->xc, obcart->dxc, obb->vec, obb->xc, + obb->dxc)) { + intersectCount++; + + double* xtm = (double*)malloc(sizeof(double) * 3); + + for (int j = 0; j < cg->dims[3 * c]; j++) + for (int k = 0; k < cg->dims[3 * c + 1]; k++) + for (int l = 0; l < cg->dims[3 * c + 2]; l++) + fillReceptorDataPtr( + cg, cell_count, c, j, k, l, pmap, vol, xtm, false, + dataPtr); + + for (int j = 0; j < cg->dims[3 * c] + 1; j++) + for (int k = 0; k < cg->dims[3 * c + 1] + 1; k++) + for (int l = 0; l < cg->dims[3 * c + 2] + 1; l++) + fillReceptorDataPtr( + cg, cell_count, c, j, k, l, pmap, vol, xtm, true, + dataPtr); + + TIOGA_FREE(xtm); + } } - - int intersectCount = 0; - if (obbIntersectCheck(obb->vec,obb->xc,obb->dxc, - obcart->vec,obcart->xc,obcart->dxc) || - obbIntersectCheck(obcart->vec,obcart->xc,obcart->dxc, - obb->vec,obb->xc,obb->dxc)) - { - intersectCount++; - - double* xtm=(double *)malloc(sizeof(double)*3); - - for(int j=0;jdims[3*c];j++) - for(int k=0;kdims[3*c+1];k++) - for(int l=0;ldims[3*c+2];l++) - fillReceptorDataPtr(cg,cell_count,c,j,k,l,pmap,vol,xtm,false,dataPtr); - - for(int j=0;jdims[3*c]+1;j++) - for(int k=0;kdims[3*c+1]+1;k++) - for(int l=0;ldims[3*c+2]+1;l++) - fillReceptorDataPtr(cg,cell_count,c,j,k,l,pmap,vol,xtm,true,dataPtr); - - TIOGA_FREE(xtm); + // + // create the communication map + // + int nsend = 0; + for (int i = 0; i < pc->numprocs; i++) + if (pmap[i] == 1) nsend++; + int nrecv = nsend; + int* sndMap = (int*)malloc(sizeof(int) * nsend); + int* rcvMap = (int*)malloc(sizeof(int) * nrecv); + int m = 0; + for (int i = 0; i < pc->numprocs; i++) { + if (pmap[i] == 1) { + sndMap[m] = rcvMap[m] = i; + m++; + } } - } - // - // create the communication map - // - int nsend=0; - for(int i=0;inumprocs;i++) if (pmap[i]==1) nsend++; - int nrecv=nsend; - int* sndMap=(int *)malloc(sizeof(int)*nsend); - int* rcvMap=(int *)malloc(sizeof(int)*nrecv); - int m=0; - for(int i=0;inumprocs;i++) - { - if (pmap[i]==1) - { - sndMap[m]=rcvMap[m]=i; - m++; + pc->setMap(nsend, nrecv, sndMap, rcvMap); + // + // if these were already allocated + // get rid of them + // + if (donorId) TIOGA_FREE(donorId); + if (tagsearch) TIOGA_FREE(tagsearch); + if (isearch) TIOGA_FREE(isearch); + if (rst) TIOGA_FREE(rst); + if (res_search) TIOGA_FREE(res_search); + if (xsearch) TIOGA_FREE(xsearch); + // + donorId = (int*)malloc(sizeof(int) * nsearch); + tagsearch = (int*)malloc(sizeof(int) * nsearch); + isearch = (int*)malloc(3 * sizeof(int) * nsearch); + res_search = (double*)malloc(sizeof(double) * nsearch); + xsearch = (double*)malloc(sizeof(double) * 3 * nsearch); + rst = (double*)malloc(sizeof(double) * 3 * nsearch); + // + dataPtr = head->next; + int k = 0, l = 0, n = 0, p = 0; + while (dataPtr != NULL) { + for (int j = 0; j < dataPtr->intDataSize - 1; j++) + isearch[p++] = dataPtr->intData[j]; + tagsearch[k++] = dataPtr->intData[dataPtr->intDataSize - 1]; + + for (int j = 0; j < dataPtr->realDataSize - 1; j++) + xsearch[n++] = dataPtr->realData[j]; + res_search[l++] = dataPtr->realData[dataPtr->realDataSize - 1]; + + dataPtr = dataPtr->next; } - } - pc->setMap(nsend,nrecv,sndMap,rcvMap); - // - // if these were already allocated - // get rid of them - // - if (donorId) TIOGA_FREE(donorId); - if (tagsearch) TIOGA_FREE(tagsearch); - if (isearch) TIOGA_FREE(isearch); - if (rst) TIOGA_FREE(rst); - if (res_search) TIOGA_FREE(res_search); - if (xsearch) TIOGA_FREE(xsearch); - // - donorId=(int *)malloc(sizeof(int)*nsearch); - tagsearch=(int *)malloc(sizeof(int)*nsearch); - isearch=(int *)malloc(3*sizeof(int)*nsearch); - res_search=(double *)malloc(sizeof(double)*nsearch); - xsearch=(double *)malloc(sizeof(double)*3*nsearch); - rst=(double *) malloc(sizeof(double)*3*nsearch); - // - dataPtr=head->next; - int k=0,l=0,n=0,p=0; - while(dataPtr!=NULL) - { - for(int j=0;jintDataSize-1;j++) - isearch[p++]=dataPtr->intData[j]; - tagsearch[k++]=dataPtr->intData[dataPtr->intDataSize-1]; - - for(int j=0;jrealDataSize-1;j++) - xsearch[n++]=dataPtr->realData[j]; - res_search[l++]=dataPtr->realData[dataPtr->realDataSize-1]; - - dataPtr=dataPtr->next; - } - - deallocateLinkList3(head); - //fclose(fp); - TIOGA_FREE(obcart); - TIOGA_FREE(pmap); - TIOGA_FREE(sndMap); - TIOGA_FREE(rcvMap); + + deallocateLinkList3(head); + // fclose(fp); + TIOGA_FREE(obcart); + TIOGA_FREE(pmap); + TIOGA_FREE(sndMap); + TIOGA_FREE(rcvMap); } -void MeshBlock::fillReceptorDataPtr(CartGrid *cg,int cell_count,int c,int j,int k,int l,int* pmap, - double vol,double* xtm,bool isNodal,INTEGERLIST2*& dataPtr) +void MeshBlock::fillReceptorDataPtr( + CartGrid* cg, + int cell_count, + int c, + int j, + int k, + int l, + int* pmap, + double vol, + double* xtm, + bool isNodal, + INTEGERLIST2*& dataPtr) { - int itm = -1; - if(isNodal){ - itm = cart_utils::get_concatenated_node_index( - cg->dims[3*c],cg->dims[3*c+1],cg->dims[3*c+2],cg->nf,j,k,l); - - xtm[0] = cg->xlo[3*c] + j*cg->dx[3*c]; - xtm[1] = cg->xlo[3*c+1] + k*cg->dx[3*c+1]; - xtm[2] = cg->xlo[3*c+2] + l*cg->dx[3*c+2]; - } - else { - itm = cart_utils::get_cell_index(cg->dims[3*c],cg->dims[3*c+1], - cg->nf,j,k,l); - - xtm[0] = cg->xlo[3*c] + (j+0.5)*cg->dx[3*c]; - xtm[1] = cg->xlo[3*c+1] + (k+0.5)*cg->dx[3*c+1]; - xtm[2] = cg->xlo[3*c+2] + (l+0.5)*cg->dx[3*c+2]; - } - - - double xd[3]; - for(int jj=0;jj<3;jj++) xd[jj]=0; - for(int jj=0;jj<3;jj++) - for(int kk=0;kk<3;kk++) - xd[jj]+=(xtm[kk]-obb->xc[kk])*obb->vec[jj][kk]; - - int iflag=0; - if (fabs(xd[0]) <= obb->dxc[0] && - fabs(xd[1]) <= obb->dxc[1] && - fabs(xd[2]) <= obb->dxc[2]) - iflag++; - - if (iflag > 0) - { - pmap[cg->proc_id[c]]=1; - dataPtr->next=(INTEGERLIST2 *) malloc(sizeof(INTEGERLIST2)); - dataPtr=dataPtr->next; - dataPtr->intDataSize=4; - dataPtr->realDataSize=4; - dataPtr->realData=(double *) malloc(sizeof(double)*dataPtr->realDataSize); - dataPtr->intData=(int *) malloc(sizeof(int)*dataPtr->intDataSize); - dataPtr->intData[0]=cg->proc_id[c]; - dataPtr->intData[1]=cg->local_id[c]; - dataPtr->intData[2]=itm; - dataPtr->intData[3]=0; - nsearch+=1; - - for(int kk=0;kkrealDataSize-1;kk++) - dataPtr->realData[kk]=xtm[kk]; - - dataPtr->realData[dataPtr->realDataSize-1]=vol; - - dataPtr->next=NULL; - } + int itm = -1; + if (isNodal) { + itm = cart_utils::get_concatenated_node_index( + cg->dims[3 * c], cg->dims[3 * c + 1], cg->dims[3 * c + 2], cg->nf, + j, k, l); + + xtm[0] = cg->xlo[3 * c] + j * cg->dx[3 * c]; + xtm[1] = cg->xlo[3 * c + 1] + k * cg->dx[3 * c + 1]; + xtm[2] = cg->xlo[3 * c + 2] + l * cg->dx[3 * c + 2]; + } else { + itm = cart_utils::get_cell_index( + cg->dims[3 * c], cg->dims[3 * c + 1], cg->nf, j, k, l); + + xtm[0] = cg->xlo[3 * c] + (j + 0.5) * cg->dx[3 * c]; + xtm[1] = cg->xlo[3 * c + 1] + (k + 0.5) * cg->dx[3 * c + 1]; + xtm[2] = cg->xlo[3 * c + 2] + (l + 0.5) * cg->dx[3 * c + 2]; + } + + double xd[3]; + for (int jj = 0; jj < 3; jj++) xd[jj] = 0; + for (int jj = 0; jj < 3; jj++) + for (int kk = 0; kk < 3; kk++) + xd[jj] += (xtm[kk] - obb->xc[kk]) * obb->vec[jj][kk]; + + int iflag = 0; + if (fabs(xd[0]) <= obb->dxc[0] && fabs(xd[1]) <= obb->dxc[1] && + fabs(xd[2]) <= obb->dxc[2]) + iflag++; + + if (iflag > 0) { + pmap[cg->proc_id[c]] = 1; + dataPtr->next = (INTEGERLIST2*)malloc(sizeof(INTEGERLIST2)); + dataPtr = dataPtr->next; + dataPtr->intDataSize = 4; + dataPtr->realDataSize = 4; + dataPtr->realData = + (double*)malloc(sizeof(double) * dataPtr->realDataSize); + dataPtr->intData = (int*)malloc(sizeof(int) * dataPtr->intDataSize); + dataPtr->intData[0] = cg->proc_id[c]; + dataPtr->intData[1] = cg->local_id[c]; + dataPtr->intData[2] = itm; + dataPtr->intData[3] = 0; + nsearch += 1; + + for (int kk = 0; kk < dataPtr->realDataSize - 1; kk++) + dataPtr->realData[kk] = xtm[kk]; + + dataPtr->realData[dataPtr->realDataSize - 1] = vol; + + dataPtr->next = NULL; + } } diff --git a/src/globals.h b/src/globals.h index e3870c2..1fa6b28 100644 --- a/src/globals.h +++ b/src/globals.h @@ -28,15 +28,16 @@ #include "tioga.h" using namespace TIOGA; #define MAXBLOCKS 100 -tioga *tg; +tioga* tg; /* ** pointer storage for connectivity arrays that ** comes from external solver */ -typedef struct inpdata { - int **vconn; - int *nc; - int *nv; +typedef struct inpdata +{ + int** vconn; + int* nc; + int* nv; } inpdata; inpdata idata[MAXBLOCKS]; diff --git a/src/highOrder.C b/src/highOrder.C index f4025cb..2b7846b 100644 --- a/src/highOrder.C +++ b/src/highOrder.C @@ -16,7 +16,7 @@ // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include "codetypes.h" #include "MeshBlock.h" #include "tioga_utils.h" @@ -28,539 +28,475 @@ void MeshBlock::getCellIblanks2(void) { - int i; - int n,nvert,m; - int icell; - int inode[8]; - int ncount,flag; - int verbose; + int i; + int n, nvert, m; + int icell; + int inode[8]; + int ncount, flag; + int verbose; - icell=0; - if (iblank_cell==NULL) iblank_cell=(int *)malloc(sizeof(int)*ncells); - for(n=0;n 0) iblank_cell[icell]=-1; - // if (ncount >= nvert/2) iblank_cell[icell]=-1; + if (flag) { + if (ncount == nvert) iblank_cell[icell] = -1; + // if (ncount > 0) iblank_cell[icell]=-1; + // if (ncount >= nvert/2) iblank_cell[icell]=-1; } - icell++; + icell++; } } } - void MeshBlock::getCellIblanks(void) { - int i; - int n,nvert,m; - int icell; - int inode[8]; - int ncount,flag; - int verbose; - int *ibl; - - if (iblank_reduced) - { - ibl=iblank_reduced; - } - else - { - ibl=iblank; + int i; + int n, nvert, m; + int icell; + int inode[8]; + int ncount, flag; + int verbose; + int* ibl; + + if (iblank_reduced) { + ibl = iblank_reduced; + } else { + ibl = iblank; } - icell=0; - if (iblank_cell==NULL) iblank_cell=(int *)malloc(sizeof(int)*ncells); - for(n=0;n 0) iblank_cell[icell]=-1; -// if (ncount >= nvert/2) iblank_cell[icell]=-1; - } - icell++; - } + icell = 0; + if (iblank_cell == NULL) iblank_cell = (int*)malloc(sizeof(int) * ncells); + for (n = 0; n < ntypes; n++) { + nvert = nv[n]; + for (i = 0; i < nc[n]; i++) { + flag = 1; + iblank_cell[icell] = 1; + verbose = 0; + // if (myid==763 && icell==7975) { + // verbose=1; + // } + ncount = 0; + for (m = 0; m < nvert && flag; m++) { + inode[m] = vconn[n][nvert * i + m] - BASE; + if (verbose) { + TRACEI(m); + TRACEI(inode[m]); + TRACEI(ibl[inode[m]]); + } + if (ibl[inode[m]] == 0) { + iblank_cell[icell] = 0; + flag = 0; + } + ncount = ncount + (ibl[inode[m]] == -1); + } + if (verbose) { + TRACEI(icell); + TRACEI(ncount); + TRACEI(nvert); + } + if (flag) { + if (ncount == nvert) iblank_cell[icell] = -1; + // if (ncount > 0) iblank_cell[icell]=-1; + // if (ncount >= nvert/2) iblank_cell[icell]=-1; + } + icell++; + } } } -void MeshBlock::clearOrphans(HOLEMAP *holemap, int nmesh,int *itmp) +void MeshBlock::clearOrphans(HOLEMAP* holemap, int nmesh, int* itmp) { - int i,j,k,m; - int reject; + int i, j, k, m; + int reject; - if (ihigh) - { - m=0; - for(i=0;ixc[k])*obc->vec[j][k]; + inode = (int*)malloc(sizeof(int) * ntotalPoints); + *nints = *nreals = 0; + for (i = 0; i < ntotalPoints; i++) { + i3 = 3 * i; + for (j = 0; j < 3; j++) xd[j] = 0; + for (j = 0; j < 3; j++) + for (k = 0; k < 3; k++) + xd[j] += (rxyz[i3 + k] - obc->xc[k]) * obc->vec[j][k]; - if (fabs(xd[0]) <= obc->dxc[0] && - fabs(xd[1]) <= obc->dxc[1] && - fabs(xd[2]) <= obc->dxc[2]) - { - inode[*nints]=i; - (*nints)++; - (*nreals)+=4; - - } + if (fabs(xd[0]) <= obc->dxc[0] && fabs(xd[1]) <= obc->dxc[1] && + fabs(xd[2]) <= obc->dxc[2]) { + inode[*nints] = i; + (*nints)++; + (*nreals) += 4; + } } - // - (*intData)=(int *)malloc(sizeof(int)*(*nints)); - (*realData)=(double *)malloc(sizeof(double)*(*nreals)); - // - m=0; - for(i=0;i<*nints;i++) - { - i3=3*inode[i]; - (*intData)[i]=inode[i]; - (*realData)[m++]=rxyz[i3]; - (*realData)[m++]=rxyz[i3+1]; - (*realData)[m++]=rxyz[i3+2]; - (*realData)[m++]=BIGVALUE; + // + (*intData) = (int*)malloc(sizeof(int) * (*nints)); + (*realData) = (double*)malloc(sizeof(double) * (*nreals)); + // + m = 0; + for (i = 0; i < *nints; i++) { + i3 = 3 * inode[i]; + (*intData)[i] = inode[i]; + (*realData)[m++] = rxyz[i3]; + (*realData)[m++] = rxyz[i3 + 1]; + (*realData)[m++] = rxyz[i3 + 2]; + (*realData)[m++] = BIGVALUE; } - // - TIOGA_FREE(inode); -} + // + TIOGA_FREE(inode); +} void MeshBlock::processPointDonors(void) { - int i,j,m,n; - int isum,nvert,i3,ivert; - double *frac; - int icell; - int ndim; - int ierr; - double xv[8][3]; - double xp[3]; - double frac2[8]; - // - ndim=NFRAC; - frac=(double *) malloc(sizeof(double)*ndim); - interp2ListSize = ninterp2; - ninterp2=0; - // - for(i=0;i -1 && iblank_cell[donorId[i]]==1) ninterp2++; - // - if (interpList2) { - for(i=0;i -1 && iblank_cell[donorId[i]]==1) - { - if (ihigh) - { - icell=donorId[i]+BASE; - interpList2[m].inode=(int *) malloc(sizeof(int)); - interpList2[m].nweights=0; - donor_frac(&(icell), - &(xsearch[3*i]), - &(interpList2[m].nweights), - &(interpList2[m].inode[0]), - frac, - &(rst[3*i]),&ndim); - interpList2[m].weights=(double *)malloc(sizeof(double)*interpList2[m].nweights); - for(j=0;j -1 && iblank_cell[donorId[i]] == 1) ninterp2++; + // + if (interpList2) { + for (i = 0; i < interp2ListSize; i++) { + if (interpList2[i].inode) TIOGA_FREE(interpList2[i].inode); + if (interpList2[i].weights) TIOGA_FREE(interpList2[i].weights); + } + TIOGA_FREE(interpList2); } - TIOGA_FREE(frac); + interp2ListSize = ninterp2; + interpList2 = (INTERPLIST*)malloc(sizeof(INTERPLIST) * interp2ListSize); + for (i = 0; i < interp2ListSize; i++) { + interpList2[i].inode = NULL; + interpList2[i].weights = NULL; + } + // + // printf("nsearch=%d %d\n",nsearch,myid); + m = 0; + for (i = 0; i < nsearch; i++) { + if (donorId[i] > -1 && iblank_cell[donorId[i]] == 1) { + if (ihigh) { + icell = donorId[i] + BASE; + interpList2[m].inode = (int*)malloc(sizeof(int)); + interpList2[m].nweights = 0; + donor_frac( + &(icell), &(xsearch[3 * i]), &(interpList2[m].nweights), + &(interpList2[m].inode[0]), frac, &(rst[3 * i]), &ndim); + interpList2[m].weights = + (double*)malloc(sizeof(double) * interpList2[m].nweights); + for (j = 0; j < interpList2[m].nweights; j++) + interpList2[m].weights[j] = frac[j]; + interpList2[m].receptorInfo[0] = isearch[3 * i]; + interpList2[m].receptorInfo[1] = isearch[3 * i + 1]; + interpList2[m].receptorInfo[2] = isearch[3 * i + 2]; + m++; + } else { + icell = donorId[i]; + isum = 0; + for (n = 0; n < ntypes; n++) { + isum += nc[n]; + if (icell < isum) { + icell = icell - (isum - nc[n]); + break; + } + } + nvert = nv[n]; + interpList2[m].inode = (int*)malloc(sizeof(int) * nvert); + interpList2[m].nweights = nvert; + interpList2[m].weights = + (double*)malloc(sizeof(double) * interpList2[m].nweights); + for (ivert = 0; ivert < nvert; ivert++) { + interpList2[m].inode[ivert] = + vconn[n][nvert * icell + ivert] - BASE; + i3 = 3 * interpList2[m].inode[ivert]; + for (j = 0; j < 3; j++) xv[ivert][j] = x[i3 + j]; + } + xp[0] = xsearch[3 * i]; + xp[1] = xsearch[3 * i + 1]; + xp[2] = xsearch[3 * i + 2]; + computeNodalWeights(xv, xp, frac2, nvert); + for (j = 0; j < nvert; j++) + interpList2[m].weights[j] = frac2[j]; + interpList2[m].receptorInfo[0] = isearch[3 * i]; + interpList2[m].receptorInfo[1] = isearch[3 * i + 1]; + interpList2[m].receptorInfo[2] = isearch[3 * i + 2]; + m++; + } + } + } + TIOGA_FREE(frac); } -void MeshBlock::getInterpolatedSolutionAtPoints(int *nints,int *nreals,int **intData, - double **realData, - double *q, - int nvar, int interptype) +void MeshBlock::getInterpolatedSolutionAtPoints( + int* nints, + int* nreals, + int** intData, + double** realData, + double* q, + int nvar, + int interptype) { - int i; - int k,m,inode; - double weight; - double *qq; - int icount,dcount; - // - qq=(double *)malloc(sizeof(double)*nvar); - // - (*nints)=ninterp2; - (*nreals)=ninterp2*nvar; - if ((*nints)==0) { - TIOGA_FREE(qq); - return; - } - // - (*intData)=(int *)malloc(sizeof(int)*3*(*nints)); - (*realData)=(double *)malloc(sizeof(double)*(*nreals)); - icount=dcount=0; - // - if (ihigh) - { - if (interptype==ROW) - { - for(i=0;i 1.0) { - // TRACED(weight); - // printf("warning: weights are not convex\n"); - // } - for(k=0;k 1.0+TOL) { - TRACED(weight); - printf("warning: weights are not convex 2\n"); - } - for(k=0;k 1.0) { + // TRACED(weight); + // printf("warning: weights are not convex\n"); + // } + for (k = 0; k < nvar; k++) + qq[k] += q[inode + m * nvar + k] * weight; + } + (*intData)[icount++] = interpList2[i].receptorInfo[0]; + (*intData)[icount++] = interpList2[i].receptorInfo[1]; + (*intData)[icount++] = interpList2[i].receptorInfo[2]; + for (k = 0; k < nvar; k++) (*realData)[dcount++] = qq[k]; + } + } + } else { + if (interptype == ROW) { + for (i = 0; i < ninterp2; i++) { + for (k = 0; k < nvar; k++) qq[k] = 0; + for (m = 0; m < interpList2[i].nweights; m++) { + inode = interpList2[i].inode[m]; + weight = interpList2[i].weights[m]; + if (weight < -TOL || weight > 1.0 + TOL) { + TRACED(weight); + printf("warning: weights are not convex 2\n"); + } + for (k = 0; k < nvar; k++) + qq[k] += q[inode * nvar + k] * weight; + } + (*intData)[icount++] = interpList2[i].receptorInfo[0]; + (*intData)[icount++] = interpList2[i].receptorInfo[1]; + (*intData)[icount++] = interpList2[i].receptorInfo[2]; + for (k = 0; k < nvar; k++) (*realData)[dcount++] = qq[k]; + } + } else if (interptype == COLUMN) { + for (i = 0; i < ninterp2; i++) { + for (k = 0; k < nvar; k++) qq[k] = 0; + for (m = 0; m < interpList2[i].nweights; m++) { + inode = interpList2[i].inode[m]; + weight = interpList2[i].weights[m]; + for (k = 0; k < nvar; k++) + qq[k] += q[k * nnodes + inode] * weight; + } + (*intData)[icount++] = interpList2[i].receptorInfo[0]; + (*intData)[icount++] = interpList2[i].receptorInfo[1]; + (*intData)[icount++] = interpList2[i].receptorInfo[2]; + for (k = 0; k < nvar; k++) (*realData)[dcount++] = qq[k]; + } + } } - // - // no column-wise storage for high-order data - // - TIOGA_FREE(qq); + // + // no column-wise storage for high-order data + // + TIOGA_FREE(qq); } - -void MeshBlock::updatePointData(double *q,double *qtmp,int nvar,int interptype) + +void MeshBlock::updatePointData( + double* q, double* qtmp, int nvar, int interptype) { - int i,j,k,n,m; - double *qout; - int index_out; - int npts; - // - if (ihigh) - { - npts=NFRAC; - qout=(double *)malloc(sizeof(double)*nvar*npts); - // - m=0; - for(i=0;i @@ -40,152 +40,154 @@ using namespace TIOGA; */ void tioga::getHoleMap(void) { - int i,j,k,m; - int ii,jj,kk; - // double wbox[6]; - std::vector> wbox(nblocks); - //int existWall; - std::vector existWall(nblocks); - int meshtag,maxtag, mtagtmp; - int *existHoleLocal; - int *existHole; - double *bboxLocal; - double *bboxGlobal; - double ds[3],dsmax,dsbox; - int bufferSize; - FILE *fp; - char fname[80]; - char intstring[12]; - // - // get the local bounding box - // - meshtag = -BIGINT; //std::numeric_limits::lowest(); - for (int i=0; igetWallBounds(&mtagtmp,&existWall[i],wbox[i].data()); - if (mtagtmp > meshtag) meshtag = mtagtmp; - } - MPI_Allreduce(&meshtag,&maxtag,1,MPI_INT,MPI_MAX,scomm); - // - if (holeMap) - { - for(i=0;igetMeshTag(); - if (holeMap[meshtag - 1].existWall) { - mb->markWallBoundary( - holeMap[meshtag - 1].samLocal, holeMap[meshtag - 1].nx, - holeMap[meshtag - 1].extents); - } - } - // - // allreduce the holeMap of each mesh - // - for(i=0;ioutputHoleMap(); - // - // free local memory - // - TIOGA_FREE(existHoleLocal); - TIOGA_FREE(existHole); - TIOGA_FREE(bboxLocal); - TIOGA_FREE(bboxGlobal); + int i, j, k, m; + int ii, jj, kk; + // double wbox[6]; + std::vector> wbox(nblocks); + // int existWall; + std::vector existWall(nblocks); + int meshtag, maxtag, mtagtmp; + int* existHoleLocal; + int* existHole; + double* bboxLocal; + double* bboxGlobal; + double ds[3], dsmax, dsbox; + int bufferSize; + FILE* fp; + char fname[80]; + char intstring[12]; + // + // get the local bounding box + // + meshtag = -BIGINT; // std::numeric_limits::lowest(); + for (int i = 0; i < nblocks; i++) { + auto& mb = mblocks[i]; + mb->getWallBounds(&mtagtmp, &existWall[i], wbox[i].data()); + if (mtagtmp > meshtag) meshtag = mtagtmp; + } + MPI_Allreduce(&meshtag, &maxtag, 1, MPI_INT, MPI_MAX, scomm); + // + if (holeMap) { + for (i = 0; i < nmesh; i++) + if (holeMap[i].existWall) TIOGA_FREE(holeMap[i].sam); + delete[] holeMap; + } + holeMap = new HOLEMAP[maxtag]; + // + existHoleLocal = (int*)malloc(sizeof(int) * maxtag); + existHole = (int*)malloc(sizeof(int) * maxtag); + // + for (i = 0; i < maxtag; i++) existHole[i] = existHoleLocal[i] = 0; + // + for (int i = 0; i < nblocks; i++) { + existHoleLocal[mtags[i] - 1] = existWall[i]; + } + // + MPI_Allreduce(existHoleLocal, existHole, maxtag, MPI_INT, MPI_MAX, scomm); + // + for (i = 0; i < maxtag; i++) holeMap[i].existWall = existHole[i]; + // + bboxLocal = (double*)malloc(sizeof(double) * 6 * maxtag); + bboxGlobal = (double*)malloc(sizeof(double) * 6 * maxtag); + // + for (i = 0; i < 3 * maxtag; i++) bboxLocal[i] = BIGVALUE; + for (i = 0; i < 3 * maxtag; i++) bboxLocal[i + 3 * maxtag] = -BIGVALUE; + for (i = 0; i < 3 * maxtag; i++) bboxGlobal[i] = BIGVALUE; + for (i = 0; i < 3 * maxtag; i++) bboxGlobal[i + 3 * maxtag] = -BIGVALUE; + + // + for (int n = 0; n < nblocks; n++) { + meshtag = mtags[n]; + for (i = 0; i < 3; i++) { + bboxLocal[3 * (meshtag - 1) + i] = wbox[n][i]; + bboxLocal[3 * (meshtag - 1) + i + 3 * maxtag] = wbox[n][i + 3]; + } + } + // + // get the global bounding box info across all the + // partitions for all meshes + // + MPI_Allreduce( + bboxLocal, bboxGlobal, 3 * maxtag, MPI_DOUBLE, MPI_MIN, scomm); + MPI_Allreduce( + &(bboxLocal[3 * maxtag]), &(bboxGlobal[3 * maxtag]), 3 * maxtag, + MPI_DOUBLE, MPI_MAX, scomm); + // + // find the bounding box for each mesh + // from the globally reduced data + // + for (i = 0; i < maxtag; i++) { + if (holeMap[i].existWall) { + for (j = 0; j < 3; j++) { + holeMap[i].extents[j] = bboxGlobal[3 * i + j]; + holeMap[i].extents[j + 3] = bboxGlobal[3 * i + j + 3 * maxtag]; + ds[j] = holeMap[i].extents[j + 3] - holeMap[i].extents[j]; + } + dsmax = std::max(ds[0], ds[1]); + dsmax = std::max(dsmax, ds[2]); + dsbox = dsmax / HOLEMAPSIZE; + + for (j = 0; j < 3; j++) { + holeMap[i].extents[j] -= (2 * dsbox); + holeMap[i].extents[j + 3] += (2 * dsbox); + holeMap[i].nx[j] = floor(std::max( + (holeMap[i].extents[j + 3] - holeMap[i].extents[j]) / dsbox, + 1.0)); + } + bufferSize = holeMap[i].nx[0] * holeMap[i].nx[1] * holeMap[i].nx[2]; + holeMap[i].sam = (int*)malloc(sizeof(int) * bufferSize); + holeMap[i].samLocal = (int*)malloc(sizeof(int) * bufferSize); + for (j = 0; j < bufferSize; j++) + holeMap[i].sam[j] = holeMap[i].samLocal[j] = 0; + } + } + // + // mark the wall boundary cells in the holeMap + // + for (int ib = 0; ib < nblocks; ib++) { + auto& mb = mblocks[ib]; + meshtag = mb->getMeshTag(); + if (holeMap[meshtag - 1].existWall) { + mb->markWallBoundary( + holeMap[meshtag - 1].samLocal, holeMap[meshtag - 1].nx, + holeMap[meshtag - 1].extents); + } + } + // + // allreduce the holeMap of each mesh + // + for (i = 0; i < maxtag; i++) { + if (holeMap[i].existWall) { + bufferSize = holeMap[i].nx[0] * holeMap[i].nx[1] * holeMap[i].nx[2]; + MPI_Allreduce( + holeMap[i].samLocal, holeMap[i].sam, bufferSize, MPI_INT, + MPI_MAX, scomm); + } + } + // + for (i = 0; i < maxtag; i++) + if (holeMap[i].existWall) TIOGA_FREE(holeMap[i].samLocal); + // + // set the global number of meshes to maxtag + // + nmesh = maxtag; + // + // now fill the holeMap + // + for (i = 0; i < maxtag; i++) + if (holeMap[i].existWall) + fillHoleMap(holeMap[i].sam, holeMap[i].nx, isym); + // + // output the hole map + // + // this->outputHoleMap(); + // + // free local memory + // + TIOGA_FREE(existHoleLocal); + TIOGA_FREE(existHole); + TIOGA_FREE(bboxLocal); + TIOGA_FREE(bboxGlobal); } /** @@ -195,797 +197,871 @@ void tioga::getHoleMap(void) * have to change it at a later date when * there is more time to develop code */ -void tioga::getAdaptiveHoleMap(void){ - int maxtag,maxtagLocal; - int mbi,mi; - int level_id; - - /* =========================== */ - /* A: count max number of tags */ - /* =========================== */ - maxtagLocal = -BIGINT; - for(mbi=0; mbigetMeshTag(); - maxtagLocal = (maxtagLocal < mbtag) ? mbtag:maxtagLocal; - } - MPI_Allreduce(&maxtagLocal,&maxtag,1,MPI_INT,MPI_MAX,scomm); - - /* =============================== */ - /* B: reallocate adaptive hole map */ - /* =============================== */ - if(adaptiveHoleMap) delete[] adaptiveHoleMap; - adaptiveHoleMap = new ADAPTIVE_HOLEMAP[maxtag]; - for(mi=0; mi existHole(maxtag); - std::fill(existHole.begin(),existHole.end(),0); - - // fill array - for(mbi=0; mbigetMeshTag()-BASE] = (uint8_t) mb->getWallFlag(); - } - MPI_Allreduce(MPI_IN_PLACE,existHole.data(),maxtag,MPI_UINT8_T,MPI_MAX,scomm); - - // set wall flags for all hole maps - for(mi=0; mi refineFlag; - std::vector existWall; - std::vector existOuter; - - double bboxLocal[6]; - double bboxGlobal[6]; - double ds[3],dsmax,dsbox; - - /* =============================================== */ - /* Step 1: build global bounding box for this body */ - /* =============================================== */ - // get the local bounding box - mb->getWallBounds(&meshtag,&existWallFlag,bboxLocal); - - // set hole for this body - AHMOLocal.existWall = existHole[meshtag-BASE]; - - // initialize global bounding box data - for(i=0; i<3; i++) bboxGlobal[i] = BIGVALUE; - for(i=0; i<3; i++) bboxGlobal[3+i]=-BIGVALUE; - - // get the global bounding box info for this body (note the communicator) - MPI_Allreduce(mb->bboxLocalAHM,bboxGlobal,3,MPI_DOUBLE,MPI_MIN,mb->blockcomm); - MPI_Allreduce(&(mb->bboxLocalAHM[3]),&(bboxGlobal[3]),3,MPI_DOUBLE,MPI_MAX,mb->blockcomm); - - /* ======================================================= */ - /* Step 2: initialize and build adaptive map for this body */ - /* ======================================================= */ - // set extents and initialize map for this body - if(AHMOLocal.existWall){ - for(j=0; j<3; j++){ - AHMOLocal.extents_lo[j] = bboxGlobal[j]; - AHMOLocal.extents_hi[j] = bboxGlobal[j+3]; - ds[j] = fabs(AHMOLocal.extents_hi[j] - AHMOLocal.extents_lo[j]); - } - - // add buffer to extents - dsmax = std::max(ds[0],ds[1]); - dsmax = std::max(dsmax,ds[2]); - dsbox = dsmax*0.01; - for(j=0; j<3; j++) AHMOLocal.extents_lo[j] -= (dsbox); - for(j=0; j<3; j++) AHMOLocal.extents_hi[j] += (dsbox); - - // initialize map for this body - AHMOLocal.nlevel = 1; - AHMOLocal.levels[0].elem_count = 0; - } - - // initialize level 0, check outer boundary and set adapt flag - adaptMapLocal = adaptMap = 0; - if(AHMOLocal.existWall){ - level_octant_t *lvl = &AHMOLocal.levels[0]; - - // allocate level 0 - lvl->level_id = 0; - lvl->elem_count = 1; - lvl->octants.resize(1); - - existWall.resize(1); - existOuter.resize(1); - - // initialize - existWall[0] = 1; - existOuter[0] = 0; - - // fill in level 0 info - lvl->octants[0].x = 0; - lvl->octants[0].y = 0; - lvl->octants[0].z = 0; - lvl->octants[0].id = 1; - lvl->octants[0].filltype = WALL_SB; - lvl->octants[0].refined = 0; - - // set neighbor octants to NULL since Level 0 - for(n=0; n<6; n++) lvl->octants[0].nhbr[n] = NULL; - - // check if outer boundary exists - mb->markBoundaryMapSurface(OUTERNODETYPE, - AHMOLocal.extents_lo, - AHMOLocal.extents_hi, - &AHMOLocal.levels[0], - NULL, - existOuter.data()); - - // check if initial octant contains both boundary types - if(existOuter[0]){ - lvl->octants[0].refined = 1; - adaptMapLocal = 1; - } - } - // check this block's map for adaption (note the communicator) - MPI_Allreduce(&adaptMapLocal,&adaptMap,1,MPI_INT,MPI_MAX,mb->blockcomm); - - // set all rank Outer flags - if(adaptMap) AHMOLocal.levels[0].octants[0].refined = existOuter[0] = existWall[0] = 1; +void tioga::getAdaptiveHoleMap(void) +{ + int maxtag, maxtagLocal; + int mbi, mi; + int level_id; + + /* =========================== */ + /* A: count max number of tags */ + /* =========================== */ + maxtagLocal = -BIGINT; + for (mbi = 0; mbi < nblocks; mbi++) { + auto& mb = mblocks[mbi]; + int mbtag = mb->getMeshTag(); + maxtagLocal = (maxtagLocal < mbtag) ? mbtag : maxtagLocal; + } + MPI_Allreduce(&maxtagLocal, &maxtag, 1, MPI_INT, MPI_MAX, scomm); + + /* =============================== */ + /* B: reallocate adaptive hole map */ + /* =============================== */ + if (adaptiveHoleMap) delete[] adaptiveHoleMap; + adaptiveHoleMap = new ADAPTIVE_HOLEMAP[maxtag]; + for (mi = 0; mi < maxtag; mi++) { + adaptiveHoleMap[mi].meta.nlevel = 0; + adaptiveHoleMap[mi].meta.elem_count = 0; + adaptiveHoleMap[mi].meta.leaf_count = 0; + } - // recursively refine adaptive map until no intersection of wall and outer octants - level_id = 0; - while(adaptMap){ - level_octant_t *lvl = &AHMOLocal.levels[level_id]; + ADAPTIVE_HOLEMAP_COMPOSITE* adaptiveHoleMapCOMPOSITE; + if (ncomposite) { + adaptiveHoleMapCOMPOSITE = new ADAPTIVE_HOLEMAP_COMPOSITE[maxtag]; + for (mi = 0; mi < maxtag; mi++) + adaptiveHoleMapCOMPOSITE[mi].meta.nlevel = 0; + } - // update level count - AHMOLocal.nlevel++; + /* ====================== */ + /* C: set existHole flags */ + /* ====================== */ + // determine holes for all bodies + std::vector existHole(maxtag); + std::fill(existHole.begin(), existHole.end(), 0); + + // fill array + for (mbi = 0; mbi < nblocks; mbi++) { + auto& mb = mblocks[mbi]; + existHole[mb->getMeshTag() - BASE] = (uint8_t)mb->getWallFlag(); + } + MPI_Allreduce( + MPI_IN_PLACE, existHole.data(), maxtag, MPI_UINT8_T, MPI_MAX, scomm); + + // set wall flags for all hole maps + for (mi = 0; mi < maxtag; mi++) + adaptiveHoleMap[mi].existWall = existHole[mi]; + + /* =============================== */ + /* D: construct Adaptive Hole Maps */ + /* =============================== */ + { // using encapsulation for clean up + /* local variables */ + ADAPTIVE_HOLEMAP_OCTANT AHMO[nblocks]; + int i, j, l, c, n; + + for (mbi = 0; mbi < nblocks; mbi++) { + ADAPTIVE_HOLEMAP_OCTANT& AHMOLocal = AHMO[mbi]; + auto& mb = mblocks[mbi]; + + int adaptMap, adaptMapLocal; + int nrefine; + int existWallFlag; + int meshtag; + + std::vector refineFlag; + std::vector existWall; + std::vector existOuter; + + double bboxLocal[6]; + double bboxGlobal[6]; + double ds[3], dsmax, dsbox; + + /* =============================================== */ + /* Step 1: build global bounding box for this body */ + /* =============================================== */ + // get the local bounding box + mb->getWallBounds(&meshtag, &existWallFlag, bboxLocal); + + // set hole for this body + AHMOLocal.existWall = existHole[meshtag - BASE]; + + // initialize global bounding box data + for (i = 0; i < 3; i++) bboxGlobal[i] = BIGVALUE; + for (i = 0; i < 3; i++) bboxGlobal[3 + i] = -BIGVALUE; + + // get the global bounding box info for this body (note the + // communicator) + MPI_Allreduce( + mb->bboxLocalAHM, bboxGlobal, 3, MPI_DOUBLE, MPI_MIN, + mb->blockcomm); + MPI_Allreduce( + &(mb->bboxLocalAHM[3]), &(bboxGlobal[3]), 3, MPI_DOUBLE, + MPI_MAX, mb->blockcomm); + + /* ======================================================= */ + /* Step 2: initialize and build adaptive map for this body */ + /* ======================================================= */ + // set extents and initialize map for this body + if (AHMOLocal.existWall) { + for (j = 0; j < 3; j++) { + AHMOLocal.extents_lo[j] = bboxGlobal[j]; + AHMOLocal.extents_hi[j] = bboxGlobal[j + 3]; + ds[j] = + fabs(AHMOLocal.extents_hi[j] - AHMOLocal.extents_lo[j]); + } - // reset adapt flag - adaptMap = 0; + // add buffer to extents + dsmax = std::max(ds[0], ds[1]); + dsmax = std::max(dsmax, ds[2]); + dsbox = dsmax * 0.01; + for (j = 0; j < 3; j++) AHMOLocal.extents_lo[j] -= (dsbox); + for (j = 0; j < 3; j++) AHMOLocal.extents_hi[j] += (dsbox); - // count number of octants to refine, set refined field before call octant_children - refineFlag.resize(lvl->elem_count); + // initialize map for this body + AHMOLocal.nlevel = 1; + AHMOLocal.levels[0].elem_count = 0; + } - nrefine = 0; - for(i=0; ielem_count; i++){ - refineFlag[i] = existWall[i] && existOuter[i]; - if(refineFlag[i]) nrefine++; - } - int nchildren = OCTANT_CHILDREN*nrefine; - - // allocate and fill next level - level_id++; - level_octant_t *new_lvl = &AHMOLocal.levels[level_id]; - - // allocate new level - new_lvl->level_id = level_id; - new_lvl->elem_count = nchildren; - new_lvl->octants.resize(nchildren); - - // zero arrays - existWall.resize(nchildren); - existOuter.resize(nchildren); - std::fill(existWall.begin(),existWall.end(),0); - std::fill(existOuter.begin(),existOuter.end(),0); - - // fill in new level children octant info - nrefine = 0; - for(i=0; ielem_count; i++){ - if(refineFlag[i]){ - uint32_t newidx = OCTANT_CHILDREN*nrefine; - - // set Morton code and filltype for new octants - octant_children(level_id,newidx, - &lvl->octants[i], - &new_lvl->octants[newidx+0], - &new_lvl->octants[newidx+1], - &new_lvl->octants[newidx+2], - &new_lvl->octants[newidx+3], - &new_lvl->octants[newidx+4], - &new_lvl->octants[newidx+5], - &new_lvl->octants[newidx+6], - &new_lvl->octants[newidx+7]); - nrefine++; - } - } + // initialize level 0, check outer boundary and set adapt flag + adaptMapLocal = adaptMap = 0; + if (AHMOLocal.existWall) { + level_octant_t* lvl = &AHMOLocal.levels[0]; + + // allocate level 0 + lvl->level_id = 0; + lvl->elem_count = 1; + lvl->octants.resize(1); + + existWall.resize(1); + existOuter.resize(1); + + // initialize + existWall[0] = 1; + existOuter[0] = 0; + + // fill in level 0 info + lvl->octants[0].x = 0; + lvl->octants[0].y = 0; + lvl->octants[0].z = 0; + lvl->octants[0].id = 1; + lvl->octants[0].filltype = WALL_SB; + lvl->octants[0].refined = 0; + + // set neighbor octants to NULL since Level 0 + for (n = 0; n < 6; n++) lvl->octants[0].nhbr[n] = NULL; + + // check if outer boundary exists + mb->markBoundaryMapSurface( + OUTERNODETYPE, AHMOLocal.extents_lo, AHMOLocal.extents_hi, + &AHMOLocal.levels[0], NULL, existOuter.data()); + + // check if initial octant contains both boundary types + if (existOuter[0]) { + lvl->octants[0].refined = 1; + adaptMapLocal = 1; + } + } + // check this block's map for adaption (note the communicator) + MPI_Allreduce( + &adaptMapLocal, &adaptMap, 1, MPI_INT, MPI_MAX, mb->blockcomm); + + // set all rank Outer flags + if (adaptMap) + AHMOLocal.levels[0].octants[0].refined = existOuter[0] = + existWall[0] = 1; + + // recursively refine adaptive map until no intersection of wall and + // outer octants + level_id = 0; + while (adaptMap) { + level_octant_t* lvl = &AHMOLocal.levels[level_id]; + + // update level count + AHMOLocal.nlevel++; + + // reset adapt flag + adaptMap = 0; + + // count number of octants to refine, set refined field before + // call octant_children + refineFlag.resize(lvl->elem_count); + + nrefine = 0; + for (i = 0; i < lvl->elem_count; i++) { + refineFlag[i] = existWall[i] && existOuter[i]; + if (refineFlag[i]) nrefine++; + } + int nchildren = OCTANT_CHILDREN * nrefine; + + // allocate and fill next level + level_id++; + level_octant_t* new_lvl = &AHMOLocal.levels[level_id]; + + // allocate new level + new_lvl->level_id = level_id; + new_lvl->elem_count = nchildren; + new_lvl->octants.resize(nchildren); + + // zero arrays + existWall.resize(nchildren); + existOuter.resize(nchildren); + std::fill(existWall.begin(), existWall.end(), 0); + std::fill(existOuter.begin(), existOuter.end(), 0); + + // fill in new level children octant info + nrefine = 0; + for (i = 0; i < lvl->elem_count; i++) { + if (refineFlag[i]) { + uint32_t newidx = OCTANT_CHILDREN * nrefine; + + // set Morton code and filltype for new octants + octant_children( + level_id, newidx, &lvl->octants[i], + &new_lvl->octants[newidx + 0], + &new_lvl->octants[newidx + 1], + &new_lvl->octants[newidx + 2], + &new_lvl->octants[newidx + 3], + &new_lvl->octants[newidx + 4], + &new_lvl->octants[newidx + 5], + &new_lvl->octants[newidx + 6], + &new_lvl->octants[newidx + 7]); + nrefine++; + } + } - // fill in children neighbors AFTER ALL new level octants are formed - nrefine = 0; - for(i=0; ielem_count; i++){ - if(refineFlag[i]){ - int newidx = OCTANT_CHILDREN*nrefine; - - // set neighbors for new octants - octant_children_neighbors(&lvl->octants[i], - &new_lvl->octants[newidx+0], - &new_lvl->octants[newidx+1], - &new_lvl->octants[newidx+2], - &new_lvl->octants[newidx+3], - &new_lvl->octants[newidx+4], - &new_lvl->octants[newidx+5], - &new_lvl->octants[newidx+6], - &new_lvl->octants[newidx+7]); - nrefine++; - } - } + // fill in children neighbors AFTER ALL new level octants are + // formed + nrefine = 0; + for (i = 0; i < lvl->elem_count; i++) { + if (refineFlag[i]) { + int newidx = OCTANT_CHILDREN * nrefine; + + // set neighbors for new octants + octant_children_neighbors( + &lvl->octants[i], &new_lvl->octants[newidx + 0], + &new_lvl->octants[newidx + 1], + &new_lvl->octants[newidx + 2], + &new_lvl->octants[newidx + 3], + &new_lvl->octants[newidx + 4], + &new_lvl->octants[newidx + 5], + &new_lvl->octants[newidx + 6], + &new_lvl->octants[newidx + 7]); + nrefine++; + } + } - // check wall boundaries - mb->markBoundaryMapSurface(WALLNODETYPE, - AHMOLocal.extents_lo, - AHMOLocal.extents_hi, - &AHMOLocal.levels[level_id], - NULL, - existWall.data()); - - // inform all mesh-block processes with this body tag of the octants flags (note the communicator) - MPI_Allreduce(MPI_IN_PLACE,existWall.data(),nchildren,MPI_UINT8_T,MPI_MAX,mb->blockcomm); - - // check outer boundaries: check only octants with wall tagged previously - mb->markBoundaryMapSurface(OUTERNODETYPE, - AHMOLocal.extents_lo, - AHMOLocal.extents_hi, - &AHMOLocal.levels[level_id], - existWall.data(), - existOuter.data()); - - // inform all mesh-block processes with this body tag of the octants flags (note the communicator) - MPI_Allreduce(MPI_IN_PLACE,existOuter.data(),nchildren,MPI_UINT8_T,MPI_MAX,mb->blockcomm); - - // update filltype to wall if touching wall; check both boundary types - for(i=0; ielem_count; i++){ - if(existWall[i]){ - new_lvl->octants[i].filltype = WALL_SB; - - if(existOuter[i]){ - new_lvl->octants[i].refined = 1; - adaptMap = 1; + // check wall boundaries + mb->markBoundaryMapSurface( + WALLNODETYPE, AHMOLocal.extents_lo, AHMOLocal.extents_hi, + &AHMOLocal.levels[level_id], NULL, existWall.data()); + + // inform all mesh-block processes with this body tag of the + // octants flags (note the communicator) + MPI_Allreduce( + MPI_IN_PLACE, existWall.data(), nchildren, MPI_UINT8_T, + MPI_MAX, mb->blockcomm); + + // check outer boundaries: check only octants with wall tagged + // previously + mb->markBoundaryMapSurface( + OUTERNODETYPE, AHMOLocal.extents_lo, AHMOLocal.extents_hi, + &AHMOLocal.levels[level_id], existWall.data(), + existOuter.data()); + + // inform all mesh-block processes with this body tag of the + // octants flags (note the communicator) + MPI_Allreduce( + MPI_IN_PLACE, existOuter.data(), nchildren, MPI_UINT8_T, + MPI_MAX, mb->blockcomm); + + // update filltype to wall if touching wall; check both boundary + // types + for (i = 0; i < new_lvl->elem_count; i++) { + if (existWall[i]) { + new_lvl->octants[i].filltype = WALL_SB; + + if (existOuter[i]) { + new_lvl->octants[i].refined = 1; + adaptMap = 1; + } + } + } + if (AHMOLocal.nlevel >= OCTANT_MAXLEVEL && adaptMap == 1) { + printf( + "[tioga] ERROR Constructing the Adaptive Hole Map! Max " + "level reached!\n"); + exit(0); + } } - } + // adaption complete: all ranks of this mesh-block are informed of + // global octree } - if(AHMOLocal.nlevel >= OCTANT_MAXLEVEL && adaptMap == 1) { - printf("[tioga] ERROR Constructing the Adaptive Hole Map! Max level reached!\n"); - exit(0); - } - } - // adaption complete: all ranks of this mesh-block are informed of global octree - } - /* ======================================================== */ - /* Step 3: mark abutting/composite bodies holes in hole map */ - /* ======================================================== */ - for(int cb=0; cbgetMeshTag(); - if(meshtag-BASE == bodyi) {rankContainsBody = 1; break;} - } + /* ======================================================== */ + /* Step 3: mark abutting/composite bodies holes in hole map */ + /* ======================================================== */ + for (int cb = 0; cb < ncomposite; cb++) { + CompositeBody& Composite = compositeBody[cb]; + int nbodies = Composite.bodyids.size(); + + for (i = 0; i < nbodies; i++) { + int bodyi = Composite.bodyids[i] - BASE; + ADAPTIVE_HOLEMAP_OCTANT& AHMOLocal = AHMO[bodyi]; + + // check if this rank contains this body + char rankContainsBody = 0; + for (mbi = 0; mbi < nblocks; mbi++) { + auto& mb = mblocks[mbi]; + int meshtag = mb->getMeshTag(); + if (meshtag - BASE == bodyi) { + rankContainsBody = 1; + break; + } + } - meshblockCompInfo &MBC = meshblockComposite[bodyi]; - ADAPTIVE_HOLEMAP_COMPOSITE &AHMC = adaptiveHoleMapCOMPOSITE[bodyi]; - ahm_meta_minimal_t &meta = AHMC.meta; - - // initialize data for all ranks - meta.nlevel = 0; - - /* --------------------------- */ - /* copy data for own mesh body */ - /* --------------------------- */ - if(MBC.comm != MPI_COMM_NULL){ - if(MBC.id == MBC.masterID){ - if(AHMOLocal.existWall){ - // 1. copy nlevel and extents - meta.nlevel = AHMOLocal.nlevel; - memcpy(meta.extents_lo,AHMOLocal.extents_lo,3*sizeof(double)); - memcpy(meta.extents_hi,AHMOLocal.extents_hi,3*sizeof(double)); - - // 2. loop each level in adaptive hole map and assemble octants - uint64_t elem_count = 0; - for(level_id=0; level_idlevel_id = level_id; - elvl->elem_count = lvl->elem_count; - elvl->octants.resize(elvl->elem_count); - - // count octants - elem_count += lvl->elem_count; - - // fill octant coordinate data - for(j=0; jelem_count; j++){ - elvl->octants[j].x = lvl->octants[j].x; - elvl->octants[j].y = lvl->octants[j].y; - elvl->octants[j].z = lvl->octants[j].z; + meshblockCompInfo& MBC = meshblockComposite[bodyi]; + ADAPTIVE_HOLEMAP_COMPOSITE& AHMC = + adaptiveHoleMapCOMPOSITE[bodyi]; + ahm_meta_minimal_t& meta = AHMC.meta; + + // initialize data for all ranks + meta.nlevel = 0; + + /* --------------------------- */ + /* copy data for own mesh body */ + /* --------------------------- */ + if (MBC.comm != MPI_COMM_NULL) { + if (MBC.id == MBC.masterID) { + if (AHMOLocal.existWall) { + // 1. copy nlevel and extents + meta.nlevel = AHMOLocal.nlevel; + memcpy( + meta.extents_lo, AHMOLocal.extents_lo, + 3 * sizeof(double)); + memcpy( + meta.extents_hi, AHMOLocal.extents_hi, + 3 * sizeof(double)); + + // 2. loop each level in adaptive hole map and + // assemble octants + uint64_t elem_count = 0; + for (level_id = 0; level_id < meta.nlevel; + level_id++) { + level_octant_t* lvl = + &AHMOLocal.levels[level_id]; + level_octant_coordinate_t* elvl = + &AHMC.levels[level_id]; + + // set level info + elvl->level_id = level_id; + elvl->elem_count = lvl->elem_count; + elvl->octants.resize(elvl->elem_count); + + // count octants + elem_count += lvl->elem_count; + + // fill octant coordinate data + for (j = 0; j < elvl->elem_count; j++) { + elvl->octants[j].x = lvl->octants[j].x; + elvl->octants[j].y = lvl->octants[j].y; + elvl->octants[j].z = lvl->octants[j].z; + } + } + // 3. set element count + meta.elem_count = elem_count; + } + } + + // 2. communicate minimal adaptive hole map to composite + // ranks a. inform of meta data for map: packed into + // contiguous buffer + MPI_Bcast( + &meta, sizeof(ahm_meta_minimal_t), MPI_BYTE, + MBC.masterID, MBC.comm); + + for (level_id = 0; level_id < meta.nlevel; level_id++) { + level_octant_coordinate_t* level = + &AHMC.levels[level_id]; + level->level_id = level_id; + + // communicate number of leaf octants on level + MPI_Bcast( + &(level->elem_count), 1, MPI_UINT32_T, MBC.masterID, + MBC.comm); + + // allocate leaf octant data for level data (if not + // master rank) + if (MBC.masterID != MBC.id) + level->octants.resize(level->elem_count); + } + + // d. loop each level in adaptive hole map: communicate + // octant coordinates + // - separate from previous loop to avoid MPI stalling + for (level_id = 0; level_id < meta.nlevel; level_id++) { + level_octant_coordinate_t* level = + &AHMC.levels[level_id]; + + // communicate leaf octant coordinate data on level + MPI_Bcast( + level->octants.data(), + level->elem_count * sizeof(octant_coordinates_t), + MPI_BYTE, MBC.masterID, MBC.comm); + } + + // e. loop each level: check composite map wall boundaries + // for all mesh blocks + for (level_id = 0; level_id < meta.nlevel; level_id++) { + level_octant_coordinate_t* level = + &AHMC.levels[level_id]; + std::vector existWall(level->elem_count, 0); + + // check composite map wall boundaries for all mesh + // blocks + for (mbi = 0; mbi < nblocks; mbi++) { + auto& mb = mblocks[mbi]; + + // check if mesh block belongs to composite body + if (compositeBodyMap[cb][bodyi] + [mb->getMeshTag() - BASE]) { + // check wall boundaries on abutting composite + // meshes + mb->markBoundaryAdaptiveMapSurfaceIntersect( + WALLNODETYPE, meta.extents_lo, + meta.extents_hi, level->level_id, + level->elem_count, level->octants.data(), + NULL, existWall.data()); + } + } + + // f. inform all mesh-block processes with this body tag + // of the octants flags (note the communicator) + MPI_Allreduce( + MPI_IN_PLACE, existWall.data(), level->elem_count, + MPI_UINT8_T, MPI_MAX, MBC.comm); + + // g. update filltype to wall if touching wall + if (rankContainsBody) { + level_octant_t* new_lvl = + &AHMOLocal.levels[level_id]; + for (int ii = 0; ii < new_lvl->elem_count; ii++) { + if (existWall[ii]) + new_lvl->octants[ii].filltype = WALL_SB; + } + } + } + // end marking wall BC in hole map for composite rank bodies } - } - // 3. set element count - meta.elem_count = elem_count; } - } - - // 2. communicate minimal adaptive hole map to composite ranks - // a. inform of meta data for map: packed into contiguous buffer - MPI_Bcast(&meta, - sizeof(ahm_meta_minimal_t), - MPI_BYTE, - MBC.masterID, - MBC.comm); + } - for(level_id=0; level_idlevel_id = level_id; - - // communicate number of leaf octants on level - MPI_Bcast(&(level->elem_count), - 1,MPI_UINT32_T, - MBC.masterID, - MBC.comm); - - // allocate leaf octant data for level data (if not master rank) - if(MBC.masterID != MBC.id) level->octants.resize(level->elem_count); - } - - // d. loop each level in adaptive hole map: communicate octant coordinates - // - separate from previous loop to avoid MPI stalling - for(level_id=0; level_idoctants.data(), - level->elem_count*sizeof(octant_coordinates_t), - MPI_BYTE, - MBC.masterID, - MBC.comm); - } - - // e. loop each level: check composite map wall boundaries for all mesh blocks - for(level_id=0; level_id existWall(level->elem_count,0); - - // check composite map wall boundaries for all mesh blocks - for(mbi=0; mbigetMeshTag()-BASE]){ - // check wall boundaries on abutting composite meshes - mb->markBoundaryAdaptiveMapSurfaceIntersect(WALLNODETYPE, - meta.extents_lo, - meta.extents_hi, - level->level_id, - level->elem_count, - level->octants.data(), - NULL, - existWall.data()); - } + /* ======================================================== */ + /* Step 4: flood fill adaptive hole map for this mesh-block */ + /* NOTE: all octants touching the octree boundary are */ + /* already tagged as OUTSIDE_SB (octant_children) */ + /* or as WALL_SB. */ + /* ======================================================== */ + for (mbi = 0; mbi < nblocks; mbi++) { + ADAPTIVE_HOLEMAP_OCTANT& AHMOLocal = AHMO[mbi]; + + if (AHMOLocal.existWall) { + for (l = 0; l < AHMOLocal.nlevel; l++) + floodfill_level(&AHMOLocal.levels[l]); } + } - // f. inform all mesh-block processes with this body tag of the octants flags (note the communicator) - MPI_Allreduce(MPI_IN_PLACE,existWall.data(),level->elem_count,MPI_UINT8_T,MPI_MAX,MBC.comm); - - // g. update filltype to wall if touching wall - if(rankContainsBody){ - level_octant_t *new_lvl = &AHMOLocal.levels[level_id]; - for(int ii=0; iielem_count; ii++){ - if(existWall[ii]) new_lvl->octants[ii].filltype = WALL_SB; - } + /* ================================================== */ + /* Step 5: build hole map and inform all complement */ + /* ranks of each mesh-block adaptive hole map */ + /* ================================================== */ + /* -------------------------------------------------- */ + /* assemble local adaptive hole map for own mesh body */ + /* -------------------------------------------------- */ + for (mbi = 0; mbi < nblocks; mbi++) { + ADAPTIVE_HOLEMAP_OCTANT& AHMOLocal = AHMO[mbi]; + auto& mb = mblocks[mbi]; + int meshtag = mb->getMeshTag(); + + ADAPTIVE_HOLEMAP& AHMLocal = adaptiveHoleMap[meshtag - BASE]; + ahm_meta_t& meta = AHMLocal.meta; + + // initialize meta + meta.nlevel = 0; + meta.leaf_count = 0; + + /* --------------------------- */ + /* copy data for own mesh body */ + /* --------------------------- */ + if (AHMLocal.existWall) { + // 1. copy nlevel and extents + meta.nlevel = AHMOLocal.nlevel; + memcpy( + meta.extents_lo, AHMOLocal.extents_lo, 3 * sizeof(double)); + memcpy( + meta.extents_hi, AHMOLocal.extents_hi, 3 * sizeof(double)); + + // 2. loop each level in adaptive hole map and assemble octants + for (level_id = 0; level_id < meta.nlevel; level_id++) { + level_octant_t* lvl = &AHMOLocal.levels[level_id]; + level_t* elvl = &AHMLocal.levels[level_id]; + + // set level info + elvl->level_id = level_id; + elvl->elem_count = lvl->elem_count; + elvl->octants.resize(elvl->elem_count); + + // fill octant data + for (j = 0; j < elvl->elem_count; j++) { + elvl->octants[j].x = lvl->octants[j].x; + elvl->octants[j].y = lvl->octants[j].y; + elvl->octants[j].z = lvl->octants[j].z; + elvl->octants[j].filltype = lvl->octants[j].filltype; + elvl->octants[j].leafflag = !lvl->octants[j].refined; + if (lvl->octants[j].refined) { + for (c = 0; c < OCTANT_CHILDREN; c++) + elvl->octants[j].children[c] = + lvl->octants[j].children[c]->id; + } + + // update leaf counter + meta.leaf_count += elvl->octants[j].leafflag; + } + + // free level full octant data set + lvl->octants.clear(); + } } - } - // end marking wall BC in hole map for composite rank bodies } - } } - /* ======================================================== */ - /* Step 4: flood fill adaptive hole map for this mesh-block */ - /* NOTE: all octants touching the octree boundary are */ - /* already tagged as OUTSIDE_SB (octant_children) */ - /* or as WALL_SB. */ - /* ======================================================== */ - for(mbi=0; mbigetMeshTag(); - - ADAPTIVE_HOLEMAP &AHMLocal = adaptiveHoleMap[meshtag-BASE]; - ahm_meta_t &meta = AHMLocal.meta; - - // initialize meta - meta.nlevel = 0; - meta.leaf_count = 0; - - /* --------------------------- */ - /* copy data for own mesh body */ - /* --------------------------- */ - if(AHMLocal.existWall){ - // 1. copy nlevel and extents - meta.nlevel = AHMOLocal.nlevel; - memcpy(meta.extents_lo,AHMOLocal.extents_lo,3*sizeof(double)); - memcpy(meta.extents_hi,AHMOLocal.extents_hi,3*sizeof(double)); - - // 2. loop each level in adaptive hole map and assemble octants - for(level_id=0; level_idlevel_id = level_id; - elvl->elem_count = lvl->elem_count; - elvl->octants.resize(elvl->elem_count); - - // fill octant data - for(j=0; jelem_count; j++){ - elvl->octants[j].x = lvl->octants[j].x; - elvl->octants[j].y = lvl->octants[j].y; - elvl->octants[j].z = lvl->octants[j].z; - elvl->octants[j].filltype = lvl->octants[j].filltype; - elvl->octants[j].leafflag =!lvl->octants[j].refined; - if(lvl->octants[j].refined){ - for(c=0; coctants[j].children[c] = - lvl->octants[j].children[c]->id; - } + meta.elem_count = 0; + if (AHME.existWall) { + meshblockCompInfo& MBC = meshblockComplement[i]; - // update leaf counter - meta.leaf_count += elvl->octants[j].leafflag; - } + // complement + master ranks only involved + if (MBC.comm != MPI_COMM_NULL) { - // free level full octant data set - lvl->octants.clear(); - } - } - } - } - - /* ========================================================= */ - /* E. communicate adaptive hole map info to complement ranks */ - /* ========================================================= */ - for(int i=0; ilevel_id = level_id; - - // communicate number of leaf octants on level - MPI_Bcast(&(elvl->elem_count), - 1,MPI_UINT32_T, - MBC.masterID, + // 1. inform of meta data for map: packed into contiguous buffer + MPI_Bcast( + &AHME.meta, sizeof(ahm_meta_t), MPI_BYTE, MBC.masterID, MBC.comm); - // allocate leaf octant data for level data (if not master rank) - if(MBC.masterID != MBC.id) elvl->octants.resize(elvl->elem_count); + // 2. loop each level in adaptive hole map and assemble octants + for (level_id = 0; level_id < meta.nlevel; level_id++) { + level_t* elvl = &AHME.levels[level_id]; - // communicate leaf octant data on level - MPI_Bcast(elvl->octants.data(), - elvl->elem_count*sizeof(octant_t), - MPI_BYTE, - MBC.masterID, - MBC.comm); + // set level id + elvl->level_id = level_id; + + // communicate number of leaf octants on level + MPI_Bcast( + &(elvl->elem_count), 1, MPI_UINT32_T, MBC.masterID, + MBC.comm); + + // allocate leaf octant data for level data (if not master + // rank) + if (MBC.masterID != MBC.id) + elvl->octants.resize(elvl->elem_count); - // count number of octants - meta.elem_count += elvl->elem_count; + // communicate leaf octant data on level + MPI_Bcast( + elvl->octants.data(), + elvl->elem_count * sizeof(octant_t), MPI_BYTE, + MBC.masterID, MBC.comm); + + // count number of octants + meta.elem_count += elvl->elem_count; + } + } + } else { + meta.leaf_count = 0; } - } - } else { - meta.leaf_count = 0; } - } - MPI_Barrier(scomm); - - // clean up memory - if(ncomposite) delete [] adaptiveHoleMapCOMPOSITE; - - // set the global number of meshes to maxtag - nmesh=maxtag; - - // output statistics - if(myid==0){ - for(int i=0;i 0){ - fprintf(stdout," " - "[tioga::performConnectivity::getAdaptiveHoleMap] " - "Mesh Body %d: Levels %d, " - "total octants %lu, total leafs %lu\n",i, - adaptiveHoleMap[i].meta.nlevel, - adaptiveHoleMap[i].meta.elem_count, - adaptiveHoleMap[i].meta.leaf_count); - fflush(stdout); - } + MPI_Barrier(scomm); + + // clean up memory + if (ncomposite) delete[] adaptiveHoleMapCOMPOSITE; + + // set the global number of meshes to maxtag + nmesh = maxtag; + + // output statistics + if (myid == 0) { + for (int i = 0; i < nmesh; i++) { + if (adaptiveHoleMap[i].meta.nlevel > 0) { + fprintf( + stdout, + " " + "[tioga::performConnectivity::getAdaptiveHoleMap] " + "Mesh Body %d: Levels %d, " + "total octants %lu, total leafs %lu\n", + i, adaptiveHoleMap[i].meta.nlevel, + static_cast( + adaptiveHoleMap[i].meta.elem_count), + static_cast( + adaptiveHoleMap[i].meta.leaf_count)); + fflush(stdout); + } + } + } + + // output the hole maps + for (mbi = 0; mbi < nblocks; mbi++) { + auto& mb = mblocks[mbi]; + mb->writeBCnodes(WALLNODETYPE, mb->getMeshTag() - BASE); } - } - - // output the hole maps - for(mbi=0; mbiwriteBCnodes(WALLNODETYPE,mb->getMeshTag()-BASE); - } - this->outputAdaptiveHoleMap(); + this->outputAdaptiveHoleMap(); } /** * Output the hole map to a tecplot compatible file -*/ + */ void tioga::outputHoleMap(void) { - int i,k; - int nnodes,ncells; - int ns1,ns2; - int ii,jj,kk,m; - FILE *fp; - double ds[3]; - char intstring[12]; - char fname[80]; - - for(i=0;i1) ? 1:0; level < meta.nlevel; level++){ - level_t &L = adaptiveHoleMap[m].levels[level]; - const qcoord_t levelh = OCTANT_LEN(L.level_id); - - // octant length - dx[0] = ds[0]*INT2DBL*levelh; - dx[1] = ds[1]*INT2DBL*levelh; - dx[2] = ds[2]*INT2DBL*levelh; - - for(e = 0; e < L.elem_count; e++){ - if(L.octants[e].leafflag==0) continue; // skip to next element - - // compute physical coordinates - x[0] = meta.extents_lo[0] + ds[0]*INT2DBL*L.octants[e].x; - y[0] = meta.extents_lo[1] + ds[1]*INT2DBL*L.octants[e].y; - z[0] = meta.extents_lo[2] + ds[2]*INT2DBL*L.octants[e].z; - x[1] = x[0] + dx[0]; - y[1] = y[0] + dx[1]; - z[1] = z[0] + dx[2]; - - pt = 0; - for(k=0;k<2;k++){ - for(j=0;j<2;j++){ - for(i=0;i<2;i++){ - pt_coords[3*pt+0] = x[i]; - pt_coords[3*pt+1] = y[j]; - pt_coords[3*pt+2] = z[k]; - pt++; +void tioga::outputAdaptiveHoleMap(void) +{ + char filename[128]; + FILE* file; + + double pt_coords[3 * 8]; + double ds[3], dx[3]; + double x[2], y[2], z[2]; + int level, e, m; + int i, j, k; + int pt; + + static int ahm_step = 0; + if (myid == 0) { + for (m = 0; m < nmesh; m++) { + if (adaptiveHoleMap[m].existWall) { + ahm_meta_t& meta = adaptiveHoleMap[m].meta; + + ds[0] = meta.extents_hi[0] - meta.extents_lo[0]; + ds[1] = meta.extents_hi[1] - meta.extents_lo[1]; + ds[2] = meta.extents_hi[2] - meta.extents_lo[2]; + + snprintf( + filename, sizeof(filename), "AHM.body%d.%d.tec", m, + ahm_step++); + writePointsHeaderVolume(filename); + + file = fopen(filename, "a"); + for (level = (meta.nlevel > 1) ? 1 : 0; level < meta.nlevel; + level++) { + level_t& L = adaptiveHoleMap[m].levels[level]; + const qcoord_t levelh = OCTANT_LEN(L.level_id); + + // octant length + dx[0] = ds[0] * INT2DBL * levelh; + dx[1] = ds[1] * INT2DBL * levelh; + dx[2] = ds[2] * INT2DBL * levelh; + + for (e = 0; e < L.elem_count; e++) { + if (L.octants[e].leafflag == 0) + continue; // skip to next element + + // compute physical coordinates + x[0] = meta.extents_lo[0] + + ds[0] * INT2DBL * L.octants[e].x; + y[0] = meta.extents_lo[1] + + ds[1] * INT2DBL * L.octants[e].y; + z[0] = meta.extents_lo[2] + + ds[2] * INT2DBL * L.octants[e].z; + x[1] = x[0] + dx[0]; + y[1] = y[0] + dx[1]; + z[1] = z[0] + dx[2]; + + pt = 0; + for (k = 0; k < 2; k++) { + for (j = 0; j < 2; j++) { + for (i = 0; i < 2; i++) { + pt_coords[3 * pt + 0] = x[i]; + pt_coords[3 * pt + 1] = y[j]; + pt_coords[3 * pt + 2] = z[k]; + pt++; + } + } + } + writePointsVolume( + file, level, e, pt_coords, 2, + L.octants[e].filltype); + } } - } + fflush(file); + fclose(file); } - writePointsVolume(file,level,e,pt_coords,2,L.octants[e].filltype); - } } - fflush(file); - fclose(file); - } } - } } diff --git a/src/kaiser.C b/src/kaiser.C index 18269b1..87d5d9c 100644 --- a/src/kaiser.C +++ b/src/kaiser.C @@ -5,125 +5,133 @@ #define NCOLS 3 // This functions expects a 3x3 matrix -void kaiser(double a[9], int /*nrows*/, int /*n*/, double eigenv[3], - double trace, double sume) { - const double small = 1.0e-12; - const double zero = 0.0; - const double half = 0.5; - const double one = 1.0; - int i, iter, j, k, ncount, nn; - double absp, absq, COS, ctn, eps, halfp, p, q, SIN, ss; - double TAN, temp, xj, xk; - - // if ((n < 1) || (n > NROWS)) { - // return; - // } - iter = 0; - trace = zero; - ss = zero; - for (j = 1; j <= NROWS; j++) { - trace = trace + a[(j - 1) * NROWS + (j - 1)]; - for (i = 1; i <= NCOLS; i++) { - ss = ss + a[(j - 1) * NROWS + (i - 1)] * a[(j - 1) * NROWS + (i - 1)]; +void kaiser( + double a[9], + int /*nrows*/, + int /*n*/, + double eigenv[3], + double trace, + double sume) +{ + const double small = 1.0e-12; + const double zero = 0.0; + const double half = 0.5; + const double one = 1.0; + int i, iter, j, k, ncount, nn; + double absp, absq, COS, ctn, eps, halfp, p, q, SIN, ss; + double TAN, temp, xj, xk; + + // if ((n < 1) || (n > NROWS)) { + // return; + // } + iter = 0; + trace = zero; + ss = zero; + for (j = 1; j <= NROWS; j++) { + trace = trace + a[(j - 1) * NROWS + (j - 1)]; + for (i = 1; i <= NCOLS; i++) { + ss = ss + + a[(j - 1) * NROWS + (i - 1)] * a[(j - 1) * NROWS + (i - 1)]; + } } - } - sume = zero; - eps = small * ss / NROWS; - nn = NROWS * (NROWS - 1) / 2; - ncount = nn; + sume = zero; + eps = small * ss / NROWS; + nn = NROWS * (NROWS - 1) / 2; + ncount = nn; - // ORTHOGONALIZE PAIRS OF COLUMNS J & K, K > J. + // ORTHOGONALIZE PAIRS OF COLUMNS J & K, K > J. twenty: - for (j = 1; j <= (NROWS - 1); j++) { - for (k = j + 1; k <= NROWS; k++) { - - // CALCULATE PLANAR ROTATION REQUIRED - - halfp = zero; - q = zero; - for (i = 1; i <= NROWS; i++) { - xj = a[(j - 1) * NROWS + (i - 1)]; - xk = a[(k - 1) * NROWS + (i - 1)]; - halfp = halfp + xj * xk; - q = q + (xj + xk) * (xj - xk); - } - p = halfp + halfp; - absp = std::fabs(p); - - // If P is very small, the vectors are almost orthogonal. - // Skip the rotation if Q >= 0 (correct ordering). - - if ((absp < eps) && (q >= zero)) { - ncount = ncount - 1; - if (ncount <= 0) { - goto onehundredsixty; + for (j = 1; j <= (NROWS - 1); j++) { + for (k = j + 1; k <= NROWS; k++) { + + // CALCULATE PLANAR ROTATION REQUIRED + + halfp = zero; + q = zero; + for (i = 1; i <= NROWS; i++) { + xj = a[(j - 1) * NROWS + (i - 1)]; + xk = a[(k - 1) * NROWS + (i - 1)]; + halfp = halfp + xj * xk; + q = q + (xj + xk) * (xj - xk); + } + p = halfp + halfp; + absp = std::fabs(p); + + // If P is very small, the vectors are almost orthogonal. + // Skip the rotation if Q >= 0 (correct ordering). + + if ((absp < eps) && (q >= zero)) { + ncount = ncount - 1; + if (ncount <= 0) { + goto onehundredsixty; + } + continue; + } + + // Rotation needed. + + absq = std::fabs(q); + if (absp <= absq) { + TAN = absp / absq; + COS = one / std::sqrt(one + TAN * TAN); + SIN = TAN * COS; + } else { + ctn = absq / absp; + SIN = one / std::sqrt(one + ctn * ctn); + COS = ctn * SIN; + } + COS = std::sqrt((one + COS) * half); + SIN = SIN / (COS + COS); + if (q < zero) { + temp = COS; + COS = SIN; + SIN = temp; + } + if (p < zero) { + SIN = -SIN; + } + + // PERFORM ROTATION + + for (i = 1; i <= NROWS; i++) { + temp = a[(j - 1) * NROWS + (i - 1)]; + a[(j - 1) * NROWS + (i - 1)] = + temp * COS + a[(k - 1) * NROWS + (i - 1)] * SIN; + a[(k - 1) * NROWS + (i - 1)] = + -temp * SIN + a[(k - 1) * NROWS + (i - 1)] * COS; + } } - continue; - } - - // Rotation needed. - - absq = std::fabs(q); - if (absp <= absq) { - TAN = absp / absq; - COS = one / std::sqrt(one + TAN * TAN); - SIN = TAN * COS; - } else { - ctn = absq / absp; - SIN = one / std::sqrt(one + ctn * ctn); - COS = ctn * SIN; - } - COS = std::sqrt((one + COS) * half); - SIN = SIN / (COS + COS); - if (q < zero) { - temp = COS; - COS = SIN; - SIN = temp; - } - if (p < zero) { - SIN = -SIN; - } - - // PERFORM ROTATION - - for (i = 1; i <= NROWS; i++) { - temp = a[(j - 1) * NROWS + (i - 1)]; - a[(j - 1) * NROWS + (i - 1)] = - temp * COS + a[(k - 1) * NROWS + (i - 1)] * SIN; - a[(k - 1) * NROWS + (i - 1)] = - -temp * SIN + a[(k - 1) * NROWS + (i - 1)] * COS; - } } - } - ncount = nn; - iter = iter + 1; - if (iter < 10) { - goto twenty; - } - - // CONVERGED, OR GAVE UP AFTER 10 ITERATIONS + ncount = nn; + iter = iter + 1; + if (iter < 10) { + goto twenty; + } + + // CONVERGED, OR GAVE UP AFTER 10 ITERATIONS onehundredsixty: - for (j = 1; j <= NROWS; j++) { - temp = 0.0; - for (int m = 1; m <= NROWS; m++) { - temp += (a[(j - 1) * NROWS + (m - 1)] * a[(j - 1) * NROWS + (m - 1)]); + for (j = 1; j <= NROWS; j++) { + temp = 0.0; + for (int m = 1; m <= NROWS; m++) { + temp += + (a[(j - 1) * NROWS + (m - 1)] * a[(j - 1) * NROWS + (m - 1)]); + } + eigenv[j - 1] = std::sqrt(temp); + sume = sume + eigenv[j - 1]; } - eigenv[j - 1] = std::sqrt(temp); - sume = sume + eigenv[j - 1]; - } - // SCALE COLUMNS TO HAVE UNIT LENGTH + // SCALE COLUMNS TO HAVE UNIT LENGTH - for (j = 1; j <= NROWS; j++) { - if (eigenv[j - 1] > zero) { - temp = one / eigenv[j - 1]; - } else { - temp = zero; - } - for (int m = 1; m <= NROWS; m++) { - a[(j - 1) * NROWS + (m - 1)] = a[(j - 1) * NROWS + (m - 1)] * temp; + for (j = 1; j <= NROWS; j++) { + if (eigenv[j - 1] > zero) { + temp = one / eigenv[j - 1]; + } else { + temp = zero; + } + for (int m = 1; m <= NROWS; m++) { + a[(j - 1) * NROWS + (m - 1)] = a[(j - 1) * NROWS + (m - 1)] * temp; + } } - } - return; + return; } diff --git a/src/kaiser.h b/src/kaiser.h index ffe1773..f2088a1 100644 --- a/src/kaiser.h +++ b/src/kaiser.h @@ -1,5 +1,5 @@ #ifndef KAISER_H #define KAISER_H -void kaiser(double a[9], int nrows, int n, double eigenv[3], double trace, - double sume); +void kaiser( + double a[9], int nrows, int n, double eigenv[3], double trace, double sume); #endif diff --git a/src/linCartInterp.C b/src/linCartInterp.C index f6b54ee..f0b710c 100644 --- a/src/linCartInterp.C +++ b/src/linCartInterp.C @@ -16,121 +16,142 @@ // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include "linCartInterp.h" #include -namespace cart_interp +namespace cart_interp { +void compute_1d_bases( + const std::vector& ref_coord, + std::vector& phi_x, + std::vector& phi_y, + std::vector& phi_z) { -void compute_1d_bases(const std::vector& ref_coord, - std::vector& phi_x, std::vector& phi_y, std::vector& phi_z) -{ - double zeta = ref_coord[0]; - double mu = ref_coord[1]; - double eta = ref_coord[2]; + double zeta = ref_coord[0]; + double mu = ref_coord[1]; + double eta = ref_coord[2]; - phi_x[0]=(1-zeta)/2; - phi_x[1]=(1+zeta)/2; + phi_x[0] = (1 - zeta) / 2; + phi_x[1] = (1 + zeta) / 2; - phi_y[0]=(1-mu)/2; - phi_y[1]=(1+mu)/2; + phi_y[0] = (1 - mu) / 2; + phi_y[1] = (1 + mu) / 2; - phi_z[0]=(1-eta)/2; - phi_z[1]=(1+eta)/2; + phi_z[0] = (1 - eta) / 2; + phi_z[1] = (1 + eta) / 2; } void compute_weights(const std::vector& ref_coord, double* weights) { - static constexpr int p = 1; - std::vector phi_x(p+1,0); - std::vector phi_y(p+1,0); - std::vector phi_z(p+1,0); - - compute_1d_bases(ref_coord,phi_x,phi_y,phi_z); - - int ind = 0; - for(int k=0;k phi_x(p + 1, 0); + std::vector phi_y(p + 1, 0); + std::vector phi_z(p + 1, 0); + + compute_1d_bases(ref_coord, phi_x, phi_y, phi_z); + + int ind = 0; + for (int k = 0; k < p + 1; k++) { + for (int j = 0; j < p + 1; j++) { + for (int i = 0; i < p + 1; i++) { + weights[ind++] = phi_z[k] * phi_y[j] * phi_x[i]; + } + } } - } } void compute_ref_coords_cell(double* ref_ratio, std::vector& ref_coord) { - static constexpr int p = 1; - // reference coordinates in -1 to 1. Assumes cells of uniform sizes - ref_coord[0] = (ref_ratio[0]-0.5>=0) ? - ((ref_ratio[0]-0.5)/p*2-1) : ((ref_ratio[0]+0.5*(2*p-1))/p*2-1); - ref_coord[1] = (ref_ratio[1]-0.5>=0) ? - ((ref_ratio[1]-0.5)/p*2-1) : ((ref_ratio[1]+0.5*(2*p-1))/p*2-1); - ref_coord[2] = (ref_ratio[2]-0.5>=0) ? - ((ref_ratio[2]-0.5)/p*2-1) : ((ref_ratio[2]+0.5*(2*p-1))/p*2-1); + static constexpr int p = 1; + // reference coordinates in -1 to 1. Assumes cells of uniform sizes + ref_coord[0] = (ref_ratio[0] - 0.5 >= 0) + ? ((ref_ratio[0] - 0.5) / p * 2 - 1) + : ((ref_ratio[0] + 0.5 * (2 * p - 1)) / p * 2 - 1); + ref_coord[1] = (ref_ratio[1] - 0.5 >= 0) + ? ((ref_ratio[1] - 0.5) / p * 2 - 1) + : ((ref_ratio[1] + 0.5 * (2 * p - 1)) / p * 2 - 1); + ref_coord[2] = (ref_ratio[2] - 0.5 >= 0) + ? ((ref_ratio[2] - 0.5) / p * 2 - 1) + : ((ref_ratio[2] + 0.5 * (2 * p - 1)) / p * 2 - 1); } void compute_ref_coords_node(double* ref_ratio, std::vector& ref_coord) { - static constexpr int p = 1; - // reference coordinates in -1 to 1. Assumes cells of uniform sizes - ref_coord[0] = ref_ratio[0]/p*2-1; - ref_coord[1] = ref_ratio[1]/p*2-1; - ref_coord[2] = ref_ratio[2]/p*2-1; + static constexpr int p = 1; + // reference coordinates in -1 to 1. Assumes cells of uniform sizes + ref_coord[0] = ref_ratio[0] / p * 2 - 1; + ref_coord[1] = ref_ratio[1] / p * 2 - 1; + ref_coord[2] = ref_ratio[2] / p * 2 - 1; } -void create_donor_stencil(const int nf, int* ijk_cell, int* dims, double* ref_ratio, int* ijk_stencil, bool isNodal) +void create_donor_stencil( + const int nf, + int* ijk_cell, + int* dims, + double* ref_ratio, + int* ijk_stencil, + bool isNodal) { - static constexpr int basis = 2; - - int start_x, start_y, start_z = 0; - int nX, nY, nZ = 0; - if(isNodal) { - start_x = ijk_cell[0]; - start_y = ijk_cell[1]; - start_z = ijk_cell[2]; - nX = dims[0]+1; - nY = dims[1]+1; - nZ = dims[2]+1; - } - else { - // determine start node if donor stencil is - // right/left or front/behind or above/below of ijk_cell cell-center - start_x = (ref_ratio[0]-0.5>=0) ? (ijk_cell[0]) : (ijk_cell[0]-1); - start_y = (ref_ratio[1]-0.5>=0) ? (ijk_cell[1]) : (ijk_cell[1]-1); - start_z = (ref_ratio[2]-0.5>=0) ? (ijk_cell[2]) : (ijk_cell[2]-1); - nX = dims[0]; - nY = dims[1]; - nZ = dims[2]; - } - - int ind = 0; - for(int k=0;k= 0) ? (ijk_cell[0]) : (ijk_cell[0] - 1); + start_y = (ref_ratio[1] - 0.5 >= 0) ? (ijk_cell[1]) : (ijk_cell[1] - 1); + start_z = (ref_ratio[2] - 0.5 >= 0) ? (ijk_cell[2]) : (ijk_cell[2] - 1); + nX = dims[0]; + nY = dims[1]; + nZ = dims[2]; + } + + int ind = 0; + for (int k = 0; k < basis; k++) { + for (int j = 0; j < basis; j++) { + for (int i = 0; i < basis; i++) { + ijk_stencil[ind++] = + std::max(-nf, std::min(start_x + i * 1, nX + nf - 1)); + ijk_stencil[ind++] = + std::max(-nf, std::min(start_y + j * 1, nY + nf - 1)); + ijk_stencil[ind++] = + std::max(-nf, std::min(start_z + k * 1, nZ + nf - 1)); + } + } + } } -void linear_interpolation(const int nf, int* ijk_cell, int* dims, double* ref_ratio, - int* nw, int* ijk_stencil, double* weights, bool isNodal) +void linear_interpolation( + const int nf, + int* ijk_cell, + int* dims, + double* ref_ratio, + int* nw, + int* ijk_stencil, + double* weights, + bool isNodal) { - std::vector ref_coord(3,0); // array of reference coordinates + std::vector ref_coord(3, 0); // array of reference coordinates - // 8-node donor stencil where the nodes are neighboring cell-centers - // ordering of cell centers in donor stencil is such that - // left->right is along x-axis. back->front is along y-axis. bottom->top is along z-axis - create_donor_stencil(nf,ijk_cell,dims,ref_ratio,ijk_stencil,isNodal); + // 8-node donor stencil where the nodes are neighboring cell-centers + // ordering of cell centers in donor stencil is such that + // left->right is along x-axis. back->front is along y-axis. bottom->top is + // along z-axis + create_donor_stencil(nf, ijk_cell, dims, ref_ratio, ijk_stencil, isNodal); - if(isNodal) - compute_ref_coords_node(ref_ratio,ref_coord); - else - compute_ref_coords_cell(ref_ratio,ref_coord); + if (isNodal) + compute_ref_coords_node(ref_ratio, ref_coord); + else + compute_ref_coords_cell(ref_ratio, ref_coord); - compute_weights(ref_coord,weights); -} + compute_weights(ref_coord, weights); } +} // namespace cart_interp diff --git a/src/linCartInterp.h b/src/linCartInterp.h index 496b8b8..225be6f 100644 --- a/src/linCartInterp.h +++ b/src/linCartInterp.h @@ -23,23 +23,36 @@ #include namespace cart_interp { -void compute_1d_bases(const std::vector &ref_coord, - std::vector &phi_x, std::vector &phi_y, - std::vector &phi_z); - -void compute_linear_weights(const std::vector &ref_coord, - double *weights); - -void compute_ref_coords_cell(double *ref_ratio, std::vector &ref_coord); - -void compute_ref_coords_node(double *ref_ratio, std::vector &ref_coord); - -void create_donor_stencil(const int nf, int *ijk_cell, int *dims, - double *ref_ratio, int *ijk_stencil, bool isNodal); - -void linear_interpolation(const int nf, int *ijk_cell, int *dims, - double *ref_ratio, int *nw, int *ijk_stencil, - double *weights, bool isNodal); +void compute_1d_bases( + const std::vector& ref_coord, + std::vector& phi_x, + std::vector& phi_y, + std::vector& phi_z); + +void compute_linear_weights( + const std::vector& ref_coord, double* weights); + +void compute_ref_coords_cell(double* ref_ratio, std::vector& ref_coord); + +void compute_ref_coords_node(double* ref_ratio, std::vector& ref_coord); + +void create_donor_stencil( + const int nf, + int* ijk_cell, + int* dims, + double* ref_ratio, + int* ijk_stencil, + bool isNodal); + +void linear_interpolation( + const int nf, + int* ijk_cell, + int* dims, + double* ref_ratio, + int* nw, + int* ijk_stencil, + double* weights, + bool isNodal); } // namespace cart_interp #endif /* LINCARTINTERP_H */ diff --git a/src/linklist.C b/src/linklist.C index 42927e1..d01dc56 100644 --- a/src/linklist.C +++ b/src/linklist.C @@ -16,91 +16,80 @@ /* You should have received a copy of the GNU Lesser General Public */ /* License along with this library; if not, write to the Free Software */ -/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ #include "codetypes.h" #include "linklist.h" -void deallocateLinkList(DONORLIST *temp) +void deallocateLinkList(DONORLIST* temp) { - while (temp != NULL) { - DONORLIST* next = temp->next; - TIOGA_FREE(temp); - temp = next; - } + while (temp != NULL) { + DONORLIST* next = temp->next; + TIOGA_FREE(temp); + temp = next; + } } -void deallocateLinkList2(INTEGERLIST *temp) +void deallocateLinkList2(INTEGERLIST* temp) { - while (temp != NULL) { - INTEGERLIST* next = temp->next; - TIOGA_FREE(temp); - temp = next; - } + while (temp != NULL) { + INTEGERLIST* next = temp->next; + TIOGA_FREE(temp); + temp = next; + } } -void deallocateLinkList3(INTEGERLIST2 *temp) +void deallocateLinkList3(INTEGERLIST2* temp) { - while (temp != NULL) { - INTEGERLIST2* tnext = temp->next; - if (temp->intData) TIOGA_FREE(temp->intData); - if (temp->realData) TIOGA_FREE(temp->realData); - TIOGA_FREE(temp); - temp = tnext; - } + while (temp != NULL) { + INTEGERLIST2* tnext = temp->next; + if (temp->intData) TIOGA_FREE(temp->intData); + if (temp->realData) TIOGA_FREE(temp->realData); + TIOGA_FREE(temp); + temp = tnext; + } } -void deallocateLinkList4(INTERPLIST2 *temp) +void deallocateLinkList4(INTERPLIST2* temp) { - while (temp != NULL) { - INTERPLIST2* tnext = temp->next; - if (temp->inode) TIOGA_FREE(temp->inode); - if (temp->weights) TIOGA_FREE(temp->weights); - TIOGA_FREE(temp); - temp = tnext; - } + while (temp != NULL) { + INTERPLIST2* tnext = temp->next; + if (temp->inode) TIOGA_FREE(temp->inode); + if (temp->weights) TIOGA_FREE(temp->weights); + TIOGA_FREE(temp); + temp = tnext; + } } -void insertInList(DONORLIST **donorList,DONORLIST *temp1) +void insertInList(DONORLIST** donorList, DONORLIST* temp1) { - DONORLIST *temp; - DONORLIST *ptemp; - int inserted; - temp=*donorList; - inserted=0; - ptemp=NULL; - while(temp!=NULL && !inserted) - { - if (fabs(temp->donorRes) > temp1->donorRes) - { - temp1->next=temp; - if (ptemp!=NULL) - { - ptemp->next=temp1; - } - else - { - *donorList=temp1; - } - inserted=1; - } - else - { - ptemp=temp; - temp=temp->next; - } + DONORLIST* temp; + DONORLIST* ptemp; + int inserted; + temp = *donorList; + inserted = 0; + ptemp = NULL; + while (temp != NULL && !inserted) { + if (fabs(temp->donorRes) > temp1->donorRes) { + temp1->next = temp; + if (ptemp != NULL) { + ptemp->next = temp1; + } else { + *donorList = temp1; + } + inserted = 1; + } else { + ptemp = temp; + temp = temp->next; + } } - if (!inserted) - { - if (*donorList) - { - temp1->next=NULL; - ptemp->next=temp1; - } - else - { - temp1->next=NULL; - *donorList=temp1; - } + if (!inserted) { + if (*donorList) { + temp1->next = NULL; + ptemp->next = temp1; + } else { + temp1->next = NULL; + *donorList = temp1; + } } } - diff --git a/src/linklist.h b/src/linklist.h index cf3b373..27b77bf 100644 --- a/src/linklist.h +++ b/src/linklist.h @@ -1,9 +1,9 @@ #ifndef LINKLIST_H #define LINKLIST_H -void deallocateLinkList(DONORLIST *temp); -void deallocateLinkList2(INTEGERLIST *temp); -void deallocateLinkList3(INTEGERLIST2 *temp); -void deallocateLinkList4(INTERPLIST2 *temp); -void insertInList(DONORLIST **donorList, DONORLIST *temp1); -int checkHoleMap(double *x, int *nx, int *sam, double *extents); +void deallocateLinkList(DONORLIST* temp); +void deallocateLinkList2(INTEGERLIST* temp); +void deallocateLinkList3(INTEGERLIST2* temp); +void deallocateLinkList4(INTERPLIST2* temp); +void insertInList(DONORLIST** donorList, DONORLIST* temp1); +int checkHoleMap(double* x, int* nx, int* sam, double* extents); #endif diff --git a/src/median.C b/src/median.C index 274072d..81c294c 100644 --- a/src/median.C +++ b/src/median.C @@ -2,143 +2,175 @@ #include // Translated verbatim from median.F90 -void median(int ix[], double x[], int& n, - double& xmed) { - double temp, xhi, xlo, xmax, xmin; - bool odd; - int hi, lo, nby2, nby2p1, mid, i, j, k, itemp; - - nby2 = n / 2; - nby2p1 = nby2 + 1; - odd = true; - - // HI & LO are position limits encompassing the median. - - if (n == (2 * nby2)) {odd = false;} - lo = 1; - hi = n; - if (n < 3) { - if (n < 1) { - xmed = 0.0; - return; +void median(int ix[], double x[], int& n, double& xmed) +{ + double temp, xhi, xlo, xmax, xmin; + bool odd; + int hi, lo, nby2, nby2p1, mid, i, j, k, itemp; + + nby2 = n / 2; + nby2p1 = nby2 + 1; + odd = true; + + // HI & LO are position limits encompassing the median. + + if (n == (2 * nby2)) { + odd = false; } - xmed = x[1-1]; - if (n == 1) {return;} - xmed = 0.5 * (xmed + x[2-1]); - if (x[2-1] < x[1-1]) { - temp = x[1-1]; - x[1-1] = x[2-1]; - x[2-1] = temp; - itemp = ix[1-1]; - ix[1-1] = ix[2-1]; - ix[2-1] = itemp; + lo = 1; + hi = n; + if (n < 3) { + if (n < 1) { + xmed = 0.0; + return; + } + xmed = x[1 - 1]; + if (n == 1) { + return; + } + xmed = 0.5 * (xmed + x[2 - 1]); + if (x[2 - 1] < x[1 - 1]) { + temp = x[1 - 1]; + x[1 - 1] = x[2 - 1]; + x[2 - 1] = temp; + itemp = ix[1 - 1]; + ix[1 - 1] = ix[2 - 1]; + ix[2 - 1] = itemp; + } + return; } - return; - } - // Find median of 1st, middle & last values. + // Find median of 1st, middle & last values. ten: - mid = (lo + hi) / 2; - xmed = x[mid-1]; - xlo = x[lo-1]; - xhi = x[hi-1]; - if(xhi < xlo) { - temp = xhi; - xhi = xlo; - xlo = temp; - } - if (xmed > xhi) { - xmed = xhi; - } else if (xmed < xlo) { - xmed = xlo; - } - - // The basic quicksort algorithm to move all values <= the sort key (XMED) - // to the left-hand end, and all higher values to the other end. - - i = lo; - j = hi; + mid = (lo + hi) / 2; + xmed = x[mid - 1]; + xlo = x[lo - 1]; + xhi = x[hi - 1]; + if (xhi < xlo) { + temp = xhi; + xhi = xlo; + xlo = temp; + } + if (xmed > xhi) { + xmed = xhi; + } else if (xmed < xlo) { + xmed = xlo; + } + + // The basic quicksort algorithm to move all values <= the sort key (XMED) + // to the left-hand end, and all higher values to the other end. + + i = lo; + j = hi; fifty: - do { - if (x[i-1] >= xmed) {break;} - i = i + 1; - } while(true); - do { - if (x[j-1] <= xmed) {break;} - j = j - 1; - } while(true); - if (i < j) { - temp = x[i-1]; - x[i-1] = x[j-1]; - x[j-1] = temp; - - itemp=ix[i-1]; - ix[i-1]=ix[j-1]; - ix[j-1]=itemp; - - i = i + 1; - j = j - 1; - - // Decide which half the median is in. - if (i <= j) {goto fifty;} - } - - if (!odd) { - if ((j == nby2) && (i == nby2p1)) {goto onehundredthirty;} - if (j < nby2) {lo = i;} - if (i > nby2p1) {hi = j;} - if (i != j) {goto onehundred;} - if (i == nby2) {lo = nby2;} - if (j == nby2p1) {hi = nby2p1;} - } else { - if (j < nby2p1) {lo = i;} - if (i > nby2p1) {hi = j;} - if (i != j) {goto onehundred;} - - // Test whether median has been isolated. - - if (i == nby2p1) {return;} - } + do { + if (x[i - 1] >= xmed) { + break; + } + i = i + 1; + } while (true); + do { + if (x[j - 1] <= xmed) { + break; + } + j = j - 1; + } while (true); + if (i < j) { + temp = x[i - 1]; + x[i - 1] = x[j - 1]; + x[j - 1] = temp; + + itemp = ix[i - 1]; + ix[i - 1] = ix[j - 1]; + ix[j - 1] = itemp; + + i = i + 1; + j = j - 1; + + // Decide which half the median is in. + if (i <= j) { + goto fifty; + } + } + + if (!odd) { + if ((j == nby2) && (i == nby2p1)) { + goto onehundredthirty; + } + if (j < nby2) { + lo = i; + } + if (i > nby2p1) { + hi = j; + } + if (i != j) { + goto onehundred; + } + if (i == nby2) { + lo = nby2; + } + if (j == nby2p1) { + hi = nby2p1; + } + } else { + if (j < nby2p1) { + lo = i; + } + if (i > nby2p1) { + hi = j; + } + if (i != j) { + goto onehundred; + } + + // Test whether median has been isolated. + + if (i == nby2p1) { + return; + } + } onehundred: - if (lo < hi - 1) {goto ten;} - - if (!odd) { - if (x[nby2p1-1] < x[nby2-1]) { - temp=x[nby2p1-1]; - x[nby2p1-1]=x[nby2-1]; - x[nby2-1]=temp; - itemp=ix[nby2p1-1]; - ix[nby2p1-1]=ix[nby2-1]; - ix[nby2-1]=itemp; + if (lo < hi - 1) { + goto ten; + } + + if (!odd) { + if (x[nby2p1 - 1] < x[nby2 - 1]) { + temp = x[nby2p1 - 1]; + x[nby2p1 - 1] = x[nby2 - 1]; + x[nby2 - 1] = temp; + itemp = ix[nby2p1 - 1]; + ix[nby2p1 - 1] = ix[nby2 - 1]; + ix[nby2 - 1] = itemp; + } + xmed = 0.5 * (x[nby2 - 1] + x[nby2p1 - 1]); + return; } - xmed = 0.5*(x[nby2-1] + x[nby2p1-1]); + temp = x[lo - 1]; + itemp = ix[lo - 1]; + if (temp > x[hi - 1]) { + x[lo - 1] = x[hi - 1]; + x[hi - 1] = temp; + ix[lo - 1] = ix[hi - 1]; + ix[hi - 1] = itemp; + } + xmed = x[nby2p1 - 1]; return; - } - temp = x[lo-1]; - itemp = ix[lo-1]; - if (temp > x[hi-1]) { - x[lo-1] = x[hi-1]; - x[hi-1] = temp; - ix[lo-1]=ix[hi-1]; - ix[hi-1]=itemp; - } - xmed = x[nby2p1-1]; - return; - - // Special case, N even, J = N/2 & I = J + 1, so the median is - // between the two halves of the series. Find max. of the first - // half & min. of the second half, then average. + + // Special case, N even, J = N/2 & I = J + 1, so the median is + // between the two halves of the series. Find max. of the first + // half & min. of the second half, then average. onehundredthirty: - xmax = x[1-1]; - for (k = lo; k <= j; k++) { - xmax = std::max(xmax, x[k-1]); - } - xmin = x[n-1]; - for (k = i; k <= hi; k++) { - xmin = std::min(xmin, x[k-1]); - } - xmed = 0.5*(xmin + xmax); - - return; + xmax = x[1 - 1]; + for (k = lo; k <= j; k++) { + xmax = std::max(xmax, x[k - 1]); + } + xmin = x[n - 1]; + for (k = i; k <= hi; k++) { + xmin = std::min(xmin, x[k - 1]); + } + xmed = 0.5 * (xmin + xmax); + + return; } diff --git a/src/median.h b/src/median.h index f20b714..a030947 100644 --- a/src/median.h +++ b/src/median.h @@ -1,4 +1,4 @@ #ifndef MEDIAN_H #define MEDIAN_H -void median(int ix[], double x[], int &n, double &xmed); +void median(int ix[], double x[], int& n, double& xmed); #endif diff --git a/src/parallelComm.C b/src/parallelComm.C index b00f246..967165d 100644 --- a/src/parallelComm.C +++ b/src/parallelComm.C @@ -16,7 +16,7 @@ // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include "codetypes.h" #include "mpi.h" #include @@ -24,120 +24,108 @@ #include "parallelComm.h" #define REAL double -void parallelComm::sendRecvPacketsAll(PACKET *sndPack, PACKET *rcvPack) +void parallelComm::sendRecvPacketsAll(PACKET* sndPack, PACKET* rcvPack) { - int i; - int *sint,*sreal,*rint,*rreal; - // - sint=(int *)malloc(sizeof(int)*numprocs); - sreal=(int *) malloc(sizeof(int)*numprocs); - rint=(int *)malloc(sizeof(int)*numprocs); - rreal=(int *) malloc(sizeof(int)*numprocs); - // - for(i=0;i snd_int_displs(numprocs+1, 0); - std::vector rcv_int_displs(numprocs+1, 0); - for (int i=1; i <= numprocs; i++) { - snd_int_displs[i] = snd_int_displs[i-1] + sint[i-1]; - rcv_int_displs[i] = rcv_int_displs[i-1] + rint[i-1]; - } - for (int i=0; i < numprocs; i++) { - int displ = snd_int_displs[i]; - for(int j=0; j < sint[i]; j++){ - all_snd_intData[displ+j] = sndPack[i].intData[j]; + int i; + int *sint, *sreal, *rint, *rreal; + // + sint = (int*)malloc(sizeof(int) * numprocs); + sreal = (int*)malloc(sizeof(int) * numprocs); + rint = (int*)malloc(sizeof(int) * numprocs); + rreal = (int*)malloc(sizeof(int) * numprocs); + // + for (i = 0; i < numprocs; i++) { + sint[i] = sndPack[i].nints; + sreal[i] = sndPack[i].nreals; + } + // + MPI_Alltoall(sint, 1, MPI_INT, rint, 1, MPI_INT, scomm); + MPI_Alltoall(sreal, 1, MPI_INT, rreal, 1, MPI_INT, scomm); + // + for (i = 0; i < numprocs; i++) { + rcvPack[i].nints = rint[i]; + rcvPack[i].nreals = rreal[i]; } - } - MPI_Request int_request; - MPI_Ialltoallv(all_snd_intData, - sint, - snd_int_displs.data(), - MPI_INT, - all_rcv_intData, - rint, - rcv_int_displs.data(), - MPI_INT, - scomm, - &int_request); + // - int all_snd_nreals = std::accumulate(sreal, sreal + numprocs, 0); - int all_rcv_nreals = std::accumulate(rreal, rreal + numprocs, 0); - REAL *all_snd_realData, *all_rcv_realData; - all_snd_realData=(REAL *) malloc(sizeof(REAL)*all_snd_nreals); - all_rcv_realData=(REAL *) malloc(sizeof(REAL)*all_rcv_nreals); - std::vector snd_real_displs(numprocs+1, 0); - std::vector rcv_real_displs(numprocs+1, 0); - for (int i=1; i <= numprocs; i++) { - snd_real_displs[i] = snd_real_displs[i-1] + sreal[i-1]; - rcv_real_displs[i] = rcv_real_displs[i-1] + rreal[i-1]; - } - for (int i=0; i < numprocs; i++) { - int displ = snd_real_displs[i]; - for(int j=0; j < sreal[i]; j++){ - all_snd_realData[displ+j] = sndPack[i].realData[j]; + int all_snd_nints = std::accumulate(sint, sint + numprocs, 0); + int all_rcv_nints = std::accumulate(rint, rint + numprocs, 0); + int *all_snd_intData, *all_rcv_intData; + all_snd_intData = (int*)malloc(sizeof(int) * all_snd_nints); + all_rcv_intData = (int*)malloc(sizeof(int) * all_rcv_nints); + std::vector snd_int_displs(numprocs + 1, 0); + std::vector rcv_int_displs(numprocs + 1, 0); + for (int i = 1; i <= numprocs; i++) { + snd_int_displs[i] = snd_int_displs[i - 1] + sint[i - 1]; + rcv_int_displs[i] = rcv_int_displs[i - 1] + rint[i - 1]; + } + for (int i = 0; i < numprocs; i++) { + int displ = snd_int_displs[i]; + for (int j = 0; j < sint[i]; j++) { + all_snd_intData[displ + j] = sndPack[i].intData[j]; + } } - } - MPI_Request real_request; - MPI_Ialltoallv(all_snd_realData, - sreal, - snd_real_displs.data(), - MPI_DOUBLE, - all_rcv_realData, - rreal, - rcv_real_displs.data(), - MPI_DOUBLE, - scomm, - &real_request); + MPI_Request int_request; + MPI_Ialltoallv( + all_snd_intData, sint, snd_int_displs.data(), MPI_INT, all_rcv_intData, + rint, rcv_int_displs.data(), MPI_INT, scomm, &int_request); - MPI_Wait(&int_request, MPI_STATUS_IGNORE); - for(i=0;i 0) { - rcvPack[i].intData=(int *) malloc(sizeof(int)*rcvPack[i].nints); + int all_snd_nreals = std::accumulate(sreal, sreal + numprocs, 0); + int all_rcv_nreals = std::accumulate(rreal, rreal + numprocs, 0); + REAL *all_snd_realData, *all_rcv_realData; + all_snd_realData = (REAL*)malloc(sizeof(REAL) * all_snd_nreals); + all_rcv_realData = (REAL*)malloc(sizeof(REAL) * all_rcv_nreals); + std::vector snd_real_displs(numprocs + 1, 0); + std::vector rcv_real_displs(numprocs + 1, 0); + for (int i = 1; i <= numprocs; i++) { + snd_real_displs[i] = snd_real_displs[i - 1] + sreal[i - 1]; + rcv_real_displs[i] = rcv_real_displs[i - 1] + rreal[i - 1]; } - if (rcvPack[i].nreals > 0) { - rcvPack[i].realData=(REAL *) malloc(sizeof(REAL)*rcvPack[i].nreals); + for (int i = 0; i < numprocs; i++) { + int displ = snd_real_displs[i]; + for (int j = 0; j < sreal[i]; j++) { + all_snd_realData[displ + j] = sndPack[i].realData[j]; + } } - } + MPI_Request real_request; + MPI_Ialltoallv( + all_snd_realData, sreal, snd_real_displs.data(), MPI_DOUBLE, + all_rcv_realData, rreal, rcv_real_displs.data(), MPI_DOUBLE, scomm, + &real_request); - MPI_Wait(&real_request, MPI_STATUS_IGNORE); - for (int i=0; i < numprocs; i++) { - int displ = rcv_int_displs[i]; - for(int j=0; j < rint[i]; j++){ - rcvPack[i].intData[j] = all_rcv_intData[displ+j]; + MPI_Wait(&int_request, MPI_STATUS_IGNORE); + for (i = 0; i < numprocs; i++) { + if (rcvPack[i].nints > 0) { + rcvPack[i].intData = (int*)malloc(sizeof(int) * rcvPack[i].nints); + } + if (rcvPack[i].nreals > 0) { + rcvPack[i].realData = + (REAL*)malloc(sizeof(REAL) * rcvPack[i].nreals); + } } - } - for (int i=0; i < numprocs; i++) { - int displ = rcv_real_displs[i]; - for(int j=0; j < rreal[i]; j++){ - rcvPack[i].realData[j] = all_rcv_realData[displ+j]; + + MPI_Wait(&real_request, MPI_STATUS_IGNORE); + for (int i = 0; i < numprocs; i++) { + int displ = rcv_int_displs[i]; + for (int j = 0; j < rint[i]; j++) { + rcvPack[i].intData[j] = all_rcv_intData[displ + j]; + } + } + for (int i = 0; i < numprocs; i++) { + int displ = rcv_real_displs[i]; + for (int j = 0; j < rreal[i]; j++) { + rcvPack[i].realData[j] = all_rcv_realData[displ + j]; + } } - } - TIOGA_FREE(all_snd_intData); - TIOGA_FREE(all_rcv_intData); - TIOGA_FREE(all_snd_realData); - TIOGA_FREE(all_rcv_realData); - TIOGA_FREE(sint); - TIOGA_FREE(sreal); - TIOGA_FREE(rint); - TIOGA_FREE(rreal); + TIOGA_FREE(all_snd_intData); + TIOGA_FREE(all_rcv_intData); + TIOGA_FREE(all_snd_realData); + TIOGA_FREE(all_rcv_realData); + TIOGA_FREE(sint); + TIOGA_FREE(sreal); + TIOGA_FREE(rint); + TIOGA_FREE(rreal); } // Old version that does not use ialltoallv @@ -157,7 +145,7 @@ void parallelComm::sendRecvPacketsAll(PACKET *sndPack, PACKET *rcvPack) // status=(MPI_Status *) malloc(sizeof(MPI_Status)*4*numprocs); // // // for(i=0;i 0) { - tag=1; - rcvPack[i].intData=(int *) malloc(sizeof(int)*rcvPack[i].nints); - MPI_Irecv(rcvPack[i].intData,rcvPack[i].nints, - MPI_INT,rcvMap[i], - tag,scomm,&request[irnum++]); - } - if (rcvPack[i].nreals > 0) { - tag=2; - rcvPack[i].realData=(REAL *) malloc(sizeof(REAL)*rcvPack[i].nreals); - MPI_Irecv(rcvPack[i].realData,rcvPack[i].nreals, - MPI_DOUBLE,rcvMap[i], - tag,scomm,&request[irnum++]); - } + // + irnum = 0; + tag = 1; + // + for (i = 0; i < nrecv; i++) + MPI_Irecv( + &(rcount[2 * i]), 2, MPI_INT, rcvMap[i], tag, scomm, + &request[irnum++]); + // + for (i = 0; i < nsend; i++) + MPI_Isend( + &(scount[2 * i]), 2, MPI_INT, sndMap[i], tag, scomm, + &request[irnum++]); + // + MPI_Waitall(irnum, request, status); + for (i = 0; i < nrecv; i++) { + rcvPack[i].nints = rcount[2 * i]; + rcvPack[i].nreals = rcount[2 * i + 1]; } - // - for(i=0;i 0){ - tag=1; - MPI_Isend(sndPack[i].intData,sndPack[i].nints, - MPI_INT,sndMap[i], - tag,scomm,&request[irnum++]); - } - if (sndPack[i].nreals > 0){ - tag=2; - MPI_Isend(sndPack[i].realData,sndPack[i].nreals, - MPI_DOUBLE,sndMap[i], - tag,scomm,&request[irnum++]); - } + // + irnum = 0; + for (i = 0; i < nrecv; i++) { + if (rcvPack[i].nints > 0) { + tag = 1; + rcvPack[i].intData = (int*)malloc(sizeof(int) * rcvPack[i].nints); + MPI_Irecv( + rcvPack[i].intData, rcvPack[i].nints, MPI_INT, rcvMap[i], tag, + scomm, &request[irnum++]); + } + if (rcvPack[i].nreals > 0) { + tag = 2; + rcvPack[i].realData = + (REAL*)malloc(sizeof(REAL) * rcvPack[i].nreals); + MPI_Irecv( + rcvPack[i].realData, rcvPack[i].nreals, MPI_DOUBLE, rcvMap[i], + tag, scomm, &request[irnum++]); + } } - MPI_Waitall(irnum,request,status); - // - TIOGA_FREE(scount); - TIOGA_FREE(rcount); - TIOGA_FREE(request); - TIOGA_FREE(status); + // + for (i = 0; i < nsend; i++) { + if (sndPack[i].nints > 0) { + tag = 1; + MPI_Isend( + sndPack[i].intData, sndPack[i].nints, MPI_INT, sndMap[i], tag, + scomm, &request[irnum++]); + } + if (sndPack[i].nreals > 0) { + tag = 2; + MPI_Isend( + sndPack[i].realData, sndPack[i].nreals, MPI_DOUBLE, sndMap[i], + tag, scomm, &request[irnum++]); + } + } + MPI_Waitall(irnum, request, status); + // + TIOGA_FREE(scount); + TIOGA_FREE(rcount); + TIOGA_FREE(request); + TIOGA_FREE(status); } -void parallelComm::sendRecvPacketsCheck(PACKET *sndPack,PACKET *rcvPack) +void parallelComm::sendRecvPacketsCheck(PACKET* sndPack, PACKET* rcvPack) { - int i; - int *scount,*rcount; - int tag,irnum; - MPI_Request *request; - MPI_Status *status; - // - scount=(int *)malloc(2*sizeof(int)*nsend); - rcount=(int *) malloc(2*sizeof(int)*nrecv); - request=(MPI_Request *) malloc(sizeof(MPI_Request)*2*(nsend+nrecv)); - status=(MPI_Status *) malloc(sizeof(MPI_Status)*2*(nsend+nrecv)); - // - for(i=0;i 0) { - tag=1; - rcvPack[i].intData=(int *) malloc(sizeof(int)*rcvPack[i].nints); - MPI_Irecv(rcvPack[i].intData,rcvPack[i].nints, - MPI_INT,rcvMap[i], - tag,scomm,&request[irnum++]); - } - if (rcvPack[i].nreals > 0 ) { - tag=2; - rcvPack[i].realData=(REAL *) malloc(sizeof(REAL)*rcvPack[i].nreals); - MPI_Irecv(rcvPack[i].realData,rcvPack[i].nreals, - MPI_DOUBLE,rcvMap[i], - tag,scomm,&request[irnum++]); - } + // for(i=0;i 0) { + tag = 1; + rcvPack[i].intData = (int*)malloc(sizeof(int) * rcvPack[i].nints); + MPI_Irecv( + rcvPack[i].intData, rcvPack[i].nints, MPI_INT, rcvMap[i], tag, + scomm, &request[irnum++]); + } + if (rcvPack[i].nreals > 0) { + tag = 2; + rcvPack[i].realData = + (REAL*)malloc(sizeof(REAL) * rcvPack[i].nreals); + MPI_Irecv( + rcvPack[i].realData, rcvPack[i].nreals, MPI_DOUBLE, rcvMap[i], + tag, scomm, &request[irnum++]); + } } - // - for(i=0;i 0){ - tag=1; - MPI_Isend(sndPack[i].intData,sndPack[i].nints, - MPI_INT,sndMap[i], - tag,scomm,&request[irnum++]); - } - if (sndPack[i].nreals > 0){ - tag=2; - MPI_Isend(sndPack[i].realData,sndPack[i].nreals, - MPI_DOUBLE,sndMap[i], - tag,scomm,&request[irnum++]); - } + // + for (i = 0; i < nsend; i++) { + if (sndPack[i].nints > 0) { + tag = 1; + MPI_Isend( + sndPack[i].intData, sndPack[i].nints, MPI_INT, sndMap[i], tag, + scomm, &request[irnum++]); + } + if (sndPack[i].nreals > 0) { + tag = 2; + MPI_Isend( + sndPack[i].realData, sndPack[i].nreals, MPI_DOUBLE, sndMap[i], + tag, scomm, &request[irnum++]); + } } - MPI_Waitall(irnum,request,status); - // - TIOGA_FREE(scount); - TIOGA_FREE(rcount); - TIOGA_FREE(request); - TIOGA_FREE(status); + MPI_Waitall(irnum, request, status); + // + TIOGA_FREE(scount); + TIOGA_FREE(rcount); + TIOGA_FREE(request); + TIOGA_FREE(status); } -void parallelComm::setMap(int ns,int nr, int *snd,int *rcv) +void parallelComm::setMap(int ns, int nr, int* snd, int* rcv) { - int i; - // - if (sndMap) TIOGA_FREE(sndMap); sndMap=NULL; - if (rcvMap) TIOGA_FREE(rcvMap); rcvMap=NULL; - // - nsend=ns; - nrecv=nr; - sndMap=(int *) malloc(sizeof(int)*nsend); - rcvMap=(int *) malloc(sizeof(int)*nrecv); - // - for(i=0;i -struct ArborX::AccessTraits { +struct ArborX::AccessTraits +{ KOKKOS_FUNCTION - static ArborX::Box get(ArborXBoxesWrapper const &d, int i) { - return {{d.data[6 * i + 0] - TOL, d.data[6 * i + 1] - TOL, d.data[6 * i + 2] - TOL}, - {d.data[6 * i + 3] + TOL, d.data[6 * i + 4] + TOL, d.data[6 * i + 5] + TOL}}; + static ArborX::Box get(ArborXBoxesWrapper const& d, int i) + { + return { + {d.data[6 * i + 0] - TOL, d.data[6 * i + 1] - TOL, + d.data[6 * i + 2] - TOL}, + {d.data[6 * i + 3] + TOL, d.data[6 * i + 4] + TOL, + d.data[6 * i + 5] + TOL}}; } KOKKOS_FUNCTION - static typename std::size_t size(ArborXBoxesWrapper const &d) { + static typename std::size_t size(ArborXBoxesWrapper const& d) + { return d.n; } using memory_space = typename DeviceType::memory_space; }; -struct MyCallback { - MeshBlock *mb; - double *xsearch; - int *donorId; - int *donorId_helper; +struct MyCallback +{ + MeshBlock* mb; + double* xsearch; + int* donorId; + int* donorId_helper; template - KOKKOS_FUNCTION auto operator()(Query const &query, int index) const { + KOKKOS_FUNCTION auto operator()(Query const& query, int index) const + { int i = ArborX::getData(query); int dId[2]; @@ -84,14 +93,14 @@ namespace { * * \param[in] node_ids Global IDs for the nodes across all MPI ranks * \param[inout] node_res The nodal resolutions - * \param[out] itag The local index of the original node (duplicate to original mapping) - * \param[in] nnodes The size of the arrays + * \param[out] itag The local index of the original node (duplicate to original + * mapping) \param[in] nnodes The size of the arrays */ void uniquenode_map(uint64_t* node_ids, double* node_res, int* itag, int nnodes) { std::unordered_map lookup; - for (int i=0; i < nnodes; i++) { + for (int i = 0; i < nnodes; i++) { auto found = lookup.find(node_ids[i]); if (found != lookup.end()) { // This is a duplicate node, store the index to the original node @@ -100,7 +109,8 @@ void uniquenode_map(uint64_t* node_ids, double* node_res, int* itag, int nnodes) // Update the original node's resolution to be the max of either // node resolution - node_res[found->second] = std::max(node_res[found->second], node_res[i]); + node_res[found->second] = + std::max(node_res[found->second], node_res[i]); } else { // This is the first appearance of the unique ID, stash it in the // lookup table @@ -111,328 +121,313 @@ void uniquenode_map(uint64_t* node_ids, double* node_res, int* itag, int nnodes) // The max node resolution was stored off in the original node, propagate // this to all the duplicates - for (int i=0; i < nnodes; i++) - node_res[i] = node_res[itag[i]]; -} + for (int i = 0; i < nnodes; i++) node_res[i] = node_res[itag[i]]; } - +} // namespace void MeshBlock::search(void) { - int i,j,k,l,m,n,p,i3; - int ndim; - int iptr,isum,nvert; - OBB *obq; - int *icell; - int *itag; - int cell_count; - int cellindex; - double xd[3]; - double dxc[3]; - double xmin[3]; - double xmax[3]; - int *dId; - // - // form the bounding box of the - // query points - // - if (nsearch == 0) { - donorCount=0; - return; - } - - if (uniform_hex) { - search_uniform_hex(); - return; - } + int i, j, k, l, m, n, p, i3; + int ndim; + int iptr, isum, nvert; + OBB* obq; + int* icell; + int* itag; + int cell_count; + int cellindex; + double xd[3]; + double dxc[3]; + double xmin[3]; + double xmax[3]; + int* dId; + // + // form the bounding box of the + // query points + // + if (nsearch == 0) { + donorCount = 0; + return; + } - obq=(OBB *) malloc(sizeof(OBB)); - -findOBB(xsearch,obq->xc,obq->dxc,obq->vec,nsearch); + if (uniform_hex) { + search_uniform_hex(); + return; + } + obq = (OBB*)malloc(sizeof(OBB)); - //writebbox(obq,4); - //writePoints(xsearch,nsearch,4); - // - // find all the cells that may have intersections with - // the OBB - // - icell=(int *)malloc(sizeof(int)*ncells); - for(i=0;ixc[k])*obq->vec[j][k]; - xmin[j]=std::min(xmin[j],xd[j]); - xmax[j]=std::max(xmax[j],xd[j]); - } - for(j=0;j<3;j++) - { - xd[j]=(xmax[j]+xmin[j])*0.5; - dxc[j]=(xmax[j]-xmin[j])*0.5; - } - } - if (fabs(xd[0]) <= (dxc[0]+obq->dxc[0]) && - fabs(xd[1]) <= (dxc[1]+obq->dxc[1]) && - fabs(xd[2]) <= (dxc[2]+obq->dxc[2])) - { - // - // create a LIFO stack - // with all the cells that - // have bounding box intersection with - // the QP bounding box - // - icell[p]=iptr; - iptr=p; - cell_count++; - } - p++; - } + findOBB(xsearch, obq->xc, obq->dxc, obq->vec, nsearch); + + // writebbox(obq,4); + // writePoints(xsearch,nsearch,4); + // + // find all the cells that may have intersections with + // the OBB + // + icell = (int*)malloc(sizeof(int) * ncells); + for (i = 0; i < ncells; i++) icell[i] = -1; + iptr = -1; + cell_count = 0; + p = 0; + for (n = 0; n < ntypes; n++) { + nvert = nv[n]; + for (i = 0; i < nc[n]; i++) { + // + // find each cell that has + // overlap with the bounding box + // + xmin[0] = xmin[1] = xmin[2] = BIGVALUE; + xmax[0] = xmax[1] = xmax[2] = -BIGVALUE; + for (m = 0; m < nvert; m++) { + i3 = 3 * (vconn[n][nvert * i + m] - BASE); + for (j = 0; j < 3; j++) { + xd[j] = 0; + for (k = 0; k < 3; k++) + xd[j] += (x[i3 + k] - obq->xc[k]) * obq->vec[j][k]; + xmin[j] = std::min(xmin[j], xd[j]); + xmax[j] = std::max(xmax[j], xd[j]); + } + for (j = 0; j < 3; j++) { + xd[j] = (xmax[j] + xmin[j]) * 0.5; + dxc[j] = (xmax[j] - xmin[j]) * 0.5; + } + } + if (fabs(xd[0]) <= (dxc[0] + obq->dxc[0]) && + fabs(xd[1]) <= (dxc[1] + obq->dxc[1]) && + fabs(xd[2]) <= (dxc[2] + obq->dxc[2])) { + // + // create a LIFO stack + // with all the cells that + // have bounding box intersection with + // the QP bounding box + // + icell[p] = iptr; + iptr = p; + cell_count++; + } + p++; + } } - // - // now find the axis aligned bounding box - // of each cell in the LIFO stack to build the - // ADT - // + // + // now find the axis aligned bounding box + // of each cell in the LIFO stack to build the + // ADT + // - if (elementBbox) TIOGA_FREE(elementBbox); - if (elementList) TIOGA_FREE(elementList); - elementBbox=(double *)malloc(sizeof(double)*cell_count*6); - elementList=(int *)malloc(sizeof(int)*cell_count); - // - k=iptr; - l=0; - p=0; - //for(k=0;k bvh(ExecutionSpace{}, ArborXBoxesWrapper{elementBbox, cell_count}); + ArborX::BVH bvh( + ExecutionSpace{}, ArborXBoxesWrapper{elementBbox, cell_count}); #else - // - // build the ADT now - // - if (adt) { - adt->clearData(); - } else { - adt = new ADT[1]; - } - adt->buildADT(ndim, cell_count, elementBbox); + // + // build the ADT now + // + if (adt) { + adt->clearData(); + } else { + adt = new ADT[1]; + } + adt->buildADT(ndim, cell_count, elementBbox); #endif - // - if (donorId) TIOGA_FREE(donorId); - donorId=(int*)malloc(sizeof(int)*nsearch); - if (xtag) TIOGA_FREE(xtag); - xtag=(int *)malloc(sizeof(int)*nsearch); - // - // create a unique hash - // + // + if (donorId) TIOGA_FREE(donorId); + donorId = (int*)malloc(sizeof(int) * nsearch); + if (xtag) TIOGA_FREE(xtag); + xtag = (int*)malloc(sizeof(int) * nsearch); + // + // create a unique hash + // #ifdef TIOGA_HAS_NODEGID - uniquenode_map(gid_search.data(), res_search, xtag, nsearch); + uniquenode_map(gid_search.data(), res_search, xtag, nsearch); #else - uniquenodes_octree(xsearch,tagsearch,res_search,xtag,&nsearch); + uniquenodes_octree(xsearch, tagsearch, res_search, xtag, &nsearch); #endif - // - donorCount=0; - ipoint=0; - dId=(int *) malloc(sizeof(int) *2); + // + donorCount = 0; + ipoint = 0; + dId = (int*)malloc(sizeof(int) * 2); #ifdef TIOGA_USE_ARBORX - int *donorId_helper = (int*)malloc(sizeof(int)*nsearch); - for (int i = 0; i < nsearch; i++) { - donorId[i] = -1; - donorId_helper[i] = 0; - } + int* donorId_helper = (int*)malloc(sizeof(int) * nsearch); + for (int i = 0; i < nsearch; i++) { + donorId[i] = -1; + donorId_helper[i] = 0; + } - using QueryType = ArborX::Intersects; - using PredicateType = - ArborX::PredicateWithAttachment; + using QueryType = ArborX::Intersects; + using PredicateType = ArborX::PredicateWithAttachment; - Kokkos::View queries_non_compact( - Kokkos::ViewAllocateWithoutInitializing("queries"), nsearch); + Kokkos::View queries_non_compact( + Kokkos::ViewAllocateWithoutInitializing("queries"), nsearch); - int n_queries; - Kokkos::parallel_scan( - "tioga:construct_queries", - Kokkos::RangePolicy(0, nsearch), - KOKKOS_LAMBDA(int i, int &update, bool last_pass) { - if (xtag[i] == i) { - if (last_pass) { - queries_non_compact(update) = - ArborX::attach(QueryType(ArborX::Point{ - xsearch[3 * i], xsearch[3 * i + 1], - xsearch[3 * i + 2]}), i); - } - ++update; - } - }, - n_queries); - auto queries = - Kokkos::subview(queries_non_compact, Kokkos::make_pair(0, n_queries)); + int n_queries; + Kokkos::parallel_scan( + "tioga:construct_queries", + Kokkos::RangePolicy(0, nsearch), + KOKKOS_LAMBDA(int i, int& update, bool last_pass) { + if (xtag[i] == i) { + if (last_pass) { + queries_non_compact(update) = ArborX::attach( + QueryType(ArborX::Point{ + xsearch[3 * i], xsearch[3 * i + 1], + xsearch[3 * i + 2]}), + i); + } + ++update; + } + }, + n_queries); + auto queries = + Kokkos::subview(queries_non_compact, Kokkos::make_pair(0, n_queries)); - // printf("#%d: n_queries = %d, n_search = %d\n", myid, n_queries, nsearch); - bvh.query(ExecutionSpace{}, queries, MyCallback{this, xsearch, donorId, donorId_helper}, - ArborX::Experimental::TraversalPolicy().setPredicateSorting(false)); + // printf("#%d: n_queries = %d, n_search = %d\n", myid, n_queries, nsearch); + bvh.query( + ExecutionSpace{}, queries, + MyCallback{this, xsearch, donorId, donorId_helper}, + ArborX::Experimental::TraversalPolicy().setPredicateSorting(false)); - for (i = 0; i < nsearch; i++) { - if (i != xtag[i]) { - donorId[i] = donorId[xtag[i]]; - } + for (i = 0; i < nsearch; i++) { + if (i != xtag[i]) { + donorId[i] = donorId[xtag[i]]; + } - if (donorId[i] > -1) { - donorCount++; - } - } + if (donorId[i] > -1) { + donorCount++; + } + } #else - for(i=0;isearchADT(this,&(donorId[i]),&(xsearch[3*i])); - adt->searchADT(this,dId,&(xsearch[3*i])); - // std::cout << "ADT -> (" << dId[0] << "," << dId[1] << ")\n"; - donorId[i]=dId[0]; - } - else { - donorId[i]=donorId[xtag[i]]; - } - if (donorId[i] > -1) { - donorCount++; - } - ipoint+=3; - } + for (i = 0; i < nsearch; i++) { + if (xtag[i] == i) { + // adt->searchADT(this,&(donorId[i]),&(xsearch[3*i])); + adt->searchADT(this, dId, &(xsearch[3 * i])); + // std::cout << "ADT -> (" << dId[0] << "," << dId[1] << ")\n"; + donorId[i] = dId[0]; + } else { + donorId[i] = donorId[xtag[i]]; + } + if (donorId[i] > -1) { + donorCount++; + } + ipoint += 3; + } #endif - TIOGA_FREE(dId); - TIOGA_FREE(icell); - TIOGA_FREE(obq); + TIOGA_FREE(dId); + TIOGA_FREE(icell); + TIOGA_FREE(obq); #ifdef TIOGA_USE_ARBORX - TIOGA_FREE(donorId_helper); + TIOGA_FREE(donorId_helper); #endif } void MeshBlock::search_uniform_hex(void) { - if (donorId) free(donorId); - donorId=(int*)malloc(sizeof(int)*nsearch); - if (xtag) free(xtag); - xtag=(int *)malloc(sizeof(int)*nsearch); - // + if (donorId) free(donorId); + donorId = (int*)malloc(sizeof(int) * nsearch); + if (xtag) free(xtag); + xtag = (int*)malloc(sizeof(int) * nsearch); + // #ifdef TIOGA_HAS_NODEGID - uniquenode_map(gid_search.data(), res_search, xtag, nsearch); + uniquenode_map(gid_search.data(), res_search, xtag, nsearch); #else - uniquenodes_octree(xsearch,tagsearch,res_search,xtag,&nsearch); + uniquenodes_octree(xsearch, tagsearch, res_search, xtag, &nsearch); #endif - // - int donorCount=0; - int *dId=(int *) malloc(sizeof(int) *2); - double xvec[8][3]; - // - // corners of a cube with of side 4*TOL - // with origin as the center - // - for(int jj=0;jj<8;jj++) - for(int k=0;k<3;k++) xvec[jj][k]=(2*((jj & (1 << k)) >> k)-1)*2*TOL; - // - double xd[3]; - int dID[2]; - for(int i=0;ivec[j][k]; - idx[j]=xd[j]/dx[j]; - } - if (xd[0] > -TOL && xd[0] < idims[0]*dx[0]+TOL && - xd[1] > -TOL && xd[1] < idims[1]*dx[1]+TOL && - xd[2] > -TOL && xd[2] < idims[2]*dx[2]+TOL) - { - for(int k=0;k<3;k++) if (idx[k]==idims[k]) idx[k]--; - dID[0]=uindx[idx[2]*idims[1]*idims[0]+idx[1]*idims[0]+idx[0]]; - dID[1]=(dID[0] > -1) ? (cellRes[dID[0]]==BIGVALUE) : 1; - for(int jj=0;jj<8 && (dId[0]==-1 || dID[1]) ;jj++) - { - for(int k=0;k<3;k++) - { - idx[k]=(xd[k]+xvec[jj][k])/dx[k]; - if (idx[k]==idims[k]) idx[k]--; - } - int dtest=uindx[idx[2]*idims[1]*idims[0]+idx[1]*idims[0]+idx[0]]; - dID[1]=(dtest > -1) ? (cellRes[dtest]==BIGVALUE) : 1; - dID[0]=(dID[0] == -1) ? dtest : (!dID[1] ? dtest : dID[0]); - } - donorId[i]=dID[0]; + // + int donorCount = 0; + int* dId = (int*)malloc(sizeof(int) * 2); + double xvec[8][3]; + // + // corners of a cube with of side 4*TOL + // with origin as the center + // + for (int jj = 0; jj < 8; jj++) + for (int k = 0; k < 3; k++) + xvec[jj][k] = (2 * ((jj & (1 << k)) >> k) - 1) * 2 * TOL; + // + double xd[3]; + int dID[2]; + for (int i = 0; i < nsearch; i++) { + int idx[3]; + if (xtag[i] == i) { + for (int j = 0; j < 3; j++) { + xd[j] = 0; + for (int k = 0; k < 3; k++) + xd[j] += (xsearch[3 * i + k] - xlow[k]) * obh->vec[j][k]; + idx[j] = xd[j] / dx[j]; } - else - { - donorId[i]=-1; - } - } - else { - donorId[i]=donorId[xtag[i]]; - } - if (donorId[i] > -1) { - donorCount++; - } - ipoint+=3; + if (xd[0] > -TOL && xd[0] < idims[0] * dx[0] + TOL && + xd[1] > -TOL && xd[1] < idims[1] * dx[1] + TOL && + xd[2] > -TOL && xd[2] < idims[2] * dx[2] + TOL) { + for (int k = 0; k < 3; k++) + if (idx[k] == idims[k]) idx[k]--; + dID[0] = uindx + [idx[2] * idims[1] * idims[0] + idx[1] * idims[0] + idx[0]]; + dID[1] = (dID[0] > -1) ? (cellRes[dID[0]] == BIGVALUE) : 1; + for (int jj = 0; jj < 8 && (dId[0] == -1 || dID[1]); jj++) { + for (int k = 0; k < 3; k++) { + idx[k] = (xd[k] + xvec[jj][k]) / dx[k]; + if (idx[k] == idims[k]) idx[k]--; + } + int dtest = uindx + [idx[2] * idims[1] * idims[0] + idx[1] * idims[0] + + idx[0]]; + dID[1] = (dtest > -1) ? (cellRes[dtest] == BIGVALUE) : 1; + dID[0] = + (dID[0] == -1) ? dtest : (!dID[1] ? dtest : dID[0]); + } + donorId[i] = dID[0]; + } else { + donorId[i] = -1; + } + } else { + donorId[i] = donorId[xtag[i]]; + } + if (donorId[i] > -1) { + donorCount++; + } + ipoint += 3; } - free(dId); + free(dId); } diff --git a/src/searchADTrecursion.C b/src/searchADTrecursion.C index 06d58c4..f5430a9 100644 --- a/src/searchADTrecursion.C +++ b/src/searchADTrecursion.C @@ -16,74 +16,105 @@ // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include "codetypes.h" #include "MeshBlock.h" -void searchIntersections(MeshBlock *mb,int *cellIndex,int *adtIntegers,double *adtReals, - double *coord,int level,int node,double *xsearch,int nelem,int ndim); +void searchIntersections( + MeshBlock* mb, + int* cellIndex, + int* adtIntegers, + double* adtReals, + double* coord, + int level, + int node, + double* xsearch, + int nelem, + int ndim); -void ADT::searchADT(MeshBlock *mb, int *cellIndex,double *xsearch) +void ADT::searchADT(MeshBlock* mb, int* cellIndex, double* xsearch) { - int i; - int flag; - int rootNode; - // - // check if the given point is in the bounds of - // the ADT - // - rootNode=0; - cellIndex[0]=-1; - cellIndex[1]=0; - // - flag=1; - for(i=0;i= adtExtents[2*i] -mb->searchTol)); - for(i=0;isearchTol)); - // - // call recursive routine to check intersections with - // ADT nodes - // - if (flag) searchIntersections(mb,cellIndex,adtIntegers,adtReals, - coord,0,rootNode,xsearch,nelem,ndim); + int i; + int flag; + int rootNode; + // + // check if the given point is in the bounds of + // the ADT + // + rootNode = 0; + cellIndex[0] = -1; + cellIndex[1] = 0; + // + flag = 1; + for (i = 0; i < ndim / 2; i++) + flag = (flag && (xsearch[i] >= adtExtents[2 * i] - mb->searchTol)); + for (i = 0; i < ndim / 2; i++) + flag = (flag && (xsearch[i] <= adtExtents[2 * i + 1] + mb->searchTol)); + // + // call recursive routine to check intersections with + // ADT nodes + // + if (flag) + searchIntersections( + mb, cellIndex, adtIntegers, adtReals, coord, 0, rootNode, xsearch, + nelem, ndim); } -void searchIntersections(MeshBlock *mb,int *cellIndex,int *adtIntegers,double *adtReals, - double *coord,int level,int node,double *xsearch,int nelem,int ndim) +void searchIntersections( + MeshBlock* mb, + int* cellIndex, + int* adtIntegers, + double* adtReals, + double* coord, + int level, + int node, + double* xsearch, + int nelem, + int ndim) { - int i; - int d,nodeChild,dimcut; - double element[ndim]; - bool flag; - // - for(i=0;i=element[i]-mb->searchTol)); - for(i=ndim/2;isearchTol)); - // - if (flag) { - mb->checkContainment(cellIndex,adtIntegers[4*node],xsearch); - if (cellIndex[0] > -1 && cellIndex[1]==0) return; - } - // - // check the left and right children - // now - // - for(d=1;d<3;d++){ - nodeChild=adtIntegers[4*node+d]; - if (nodeChild > -1) { - nodeChild=adtIntegers[4*nodeChild+3]; - for(i=0;i= element[i] - mb->searchTol)); + for (i = ndim / 2; i < ndim; i++) + flag = (flag && (xsearch[i - ndim / 2] <= element[i] + mb->searchTol)); + // + if (flag) { + mb->checkContainment(cellIndex, adtIntegers[4 * node], xsearch); + if (cellIndex[0] > -1 && cellIndex[1] == 0) return; + } + // + // check the left and right children + // now + // + for (d = 1; d < 3; d++) { + nodeChild = adtIntegers[4 * node + d]; + if (nodeChild > -1) { + nodeChild = adtIntegers[4 * nodeChild + 3]; + for (i = 0; i < ndim; i++) + element[i] = adtReals[ndim * nodeChild + i]; - flag=1; - for(i=0;i=element[i]-mb->searchTol)); - for(i=ndim/2;isearchTol)); - if (flag) { - searchIntersections(mb,cellIndex,adtIntegers,adtReals,coord,level+1, - nodeChild,xsearch,nelem,ndim); - if (cellIndex[0] > -1 && cellIndex[1]==0) return; - } - } - } - return; + flag = 1; + for (i = 0; i < ndim / 2; i++) + flag = (flag && (xsearch[i] >= element[i] - mb->searchTol)); + for (i = ndim / 2; i < ndim; i++) + flag = + (flag && + (xsearch[i - ndim / 2] <= element[i] + mb->searchTol)); + if (flag) { + searchIntersections( + mb, cellIndex, adtIntegers, adtReals, coord, level + 1, + nodeChild, xsearch, nelem, ndim); + if (cellIndex[0] > -1 && cellIndex[1] == 0) return; + } + } + } + return; } \ No newline at end of file diff --git a/src/tioga.C b/src/tioga.C index 3405419..d31c8a4 100644 --- a/src/tioga.C +++ b/src/tioga.C @@ -16,7 +16,7 @@ // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include "codetypes.h" #include "tioga.h" #include @@ -30,1279 +30,1323 @@ using namespace TIOGA; */ void tioga::setCommunicator(MPI_Comm communicator, int id_proc, int nprocs) { - scomm=communicator; - myid=id_proc; - numprocs=nprocs; - sendCount=(int *) malloc(sizeof(int)*numprocs); - recvCount=(int *) malloc(sizeof(int)*numprocs); - - // get MPI group for TIOGA WORLD communicator: used to obtain subgroups - MPI_Comm_group(scomm,&scomm_group); - // - // only one mesh block per process for now - // this can be changed at a later date - // but will be a fairly invasive change - // - // nblocks=0; - // mb=new MeshBlock[1]; - // - // instantiate the parallel communication class - // - pc=new parallelComm[1]; - pc->myid=myid; - pc->scomm=scomm; - pc->numprocs=numprocs; - - // instantiate the parallel communication class - // - pc_cart=new parallelComm[1]; - pc_cart->myid=myid; - pc_cart->scomm=scomm; - pc_cart->numprocs=numprocs; - // + scomm = communicator; + myid = id_proc; + numprocs = nprocs; + sendCount = (int*)malloc(sizeof(int) * numprocs); + recvCount = (int*)malloc(sizeof(int) * numprocs); + + // get MPI group for TIOGA WORLD communicator: used to obtain subgroups + MPI_Comm_group(scomm, &scomm_group); + // + // only one mesh block per process for now + // this can be changed at a later date + // but will be a fairly invasive change + // + // nblocks=0; + // mb=new MeshBlock[1]; + // + // instantiate the parallel communication class + // + pc = new parallelComm[1]; + pc->myid = myid; + pc->scomm = scomm; + pc->numprocs = numprocs; + + // instantiate the parallel communication class + // + pc_cart = new parallelComm[1]; + pc_cart->myid = myid; + pc_cart->scomm = scomm; + pc_cart->numprocs = numprocs; + // } -void tioga::setNumCompositeBodies(int ncomp){ - ncomposite=ncomp; - compositeBody.resize(ncomposite); +void tioga::setNumCompositeBodies(int ncomp) +{ + ncomposite = ncomp; + compositeBody.resize(ncomposite); } /** * register a composite body */ -void tioga::registerCompositeBody(int compbodytag,int nbodytags,int *meshtags,int *dominancetags,double searchTol){ - // resize and fill composite body tag IDs - compositeBody[compbodytag-BASE].searchTol = searchTol; - compositeBody[compbodytag-BASE].bodyids.resize(nbodytags); - compositeBody[compbodytag-BASE].dominanceflags.resize(nbodytags); - for(int i=0; i0){ - /* ================================= */ - /* 1. set mesh block composite flags */ - /* ================================= */ - for(int mbi=0; mbigetMeshTag()-BASE; - - for(int cb=0; cbsetCompositeFlag(Composite.searchTol,Composite.dominanceflags[i]); +void tioga::assembleCompositeMap(void) +{ + int bodyi, bodyj; + int maxtag; + int i, j; + + if (ncomposite > 0) { + /* ================================= */ + /* 1. set mesh block composite flags */ + /* ================================= */ + for (int mbi = 0; mbi < nblocks; mbi++) { + auto& mb = mblocks[mbi]; + int mbtag = mb->getMeshTag() - BASE; + + for (int cb = 0; cb < ncomposite; cb++) { + CompositeBody& Composite = compositeBody[cb]; + + int nbodies = Composite.bodyids.size(); + for (i = 0; i < nbodies; i++) { + bodyi = Composite.bodyids[i] - BASE; + if (bodyi == mbtag) + mb->setCompositeFlag( + Composite.searchTol, Composite.dominanceflags[i]); + } + } } - } - } - /* ======================================== */ - /* 2. assemble composite body communicators */ - /* ======================================== */ - // calculate max number of mesh tags - int maxtagLocal = -BIGINT; - for(int mbi=0; mbigetMeshTag(); + /* ======================================== */ + /* 2. assemble composite body communicators */ + /* ======================================== */ + // calculate max number of mesh tags + int maxtagLocal = -BIGINT; + for (int mbi = 0; mbi < nblocks; mbi++) { + auto& mb = mblocks[mbi]; + int mbtag = mb->getMeshTag(); - maxtagLocal = (maxtagLocal < mbtag) ? mbtag:maxtagLocal; - } - MPI_Allreduce(&maxtagLocal,&maxtag,1,MPI_INT,MPI_MAX,scomm); - - // resize the composite body map: number of composite bodies - compositeBodyMap.resize(ncomposite); - - // fill composite map: all ranks have compositeBody info -> compositeBodyMap is globally known - for(int cb=0; cb existMeshTag(numprocs); - std::vector comp_list(numprocs); - - /* ===================================== */ - /* set mesh body ranks and communicators */ - /* ===================================== */ - /* NOTE: There is one task. - * 1. Build communicator between all COMPOSITE ranks of a body - * + the master rank of that body. - * 1a. For each body, we set the rank with lowest id as the rank master - * 1b. Build body composite subgroup/communicator and new rank IDs. - */ - - /* ================================ */ - /* Step A: count max number of tags */ - /* ================================ */ - maxtagLocal = -BIGINT; - for(int mbi=0; mbigetMeshTag(); - - maxtagLocal = (maxtagLocal < mbtag) ? mbtag:maxtagLocal; - } - MPI_Allreduce(&maxtagLocal,&maxtag,1,MPI_INT,MPI_MAX,scomm); - - // allocate mesh block complement communicators and rank master arrays - if(meshblockComposite) delete [] meshblockComposite; - meshblockComposite = new meshblockCompInfo[maxtag]; - - /* ========================================= */ - /* Step B: create each subgroup per mesh tag */ - /* ========================================= */ - for(int cb=0; cbgetMeshTag(); - if(bodyj == mbtag-BASE){foundFlag = 1; break;} + MPI_Allreduce(&maxtagLocal, &maxtag, 1, MPI_INT, MPI_MAX, scomm); + + // resize the composite body map: number of composite bodies + compositeBodyMap.resize(ncomposite); + + // fill composite map: all ranks have compositeBody info -> + // compositeBodyMap is globally known + for (int cb = 0; cb < ncomposite; cb++) { + CompositeBody& Composite = compositeBody[cb]; + + // resize the composite body map: [#MB]x[#MB] + compositeBodyMap[cb].resize(maxtag); + for (i = 0; i < maxtag; i++) + compositeBodyMap[cb][i].resize(maxtag, 0); // fill 0 + + int nbodies = Composite.bodyids.size(); + for (i = 0; i < nbodies; i++) { + bodyi = Composite.bodyids[i] - BASE; + for (j = i + 1; j < nbodies; j++) { + bodyj = Composite.bodyids[j] - BASE; + compositeBodyMap[cb][bodyi][bodyj] = 1; + compositeBodyMap[cb][bodyj][bodyi] = 1; // transpose + } + } } - } - - // 3. inform all ranks of which ranks are involved in this mesh tag - std::fill(existMeshTag.begin(),existMeshTag.end(),0); - MPI_Allgather(&foundFlag,1,MPI_CHAR,existMeshTag.data(),1,MPI_CHAR,scomm); - // reset composite rank lists - std::fill(comp_list.begin(),comp_list.end(),0); + // assemble composite-body communication schedules + assembleCompositeComms(); + } +} - // create MPI subgroup ranks for this mesh tag: composite list - compositecount = 0; - for(int ii=0; ii existMeshTag(numprocs); + std::vector comp_list(numprocs); + + /* ===================================== */ + /* set mesh body ranks and communicators */ + /* ===================================== */ + /* NOTE: There is one task. + * 1. Build communicator between all COMPOSITE ranks of a body + * + the master rank of that body. + * 1a. For each body, we set the rank with lowest id as the rank master + * 1b. Build body composite subgroup/communicator and new rank IDs. + */ + + /* ================================ */ + /* Step A: count max number of tags */ + /* ================================ */ + maxtagLocal = -BIGINT; + for (int mbi = 0; mbi < nblocks; mbi++) { + auto& mb = mblocks[mbi]; + int mbtag = mb->getMeshTag(); - // construct the subgroups using the composite rank lists - MPI_Group_incl(scomm_group,compositecount,comp_list.data(),&meshblockCompositeGroup); + maxtagLocal = (maxtagLocal < mbtag) ? mbtag : maxtagLocal; + } + MPI_Allreduce(&maxtagLocal, &maxtag, 1, MPI_INT, MPI_MAX, scomm); - // create composite MPI subgroup communicator and rank info - MPI_Comm_create(scomm,meshblockCompositeGroup,&(MBC.comm)); - MPI_Comm_rank(MBC.comm,&(MBC.id)); - MPI_Comm_size(MBC.comm,&(MBC.nrank)); + // allocate mesh block complement communicators and rank master arrays + if (meshblockComposite) delete[] meshblockComposite; + meshblockComposite = new meshblockCompInfo[maxtag]; - //printf("My GID[%2d] (comp rank %2d of %2d), body_tag[%d] of %d blocks, master rank %d, %d\n", - // myid,MBC.id,MBC.nrank,bodyi,maxtag,MBC.masterID,myid == MBC.masterID); + /* ========================================= */ + /* Step B: create each subgroup per mesh tag */ + /* ========================================= */ + for (int cb = 0; cb < ncomposite; cb++) { + CompositeBody& Composite = compositeBody[cb]; + int nbodies = Composite.bodyids.size(); - // cleanup memory - MPI_Group_free(&meshblockCompositeGroup); + for (int i = 0; i < nbodies; i++) { + int bodyi = Composite.bodyids[i] - BASE; + meshblockCompInfo& MBC = meshblockComposite[bodyi]; + + // 1. set composite master rank ID (use complement info) + MBC.masterID = meshblockComplement[bodyi].masterID; + MPI_Allreduce( + MPI_IN_PLACE, &(MBC.masterID), 1, MPI_INT, MPI_MAX, scomm); + MBC.comm = MPI_COMM_NULL; + + // 2. find if other ranks with mesh blocks in same composite body + char foundFlag = 0; + for (int j = 0; j < nbodies && foundFlag == 0; j++) { + int bodyj = Composite.bodyids[j] - BASE; + + for (int mbi = 0; mbi < nblocks; mbi++) { + auto& mb = mblocks[mbi]; + int mbtag = mb->getMeshTag(); + if (bodyj == mbtag - BASE) { + foundFlag = 1; + break; + } + } + } + + // 3. inform all ranks of which ranks are involved in this mesh tag + std::fill(existMeshTag.begin(), existMeshTag.end(), 0); + MPI_Allgather( + &foundFlag, 1, MPI_CHAR, existMeshTag.data(), 1, MPI_CHAR, + scomm); + + // reset composite rank lists + std::fill(comp_list.begin(), comp_list.end(), 0); + + // create MPI subgroup ranks for this mesh tag: composite list + compositecount = 0; + for (int ii = 0; ii < numprocs; ii++) { + // add rank i to composite list + if (existMeshTag[ii]) comp_list[compositecount++] = ii; + } + + // construct the subgroups using the composite rank lists + MPI_Group_incl( + scomm_group, compositecount, comp_list.data(), + &meshblockCompositeGroup); + + // create composite MPI subgroup communicator and rank info + MPI_Comm_create(scomm, meshblockCompositeGroup, &(MBC.comm)); + MPI_Comm_rank(MBC.comm, &(MBC.id)); + MPI_Comm_size(MBC.comm, &(MBC.nrank)); + + // printf("My GID[%2d] (comp rank %2d of %2d), body_tag[%d] of %d + // blocks, master rank %d, %d\n", + // myid,MBC.id,MBC.nrank,bodyi,maxtag,MBC.masterID,myid == + // MBC.masterID); + + // cleanup memory + MPI_Group_free(&meshblockCompositeGroup); + } } - } } -void tioga::assembleComplementComms(void){ - MPI_Group meshblockIncludeGroup; - MPI_Group meshblockExcludeGroup; - - int maxtag,maxtagLocal; - int body_minrank; - int incount,excount; - char compListFlag; - - std::vector existMeshTag(numprocs); - std::vector incl_list(numprocs); - std::vector comp_list(numprocs); - - /* ===================================== */ - /* set mesh body ranks and communicators */ - /* ===================================== */ - /* NOTE: There are two tasks. - * 1. Build communicator between all ranks involved in the same body. - * 2. Build communicator between all complement ranks of a body - * + the master rank of that body. - * 2a. For each body, we set the rank with lowest id as the rank master - * 2b. Build body complement subgroup/communicator and new rank IDs. - */ - - /* ================================ */ - /* Step A: count max number of tags */ - /* ================================ */ - maxtagLocal = -BIGINT; - for(int mbi=0; mbigetMeshTag(); - - maxtagLocal = (maxtagLocal < mbtag) ? mbtag:maxtagLocal; - - // cleanup memory - if(mb->blockcomm != MPI_COMM_NULL) MPI_Comm_free(&mb->blockcomm); - } - MPI_Allreduce(&maxtagLocal,&maxtag,1,MPI_INT,MPI_MAX,scomm); - - // allocate mesh block complement communicators and rank master arrays - if(meshblockComplement) delete [] meshblockComplement; - meshblockComplement = new meshblockCompInfo[maxtag]; - - /* ========================================= */ - /* Step B: create each subgroup per mesh tag */ - /* ========================================= */ - for(int mtag=1; mtag<=maxtag; mtag++){ - meshblockCompInfo &MBC = meshblockComplement[mtag-BASE]; - - // check if body exists on rank - char foundFlag = 0; - for(int mbi=0; mbi existMeshTag(numprocs); + std::vector incl_list(numprocs); + std::vector comp_list(numprocs); + + /* ===================================== */ + /* set mesh body ranks and communicators */ + /* ===================================== */ + /* NOTE: There are two tasks. + * 1. Build communicator between all ranks involved in the same body. + * 2. Build communicator between all complement ranks of a body + * + the master rank of that body. + * 2a. For each body, we set the rank with lowest id as the rank master + * 2b. Build body complement subgroup/communicator and new rank IDs. + */ + + /* ================================ */ + /* Step A: count max number of tags */ + /* ================================ */ + maxtagLocal = -BIGINT; + for (int mbi = 0; mbi < nblocks; mbi++) { + auto& mb = mblocks[mbi]; + int mbtag = mb->getMeshTag(); - // inform all ranks of which ranks are involved in this mesh tag - std::fill(existMeshTag.begin(),existMeshTag.end(),0); - MPI_Allgather(&foundFlag,1,MPI_CHAR,existMeshTag.data(),1,MPI_CHAR,scomm); + maxtagLocal = (maxtagLocal < mbtag) ? mbtag : maxtagLocal; - // get mesh master id: stop at first rank found - int meshMasterId = -1; - for(int i=0; iblockcomm != MPI_COMM_NULL) MPI_Comm_free(&mb->blockcomm); } + MPI_Allreduce(&maxtagLocal, &maxtag, 1, MPI_INT, MPI_MAX, scomm); + + // allocate mesh block complement communicators and rank master arrays + if (meshblockComplement) delete[] meshblockComplement; + meshblockComplement = new meshblockCompInfo[maxtag]; + + /* ========================================= */ + /* Step B: create each subgroup per mesh tag */ + /* ========================================= */ + for (int mtag = 1; mtag <= maxtag; mtag++) { + meshblockCompInfo& MBC = meshblockComplement[mtag - BASE]; + + // check if body exists on rank + char foundFlag = 0; + for (int mbi = 0; mbi < nblocks; mbi++) { + if (mtags[mbi] == mtag) { + foundFlag = 1; + break; + } + } - // construct the subgroups using the inclusion and complement rank lists - MPI_Group_incl(scomm_group,incount,incl_list.data(),&meshblockIncludeGroup); - MPI_Group_incl(scomm_group,excount,comp_list.data(),&meshblockExcludeGroup); + // inform all ranks of which ranks are involved in this mesh tag + std::fill(existMeshTag.begin(), existMeshTag.end(), 0); + MPI_Allgather( + &foundFlag, 1, MPI_CHAR, existMeshTag.data(), 1, MPI_CHAR, scomm); + + // get mesh master id: stop at first rank found + int meshMasterId = -1; + for (int i = 0; i < numprocs; i++) { + if (existMeshTag[i] == 1) { + meshMasterId = i; + break; + }; + } - // create complement MPI subgroup communicator and rank - MPI_Comm_create(scomm,meshblockExcludeGroup,&(MBC.comm)); + // set complement list flag (include mesh rank master) + compListFlag = (existMeshTag[myid]) ? 0 : 1; + if (myid == meshMasterId) compListFlag = 1; + + // reset inclusion and complement rank lists + incount = excount = 0; + std::fill(incl_list.begin(), incl_list.end(), 0); + std::fill(comp_list.begin(), comp_list.end(), 0); + + // store mesh rank master in exclude list (as it broadcasts the hole + // map) + comp_list[excount++] = meshMasterId; + + // create MPI subgroup ranks for this mesh tag: inclusion and comp lists + for (int i = 0; i < numprocs; i++) { + // add rank i to appropriate list + if (existMeshTag[i]) { + incl_list[incount++] = i; + } else { + comp_list[excount++] = i; + } + } - if(compListFlag){ - MPI_Comm_rank(MBC.comm,&(MBC.id)); - MPI_Comm_size(MBC.comm,&(MBC.nrank)); + // construct the subgroups using the inclusion and complement rank lists + MPI_Group_incl( + scomm_group, incount, incl_list.data(), &meshblockIncludeGroup); + MPI_Group_incl( + scomm_group, excount, comp_list.data(), &meshblockExcludeGroup); - MBC.masterID = (myid == meshMasterId) ? MBC.id : -1; - MPI_Allreduce(MPI_IN_PLACE,&(MBC.masterID),1,MPI_INT,MPI_MAX,MBC.comm); + // create complement MPI subgroup communicator and rank + MPI_Comm_create(scomm, meshblockExcludeGroup, &(MBC.comm)); - //printf("My GID[%2d] (comp rank %2d of %2d), body_tag[%d] of %d blocks, master rank %d, %d\n", - // myid,MBC.id,MBC.nrank,mtag,maxtag,MBC.masterID,myid == meshMasterId); - } + if (compListFlag) { + MPI_Comm_rank(MBC.comm, &(MBC.id)); + MPI_Comm_size(MBC.comm, &(MBC.nrank)); - // create MPI subgroup communicator for this mesh tag - for(int mbi=0; mbiblockcomm)); - MPI_Comm_rank(mb->blockcomm,&mb->blockcomm_id); - MPI_Comm_size(mb->blockcomm,&mb->blockcomm_numprocs); + // printf("My GID[%2d] (comp rank %2d of %2d), body_tag[%d] of %d + // blocks, master rank %d, %d\n", + // myid,MBC.id,MBC.nrank,mtag,maxtag,MBC.masterID,myid == + // meshMasterId); + } - // Task 2a: set rank master for this body tag: lowest rank in this block - MPI_Allreduce(&myid,&body_minrank,1,MPI_INT,MPI_MIN,mb->blockcomm); - mb->meshMaster = (myid == body_minrank); + // create MPI subgroup communicator for this mesh tag + for (int mbi = 0; mbi < nblocks; mbi++) { + // create MPI subgroup communicator for this mesh tag + if (mytag[mbi] == mtag) { + auto& mb = mblocks[mbi]; + + MPI_Comm_create_group( + scomm, meshblockIncludeGroup, 0, &(mb->blockcomm)); + MPI_Comm_rank(mb->blockcomm, &mb->blockcomm_id); + MPI_Comm_size(mb->blockcomm, &mb->blockcomm_numprocs); + + // Task 2a: set rank master for this body tag: lowest rank in + // this block + MPI_Allreduce( + &myid, &body_minrank, 1, MPI_INT, MPI_MIN, mb->blockcomm); + mb->meshMaster = (myid == body_minrank); + + // printf("My ID[%2d] (local rank %2d of %2d), body_tag[%d] of + // %d blocks\n", + // myid,mb->blockcomm_id,mb->blockcomm_numprocs,mytag[mbi],nblocks); + } + } - //printf("My ID[%2d] (local rank %2d of %2d), body_tag[%d] of %d blocks\n", - // myid,mb->blockcomm_id,mb->blockcomm_numprocs,mytag[mbi],nblocks); - } + // cleanup memory + MPI_Group_free(&meshblockIncludeGroup); + MPI_Group_free(&meshblockExcludeGroup); } - - // cleanup memory - MPI_Group_free(&meshblockIncludeGroup); - MPI_Group_free(&meshblockExcludeGroup); - } } /** * register grid data for each mesh block */ -void tioga::registerGridData(int btag,int nnodes,double *xyz,int *ibl, int nwbc,int nobc, - int *wbcnode,int *obcnode,int ntypes, int *nv, int *nc, int **vconn, - uint64_t* cell_gid, uint64_t* node_gid) +void tioga::registerGridData( + int btag, + int nnodes, + double* xyz, + int* ibl, + int nwbc, + int nobc, + int* wbcnode, + int* obcnode, + int ntypes, + int* nv, + int* nc, + int** vconn, + uint64_t* cell_gid, + uint64_t* node_gid) { - int iblk; - - auto idxit = tag_iblk_map.find(btag); - if (idxit == tag_iblk_map.end()) { - mtags.push_back(btag); - mytag.push_back(btag); - mblocks.push_back(std::unique_ptr(new MeshBlock)); - nblocks = mblocks.size(); - iblk = nblocks - 1; - tag_iblk_map[btag] = iblk; - } else { - iblk = idxit->second; - } - - /* ================================== */ - /* set of mesh body data and body tag */ - /* ================================== */ - auto& mb = mblocks[iblk]; - mb->setData(btag, nnodes, xyz, ibl, nwbc, nobc, wbcnode, obcnode, ntypes, nv, - nc, vconn, cell_gid, node_gid); - mb->myid = myid; + int iblk; + + auto idxit = tag_iblk_map.find(btag); + if (idxit == tag_iblk_map.end()) { + mtags.push_back(btag); + mytag.push_back(btag); + mblocks.push_back(std::unique_ptr(new MeshBlock)); + nblocks = mblocks.size(); + iblk = nblocks - 1; + tag_iblk_map[btag] = iblk; + } else { + iblk = idxit->second; + } + + /* ================================== */ + /* set of mesh body data and body tag */ + /* ================================== */ + auto& mb = mblocks[iblk]; + mb->setData( + btag, nnodes, xyz, ibl, nwbc, nobc, wbcnode, obcnode, ntypes, nv, nc, + vconn, cell_gid, node_gid); + mb->myid = myid; } -void tioga::register_unstructured_grid(TIOGA::MeshBlockInfo *minfo) +void tioga::register_unstructured_grid(TIOGA::MeshBlockInfo* minfo) { - int iblk; - - const int btag = minfo->meshtag; - auto idxit = tag_iblk_map.find(btag); - if (idxit == tag_iblk_map.end()) { - mtags.push_back(btag); - mytag.push_back(btag); - mblocks.push_back(std::unique_ptr(new MeshBlock)); - nblocks = mblocks.size(); - iblk = nblocks - 1; - tag_iblk_map[btag] = iblk; - } else { - iblk = idxit->second; - } - - auto& mb = mblocks[iblk]; - mb->setData(minfo); - mb->myid = myid; + int iblk; + + const int btag = minfo->meshtag; + auto idxit = tag_iblk_map.find(btag); + if (idxit == tag_iblk_map.end()) { + mtags.push_back(btag); + mytag.push_back(btag); + mblocks.push_back(std::unique_ptr(new MeshBlock)); + nblocks = mblocks.size(); + iblk = nblocks - 1; + tag_iblk_map[btag] = iblk; + } else { + iblk = idxit->second; + } + + auto& mb = mblocks[iblk]; + mb->setData(minfo); + mb->myid = myid; } -void tioga::registerSolution(int btag,double *q) +void tioga::registerSolution(int btag, double* q) { - auto idxit=tag_iblk_map.find(btag); - int iblk=idxit->second; - qblock[iblk]=q; + auto idxit = tag_iblk_map.find(btag); + int iblk = idxit->second; + qblock[iblk] = q; } -void tioga::register_unstructured_solution(int btag,double *q,int nvar,int interptype) +void tioga::register_unstructured_solution( + int btag, double* q, int nvar, int interptype) { - auto idxit=tag_iblk_map.find(btag); - int iblk=idxit->second; - qblock[iblk]=q; - mblocks[iblk]->num_var() = nvar; - mblocks[iblk]->set_interptype(interptype); + auto idxit = tag_iblk_map.find(btag); + int iblk = idxit->second; + qblock[iblk] = q; + mblocks[iblk]->num_var() = nvar; + mblocks[iblk]->set_interptype(interptype); } void tioga::register_unstructured_solution() { - for (int iblk = 0; iblk < mblocks.size(); ++iblk) { - const auto* minfo = mblocks[iblk]->mesh_info(); - qblock[iblk] = minfo->qnode.hptr; - mblocks[iblk]->num_var() = minfo->num_vars; - } + for (int iblk = 0; iblk < mblocks.size(); ++iblk) { + const auto* minfo = mblocks[iblk]->mesh_info(); + qblock[iblk] = minfo->qnode.hptr; + mblocks[iblk]->num_var() = minfo->num_vars; + } } void tioga::profile(void) { - this->myTimer("tioga::profile",0); - for(int ib=0;ibmexclude=mexclude; - mb->nfringe=nfringe; - mb->preprocess(USE_ADAPTIVE_HOLEMAP); - //mb->writeGridFile(myid); - } - //mb->writeOBB(myid); - //if (myid==4) mb->writeOutput(myid); - //if (myid==4) mb->writeOBB(myid); - this->myTimer("tioga::profile",1); + this->myTimer("tioga::profile", 0); + for (int ib = 0; ib < nblocks; ib++) { + auto& mb = mblocks[ib]; + mb->mexclude = mexclude; + mb->nfringe = nfringe; + mb->preprocess(USE_ADAPTIVE_HOLEMAP); + // mb->writeGridFile(myid); + } + // mb->writeOBB(myid); + // if (myid==4) mb->writeOutput(myid); + // if (myid==4) mb->writeOBB(myid); + this->myTimer("tioga::profile", 1); } void tioga::performConnectivity(void) { - this->myTimer("tioga::performConnectivity",0); - if (USE_ADAPTIVE_HOLEMAP) { - this->myTimer("tioga::getAdaptiveHoleMap",0); - getAdaptiveHoleMap(); - this->myTimer("tioga::getAdaptiveHoleMap",1); - } else { - this->myTimer("tioga::getHoleMap",0); - getHoleMap(); - this->myTimer("tioga::getHoleMap",1); - } - this->myTimer("tioga::exchangeBoxes",0); - exchangeBoxes(); - this->myTimer("tioga::exchangeBoxes",1); - this->myTimer("tioga::exchangeSearchData",0); - exchangeSearchData(); - this->myTimer("tioga::exchangeSearchData",1); - this->myTimer("tioga::search",0); - for(int ib=0;ib < nblocks;ib++){ - auto& mb = mblocks[ib]; - mb->ihigh=0; - mb->resetInterpData(); - mb->search(); - } - this->myTimer("tioga::search",1); - this->myTimer("tioga::exchangeDonors",0); - exchangeDonors(); - this->myTimer("tioga::exchangeDonors",1); - //this->reduce_fringes(); - //outputStatistics(); - MPI_Allreduce(&ihigh,&ihighGlobal,1,MPI_INT,MPI_MAX,scomm); - //if (ihighGlobal) { - this->myTimer("tioga::getCellIblanks",0); - for (int ib=0;ibgetCellIblanks2(); + this->myTimer("tioga::performConnectivity", 0); + if (USE_ADAPTIVE_HOLEMAP) { + this->myTimer("tioga::getAdaptiveHoleMap", 0); + getAdaptiveHoleMap(); + this->myTimer("tioga::getAdaptiveHoleMap", 1); + } else { + this->myTimer("tioga::getHoleMap", 0); + getHoleMap(); + this->myTimer("tioga::getHoleMap", 1); } - else { - mb->getCellIblanks(); + this->myTimer("tioga::exchangeBoxes", 0); + exchangeBoxes(); + this->myTimer("tioga::exchangeBoxes", 1); + this->myTimer("tioga::exchangeSearchData", 0); + exchangeSearchData(); + this->myTimer("tioga::exchangeSearchData", 1); + this->myTimer("tioga::search", 0); + for (int ib = 0; ib < nblocks; ib++) { + auto& mb = mblocks[ib]; + mb->ihigh = 0; + mb->resetInterpData(); + mb->search(); } - //mb->writeGridFile(100*myid+mtags[ib]); - } - this->myTimer("tioga::getCellIblanks",1); - if (qblock) TIOGA_FREE(qblock); - qblock=(double **)malloc(sizeof(double *)*nblocks); - for(int ib=0;ibwriteOutput(myid); - //TRACEI(myid); - this->myTimer("tioga::performConnectivity",1); + this->myTimer("tioga::search", 1); + this->myTimer("tioga::exchangeDonors", 0); + exchangeDonors(); + this->myTimer("tioga::exchangeDonors", 1); + // this->reduce_fringes(); + // outputStatistics(); + MPI_Allreduce(&ihigh, &ihighGlobal, 1, MPI_INT, MPI_MAX, scomm); + // if (ihighGlobal) { + this->myTimer("tioga::getCellIblanks", 0); + for (int ib = 0; ib < nblocks; ib++) { + auto& mb = mblocks[ib]; + if (ihighGlobal) { + mb->getCellIblanks2(); + } else { + mb->getCellIblanks(); + } + // mb->writeGridFile(100*myid+mtags[ib]); + } + this->myTimer("tioga::getCellIblanks", 1); + if (qblock) TIOGA_FREE(qblock); + qblock = (double**)malloc(sizeof(double*) * nblocks); + for (int ib = 0; ib < nblocks; ib++) qblock[ib] = NULL; + //} + // mb->writeOutput(myid); + // TRACEI(myid); + this->myTimer("tioga::performConnectivity", 1); } void tioga::performConnectivityHighOrder(void) { - for(int ib=0;ibihigh=ihigh; - mb->getInternalNodes(); - } - exchangeSearchData(1); - for(int ib=0;ibsearch(); - mb->processPointDonors(); - } - iorphanPrint=1; + for (int ib = 0; ib < nblocks; ib++) { + auto& mb = mblocks[ib]; + mb->ihigh = ihigh; + mb->getInternalNodes(); + } + exchangeSearchData(1); + for (int ib = 0; ib < nblocks; ib++) { + auto& mb = mblocks[ib]; + mb->search(); + mb->processPointDonors(); + } + iorphanPrint = 1; } void tioga::performConnectivityAMR(void) { - int i,ierr; - int iamr; - - iamr=(ncart >0)?1:0; - MPI_Allreduce(&iamr,&iamrGlobal,1,MPI_INT,MPI_MAX,scomm); - this->myTimer("tioga::cg->preprocess",0); - cg->preprocess(); - this->myTimer("tioga::cg->preprocess",1); - this->myTimer("tioga::cb[i].preprocess",0); - for(i=0;imyTimer("tioga::cb[i].preprocess",1); - - int nbmax; - MPI_Allreduce(&nblocks, &nbmax, 1, MPI_INT, MPI_MAX, scomm); - for(int ib=0;ibmyTimer("tioga::getCartReceptors",0); - if (ib < nblocks) mblocks[ib]->getCartReceptors(cg,pc_cart); - this->myTimer("tioga::getCartReceptors",1); - if (ib < nblocks) mblocks[ib]->ihigh=ihigh; - this->myTimer("tioga::searchCartesianMB",0); - if (ib < nblocks) mblocks[ib]->search(); - this->myTimer("tioga::searchCartesianMB",1); - if (ib < nblocks) mblocks[ib]->getUnresolvedMandatoryReceptors(); - this->myTimer("tioga::cgSearch",0); - if (ib < nblocks) cg->search( - mblocks[ib]->rxyzCart,mblocks[ib]->donorIdCart,mblocks[ib]->ntotalPointsCart); - this->myTimer("tioga::cgSearch",1); - } - - //checkComm(); - this->myTimer("tioga::exchangeAMRDonors",0); - exchangeAMRDonors(); - this->myTimer("tioga::exchangeAMRDonors",1); - for(int ib=0;ibgetCellIblanks(); - } - // mb->writeCellFile(myid); - //for(i=0;i 0) ? 1 : 0; + MPI_Allreduce(&iamr, &iamrGlobal, 1, MPI_INT, MPI_MAX, scomm); + this->myTimer("tioga::cg->preprocess", 0); + cg->preprocess(); + this->myTimer("tioga::cg->preprocess", 1); + this->myTimer("tioga::cb[i].preprocess", 0); + for (i = 0; i < ncart; i++) cb[i].preprocess(cg); + this->myTimer("tioga::cb[i].preprocess", 1); + + int nbmax; + MPI_Allreduce(&nblocks, &nbmax, 1, MPI_INT, MPI_MAX, scomm); + for (int ib = 0; ib < nbmax; ib++) { + this->myTimer("tioga::getCartReceptors", 0); + if (ib < nblocks) mblocks[ib]->getCartReceptors(cg, pc_cart); + this->myTimer("tioga::getCartReceptors", 1); + if (ib < nblocks) mblocks[ib]->ihigh = ihigh; + this->myTimer("tioga::searchCartesianMB", 0); + if (ib < nblocks) mblocks[ib]->search(); + this->myTimer("tioga::searchCartesianMB", 1); + if (ib < nblocks) mblocks[ib]->getUnresolvedMandatoryReceptors(); + this->myTimer("tioga::cgSearch", 0); + if (ib < nblocks) + cg->search( + mblocks[ib]->rxyzCart, mblocks[ib]->donorIdCart, + mblocks[ib]->ntotalPointsCart); + this->myTimer("tioga::cgSearch", 1); + } + + // checkComm(); + this->myTimer("tioga::exchangeAMRDonors", 0); + exchangeAMRDonors(); + this->myTimer("tioga::exchangeAMRDonors", 1); + for (int ib = 0; ib < nblocks; ib++) { + auto& mb = mblocks[ib]; + mb->getCellIblanks(); + } + // mb->writeCellFile(myid); + // for(i=0;i 0) && (ncart > 0)) - assert(mblocks[0]->num_var() == (cb[0].num_cell_var()+cb[0].num_node_var())); - - int nvar = 0; - if (nblocks > 0) - nvar = mblocks[0]->num_var(); - else if (ncart > 0) - nvar = cb[0].num_cell_var()+cb[0].num_node_var(); - - int i,j,k,m; - int nints; - int nreals; - int *integerRecords; - double *realRecords; - int nsend,nrecv; - int *sndMap,*rcvMap; - int *sndMapNB,*rcvMapNB; - int nsendNB,nrecvNB; - PACKET *sndPack,*rcvPack; - int *icount,*dcount; - int bid; - // - // initialize send and recv packets - // - for(int ib=0;ib 0) && (ncart > 0)) + assert( + mblocks[0]->num_var() == + (cb[0].num_cell_var() + cb[0].num_node_var())); + + int nvar = 0; + if (nblocks > 0) + nvar = mblocks[0]->num_var(); + else if (ncart > 0) + nvar = cb[0].num_cell_var() + cb[0].num_node_var(); + + int i, j, k, m; + int nints; + int nreals; + int* integerRecords; + double* realRecords; + int nsend, nrecv; + int *sndMap, *rcvMap; + int *sndMapNB, *rcvMapNB; + int nsendNB, nrecvNB; + PACKET *sndPack, *rcvPack; + int *icount, *dcount; + int bid; + // + // initialize send and recv packets + // + for (int ib = 0; ib < nblocks; ib++) + if (qblock[ib] == NULL) { + printf("Solution data not set, cannot update \n"); + return; + } + icount = dcount = NULL; + integerRecords = NULL; + realRecords = NULL; + // + pc_cart->getMap(&nsend, &nrecv, &sndMap, &rcvMap); + if (nsend == 0) return; + sndPack = (PACKET*)malloc(sizeof(PACKET) * nsend); + rcvPack = (PACKET*)malloc(sizeof(PACKET) * nrecv); + icount = (int*)malloc(sizeof(int) * nsend); + dcount = (int*)malloc(sizeof(int) * nrecv); + // + pc_cart->initPackets(sndPack, rcvPack); + // + // get the interpolated solution now + // + integerRecords = NULL; + realRecords = NULL; + // + // TODO : verify for nblocks > 1 + // + // get nearbody process maps + // + pc->getMap(&nsendNB, &nrecvNB, &sndMapNB, &rcvMapNB); + + nints = nreals = 0; + for (int ib = 0; ib < nblocks; ib++) { + auto& mb = mblocks[ib]; + mb->getInterpolatedSolutionAMR( + &nints, &nreals, &integerRecords, &realRecords, qblock[ib], + sndMapNB); } - icount=dcount=NULL; - integerRecords=NULL; - realRecords=NULL; - // - pc_cart->getMap(&nsend,&nrecv,&sndMap,&rcvMap); - if (nsend==0) return; - sndPack=(PACKET *)malloc(sizeof(PACKET)*nsend); - rcvPack=(PACKET *)malloc(sizeof(PACKET)*nrecv); - icount=(int *)malloc(sizeof(int)*nsend); - dcount=(int *)malloc(sizeof(int)*nrecv); - // - pc_cart->initPackets(sndPack,rcvPack); - // - // get the interpolated solution now - // - integerRecords=NULL; - realRecords=NULL; - // - // TODO : verify for nblocks > 1 - // - // get nearbody process maps - // - pc->getMap(&nsendNB,&nrecvNB,&sndMapNB,&rcvMapNB); - - nints=nreals=0; - for(int ib=0;ibgetInterpolatedSolutionAMR(&nints,&nreals,&integerRecords,&realRecords,qblock[ib],sndMapNB); - } - for(i=0;i nsend) { - TRACEI(nsend); - TRACEI(i); - TRACEI(nints); - TRACEI(k); - } - assert(k < nsend); - sndPack[k].nints+=2; - sndPack[k].nreals+=nvar; + for (i = 0; i < ncart; i++) + cb[i].getInterpolatedData( + &nints, &nreals, &integerRecords, &realRecords); + // + // populate the packets + // + for (i = 0; i < nints; i++) { + k = integerRecords[3 * i]; + if (k < 0 || k > nsend) { + TRACEI(nsend); + TRACEI(i); + TRACEI(nints); + TRACEI(k); + } + assert(k < nsend); + sndPack[k].nints += 2; + sndPack[k].nreals += nvar; } - for(k=0;ksendRecvPacketsAll(sndPack,rcvPack); - // - // decode the packets and update the data - // - for(k=0;kupdateSolnData(inode,&rcvPack[k].realData[m],qblock[-(bid+1)]); - } - else - { - cb[bid-1].update(&rcvPack[k].realData[m],rcvPack[k].intData[2*i+1]); - } - m+=nvar; - } + // + // communicate the data across + // use All comm because pc_cart is across all procs + // anyway + // + pc_cart->sendRecvPacketsAll(sndPack, rcvPack); + // + // decode the packets and update the data + // + for (k = 0; k < nrecv; k++) { + m = 0; + for (i = 0; i < rcvPack[k].nints / 2; i++) { + bid = rcvPack[k].intData[2 * i]; + if (bid < 0) { + int inode = rcvPack[k].intData[2 * i + 1]; + mblocks[-(bid + 1)]->updateSolnData( + inode, &rcvPack[k].realData[m], qblock[-(bid + 1)]); + } else { + cb[bid - 1].update( + &rcvPack[k].realData[m], rcvPack[k].intData[2 * i + 1]); + } + m += nvar; + } } - // - // release all memory - // - //this->writeData(nvar,0); - pc_cart->clearPackets(sndPack,rcvPack); - TIOGA_FREE(sndPack); - TIOGA_FREE(rcvPack); - if (integerRecords) TIOGA_FREE(integerRecords); - if (realRecords) TIOGA_FREE(realRecords); - if (icount) TIOGA_FREE(icount); - if (dcount) TIOGA_FREE(dcount); + // + // release all memory + // + // this->writeData(nvar,0); + pc_cart->clearPackets(sndPack, rcvPack); + TIOGA_FREE(sndPack); + TIOGA_FREE(rcvPack); + if (integerRecords) TIOGA_FREE(integerRecords); + if (realRecords) TIOGA_FREE(realRecords); + if (icount) TIOGA_FREE(icount); + if (dcount) TIOGA_FREE(dcount); } -void tioga::dataUpdate(int nvar,int interptype, int at_points) +void tioga::dataUpdate(int nvar, int interptype, int at_points) { - int **integerRecords; - double **realRecords; - double **qtmp; - int **itmp; - int nsend,nrecv; - int *sndMap,*rcvMap; - PACKET *sndPack,*rcvPack; - char ofname[100]; - FILE *fp; - // - for(int ib=0;ibgetMap(&nsend,&nrecv,&sndMap,&rcvMap); - if (nsend==0) return; - sndPack=(PACKET *)malloc(sizeof(PACKET)*nsend); - rcvPack=(PACKET *)malloc(sizeof(PACKET)*nrecv); - // - pc->initPackets(sndPack,rcvPack); - // - // get the interpolated solution now - // - integerRecords=(int **)malloc(sizeof(int*)*nblocks); - realRecords=(double **)malloc(sizeof(double*)*nblocks); - for(int ib=0;ibgetMap(&nsend, &nrecv, &sndMap, &rcvMap); + if (nsend == 0) return; + sndPack = (PACKET*)malloc(sizeof(PACKET) * nsend); + rcvPack = (PACKET*)malloc(sizeof(PACKET) * nrecv); + // + pc->initPackets(sndPack, rcvPack); + // + // get the interpolated solution now + // + integerRecords = (int**)malloc(sizeof(int*) * nblocks); + realRecords = (double**)malloc(sizeof(double*) * nblocks); + for (int ib = 0; ib < nblocks; ib++) { + integerRecords[ib] = NULL; + realRecords[ib] = NULL; } - std::vector nints(nblocks,0), nreals(nblocks,0); - std::vector icount(nsend,0),dcount(nsend,0); - - for(int ib=0;ibgetInterpolatedSolution(&(nints[ib]),&(nreals[ib]),&(integerRecords[ib]),&(realRecords[ib]), - q,nvar,interptype); - } - else { - mb->getInterpolatedSolutionAtPoints(&(nints[ib]),&(nreals[ib]),&(integerRecords[ib]), - &(realRecords[ib]),q,nvar,interptype); - } - // - // populate the packets - // - for(int i=0;i nints(nblocks, 0), nreals(nblocks, 0); + std::vector icount(nsend, 0), dcount(nsend, 0); + + for (int ib = 0; ib < nblocks; ib++) { + auto& mb = mblocks[ib]; + double* q = qblock[ib]; + if (at_points == 0) { + mb->getInterpolatedSolution( + &(nints[ib]), &(nreals[ib]), &(integerRecords[ib]), + &(realRecords[ib]), q, nvar, interptype); + } else { + mb->getInterpolatedSolutionAtPoints( + &(nints[ib]), &(nreals[ib]), &(integerRecords[ib]), + &(realRecords[ib]), q, nvar, interptype); + } + // + // populate the packets + // + for (int i = 0; i < nints[ib]; i++) { + int k = integerRecords[ib][3 * i]; + sndPack[k].nints += 2; + sndPack[k].nreals += nvar; + } } - // - for(int k=0;ksendRecvPackets(sndPack,rcvPack); - // - // decode the packets and update the data - // - if (at_points) { - qtmp=(double **)malloc(sizeof(double*)*nblocks); - itmp=(int **)malloc(sizeof(double*)*nblocks); - for(int ib=0;ibntotalPoints*nvar); - itmp[ib]=(int *)malloc(sizeof(int)*mblocks[ib]->ntotalPoints); - for(int i=0;i < mblocks[ib]->ntotalPoints;i++) itmp[ib][i]=0; + // + // communicate the data across + // + pc->sendRecvPackets(sndPack, rcvPack); + // + // decode the packets and update the data + // + if (at_points) { + qtmp = (double**)malloc(sizeof(double*) * nblocks); + itmp = (int**)malloc(sizeof(double*) * nblocks); + for (int ib = 0; ib < nblocks; ib++) { + qtmp[ib] = (double*)malloc( + sizeof(double) * mblocks[ib]->ntotalPoints * nvar); + itmp[ib] = (int*)malloc(sizeof(int) * mblocks[ib]->ntotalPoints); + for (int i = 0; i < mblocks[ib]->ntotalPoints; i++) itmp[ib][i] = 0; + } } - } - // - for(int k=0;knum_var() = nvar; - mb->set_interptype(interptype); - mb->updateSolnData(pointid,&rcvPack[k].realData[m],q); - } - else { - for (int j=0;jnum_var() = nvar; + mb->set_interptype(interptype); + mb->updateSolnData(pointid, &rcvPack[k].realData[m], q); + } else { + for (int j = 0; j < nvar; j++) + qtmp[ib][pointid * nvar + j] = rcvPack[k].realData[m + j]; + itmp[ib][pointid] = 1; + } + m += nvar; + } } - int norphanPoint=0; - int ntotalPoints=0; - for(int ib=0;ib < nblocks;ib++) - { - auto &mb = mblocks[ib]; - for(int i=0;intotalPoints;i++) - { - if (itmp[ib][i]==0 && iorphanPrint) { - if (fp==NULL) - { - sprintf(ofname,"orphan%d.%d.dat",myid,ib); - fp=fopen(ofname,"w"); - } - mb->outputOrphan(fp,i); - norphanPoint++; - } - } - ntotalPoints+=mb->ntotalPoints; + int norphanPoint = 0; + int ntotalPoints = 0; + for (int ib = 0; ib < nblocks; ib++) { + auto& mb = mblocks[ib]; + for (int i = 0; i < mb->ntotalPoints; i++) { + if (itmp[ib][i] == 0 && iorphanPrint) { + if (fp == NULL) { + snprintf( + ofname, sizeof(ofname), "orphan%d.%d.dat", myid, ib); + fp = fopen(ofname, "w"); + } + mb->outputOrphan(fp, i); + norphanPoint++; + } + } + ntotalPoints += mb->ntotalPoints; + } + if (fp != NULL) fclose(fp); + if (norphanPoint > 0 && iorphanPrint) { + printf( + "\e[0;31m" + "Warning::" + "\e[0m" + "number of orphans in %d = %d of %d\n", + myid, norphanPoint, ntotalPoints); + iorphanPrint = 0; + } + // + // change the state of cells/nodes who are orphans + // + if (at_points) { + for (int ib = 0; ib < nblocks; ib++) { + auto& mb = mblocks[ib]; + mb->clearOrphans(holeMap, nmesh, itmp[ib]); + mb->updatePointData(qblock[ib], qtmp[ib], nvar, interptype); + } + } + // + // release all memory + // + pc->clearPackets(sndPack, rcvPack); + TIOGA_FREE(sndPack); + TIOGA_FREE(rcvPack); + if (integerRecords) { + for (int ib = 0; ib < nblocks; ib++) + if (integerRecords[ib]) TIOGA_FREE(integerRecords[ib]); + TIOGA_FREE(integerRecords); + } + if (realRecords) { + for (int ib = 0; ib < nblocks; ib++) + if (realRecords[ib]) TIOGA_FREE(realRecords[ib]); + TIOGA_FREE(realRecords); + } + if (qtmp) { + for (int ib = 0; ib < nblocks; ib++) + if (qtmp[ib]) TIOGA_FREE(qtmp[ib]); + TIOGA_FREE(qtmp); + } + if (itmp) { + for (int ib = 0; ib < nblocks; ib++) + if (itmp[ib]) TIOGA_FREE(itmp[ib]); + TIOGA_FREE(itmp); } - if (fp!=NULL) fclose(fp); - if (norphanPoint > 0 && iorphanPrint) { - printf("\e[0;31m" "Warning::" "\e[0m" "number of orphans in %d = %d of %d\n", - myid,norphanPoint,ntotalPoints); - iorphanPrint=0; - } - // - // change the state of cells/nodes who are orphans - // - if (at_points) { - for (int ib=0;ibclearOrphans(holeMap,nmesh,itmp[ib]); - mb->updatePointData(qblock[ib],qtmp[ib],nvar,interptype); - } - } - // - // release all memory - // - pc->clearPackets(sndPack,rcvPack); - TIOGA_FREE(sndPack); - TIOGA_FREE(rcvPack); - if (integerRecords) { - for(int ib=0;ibwriteGridFile(myid); - for(int ib=0;ibwriteFlowFile(100*myid+ib,qblock[ib],nvar,interptype); - mblocks[ib]->checkOrphans(); - } - for (int ib=0;ibwriteGridFile(myid); + for (int ib = 0; ib < nblocks; ib++) { + mblocks[ib]->writeFlowFile( + 100 * myid + ib, qblock[ib], nvar, interptype); + mblocks[ib]->checkOrphans(); + } + for (int ib = 0; ib < ncart; ib++) cb[ib].writeCellFile(ib); } -void tioga::getDonorCount(int btag, int *dcount,int *fcount) +void tioga::getDonorCount(int btag, int* dcount, int* fcount) { - int nsend, nrecv; - int *sndMap, *rcvMap; - - pc->getMap(&nsend,&nrecv,&sndMap,&rcvMap); - if (nsend == 0) { - *dcount = 0; - *fcount = 0; - return; - } - - auto idxit = tag_iblk_map.find(btag); - int iblk=idxit->second; - auto &mb = mblocks[iblk]; - mb->getDonorCount(dcount,fcount); + int nsend, nrecv; + int *sndMap, *rcvMap; + + pc->getMap(&nsend, &nrecv, &sndMap, &rcvMap); + if (nsend == 0) { + *dcount = 0; + *fcount = 0; + return; + } + + auto idxit = tag_iblk_map.find(btag); + int iblk = idxit->second; + auto& mb = mblocks[iblk]; + mb->getDonorCount(dcount, fcount); } -void tioga::getDonorInfo(int btag,int *receptors,int *indices,double *frac,int *dcount) +void tioga::getDonorInfo( + int btag, int* receptors, int* indices, double* frac, int* dcount) { - int nsend,nrecv; - int *sndMap,*rcvMap; - int i; - - pc->getMap(&nsend,&nrecv,&sndMap,&rcvMap); - if (nsend == 0) return; - - auto idxit=tag_iblk_map.find(btag); - int iblk=idxit->second; - auto &mb = mblocks[iblk]; - mb->getDonorInfo(receptors,indices,frac); - // - // change to actual processor id here - // - for(i=0;i<4*(*dcount);i+=4) - receptors[i]=sndMap[receptors[i]]; + int nsend, nrecv; + int *sndMap, *rcvMap; + int i; + + pc->getMap(&nsend, &nrecv, &sndMap, &rcvMap); + if (nsend == 0) return; + auto idxit = tag_iblk_map.find(btag); + int iblk = idxit->second; + auto& mb = mblocks[iblk]; + mb->getDonorInfo(receptors, indices, frac); + // + // change to actual processor id here + // + for (i = 0; i < 4 * (*dcount); i += 4) receptors[i] = sndMap[receptors[i]]; } void tioga::getReceptorInfo(std::vector& receptors) { - int nsend, nrecv; - int *sndMap, *rcvMap; - PACKET *sndPack, *rcvPack; - pc->getMap(&nsend, &nrecv, &sndMap, &rcvMap); - - if (nsend == 0) { - receptors.clear(); - return; - } - - // - // create packets to send and receive - // and initialize them to zero - // - sndPack = (PACKET*)malloc(sizeof(PACKET) * nsend); - rcvPack = (PACKET*)malloc(sizeof(PACKET) * nrecv); - - for (int i = 0; i < nsend; i++) { - sndPack[i].nints = sndPack[i].nreals = 0; - sndPack[i].intData = NULL; - sndPack[i].realData = NULL; - } - // - for (int i = 0; i < nrecv; i++) { - rcvPack[i].nints = rcvPack[i].nreals = 0; - rcvPack[i].intData = NULL; - rcvPack[i].realData = NULL; - } - - std::vector dcount(nblocks), fcount(nblocks); - std::vector > fringeSend(nblocks); - - for (int ib=0; ib < nblocks; ib++) { - mblocks[ib]->getDonorCount(&dcount[ib], &fcount[ib]); - - // For each fringe the following data is returned by mesh block - // - // - MPI rank of the fringe point - // - local node ID for the fringe point (on that proc) - // - local mesh block index containing the fringe point (on that proc) - // - Global ID of the donor cell - // - // The donor cell GID is uint64_t and is packed using 2*sizeof(int) bytes - // through the int array. This makes total number of ints per fringe data - // be (3 + 2) = 5 - // - fringeSend[ib].resize(5 * dcount[ib]); - mblocks[ib]->getReceptorInfo(fringeSend[ib].data()); - - std::vector& fringeData = fringeSend[ib]; - for (int i=0; i<(5*dcount[ib]); i+=5) { - int k = fringeData[i]; - sndPack[k].nints += 4; + int nsend, nrecv; + int *sndMap, *rcvMap; + PACKET *sndPack, *rcvPack; + pc->getMap(&nsend, &nrecv, &sndMap, &rcvMap); + + if (nsend == 0) { + receptors.clear(); + return; + } + + // + // create packets to send and receive + // and initialize them to zero + // + sndPack = (PACKET*)malloc(sizeof(PACKET) * nsend); + rcvPack = (PACKET*)malloc(sizeof(PACKET) * nrecv); + + for (int i = 0; i < nsend; i++) { + sndPack[i].nints = sndPack[i].nreals = 0; + sndPack[i].intData = NULL; + sndPack[i].realData = NULL; + } + // + for (int i = 0; i < nrecv; i++) { + rcvPack[i].nints = rcvPack[i].nreals = 0; + rcvPack[i].intData = NULL; + rcvPack[i].realData = NULL; } - } - // Allocate buffers for data send - for (int k=0; k dcount(nblocks), fcount(nblocks); + std::vector> fringeSend(nblocks); + + for (int ib = 0; ib < nblocks; ib++) { + mblocks[ib]->getDonorCount(&dcount[ib], &fcount[ib]); + + // For each fringe the following data is returned by mesh block + // + // - MPI rank of the fringe point + // - local node ID for the fringe point (on that proc) + // - local mesh block index containing the fringe point (on that proc) + // - Global ID of the donor cell + // + // The donor cell GID is uint64_t and is packed using 2*sizeof(int) + // bytes through the int array. This makes total number of ints per + // fringe data be (3 + 2) = 5 + // + fringeSend[ib].resize(5 * dcount[ib]); + mblocks[ib]->getReceptorInfo(fringeSend[ib].data()); + + std::vector& fringeData = fringeSend[ib]; + for (int i = 0; i < (5 * dcount[ib]); i += 5) { + int k = fringeData[i]; + sndPack[k].nints += 4; + } + } + + // Allocate buffers for data send + for (int k = 0; k < nsend; k++) { + sndPack[k].intData = (int*)malloc(sizeof(int) * sndPack[k].nints); + } - std::vector ix(nsend, 0); - for (int ib=0; ib& fringeData = fringeSend[ib]; + std::vector ix(nsend, 0); + for (int ib = 0; ib < nblocks; ib++) { + std::vector& fringeData = fringeSend[ib]; - for(size_t i=0; isendRecvPackets(sndPack, rcvPack); - - int rsize=0; - for (int k=0; ksendRecvPackets(sndPack, rcvPack); + + int rsize = 0; + for (int k = 0; k < nrecv; k++) { + rsize += rcvPack[k].nints; + } + receptors.resize(rsize); + + size_t idx = 0; + for (int k = 0; k < nrecv; k++) { + for (int j = 0; j < rcvPack[k].nints; j += 4) { + receptors[idx++] = rcvPack[k].intData[j]; + receptors[idx++] = mtags[rcvPack[k].intData[j + 1]]; + receptors[idx++] = rcvPack[k].intData[j + 2]; + receptors[idx++] = rcvPack[k].intData[j + 3]; + } } - } - pc->clearPackets(sndPack, rcvPack); - TIOGA_FREE(sndPack); - TIOGA_FREE(rcvPack); + pc->clearPackets(sndPack, rcvPack); + TIOGA_FREE(sndPack); + TIOGA_FREE(rcvPack); } tioga::~tioga() { - int i; - if (holeMap) - { - for(i=0;imyid = myid; - ncart = minfo->ngrids_local; + cg = new CartGrid[1]; + cg->myid = myid; + ncart = minfo->ngrids_local; - if (ncart < 1) return; + if (ncart < 1) return; - cb = new CartBlock[ncart]; - cg->registerData(minfo); + cb = new CartBlock[ncart]; + cg->registerData(minfo); - for (int ic = 0; ic < ncart; ++ic) { - cb[ic].registerData(ic, minfo); - } + for (int ic = 0; ic < ncart; ++ic) { + cb[ic].registerData(ic, minfo); + } } void tioga::register_amr_solution() { - auto* minfo = cg->m_info; - for (int ic = 0; ic < ncart; ++ic) { - cb[ic].registerSolution(ic, minfo); - } + auto* minfo = cg->m_info; + for (int ic = 0; ic < ncart; ++ic) { + cb[ic].registerSolution(ic, minfo); + } } -void tioga::register_amr_global_data(int nf,int *idata,double *rdata,int ngridsin) +void tioga::register_amr_global_data( + int nf, int* idata, double* rdata, int ngridsin) { - if (cg) delete [] cg; - cg=new CartGrid[1]; - cg->myid=myid; - cg->registerData(nf,idata,rdata,ngridsin); + if (cg) delete[] cg; + cg = new CartGrid[1]; + cg->myid = myid; + cg->registerData(nf, idata, rdata, ngridsin); } void tioga::set_amr_patch_count(int npatchesin) { - ncart=npatchesin; - if (cb) delete [] cb; - cb=new CartBlock[ncart]; + ncart = npatchesin; + if (cb) delete[] cb; + cb = new CartBlock[ncart]; } -void tioga::register_amr_local_data(int ipatch,int global_id,int *iblank,int *iblankn) +void tioga::register_amr_local_data( + int ipatch, int global_id, int* iblank, int* iblankn) { - cb[ipatch].registerData(ipatch,global_id,iblank,iblankn); + cb[ipatch].registerData(ipatch, global_id, iblank, iblankn); } -void tioga::register_amr_solution(int ipatch,double *q,int nvar_cell,int nvar_node) +void tioga::register_amr_solution( + int ipatch, double* q, int nvar_cell, int nvar_node) { - cb[ipatch].registerSolution(q,nvar_cell,nvar_node); + cb[ipatch].registerSolution(q, nvar_cell, nvar_node); } #ifdef TIOGA_ENABLE_TIMERS -void tioga::myTimer(char const *info,int type) +void tioga::myTimer(char const* info, int type) #else void tioga::myTimer(char const*, int) #endif { #ifdef TIOGA_ENABLE_TIMERS - static double t_start; - double t_end; - - MPI_Barrier(scomm); - if (type==0) { - t_start=MPI_Wtime(); - if (myid==0) printf("Begin %s\n",info); - } - if (type==1) { - t_end=MPI_Wtime(); - if (myid==0) printf("End %s, time taken=%lf\n",info,t_end-t_start); - } + static double t_start; + double t_end; + + MPI_Barrier(scomm); + if (type == 0) { + t_start = MPI_Wtime(); + if (myid == 0) printf("Begin %s\n", info); + } + if (type == 1) { + t_end = MPI_Wtime(); + if (myid == 0) + printf("End %s, time taken=%lf\n", info, t_end - t_start); + } #endif } void tioga::reduce_fringes(void) { - // - int nsend,nrecv; - int *sndMap; - int *rcvMap; - PACKET *sndPack,*rcvPack; - // - // get the processor map for sending - // and receiving - // - pc->getMap(&nsend,&nrecv,&sndMap,&rcvMap); - //if (nsend == 0) return; - - for(int ib=0;ibreduce_fringes(); - } - // - // now redo the process in exchangeDonors to reduce - // the data - // - // TODO make the stuff below into a subroutine to be more modular - // - // Find cancellation data (based on donor quality) - // - std::vector nrecords(nblocks,0); - int** donorRecords = (int**)malloc(sizeof(int*)*nblocks); - // - for (int i=0; igetCancellationData(&(nrecords[i]), - &(donorRecords[i])); - } - // - // create packets to send and receive - // and initialize them to zero - // - sndPack=(PACKET *)malloc(sizeof(PACKET)*nsend); - rcvPack=(PACKET *)malloc(sizeof(PACKET)*nrecv); - // - pc->initPackets(sndPack,rcvPack); - // - std::vector nintsSend(nsend,0); - std::vector ixOffset(nsend,0); - std::fill(nintsSend.begin(), nintsSend.end(), 0); - std::fill(ixOffset.begin(), ixOffset.end(), 0); - // - for (int n=0; n < nblocks; n++) { - for (int i=0; igetMap(&nsend, &nrecv, &sndMap, &rcvMap); + // if (nsend == 0) return; + + for (int ib = 0; ib < nblocks; ib++) { + auto& mb = mblocks[ib]; + mb->reduce_fringes(); } - } - // - for(int k=0;k nrecords(nblocks, 0); + int** donorRecords = (int**)malloc(sizeof(int*) * nblocks); + // + for (int i = 0; i < nblocks; i++) { + donorRecords[i] = NULL; + nrecords[i] = 0; + mblocks[i]->getCancellationData(&(nrecords[i]), &(donorRecords[i])); } - } - // - // communciate cancellation data comm 3 - // - pc->sendRecvPackets(sndPack,rcvPack); - // - for (int k=0; kcancelDonor(recid); + // + // create packets to send and receive + // and initialize them to zero + // + sndPack = (PACKET*)malloc(sizeof(PACKET) * nsend); + rcvPack = (PACKET*)malloc(sizeof(PACKET) * nrecv); + // + pc->initPackets(sndPack, rcvPack); + // + std::vector nintsSend(nsend, 0); + std::vector ixOffset(nsend, 0); + std::fill(nintsSend.begin(), nintsSend.end(), 0); + std::fill(ixOffset.begin(), ixOffset.end(), 0); + // + for (int n = 0; n < nblocks; n++) { + for (int i = 0; i < nrecords[n]; i++) { + int k = donorRecords[n][3 * i]; + sndPack[k].nints += 2; + } } - } - // - for (int ib=0;ibresetCoincident(); - } - // - pc->clearPackets(sndPack, rcvPack); - // - // Find final interpolation data - // - for (int i=0; igetInterpData(&(nrecords[i]), - &(donorRecords[i])); - } - std::fill(nintsSend.begin(), nintsSend.end(), 0); - std::fill(ixOffset.begin(), ixOffset.end(), 0); - for (int n=0; n < nblocks; n++) { - for (int i=0; isendRecvPackets(sndPack, rcvPack); + // + for (int k = 0; k < nrecv; k++) { + int m = 0; + for (int j = 0; j < rcvPack[k].nints / 2; j++) { + int recid = rcvPack[k].intData[m++]; + int ib = tag_iblk_map[rcvPack[k].intData[m++]]; + mblocks[ib]->cancelDonor(recid); + } } - } - for(int k=0;kresetCoincident(); } - } - // - // comm 4 - // final receptor data to set iblanks - // - pc->sendRecvPackets(sndPack,rcvPack); - // - for(int ib=0;ibclearIblanks(); - - for (int k=0; ksetIblanks(pointid); - } - } - pc->clearPackets(sndPack,rcvPack); - TIOGA_FREE(sndPack); - TIOGA_FREE(rcvPack); - - if (donorRecords) { - for (int i=0; iclearPackets(sndPack, rcvPack); + // + // Find final interpolation data + // + for (int i = 0; i < nblocks; i++) { + if (donorRecords[i]) { + TIOGA_FREE(donorRecords[i]); + donorRecords[i] = NULL; + } + nrecords[i] = 0; + mblocks[i]->getInterpData(&(nrecords[i]), &(donorRecords[i])); + } + std::fill(nintsSend.begin(), nintsSend.end(), 0); + std::fill(ixOffset.begin(), ixOffset.end(), 0); + for (int n = 0; n < nblocks; n++) { + for (int i = 0; i < nrecords[n]; i++) { + int k = donorRecords[n][3 * i]; + sndPack[k].nints += 2; + } + } + for (int k = 0; k < nsend; k++) + sndPack[k].intData = (int*)malloc(sizeof(int) * sndPack[k].nints); + for (int n = 0; n < nblocks; n++) { + for (int i = 0; i < nrecords[n]; i++) { + int k = donorRecords[n][3 * i]; + sndPack[k].intData[ixOffset[k]++] = donorRecords[n][3 * i + 1]; + sndPack[k].intData[ixOffset[k]++] = donorRecords[n][3 * i + 2]; + } + } + // + // comm 4 + // final receptor data to set iblanks + // + pc->sendRecvPackets(sndPack, rcvPack); + // + for (int ib = 0; ib < nblocks; ib++) mblocks[ib]->clearIblanks(); + + for (int k = 0; k < nrecv; k++) { + int m = 0; + for (int j = 0; j < rcvPack[k].nints / 2; j++) { + int pointid = rcvPack[k].intData[m++]; + int ib = rcvPack[k].intData[m++]; + mblocks[ib]->setIblanks(pointid); + } + } + pc->clearPackets(sndPack, rcvPack); + TIOGA_FREE(sndPack); + TIOGA_FREE(rcvPack); + + if (donorRecords) { + for (int i = 0; i < nblocks; i++) { + if (donorRecords[i]) TIOGA_FREE(donorRecords[i]); + } + TIOGA_FREE(donorRecords); } - TIOGA_FREE(donorRecords); - } - outputStatistics(); - //mb->writeOBB(myid); - //if (myid==4) mb->writeOutput(myid); - //if (myid==4) mb->writeOBB(myid); + outputStatistics(); + // mb->writeOBB(myid); + // if (myid==4) mb->writeOutput(myid); + // if (myid==4) mb->writeOBB(myid); } /** Create valid CartGrid data on all TIOGA MPI processes @@ -1316,89 +1360,90 @@ void tioga::reduce_fringes(void) */ void tioga::preprocess_amr_data(int root) { - assert(root < numprocs); - assert((root != myid) || (cg != nullptr)); - - // Only perform this step if we detect that AMR solver is NOT running on all - // MPI ranks. The assumption is that the solver has called - // tioga::register_amr_grid on all processes that it is running on and, - // therefore, there is a valid CartGrid instance on these MPI ranks. - { - int ilocal = (cg == nullptr) ? 0 : 1; - int iglobal = 0; - MPI_Allreduce(&ilocal, &iglobal, 1, MPI_INT, MPI_SUM, scomm); - - // If everyone has a valid CartGrid instance, there is nothing to do so - // return. - if (iglobal == numprocs) return; - } - - // Some MPI ranks do not have information regarding the AMR mesh. We broadcast - // the AMR patch information from ranks that have it and then create a valid - // CartGrid instance on MPI ranks that do not have it. - - constexpr int nint_per_grid = 10; - constexpr int nreal_per_grid = 6; - - // Let all processes know the number of global AMR patches so that they can - // create buffers for MPI broadcast. - int ngrids_global = (root == myid) ? cg->m_info->ngrids_global : 0; - MPI_Bcast(&ngrids_global, 1, MPI_INT, root, scomm); - - // Buffers that will be used to perform MPI communications. The data layout is - // similar to what CartGrid uses for the registerData interface. We add an - // additional parameter at the end to exchange the number of ghosts per patch. - std::vector idata(ngrids_global * nint_per_grid + 1); - std::vector rdata(ngrids_global * nreal_per_grid); - - // On root MPI process for the AMR solver, populate the buffer for broadcast - // to all processes. - if (root == myid) { - const auto* ainfo = cg->m_info; - for (int pp = 0; pp < ngrids_global; ++pp) { - int i3 = pp * 3; - int i6 = pp * 6; - int iloc = nint_per_grid * pp; - - idata[iloc] = pp; - idata[iloc + 1] = ainfo->level.hptr[pp]; - idata[iloc + 2] = ainfo->mpi_rank.hptr[pp]; - idata[iloc + 3] = ainfo->local_id.hptr[pp]; - - for (int n = 0; n < 3; ++n) { - idata[iloc + 4 + n] = ainfo->ilow.hptr[i3 + n]; - idata[iloc + 7 + n] = ainfo->ihigh.hptr[i3 + n]; - - rdata[i6 + n] = ainfo->xlo.hptr[i3 + n]; - rdata[i6 + n + 3] = ainfo->dx.hptr[i3 + n]; - } + assert(root < numprocs); + assert((root != myid) || (cg != nullptr)); + + // Only perform this step if we detect that AMR solver is NOT running on all + // MPI ranks. The assumption is that the solver has called + // tioga::register_amr_grid on all processes that it is running on and, + // therefore, there is a valid CartGrid instance on these MPI ranks. + { + int ilocal = (cg == nullptr) ? 0 : 1; + int iglobal = 0; + MPI_Allreduce(&ilocal, &iglobal, 1, MPI_INT, MPI_SUM, scomm); + + // If everyone has a valid CartGrid instance, there is nothing to do so + // return. + if (iglobal == numprocs) return; } - // Add in number of ghost cells surrounding each patch - idata.back() = ainfo->num_ghost; - } + // Some MPI ranks do not have information regarding the AMR mesh. We + // broadcast the AMR patch information from ranks that have it and then + // create a valid CartGrid instance on MPI ranks that do not have it. + + constexpr int nint_per_grid = 10; + constexpr int nreal_per_grid = 6; + + // Let all processes know the number of global AMR patches so that they can + // create buffers for MPI broadcast. + int ngrids_global = (root == myid) ? cg->m_info->ngrids_global : 0; + MPI_Bcast(&ngrids_global, 1, MPI_INT, root, scomm); + + // Buffers that will be used to perform MPI communications. The data layout + // is similar to what CartGrid uses for the registerData interface. We add + // an additional parameter at the end to exchange the number of ghosts per + // patch. + std::vector idata(ngrids_global * nint_per_grid + 1); + std::vector rdata(ngrids_global * nreal_per_grid); + + // On root MPI process for the AMR solver, populate the buffer for broadcast + // to all processes. + if (root == myid) { + const auto* ainfo = cg->m_info; + for (int pp = 0; pp < ngrids_global; ++pp) { + int i3 = pp * 3; + int i6 = pp * 6; + int iloc = nint_per_grid * pp; + + idata[iloc] = pp; + idata[iloc + 1] = ainfo->level.hptr[pp]; + idata[iloc + 2] = ainfo->mpi_rank.hptr[pp]; + idata[iloc + 3] = ainfo->local_id.hptr[pp]; + + for (int n = 0; n < 3; ++n) { + idata[iloc + 4 + n] = ainfo->ilow.hptr[i3 + n]; + idata[iloc + 7 + n] = ainfo->ihigh.hptr[i3 + n]; + + rdata[i6 + n] = ainfo->xlo.hptr[i3 + n]; + rdata[i6 + n + 3] = ainfo->dx.hptr[i3 + n]; + } + } + + // Add in number of ghost cells surrounding each patch + idata.back() = ainfo->num_ghost; + } - // Broadcast from AMR solver root MPI proc to all ranks - MPI_Bcast(idata.data(), idata.size(), MPI_INT, root, scomm); - MPI_Bcast(rdata.data(), rdata.size(), MPI_DOUBLE, root, scomm); + // Broadcast from AMR solver root MPI proc to all ranks + MPI_Bcast(idata.data(), idata.size(), MPI_INT, root, scomm); + MPI_Bcast(rdata.data(), rdata.size(), MPI_DOUBLE, root, scomm); - // For MPI ranks that already have a valid AMR grid registered, do nothing and - // return early. - if (cg != nullptr) return; + // For MPI ranks that already have a valid AMR grid registered, do nothing + // and return early. + if (cg != nullptr) return; - // These MPI ranks don't have AMR mesh, but require patch information for - // performing searches. So create appropriate data here. - { - int nghost = idata.back(); - cg = new CartGrid[1]; - cg->myid = myid; + // These MPI ranks don't have AMR mesh, but require patch information for + // performing searches. So create appropriate data here. + { + int nghost = idata.back(); + cg = new CartGrid[1]; + cg->myid = myid; - // For these MPI ranks there are no local patches - assert(cb == nullptr); - ncart = 0; + // For these MPI ranks there are no local patches + assert(cb == nullptr); + ncart = 0; - // Register data using the buffer interface. AMRMeshInfo object will be - // created by CartGrid - cg->registerData(nghost, idata.data(), rdata.data(), ngrids_global); - } + // Register data using the buffer interface. AMRMeshInfo object will be + // created by CartGrid + cg->registerData(nghost, idata.data(), rdata.data(), ngrids_global); + } } diff --git a/src/tioga.h b/src/tioga.h index a555475..95db54d 100644 --- a/src/tioga.h +++ b/src/tioga.h @@ -51,261 +51,287 @@ namespace TIOGA { -class tioga { +class tioga +{ private: - int nblocks; - int nblocksq; - int ncart; - MeshBlock *mb; - CartGrid *cg; - CartBlock *cb; - int nmesh; - HOLEMAP *holeMap; - ADAPTIVE_HOLEMAP *adaptiveHoleMap; - int USE_ADAPTIVE_HOLEMAP; - MPI_Comm scomm; - MPI_Group scomm_group; - parallelComm *pc; - parallelComm *pc_cart; - int isym; - int ierr; - - int myid, numprocs; - int *sendCount; - int *recvCount; - std::vector obblist; - int iorphanPrint; - - //! Mesh Block Complement data - meshblockCompInfo *meshblockComplement; - - //! Mesh Block Composite data - meshblockCompInfo *meshblockComposite; - - //! Composite Body info - int ncomposite; /** < number of composite bodies */ - std::vector - compositeBody; /** < list of composite body structs */ - std::vector>> - compositeBodyMap; /** < mesh block composite-body map flag */ - - //! Mesh blocks in this processor - std::vector> mblocks; - //! Solver assigned mesh tags for the mesh blocks - std::vector mtags; - std::vector mytag; - //! Mesh tag to local block index lookup mapping - std::map tag_iblk_map; - - //! Intersect block unique ID to index lookup mapping - std::map intBoxMap; - - //! Parallel comms to obblist indices - std::vector ibsPerProc; - std::vector> ibProcMap; - //! q-variables registered - double **qblock; + int nblocks; + int nblocksq; + int ncart; + MeshBlock* mb; + CartGrid* cg; + CartBlock* cb; + int nmesh; + HOLEMAP* holeMap; + ADAPTIVE_HOLEMAP* adaptiveHoleMap; + int USE_ADAPTIVE_HOLEMAP; + MPI_Comm scomm; + MPI_Group scomm_group; + parallelComm* pc; + parallelComm* pc_cart; + int isym; + int ierr; + + int myid, numprocs; + int* sendCount; + int* recvCount; + std::vector obblist; + int iorphanPrint; + + //! Mesh Block Complement data + meshblockCompInfo* meshblockComplement; + + //! Mesh Block Composite data + meshblockCompInfo* meshblockComposite; + + //! Composite Body info + int ncomposite; /** < number of composite bodies */ + std::vector + compositeBody; /** < list of composite body structs */ + std::vector>> + compositeBodyMap; /** < mesh block composite-body map flag */ + + //! Mesh blocks in this processor + std::vector> mblocks; + //! Solver assigned mesh tags for the mesh blocks + std::vector mtags; + std::vector mytag; + //! Mesh tag to local block index lookup mapping + std::map tag_iblk_map; + + //! Intersect block unique ID to index lookup mapping + std::map intBoxMap; + + //! Parallel comms to obblist indices + std::vector ibsPerProc; + std::vector> ibProcMap; + //! q-variables registered + double** qblock; public: - int ihigh; - int ihighGlobal; - int iamrGlobal; - int mexclude, nfringe; - /** basic constructor */ - tioga() - /* - : mblocks(0), - mtags(0) - */ - { - mb = NULL; - cg = NULL; - cb = NULL; - holeMap = NULL; - adaptiveHoleMap = NULL; - pc = NULL; - sendCount = NULL; - recvCount = NULL; - pc_cart = NULL; - meshblockComplement = NULL; - meshblockComposite = NULL; - // obblist=NULL; - // isym=2;ihigh=0;nblocks=0;ncart=0;ihighGlobal=0;iamrGlobal=0; - isym = 3; - ihigh = 0; - nblocks = 0; - ncart = 0; - ncomposite = 0; - ihighGlobal = 0; - iamrGlobal = 0; - mexclude = 3, nfringe = 1; - USE_ADAPTIVE_HOLEMAP = 0; // Default to original hole map - qblock = NULL; - mblocks.clear(); - mtags.clear(); - } - - /** basic destructor */ - ~tioga(); - - /** set communicator */ - void setCommunicator(MPI_Comm communicator, int id_proc, int nprocs); - - void assembleComplementComms(void); - void assembleCompositeComms(void); - void assembleCompositeMap(void); - - int getNumCompositeBodies() { return ncomposite; } - void setNumCompositeBodies(int ncomposite); - - void registerCompositeBody(int compbodytag, int nbodytags, int *meshtags, - int *dominancetags, double searchTol); - - /** registerGrid data */ - - void registerGridData(int btag, int nnodes, double *xyz, int *ibl, int nwbc, - int nobc, int *wbcnode, int *obcnode, int ntypes, - int *nv, int *nc, int **vconn, - uint64_t *cell_gid = NULL, uint64_t *node_gid = NULL); - - void registerSolution(int btag, double *q); - - void register_unstructured_solution(int btag, double *q, int nvar, - int interptype); - - void register_unstructured_grid(TIOGA::MeshBlockInfo *minfo); - void register_unstructured_solution(); - - void register_amr_grid(TIOGA::AMRMeshInfo *minfo); - void register_amr_solution(); - - /** Synchronize AMR patch information on all processes - * - * \param root Root process from which data is broadcast to other processes - */ - void preprocess_amr_data(int root = 0); - - void profile(void); - - void exchangeBoxes(void); - - void exchangeSearchData(int at_points = 0); - - void exchangeDonors(void); - - /** perform overset grid connectivity */ - - void performConnectivity(void); - void performConnectivityHighOrder(void); - void performConnectivityAMR(void); - - /** update data */ - void dataUpdate(int nvar, int interptype, int at_points = 0); - - void dataUpdate_AMR(); - - void dataUpdate_highorder(int nvar, double *q, int interptype); - - /** get hole map for each mesh */ - void getHoleMap(void); - void getAdaptiveHoleMap(void); - - /** output HoleMaps */ - void outputHoleMap(void); - void outputAdaptiveHoleMap(void); - - void writeData(int nvar, int interptype); - - void getDonorCount(int btag, int *dcount, int *fcount); - - void getDonorInfo(int btag, int *receptors, int *indices, double *frac, - int *dcount); - - void getReceptorInfo(std::vector &); - - /** set hole map algorithm: [0] original hole map, [1] adaptive hole map */ - void setHoleMapAlgorithm(int alg) { USE_ADAPTIVE_HOLEMAP = alg; }; - int getHoleMapAlgorithm() { return USE_ADAPTIVE_HOLEMAP; }; - /** set symmetry bc */ - void setSymmetry(int syminput) { isym = syminput; }; - /** set resolutions for nodes and cells */ - void setResolutions(double *nres, double *cres) { - auto &mb = mblocks[0]; - mb->setResolutions(nres, cres); - } + int ihigh; + int ihighGlobal; + int iamrGlobal; + int mexclude, nfringe; + /** basic constructor */ + tioga() + /* + : mblocks(0), + mtags(0) + */ + { + mb = NULL; + cg = NULL; + cb = NULL; + holeMap = NULL; + adaptiveHoleMap = NULL; + pc = NULL; + sendCount = NULL; + recvCount = NULL; + pc_cart = NULL; + meshblockComplement = NULL; + meshblockComposite = NULL; + // obblist=NULL; + // isym=2;ihigh=0;nblocks=0;ncart=0;ihighGlobal=0;iamrGlobal=0; + isym = 3; + ihigh = 0; + nblocks = 0; + ncart = 0; + ncomposite = 0; + ihighGlobal = 0; + iamrGlobal = 0; + mexclude = 3, nfringe = 1; + USE_ADAPTIVE_HOLEMAP = 0; // Default to original hole map + qblock = NULL; + mblocks.clear(); + mtags.clear(); + } + + /** basic destructor */ + ~tioga(); + + /** set communicator */ + void setCommunicator(MPI_Comm communicator, int id_proc, int nprocs); + + void assembleComplementComms(void); + void assembleCompositeComms(void); + void assembleCompositeMap(void); + + int getNumCompositeBodies() { return ncomposite; } + void setNumCompositeBodies(int ncomposite); + + void registerCompositeBody( + int compbodytag, + int nbodytags, + int* meshtags, + int* dominancetags, + double searchTol); + + /** registerGrid data */ + + void registerGridData( + int btag, + int nnodes, + double* xyz, + int* ibl, + int nwbc, + int nobc, + int* wbcnode, + int* obcnode, + int ntypes, + int* nv, + int* nc, + int** vconn, + uint64_t* cell_gid = NULL, + uint64_t* node_gid = NULL); + + void registerSolution(int btag, double* q); + + void register_unstructured_solution( + int btag, double* q, int nvar, int interptype); + + void register_unstructured_grid(TIOGA::MeshBlockInfo* minfo); + void register_unstructured_solution(); + + void register_amr_grid(TIOGA::AMRMeshInfo* minfo); + void register_amr_solution(); + + /** Synchronize AMR patch information on all processes + * + * \param root Root process from which data is broadcast to other processes + */ + void preprocess_amr_data(int root = 0); + + void profile(void); + + void exchangeBoxes(void); + + void exchangeSearchData(int at_points = 0); + + void exchangeDonors(void); + + /** perform overset grid connectivity */ + + void performConnectivity(void); + void performConnectivityHighOrder(void); + void performConnectivityAMR(void); - void setResolutions(int btag, double *nres, double *cres) { - auto idxit = tag_iblk_map.find(btag); - int iblk = idxit->second; - auto &mb = mblocks[iblk]; - mb->setResolutions(nres, cres); - } + /** update data */ + void dataUpdate(int nvar, int interptype, int at_points = 0); - void setMexclude(int *mexclude_input) { mexclude = *mexclude_input; } + void dataUpdate_AMR(); - void setNfringe(int *nfringe_input) { nfringe = *nfringe_input; } + void dataUpdate_highorder(int nvar, double* q, int interptype); - void set_cell_iblank(int *iblank_cell) { - auto &mb = mblocks[0]; - mb->set_cell_iblank(iblank_cell); - } + /** get hole map for each mesh */ + void getHoleMap(void); + void getAdaptiveHoleMap(void); - void set_uniform_hex_flag(int btag, int flag) { - auto idxit = tag_iblk_map.find(btag); - int iblk = idxit->second; - auto &mb = mblocks[iblk]; - mb->check_uniform_hex_flag = flag; - } + /** output HoleMaps */ + void outputHoleMap(void); + void outputAdaptiveHoleMap(void); - void set_cell_iblank(int btag, int *ib_cell) { - auto idxit = tag_iblk_map.find(btag); - int iblk = idxit->second; - auto &mb = mblocks[iblk]; - mb->set_cell_iblank(ib_cell); - } + void writeData(int nvar, int interptype); - void setcallback(void (*f1)(int *, int *), void (*f2)(int *, int *, double *), - void (*f3)(int *, double *, int *, double *), - void (*f4)(int *, double *, int *, int *, double *, double *, - int *), - void (*f5)(int *, int *, double *, int *, int *, double *)) { - for (int ib = 0; ib < nblocks; ib++) { - auto &mb = mblocks[ib]; - mb->setcallback(f1, f2, f3, f4, f5); + void getDonorCount(int btag, int* dcount, int* fcount); + + void getDonorInfo( + int btag, int* receptors, int* indices, double* frac, int* dcount); + + void getReceptorInfo(std::vector&); + + /** set hole map algorithm: [0] original hole map, [1] adaptive hole map */ + void setHoleMapAlgorithm(int alg) { USE_ADAPTIVE_HOLEMAP = alg; }; + int getHoleMapAlgorithm() { return USE_ADAPTIVE_HOLEMAP; }; + /** set symmetry bc */ + void setSymmetry(int syminput) { isym = syminput; }; + /** set resolutions for nodes and cells */ + void setResolutions(double* nres, double* cres) + { + auto& mb = mblocks[0]; + mb->setResolutions(nres, cres); + } + + void setResolutions(int btag, double* nres, double* cres) + { + auto idxit = tag_iblk_map.find(btag); + int iblk = idxit->second; + auto& mb = mblocks[iblk]; + mb->setResolutions(nres, cres); } - ihigh = 1; - } - - void setp4estcallback(void (*f1)(double *, int *, int *, int *), - void (*f2)(int *, int *)) { - for (int ib = 0; ib < nblocks; ib++) { - auto &mb = mblocks[ib]; // TODO:this may have to based on unique tag of - // p4est blocks - mb->setp4estcallback(f1, f2); + + void setMexclude(int* mexclude_input) { mexclude = *mexclude_input; } + + void setNfringe(int* nfringe_input) { nfringe = *nfringe_input; } + + void set_cell_iblank(int* iblank_cell) + { + auto& mb = mblocks[0]; + mb->set_cell_iblank(iblank_cell); + } + + void set_uniform_hex_flag(int btag, int flag) + { + auto idxit = tag_iblk_map.find(btag); + int iblk = idxit->second; + auto& mb = mblocks[iblk]; + mb->check_uniform_hex_flag = flag; } - } - void set_p4est(void) { - for (int ib = 0; ib < nblocks; ib++) { - mytag[ib] = -mytag[ib]; - auto &mb = mblocks[ib]; // TODO - mb->resolutionScale = 1000.0; + void set_cell_iblank(int btag, int* ib_cell) + { + auto idxit = tag_iblk_map.find(btag); + int iblk = idxit->second; + auto& mb = mblocks[iblk]; + mb->set_cell_iblank(ib_cell); } - } - - void set_amr_callback(void (*f1)(int *, double *, int *, double *)) { - cg->setcallback(f1); - } - - void register_amr_global_data(int, int *, double *, int); - void set_amr_patch_count(int); - void register_amr_local_data(int, int, int *, int *); - void register_amr_solution(int, double *, int, int); - void exchangeAMRDonors(void); - void checkComm(void); - void outputStatistics(void); - void myTimer(char const *, int); - void reduce_fringes(void); + + void setcallback( + void (*f1)(int*, int*), + void (*f2)(int*, int*, double*), + void (*f3)(int*, double*, int*, double*), + void (*f4)(int*, double*, int*, int*, double*, double*, int*), + void (*f5)(int*, int*, double*, int*, int*, double*)) + { + for (int ib = 0; ib < nblocks; ib++) { + auto& mb = mblocks[ib]; + mb->setcallback(f1, f2, f3, f4, f5); + } + ihigh = 1; + } + + void setp4estcallback( + void (*f1)(double*, int*, int*, int*), void (*f2)(int*, int*)) + { + for (int ib = 0; ib < nblocks; ib++) { + auto& mb = mblocks[ib]; // TODO:this may have to based on unique tag + // of p4est blocks + mb->setp4estcallback(f1, f2); + } + } + + void set_p4est(void) + { + for (int ib = 0; ib < nblocks; ib++) { + mytag[ib] = -mytag[ib]; + auto& mb = mblocks[ib]; // TODO + mb->resolutionScale = 1000.0; + } + } + + void set_amr_callback(void (*f1)(int*, double*, int*, double*)) + { + cg->setcallback(f1); + } + + void register_amr_global_data(int, int*, double*, int); + void set_amr_patch_count(int); + void register_amr_local_data(int, int, int*, int*); + void register_amr_solution(int, double*, int, int); + void exchangeAMRDonors(void); + void checkComm(void); + void outputStatistics(void); + void myTimer(char const*, int); + void reduce_fringes(void); }; } // namespace TIOGA diff --git a/src/tiogaInterface.C b/src/tiogaInterface.C index 000cd24..f2306ea 100644 --- a/src/tiogaInterface.C +++ b/src/tiogaInterface.C @@ -16,7 +16,7 @@ // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include #include #include @@ -25,7 +25,7 @@ #include "tioga.h" #include "globals.h" // -// All the interfaces that are +// All the interfaces that are // accessible to third party f90 and C // flow solvers // @@ -35,316 +35,301 @@ // extern "C" { - void tioga_init_f90_(int *scomm) - { - int id_proc,nprocs; +void tioga_init_f90_(int* scomm) +{ + int id_proc, nprocs; MPI_Comm tcomm; - //tcomm=(MPI_Comm) (*scomm); - tcomm=MPI_Comm_f2c(*scomm); + // tcomm=(MPI_Comm) (*scomm); + tcomm = MPI_Comm_f2c(*scomm); // - tg=new tioga[1]; + tg = new tioga[1]; // - //MPI_Comm_rank(MPI_COMM_WORLD,&id_proc); - //MPI_Comm_size(MPI_COMM_WORLD,&nprocs); - MPI_Comm_rank(tcomm,&id_proc); - MPI_Comm_size(tcomm,&nprocs); + // MPI_Comm_rank(MPI_COMM_WORLD,&id_proc); + // MPI_Comm_size(MPI_COMM_WORLD,&nprocs); + MPI_Comm_rank(tcomm, &id_proc); + MPI_Comm_size(tcomm, &nprocs); // - tg->setCommunicator(tcomm,id_proc,nprocs); - for(int i=0;isetCommunicator(tcomm, id_proc, nprocs); + for (int i = 0; i < MAXBLOCKS; i++) { + idata[i].nc = NULL; + idata[i].nv = NULL; + idata[i].vconn = NULL; + } +} + +void tioga_init_(MPI_Comm tcomm) +{ + int id_proc, nprocs; + // MPI_Comm tcomm; + // tcomm=(MPI_Comm) (*scomm); + // tcomm=MPI_Comm_f2c(*scomm); // - tg=new tioga[1]; + tg = new tioga[1]; // - //MPI_Comm_rank(MPI_COMM_WORLD,&id_proc); - //MPI_Comm_size(MPI_COMM_WORLD,&nprocs); - MPI_Comm_rank(tcomm,&id_proc); - MPI_Comm_size(tcomm,&nprocs); + // MPI_Comm_rank(MPI_COMM_WORLD,&id_proc); + // MPI_Comm_size(MPI_COMM_WORLD,&nprocs); + MPI_Comm_rank(tcomm, &id_proc); + MPI_Comm_size(tcomm, &nprocs); // - tg->setCommunicator(tcomm,id_proc,nprocs); - for (int i=0;isetCommunicator(tcomm, id_proc, nprocs); + for (int i = 0; i < MAXBLOCKS; i++) { + idata[i].nc = NULL; + idata[i].nv = NULL; + idata[i].vconn = NULL; + } +} + +void tioga_registergrid_data_( + int* btag, + int* nnodes, + double* xyz, + int* ibl, + int* nwbc, + int* nobc, + int* wbcnode, + int* obcnode, + int* ntypes, + ...) +{ va_list arguments; int i; - int iblk=0; + int iblk = 0; va_start(arguments, ntypes); - if(idata[iblk].nv) TIOGA_FREE(idata[iblk].nv); - if(idata[iblk].nc) TIOGA_FREE(idata[iblk].nc); - if(idata[iblk].vconn) TIOGA_FREE(idata[iblk].vconn); - idata[iblk].nv=(int *) malloc(sizeof(int)*(*ntypes)); - idata[iblk].nc=(int *) malloc(sizeof(int)*(*ntypes)); - idata[iblk].vconn=(int **)malloc(sizeof(int *)*(*ntypes)); - for(i=0;i<*ntypes;i++) - { - idata[iblk].nv[i]=*(va_arg(arguments, int *)); - idata[iblk].nc[i]=*(va_arg(arguments, int *)); - idata[iblk].vconn[i]=va_arg(arguments, int *); - } - tg->registerGridData(*btag,*nnodes,xyz,ibl,*nwbc,*nobc,wbcnode,obcnode,*ntypes,idata[iblk].nv,idata[iblk].nc,idata[iblk].vconn); - } - - - void tioga_registergrid_data_mb_(int *bid, int *btag,int *nnodes,double *xyz,int *ibl,int *nwbc, int *nobc,int *wbcnode, - int *obcnode,int *ntypes,...) - { + if (idata[iblk].nv) TIOGA_FREE(idata[iblk].nv); + if (idata[iblk].nc) TIOGA_FREE(idata[iblk].nc); + if (idata[iblk].vconn) TIOGA_FREE(idata[iblk].vconn); + idata[iblk].nv = (int*)malloc(sizeof(int) * (*ntypes)); + idata[iblk].nc = (int*)malloc(sizeof(int) * (*ntypes)); + idata[iblk].vconn = (int**)malloc(sizeof(int*) * (*ntypes)); + for (i = 0; i < *ntypes; i++) { + idata[iblk].nv[i] = *(va_arg(arguments, int*)); + idata[iblk].nc[i] = *(va_arg(arguments, int*)); + idata[iblk].vconn[i] = va_arg(arguments, int*); + } + tg->registerGridData( + *btag, *nnodes, xyz, ibl, *nwbc, *nobc, wbcnode, obcnode, *ntypes, + idata[iblk].nv, idata[iblk].nc, idata[iblk].vconn); +} + +void tioga_registergrid_data_mb_( + int* bid, + int* btag, + int* nnodes, + double* xyz, + int* ibl, + int* nwbc, + int* nobc, + int* wbcnode, + int* obcnode, + int* ntypes, + ...) +{ va_list arguments; int i; - int iblk=*bid-BASE; + int iblk = *bid - BASE; va_start(arguments, ntypes); - if(idata[iblk].nv) TIOGA_FREE(idata[iblk].nv); - if(idata[iblk].nc) TIOGA_FREE(idata[iblk].nc); - if(idata[iblk].vconn) TIOGA_FREE(idata[iblk].vconn); - idata[iblk].nv=(int *) malloc(sizeof(int)*(*ntypes)); - idata[iblk].nc=(int *) malloc(sizeof(int)*(*ntypes)); - idata[iblk].vconn=(int **)malloc(sizeof(int *)*(*ntypes)); - for(i=0;i<*ntypes;i++) - { - idata[iblk].nv[i]=*(va_arg(arguments, int *)); - idata[iblk].nc[i]=*(va_arg(arguments, int *)); - idata[iblk].vconn[i]=va_arg(arguments, int *); - } - tg->registerGridData(*btag,*nnodes,xyz,ibl,*nwbc,*nobc,wbcnode,obcnode,*ntypes,idata[iblk].nv,idata[iblk].nc,idata[iblk].vconn); - } - - void tioga_register_amr_global_data_(int *nf, int *idata,double *rdata,int *ngridsin) - { - tg->register_amr_global_data(*nf,idata,rdata,*ngridsin); - } - - - void tioga_register_amr_patch_count_(int *npatches) - { + if (idata[iblk].nv) TIOGA_FREE(idata[iblk].nv); + if (idata[iblk].nc) TIOGA_FREE(idata[iblk].nc); + if (idata[iblk].vconn) TIOGA_FREE(idata[iblk].vconn); + idata[iblk].nv = (int*)malloc(sizeof(int) * (*ntypes)); + idata[iblk].nc = (int*)malloc(sizeof(int) * (*ntypes)); + idata[iblk].vconn = (int**)malloc(sizeof(int*) * (*ntypes)); + for (i = 0; i < *ntypes; i++) { + idata[iblk].nv[i] = *(va_arg(arguments, int*)); + idata[iblk].nc[i] = *(va_arg(arguments, int*)); + idata[iblk].vconn[i] = va_arg(arguments, int*); + } + tg->registerGridData( + *btag, *nnodes, xyz, ibl, *nwbc, *nobc, wbcnode, obcnode, *ntypes, + idata[iblk].nv, idata[iblk].nc, idata[iblk].vconn); +} + +void tioga_register_amr_global_data_( + int* nf, int* idata, double* rdata, int* ngridsin) +{ + tg->register_amr_global_data(*nf, idata, rdata, *ngridsin); +} + +void tioga_register_amr_patch_count_(int* npatches) +{ tg->set_amr_patch_count(*npatches); - } - - void tioga_register_amr_local_data_(int *ipatch,int *global_id,int *iblank,int *iblankn) - { - tg->register_amr_local_data(*ipatch,*global_id,iblank,iblankn); - } - - void tioga_register_amr_solution_(int *ipatch,double *q,int nvar_cell,int nvar_node) - { - tg->register_amr_solution(*ipatch,q,nvar_cell,nvar_node); - } - - void tioga_setcomposite_(int *ncomp) - { - tg->setNumCompositeBodies(*ncomp); - } - - void tioga_register_composite_body_(int *compbodytag,int *nbodytags,int *bodytags,int *dominancetags,double *searchTol) - { - tg->registerCompositeBody(*compbodytag,*nbodytags,bodytags,dominancetags,*searchTol); - } - - void tioga_preprocess_grids_(void) - { - if(tg->getHoleMapAlgorithm() == 1){ - tg->assembleComplementComms(); // build complement rank communicators - if(tg->getNumCompositeBodies()>0) tg->assembleCompositeMap(); // abutting meshes (AFTER assembleComplementComms) +} + +void tioga_register_amr_local_data_( + int* ipatch, int* global_id, int* iblank, int* iblankn) +{ + tg->register_amr_local_data(*ipatch, *global_id, iblank, iblankn); +} + +void tioga_register_amr_solution_( + int* ipatch, double* q, int nvar_cell, int nvar_node) +{ + tg->register_amr_solution(*ipatch, q, nvar_cell, nvar_node); +} + +void tioga_setcomposite_(int* ncomp) { tg->setNumCompositeBodies(*ncomp); } + +void tioga_register_composite_body_( + int* compbodytag, + int* nbodytags, + int* bodytags, + int* dominancetags, + double* searchTol) +{ + tg->registerCompositeBody( + *compbodytag, *nbodytags, bodytags, dominancetags, *searchTol); +} + +void tioga_preprocess_grids_(void) +{ + if (tg->getHoleMapAlgorithm() == 1) { + tg->assembleComplementComms(); // build complement rank communicators + if (tg->getNumCompositeBodies() > 0) + tg->assembleCompositeMap(); // abutting meshes (AFTER + // assembleComplementComms) } tg->profile(); - } +} - void tioga_performconnectivity_(void) - { - tg->performConnectivity(); - } +void tioga_performconnectivity_(void) { tg->performConnectivity(); } - void tioga_performconnectivity_highorder_(void) - { +void tioga_performconnectivity_highorder_(void) +{ tg->performConnectivityHighOrder(); - } +} - void tioga_performconnectivity_amr_(void) - { - tg->performConnectivityAMR(); - } +void tioga_performconnectivity_amr_(void) { tg->performConnectivityAMR(); } - void tioga_registersolution_(int *bid,double *q) - { - tg->registerSolution(*bid,q); - } +void tioga_registersolution_(int* bid, double* q) +{ + tg->registerSolution(*bid, q); +} - void tioga_dataupdate_mb_(int *nvar,char *itype) - { +void tioga_dataupdate_mb_(int* nvar, char* itype) +{ int interptype; - if (strstr(itype,"row")) - { - interptype=0; - } - else if (strstr(itype,"column")) - { - interptype=1; - } - else - { - printf("#tiogaInterface.C:dataupdate_:unknown data orientation\n"); - return; - } - - //tg->dataUpdate(*nvar,interptype); - - if (tg->ihighGlobal==0) - { - if (tg->iamrGlobal==0) - { - tg->dataUpdate(*nvar,interptype); - } - else - { - tg->dataUpdate_AMR(); - } + if (strstr(itype, "row")) { + interptype = 0; + } else if (strstr(itype, "column")) { + interptype = 1; + } else { + printf("#tiogaInterface.C:dataupdate_:unknown data orientation\n"); + return; } - else - { - if (tg->iamrGlobal==0) - { - tg->dataUpdate(*nvar,interptype,1); - } - else - { - printf("Data update between high-order near-body and AMR cartesian Not implemented yet\n"); - } + + // tg->dataUpdate(*nvar,interptype); + + if (tg->ihighGlobal == 0) { + if (tg->iamrGlobal == 0) { + tg->dataUpdate(*nvar, interptype); + } else { + tg->dataUpdate_AMR(); + } + } else { + if (tg->iamrGlobal == 0) { + tg->dataUpdate(*nvar, interptype, 1); + } else { + printf( + "Data update between high-order near-body and AMR cartesian " + "Not implemented yet\n"); + } } - } +} - void tioga_dataupdate_(double *q,int *nvar,char *itype) - { +void tioga_dataupdate_(double* q, int* nvar, char* itype) +{ int interptype; - int bid=0; - tg->registerSolution(bid,q); - tioga_dataupdate_mb_(nvar,itype); - } + int bid = 0; + tg->registerSolution(bid, q); + tioga_dataupdate_mb_(nvar, itype); +} - void tioga_writeoutputfiles_(int *nvar,char *itype) - { +void tioga_writeoutputfiles_(int* nvar, char* itype) +{ int interptype; - if (strstr(itype,"row")) - { - interptype=0; - } - else if (strstr(itype,"column")) - { - interptype=1; - } - else - { - printf("#tiogaInterface.C:dataupdate_:unknown data orientation\n"); - return; - } - tg->writeData(*nvar,interptype); - } - void tioga_getdonorcount_(int *btag,int *dcount,int *fcount) - { - tg->getDonorCount(*btag,dcount,fcount); - } - void tioga_getdonorinfo_(int *btag,int *receptors,int *indices,double *frac,int *dcount) - { - tg->getDonorInfo(*btag,receptors,indices,frac,dcount); - } - - void tioga_setholemapalg_(int *alg) - { - tg->setHoleMapAlgorithm(*alg); - } - - void tioga_setsymmetry_(int *isym) - { - tg->setSymmetry(*isym); - } - - void tioga_setresolutions_(double *nres,double *cres) - { - tg->setResolutions(nres,cres); - } - - void tioga_setresolutions_multi_(int *btag,double *nres,double *cres) - { - tg->setResolutions(*btag,nres,cres); - } - - void tioga_setcelliblank_(int *iblank_cell) - { + if (strstr(itype, "row")) { + interptype = 0; + } else if (strstr(itype, "column")) { + interptype = 1; + } else { + printf("#tiogaInterface.C:dataupdate_:unknown data orientation\n"); + return; + } + tg->writeData(*nvar, interptype); +} +void tioga_getdonorcount_(int* btag, int* dcount, int* fcount) +{ + tg->getDonorCount(*btag, dcount, fcount); +} +void tioga_getdonorinfo_( + int* btag, int* receptors, int* indices, double* frac, int* dcount) +{ + tg->getDonorInfo(*btag, receptors, indices, frac, dcount); +} + +void tioga_setholemapalg_(int* alg) { tg->setHoleMapAlgorithm(*alg); } + +void tioga_setsymmetry_(int* isym) { tg->setSymmetry(*isym); } + +void tioga_setresolutions_(double* nres, double* cres) +{ + tg->setResolutions(nres, cres); +} + +void tioga_setresolutions_multi_(int* btag, double* nres, double* cres) +{ + tg->setResolutions(*btag, nres, cres); +} + +void tioga_setcelliblank_(int* iblank_cell) +{ tg->set_cell_iblank(iblank_cell); - } - - void tioga_set_highorder_callback_(void (*f1)(int*, int*), - void (*f2)(int *,int *,double *), - void (*f3)(int *,double *,int *,double *), - void (*f4)(int *,double *,int *,int *,double *,double *,int *), - void (*f5)(int *,int *,double *,int *,int *,double *)) - { - tg->setcallback(f1,f2,f3,f4,f5); +} + +void tioga_set_highorder_callback_( + void (*f1)(int*, int*), + void (*f2)(int*, int*, double*), + void (*f3)(int*, double*, int*, double*), + void (*f4)(int*, double*, int*, int*, double*, double*, int*), + void (*f5)(int*, int*, double*, int*, int*, double*)) +{ + tg->setcallback(f1, f2, f3, f4, f5); // get_nodes_per_cell=f1; - //get_receptor_nodes=f2; - //donor_inclusion_test=f3; - //donor_frac=f4; - //convert_to_modal=f5; - } - - void tioga_set_p4est_(void) - { - tg->set_p4est(); - } - void tioga_set_amr_callback_(void (*f1)(int *,double *,int *,double *)) - { + // get_receptor_nodes=f2; + // donor_inclusion_test=f3; + // donor_frac=f4; + // convert_to_modal=f5; +} + +void tioga_set_p4est_(void) { tg->set_p4est(); } +void tioga_set_amr_callback_(void (*f1)(int*, double*, int*, double*)) +{ tg->set_amr_callback(f1); - } - void tioga_set_p4est_search_callback_(void (*f1)(double *xsearch,int *process_id,int *cell_id,int *npts), - void (*f2)(int *pid,int *iflag)) - { - tg->setp4estcallback(f1,f2); - //jayfixme tg->set_p4est_search_callback(f1); - } - - void tioga_reduce_fringes_(void) - { - tg->reduce_fringes(); - } - - void tioga_setnfringe_(int *nfringe) - { - tg->setNfringe(nfringe); - } - - void tioga_setmexclude_(int *mexclude) - { - tg->setMexclude(mexclude); - } - - void tioga_delete_(void) - { - delete [] tg; - for(int i=0;isetp4estcallback(f1, f2); + // jayfixme tg->set_p4est_search_callback(f1); +} + +void tioga_reduce_fringes_(void) { tg->reduce_fringes(); } + +void tioga_setnfringe_(int* nfringe) { tg->setNfringe(nfringe); } +void tioga_setmexclude_(int* mexclude) { tg->setMexclude(mexclude); } + +void tioga_delete_(void) +{ + delete[] tg; + for (int i = 0; i < MAXBLOCKS; i++) { + if (idata[i].nc) TIOGA_FREE(idata[i].nc); + if (idata[i].nv) TIOGA_FREE(idata[i].nv); + if (idata[i].vconn) TIOGA_FREE(idata[i].vconn); + } +} } diff --git a/src/tioga_cuda.h b/src/tioga_cuda.h index 0e9aeeb..a7cfc76 100644 --- a/src/tioga_cuda.h +++ b/src/tioga_cuda.h @@ -19,58 +19,71 @@ using gpuError_t = cudaError_t; constexpr gpuError_t gpuSuccess = cudaSuccess; inline gpuError_t gpuGetLastError() { return cudaGetLastError(); } -inline const char *gpuGetErrorString(gpuError_t err) { - return cudaGetErrorString(err); +inline const char* gpuGetErrorString(gpuError_t err) +{ + return cudaGetErrorString(err); } #define TIOGA_CUDA_CHECK_ERROR(call) \ - do { \ - TIOGA::gpu::gpuError_t gpu_ierr = (call); \ - if (TIOGA::gpu::gpuSuccess != gpu_ierr) { \ - std::string err_str(std::string("TIOGA GPU error: ") + __FILE__ + ":" + \ - std::to_string(__LINE__) + ": " + \ - TIOGA::gpu::gpuGetErrorString(gpu_ierr)); \ - throw std::runtime_error(err_str); \ - } \ - } while (0) + do { \ + TIOGA::gpu::gpuError_t gpu_ierr = (call); \ + if (TIOGA::gpu::gpuSuccess != gpu_ierr) { \ + std::string err_str( \ + std::string("TIOGA GPU error: ") + __FILE__ + ":" + \ + std::to_string(__LINE__) + ": " + \ + TIOGA::gpu::gpuGetErrorString(gpu_ierr)); \ + throw std::runtime_error(err_str); \ + } \ + } while (0) #define TIOGA_GPU_CALL(call) cuda##call #define TIOGA_GPU_CALL_CHECK(call) TIOGA_CUDA_CHECK_ERROR(TIOGA_GPU_CALL(call)) #define TIOGA_GPU_LAUNCH_FUNC(func, blocks, threads, sharedmem, stream, ...) \ - func<<>>(__VA_ARGS__); + func<<>>(__VA_ARGS__); -template inline T *allocate_on_device(const size_t size) { - T *dptr = nullptr; - TIOGA_CUDA_CHECK_ERROR(cudaMalloc((void **)(&dptr), size)); - return dptr; +template +inline T* allocate_on_device(const size_t size) +{ + T* dptr = nullptr; + TIOGA_CUDA_CHECK_ERROR(cudaMalloc((void**)(&dptr), size)); + return dptr; } template -inline void copy_to_device(T *dptr, const T *hptr, const size_t size) { - TIOGA_CUDA_CHECK_ERROR(cudaMemcpy(dptr, hptr, size, cudaMemcpyHostToDevice)); +inline void copy_to_device(T* dptr, const T* hptr, const size_t size) +{ + TIOGA_CUDA_CHECK_ERROR( + cudaMemcpy(dptr, hptr, size, cudaMemcpyHostToDevice)); } template -inline T *push_to_device(const T *hptr, const size_t size) { - T *dptr = allocate_on_device(size); - TIOGA_CUDA_CHECK_ERROR(cudaMemcpy(dptr, hptr, size, cudaMemcpyHostToDevice)); - return dptr; +inline T* push_to_device(const T* hptr, const size_t size) +{ + T* dptr = allocate_on_device(size); + TIOGA_CUDA_CHECK_ERROR( + cudaMemcpy(dptr, hptr, size, cudaMemcpyHostToDevice)); + return dptr; } template -inline void pull_from_device(T *hptr, T *dptr, const size_t size) { - TIOGA_CUDA_CHECK_ERROR(cudaMemcpy(hptr, dptr, size, cudaMemcpyDeviceToHost)); +inline void pull_from_device(T* hptr, T* dptr, const size_t size) +{ + TIOGA_CUDA_CHECK_ERROR( + cudaMemcpy(hptr, dptr, size, cudaMemcpyDeviceToHost)); } -template inline void deallocate_device(T **dptr) { - TIOGA_CUDA_CHECK_ERROR(cudaFree(static_cast(*dptr))); - *dptr = nullptr; +template +inline void deallocate_device(T** dptr) +{ + TIOGA_CUDA_CHECK_ERROR(cudaFree(static_cast(*dptr))); + *dptr = nullptr; } template -inline void memset_on_device(T *dptr, T val, const size_t sz) { - TIOGA_CUDA_CHECK_ERROR(cudaMemset(dptr, val, sz)); +inline void memset_on_device(T* dptr, T val, const size_t sz) +{ + TIOGA_CUDA_CHECK_ERROR(cudaMemset(dptr, val, sz)); } inline void synchronize() { cudaDeviceSynchronize(); } diff --git a/src/tioga_gpu.h b/src/tioga_gpu.h index 2eb7129..e4ed359 100644 --- a/src/tioga_gpu.h +++ b/src/tioga_gpu.h @@ -14,15 +14,16 @@ namespace gpu { #if defined(TIOGA_HAS_GPU) #define TIOGA_GPU_CHECK_ERROR(call) \ - { \ - TIOGA::gpu::gpuError_t gpu_ierr = (call); \ - if (TIOGA::gpu::gpuSuccess != gpu_ierr) { \ - std::string errStr(std::string("TIOGA GPU error: ") + __FILE__ + ":" + \ - std::to_string(__LINE__) + ": " + \ - TIOGA::gpu::gpuGetErrorString(gpu_ierr)); \ - throw std::runtime_error(errStr); \ - } \ - } + { \ + TIOGA::gpu::gpuError_t gpu_ierr = (call); \ + if (TIOGA::gpu::gpuSuccess != gpu_ierr) { \ + std::string errStr( \ + std::string("TIOGA GPU error: ") + __FILE__ + ":" + \ + std::to_string(__LINE__) + ": " + \ + TIOGA::gpu::gpuGetErrorString(gpu_ierr)); \ + throw std::runtime_error(errStr); \ + } \ + } #else #define TIOGA_GPU_CHECK_ERROR(call) (call) #endif diff --git a/src/tioga_hip.h b/src/tioga_hip.h index 80ee9bd..fc40ff9 100644 --- a/src/tioga_hip.h +++ b/src/tioga_hip.h @@ -19,58 +19,68 @@ using gpuError_t = hipError_t; constexpr gpuError_t gpuSuccess = hipSuccess; inline gpuError_t gpuGetLastError() { return hipGetLastError(); } -inline const char *gpuGetErrorString(gpuError_t err) { - return hipGetErrorString(err); +inline const char* gpuGetErrorString(gpuError_t err) +{ + return hipGetErrorString(err); } #define TIOGA_HIP_CHECK_ERROR(call) \ - do { \ - TIOGA::gpu::gpuError_t gpu_ierr = (call); \ - if (TIOGA::gpu::gpuSuccess != gpu_ierr) { \ - std::string err_str(std::string("TIOGA GPU error: ") + __FILE__ + ":" + \ - std::to_string(__LINE__) + ": " + \ - TIOGA::gpu::gpuGetErrorString(gpu_ierr)); \ - throw std::runtime_error(err_str); \ - } \ - } while (0) + do { \ + TIOGA::gpu::gpuError_t gpu_ierr = (call); \ + if (TIOGA::gpu::gpuSuccess != gpu_ierr) { \ + std::string err_str( \ + std::string("TIOGA GPU error: ") + __FILE__ + ":" + \ + std::to_string(__LINE__) + ": " + \ + TIOGA::gpu::gpuGetErrorString(gpu_ierr)); \ + throw std::runtime_error(err_str); \ + } \ + } while (0) #define TIOGA_GPU_CALL(call) hip##call #define TIOGA_GPU_CALL_CHECK(call) TIOGA_HIP_CHECK_ERROR(TIOGA_GPU_CALL(call)) #define TIOGA_GPU_LAUNCH_FUNC(func, blocks, threads, sharedmem, stream, ...) \ - hipLaunchKernelGGL(func, blocks, threads, sharedmem, stream, __VA_ARGS__); + hipLaunchKernelGGL(func, blocks, threads, sharedmem, stream, __VA_ARGS__); -template inline T *allocate_on_device(const size_t size) { - T *dptr = nullptr; - TIOGA_HIP_CHECK_ERROR(hipMalloc((void **)(&dptr), size)); - return dptr; +template +inline T* allocate_on_device(const size_t size) +{ + T* dptr = nullptr; + TIOGA_HIP_CHECK_ERROR(hipMalloc((void**)(&dptr), size)); + return dptr; } template -inline void copy_to_device(T *dptr, const T *hptr, const size_t size) { - TIOGA_HIP_CHECK_ERROR(hipMemcpy(dptr, hptr, size, hipMemcpyHostToDevice)); +inline void copy_to_device(T* dptr, const T* hptr, const size_t size) +{ + TIOGA_HIP_CHECK_ERROR(hipMemcpy(dptr, hptr, size, hipMemcpyHostToDevice)); } template -inline T *push_to_device(const T *hptr, const size_t size) { - T *dptr = allocate_on_device(size); - TIOGA_HIP_CHECK_ERROR(hipMemcpy(dptr, hptr, size, hipMemcpyHostToDevice)); - return dptr; +inline T* push_to_device(const T* hptr, const size_t size) +{ + T* dptr = allocate_on_device(size); + TIOGA_HIP_CHECK_ERROR(hipMemcpy(dptr, hptr, size, hipMemcpyHostToDevice)); + return dptr; } template -inline void pull_from_device(T *hptr, T *dptr, const size_t size) { - TIOGA_HIP_CHECK_ERROR(hipMemcpy(hptr, dptr, size, hipMemcpyDeviceToHost)); +inline void pull_from_device(T* hptr, T* dptr, const size_t size) +{ + TIOGA_HIP_CHECK_ERROR(hipMemcpy(hptr, dptr, size, hipMemcpyDeviceToHost)); } -template inline void deallocate_device(T **dptr) { - TIOGA_HIP_CHECK_ERROR(hipFree(static_cast(*dptr))); - *dptr = nullptr; +template +inline void deallocate_device(T** dptr) +{ + TIOGA_HIP_CHECK_ERROR(hipFree(static_cast(*dptr))); + *dptr = nullptr; } template -inline void memset_on_device(T *dptr, T val, const size_t sz) { - TIOGA_HIP_CHECK_ERROR(hipMemset(dptr, val, sz)); +inline void memset_on_device(T* dptr, T val, const size_t sz) +{ + TIOGA_HIP_CHECK_ERROR(hipMemset(dptr, val, sz)); } inline void synchronize() { hipDeviceSynchronize(); } diff --git a/src/tioga_math.C b/src/tioga_math.C index b7d7897..f9c2042 100644 --- a/src/tioga_math.C +++ b/src/tioga_math.C @@ -16,328 +16,308 @@ /* You should have received a copy of the GNU Lesser General Public */ /* License along with this library; if not, write to the Free Software */ -/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ #include #include #include #include "codetypes.h" #include "cellVolume.h" -void solvec(double **a,double *b,int *iflag,int n) +void solvec(double** a, double* b, int* iflag, int n) { - int i,j,k,l,flag,temp1; - double fact; - double temp; - double sum; - double eps=1e-8; + int i, j, k, l, flag, temp1; + double fact; + double temp; + double sum; + double eps = 1e-8; - - for(i=0;i=0;i--) - { - sum=0; - for(j=i+1;j= 0; i--) { + sum = 0; + for (j = i + 1; j < n; j++) sum += a[i][j] * b[j]; + b[i] = (b[i] - sum) / a[i][i]; } - *iflag=1; - return; - + *iflag = 1; + return; } -void newtonSolve(double f[7][3],double *u1,double *v1,double *w1) +void newtonSolve(double f[7][3], double* u1, double* v1, double* w1) { - int i,j,k; - int iter,itmax,isolflag; - double u,v,w; - double uv,wu,vw,uvw,norm,convergenceLimit; - double *rhs; - double **lhs; - double alph; - // - lhs=(double **)malloc(sizeof(double)*3); - for(i=0;i<3;i++) - lhs[i]=(double *)malloc(sizeof(double)*3); - rhs=(double *)malloc(sizeof(double)*3); - // - itmax=500; - convergenceLimit=1e-14; - alph=1.0; - isolflag=1.0; - // - u=v=w=0.5; - // - for(iter=0;iter inline T *allocate_on_device(const size_t size) { - return static_cast(std::malloc(size)); +template +inline T* allocate_on_device(const size_t size) +{ + return static_cast(std::malloc(size)); } template -inline void copy_to_device(T *dptr, const T *hptr, const size_t size) { - std::memcpy(dptr, hptr, size); +inline void copy_to_device(T* dptr, const T* hptr, const size_t size) +{ + std::memcpy(dptr, hptr, size); } template -inline T *push_to_device(const T *hptr, const size_t size) { - T *dptr = allocate_on_device(size); - std::memcpy(dptr, hptr, size); - return dptr; +inline T* push_to_device(const T* hptr, const size_t size) +{ + T* dptr = allocate_on_device(size); + std::memcpy(dptr, hptr, size); + return dptr; } template -inline void pull_from_device(T *hptr, T *dptr, const size_t size) { - std::memcpy(hptr, dptr, size); +inline void pull_from_device(T* hptr, T* dptr, const size_t size) +{ + std::memcpy(hptr, dptr, size); } -template inline void deallocate_device(T **dptr) { - std::free(*dptr); - *dptr = nullptr; +template +inline void deallocate_device(T** dptr) +{ + std::free(*dptr); + *dptr = nullptr; } template -inline void memset_on_device(T *dptr, T val, const size_t sz) { - std::memset(dptr, val, sz); +inline void memset_on_device(T* dptr, T val, const size_t sz) +{ + std::memset(dptr, val, sz); } } // namespace gpu diff --git a/src/tioga_triBox.C b/src/tioga_triBox.C index 6ea9eb1..0b03962 100644 --- a/src/tioga_triBox.C +++ b/src/tioga_triBox.C @@ -17,18 +17,22 @@ /* Copyright 2020 Tomas Akenine-Möller -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and -to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial -portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS -OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT -OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include @@ -38,162 +42,205 @@ OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE #define Y 1 #define Z 2 -#define CROSS(dest,v1,v2) \ - dest[0]=v1[1]*v2[2]-v1[2]*v2[1]; \ - dest[1]=v1[2]*v2[0]-v1[0]*v2[2]; \ - dest[2]=v1[0]*v2[1]-v1[1]*v2[0]; - -#define DOT(v1,v2) (v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2]) - -#define SUB(dest,v1,v2) \ - dest[0]=v1[0]-v2[0]; \ - dest[1]=v1[1]-v2[1]; \ - dest[2]=v1[2]-v2[2]; - -#define FINDMINMAX(x0,x1,x2,min,max) \ - min = max = x0; \ - if(x1max) max=x1;\ - if(x2max) max=x2; - -int planeBoxOverlap(double normal[3], double vert[3], double maxbox[3]){ - double vmin[3],vmax[3]; - double v; - int q; - - for(q=X;q<=Z;q++){ - v=vert[q]; - - if(normal[q]>0.0){ - vmin[q]=-maxbox[q] - v; - vmax[q]= maxbox[q] - v; - }else{ - vmin[q]= maxbox[q] - v; - vmax[q]=-maxbox[q] - v; +#define CROSS(dest, v1, v2) \ + dest[0] = v1[1] * v2[2] - v1[2] * v2[1]; \ + dest[1] = v1[2] * v2[0] - v1[0] * v2[2]; \ + dest[2] = v1[0] * v2[1] - v1[1] * v2[0]; + +#define DOT(v1, v2) (v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]) + +#define SUB(dest, v1, v2) \ + dest[0] = v1[0] - v2[0]; \ + dest[1] = v1[1] - v2[1]; \ + dest[2] = v1[2] - v2[2]; + +#define FINDMINMAX(x0, x1, x2, min, max) \ + min = max = x0; \ + if (x1 < min) min = x1; \ + if (x1 > max) max = x1; \ + if (x2 < min) min = x2; \ + if (x2 > max) max = x2; + +int planeBoxOverlap(double normal[3], double vert[3], double maxbox[3]) +{ + double vmin[3], vmax[3]; + double v; + int q; + + for (q = X; q <= Z; q++) { + v = vert[q]; + + if (normal[q] > 0.0) { + vmin[q] = -maxbox[q] - v; + vmax[q] = maxbox[q] - v; + } else { + vmin[q] = maxbox[q] - v; + vmax[q] = -maxbox[q] - v; + } } - } - if(DOT(normal,vmin)> 0.0) return 0; - if(DOT(normal,vmax)>=0.0) return 1; - return 0; + if (DOT(normal, vmin) > 0.0) return 0; + if (DOT(normal, vmax) >= 0.0) return 1; + return 0; } /*======================== X-tests ========================*/ -#define AXISTEST_X01(a, b, fa, fb) \ - p0 = a*v0[Y] - b*v0[Z]; \ - p2 = a*v2[Y] - b*v2[Z]; \ - if(p0rad || max<-rad) return 0; - -#define AXISTEST_X2(a, b, fa, fb) \ - p0 = a*v0[Y] - b*v0[Z]; \ - p1 = a*v1[Y] - b*v1[Z]; \ - if(p0rad || max<-rad) return 0; +#define AXISTEST_X01(a, b, fa, fb) \ + p0 = a * v0[Y] - b * v0[Z]; \ + p2 = a * v2[Y] - b * v2[Z]; \ + if (p0 < p2) { \ + min = p0; \ + max = p2; \ + } else { \ + min = p2; \ + max = p0; \ + } \ + rad = fa * boxhalfsize[Y] + fb * boxhalfsize[Z]; \ + if (min > rad || max < -rad) return 0; + +#define AXISTEST_X2(a, b, fa, fb) \ + p0 = a * v0[Y] - b * v0[Z]; \ + p1 = a * v1[Y] - b * v1[Z]; \ + if (p0 < p1) { \ + min = p0; \ + max = p1; \ + } else { \ + min = p1; \ + max = p0; \ + } \ + rad = fa * boxhalfsize[Y] + fb * boxhalfsize[Z]; \ + if (min > rad || max < -rad) return 0; /*======================== Y-tests ========================*/ -#define AXISTEST_Y02(a, b, fa, fb) \ - p0 = -a*v0[X] + b*v0[Z]; \ - p2 = -a*v2[X] + b*v2[Z]; \ - if(p0rad || max<-rad) return 0; - -#define AXISTEST_Y1(a, b, fa, fb) \ - p0 = -a*v0[X] + b*v0[Z]; \ - p1 = -a*v1[X] + b*v1[Z]; \ - if(p0rad || max<-rad) return 0; +#define AXISTEST_Y02(a, b, fa, fb) \ + p0 = -a * v0[X] + b * v0[Z]; \ + p2 = -a * v2[X] + b * v2[Z]; \ + if (p0 < p2) { \ + min = p0; \ + max = p2; \ + } else { \ + min = p2; \ + max = p0; \ + } \ + rad = fa * boxhalfsize[X] + fb * boxhalfsize[Z]; \ + if (min > rad || max < -rad) return 0; + +#define AXISTEST_Y1(a, b, fa, fb) \ + p0 = -a * v0[X] + b * v0[Z]; \ + p1 = -a * v1[X] + b * v1[Z]; \ + if (p0 < p1) { \ + min = p0; \ + max = p1; \ + } else { \ + min = p1; \ + max = p0; \ + } \ + rad = fa * boxhalfsize[X] + fb * boxhalfsize[Z]; \ + if (min > rad || max < -rad) return 0; /*======================== Z-tests ========================*/ -#define AXISTEST_Z12(a, b, fa, fb) \ - p1 = a*v1[X] - b*v1[Y]; \ - p2 = a*v2[X] - b*v2[Y]; \ - if(p2rad || max<-rad) return 0; - -#define AXISTEST_Z0(a, b, fa, fb) \ - p0 = a*v0[X] - b*v0[Y]; \ - p1 = a*v1[X] - b*v1[Y]; \ - if(p0rad || max<-rad) return 0; - - -int triBoxOverlap(double boxcenter[3],double boxhalfsize[3], - double *pt1,double *pt2,double *pt3){ - /* use separating axis theorem to test overlap between triangle and box */ - /* need to test for overlap in these directions: */ - /* 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle */ - /* we do not even need to test these) */ - /* 2) normal of the triangle */ - /* 3) crossproduct(edge from tri, {x,y,z}-direction) */ - /* this gives 3x3=9 more tests */ - double v0[3],v1[3],v2[3]; - double min,max,p0,p1,p2,rad,fex,fey,fez; - double normal[3],e0[3],e1[3],e2[3]; - - /* move everything so that the boxcenter is in (0,0,0) */ - SUB(v0,pt1,boxcenter); - SUB(v1,pt2,boxcenter); - SUB(v2,pt3,boxcenter); - - /* compute triangle edges */ - SUB(e0,v1,v0); /* tri edge 0 */ - SUB(e1,v2,v1); /* tri edge 1 */ - SUB(e2,v0,v2); /* tri edge 2 */ - - /* Bullet 3: */ - /* test the 9 tests first (this was faster) */ - fex = fabs(e0[X]); - fey = fabs(e0[Y]); - fez = fabs(e0[Z]); - AXISTEST_X01(e0[Z], e0[Y], fez, fey); - AXISTEST_Y02(e0[Z], e0[X], fez, fex); - AXISTEST_Z12(e0[Y], e0[X], fey, fex); - - fex = fabs(e1[X]); - fey = fabs(e1[Y]); - fez = fabs(e1[Z]); - AXISTEST_X01(e1[Z], e1[Y], fez, fey); - AXISTEST_Y02(e1[Z], e1[X], fez, fex); - AXISTEST_Z0(e1[Y], e1[X], fey, fex); - - fex = fabs(e2[X]); - fey = fabs(e2[Y]); - fez = fabs(e2[Z]); - AXISTEST_X2(e2[Z], e2[Y], fez, fey); - AXISTEST_Y1(e2[Z], e2[X], fez, fex); - AXISTEST_Z12(e2[Y], e2[X], fey, fex); - - /* Bullet 1: */ - /* first test overlap in the {x,y,z}-directions */ - /* find min, max of the triangle each direction, and test for overlap in */ - /* that direction -- this is equivalent to testing a minimal AABB around */ - /* the triangle against the AABB */ - - /* test in X-direction */ - FINDMINMAX(v0[X],v1[X],v2[X],min,max); - if(min>boxhalfsize[X] || max<-boxhalfsize[X]) return 0; - - /* test in Y-direction */ - FINDMINMAX(v0[Y],v1[Y],v2[Y],min,max); - if(min>boxhalfsize[Y] || max<-boxhalfsize[Y]) return 0; - - /* test in Z-direction */ - FINDMINMAX(v0[Z],v1[Z],v2[Z],min,max); - if(min>boxhalfsize[Z] || max<-boxhalfsize[Z]) return 0; - - /* Bullet 2: */ - /* test if the box intersects the plane of the triangle */ - /* compute plane equation of triangle: normal*x+d=0 */ - CROSS(normal,e0,e1); - - if(!planeBoxOverlap(normal,v0,boxhalfsize)) return 0; - return 1; /* box and triangle overlaps */ +#define AXISTEST_Z12(a, b, fa, fb) \ + p1 = a * v1[X] - b * v1[Y]; \ + p2 = a * v2[X] - b * v2[Y]; \ + if (p2 < p1) { \ + min = p2; \ + max = p1; \ + } else { \ + min = p1; \ + max = p2; \ + } \ + rad = fa * boxhalfsize[X] + fb * boxhalfsize[Y]; \ + if (min > rad || max < -rad) return 0; + +#define AXISTEST_Z0(a, b, fa, fb) \ + p0 = a * v0[X] - b * v0[Y]; \ + p1 = a * v1[X] - b * v1[Y]; \ + if (p0 < p1) { \ + min = p0; \ + max = p1; \ + } else { \ + min = p1; \ + max = p0; \ + } \ + rad = fa * boxhalfsize[X] + fb * boxhalfsize[Y]; \ + if (min > rad || max < -rad) return 0; + +int triBoxOverlap( + double boxcenter[3], + double boxhalfsize[3], + double* pt1, + double* pt2, + double* pt3) +{ + /* use separating axis theorem to test overlap between triangle and box + */ + /* need to test for overlap in these directions: */ + /* 1) the {x,y,z}-directions (actually, since we use the AABB of the + * triangle */ + /* we do not even need to test these) */ + /* 2) normal of the triangle */ + /* 3) crossproduct(edge from tri, {x,y,z}-direction) */ + /* this gives 3x3=9 more tests */ + double v0[3], v1[3], v2[3]; + double min, max, p0, p1, p2, rad, fex, fey, fez; + double normal[3], e0[3], e1[3], e2[3]; + + /* move everything so that the boxcenter is in (0,0,0) */ + SUB(v0, pt1, boxcenter); + SUB(v1, pt2, boxcenter); + SUB(v2, pt3, boxcenter); + + /* compute triangle edges */ + SUB(e0, v1, v0); /* tri edge 0 */ + SUB(e1, v2, v1); /* tri edge 1 */ + SUB(e2, v0, v2); /* tri edge 2 */ + + /* Bullet 3: */ + /* test the 9 tests first (this was faster) */ + fex = fabs(e0[X]); + fey = fabs(e0[Y]); + fez = fabs(e0[Z]); + AXISTEST_X01(e0[Z], e0[Y], fez, fey); + AXISTEST_Y02(e0[Z], e0[X], fez, fex); + AXISTEST_Z12(e0[Y], e0[X], fey, fex); + + fex = fabs(e1[X]); + fey = fabs(e1[Y]); + fez = fabs(e1[Z]); + AXISTEST_X01(e1[Z], e1[Y], fez, fey); + AXISTEST_Y02(e1[Z], e1[X], fez, fex); + AXISTEST_Z0(e1[Y], e1[X], fey, fex); + + fex = fabs(e2[X]); + fey = fabs(e2[Y]); + fez = fabs(e2[Z]); + AXISTEST_X2(e2[Z], e2[Y], fez, fey); + AXISTEST_Y1(e2[Z], e2[X], fez, fex); + AXISTEST_Z12(e2[Y], e2[X], fey, fex); + + /* Bullet 1: */ + /* first test overlap in the {x,y,z}-directions */ + /* find min, max of the triangle each direction, and test for overlap in */ + /* that direction -- this is equivalent to testing a minimal AABB around */ + /* the triangle against the AABB */ + + /* test in X-direction */ + FINDMINMAX(v0[X], v1[X], v2[X], min, max); + if (min > boxhalfsize[X] || max < -boxhalfsize[X]) return 0; + + /* test in Y-direction */ + FINDMINMAX(v0[Y], v1[Y], v2[Y], min, max); + if (min > boxhalfsize[Y] || max < -boxhalfsize[Y]) return 0; + + /* test in Z-direction */ + FINDMINMAX(v0[Z], v1[Z], v2[Z], min, max); + if (min > boxhalfsize[Z] || max < -boxhalfsize[Z]) return 0; + + /* Bullet 2: */ + /* test if the box intersects the plane of the triangle */ + /* compute plane equation of triangle: normal*x+d=0 */ + CROSS(normal, e0, e1); + + if (!planeBoxOverlap(normal, v0, boxhalfsize)) return 0; + return 1; /* box and triangle overlaps */ } \ No newline at end of file diff --git a/src/tioga_utils.C b/src/tioga_utils.C index 974f2e2..e3ae89f 100644 --- a/src/tioga_utils.C +++ b/src/tioga_utils.C @@ -15,234 +15,225 @@ /* You should have received a copy of the GNU Lesser General Public */ /* License along with this library; if not, write to the Free Software */ -/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ #include "codetypes.h" #include "tioga_utils.h" #include "kaiser.h" /*** ** find oriented bounding box for a given set of points -*/ -void findOBB(double *x,double xc[3],double dxc[3],double vec[3][3],int nnodes) + */ +void findOBB( + double* x, double xc[3], double dxc[3], double vec[3][3], int nnodes) { - int i,j,k,m,i3; - double aa[9]; - double eigenv[3]; - double trace,sume; - double xd[3]; - double xmin[3],xmax[3]; - int nrows,ncols; - // - xc[0]=xc[1]=xc[2]=0; - // - // find centroid coordinates (not true centroid) - // - for(i=0;i nx[i]-1) return 0; + int i; + int mm; + double dx[3]; + int ix[3]; + + for (i = 0; i < 3; i++) dx[i] = (extents[i + 3] - extents[i]) / nx[i]; + for (i = 0; i < 3; i++) { + ix[i] = (x[i] - extents[i]) / dx[i]; + if (ix[i] < 0 || ix[i] > nx[i] - 1) return 0; } - mm=ix[2]*nx[1]*nx[0]+ix[1]*nx[0]+ix[0]; - return sam[mm]; + mm = ix[2] * nx[1] * nx[0] + ix[1] * nx[0] + ix[0]; + return sam[mm]; } -int search_octant(double *xpt,double ds[3],ADAPTIVE_HOLEMAP *AHM, - octant_t *parent,int level_id){ - double dx[3]; - double xlo[3]; - uint32_t cidx; - int e; - - const qcoord_t levelh = OCTANT_LEN(level_id); - - // compute octant lengths - dx[0] = ds[0]*INT2DBL*levelh; - dx[1] = ds[1]*INT2DBL*levelh; - dx[2] = ds[2]*INT2DBL*levelh; - - // compute physical coordinates - xlo[0] = AHM->meta.extents_lo[0] + ds[0]*INT2DBL*parent->x; - xlo[1] = AHM->meta.extents_lo[1] + ds[1]*INT2DBL*parent->y; - xlo[2] = AHM->meta.extents_lo[2] + ds[2]*INT2DBL*parent->z; - - /* check intersection with box around each point */ - const double TOL2 = 0.0; - if(xpt[0] < xlo[0]+TOL2) return OUTSIDE_SB; - if(xpt[0] > xlo[0]+dx[0]-TOL2) return OUTSIDE_SB; - if(xpt[1] < xlo[1]+TOL2) return OUTSIDE_SB; - if(xpt[1] > xlo[1]+dx[1]-TOL2) return OUTSIDE_SB; - if(xpt[2] < xlo[2]+TOL2) return OUTSIDE_SB; - if(xpt[2] > xlo[2]+dx[2]-TOL2) return OUTSIDE_SB; - - // point exists inside this octant: need to check if leaf or parent - // check if parent is refined: [yes] search children, [no] return filltype - - if(parent->leafflag == 0){ - level_t *nextLevel = &(AHM->levels[level_id+1]); - - /* Search children for filltype: - * Stop at first non-zero value since a point - * may exist in at most one leaf octant. - * - * Note: we set up the filltype to have any value > 0 (OUTSIDE_SB) - * be an INSIDE_SB point or a possible WALL_SB. - */ - int value = OUTSIDE_SB; - for(e=0; echildren[e]; - value = search_octant(xpt,ds,AHM,&(nextLevel->octants[cidx]),level_id+1); +int search_octant( + double* xpt, + double ds[3], + ADAPTIVE_HOLEMAP* AHM, + octant_t* parent, + int level_id) +{ + double dx[3]; + double xlo[3]; + uint32_t cidx; + int e; + + const qcoord_t levelh = OCTANT_LEN(level_id); + + // compute octant lengths + dx[0] = ds[0] * INT2DBL * levelh; + dx[1] = ds[1] * INT2DBL * levelh; + dx[2] = ds[2] * INT2DBL * levelh; + + // compute physical coordinates + xlo[0] = AHM->meta.extents_lo[0] + ds[0] * INT2DBL * parent->x; + xlo[1] = AHM->meta.extents_lo[1] + ds[1] * INT2DBL * parent->y; + xlo[2] = AHM->meta.extents_lo[2] + ds[2] * INT2DBL * parent->z; + + /* check intersection with box around each point */ + const double TOL2 = 0.0; + if (xpt[0] < xlo[0] + TOL2) return OUTSIDE_SB; + if (xpt[0] > xlo[0] + dx[0] - TOL2) return OUTSIDE_SB; + if (xpt[1] < xlo[1] + TOL2) return OUTSIDE_SB; + if (xpt[1] > xlo[1] + dx[1] - TOL2) return OUTSIDE_SB; + if (xpt[2] < xlo[2] + TOL2) return OUTSIDE_SB; + if (xpt[2] > xlo[2] + dx[2] - TOL2) return OUTSIDE_SB; + + // point exists inside this octant: need to check if leaf or parent + // check if parent is refined: [yes] search children, [no] return filltype + + if (parent->leafflag == 0) { + level_t* nextLevel = &(AHM->levels[level_id + 1]); + + /* Search children for filltype: + * Stop at first non-zero value since a point + * may exist in at most one leaf octant. + * + * Note: we set up the filltype to have any value > 0 (OUTSIDE_SB) + * be an INSIDE_SB point or a possible WALL_SB. + */ + int value = OUTSIDE_SB; + for (e = 0; e < OCTANT_CHILDREN && value == OUTSIDE_SB; e++) { + cidx = parent->children[e]; + value = search_octant( + xpt, ds, AHM, &(nextLevel->octants[cidx]), level_id + 1); + } + return value; } - return value; - } - // found point in octant which is a leaf: return fill type - return parent->filltype; + // found point in octant which is a leaf: return fill type + return parent->filltype; } -int checkAdaptiveHoleMap(double *xpt,ADAPTIVE_HOLEMAP *AHM){ - double ds[3]; +int checkAdaptiveHoleMap(double* xpt, ADAPTIVE_HOLEMAP* AHM) +{ + double ds[3]; - // get octant physical lengths - ds[0] = AHM->meta.extents_hi[0] - AHM->meta.extents_lo[0]; - ds[1] = AHM->meta.extents_hi[1] - AHM->meta.extents_lo[1]; - ds[2] = AHM->meta.extents_hi[2] - AHM->meta.extents_lo[2]; + // get octant physical lengths + ds[0] = AHM->meta.extents_hi[0] - AHM->meta.extents_lo[0]; + ds[1] = AHM->meta.extents_hi[1] - AHM->meta.extents_lo[1]; + ds[2] = AHM->meta.extents_hi[2] - AHM->meta.extents_lo[2]; - // recursively search from root octant - octant_t *root = &(AHM->levels[0].octants[0]); - return search_octant(xpt,ds,AHM,root,0); + // recursively search from root octant + octant_t* root = &(AHM->levels[0].octants[0]); + return search_octant(xpt, ds, AHM, root, 0); } /** @@ -250,841 +241,888 @@ int checkAdaptiveHoleMap(double *xpt,ADAPTIVE_HOLEMAP *AHM){ flood fill from outside the marked boundary. boundary is marked by "2" */ -void fillHoleMap(int *holeMap, int ix[3],int isym) +void fillHoleMap(int* holeMap, int ix[3], int isym) { - int m; - int ii,jj,kk,mm; - int ns2; - int i,j,k; - int ipaint,npaint,nneig; - int mk[6]; - // - // now start from outside and paint the - // the exterior - // - ns2=ix[0]*ix[1]; - // - for(kk=0;kk 0) - { - npaint=0; - for(k=1;k 0) - { - holeMap[m]=1; - npaint++; + int m; + int ii, jj, kk, mm; + int ns2; + int i, j, k; + int ipaint, npaint, nneig; + int mk[6]; + // + // now start from outside and paint the + // the exterior + // + ns2 = ix[0] * ix[1]; + // + for (kk = 0; kk < ix[2]; kk += (ix[2] - 1)) + for (jj = 0; jj < ix[1]; jj++) + for (ii = 0; ii < ix[0]; ii++) { + mm = kk * ns2 + jj * ix[0] + ii; + holeMap[mm] = 1; + } + for (kk = 0; kk < ix[2]; kk++) + for (jj = 0; jj < ix[1]; jj += (ix[1] - 1)) + for (ii = 0; ii < ix[0]; ii++) { + mm = kk * ns2 + jj * ix[0] + ii; + holeMap[mm] = 1; + } + for (kk = 0; kk < ix[2]; kk++) + for (jj = 0; jj < ix[1]; jj++) + for (ii = 0; ii < ix[0]; ii += (ix[0] - 1)) { + mm = kk * ns2 + jj * ix[0] + ii; + holeMap[mm] = 1; + } + npaint = ns2 * ix[2]; + while (npaint > 0) { + npaint = 0; + for (k = 1; k < ix[2] - 1; k++) + for (j = 1; j < ix[1] - 1; j++) + for (i = 1; i < ix[0] - 1; i++) { + m = k * ns2 + j * ix[0] + i; + if (holeMap[m] == 0) { + ipaint = 0; + if (isym == 1) { + mk[0] = m - ns2; + mk[1] = m + ns2; + mk[2] = m - ix[0]; + mk[3] = m + ix[0]; + mk[4] = m - 1; + mk[5] = m + 1; + nneig = 4; + } else if (isym == 2) { + mk[0] = m - ns2; + mk[1] = m + ns2; + mk[4] = m - ix[0]; + mk[5] = m + ix[0]; + mk[2] = m - 1; + mk[3] = m + 1; + nneig = 4; + } else if (isym == 3) { + mk[4] = m - ns2; + mk[5] = m + ns2; + mk[0] = m - ix[0]; + mk[1] = m + ix[0]; + mk[2] = m - 1; + mk[3] = m + 1; + nneig = 4; + } else { + mk[0] = m - ns2; + mk[1] = m + ns2; + mk[2] = m - ix[0]; + mk[3] = m + ix[0]; + mk[4] = m - 1; + mk[5] = m + 1; + nneig = 6; + } + for (kk = 0; kk < nneig && ipaint == 0; kk++) { + ipaint = (ipaint || holeMap[mk[kk]] == 1); + } + if (ipaint > 0) { + holeMap[m] = 1; + npaint++; + } } } - } } - for(i=0;i (r0+r1+eps)) return 0; + int iflag; + int i, j, k; + int i1, i2, j1, j2; + double r, r0, r1; + double d1, d2; + double eps = 1e-12; + double D[3]; + double c[3][3]; + // + // D=distance between centers + // C=scalar product of axes + // + for (i = 0; i < 3; i++) D[i] = xB[i] - xA[i]; + for (i = 0; i < 3; i++) + for (j = 0; j < 3; j++) { + c[i][j] = 0; + for (k = 0; k < 3; k++) c[i][j] = c[i][j] + vA[i][k] * vB[j][k]; + } + // + // separating axes based on the faces of box A + // + for (i = 0; i < 3; i++) { + r0 = dxA[i]; + r1 = 0; + r = 0; + for (j = 0; j < 3; j++) { + r1 += dxB[j] * fabs(c[i][j]); + r += fabs(vA[i][j]) * D[j]; + } + if (r > (r0 + r1 + eps)) return 0; } - // - // separating axes based on the faces of box B - // - for(i=0;i<3;i++) - { - r1=dxB[i]; - r0=0; - r=0; - for(j=0;j<3;j++) - { - r0+=dxA[j]*fabs(c[j][i]); - r+=fabs(vB[i][j])*D[j]; - } - if (r > (r0+r1+eps)) return 0; + // + // separating axes based on the faces of box B + // + for (i = 0; i < 3; i++) { + r1 = dxB[i]; + r0 = 0; + r = 0; + for (j = 0; j < 3; j++) { + r0 += dxA[j] * fabs(c[j][i]); + r += fabs(vB[i][j]) * D[j]; + } + if (r > (r0 + r1 + eps)) return 0; } - // - // cross products - // - for(i=0;i<3;i++) - { - i1=(i+1)%3; - i2=(i+2)%3; - for(j=0;j<3;j++) - { - j1=(j+1)%3; - j2=(j+2)%3; - - r0=dxA[i1]*fabs(c[i2][j])+dxA[i2]*fabs(c[i1][j]); - r1=dxB[j1]*fabs(c[i][j2])+dxB[j2]*fabs(c[i][j1]); - - d2=0; - d1=0; - for(k=0;k<3;k++) - { - d2+=vA[i2][k]*D[k]; - d1+=vA[i1][k]*D[k]; - } - - r=fabs(c[i1][j]*d2-c[i2][j]*d1); - - if (r > (r0+r1+eps)) { - return 0; - } - } + // + // cross products + // + for (i = 0; i < 3; i++) { + i1 = (i + 1) % 3; + i2 = (i + 2) % 3; + for (j = 0; j < 3; j++) { + j1 = (j + 1) % 3; + j2 = (j + 2) % 3; + + r0 = dxA[i1] * fabs(c[i2][j]) + dxA[i2] * fabs(c[i1][j]); + r1 = dxB[j1] * fabs(c[i][j2]) + dxB[j2] * fabs(c[i][j1]); + + d2 = 0; + d1 = 0; + for (k = 0; k < 3; k++) { + d2 += vA[i2][k] * D[k]; + d1 += vA[i1][k] * D[k]; + } + + r = fabs(c[i1][j] * d2 - c[i2][j] * d1); + + if (r > (r0 + r1 + eps)) { + return 0; + } + } } - // - // return zero if no separation can be found - // - return 1; + // + // return zero if no separation can be found + // + return 1; } -void getobbcoords(double xc[3],double dxc[3],double vec[3][3],double xv[8][3]) +void getobbcoords( + double xc[3], double dxc[3], double vec[3][3], double xv[8][3]) { - int i,j,k,ik; - for(i=0;i<8;i++) - { - for(k=0;k<3;k++) - xv[i][k]=xc[k]; - for(k=0;k<3;k++) - { - ik=(2*((i & (1 << k)) >> k)-1); - for(j=0;j<3;j++) - xv[i][j]+=ik*dxc[k]*vec[k][j]; - } - } + int i, j, k, ik; + for (i = 0; i < 8; i++) { + for (k = 0; k < 3; k++) xv[i][k] = xc[k]; + for (k = 0; k < 3; k++) { + ik = (2 * ((i & (1 << k)) >> k) - 1); + for (j = 0; j < 3; j++) xv[i][j] += ik * dxc[k] * vec[k][j]; + } + } } -void transform2OBB(double xv[3],double xc[3],double vec[3][3],double xd[3]) +void transform2OBB(double xv[3], double xc[3], double vec[3][3], double xd[3]) { - int j,k; - for(j=0;j<3;j++) - { - xd[j]=0; - for(k=0;k<3;k++) - xd[j]+=(xv[k]-xc[k])*vec[j][k]; - } + int j, k; + for (j = 0; j < 3; j++) { + xd[j] = 0; + for (k = 0; k < 3; k++) xd[j] += (xv[k] - xc[k]) * vec[j][k]; + } } - -void writebbox(OBB *obb,int bid) +void writebbox(OBB* obb, int bid) { - FILE *fp; - char intstring[12]; - char fname[80]; - int l,k,j,m,il,ik,ij; - REAL xx[3]; - - sprintf(intstring,"%d",100000+bid); - sprintf(fname,"qbox%s.dat",&(intstring[1])); - fp=fopen(fname,"w"); - fprintf(fp,"TITLE =\"Box file\"\n"); - fprintf(fp,"VARIABLES=\"X\",\"Y\",\"Z\"\n"); - fprintf(fp,"ZONE T=\"VOL_MIXED\",N=%d E=%d ET=BRICK, F=FEPOINT\n",8, - 1); - - for(l=0;l<2;l++) - { - il=2*(l%2)-1; - for(k=0;k<2;k++) - { - ik=2*(k%2)-1; - for(j=0;j<2;j++) - { - ij=2*(j%2)-1; - xx[0]=xx[1]=xx[2]=0; - for(m=0;m<3;m++) - xx[m]=obb->xc[m]+ij*obb->vec[0][m]*obb->dxc[0] - +ik*obb->vec[1][m]*obb->dxc[1] - +il*obb->vec[2][m]*obb->dxc[2]; - fprintf(fp,"%f %f %f\n",xx[0],xx[1],xx[2]); - } - } + FILE* fp; + char intstring[12]; + char fname[80]; + int l, k, j, m, il, ik, ij; + REAL xx[3]; + + snprintf(intstring, sizeof(intstring), "%d", 100000 + bid); + snprintf(fname, sizeof(fname), "qbox%s.dat", &(intstring[1])); + fp = fopen(fname, "w"); + fprintf(fp, "TITLE =\"Box file\"\n"); + fprintf(fp, "VARIABLES=\"X\",\"Y\",\"Z\"\n"); + fprintf(fp, "ZONE T=\"VOL_MIXED\",N=%d E=%d ET=BRICK, F=FEPOINT\n", 8, 1); + + for (l = 0; l < 2; l++) { + il = 2 * (l % 2) - 1; + for (k = 0; k < 2; k++) { + ik = 2 * (k % 2) - 1; + for (j = 0; j < 2; j++) { + ij = 2 * (j % 2) - 1; + xx[0] = xx[1] = xx[2] = 0; + for (m = 0; m < 3; m++) + xx[m] = obb->xc[m] + ij * obb->vec[0][m] * obb->dxc[0] + + ik * obb->vec[1][m] * obb->dxc[1] + + il * obb->vec[2][m] * obb->dxc[2]; + fprintf(fp, "%f %f %f\n", xx[0], xx[1], xx[2]); + } + } } - fprintf(fp,"1 2 4 3 5 6 8 7\n"); - fclose(fp); + fprintf(fp, "1 2 4 3 5 6 8 7\n"); + fclose(fp); } -void writebboxdiv(OBB *obb,int bid) +void writebboxdiv(OBB* obb, int bid) { - double mapdx[3],mdx[3],mx0[3]; - double mapdims[3]; - int ncells,npts; - double xv[8][3],xc[3],xd[3]; - int i,j,k,l,m,n; - int iorder[8]={1, 2, 4, 3, 5, 6, 8, 7}; - FILE *fp; - char intstring[12]; - char fname[80]; - - for(j=0;j<3;j++) { mapdims[j]=12; mapdx[j]=2*obb->dxc[j]/mapdims[j]; mdx[j]=0.5*mapdx[j];mx0[j]=0;} - ncells=mapdims[2]*mapdims[1]*mapdims[0]; - npts=ncells*8; - sprintf(intstring,"%d",100000+bid); - sprintf(fname,"dbox%s.dat",&(intstring[1])); - fp=fopen(fname,"w"); - fprintf(fp,"TITLE =\"Box file\"\n"); - fprintf(fp,"VARIABLES=\"X\",\"Y\",\"Z\"\n"); - fprintf(fp,"ZONE T=\"VOL_MIXED\",N=%d E=%d ET=BRICK, F=FEPOINT\n",npts,ncells); - - getobbcoords(mx0,mdx,obb->vec,xv); - for(l=0;ldxc[0]+j*mapdx[0]+mapdx[0]*0.5; - xd[1]=-obb->dxc[1]+k*mapdx[1]+mapdx[1]*0.5; - xd[2]=-obb->dxc[2]+l*mapdx[2]+mapdx[2]*0.5; - for(n=0;n<3;n++) - { - xc[n]=obb->xc[n]; - for(m=0;m<3;m++) - xc[n]+=(xd[m]*obb->vec[m][n]); + double mapdx[3], mdx[3], mx0[3]; + double mapdims[3]; + int ncells, npts; + double xv[8][3], xc[3], xd[3]; + int i, j, k, l, m, n; + int iorder[8] = {1, 2, 4, 3, 5, 6, 8, 7}; + FILE* fp; + char intstring[12]; + char fname[80]; + + for (j = 0; j < 3; j++) { + mapdims[j] = 12; + mapdx[j] = 2 * obb->dxc[j] / mapdims[j]; + mdx[j] = 0.5 * mapdx[j]; + mx0[j] = 0; + } + ncells = mapdims[2] * mapdims[1] * mapdims[0]; + npts = ncells * 8; + snprintf(intstring, sizeof(intstring), "%d", 100000 + bid); + snprintf(fname, sizeof(fname), "dbox%s.dat", &(intstring[1])); + fp = fopen(fname, "w"); + fprintf(fp, "TITLE =\"Box file\"\n"); + fprintf(fp, "VARIABLES=\"X\",\"Y\",\"Z\"\n"); + fprintf( + fp, "ZONE T=\"VOL_MIXED\",N=%d E=%d ET=BRICK, F=FEPOINT\n", npts, + ncells); + + getobbcoords(mx0, mdx, obb->vec, xv); + for (l = 0; l < mapdims[2]; l++) + for (k = 0; k < mapdims[1]; k++) + for (j = 0; j < mapdims[0]; j++) { + xd[0] = -obb->dxc[0] + j * mapdx[0] + mapdx[0] * 0.5; + xd[1] = -obb->dxc[1] + k * mapdx[1] + mapdx[1] * 0.5; + xd[2] = -obb->dxc[2] + l * mapdx[2] + mapdx[2] * 0.5; + for (n = 0; n < 3; n++) { + xc[n] = obb->xc[n]; + for (m = 0; m < 3; m++) xc[n] += (xd[m] * obb->vec[m][n]); + } + for (m = 0; m < 8; m++) + fprintf( + fp, "%f %f %f\n", xc[0] + xv[m][0], xc[1] + xv[m][1], + xc[2] + xv[m][2]); } - for(m=0;m<8;m++) - fprintf(fp,"%f %f %f\n",xc[0]+xv[m][0],xc[1]+xv[m][1],xc[2]+xv[m][2]); - } - for(l=0;l(NSUB)); - jmax=std::max(jmax,1); - dsx=(xmax[0]-xmin[0]+TOL)/jmax; - dsxi=1./dsx; - kmax=std::min(round((xmax[1]-xmin[1])*dsi),static_cast(NSUB)); - kmax=std::max(kmax,1); - dsy=(xmax[1]-xmin[1]+TOL)/kmax; - dsyi=1./dsy; - lmax=std::min(round((xmax[2]-xmin[2])*dsi),static_cast(NSUB)); - lmax=std::max(lmax,1); - dsz=(xmax[2]-xmin[2]+TOL)/lmax; - dszi=1./dsz; - nsblks=jmax*kmax*lmax; - jkmax=jmax*kmax; - cft=(int *)malloc(sizeof(int)*(nsblks+1)); - numpts=(int *)malloc(sizeof(int)*nsblks); - ilist=(int *)malloc(sizeof(int)*nnodes); - - for(i=0;i(NSUB)); + jmax = std::max(jmax, 1); + dsx = (xmax[0] - xmin[0] + TOL) / jmax; + dsxi = 1. / dsx; + kmax = + std::min(round((xmax[1] - xmin[1]) * dsi), static_cast(NSUB)); + kmax = std::max(kmax, 1); + dsy = (xmax[1] - xmin[1] + TOL) / kmax; + dsyi = 1. / dsy; + lmax = + std::min(round((xmax[2] - xmin[2]) * dsi), static_cast(NSUB)); + lmax = std::max(lmax, 1); + dsz = (xmax[2] - xmin[2] + TOL) / lmax; + dszi = 1. / dsz; + nsblks = jmax * kmax * lmax; + jkmax = jmax * kmax; + cft = (int*)malloc(sizeof(int) * (nsblks + 1)); + numpts = (int*)malloc(sizeof(int) * nsblks); + ilist = (int*)malloc(sizeof(int) * nnodes); + + for (i = 0; i < nsblks; i++) numpts[i] = 0; + for (i = 0; i < nnodes; i++) { + i3 = 3 * i; + jj = (int)((x[i3] - xmin[0]) * dsxi); + kk = (int)((x[i3 + 1] - xmin[1]) * dsyi); + ll = (int)((x[i3 + 2] - xmin[2]) * dszi); + indx = ll * jkmax + kk * jmax + jj; + numpts[indx] = numpts[indx] + 1; } - cft[0]=0; - for(i=0;i p2) { - rtag[p2]=std::max(rtag[p1],rtag[p2]); - itag[p1]=itag[p2]; - } - else { - rtag[p1]=std::max(rtag[p1],rtag[p2]); - itag[p2]=itag[p1]; - } - } - } - } - /* - m=0; - for(i=0;i p2) { + rtag[p2] = std::max(rtag[p1], rtag[p2]); + itag[p1] = itag[p2]; + } else { + rtag[p1] = std::max(rtag[p1], rtag[p2]); + itag[p2] = itag[p1]; + } + } + } + } + /* + m=0; + for(i=0;i 20) { + int nd = ndim; + double coordmid; + int i, j, ibox; + int p1, p2; + int* tmpint; + int npts[8], iv[3], cft[9]; + double xmax[3], xmin[3], xmid[3], dx[3], xp[3]; + int icheck = 1; // - // find the bound of the boxes + // if there are more than 10 elements divide the tree // - icheck=0; - xmin[0]=xmin[1]=xmin[2]=BIGVALUE; - xmax[0]=xmax[1]=xmax[2]=-BIGVALUE; - for(i=0;i 20) { + // + // find the bound of the boxes + // + icheck = 0; + xmin[0] = xmin[1] = xmin[2] = BIGVALUE; + xmax[0] = xmax[1] = xmax[2] = -BIGVALUE; + for (i = 0; i < nav; i++) + for (j = 0; j < nd; j++) { + xmin[j] = + std::min(xmin[j], coord[ndim * elementsAvailable[i] + j]); + xmax[j] = + std::max(xmax[j], coord[ndim * elementsAvailable[i] + j]); + } + for (j = 0; j < nd; j++) { + xmid[j] = (xmax[j] + xmin[j]) * 0.5; + dx[j] = (xmax[j] - xmin[j]) * 0.5 + TOL; + } + for (j = 0; j < 8; j++) npts[j] = 0; + for (i = 0; i < nav; i++) { + for (j = 0; j < 3; j++) { + xp[j] = coord[ndim * elementsAvailable[i] + j] - xmid[j]; + iv[j] = floor(xp[j] / dx[j]) + 1; + } + ibox = 4 * iv[0] + 2 * iv[1] + iv[2]; + npts[ibox]++; + } + for (j = 0; j < 8; j++) + if (npts[j] == nav) icheck = 1; + if (!icheck) { + cft[0] = 0; + for (j = 0; j < 8; j++) cft[j + 1] = cft[j] + npts[j]; + tmpint = (int*)malloc(sizeof(int) * nav); + for (i = 0; i < nav; i++) { + for (j = 0; j < 3; j++) { + xp[j] = coord[ndim * elementsAvailable[i] + j] - xmid[j]; + iv[j] = floor(xp[j] / dx[j]) + 1; + } + ibox = 4 * iv[0] + 2 * iv[1] + iv[2]; + npts[ibox] = npts[ibox] - 1; + tmpint[npts[ibox] + cft[ibox]] = elementsAvailable[i]; + } + for (i = 0; i < nav; i++) elementsAvailable[i] = tmpint[i]; + TIOGA_FREE(tmpint); + for (j = 0; j < 8; j++) + if (cft[j + 1] > cft[j]) + uniqNodesTree( + coord, itag, rtag, meshtag, + &(elementsAvailable[cft[j]]), ndim, + cft[j + 1] - cft[j]); + } + } + if (icheck) { + for (i = 0; i < nav; i++) { + p1 = elementsAvailable[i]; + for (j = i + 1; j < nav; j++) { + p2 = elementsAvailable[j]; + if (fabs(coord[3 * p1] - coord[3 * p2]) + + fabs(coord[3 * p1 + 1] - coord[3 * p2 + 1]) + + fabs(coord[3 * p1 + 2] - coord[3 * p2 + 2]) < + TOL && + meshtag[p1] == meshtag[p2]) { + if (p1 > p2) { + rtag[p2] = std::max(rtag[p1], rtag[p2]); + itag[p1] = itag[p2]; + } else { + rtag[p1] = std::max(rtag[p1], rtag[p2]); + itag[p2] = itag[p1]; + } + } + } + } } - for(j=0;j<8;j++) npts[j]=0; - for(i=0;i cft[j]) - uniqNodesTree(coord,itag,rtag,meshtag,&(elementsAvailable[cft[j]]), - ndim,cft[j+1]-cft[j]); - } - } - if (icheck) { - for(i=0;i p2) { - rtag[p2]=std::max(rtag[p1],rtag[p2]); - itag[p1]=itag[p2]; - } - else { - rtag[p1]=std::max(rtag[p1],rtag[p2]); - itag[p2]=itag[p1]; - } - } - } - } - } } /* * Create a unique hash for list of coordinates with duplicates in * them. Find the rtag as max of all duplicate samples. itag contains * the hash to the real point */ -void uniquenodes_octree(double *x,int *meshtag,double *rtag,int *itag, - int *nn) +void uniquenodes_octree( + double* x, int* meshtag, double* rtag, int* itag, int* nn) { - int nelem=*nn; - int *elementsAvailable; - int i; - - elementsAvailable=(int *)malloc(sizeof(int)*nelem); - for(i=0;ix == 0) || (c->y == 0) || (c->z == 0) || - ((c->x + inc) == OCTANT_ROOT_LEN) || - ((c->y + inc) == OCTANT_ROOT_LEN) || - ((c->z + inc) == OCTANT_ROOT_LEN))) ? OUTSIDE_SB:INSIDE_SB; - return type; +uint8_t octant_filltype(octant_full_t* c, const qcoord_t inc) +{ + /* flood-fill octant boundaries to (OUTSIDE_SB) if touching + * the global boundary; used to initialize the flood fill process. + */ + // returns (OUTSIDE_SB) if touching an octant boundary, (INSIDE_SB) + // otherwise + uint8_t type = (((c->x == 0) || (c->y == 0) || (c->z == 0) || + ((c->x + inc) == OCTANT_ROOT_LEN) || + ((c->y + inc) == OCTANT_ROOT_LEN) || + ((c->z + inc) == OCTANT_ROOT_LEN))) + ? OUTSIDE_SB + : INSIDE_SB; + return type; } -void octant_children(uint8_t children_level,uint32_t newidx, - octant_full_t * q, - octant_full_t *c0, octant_full_t *c1, - octant_full_t *c2, octant_full_t *c3, - octant_full_t *c4, octant_full_t *c5, - octant_full_t *c6, octant_full_t *c7){ - /* FILL IN OCTANT CHILDREN DATA: - * 0. valid flag - * 1. coordinates - * 2. neighboring octants - * 3. initial fill type - */ - - const qcoord_t inc = OCTANT_LEN (children_level); - - // set parent's children octant pointers - q->children[0] = c0; - q->children[1] = c1; - q->children[2] = c2; - q->children[3] = c3; - q->children[4] = c4; - q->children[5] = c5; - q->children[6] = c6; - q->children[7] = c7; - - // set children information - // LO-LO-LO OCTANT - c0->x = q->x; - c0->y = q->y; - c0->z = q->z; - c0->id = newidx+0; - c0->filltype = octant_filltype(c0,inc); - c0->refined = 0; - - // HI-LO-LO OCTANT - c1->x = c0->x | inc; - c1->y = c0->y; - c1->z = c0->z; - c1->id = newidx+1; - c1->filltype = octant_filltype(c1,inc); - c1->refined = 0; - - // LO-HI-LO OCTANT - c2->x = c0->x; - c2->y = c0->y | inc; - c2->z = c0->z; - c2->id = newidx+2; - c2->filltype = octant_filltype(c2,inc); - c2->refined = 0; - - // HI-HI-LO OCTANT - c3->x = c1->x; - c3->y = c2->y; - c3->z = c0->z; - c3->id = newidx+3; - c3->filltype = octant_filltype(c3,inc); - c3->refined = 0; - - // LO-LO-HI OCTANT - c4->x = c0->x; - c4->y = c0->y; - c4->z = c0->z | inc; - c4->id = newidx+4; - c4->filltype = octant_filltype(c4,inc); - c4->refined = 0; - - // HI-LO-HI OCTANT - c5->x = c1->x; - c5->y = c1->y; - c5->z = c4->z; - c5->id = newidx+5; - c5->filltype = octant_filltype(c5,inc); - c5->refined = 0; - - // LO-HI-HI OCTANT - c6->x = c2->x; - c6->y = c2->y; - c6->z = c4->z; - c6->id = newidx+6; - c6->filltype = octant_filltype(c6,inc); - c6->refined = 0; - - // HI-HI-HI OCTANT - c7->x = c3->x; - c7->y = c3->y; - c7->z = c4->z; - c7->id = newidx+7; - c7->filltype = octant_filltype(c7,inc); - c7->refined = 0; +void octant_children( + uint8_t children_level, + uint32_t newidx, + octant_full_t* q, + octant_full_t* c0, + octant_full_t* c1, + octant_full_t* c2, + octant_full_t* c3, + octant_full_t* c4, + octant_full_t* c5, + octant_full_t* c6, + octant_full_t* c7) +{ + /* FILL IN OCTANT CHILDREN DATA: + * 0. valid flag + * 1. coordinates + * 2. neighboring octants + * 3. initial fill type + */ + + const qcoord_t inc = OCTANT_LEN(children_level); + + // set parent's children octant pointers + q->children[0] = c0; + q->children[1] = c1; + q->children[2] = c2; + q->children[3] = c3; + q->children[4] = c4; + q->children[5] = c5; + q->children[6] = c6; + q->children[7] = c7; + + // set children information + // LO-LO-LO OCTANT + c0->x = q->x; + c0->y = q->y; + c0->z = q->z; + c0->id = newidx + 0; + c0->filltype = octant_filltype(c0, inc); + c0->refined = 0; + + // HI-LO-LO OCTANT + c1->x = c0->x | inc; + c1->y = c0->y; + c1->z = c0->z; + c1->id = newidx + 1; + c1->filltype = octant_filltype(c1, inc); + c1->refined = 0; + + // LO-HI-LO OCTANT + c2->x = c0->x; + c2->y = c0->y | inc; + c2->z = c0->z; + c2->id = newidx + 2; + c2->filltype = octant_filltype(c2, inc); + c2->refined = 0; + + // HI-HI-LO OCTANT + c3->x = c1->x; + c3->y = c2->y; + c3->z = c0->z; + c3->id = newidx + 3; + c3->filltype = octant_filltype(c3, inc); + c3->refined = 0; + + // LO-LO-HI OCTANT + c4->x = c0->x; + c4->y = c0->y; + c4->z = c0->z | inc; + c4->id = newidx + 4; + c4->filltype = octant_filltype(c4, inc); + c4->refined = 0; + + // HI-LO-HI OCTANT + c5->x = c1->x; + c5->y = c1->y; + c5->z = c4->z; + c5->id = newidx + 5; + c5->filltype = octant_filltype(c5, inc); + c5->refined = 0; + + // LO-HI-HI OCTANT + c6->x = c2->x; + c6->y = c2->y; + c6->z = c4->z; + c6->id = newidx + 6; + c6->filltype = octant_filltype(c6, inc); + c6->refined = 0; + + // HI-HI-HI OCTANT + c7->x = c3->x; + c7->y = c3->y; + c7->z = c4->z; + c7->id = newidx + 7; + c7->filltype = octant_filltype(c7, inc); + c7->refined = 0; } -void octant_children_neighbors(const octant_full_t * q, - octant_full_t *c0, octant_full_t *c1, - octant_full_t *c2, octant_full_t *c3, - octant_full_t *c4, octant_full_t *c5, - octant_full_t *c6, octant_full_t *c7){ - // 3D OCTANTS: lexicographic order [x][y][z] - // (Drawn as 2D: 0,1,2,3 octants are zlo & 4,5,6,7 octants are zhi) - /* *-------*-------* *-------*-------* y - * | | | | | | ^ - * | 2 | 3 | | 6 | 7 | | - * | | | | | | | - * *-------*-------* *-------*-------* *-----> x - * | | | | | | \ - * | 0 | 1 | | 4 | 5 | \ - * | | | | | | \ - * *-------*-------* *-------*-------* z - */ - - /* This function assigns each child octant its neighbors. - * A neighbor may come from outside the original parent footprint, - * thus we use the parent's neighbor to determine the child's neighbor. - * In this event, we must check if the parent's neighbor exists, - * e.g. q->nhbr[XLO] might be NULL, and if it exists, check if it is refined. - * If so, the neighbor on this level will be a child of the parent's neighbor. - * Note we take advantage of short circuiting in the ternary logic check. - */ - - // OCTANT: [0] - c0->nhbr[XLO] = (q->nhbr[XLO] && q->nhbr[XLO]->refined) ? q->nhbr[XLO]->children[1]:q->nhbr[XLO]; - c0->nhbr[XHI] = c1; - c0->nhbr[YLO] = (q->nhbr[YLO] && q->nhbr[YLO]->refined) ? q->nhbr[YLO]->children[2]:q->nhbr[YLO]; - c0->nhbr[YHI] = c2; - c0->nhbr[ZLO] = (q->nhbr[ZLO] && q->nhbr[ZLO]->refined) ? q->nhbr[ZLO]->children[4]:q->nhbr[ZLO]; - c0->nhbr[ZHI] = c4; - - // OCTANT: [1] - c1->nhbr[XLO] = c0; - c1->nhbr[XHI] = (q->nhbr[XHI] && q->nhbr[XHI]->refined) ? q->nhbr[XHI]->children[0]:q->nhbr[XHI]; - c1->nhbr[YLO] = (q->nhbr[YLO] && q->nhbr[YLO]->refined) ? q->nhbr[YLO]->children[3]:q->nhbr[YLO]; - c1->nhbr[YHI] = c3; - c1->nhbr[ZLO] = (q->nhbr[ZLO] && q->nhbr[ZLO]->refined) ? q->nhbr[ZLO]->children[5]:q->nhbr[ZLO]; - c1->nhbr[ZHI] = c5; - - // OCTANT: [2] - c2->nhbr[XLO] = (q->nhbr[XLO] && q->nhbr[XLO]->refined) ? q->nhbr[XLO]->children[3]:q->nhbr[XLO]; - c2->nhbr[XHI] = c3; - c2->nhbr[YLO] = c0; - c2->nhbr[YHI] = (q->nhbr[YHI] && q->nhbr[YHI]->refined) ? q->nhbr[YHI]->children[0]:q->nhbr[YHI]; - c2->nhbr[ZLO] = (q->nhbr[ZLO] && q->nhbr[ZLO]->refined) ? q->nhbr[ZLO]->children[6]:q->nhbr[ZLO]; - c2->nhbr[ZHI] = c6; - - // OCTANT: [3] - c3->nhbr[XLO] = c2; - c3->nhbr[XHI] = (q->nhbr[XHI] && q->nhbr[XHI]->refined) ? q->nhbr[XHI]->children[2]:q->nhbr[XHI]; - c3->nhbr[YLO] = c1; - c3->nhbr[YHI] = (q->nhbr[YHI] && q->nhbr[YHI]->refined) ? q->nhbr[YHI]->children[1]:q->nhbr[YHI]; - c3->nhbr[ZLO] = (q->nhbr[ZLO] && q->nhbr[ZLO]->refined) ? q->nhbr[ZLO]->children[7]:q->nhbr[ZLO]; - c3->nhbr[ZHI] = c7; - - // OCTANT: [4] - c4->nhbr[XLO] = (q->nhbr[XLO] && q->nhbr[XLO]->refined) ? q->nhbr[XLO]->children[5]:q->nhbr[XLO]; - c4->nhbr[XHI] = c5; - c4->nhbr[YLO] = (q->nhbr[YLO] && q->nhbr[YLO]->refined) ? q->nhbr[YLO]->children[6]:q->nhbr[YLO]; - c4->nhbr[YHI] = c6; - c4->nhbr[ZLO] = c0; - c4->nhbr[ZHI] = (q->nhbr[ZHI] && q->nhbr[ZHI]->refined) ? q->nhbr[ZHI]->children[0]:q->nhbr[ZHI]; - - // OCTANT: [5] - c5->nhbr[XLO] = c4; - c5->nhbr[XHI] = (q->nhbr[XHI] && q->nhbr[XHI]->refined) ? q->nhbr[XHI]->children[4]:q->nhbr[XHI]; - c5->nhbr[YLO] = (q->nhbr[YLO] && q->nhbr[YLO]->refined) ? q->nhbr[YLO]->children[7]:q->nhbr[YLO]; - c5->nhbr[YHI] = c7; - c5->nhbr[ZLO] = c1; - c5->nhbr[ZHI] = (q->nhbr[ZHI] && q->nhbr[ZHI]->refined) ? q->nhbr[ZHI]->children[1]:q->nhbr[ZHI]; - - // OCTANT: [6] - c6->nhbr[XLO] = (q->nhbr[XLO] && q->nhbr[XLO]->refined) ? q->nhbr[XLO]->children[7]:q->nhbr[XLO]; - c6->nhbr[XHI] = c7; - c6->nhbr[YLO] = c4; - c6->nhbr[YHI] = (q->nhbr[YHI] && q->nhbr[YHI]->refined) ? q->nhbr[YHI]->children[4]:q->nhbr[YHI]; - c6->nhbr[ZLO] = c2; - c6->nhbr[ZHI] = (q->nhbr[ZHI] && q->nhbr[ZHI]->refined) ? q->nhbr[ZHI]->children[2]:q->nhbr[ZHI]; - - // OCTANT: [7] - c7->nhbr[XLO] = c6; - c7->nhbr[XHI] = (q->nhbr[XHI] && q->nhbr[XHI]->refined) ? q->nhbr[XHI]->children[6]:q->nhbr[XHI]; - c7->nhbr[YLO] = c5; - c7->nhbr[YHI] = (q->nhbr[YHI] && q->nhbr[YHI]->refined) ? q->nhbr[YHI]->children[5]:q->nhbr[YHI]; - c7->nhbr[ZLO] = c3; - c7->nhbr[ZHI] = (q->nhbr[ZHI] && q->nhbr[ZHI]->refined) ? q->nhbr[ZHI]->children[3]:q->nhbr[ZHI]; +void octant_children_neighbors( + const octant_full_t* q, + octant_full_t* c0, + octant_full_t* c1, + octant_full_t* c2, + octant_full_t* c3, + octant_full_t* c4, + octant_full_t* c5, + octant_full_t* c6, + octant_full_t* c7) +{ + // 3D OCTANTS: lexicographic order [x][y][z] + // (Drawn as 2D: 0,1,2,3 octants are zlo & 4,5,6,7 octants are zhi) + /* *-------*-------* *-------*-------* y + * | | | | | | ^ + * | 2 | 3 | | 6 | 7 | | + * | | | | | | | + * *-------*-------* *-------*-------* *-----> x + * | | | | | | \ + * | 0 | 1 | | 4 | 5 | \ + * | | | | | | \ + * *-------*-------* *-------*-------* z + */ + + /* This function assigns each child octant its neighbors. + * A neighbor may come from outside the original parent footprint, + * thus we use the parent's neighbor to determine the child's neighbor. + * In this event, we must check if the parent's neighbor exists, + * e.g. q->nhbr[XLO] might be NULL, and if it exists, check if it is + * refined. If so, the neighbor on this level will be a child of the + * parent's neighbor. Note we take advantage of short circuiting in the + * ternary logic check. + */ + + // OCTANT: [0] + c0->nhbr[XLO] = (q->nhbr[XLO] && q->nhbr[XLO]->refined) + ? q->nhbr[XLO]->children[1] + : q->nhbr[XLO]; + c0->nhbr[XHI] = c1; + c0->nhbr[YLO] = (q->nhbr[YLO] && q->nhbr[YLO]->refined) + ? q->nhbr[YLO]->children[2] + : q->nhbr[YLO]; + c0->nhbr[YHI] = c2; + c0->nhbr[ZLO] = (q->nhbr[ZLO] && q->nhbr[ZLO]->refined) + ? q->nhbr[ZLO]->children[4] + : q->nhbr[ZLO]; + c0->nhbr[ZHI] = c4; + + // OCTANT: [1] + c1->nhbr[XLO] = c0; + c1->nhbr[XHI] = (q->nhbr[XHI] && q->nhbr[XHI]->refined) + ? q->nhbr[XHI]->children[0] + : q->nhbr[XHI]; + c1->nhbr[YLO] = (q->nhbr[YLO] && q->nhbr[YLO]->refined) + ? q->nhbr[YLO]->children[3] + : q->nhbr[YLO]; + c1->nhbr[YHI] = c3; + c1->nhbr[ZLO] = (q->nhbr[ZLO] && q->nhbr[ZLO]->refined) + ? q->nhbr[ZLO]->children[5] + : q->nhbr[ZLO]; + c1->nhbr[ZHI] = c5; + + // OCTANT: [2] + c2->nhbr[XLO] = (q->nhbr[XLO] && q->nhbr[XLO]->refined) + ? q->nhbr[XLO]->children[3] + : q->nhbr[XLO]; + c2->nhbr[XHI] = c3; + c2->nhbr[YLO] = c0; + c2->nhbr[YHI] = (q->nhbr[YHI] && q->nhbr[YHI]->refined) + ? q->nhbr[YHI]->children[0] + : q->nhbr[YHI]; + c2->nhbr[ZLO] = (q->nhbr[ZLO] && q->nhbr[ZLO]->refined) + ? q->nhbr[ZLO]->children[6] + : q->nhbr[ZLO]; + c2->nhbr[ZHI] = c6; + + // OCTANT: [3] + c3->nhbr[XLO] = c2; + c3->nhbr[XHI] = (q->nhbr[XHI] && q->nhbr[XHI]->refined) + ? q->nhbr[XHI]->children[2] + : q->nhbr[XHI]; + c3->nhbr[YLO] = c1; + c3->nhbr[YHI] = (q->nhbr[YHI] && q->nhbr[YHI]->refined) + ? q->nhbr[YHI]->children[1] + : q->nhbr[YHI]; + c3->nhbr[ZLO] = (q->nhbr[ZLO] && q->nhbr[ZLO]->refined) + ? q->nhbr[ZLO]->children[7] + : q->nhbr[ZLO]; + c3->nhbr[ZHI] = c7; + + // OCTANT: [4] + c4->nhbr[XLO] = (q->nhbr[XLO] && q->nhbr[XLO]->refined) + ? q->nhbr[XLO]->children[5] + : q->nhbr[XLO]; + c4->nhbr[XHI] = c5; + c4->nhbr[YLO] = (q->nhbr[YLO] && q->nhbr[YLO]->refined) + ? q->nhbr[YLO]->children[6] + : q->nhbr[YLO]; + c4->nhbr[YHI] = c6; + c4->nhbr[ZLO] = c0; + c4->nhbr[ZHI] = (q->nhbr[ZHI] && q->nhbr[ZHI]->refined) + ? q->nhbr[ZHI]->children[0] + : q->nhbr[ZHI]; + + // OCTANT: [5] + c5->nhbr[XLO] = c4; + c5->nhbr[XHI] = (q->nhbr[XHI] && q->nhbr[XHI]->refined) + ? q->nhbr[XHI]->children[4] + : q->nhbr[XHI]; + c5->nhbr[YLO] = (q->nhbr[YLO] && q->nhbr[YLO]->refined) + ? q->nhbr[YLO]->children[7] + : q->nhbr[YLO]; + c5->nhbr[YHI] = c7; + c5->nhbr[ZLO] = c1; + c5->nhbr[ZHI] = (q->nhbr[ZHI] && q->nhbr[ZHI]->refined) + ? q->nhbr[ZHI]->children[1] + : q->nhbr[ZHI]; + + // OCTANT: [6] + c6->nhbr[XLO] = (q->nhbr[XLO] && q->nhbr[XLO]->refined) + ? q->nhbr[XLO]->children[7] + : q->nhbr[XLO]; + c6->nhbr[XHI] = c7; + c6->nhbr[YLO] = c4; + c6->nhbr[YHI] = (q->nhbr[YHI] && q->nhbr[YHI]->refined) + ? q->nhbr[YHI]->children[4] + : q->nhbr[YHI]; + c6->nhbr[ZLO] = c2; + c6->nhbr[ZHI] = (q->nhbr[ZHI] && q->nhbr[ZHI]->refined) + ? q->nhbr[ZHI]->children[2] + : q->nhbr[ZHI]; + + // OCTANT: [7] + c7->nhbr[XLO] = c6; + c7->nhbr[XHI] = (q->nhbr[XHI] && q->nhbr[XHI]->refined) + ? q->nhbr[XHI]->children[6] + : q->nhbr[XHI]; + c7->nhbr[YLO] = c5; + c7->nhbr[YHI] = (q->nhbr[YHI] && q->nhbr[YHI]->refined) + ? q->nhbr[YHI]->children[5] + : q->nhbr[YHI]; + c7->nhbr[ZLO] = c3; + c7->nhbr[ZHI] = (q->nhbr[ZHI] && q->nhbr[ZHI]->refined) + ? q->nhbr[ZHI]->children[3] + : q->nhbr[ZHI]; } -void floodfill_octant(octant_full_t *o){ - const int nneig = 6; - char ipaint; - int n; - - // return if outside or wall SB - if(o->filltype==OUTSIDE_SB || - o->filltype==WALL_SB) return; - - // INSIDE_SB: search neighbors - ipaint = INSIDE_SB; - for(n=0; nnhbr[n] && !o->nhbr[n]->refined){ - if(o->nhbr[n]->filltype==OUTSIDE_SB) ipaint = OUTSIDE_SB; +void floodfill_octant(octant_full_t* o) +{ + const int nneig = 6; + char ipaint; + int n; + + // return if outside or wall SB + if (o->filltype == OUTSIDE_SB || o->filltype == WALL_SB) return; + + // INSIDE_SB: search neighbors + ipaint = INSIDE_SB; + for (n = 0; n < nneig && ipaint == INSIDE_SB; n++) { + // search neighbor if it exists and is a leaf + if (o->nhbr[n] && !o->nhbr[n]->refined) { + if (o->nhbr[n]->filltype == OUTSIDE_SB) ipaint = OUTSIDE_SB; + } } - } - o->filltype = ipaint; + o->filltype = ipaint; } /* recursive search in all directions */ -void floodfill_level(level_octant_t *level){ - int nneig = 6; - int j,n; - - for(j=0;jelem_count;j++){ - octant_full_t *o = &level->octants[j]; - if(!o->refined) floodfill_octant(o); - - // fill neighbors (required since we jump around mesh due to Morton order) - for(n=0; nnhbr[n] && !o->nhbr[n]->refined) floodfill_octant(o->nhbr[n]); +void floodfill_level(level_octant_t* level) +{ + int nneig = 6; + int j, n; + + for (j = 0; j < level->elem_count; j++) { + octant_full_t* o = &level->octants[j]; + if (!o->refined) floodfill_octant(o); + + // fill neighbors (required since we jump around mesh due to Morton + // order) + for (n = 0; n < nneig; n++) { + if (o->nhbr[n] && !o->nhbr[n]->refined) + floodfill_octant(o->nhbr[n]); + } } - } } -char checkFaceBoundaryNodes(int *nodes,const char *bcnodeflag, - const int numfaceverts,const int *faceConn, - const char *duplicatenodeflag){ - /* NOTE: faceConn is base 1 but nodes is base 0 */ - char bcFlag = 1; - int v; - - // if any node on face is duplicate tag (wall + outer bc), return 0 (false) - if(duplicatenodeflag){ - for(v=0;v #include -struct Node { - int id; - double x, y, z; - const double eps = 1E-10; +struct Node +{ + int id; + double x, y, z; + const double eps = 1E-10; - Node() {} - Node(int id, double *geo) { - this->id = id; - this->x = geo[0]; - this->y = geo[1]; - this->z = geo[2]; - } - - bool operator==(const Node &otherNode) const { - return (otherNode.id == id) || ((abs(this->x - otherNode.x) <= this->eps) && - (abs(this->y - otherNode.y) <= this->eps) && - (abs(this->z - otherNode.z) <= this->eps)); - } + Node() {} + Node(int id, double* geo) + { + this->id = id; + this->x = geo[0]; + this->y = geo[1]; + this->z = geo[2]; + } - struct HashFunction { - size_t operator()(const Node &node) const { - size_t xHash = std::hash()(int(node.x)); - size_t yHash = std::hash()(int(node.y)) << 1; - size_t zHash = std::hash()(int(node.z)) << 2; - return xHash ^ yHash ^ zHash; + bool operator==(const Node& otherNode) const + { + return (otherNode.id == id) || + ((abs(this->x - otherNode.x) <= this->eps) && + (abs(this->y - otherNode.y) <= this->eps) && + (abs(this->z - otherNode.z) <= this->eps)); } - }; + + struct HashFunction + { + size_t operator()(const Node& node) const + { + size_t xHash = std::hash()(int(node.x)); + size_t yHash = std::hash()(int(node.y)) << 1; + size_t zHash = std::hash()(int(node.z)) << 2; + return xHash ^ yHash ^ zHash; + } + }; }; /* function declarations */ -void findOBB(double *x, double xc[3], double dxc[3], double vec[3][3], - int nnodes); -int checkHoleMap(double *x, int *nx, int *sam, double *extents); -int checkAdaptiveHoleMap(double *xpt, ADAPTIVE_HOLEMAP *AHM); -void fillHoleMap(int *holeMap, int ix[3], int isym); -void octant_children(uint8_t children_level, uint32_t idx, octant_full_t *q, - octant_full_t *c0, octant_full_t *c1, octant_full_t *c2, - octant_full_t *c3, octant_full_t *c4, octant_full_t *c5, - octant_full_t *c6, octant_full_t *c7); -void octant_children_neighbors(const octant_full_t *q, octant_full_t *c0, - octant_full_t *c1, octant_full_t *c2, - octant_full_t *c3, octant_full_t *c4, - octant_full_t *c5, octant_full_t *c6, - octant_full_t *c7); -void floodfill_level(level_octant_t *level); -int obbIntersectCheck(double vA[3][3], double xA[3], double dxA[3], - double vB[3][3], double xB[3], double dxB[3]); -void getobbcoords(double xc[3], double dxc[3], double vec[3][3], - double xv[8][3]); +void findOBB( + double* x, double xc[3], double dxc[3], double vec[3][3], int nnodes); +int checkHoleMap(double* x, int* nx, int* sam, double* extents); +int checkAdaptiveHoleMap(double* xpt, ADAPTIVE_HOLEMAP* AHM); +void fillHoleMap(int* holeMap, int ix[3], int isym); +void octant_children( + uint8_t children_level, + uint32_t idx, + octant_full_t* q, + octant_full_t* c0, + octant_full_t* c1, + octant_full_t* c2, + octant_full_t* c3, + octant_full_t* c4, + octant_full_t* c5, + octant_full_t* c6, + octant_full_t* c7); +void octant_children_neighbors( + const octant_full_t* q, + octant_full_t* c0, + octant_full_t* c1, + octant_full_t* c2, + octant_full_t* c3, + octant_full_t* c4, + octant_full_t* c5, + octant_full_t* c6, + octant_full_t* c7); +void floodfill_level(level_octant_t* level); +int obbIntersectCheck( + double vA[3][3], + double xA[3], + double dxA[3], + double vB[3][3], + double xB[3], + double dxB[3]); +void getobbcoords( + double xc[3], double dxc[3], double vec[3][3], double xv[8][3]); void transform2OBB(double xv[3], double xc[3], double vec[3][3], double xd[3]); -void writebbox(OBB *obb, int bid); -void writebboxdiv(OBB *obb, int bid); -void writePoints(double *x, int nsearch, int bid); -void uniquenodes(double *x, int *meshtag, double *rtag, int *itag, int *nn); -void uniqNodesTree(double *coord, int *itag, double *rtag, int *meshtag, - int *elementsAvailable, int ndim, int nav); -void uniquenodes_octree(double *x, int *meshtag, double *rtag, int *itag, - int *nn); +void writebbox(OBB* obb, int bid); +void writebboxdiv(OBB* obb, int bid); +void writePoints(double* x, int nsearch, int bid); +void uniquenodes(double* x, int* meshtag, double* rtag, int* itag, int* nn); +void uniqNodesTree( + double* coord, + int* itag, + double* rtag, + int* meshtag, + int* elementsAvailable, + int ndim, + int nav); +void uniquenodes_octree( + double* x, int* meshtag, double* rtag, int* itag, int* nn); -void qcoord_to_vertex(qcoord_t x, qcoord_t y, qcoord_t z, double *vertices, - double vxyz[3]); -char checkFaceBoundaryNodes(int *nodes, const char *bcnodeflag, - const int numfaceverts, const int *faceConn, - const char *duplicatenodeflag); -int triBoxOverlap(double boxcenter[3], double boxhalfsize[3], double *pt1, - double *pt2, double *pt3); +void qcoord_to_vertex( + qcoord_t x, qcoord_t y, qcoord_t z, double* vertices, double vxyz[3]); +char checkFaceBoundaryNodes( + int* nodes, + const char* bcnodeflag, + const int numfaceverts, + const int* faceConn, + const char* duplicatenodeflag); +int triBoxOverlap( + double boxcenter[3], + double boxhalfsize[3], + double* pt1, + double* pt2, + double* pt3); /* inline functions */ // #include