void IncrementalLinearStatic :: updateDofUnknownsDictionary(DofManager *inode, TimeStep *tStep)
{
    // update DOF unknowns dictionary, where
    // unknowns are hold instead of keeping them in global unknowns
    // vectors in engng instances
    // this is necessary, because during solution equation numbers for
    // particular DOFs may changed, and it is necessary to keep them
    // in DOF level.

    int ndofs = inode->giveNumberOfDofs();
    Dof *iDof;
    double val;
    for ( int i = 1; i <= ndofs; i++ ) {
        iDof = inode->giveDof(i);
        // skip slave DOFs (only master (primary) DOFs have to be updated).
        if (!iDof->isPrimaryDof()) continue;
        val = iDof->giveUnknown(VM_Total, tStep);
        if ( !iDof->hasBc(tStep) ) {
            val += this->incrementOfDisplacementVector.at( iDof->__giveEquationNumber() );
        }

        iDof->updateUnknownsDictionary(tStep, VM_Total_Old, val);
        iDof->updateUnknownsDictionary(tStep, VM_Total, val);
    }
}
void
NonStationaryTransportProblem :: applyIC(TimeStep *stepWhenIcApply)
{
    Domain *domain = this->giveDomain(1);
    int neq =  this->giveNumberOfEquations(EID_ConservationEquation);
    FloatArray *solutionVector;
    double val;

#ifdef VERBOSE
    OOFEM_LOG_INFO("Applying initial conditions\n");
#endif
    int nDofs, j, k, jj;
    int nman  = domain->giveNumberOfDofManagers();
    DofManager *node;
    Dof *iDof;

    UnknownsField->advanceSolution(stepWhenIcApply);
    solutionVector = UnknownsField->giveSolutionVector(stepWhenIcApply);
    solutionVector->resize(neq);
    solutionVector->zero();

    for ( j = 1; j <= nman; j++ ) {
        node = domain->giveDofManager(j);
        nDofs = node->giveNumberOfDofs();

        for ( k = 1; k <= nDofs; k++ ) {
            // ask for initial values obtained from
            // bc (boundary conditions) and ic (initial conditions)
            iDof  =  node->giveDof(k);
            if ( !iDof->isPrimaryDof() ) {
                continue;
            }

            jj = iDof->__giveEquationNumber();
            if ( jj ) {
                val = iDof->giveUnknown(EID_ConservationEquation, VM_Total, stepWhenIcApply);
                solutionVector->at(jj) = val;
                //update in dictionary, if the problem is growing/decreasing
                if ( this->changingProblemSize ) {
                    iDof->updateUnknownsDictionary(stepWhenIcApply, EID_MomentumBalance, VM_Total, val);
                }
            }
        }
    }

    int nelem = domain->giveNumberOfElements();
    
    //project initial temperature to integration points

//     for ( j = 1; j <= nelem; j++ ) {
//         domain->giveElement(j)->updateInternalState(stepWhenIcApply);
//     }

#ifdef __CEMHYD_MODULE
    // Not relevant in linear case, but needed for CemhydMat for temperature averaging before solving balance equations
    // Update element state according to given ic
    TransportElement *element;
    CemhydMat *cem;
    for ( j = 1; j <= nelem; j++ ) {
        element = ( TransportElement * ) domain->giveElement(j);
        //assign status to each integration point on each element
        if ( element->giveMaterial()->giveClassID() == CemhydMatClass ) {
            element->giveMaterial()->initMaterial(element); //create microstructures and statuses on specific GPs
            element->updateInternalState(stepWhenIcApply);   //store temporary unequilibrated temperature
            element->updateYourself(stepWhenIcApply);   //store equilibrated temperature
            cem = ( CemhydMat * ) element->giveMaterial();
            cem->clearWeightTemperatureProductVolume(element);
            cem->storeWeightTemperatureProductVolume(element, stepWhenIcApply);
        }
    }

    //perform averaging on each material instance of CemhydMatClass
    int nmat = domain->giveNumberOfMaterialModels();
    for ( j = 1; j <= nmat; j++ ) {
        if ( domain->giveMaterial(j)->giveClassID() == CemhydMatClass ) {
            cem = ( CemhydMat * ) domain->giveMaterial(j);
            cem->averageTemperature();
        }
    }
#endif //__CEMHYD_MODULE
}
void IncrementalLinearStatic :: solveYourselfAt(TimeStep *tStep)
{
    // Creates system of governing eq's and solves them at given time step

    // Initiates the total displacement to zero.
    if ( tStep->isTheFirstStep() ) {
        Domain *d = this->giveDomain(1);
        for ( int i = 1; i <= d->giveNumberOfDofManagers(); i++ ) {
            DofManager *dofman = d->giveDofManager(i);
            for ( int j = 1; j <= dofman->giveNumberOfDofs(); j++ ) {
                dofman->giveDof(j)->updateUnknownsDictionary(tStep, VM_Total_Old, 0.);
                dofman->giveDof(j)->updateUnknownsDictionary(tStep, VM_Total, 0.);
                // This is actually redundant now;
                //dofman->giveDof(j)->updateUnknownsDictionary(tStep, VM_Incremental, 0.);
            }
        }

	int nbc = d->giveNumberOfBoundaryConditions();
	for ( int ibc = 1; ibc <= nbc; ++ibc ) {
	  GeneralBoundaryCondition *bc = d->giveBc(ibc);
	  ActiveBoundaryCondition *abc;

	  if ( ( abc = dynamic_cast< ActiveBoundaryCondition * >( bc ) ) ) {
	    int ndman = abc->giveNumberOfInternalDofManagers();
	    for ( int i = 1; i <= ndman; i++ ) {
	      DofManager *dofman = abc->giveInternalDofManager(i);
	      for ( int j = 1; j <= dofman->giveNumberOfDofs(); j++ ) {
                dofman->giveDof(j)->updateUnknownsDictionary(tStep, VM_Total_Old, 0.);
                dofman->giveDof(j)->updateUnknownsDictionary(tStep, VM_Total, 0.);
                // This is actually redundant now;
                //dofman->giveDof(j)->updateUnknownsDictionary(tStep, VM_Incremental, 0.);
	      }
	    }
	  }
	}
    }

    // Apply dirichlet b.c's on total values
    Domain *d = this->giveDomain(1);
    for ( int i = 1; i <= d->giveNumberOfDofManagers(); i++ ) {
        DofManager *dofman = d->giveDofManager(i);
        for ( int j = 1; j <= dofman->giveNumberOfDofs(); j++ ) {
            Dof *d = dofman->giveDof(j);
            double tot = d->giveUnknown(VM_Total_Old, tStep);
            if ( d->hasBc(tStep) ) {
                tot += d->giveBcValue(VM_Incremental, tStep);
            }

            d->updateUnknownsDictionary(tStep, VM_Total, tot);
        }
    }


#ifdef VERBOSE
    OOFEM_LOG_RELEVANT( "Solving [step number %8d, time %15e]\n", tStep->giveNumber(), tStep->giveTargetTime() );
#endif

    int neq = this->giveNumberOfDomainEquations(1, EModelDefaultEquationNumbering());

    if (neq == 0) { // Allows for fully prescribed/empty problems.
        return;
    }

    incrementOfDisplacementVector.resize(neq);
    incrementOfDisplacementVector.zero();

#ifdef VERBOSE
    OOFEM_LOG_INFO("Assembling load\n");
#endif
    // Assembling the element part of load vector
    internalLoadVector.resize(neq);
    internalLoadVector.zero();
    this->assembleVector( internalLoadVector, tStep, EID_MomentumBalance, InternalForcesVector,
                          VM_Total, EModelDefaultEquationNumbering(), this->giveDomain(1) );

    loadVector.resize(neq);
    loadVector.zero();
    this->assembleVector( loadVector, tStep, EID_MomentumBalance, ExternalForcesVector,
                          VM_Total, EModelDefaultEquationNumbering(), this->giveDomain(1) );

    loadVector.subtract(internalLoadVector);

#ifdef VERBOSE
    OOFEM_LOG_INFO("Assembling stiffness matrix\n");
#endif
    if ( stiffnessMatrix ) {
        delete stiffnessMatrix;
    }

    stiffnessMatrix = classFactory.createSparseMtrx(sparseMtrxType);
    if ( stiffnessMatrix == NULL ) {
        _error("solveYourselfAt: sparse matrix creation failed");
    }

    stiffnessMatrix->buildInternalStructure( this, 1, EID_MomentumBalance, EModelDefaultEquationNumbering() );
    stiffnessMatrix->zero();
    this->assemble( stiffnessMatrix, tStep, EID_MomentumBalance, StiffnessMatrix,
                   EModelDefaultEquationNumbering(), this->giveDomain(1) );

#ifdef VERBOSE
    OOFEM_LOG_INFO("Solving ...\n");
#endif
    this->giveNumericalMethod( this->giveCurrentMetaStep() );
    NM_Status s = nMethod->solve(stiffnessMatrix, & loadVector, & incrementOfDisplacementVector);
    if ( !(s & NM_Success) ) {
        OOFEM_ERROR("IncrementalLinearStatic :: solverYourselfAt - No success in solving system.");
    }
}