Beispiel #1
0
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 ];
    }
}
Beispiel #2
0
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);
    }
}
Beispiel #3
0
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 ];
}
Beispiel #4
0
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 ];
    }
}
Beispiel #5
0
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;
}
Beispiel #7
0
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
}
Beispiel #8
0
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
}
Beispiel #9
0
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
    }
}
Beispiel #10
0
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;
}
Beispiel #11
0
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() );
    }
}
Beispiel #14
0
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 ];
    }
}
Beispiel #15
0
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
    }
}
Beispiel #16
0
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;
}
Beispiel #18
0
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;
}
Beispiel #19
0
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);
        }
    }

}
Beispiel #20
0
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 );
        }
    }
}
Beispiel #21
0
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
}