Skip to content

Commit

Permalink
Fix issue openfedem/fedem-gui#7: Support MPC Nastran bulk entries
Browse files Browse the repository at this point in the history
by conversion to WVAGM elements. Replace some static functions in
FFlNastranProcessor.C file scope by lambdas.
  • Loading branch information
kmokstad committed Oct 24, 2024
1 parent 858f434 commit d8bb252
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 44 deletions.
158 changes: 114 additions & 44 deletions src/FFlLib/FFlIOAdaptors/FFlNastranProcessor.C
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ bool FFlNastranReader::processThisEntry (const std::string& name,
if (name == "RBE2") return process_RBE2 (entry);
if (name == "RBE3") return process_RBE3 (entry);
if (name == "RBAR") return process_RBAR (entry);
if (name == "MPC") return process_MPC (entry);
if (name == "CWELD") return process_CWELD (entry);
if (name == "CBEAM") return process_CBEAM (entry);
if (name == "CBAR") return process_CBAR (entry);
Expand Down Expand Up @@ -255,6 +256,7 @@ bool FFlNastranReader::processThisEntry (const std::string& name,
return true;
}


////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////// ASET ///
////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -2449,6 +2451,7 @@ bool FFlNastranReader::process_MAT9 (std::vector<std::string>& entry)
return true;
}


////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////// PCOMP //
////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -2506,6 +2509,7 @@ bool FFlNastranReader::process_PCOMP (std::vector<std::string>& entry)
return true;
}


////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////// MOMENT /
////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -2547,6 +2551,75 @@ bool FFlNastranReader::process_MOMENT (std::vector<std::string>& entry)
}


////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////// MPC ////
////////////////////////////////////////////////////////////////////////////////

bool FFlNastranReader::process_MPC (std::vector<std::string>& entry)
{
START_TIMER("process_MPC")

if (entry.size() < 7) entry.resize(7,"");

int SID = 0;
size_t nMst = 1 + (entry.size()-6)/4;
std::vector<int> G(1+nMst,0), C(1+nMst,0);
std::vector<double> A(1+nMst,0.0);

CONVERT_ENTRY ("MPC",
fieldValue(entry[0],SID) &&
fieldValue(entry[1],G[0]) &&
fieldValue(entry[2],C[0]) &&
fieldValue(entry[3],A[0]) &&
fieldValue(entry[4],G[1]) &&
fieldValue(entry[5],C[1]) &&
fieldValue(entry[6],A[1]));

size_t i = 8;
for (size_t j = 2; i+2 < entry.size(); j++)
{
CONVERT_ENTRY ("MPC",
fieldValue(entry[i+1],G[j]) &&
fieldValue(entry[i+2],C[j]) &&
(i+3 >= entry.size() || fieldValue(entry[i+3],A[j])));
i += j%2 ? 3 : 5;
}

#ifdef FFL_DEBUG
std::cout <<"Multi-point constraint, SID = "<< SID <<": ";
for (i = 0; i < G.size(); i++)
{
if (i == 0)
std::cout << A.front();
else if (A[i] < 0.0)
std::cout <<" - "<< -A[i];
else if (A[i] > 0.0)
std::cout <<" + "<< A[i];
else
continue;
std::cout <<"*("<< G[i] <<","<< C[i] <<")";
}
std::cout <<" = 0"<< std::endl;
#endif

if (fabs(A.front()) < 1.0e-12)
{
ListUI <<"\n *** Error: A1 ("<< A.front() <<") must be non-zero"
<<" for MPC "<< SID <<".\n";
STOPP_TIMER("process_MPC")
return false;
}

FFl::DepDOFs masters = myMPCs[G.front()][C.front()];
masters.reserve(G.size()-1);
for (i = 1; i < G.size(); i++)
masters.push_back(FFl::DepDOF(G[i],C[i],A[i]/A.front()));

STOPP_TIMER("process_MPC")
return true;
}


////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////// PBAR ///
////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -3579,59 +3652,57 @@ bool FFlNastranReader::process_RBE2 (std::vector<std::string>& entry)
/////////////////////////////////////////////////////////////////////// RBE3 ///
////////////////////////////////////////////////////////////////////////////////

// Some auxilliary functions for processing of component numbers in process_RBE3

static bool isDigitIn (int target, const int digit)
bool FFlNastranReader::process_RBE3 (std::vector<std::string>& entry)
{
while (target > 0)
// Lambda function checking if given target integer contains given digit
auto&& isDigitIn = [](int target, const int digit)
{
if (target%10 == digit) return true;
target /= 10;
}
return false;
}
while (target > 0)
if (target%10 == digit)
return true;
else
target /= 10;
return false;
};

static bool isSubset (int target, int value)
{
while (value > 0)
// Lambda function checking if given target integer contains a set of digits.
auto&& isSubset = [&isDigitIn](int target, int value)
{
if (!isDigitIn(target,value%10)) return false;
value /= 10;
}
return true;
}

static bool setMinusIfSubset (int& target, int value)
{
if (!isSubset(target,value)) return false;
while (value > 0)
if (!isDigitIn(target,value%10))
return false;
else
value /= 10;
return true;
};

int digit, result = 0, expon = 1;
while (target > 0)
// Lambda function removong a set of digits from given target integer.
auto&& setMinusIfSubset = [&isSubset,&isDigitIn](int& target, int value)
{
digit = target%10;
if (!isDigitIn(value,digit)) result += digit*expon;
expon *= 10;
target /= 10;
}
target = result;
return true;
}
if (!isSubset(target,value))
return false;

int digit, result = 0, expon = 1;
while (target > 0)
{
digit = target%10;
if (!isDigitIn(value,digit))
result += digit*expon;
expon *= 10;
target /= 10;
}

/*!
\brief Group of independent nodes with common weight and component numbers.
*/

struct NodeGroup
{
double WT = 0.0; //!< Common weighting factor
int C = 0; //!< Component numbers
std::vector<int> G; //!< List of node numbers
};
target = result;
return true;
};

struct NodeGroup
{
double WT = 0.0;
int C = 0;
std::vector<int> G;
};

bool FFlNastranReader::process_RBE3 (std::vector<std::string>& entry)
{
START_TIMER("process_RBE3")

int n, EID, REFC = 0;
Expand Down Expand Up @@ -3772,7 +3843,6 @@ bool FFlNastranReader::process_RBE3 (std::vector<std::string>& entry)
//////////////////////////////////////////////////////////////////////// SPC ///
////////////////////////////////////////////////////////////////////////////////


FFlNastranReader::IntMap::iterator FFlNastranReader::setDofFlag (int n, int flg)
{
IntMap::iterator it = nodeStat.find(n);
Expand Down
5 changes: 5 additions & 0 deletions src/FFlLib/FFlIOAdaptors/FFlNastranReader.C
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,11 @@ bool FFlNastranReader::resolve (bool stillOK)
std::cout <<"FFlNastranReader: resolving loads ..."<< std::endl;
#endif
if (stillOK) stillOK = this->resolveLoads();
#ifdef FFL_DEBUG
std::cout <<"FFlNastranReader: resolving MPCs ..."<< std::endl;
#endif
if (stillOK) stillOK = FFl::convertMPCsToWAVGM(myLink,myMPCs);
myMPCs.clear();
#ifdef FFL_DEBUG
std::cout <<"FFlNastranReader: resolve done."<< std::endl;
#endif
Expand Down
4 changes: 4 additions & 0 deletions src/FFlLib/FFlIOAdaptors/FFlNastranReader.H
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#define FFL_NASTRAN_READER_H

#include "FFlReaderBase.H"
#include "FFlLib/FFlUtils.H"
#include "FFaLib/FFaAlgebra/FFaMat34.H"
#include "FFaLib/FFaAlgebra/FFaVec3.H"
#include <string>
Expand Down Expand Up @@ -129,6 +130,8 @@ private:
FFaCheckSum* attChkSum;
std::map<unsigned int,FFlAttributeBase*> uniqueAtts;

FFl::MPCMap myMPCs;

static int nWarnings, nNotes; // Accumulates the number of warnings and notes

mutable std::pair<int,std::string> lastComment;
Expand Down Expand Up @@ -255,6 +258,7 @@ protected:
DEF_PROCESSOR( MAT8 ) // Material properties
DEF_PROCESSOR( MAT9 ) // Material properties
DEF_PROCESSOR( MOMENT ) // Concentrated moment at grid point
DEF_PROCESSOR( MPC ) // Multi-point constraints
DEF_PROCESSOR( PBAR ) // Properties for CBAR
DEF_PROCESSOR( PBARL ) // Properties for CBAR with cross section dimensions
DEF_PROCESSOR( PBEAM ) // Properties for CBEAM
Expand Down

0 comments on commit d8bb252

Please sign in to comment.