void FE2FluidMaterial :: giveVolumetricPressureStiffness(double &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) { FE2FluidMaterialStatus *ms = static_cast<FE2FluidMaterialStatus*> (this->giveStatus(gp)); ms->computeTangents(tStep); if ( mode == TangentStiffness ) { answer = ms->giveVolumetricPressureTangent(); #ifdef DEBUG_TANGENT // Numerical ATS for debugging FloatArray strain(3); strain.zero(); FloatArray sig; double epspvol, epspvolh, pressure = 0.0; double h = 1.0; // Linear problem, size of this doesn't matter. computeDeviatoricStressVector(sig, epspvol, gp, strain, pressure, tStep); computeDeviatoricStressVector(sig, epspvolh, gp, strain, pressure+h, tStep); double dvol = (epspvolh - epspvol)/h; printf("Analytical volumetric pressure tangent = %e\n", answer); printf("Numerical volumetric pressure tangent = %e\n", dvol); double norm = fabs(dvol - answer); if (norm > fabs(answer)*DEBUG_ERR && norm > 0.0) { OOFEM_ERROR("Error in volumetric pressure tangent"); } #endif } else { OOFEM_ERROR("Mode not implemented"); } }
void FE2FluidMaterial :: giveDeviatoricPressureStiffness(FloatArray &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) { FE2FluidMaterialStatus *ms = static_cast<FE2FluidMaterialStatus*> (this->giveStatus(gp)); ms->computeTangents(tStep); if ( mode == TangentStiffness ) { answer = ms->giveDeviatoricPressureTangent(); #ifdef DEBUG_TANGENT // Numerical ATS for debugging FloatArray strain(3); strain.zero(); FloatArray sig, sigh; double epspvol, pressure = 0.0; double h = 1.00; // Linear problem, size of this doesn't matter. computeDeviatoricStressVector (sig, epspvol, gp, strain, pressure, tStep); computeDeviatoricStressVector (sigh, epspvol, gp, strain, pressure+h, tStep); FloatArray dsigh; dsigh.beDifferenceOf(sigh,sig); dsigh.times(1/h); printf("Analytical deviatoric pressure tangent = "); answer.printYourself(); printf("Numerical deviatoric pressure tangent = "); dsigh.printYourself(); dsigh.subtract(answer); double norm = dsigh.computeNorm(); if (norm > answer.computeNorm()*DEBUG_ERR && norm > 0.0) { OOFEM_ERROR("Error in deviatoric pressure tangent"); } #endif } else { OOFEM_ERROR("Mode not implemented"); } }
void FE2FluidMaterial :: giveDeviatoricStiffnessMatrix(FloatMatrix &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) { FE2FluidMaterialStatus *ms = static_cast< FE2FluidMaterialStatus * >( this->giveStatus(gp) ); ms->computeTangents(tStep); if ( mode == TangentStiffness ) { answer = ms->giveDeviatoricTangent(); } else { OOFEM_ERROR("Mode not implemented"); } }
int FE2FluidMaterial :: giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep) { FE2FluidMaterialStatus *status = static_cast<FE2FluidMaterialStatus *>(this->giveStatus(gp)); if ( type == IST_VOFFraction ) { answer.setValues(1, status->giveVOFFraction()); return true; } else { return FluidDynamicMaterial::giveIPValue(answer, gp, type, tStep); } }
void FE2FluidMaterial :: computeDeviatoricStressVector(FloatArray &stress_dev, double &r_vol, GaussPoint *gp, const FloatArray &eps, double pressure, TimeStep *tStep) { FloatMatrix d, tangent; FE2FluidMaterialStatus *ms = static_cast< FE2FluidMaterialStatus * >( this->giveStatus(gp) ); ms->setTimeStep(tStep); MixedGradientPressureBC *bc = ms->giveBC(); StokesFlow *rve = ms->giveRVE(); // Set input bc->setPrescribedDeviatoricGradientFromVoigt(eps); bc->setPrescribedPressure(pressure); // Solve subscale problem rve->solveYourselfAt(tStep); bc->computeFields(stress_dev, r_vol, tStep); ms->letDeviatoricStressVectorBe(stress_dev); ms->letDeviatoricStrainRateVectorBe(eps); ms->letPressureBe(pressure); ms->markOldTangents(); // Mark this so that tangents are reevaluated if they are needed. // One could also just compute them here, but you don't actually need them if the problem has converged, so this method saves on that iteration. // Computing the tangents are often *more* expensive than computeFields, so this is well worth the time it saves // All the tangents are computed in one go, because they are almost always all needed, and doing so saves time. }
void FE2FluidMaterial :: giveDeviatoricStiffnessMatrix(FloatMatrix &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) { FE2FluidMaterialStatus *ms = static_cast<FE2FluidMaterialStatus*> (this->giveStatus(gp)); ms->computeTangents(tStep); if ( mode == TangentStiffness ) { answer = ms->giveDeviatoricTangent(); #ifdef DEBUG_TANGENT // Numerical ATS for debugging FloatArray tempStrain(3); tempStrain.zero(); FloatArray sig, strain, sig11, sig22, sig12; double epspvol; computeDeviatoricStressVector (sig, epspvol, gp, tempStrain, 0.0, tStep); double h = 0.001; // Linear problem, size of this doesn't matter. strain.resize(3); strain = tempStrain; strain.at(1) += h; computeDeviatoricStressVector (sig11, epspvol, gp, strain, 0.0, tStep); strain = tempStrain; strain.at(2) += h; computeDeviatoricStressVector (sig22, epspvol, gp, strain, 0.0, tStep); strain = tempStrain; strain.at(3) += h; computeDeviatoricStressVector (sig12, epspvol, gp, strain, 0.0, tStep); FloatArray dsig11; dsig11.beDifferenceOf(sig11,sig); dsig11.times(1/h); FloatArray dsig22; dsig22.beDifferenceOf(sig22,sig); dsig22.times(1/h); FloatArray dsig12; dsig12.beDifferenceOf(sig12,sig); dsig12.times(1/h); FloatMatrix numericalATS; numericalATS.resize(3,3); numericalATS.zero(); numericalATS.setColumn(dsig11,1); numericalATS.setColumn(dsig22,2); numericalATS.setColumn(dsig12,3); printf("Analytical deviatoric tangent = "); answer.printYourself(); printf("Numerical deviatoric tangent = "); numericalATS.printYourself(); numericalATS.subtract(answer); double norm = numericalATS.computeFrobeniusNorm(); if (norm > answer.computeFrobeniusNorm()*DEBUG_ERR && norm > 0.0) { OOFEM_ERROR("Error in deviatoric tangent"); } #endif } else { OOFEM_ERROR("Mode not implemented"); } }
double FE2FluidMaterial :: giveEffectiveViscosity(GaussPoint *gp, TimeStep *tStep) { FE2FluidMaterialStatus *status = static_cast<FE2FluidMaterialStatus *>(this->giveStatus(gp)); status->computeTangents(tStep); const FloatMatrix &t = status->giveDeviatoricTangent(); // Project against the normalized I_dev double v; if ( gp->giveMaterialMode() == _3dFlow ) { v = (t.at(1,1)*2. + t.at(1,2) + t.at(1,3))/3. + (t.at(2,1) + t.at(2,2)*2. + t.at(2,3))/3. + (t.at(3,1) + t.at(3,2) + t.at(2,3)*2.)/3. + t.at(4,4) + t.at(5,5) + t.at(6,6); v /= 5.; } else { v = (t.at(1,1)*2. + t.at(1,2))/3. + (t.at(2,1) + t.at(2,2)*2.)/3. + t.at(3,3); v *= 19./9.; } return v; }
void FE2FluidMaterial :: giveVolumetricDeviatoricStiffness(FloatArray &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) { FE2FluidMaterialStatus *ms = static_cast<FE2FluidMaterialStatus*> (this->giveStatus(gp)); ms->computeTangents(tStep); if ( mode == TangentStiffness ) { answer = ms->giveVolumetricDeviatoricTangent(); #ifdef DEBUG_TANGENT // Numerical ATS for debugging FloatArray tempStrain(3); tempStrain.zero(); FloatArray sig, strain; double epspvol, epspvol11, epspvol22, epspvol12, pressure = 0.0; double h = 1.0; // Linear problem, size of this doesn't matter. computeDeviatoricStressVector (sig, epspvol, gp, tempStrain, pressure, tStep); strain = tempStrain; strain.at(1) += h; computeDeviatoricStressVector(sig, epspvol11, gp, strain, pressure, tStep); strain = tempStrain; strain.at(2) += h; computeDeviatoricStressVector(sig, epspvol22, gp, strain, pressure, tStep); strain = tempStrain; strain.at(3) += h; computeDeviatoricStressVector(sig, epspvol12, gp, strain, pressure, tStep); FloatArray dvol(3); dvol.at(1) = (epspvol11 - epspvol)/h; dvol.at(2) = (epspvol22 - epspvol)/h; dvol.at(3) = (epspvol12 - epspvol)/h; dvol.at(1) += 1.0; dvol.at(2) += 1.0; printf("Analytical volumetric deviatoric tangent = "); answer.printYourself(); printf("Numerical volumetric deviatoric tangent = "); dvol.printYourself(); dvol.subtract(answer); double norm = dvol.computeNorm(); if (norm > answer.computeNorm()*DEBUG_ERR && norm > 0.0) { OOFEM_ERROR("Error in volumetric deviatoric tangent"); } #endif } else { OOFEM_ERROR("Mode not implemented"); } }
int FE2FluidMaterial :: giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep) { FE2FluidMaterialStatus *status = static_cast< FE2FluidMaterialStatus * >( this->giveStatus(gp) ); if ( type == IST_VOFFraction ) { answer = FloatArray{status->giveVOFFraction()}; return true; } else if ( type == IST_Pressure ) { answer = FloatArray{status->givePressure()}; return true; } else if ( type == IST_Undefined ) { ///@todo What should one call this value? Relation between pressure and volumetric strain-rate. #if 0 // Numerical ATS for debugging FloatArray strain(3); strain.zero(); FloatArray sig; double epspvol, epspvolh, pressure = 0.0; double h = 1.0; // Linear problem, size of this doesn't matter. computeDeviatoricStressVector(sig, epspvol, gp, strain, pressure, tStep); computeDeviatoricStressVector(sig, epspvolh, gp, strain, pressure + h, tStep); double dvol = - ( epspvolh - epspvol ) / h; printf("Analytical volumetric pressure tangent = %f\n", status->giveVolumetricPressureTangent()); printf("Numerical volumetric pressure tangent = %f\n", dvol); double norm = fabs(dvol - status->giveVolumetricPressureTangent()); if ( norm > fabs(status->giveVolumetricPressureTangent()) * DEBUG_ERR && norm > 0.0 ) { OOFEM_ERROR("Error in volumetric pressure tangent"); } #endif answer = FloatArray{status->giveVolumetricPressureTangent()}; return true; } else { return FluidDynamicMaterial :: giveIPValue(answer, gp, type, tStep); } }
void FE2FluidMaterial :: giveStiffnessMatrices(FloatMatrix &dsdd, FloatArray &dsdp, FloatArray &dedd, double &dedp, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) { FE2FluidMaterialStatus *ms = static_cast< FE2FluidMaterialStatus * >( this->giveStatus(gp) ); ms->computeTangents(tStep); if ( mode == TangentStiffness ) { dsdd = ms->giveDeviatoricTangent(); dsdp = ms->giveDeviatoricPressureTangent(); dedd = ms->giveVolumetricDeviatoricTangent(); dedp = ms->giveVolumetricPressureTangent(); #if 0 // Numerical ATS for debugging FloatMatrix numericalATS(6, 6); FloatArray dsig; FloatArray tempStrain(6); tempStrain.zero(); FloatArray sig, strain, sigPert; double epspvol; computeDeviatoricStressVector(sig, epspvol, gp, tempStrain, 0., tStep); double h = 0.001; // Linear problem, size of this doesn't matter. for ( int k = 1; k <= 6; ++k ) { strain = tempStrain; strain.at(k) += h; double tmp = strain.at(1) + strain.at(2) + strain.at(3); strain.at(1) -= tmp/3.0; strain.at(2) -= tmp/3.0; strain.at(3) -= tmp/3.0; strain.printYourself(); computeDeviatoricStressVector(sigPert, epspvol, gp, strain, 0., tStep); sigPert.printYourself(); dsig.beDifferenceOf(sigPert, sig); numericalATS.setColumn(dsig, k); } numericalATS.times(1. / h); printf("Analytical deviatoric tangent = "); dsdd.printYourself(); printf("Numerical deviatoric tangent = "); numericalATS.printYourself(); numericalATS.subtract(dsdd); double norm = numericalATS.computeFrobeniusNorm(); if ( norm > dsdd.computeFrobeniusNorm() * DEBUG_ERR && norm > 0.0 ) { OOFEM_ERROR("Error in deviatoric tangent"); } #endif #if 0 // Numerical ATS for debugging FloatArray strain(3); strain.zero(); FloatArray sig, sigh; double epspvol, pressure = 0.0; double h = 1.00; // Linear problem, size of this doesn't matter. computeDeviatoricStressVector(sig, epspvol, gp, strain, pressure, tStep); computeDeviatoricStressVector(sigh, epspvol, gp, strain, pressure + h, tStep); FloatArray dsigh; dsigh.beDifferenceOf(sigh, sig); dsigh.times(1 / h); printf("Analytical deviatoric pressure tangent = "); dsdp.printYourself(); printf("Numerical deviatoric pressure tangent = "); dsigh.printYourself(); dsigh.subtract(dsdp); double norm = dsigh.computeNorm(); if ( norm > dsdp.computeNorm() * DEBUG_ERR && norm > 0.0 ) { OOFEM_ERROR("Error in deviatoric pressure tangent"); } #endif #if 0 // Numerical ATS for debugging FloatArray tempStrain(3); tempStrain.zero(); FloatArray sig, strain; double epspvol, epspvol11, epspvol22, epspvol12, pressure = 0.0; double h = 1.0; // Linear problem, size of this doesn't matter. computeDeviatoricStressVector(sig, epspvol, gp, tempStrain, pressure, tStep); strain = tempStrain; strain.at(1) += h; computeDeviatoricStressVector(sig, epspvol11, gp, strain, pressure, tStep); strain = tempStrain; strain.at(2) += h; computeDeviatoricStressVector(sig, epspvol22, gp, strain, pressure, tStep); strain = tempStrain; strain.at(3) += h; computeDeviatoricStressVector(sig, epspvol12, gp, strain, pressure, tStep); FloatArray dvol(3); dvol.at(1) = ( epspvol11 - epspvol ) / h; dvol.at(2) = ( epspvol22 - epspvol ) / h; dvol.at(3) = ( epspvol12 - epspvol ) / h; dvol.at(1) += 1.0; dvol.at(2) += 1.0; printf("Analytical volumetric deviatoric tangent = "); dedd.printYourself(); printf("Numerical volumetric deviatoric tangent = "); dvol.printYourself(); dvol.subtract(dedd); double norm = dvol.computeNorm(); if ( norm > dedd.computeNorm() * DEBUG_ERR && norm > 0.0 ) { OOFEM_ERROR("Error in volumetric deviatoric tangent"); } #endif #if 0 // Numerical ATS for debugging FloatArray strain(3); strain.zero(); FloatArray sig; double epspvol, epspvolh, pressure = 0.0; double h = 1.0; // Linear problem, size of this doesn't matter. computeDeviatoricStressVector(sig, epspvol, gp, strain, pressure, tStep); computeDeviatoricStressVector(sig, epspvolh, gp, strain, pressure + h, tStep); double dvol = -( epspvolh - epspvol ) / h; printf("Analytical volumetric pressure tangent = %e\n", dedp); printf("Numerical volumetric pressure tangent = %e\n", dvol); double norm = fabs(dvol - dedp); if ( norm > fabs(dedp) * DEBUG_ERR && norm > 0.0 ) { OOFEM_ERROR("Error in volumetric pressure tangent"); } #endif } else { OOFEM_ERROR("Mode not implemented"); } }