66#ifdef __MPI_PARALLEL_MODE
81QClinearStatic :: ~QClinearStatic()
89 LinearStatic :: initializeFrom(ir);
160 OOFEM_ERROR(
"Links cannot be set manualy if particles are generated automaticaly");
163 OOFEM_ERROR(
"Interpolation elements cannot be set manually if particles are generated automaticaly");
172#ifdef __MPI_PARALLEL_MODE
184QClinearStatic :: postInitialize()
218 EngngModel :: postInitialize();
235 for (
auto &el : this->
giveDomain(1)->giveElements() ) {
236 el->postInitialize();
242 for (
auto &el : this->
giveDomain(1)->giveElements() ) {
243 el->postInitialize();
252 for (
auto &el : this->
giveDomain(1)->giveElements() ) {
253 el->postInitialize();
273void QClinearStatic :: solveYourself()
275 LinearStatic :: solveYourself();
279void QClinearStatic :: solveYourselfAt(
TimeStep *tStep)
285 LinearStatic :: solveYourselfAt(tStep);
299 OOFEM_ERROR(
"invalid format of FullSolvedDomainRadius");
302 OOFEM_ERROR(
"invalid format of FullSolvedDomainBox");
309QClinearStatic :: nodeInFullSolvedDomainTest(
Node *n)
324 OOFEM_ERROR(
"Definition of Full Solved Domain by list of interpolation element has not been implemented yet");
359 if ( ( A.at(1) <= coordinates.at(1) ) && ( coordinates.at(1) <= B.
at(1) ) && \
360 ( A.at(2) <= coordinates.at(2) ) && ( coordinates.at(2) <= B.
at(2) ) && \
361 ( A.at(3) <= coordinates.at(3) ) && ( coordinates.at(3) <= B.
at(3) ) ) {
372QClinearStatic :: setRepNodesInVerticesOfInterpolationMesh(
Domain *d)
376 for (
int i = 1; i <= noe; i++ ) {
379 for (
int j = 1; j <= noen; j++ ) {
387 }
else if ( noen == 2 ) {
397QClinearStatic :: setQCNodeType(
Domain *d)
407 OOFEM_WARNING(
"Node %d is not \"qcNode\", quasicontinuum is not applied in this node", i);
414QClinearStatic :: updateNodeTypes(
Domain *d)
428 OOFEM_WARNING(
"Node %d is not \"qcNode\", quasicontinuum is not applied in this node", i);
435QClinearStatic :: createInterpolationMeshNodes(
Domain *d)
448std :: vector< IntArray >
449QClinearStatic :: generateInterpolationMesh(
Domain *d)
451 std :: vector< IntArray >newMeshNodes;
455 std :: vector< FloatArray >nodeCoords;
456 std :: vector< IntArray >meshNodes;
459 char options_string [ 128 ] =
"";
460 const char *t3dInFile;
461 const char *t3dOutFile;
465 temp.append(
".oofem.t3d.out");
466 t3dOutFile = temp.c_str();
468 sprintf(options_string,
"-i %s -o %s -S -u %f -Q -W", t3dInFile, t3dOutFile,
defaultT3DMeshSize);
474 t3d_main(NULL, options_string);
475 }
catch(
int exit_code) {
476 fprintf(stderr,
"T3d was prematuraly terminated with error code %d\n\n", exit_code);
480 OOFEM_ERROR(
"OOFEM is NOT compiled with T3D option but T3D in needed");
499std :: vector< IntArray >
500QClinearStatic :: loadInterpolationMesh(
Domain *d)
502 std :: vector< IntArray >newMeshNodes;
506 std :: vector< FloatArray >nodeCoords;
507 std :: vector< IntArray >meshNodes;
510 const char *t3dOutFile;
528std :: vector< IntArray >
529QClinearStatic :: transformMeshToParticles(
Domain *d, std :: vector< FloatArray > &nodeCoords, std :: vector< IntArray > &meshNodes)
538 int nomn = (int) nodeCoords.size();
540 int nome = (int) meshNodes.size();
543 std :: vector< IntArray >newMeshNodes;
544 newMeshNodes.clear();
547 newNodeNumbers.
resize(nomn);
550 for (
int i = 1; i <= nomn; i++ ) {
554 if ( nearestParticle ) {
559 OOFEM_ERROR(
"Vertex of interpolation mesh is shifted to node which is not \"qcNode\"");
566 newNodeNumbers [ i - 1 ] = nearestParticle->
giveNumber();
575 if ( meshNodes [ 0 ].giveSize() == 3 ) {
579 for (
int i = 1; i <= nome; i++ ) {
580 int n1 = meshNodes [ i - 1 ].at(1);
581 int n2 = meshNodes [ i - 1 ].at(2);
582 int n3 = meshNodes [ i - 1 ].at(3);
583 if ( newNodeNumbers.
at(n1) == newNodeNumbers.
at(n2) || \
584 newNodeNumbers.
at(n1) == newNodeNumbers.
at(n3) || \
585 newNodeNumbers.
at(n2) == newNodeNumbers.
at(n3) ) {
592 OOFEM_WARNING(
"%d-th interpolation element degenerates to negative volume", i);
595 OkmeshNodes.
at(1) = newNodeNumbers.
at(n1);
596 OkmeshNodes.
at(2) = newNodeNumbers.
at(n2);
597 OkmeshNodes.
at(3) = newNodeNumbers.
at(n3);
598 newMeshNodes.push_back(OkmeshNodes);
605 for (
int i = 1; i <= nome; i++ ) {
610 int n1 = meshNodes [ i - 1 ].at(1);
611 int n2 = meshNodes [ i - 1 ].at(2);
612 int n3 = meshNodes [ i - 1 ].at(3);
613 int n4 = meshNodes [ i - 1 ].at(4);
614 if ( newNodeNumbers.
at(n1) == newNodeNumbers.
at(n2) || \
615 newNodeNumbers.
at(n1) == newNodeNumbers.
at(n3) || \
616 newNodeNumbers.
at(n1) == newNodeNumbers.
at(n4) || \
617 newNodeNumbers.
at(n2) == newNodeNumbers.
at(n3) || \
618 newNodeNumbers.
at(n2) == newNodeNumbers.
at(n4) || \
619 newNodeNumbers.
at(n3) == newNodeNumbers.
at(n4) ) {
634 double detJ = ( x4 - x1 ) * ( y2 - y1 ) * ( z3 - z1 ) - ( x4 - x1 ) * ( y3 - y1 ) * ( z2 - z1 ) + ( x3 - x1 ) * ( y4 - y1 ) * ( z2 - z1 ) - ( x2 - x1 ) * ( y4 - y1 ) * ( z3 - z1 ) + ( x2 - x1 ) * ( y3 - y1 ) * ( z4 - z1 ) - ( x3 - x1 ) * ( y2 - y1 ) * ( z4 - z1 );
636 OOFEM_WARNING(
"%d-th interpolation element degenerates to negative volume", i);
640 OkmeshNodes.
at(1) = newNodeNumbers.
at(n1);
641 OkmeshNodes.
at(2) = newNodeNumbers.
at(n2);
642 OkmeshNodes.
at(3) = newNodeNumbers.
at(n3);
643 OkmeshNodes.
at(4) = newNodeNumbers.
at(n4);
644 newMeshNodes.push_back(OkmeshNodes);
655QClinearStatic :: computeTotalVolumeOfInterpolationMesh(
Domain *d)
661 double totalVolume = 0.;
672 totalVolume += volume / th;
675 }
else if ( dim == 3 ) {
681 totalVolume += volume;
685 OOFEM_ERROR(
"Invalid number of dimensions. Only 2d and 3d domains are supported in QC simulation. \n");
696 double minDistance = 1.0e100;
701 if ( dist < minDistance ) {
709 OOFEM_ERROR(
"Neares particle for point [%f, %f] not found", coords.
at(1), coords.
at(2) );
716QClinearStatic :: giveFullSolvedDomain()
727 for (
int i = 1; i <= nodeList.
giveSize(); i++ ) {
737QClinearStatic :: setActivatedElementList(
IntArray elemList)
741 for (
int i = 1; i <= elemList.
giveSize(); i++ ) {
743 if ( elemList.
at(i) == 1 ) {
#define REGISTER_EngngModel(class)
virtual double give(CrossSectionProperty a, GaussPoint *gp) const
int giveGlobalNumber() const
double giveCoordinate(int i) const
const FloatArray & giveCoordinates() const
int giveNumberOfElements() const
Returns number of elements in domain.
int giveNumberOfDofManagers() const
Returns number of dof managers in domain.
DofManager * giveDofManager(int n)
Element * giveElement(int n)
int giveNumberOfSpatialDimensions()
Returns number of spatial dimensions.
int giveGlobalNumber() const
virtual double computeVolumeAreaOrLength()
Computes the volume, area or length of the element depending on its spatial dimension.
virtual DofManager * giveInternalDofManager(int i) const
virtual int giveNumberOfDofManagers() const
CrossSection * giveCrossSection()
int giveNumberOfProcesses() const
Returns the number of collaborating processes.
int giveRank() const
Returns domain rank in a group of collaborating processes (0..groupSize-1).
ProblemCommunicator * communicator
Communicator.
Domain * giveDomain(int n)
CommunicatorBuff * commBuff
Common Communicator buffer.
bool isParallel() const
Returns true if receiver in parallel mode.
double computeNorm() const
void initializeLinkGenerator(InputRecord &ir)
void initializeParticleGenerator(InputRecord &ir)
LinearStatic(int i, EngngModel *master=nullptr)
virtual int giveQcNodeType()
FloatArray FullSolvedDomainNodes
virtual double computeTotalVolumeOfInterpolationMesh(Domain *d)
std::vector< bool > activatedElementList
int generateInterpolationElements
virtual std::vector< IntArray > transformMeshToParticles(Domain *d, std::vector< FloatArray > &nodeCoords, std::vector< IntArray > &meshNodes)
virtual std::vector< IntArray > loadInterpolationMesh(Domain *d)
int interpolationElementsMaterialNumber
QuasicontinuumNumberingscheme qcEquationNumbering
virtual bool nodeInFullSolvedDomainTest(Node *n)
FloatArray FullSolvedDomainRadius
std::vector< bool > activatedNodeList
FloatArray FullSolvedDomainElements
QCFullsolveddomain Fullsolveddomain
double defaultT3DMeshSize
int numberOfIntepolationElements
virtual void initializeFullSolvedDomain(InputRecord &ir)
virtual void setRepNodesInVerticesOfInterpolationMesh(Domain *d)
virtual std::vector< IntArray > generateInterpolationMesh(Domain *d)
virtual DofManager * findNearestParticle(Domain *d, FloatArray coords)
FloatArray FullSolvedDomainBox
std::vector< IntArray > interpolationMeshNodes
virtual void createInterpolationMeshNodes(Domain *d)
int homogenizationMtrxType
FloatArray displacementVector
void createInterpolationElements(Domain *d)
void applyApproach1(Domain *d)
void applyApproach3(Domain *d, int homMtrxType)
void setNoDimensions(Domain *d)
void setupInterpolationMesh(Domain *d, int generateInterpolationElements, int interpolationElementsMaterialNumber, std::vector< IntArray > &newMeshNodes)
void applyApproach2(Domain *d, int homMtrxType, double volumeOfInterpolationMesh)
void addCrosssectionToInterpolationElements(Domain *d)
int createQCInterpolationMesh(const char *t3dOutFile, std::vector< FloatArray > &nodeCoords, std::vector< IntArray > &cellNodes, IntArray &cellTypes)
virtual void setAsHanging()
int giveQcNodeType() override
virtual void setAsRepnode()
#define OOFEM_WARNING(...)
double distance(const FloatArray &x, const FloatArray &y)
#define _IFT_FullSolvedDomain_box
#define _IFT_QuasiContinuum_t3d_File_Name
#define _IFT_QuasiContinuum_generate_Particles
#define _IFT_QuasiContinuum_T3D_Interpolation_Mesh_size
#define _IFT_QuasiContinuum_mtrx_type
#define _IFT_QuasiContinuum_generate_Links
#define _IFT_FullSolvedDomain_elements
#define _IFT_FullSolvedDomain_nodes
#define _IFT_QuasiContinuum_approach
#define _IFT_QuasiContinuum_interp_Mat_Number
#define _IFT_QuasiContinuum_generate_Interpolation_Elements
#define _IFT_FullSolvedDomain_radius