void FloatArray :: subtract(const FloatArray &src) // Performs the operation a=a-src, where a stands for the receiver. If the // receiver's size is 0, adjusts its size to that of src. { if ( src.giveSize() == 0 ) { return; } if ( !size ) { this->resize(src.size); for ( int i = 0; i < this->size; ++i ) { this->values [ i ] = -src.values [ i ]; } return; } # ifdef DEBUG if ( this->size != src.size ) { OOFEM_ERROR3("FloatArray dimension mismatch in a[%d]->add(b[%d])\n", size, src.size); } # endif for ( int i = 0; i < this->size; ++i ) { this->values [ i ] -= src.values [ i ]; } }
void FloatArray :: checkBounds(int i) const // Checks that the receiver's size is not smaller than 'i'. { if ( i <= 0 ) { OOFEM_ERROR2("FloatArray :: checkBounds : array error on index : %d <= 0 \n", i); } if ( i > size ) { OOFEM_ERROR3("FloatArray :: checkBounds : array error on index : %d > %d \n", i, size); } }
double & Skyline :: at(int i, int j) { // returns (i,j) element of the receiver // indexes are checked if DEBUG is true int d1, k, ind; #ifdef DEBUG // check size if ( ( i > this->giveNumberOfRows() ) || ( j > this->giveNumberOfRows() ) ) { OOFEM_ERROR3("Skyline::at : dimension mismatch - accessing value at (%d,%d)", i, j); } #endif // only upper triangular part of skyline is stored if ( j < i ) { k = i; i = j; j = k; } d1 = this->adr->at(j); ind = d1 + ( j - i ); if ( ( adr->at(j + 1) - adr->at(j) ) <= ( j - i ) ) { OOFEM_ERROR3("Skyline::at : request for element which is not in sparse mtrx (%d,%d)", i, j); // // NOTE: // // don't return reference to some zero value; it is true, but possible change // of its value will require rebuilding internal storage structure // of sparse matrix // } // increment version flag this->version++; return mtrx [ ind ]; }
void FloatArray :: beDifferenceOf(const FloatArray &a, const FloatArray &b, int n) { #ifdef DEBUG if ( a.size < n || b.size < n ) { OOFEM_ERROR3("FloatArray :: beDifferenceOf - wrong size ", a.size, b.size); } #endif this->resize(n); for ( int i = 0; i < n; ++i ) { this->values [ i ] = a.values [ i ] - b.values [ i ]; } }
void FloatArray :: beDifferenceOf(const FloatArray &a, const FloatArray &b) { #ifdef DEBUG if ( a.size != b.size ) { OOFEM_ERROR3("FloatArray :: beDifferenceOf - size mismatch (%d : %d)", a.size, b.size); } #endif this->resize(a.size); for ( int i = 0; i < this->size; ++i ) { this->values [ i ] = a.values [ i ] - b.values [ i ]; } }
double SimpleCrossSection :: give(CrossSectionProperty aProperty) { double value = 0.0; if ( propertyDictionary->includes(aProperty) ) { value = propertyDictionary->at(aProperty); } else { OOFEM_ERROR3("Simple cross-section Number %d has undefined property ID %d", this->giveNumber(), aProperty); } return value; }
double &CompCol :: operator() (int i, int j) { // increment version this->version++; for ( int t = colptr_(j); t < colptr_(j + 1); t++ ) { if ( rowind_(t) == i ) { return val_(t); } } OOFEM_ERROR3("CompCol::operator(): Array element (%d,%d) not in sparse structure -- cannot assign", i, j); return val_(0); // return to suppress compiler warning message }
double &CompCol :: at(int i, int j) { // increment version this->version++; for ( int t = colptr_(j - 1); t < colptr_(j); t++ ) { if ( rowind_(t) == i - 1 ) { return val_(t); } } OOFEM_ERROR3("CompCol::operator(): Array accessing exception -- (%d,%d) out of bounds", i, j); return val_(0); // return to suppress compiler warning message }
double CompCol :: operator() (int i, int j) const { for ( int t = colptr_(j); t < colptr_(j + 1); t++ ) { if ( rowind_(t) == i ) { return val_(t); } } if ( i < dim_ [ 0 ] && j < dim_ [ 1 ] ) { return 0.0; } else { OOFEM_ERROR3("CompCol::operator(): Array accessing exception -- (%d,%d) out of bounds", i, j); return ( 0 ); // return to suppress compiler warning message } }
double FloatArray :: dotProduct(const FloatArray &x, int size) const { # ifdef DEBUG if ( size > this->size || size > x.size ) { OOFEM_ERROR3("FloatArray :: dotProduct : dimension mismatch in a[%d]->dotProduct(b[%d])\n", this->size, x.size); } # endif double dp = 0; for ( int i = 0; i < size; i++ ) { dp += this->values [ i ] * x.values [ i ]; } return dp; }
void FloatArray :: beMinOf(const FloatArray &a, const FloatArray &b) { int n = a.giveSize(); # ifdef DEBUG if ( n != b.size ) { OOFEM_ERROR3("FloatArray dimension mismatch in beMinOf(a[%d],b[%d])\n", n, b.size); } # endif this->resize(n); for ( int i = 0; i < n; i++ ) { this->values [ i ] = min( a(i), b(i) ); } }
IRResultType AbaqusUserMaterial :: initializeFrom(InputRecord *ir) { const char *__proc = "initializeFrom"; IRResultType result; std :: string umatname; std :: string umatfile; this->Material :: initializeFrom(ir); IR_GIVE_FIELD(ir, this->numState, IFT_AbaqusUserMaterial_numState, "numstate"); IR_GIVE_FIELD(ir, this->properties, IFT_AbaqusUserMaterial_properties, "properties"); IR_GIVE_FIELD(ir, umatfile, IFT_AbaqusUserMaterial_userMaterial, "umat"); umatname = "umat"; IR_GIVE_OPTIONAL_FIELD(ir, umatname, IFT_AbaqusUserMaterial_userMaterial, "name"); strncpy(this->cmname, umatname.c_str(), 80); #ifdef _WIN32 ///@todo Check all the windows support. this->umatobj = ( void * ) LoadLibrary( umatfile.c_str() ); if ( !this->umatobj ) { OOFEM_ERROR2( "AbaqusUserMaterial :: initializeFrom - couldn't load \"%s\",\ndlerror: %s", umatfile.c_str() ); } // * ( void ** )( & this->umat ) = GetProcAddress( ( HMODULE ) this->umatobj, "umat_" ); *(FARPROC *)( & this->umat ) = GetProcAddress( ( HMODULE ) this->umatobj, "umat_" );//works for MinGW 32bit if ( !this->umat ) { // char *dlresult = GetLastError(); DWORD dlresult = GetLastError();//works for MinGW 32bit OOFEM_ERROR2("AbaqusUserMaterial :: initializeFrom - couldn't load symbol umat,\nerror: %s\n", dlresult); } #else this->umatobj = dlopen(umatfile.c_str(), RTLD_NOW); if ( !this->umatobj ) { OOFEM_ERROR3( "AbaqusUserMaterial :: initializeFrom - couldn't load \"%s\",\ndlerror: %s", umatfile.c_str(), dlerror() ); } * ( void ** ) ( & this->umat ) = dlsym(this->umatobj, "umat_"); char *dlresult = dlerror(); if ( dlresult ) { OOFEM_ERROR2("AbaqusUserMaterial :: initializeFrom - couldn't load symbol umat,\ndlerror: %s\n", dlresult); } #endif return IRRT_OK; }
void SimpleCrossSection :: giveMaterialStiffnessMatrixOf(FloatMatrix &answer, MatResponseForm form, MatResponseMode rMode, GaussPoint *gp, StructuralMaterial *mat, TimeStep *tStep) // // may be only simple interface to material class, forcing returned matrix to be in reduced form. // otherwise special methods called to obtain required stiffness from 3d case. // { // Material *mat = gp->giveElement()->giveMaterial(); if ( mat->hasMaterialModeCapability( gp->giveMaterialMode() ) ) { mat->giveCharacteristicMatrix(answer, form, rMode, gp, tStep); return; } else { OOFEM_ERROR3("GiveMaterialStiffnessMatrixOf: unsupported StressStrainMode %s on Element number %d", __MaterialModeToString(gp->giveMaterialMode()), gp->giveElement()->giveGlobalNumber() ); } }
void FloatArray :: add(const double factor, const FloatArray &b) // Performs the operation a=a+factor*b, where a stands for the receiver. If the // receiver's size is 0, adjusts its size to that of b. { if ( this->size == 0 ) { this->beScaled(factor, b); return; } # ifdef DEBUG if ( size != b.size ) { OOFEM_ERROR3("FloatArray :: add : dimension mismatch in a[%d]->add(b[%d])\n", size, b.size); } # endif for ( int i = 0; i < this->size; ++i ) { this->values [ i ] += factor * b.values [ i ]; } }
double SymCompCol :: operator() (int i, int j) const { int ii = i, jj = j; if ( ii < jj ) { ii = j; jj = i; } for ( int t = colptr_(jj); t < colptr_(jj + 1); t++ ) { if ( rowind_(t) == ii ) { return val_(t); } } if ( i < dim_ [ 0 ] && j < dim_ [ 1 ] ) { return 0.0; } else { OOFEM_ERROR3("SymCompCol::operator(): Array accessing exception, index out of bounds (%d,%d)", i, j); return ( 0 ); // return to suppress compiler warning message } }
void FloatArray :: add(const FloatArray &b) // Performs the operation a=a+b, where a stands for the receiver. If the // receiver's size is 0, adjusts its size to that of b. Returns the // receiver. { if ( b.size == 0 ) { return; } if ( !size ) { * this = b; return; } if ( size != b.size ) { OOFEM_ERROR3("FloatArray :: add : dimension mismatch in a[%d]->add(b[%d])\n", size, b.size); } for ( int i = 0; i < this->size; i++ ) { this->values [ i ] += b.values [ i ]; } }
IRResultType LinearConstraintBC :: initializeFrom(InputRecord *ir) { ActiveBoundaryCondition :: initializeFrom(ir); const char *__proc = "initializeFrom"; IRResultType result; rhsLtf = 0; IR_GIVE_FIELD(ir, weights, _IFT_LinearConstraintBC_weights); IR_GIVE_FIELD(ir, rhs, _IFT_LinearConstraintBC_rhs); IR_GIVE_FIELD(ir, dofmans, _IFT_LinearConstraintBC_dofmans); IR_GIVE_FIELD(ir, dofs, _IFT_LinearConstraintBC_dofs); if(weights.giveSize() != dofmans.giveSize()){ OOFEM_ERROR3("Size mismatch, weights %d and dofmans %d", weights.giveSize(), dofmans.giveSize()); } IR_GIVE_OPTIONAL_FIELD(ir, weightsLtf, _IFT_LinearConstraintBC_weightsltf); IR_GIVE_OPTIONAL_FIELD(ir, rhsLtf, _IFT_LinearConstraintBC_rhsltf); IR_GIVE_FIELD(ir, lhsType, _IFT_LinearConstraintBC_lhstype); IR_GIVE_FIELD(ir, rhsType, _IFT_LinearConstraintBC_rhstype); return IRRT_OK; }
TimeStep *NonLinearStatic :: giveNextStep() { int istep = giveNumberOfFirstStep(); int mstepNum = 1; double totalTime = 0.0; StateCounterType counter = 1; double deltaTtmp = deltaT; //do not increase deltaT on microproblem if ( pScale == microScale ) { deltaTtmp = 0.; } if (previousStep != NULL){ delete previousStep; } if ( currentStep != NULL ) { totalTime = currentStep->giveTargetTime() + deltaTtmp; istep = currentStep->giveNumber() + 1; counter = currentStep->giveSolutionStateCounter() + 1; mstepNum = currentStep->giveMetaStepNumber(); if ( !this->giveMetaStep(mstepNum)->isStepValid(istep) ) { mstepNum++; if ( mstepNum > nMetaSteps ) { OOFEM_ERROR3("giveNextStep: no next step available, mstepNum=%d > nMetaSteps=%d", mstepNum, nMetaSteps); } } } previousStep = currentStep; currentStep = new TimeStep(istep, this, mstepNum, totalTime, deltaTtmp, counter); // dt variable are set eq to 0 for statics - has no meaning // *Wrong* It has meaning for viscoelastic materials. return currentStep; }
void FloatArray :: assemble(const FloatArray &fe, const IntArray &loc) // Assembles the array fe (typically, the load vector of a finite // element) to the receiver, using loc as location array. { int i, ii, n; # ifdef DEBUG if ( ( n = fe.giveSize() ) != loc.giveSize() ) { OOFEM_ERROR3("FloatArray::assemble : dimensions of 'fe' (%d) and 'loc' (%d) mismatch",fe.giveSize(), loc.giveSize()); } this->checkSizeTowards(loc); # endif n = fe.giveSize(); for ( i = 1; i <= n; i++ ) { ii = loc.at(i); if ( ii ) { // if non 0 coefficient, this->at(ii) += fe.at(i); } } }
void LEPlic :: findCellLineConstant(double &p, FloatArray &fvgrad, int ie, bool coord_upd, bool temp_vof_flag) { /* The line constatnt p is solved from the general non-linear function * F(p) = V(p)-V = 0, * where V(p) is the truncated volume resulting from the intersection between * assumed line segment and the reference cell * V is the given Volume of Fluid ratio * To find zero of this function, Brent's method is been used. */ Element *elem = domain->giveElement(ie); LEPlicElementInterface *interface = static_cast< LEPlicElementInterface * >( elem->giveInterface(LEPlicElementInterfaceType) ); int ivert, nelemnodes = elem->giveNumberOfNodes(); double ivof, fvi; double ivx, ivy, pp, target_vof; if ( temp_vof_flag ) { target_vof = interface->giveTempVolumeFraction(); } else { target_vof = interface->giveVolumeFraction(); } computeLEPLICVolumeFractionWrapper wrapper(interface, this, fvgrad, target_vof, coord_upd); /* * Initial part: find lower and uper bounds for Brent algorithm * Here lines with given interface normal are passed through each vertex * and corresponding volume fractions are computed. The two lines forming * truncation volumes that bound the actual material in the cell provide * upper and lower bounds for line constant */ double upper_vof = 10.0, lower_vof = -10.0; double upper_p = 0.0, lower_p = 0.0; if ( temp_vof_flag ) { fvi = interface->giveTempVolumeFraction(); } else { fvi = interface->giveVolumeFraction(); } if ( ( fvi > LEPLIC_ZERO_VOF ) && ( fvi < 1.0 ) ) { // boundary cell for ( ivert = 1; ivert <= nelemnodes; ivert++ ) { if ( coord_upd ) { ivx = giveUpdatedXCoordinate( elem->giveNode(ivert)->giveNumber() ); ivy = giveUpdatedYCoordinate( elem->giveNode(ivert)->giveNumber() ); } else { ivx = elem->giveNode(ivert)->giveCoordinate(1); ivy = elem->giveNode(ivert)->giveCoordinate(2); } // determine line constant for vertex ivert pp = -( fvgrad.at(1) * ivx + fvgrad.at(2) * ivy ); ivof = interface->computeLEPLICVolumeFraction(fvgrad, pp, this, coord_upd); if ( ( ( ivof - target_vof ) >= 0. ) && ( ivof < upper_vof ) ) { upper_vof = ivof; upper_p = pp; } else if ( ( ( target_vof - ivof ) >= 0. ) && ( ivof > lower_vof ) ) { lower_vof = ivof; lower_p = pp; } } if ( ( lower_vof >= 0. ) && ( upper_vof <= 1.00000000001 ) ) { // now use brent's method to find minima of V(p)-V function brent(lower_p, 0.5 * ( lower_p + upper_p ), upper_p, mem_fun< computeLEPLICVolumeFractionWrapper >(& wrapper, & computeLEPLICVolumeFractionWrapper :: eval), LEPLIC_BRENT_EPS, p); //interface->setTempLineConstant (p); #ifdef __OOFEG /* * Polygon grp, cell; * // check here * //Polygon testvolpoly; * //interface->formMaterialVolumePoly(testvolpoly, this, fvgrad, p, true); * //double debug_vof = interface->truncateMatVolume(testvolpoly); * * //printf ("Cell %d-> target_vof is %e, debug val is %e\n", ie, target_vof, debug_vof); * interface->formMyVolumePoly (cell, this, true); * GraphicObj *goc = cell.draw(::gc[0], false); * EASValsSetLayer(OOFEG_DEBUG_LAYER); * EASValsSetColor(::gc[0].getBcIcColor()); * EGWithMaskChangeAttributes(COLOR_MASK | LAYER_MASK, goc); * EMDrawGraphics (ESIModel(), goc); * * interface->formVolumeInterfacePoly (grp, this, fvgrad, p, true); * GraphicObj *go = grp.draw(::gc[0], true); * EASValsSetColor(::gc[0].getActiveCrackColor()); * EGWithMaskChangeAttributes(COLOR_MASK | LAYER_MASK, go); * EMDrawGraphics (ESIModel(), go); * //ESIEventLoop (YES, "findCellLineConstant -> Press Ctrl-p to continue"); */ #endif } else { //fprintf (stderr, "target_vof = %le, fvi=%le\n", target_vof, fvi); OOFEM_ERROR3("LEPlic::findCellLineConstant: finding lower and uper bounds of line constant value failed (lowerVOF = %lf, upperVOF=%lf)", lower_vof, upper_vof ); } } }
void PetscNatural2GlobalOrdering :: init(EngngModel *emodel, EquationID ut, int di, EquationType et) { Domain *d = emodel->giveDomain(di); int i, j, k, p, ndofs, ndofman = d->giveNumberOfDofManagers(); int myrank = emodel->giveRank(); DofManager *dman; // determine number of local eqs + number of those shared DOFs which are numbered by receiver // shared dofman is numbered on partition with lovest rank number EModelDefaultEquationNumbering dn; EModelDefaultPrescribedEquationNumbering dpn; #ifdef __VERBOSE_PARALLEL VERBOSEPARALLEL_PRINT("PetscNatural2GlobalOrdering :: init", "initializing N2G ordering", myrank); #endif l_neqs = 0; for ( i = 1; i <= ndofman; i++ ) { dman = d->giveDofManager(i); /* * if (dman->giveParallelMode() == DofManager_local) { // count all dofman eqs * ndofs = dman->giveNumberOfDofs (); * for (j=1; j<=ndofs; j++) { * if (dman->giveDof(j)->isPrimaryDof()) { * if (dman->giveDof(j)->giveEquationNumber()) l_neqs++; * } * } * } else if (dman->giveParallelMode() == DofManager_shared) { * // determine if problem is the lowest one sharing the dofman; if yes the receiver is responsible to * // deliver number * IntArray *plist = dman->givePartitionList(); * int n = plist->giveSize(); * int minrank = myrank; * for (j=1; j<=n; j++) minrank = min (minrank, plist->at(j)); * if (minrank == myrank) { // count eqs * ndofs = dman->giveNumberOfDofs (); * for (j=1; j<=ndofs; j++) { * if (dman->giveDof(j)->isPrimaryDof()) { * if (dman->giveDof(j)->giveEquationNumber()) l_neqs++; * } * } * } * } // end shared dman */ if ( isLocal(dman) ) { ndofs = dman->giveNumberOfDofs(); for ( j = 1; j <= ndofs; j++ ) { if ( dman->giveDof(j)->isPrimaryDof() ) { if ( et == et_standard ) { if ( dman->giveDof(j)->giveEquationNumber(dn) ) { l_neqs++; } } else { if ( dman->giveDof(j)->giveEquationNumber(dpn) ) { l_neqs++; } } } } } } // exchange with other procs the number of eqs numbered on particular procs int *leqs = new int [ emodel->giveNumberOfProcesses() ]; MPI_Allgather(& l_neqs, 1, MPI_INT, leqs, 1, MPI_INT, MPI_COMM_WORLD); // compute local offset int offset = 0; for ( j = 0; j < myrank; j++ ) { offset += leqs [ j ]; } // count global number of eqs for ( g_neqs = 0, j = 0; j < emodel->giveNumberOfProcesses(); j++ ) { g_neqs += leqs [ j ]; } // send numbered shared ones if ( et == et_standard ) { locGlobMap.resize( emodel->giveNumberOfEquations(ut) ); } else { locGlobMap.resize( emodel->giveNumberOfPrescribedEquations(ut) ); } // determine shared dofs int psize, nproc = emodel->giveNumberOfProcesses(); IntArray sizeToSend(nproc), sizeToRecv(nproc), nrecToReceive(nproc); #ifdef __VERBOSE_PARALLEL IntArray nrecToSend(nproc); #endif const IntArray *plist; for ( i = 1; i <= ndofman; i++ ) { // if (domain->giveDofManager(i)->giveParallelMode() == DofManager_shared) { if ( isShared( d->giveDofManager(i) ) ) { int n = d->giveDofManager(i)->giveNumberOfDofs(); plist = d->giveDofManager(i)->givePartitionList(); psize = plist->giveSize(); int minrank = myrank; for ( j = 1; j <= psize; j++ ) { minrank = min( minrank, plist->at(j) ); } if ( minrank == myrank ) { // count to send for ( j = 1; j <= psize; j++ ) { #ifdef __VERBOSE_PARALLEL nrecToSend( plist->at(j) )++; #endif sizeToSend( plist->at(j) ) += ( 1 + n ); // ndofs+dofman number } } else { nrecToReceive(minrank)++; sizeToRecv(minrank) += ( 1 + n ); // ndofs+dofman number } } } #ifdef __VERBOSE_PARALLEL for ( i = 0; i < nproc; i++ ) { OOFEM_LOG_INFO("[%d] Record Statistics: Sending %d Receiving %d to %d\n", myrank, nrecToSend(i), nrecToReceive(i), i); } #endif std :: map< int, int >globloc; // global->local mapping for shared // number local guys int globeq = offset; for ( i = 1; i <= ndofman; i++ ) { dman = d->giveDofManager(i); //if (dman->giveParallelMode() == DofManager_shared) { if ( isShared(dman) ) { globloc [ dman->giveGlobalNumber() ] = i; // build global->local mapping for shared plist = dman->givePartitionList(); psize = plist->giveSize(); int minrank = myrank; for ( j = 1; j <= psize; j++ ) { minrank = min( minrank, plist->at(j) ); } if ( minrank == myrank ) { // local ndofs = dman->giveNumberOfDofs(); for ( j = 1; j <= ndofs; j++ ) { if ( dman->giveDof(j)->isPrimaryDof() ) { int eq; if ( et == et_standard ) { eq = dman->giveDof(j)->giveEquationNumber(dn); } else { eq = dman->giveDof(j)->giveEquationNumber(dpn); } if ( eq ) { locGlobMap.at(eq) = globeq++; } } } } //} else if (dman->giveParallelMode() == DofManager_local) { } else { ndofs = dman->giveNumberOfDofs(); for ( j = 1; j <= ndofs; j++ ) { if ( dman->giveDof(j)->isPrimaryDof() ) { int eq; if ( et == et_standard ) { eq = dman->giveDof(j)->giveEquationNumber(dn); } else { eq = dman->giveDof(j)->giveEquationNumber(dpn); } if ( eq ) { locGlobMap.at(eq) = globeq++; } } } } } /* * fprintf (stderr, "[%d] locGlobMap: ", myrank); * for (i=1; i<=locGlobMap.giveSize(); i++) * fprintf (stderr, "%d ",locGlobMap.at(i)); */ // pack data for remote procs CommunicationBuffer **buffs = new CommunicationBuffer * [ nproc ]; for ( p = 0; p < nproc; p++ ) { buffs [ p ] = new StaticCommunicationBuffer(MPI_COMM_WORLD, 0); buffs [ p ]->resize( buffs [ p ]->givePackSize(MPI_INT, 1) * sizeToSend(p) ); #if 0 OOFEM_LOG_INFO( "[%d]PetscN2G:: init: Send buffer[%d] size %d\n", myrank, p, sizeToSend(p) ); #endif } for ( i = 1; i <= ndofman; i++ ) { if ( isShared( d->giveDofManager(i) ) ) { dman = d->giveDofManager(i); plist = dman->givePartitionList(); psize = plist->giveSize(); int minrank = myrank; for ( j = 1; j <= psize; j++ ) { minrank = min( minrank, plist->at(j) ); } if ( minrank == myrank ) { // do send for ( j = 1; j <= psize; j++ ) { p = plist->at(j); if ( p == myrank ) { continue; } #if 0 OOFEM_LOG_INFO("[%d]PetscN2G:: init: Sending localShared node %d[%d] to proc %d\n", myrank, i, dman->giveGlobalNumber(), p); #endif buffs [ p ]->packInt( dman->giveGlobalNumber() ); ndofs = dman->giveNumberOfDofs(); for ( k = 1; k <= ndofs; k++ ) { if ( dman->giveDof(k)->isPrimaryDof() ) { int eq; if ( et == et_standard ) { eq = dman->giveDof(k)->giveEquationNumber(dn); } else { eq = dman->giveDof(k)->giveEquationNumber(dpn); } if ( eq ) { buffs [ p ]->packInt( locGlobMap.at(eq) ); } } } } } } } //fprintf (stderr, "[%d] Sending glob nums ...", myrank); // send buffers for ( p = 0; p < nproc; p++ ) { if ( p != myrank ) { buffs [ p ]->iSend(p, 999); } } /**** * * for (p=0; p<nproc; p++) { * if (p == myrank) continue; * for (i=1; i<= ndofman; i++) { * //if (domain->giveDofManager(i)->giveParallelMode() == DofManager_shared) { * if (isShared(d->giveDofManager(i))) { * dman = d->giveDofManager(i); * plist = dman->givePartitionList(); * psize = plist->giveSize(); * int minrank = myrank; * for (j=1; j<=psize; j++) minrank = min (minrank, plist->at(j)); * if (minrank == myrank) { // do send * buffs[p]->packInt(dman->giveGlobalNumber()); * ndofs = dman->giveNumberOfDofs (); * for (j=1; j<=ndofs; j++) { * if (dman->giveDof(j)->isPrimaryDof()) { * buffs[p]->packInt(locGlobMap.at(dman->giveDof(j)->giveEquationNumber())); * } * } * } * } * } * // send buffer * buffs[p]->iSend(p, 999); * } ****/ // receive remote eqs and complete global numbering CommunicationBuffer **rbuffs = new CommunicationBuffer * [ nproc ]; for ( p = 0; p < nproc; p++ ) { rbuffs [ p ] = new StaticCommunicationBuffer(MPI_COMM_WORLD, 0); rbuffs [ p ]->resize( rbuffs [ p ]->givePackSize(MPI_INT, 1) * sizeToRecv(p) ); #if 0 OOFEM_LOG_INFO( "[%d]PetscN2G:: init: Receive buffer[%d] size %d\n", myrank, p, sizeToRecv(p) ); #endif } //fprintf (stderr, "[%d] Receiving glob nums ...", myrank); for ( p = 0; p < nproc; p++ ) { if ( p != myrank ) { rbuffs [ p ]->iRecv(p, 999); } } IntArray finished(nproc); finished.zero(); int fin = 1; finished.at(emodel->giveRank() + 1) = 1; do { for ( p = 0; p < nproc; p++ ) { if ( finished.at(p + 1) == 0 ) { if ( rbuffs [ p ]->testCompletion() ) { // data are here // unpack them int nite = nrecToReceive(p); int shdm, ldm; for ( i = 1; i <= nite; i++ ) { rbuffs [ p ]->unpackInt(shdm); #if 0 OOFEM_LOG_INFO("[%d]PetscN2G:: init: Received shared node [%d] from proc %d\n", myrank, shdm, p); #endif // // find local guy coorecponding to shdm if ( globloc.find(shdm) != globloc.end() ) { ldm = globloc [ shdm ]; } else { OOFEM_ERROR3("[%d] PetscNatural2GlobalOrdering :: init: invalid shared dofman received, globnum %d\n", myrank, shdm); } dman = d->giveDofManager(ldm); ndofs = dman->giveNumberOfDofs(); for ( j = 1; j <= ndofs; j++ ) { if ( dman->giveDof(j)->isPrimaryDof() ) { int eq; if ( et == et_standard ) { eq = dman->giveDof(j)->giveEquationNumber(dn); } else { eq = dman->giveDof(j)->giveEquationNumber(dpn); } if ( eq ) { int val; rbuffs [ p ]->unpackInt(val); locGlobMap.at(eq) = val; } } } } finished.at(p + 1) = 1; fin++; } } } } while ( fin < nproc ); /* * fprintf (stderr, "[%d] Finished receiving glob nums ...", myrank); * * fprintf (stderr, "[%d] locGlobMap:", myrank); * for (i=1; i<=locGlobMap.giveSize(); i++) * fprintf (stderr, "%d ",locGlobMap.at(i)); */ #ifdef __VERBOSE_PARALLEL if ( et == et_standard ) { int _eq; char *ptr; char *locname = "local", *shname = "shared", *unkname = "unknown"; for ( i = 1; i <= ndofman; i++ ) { dman = d->giveDofManager(i); if ( dman->giveParallelMode() == DofManager_local ) { ptr = locname; } else if ( dman->giveParallelMode() == DofManager_shared ) { ptr = shname; } else { ptr = unkname; } ndofs = dman->giveNumberOfDofs(); for ( j = 1; j <= ndofs; j++ ) { if ( ( _eq = dman->giveDof(j)->giveEquationNumber(dn) ) ) { fprintf( stderr, "[%d] n:%6s %d[%d] (%d), leq = %d, geq = %d\n", emodel->giveRank(), ptr, i, dman->giveGlobalNumber(), j, _eq, locGlobMap.at(_eq) ); } else { fprintf(stderr, "[%d] n:%6s %d[%d] (%d), leq = %d, geq = %d\n", emodel->giveRank(), ptr, i, dman->giveGlobalNumber(), j, _eq, 0); } } } } #endif // build reverse map int lneq; if ( et == et_standard ) { lneq = emodel->giveNumberOfEquations(ut); } else { lneq = emodel->giveNumberOfPrescribedEquations(ut); } globLocMap.clear(); for ( i = 1; i <= lneq; i++ ) { globLocMap [ locGlobMap.at(i) ] = i; } for ( p = 0; p < nproc; p++ ) { delete rbuffs [ p ]; delete buffs [ p ]; } delete[] rbuffs; delete[] buffs; delete[] leqs; MPI_Barrier(MPI_COMM_WORLD); #ifdef __VERBOSE_PARALLEL VERBOSEPARALLEL_PRINT("PetscNatural2GlobalOrdering :: init", "done", myrank); #endif }