Exemplo n.º 1
0
void
Node2NodeContact :: giveLocationArray(IntArray &answer, const UnknownNumberingScheme &s)
{
    // should return location array for the master and the slave node
    // TODO this whole thing should be rewritten  
  
  
    answer.resize(6);
    answer.zero();
    //TODO should use a proper unknownnumberingscheme
    IntArray dofIdArray = {D_u, D_v, D_w};
    
    // master node
    for ( int i = 1; i <= dofIdArray.giveSize(); i++ ) {
        if ( this->masterNode->hasDofID( (DofIDItem)dofIdArray.at(i) ) ) { // add corresponding number
            Dof *dof= this->masterNode->giveDofWithID( (DofIDItem)dofIdArray.at(i) );
            answer.at(i) = s.giveDofEquationNumber( dof );
        } 
    }

    // slave node
    for ( int i = 1; i <= dofIdArray.giveSize(); i++ ) {
        if ( this->slaveNode->hasDofID( (DofIDItem)dofIdArray.at(i) ) ) { // add corresponding number
            Dof *dof= this->slaveNode->giveDofWithID( (DofIDItem)dofIdArray.at(i) );
            answer.at(3 + i) = s.giveDofEquationNumber( dof );
        } 
    }    
    
}    
void LinearConstraintBC :: giveLocArray(const UnknownNumberingScheme &r_s,  IntArray &locr, int& lambda_eq)
{
    int size = this->weights.giveSize();
    Dof *idof;

    locr.resize(size);
    // assemble location array
    for ( int _i = 1; _i <= size; _i++ ) {
        idof = this->domain->giveDofManager( this->dofmans.at(_i) )->giveDof( this->dofs.at(_i) );
        locr.at(_i) = r_s.giveDofEquationNumber(idof);
    }

    lambda_eq = r_s.giveDofEquationNumber( md->giveDof(1) );
}
Exemplo n.º 3
0
void DofManager :: giveLocationArray(const IntArray &dofIDArry, IntArray &locationArray, const UnknownNumberingScheme &s) const
{
    if ( !hasSlaveDofs ) {
        int size;
        // prevents some size problem when connecting different elements with
        // different number of dofs
        size = dofIDArry.giveSize();
        locationArray.resize(size);
        for ( int i = 1; i <= size; i++ ) {
            auto pos = this->findDofWithDofId( ( DofIDItem ) dofIDArry.at(i) );
            if ( pos == this->end() ) {
                OOFEM_ERROR("incompatible dof (%d) requested", dofIDArry.at(i));
            }

            locationArray.at(i) = s.giveDofEquationNumber( *pos );
        }
    } else {
        IntArray mstrEqNmbrs;
        locationArray.clear();

        for ( int dofid: dofIDArry ) {
            auto pos = this->findDofWithDofId( ( DofIDItem ) dofid );
            if ( pos == this->end() ) {
                OOFEM_ERROR("incompatible dof (%d) requested", dofid);
            }
            (*pos)->giveEquationNumbers(mstrEqNmbrs, s);
            locationArray.followedBy(mstrEqNmbrs);
        }
    }
}
Exemplo n.º 4
0
int CBS :: giveNumberOfDomainEquations(int d, const UnknownNumberingScheme &num)
{
    if ( !equationNumberingCompleted ) {
        this->forceEquationNumbering();
    }

    return num.giveRequiredNumberOfDomainEquation();
}
Exemplo n.º 5
0
void
Node2NodeContactL :: giveLocationArray(IntArray &answer, const UnknownNumberingScheme &s)
{
  
    Node2NodeContact :: giveLocationArray(answer, s);
    
    // Add one lagrange dof
    if ( this->masterNode->hasDofID( (DofIDItem)this->giveDofIdArray().at(1) ) ) { 
        Dof *dof= this->masterNode->giveDofWithID( (DofIDItem)this->giveDofIdArray().at(1) );
        answer.followedBy( s.giveDofEquationNumber(dof) );
    }
    
}    
void LinearConstraintBC :: assembleVector(FloatArray &answer, TimeStep *tStep, EquationID eid,
                                          CharType type, ValueModeType mode,
                                          const UnknownNumberingScheme &s, FloatArray *eNorms)
{
  IntArray loc, lambdaeq(1);
  FloatArray vec(1);
  double factor=1.;

  if (!this->rhsType.contains((int) type)) return ;
  if (!this->isImposed(tStep)) return;

  if (type == InternalForcesVector) {
    // compute true residual
    int size = this->weights.giveSize();
    Dof *idof;

    // assemble location array
    for ( int _i = 1; _i <= size; _i++ ) {
        factor=1.;
        if(weightsLtf.giveSize()){
            factor = domain->giveLoadTimeFunction(weightsLtf.at(_i))->__at(tStep->giveIntrinsicTime());
        }
        idof = this->domain->giveDofManager( this->dofmans.at(_i) )->giveDof( this->dofs.at(_i) );
        answer.at(s.giveDofEquationNumber(idof)) += md->giveDof(1)->giveUnknown(mode, tStep) * this->weights.at(_i)*factor;
        answer.at(s.giveDofEquationNumber( md->giveDof(1) )) += idof->giveUnknown(mode, tStep) * this->weights.at(_i)*factor;
    }

  } else {
    // use rhs value

    if(rhsLtf){
      factor = domain->giveLoadTimeFunction(rhsLtf)->__at(tStep->giveIntrinsicTime());
    }
    this->giveLocArray(s, loc, lambdaeq.at(1));
    vec.at(1) = rhs*factor;
    answer.assemble(vec, lambdaeq);
  }
}
Exemplo n.º 7
0
void DofManager :: giveCompleteLocationArray(IntArray &locationArray, const UnknownNumberingScheme &s) const
{
    if ( !hasSlaveDofs ) {
        // prevents some size problem when connecting different elements with
        // different number of dofs
        locationArray.resizeWithValues(0, this->giveNumberOfDofs());
        for ( Dof *dof: *this ) {
            locationArray.followedBy( s.giveDofEquationNumber( dof ) );
        }
    } else {
        IntArray temp;
        locationArray.resize(0);
        for ( Dof *dof: *this ) {
            dof->giveEquationNumbers(temp, s);
            locationArray.followedBy(temp);
        }
    }
}
Exemplo n.º 8
0
void Dof :: giveEquationNumbers(IntArray &masterEqNumbers, const UnknownNumberingScheme &s)
{
    masterEqNumbers.resize(1);
    masterEqNumbers.at(1) = s.giveDofEquationNumber(this);
}
Exemplo n.º 9
0
int Dof :: giveEquationNumber(const UnknownNumberingScheme &s)
{
    return s.giveDofEquationNumber(this);
}
Exemplo n.º 10
0
int Skyline :: buildInternalStructure(EngngModel *eModel, int di, const UnknownNumberingScheme &s)
{
    // first create array of
    // maximal column height for assembled characteristics matrix
    //

    int maxle;
    int ac1;
    int neq;
    if ( s.isDefault() ) {
        neq = eModel->giveNumberOfDomainEquations(di, s);
    } else {
        neq = s.giveRequiredNumberOfDomainEquation();
    }
    if ( neq == 0 ) {
        if ( mtrx ) {
            delete mtrx;
        }
        mtrx = NULL;
        adr.clear();
        return true;
    }

    IntArray loc;
    IntArray mht(neq);
    Domain *domain = eModel->giveDomain(di);

    for ( int j = 1; j <= neq; j++ ) {
        mht.at(j) = j; // initialize column height, maximum is line number (since it only stores upper triangular)
    }

    // loop over elements code numbers
    for ( auto &elem : domain->giveElements() ) {
        elem->giveLocationArray(loc, s);
        maxle = INT_MAX;
        for ( int ieq : loc ) {
            if ( ieq != 0 ) {
                maxle = min(maxle, ieq);
            }
        }

        for ( int ieq : loc ) {
            if ( ieq != 0 ) {
                mht.at(ieq) = min( maxle, mht.at(ieq) );
            }
        }
    }

    // loop over active boundary conditions (e.g. relative kinematic constraints)
    std :: vector< IntArray >r_locs;
    std :: vector< IntArray >c_locs;

    for ( auto &gbc : domain->giveBcs() ) {
        ActiveBoundaryCondition *bc = dynamic_cast< ActiveBoundaryCondition * >( gbc.get() );
        if ( bc != NULL ) {
            bc->giveLocationArrays(r_locs, c_locs, UnknownCharType, s, s);
            for ( std :: size_t k = 0; k < r_locs.size(); k++ ) {
                IntArray &krloc = r_locs [ k ];
                IntArray &kcloc = c_locs [ k ];
                maxle = INT_MAX;
                for ( int ii : krloc ) {
                    if ( ii > 0 ) {
                        maxle = min(maxle, ii);
                    }
                }
                for ( int jj : kcloc ) {
                    if ( jj > 0 ) {
                        mht.at(jj) = min( maxle, mht.at(jj) );
                    }
                }
            }
        }
    }

    
    if ( domain->hasContactManager() ) {
        ContactManager *cMan = domain->giveContactManager();
            
        for ( int i =1; i <= cMan->giveNumberOfContactDefinitions(); i++ ) {
            ContactDefinition *cDef = cMan->giveContactDefinition(i);
            for ( int k = 1; k <= cDef->giveNumbertOfContactElements(); k++ ) {
                ContactElement *cEl = cDef->giveContactElement(k);
                cEl->giveLocationArray(loc, s);
            
                maxle = INT_MAX;
                for ( int ieq : loc ) {
                    if ( ieq != 0 ) {
                        maxle = min(maxle, ieq);
                    }
                }

                for ( int ieq : loc ) {
                    if ( ieq != 0 ) {
                        mht.at(ieq) = min( maxle, mht.at(ieq) );
                    }
                  
                }
            }
        }
    }
    
    // NOTE
    // add there call to eModel if any possible additional equation added by
    // eModel
    // currently not supported

    // increases number of columns according to size of mht
    // mht is array containing minimal equation number per column
    // This method also increases column height.


    adr.resize(neq + 1);

    ac1 = 1;
    for ( int i = 1; i <= neq; i++ ) {
        adr.at(i) = ac1;
        ac1 += ( i - mht.at(i) + 1 );
    }

    adr.at(neq + 1) = ac1;
    nRows = nColumns = neq;
    nwk  = ac1;
    if ( mtrx ) {
        free(mtrx);
    }

    mtrx = ( double * ) calloc( ac1, sizeof( double ) );
    if ( !mtrx ) {
        OOFEM_ERROR("Can't allocate: %d", ac1);
    }

    // increment version
    this->version++;
    return true;
}
Exemplo n.º 11
0
int Skyline :: buildInternalStructure(EngngModel *eModel, int di, EquationID ut, const UnknownNumberingScheme &s)
{
    // first create array of
    // maximal column height for assembled characteristics matrix
    //

    int j, js, ieq, maxle;
    int i, ac1;
    int neq;
    if ( s.isDefault() ) {
        neq = eModel->giveNumberOfDomainEquations(di, ut);
    } else {
        neq = s.giveRequiredNumberOfDomainEquation();
        if ( neq == 0 ) {
            OOFEM_ERROR("Undefined Required number of domain equations");
        }
    }

    IntArray loc;
    IntArray *mht = new IntArray(neq);
    Domain *domain = eModel->giveDomain(di);

    for ( j = 1; j <= neq; j++ ) {
        mht->at(j) = j; // initialize column height, maximum is line number (since it only stores upper triangular)
    }

    int nelem = domain->giveNumberOfElements();

    // loop over elements code numbers
    for ( i = 1; i <= nelem; i++ ) {
        domain->giveElement(i)->giveLocationArray(loc, ut, s);
        js = loc.giveSize();
        maxle = INT_MAX;
        for ( j = 1; j <= js; j++ ) {
            ieq = loc.at(j);
            if ( ieq != 0 ) {
                maxle = min(maxle, ieq);
            }
        }

        for ( j = 1; j <= js; j++ ) {
            ieq = loc.at(j);
            if ( ieq != 0 ) {
                mht->at(ieq) = min( maxle, mht->at(ieq) );
            }
        }
    }

    // NOTE
    // add there call to eModel if any possible additional equation added by
    // eModel
    // currently not supported

    // increases number of columns according to size of mht
    // mht is array containing minimal equation number per column
    // This method also increases column height.


    if ( this->adr ) {
        delete adr;
    }

    adr = new IntArray(neq + 1);

    ac1 = 1;
    for ( i = 1; i <= neq; i++ ) {
        adr->at(i) = ac1;
        ac1 += ( i - mht->at(i) + 1 );
    }

    adr->at(neq + 1) = ac1;
    nRows = nColumns = neq;
    nwk  = ac1;
    if ( mtrx ) {
        freeDouble(mtrx);
    }

    mtrx = allocDouble(ac1);

    delete mht;

    // increment version
    this->version++;
    return true;
}
Exemplo n.º 12
0
///@todo I haven't looked at the parallel code yet (lack of time right now, and i want to see it work first). / Mikael
int
PetscSparseMtrx :: buildInternalStructure(EngngModel *eModel, int di, EquationID ut, const UnknownNumberingScheme &r_s, const UnknownNumberingScheme &c_s)
{
    IntArray loc;
    Domain *domain = eModel->giveDomain(di);
    int nelem;

    if ( mtrx ) {
        MatDestroy(&mtrx);
    }

    if ( this->kspInit ) {
      KSPDestroy(&ksp);
      this->kspInit  = false; // force ksp to be initialized
    }

    this->ut = ut;
    this->emodel = eModel;
    this->di = di;

#ifdef __PARALLEL_MODE
    if ( eModel->isParallel() ) {
        OOFEM_ERROR("PetscSparseMtrx :: buildInternalStructure - Not implemented");
    }
#endif
    // This should be based on the numberingscheme. Also, geqs seems redundant.

    // This could simplify things.
    int npeqs = eModel->giveNumberOfPrescribedEquations(ut);
    int neqs = eModel->giveNumberOfEquations(ut);
    nRows = r_s.isDefault() ? neqs : npeqs;
    nColumns = c_s.isDefault() ? neqs : npeqs;

    int totalEquations = eModel->giveNumberOfEquations(ut) + eModel->giveNumberOfPrescribedEquations(ut);

    //determine nonzero structure of matrix
    int ii, jj;
    Element *elem;
    IntArray r_loc, c_loc;
    std :: vector< std :: set< int > >rows(totalEquations);
    std :: vector< std :: set< int > >rows_sym(totalEquations); // Only the symmetric part

    nelem = domain->giveNumberOfElements();
    for ( int n = 1; n <= nelem; n++ ) {
        elem = domain->giveElement(n);
        elem->giveLocationArray(r_loc, ut, r_s);
        elem->giveLocationArray(c_loc, ut, c_s);
        for ( int i = 1; i <= r_loc.giveSize(); i++ ) {
            if ( ( ii = r_loc.at(i) ) ) {
                for ( int j = 1; j <= c_loc.giveSize(); j++ ) {
                    jj = c_loc.at(j);
                    if ( jj ) {
                        rows [ ii - 1 ].insert(jj - 1);
                        if ( jj >= ii ) {
                            rows_sym [ ii - 1 ].insert(jj - 1);
                        }
                    }
                }
            }
        }
    }
    // Structure from active boundary conditions.
    AList<IntArray> r_locs, c_locs;
    for ( int n = 1; n <= domain->giveNumberOfBoundaryConditions(); n++ ) {
        ActiveBoundaryCondition *activebc = dynamic_cast<ActiveBoundaryCondition*>(domain->giveBc(n));
        if (activebc) {
            ///@todo Deal with the CharType here.
            activebc->giveLocationArrays(r_locs, c_locs, ut, TangentStiffnessMatrix, r_s, c_s, domain);
            for (int k = 1; k < r_locs.giveSize(); k++) {
                IntArray *krloc = r_locs.at(k);
                IntArray *kcloc = c_locs.at(k);
                for ( int i = 1; i <= krloc->giveSize(); i++ ) {
                    if ( ( ii = krloc->at(i) ) ) {
                        for ( int j = 1; j <= kcloc->giveSize(); j++ ) {
                            jj = kcloc->at(j);
                            if ( jj ) {
                                rows [ ii - 1 ].insert(jj - 1);
                                if ( jj >= ii ) {
                                    rows_sym [ ii - 1 ].insert(jj - 1);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    geqs = leqs = nRows;

    IntArray d_nnz(leqs);
    IntArray d_nnz_sym(leqs);
    for ( int i = 0; i < leqs; i++ ) {
        d_nnz(i) = rows [ i ].size();
        d_nnz_sym(i) = rows_sym [ i ].size();
    }

    // create PETSc mat
    MatCreate(PETSC_COMM_SELF, & mtrx);
    MatSetSizes(mtrx, nRows, nColumns, nRows, nColumns);
    //MatSetType(mtrx, MATSEQAIJ);
    MatSetType(mtrx, MATSEQSBAIJ);
    MatSetFromOptions(mtrx);

    //The incompatible preallocations are ignored automatically.
    MatSetUp(mtrx);
    MatSeqAIJSetPreallocation( mtrx, 0, d_nnz.givePointer() );
    MatSeqBAIJSetPreallocation( mtrx, PETSC_DECIDE, 0, d_nnz.givePointer() ); ///@todo Not sure about PETSC_DECIDE here.
    //MatSeqSBAIJSetPreallocation( mtrx, PETSC_DECIDE, 0, d_nnz_sym.givePointer() ); // Symmetry should practically never apply here.

    MatSetOption(mtrx, MAT_ROW_ORIENTED, PETSC_FALSE); // To allow the insertion of values using MatSetValues in column major order
    MatSetOption(mtrx, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE);

    this->newValues = true;
    return true;
}