OOFEM 3.0
Loading...
Searching...
No Matches
structuralmaterialevaluator.C
Go to the documentation of this file.
1/*
2 *
3 * ##### ##### ###### ###### ### ###
4 * ## ## ## ## ## ## ## ### ##
5 * ## ## ## ## #### #### ## # ##
6 * ## ## ## ## ## ## ## ##
7 * ## ## ## ## ## ## ## ##
8 * ##### ##### ## ###### ## ##
9 *
10 *
11 * OOFEM : Object Oriented Finite Element Code
12 *
13 * Copyright (C) 1993 - 2025 Borek Patzak
14 *
15 *
16 *
17 * Czech Technical University, Faculty of Civil Engineering,
18 * Department of Structural Mechanics, 166 29 Prague, Czech Republic
19 *
20 * This library is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU Lesser General Public
22 * License as published by the Free Software Foundation; either
23 * version 2.1 of the License, or (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 * Lesser General Public License for more details.
29 *
30 * You should have received a copy of the GNU Lesser General Public
31 * License along with this library; if not, write to the Free Software
32 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33 */
34
36#include "inputrecord.h"
37#include "timestep.h"
38#include "domain.h"
39#include "gausspoint.h"
42#include "function.h"
43#include "classfactory.h"
44
45#include <fstream>
46
47namespace oofem {
49
50StructuralMaterialEvaluator :: StructuralMaterialEvaluator(int i, EngngModel *_master) : EngngModel(i, _master)
51{
52 this->ndomains = 1;
53}
54
55StructuralMaterialEvaluator :: ~StructuralMaterialEvaluator()
56{ }
57
58void StructuralMaterialEvaluator :: initializeFrom(InputRecord &ir)
59{
60 this->deltaT = 1.0;
63
64 //IR_GIVE_FIELD(ir, this->ndim, _IFT_StructuralMaterialEvaluator_nDimensions);
65
69
70 tolerance = 1.0;
71 if ( this->sControl.giveSize() > 0 ) {
73 }
74
76
77 this->suppressOutput = true;
78
79 // Compute the strain control (everything not controlled by stress)
80 for ( int i = 1; i <= 6; ++i ) {
81 if ( !sControl.contains(i) ) {
82 eControl.followedBy(i);
83 }
84 }
85}
86
87
88void StructuralMaterialEvaluator :: solveYourself()
89{
90 Domain *d = this->giveDomain(1);
91
92 MaterialMode mode = _3dMat;
93 FloatArray initialStrain(6);
94 gps.clear();
95 gps.reserve(d->giveNumberOfMaterialModels());
96 for ( int i = 1; i <= d->giveNumberOfMaterialModels(); i++ ) {
97 std :: unique_ptr< GaussPoint > gp = std::make_unique<GaussPoint>(nullptr, i, FloatArray(0), 1, mode);
98 gps.emplace_back( std :: move(gp) );
99 // Initialize the strain vector;
100 StructuralMaterialStatus *status = static_cast< StructuralMaterialStatus * >( d->giveMaterial(i)->giveStatus( gps[i-1].get() ) );
101 status->letStrainVectorBe(initialStrain);
102 }
103
104 std :: string outname = this->giveOutputBaseFileName() + ".matdata";
105 this->outfile.open( outname.c_str() );
106
107 this->timer.startTimer(EngngModelTimer :: EMTT_AnalysisTimer);
108
109 TimeStep *tStep = giveNextStep();
110
111 // Note, strain == strain-rate (kept as strain for brevity)
112 int maxiter = 100; // User input?
113 FloatArray stressC, deltaStrain, strain, stress, res;
114 stressC.resize( sControl.giveSize() );
115 res.resize( sControl.giveSize() );
116
117 FloatMatrix tangent, reducedTangent;
118 for ( int istep = 1; istep <= this->numberOfSteps; ++istep ) {
119 this->timer.startTimer(EngngModelTimer :: EMTT_SolutionStepTimer);
120 for ( int imat = 1; imat <= d->giveNumberOfMaterialModels(); ++imat ) {
121 GaussPoint *gp = gps[imat-1].get();
122 StructuralMaterial *mat = static_cast< StructuralMaterial * >( d->giveMaterial(imat) );
123 StructuralMaterialStatus *status = static_cast< StructuralMaterialStatus * >( mat->giveStatus(gp) );
124
125 strain = status->giveStrainVector();
126 // Update the controlled parts
127 for ( int j = 1; j <= eControl.giveSize(); ++j ) {
128 int p = eControl.at(j);
129 strain.at(p) = d->giveFunction( cmpntFunctions.at(p) )->evaluateAtTime( tStep->giveIntrinsicTime() );
130 }
131
132 for ( int j = 1; j <= sControl.giveSize(); ++j ) {
133 int p = sControl.at(j);
134 stressC.at(j) = d->giveFunction( cmpntFunctions.at(p) )->evaluateAtTime( tStep->giveIntrinsicTime() );
135 }
136
137 //strain.add(-100, {6.27e-06, 6.27e-06, 6.27e-06, 0, 0, 0});
138 for ( int iter = 1; iter < maxiter; iter++ ) {
139#if 0
140 // Debugging:
141 mat->give3dMaterialStiffnessMatrix(tangent, TangentStiffness, gp, tStep);
142 tangent.printYourself("# tangent");
143
144 strain.zero();
145 mat->giveRealStressVector_3d(stress, gp, strain, tStep);
146 FloatArray strain2;
147 tangent.solveForRhs(stress, strain2);
148 strain2.printYourself("# thermal expansion");
149 break;
150#endif
151
152 strain.printYourself("Macro strain guess");
153 stress = mat->giveRealStressVector_3d(strain, gp, tStep);
154 for ( int j = 1; j <= sControl.giveSize(); ++j ) {
155 res.at(j) = stressC.at(j) - stress.at( sControl.at(j) );
156 }
157
158 OOFEM_LOG_INFO("*** Time step: %d (t = %.2e), Material %d, Iteration: %d, Residual = %e (tolerance %.2e)\n",
159 istep, tStep->giveIntrinsicTime(), imat, iter, res.computeNorm(), tolerance);
160
161 if ( res.computeNorm() <= tolerance ) {
162 break;
163 } else {
164 if ( tangent.giveNumberOfRows() == 0 || !keepTangent ) {
165 tangent = mat->give3dMaterialStiffnessMatrix(TangentStiffness, gp, tStep);
166 }
167
168 // Pick out the stress-controlled part;
169 reducedTangent.beSubMatrixOf(tangent, sControl, sControl);
170
171 // Update stress-controlled part of the strain
172 reducedTangent.solveForRhs(res, deltaStrain);
173 //deltaStrain.printYourself("deltaStrain");
174 for ( int j = 1; j <= sControl.giveSize(); ++j ) {
175 strain.at( sControl.at(j) ) += deltaStrain.at(j);
176 }
177 }
178 }
179
180 if ( res.computeNorm() > tolerance ) {
181 OOFEM_WARNING("Residual did not converge!");
182 }
183
184 // This material model has converged, so we update it and go on to the next.
185 gp->updateYourself(tStep);
186 }
187
188 this->timer.stopTimer(EngngModelTimer :: EMTT_SolutionStepTimer);
189 this->doStepOutput(tStep);
190 tStep = giveNextStep();
191 }
192
193 this->timer.stopTimer(EngngModelTimer :: EMTT_AnalysisTimer);
194 this->outfile.close();
195}
196
197int StructuralMaterialEvaluator :: checkConsistency()
198{
199 Domain *d = this->giveDomain(1);
200 for ( auto &mat : d->giveMaterials() ) {
201 if ( !dynamic_cast< StructuralMaterial * >( mat.get() ) ) {
202 OOFEM_LOG_ERROR("Material %d is not a StructuralMaterial", mat->giveNumber());
203 return 0;
204 }
205 }
206
207 return EngngModel :: checkConsistency();
208}
209
210void StructuralMaterialEvaluator :: doStepOutput(TimeStep *tStep)
211{
212 FloatArray outputValue;
213 Domain *d = this->giveDomain(1);
214 if ( tStep->isTheFirstStep() ) {
215 this->outfile << "# Time";
216 for ( int var : this->vars ) {
217 this->outfile << ", " << __InternalStateTypeToString( ( InternalStateType ) var );
218 }
219
220 this->outfile << '\n';
221 }
222
223 outfile << tStep->giveIntrinsicTime();
224 for ( int i = 1; i <= d->giveNumberOfMaterialModels(); i++ ) {
225 Material *mat = d->giveMaterial(i);
226 for ( int var : this->vars ) {
227 mat->giveIPValue(outputValue, gps[i-1].get(), ( InternalStateType ) var, tStep);
228 outfile << " " << outputValue;
229 }
230 }
231
232 outfile << std :: endl;
233}
234
235TimeStep *StructuralMaterialEvaluator :: giveNextStep()
236{
237 if ( !currentStep ) {
238 // first step -> generate initial step
239 //currentStep = std::make_unique<TimeStep>(*giveSolutionStepWhenIcApply());
240 currentStep = std::make_unique<TimeStep>(giveNumberOfTimeStepWhenIcApply(), this, 1, 0., this->deltaT, 0);
241 }
242 previousStep = std :: move(currentStep);
243 currentStep = std::make_unique<TimeStep>(*previousStep, this->deltaT);
244
245 return currentStep.get();
246}
247} // end namespace oofem
#define REGISTER_EngngModel(class)
Material * giveMaterial(int n)
Definition domain.C:284
int giveNumberOfMaterialModels() const
Returns number of material models in domain.
Definition domain.h:465
std ::vector< std ::unique_ptr< Material > > & giveMaterials()
Definition domain.h:371
Function * giveFunction(int n)
Definition domain.C:271
int giveNumberOfTimeStepWhenIcApply()
Returns the time step number, when initial conditions should apply.
Definition engngm.h:787
std::string giveOutputBaseFileName()
Definition engngm.h:386
EngngModel(int i, EngngModel *_master=NULL)
Definition engngm.C:99
std ::unique_ptr< TimeStep > previousStep
Previous time step.
Definition engngm.h:243
int ndomains
Number of receiver domains.
Definition engngm.h:215
int numberOfSteps
Total number of time steps.
Definition engngm.h:219
Domain * giveDomain(int n)
Definition engngm.C:1936
std ::unique_ptr< TimeStep > currentStep
Current time step.
Definition engngm.h:241
EngngModelTimer timer
E-model timer.
Definition engngm.h:279
bool suppressOutput
Flag for suppressing output to file.
Definition engngm.h:337
double computeNorm() const
Definition floatarray.C:861
void resize(Index s)
Definition floatarray.C:94
double & at(Index i)
Definition floatarray.h:202
virtual void printYourself() const
Definition floatarray.C:762
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
void beSubMatrixOf(const FloatMatrix &src, Index topRow, Index bottomRow, Index topCol, Index bottomCol)
*Prints matrix to stdout Useful for debugging void printYourself() const
int giveNumberOfRows() const
Returns number of rows of receiver.
bool solveForRhs(const FloatArray &b, FloatArray &answer, bool transpose=false)
virtual double evaluateAtTime(double t)
Definition function.C:78
void updateYourself(TimeStep *tStep)
Definition gausspoint.C:127
virtual bool hasField(InputFieldType id)=0
Returns true if record contains field identified by idString keyword.
virtual MaterialStatus * giveStatus(GaussPoint *gp) const
Definition material.C:206
virtual int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
Definition material.C:138
void doStepOutput(TimeStep *tStep) override
TimeStep * giveNextStep() override
Returns next time step (next to current step) of receiver.
IntArray sControl
Time functions controlling each component of the deviatoric part of the stress.
std::vector< std ::unique_ptr< GaussPoint > > gps
const FloatArray & giveStrainVector() const
Returns the const pointer to receiver's strain vector.
void letStrainVectorBe(const FloatArray &v)
Assigns strain vector to given vector v.
virtual FloatMatrixF< 6, 6 > give3dMaterialStiffnessMatrix(MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) const
virtual FloatArrayF< 6 > giveRealStressVector_3d(const FloatArrayF< 6 > &strain, GaussPoint *gp, TimeStep *tStep) const
Default implementation relies on giveRealStressVector for second Piola-Kirchoff stress.
bool isTheFirstStep()
Definition timestep.C:148
double giveIntrinsicTime()
Returns intrinsic time, e.g. time in which constitutive model is evaluated.
Definition timestep.h:166
#define OOFEM_WARNING(...)
Definition error.h:80
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Definition inputrecord.h:75
#define IR_GIVE_FIELD(__ir, __value, __id)
Definition inputrecord.h:67
#define OOFEM_LOG_INFO(...)
Definition logger.h:143
#define OOFEM_LOG_ERROR(...)
Definition logger.h:138
const char * __InternalStateTypeToString(InternalStateType _value)
Definition cltypes.C:309
#define _IFT_StructuralMaterialEvaluator_componentFunctions
Integer list of time functions for each component.
#define _IFT_StructuralMaterialEvaluator_tolerance
Tolerance for stress control.
#define _IFT_StructuralMaterialEvaluator_numberOfTimeSteps
#define _IFT_StructuralMaterialEvaluator_keepTangent
#define _IFT_StructuralMaterialEvaluator_stressControl
Integer list of the stress components which are controlled.
#define _IFT_StructuralMaterialEvaluator_deltat
#define _IFT_StructuralMaterialEvaluator_outputVariables
Variables (from integration point) to be written.

This page is part of the OOFEM-3.0 documentation. Copyright Copyright (C) 1994-2025 Borek Patzak Bořek Patzák
Project e-mail: oofem@fsv.cvut.cz
Generated at for OOFEM by doxygen 1.15.0 written by Dimitri van Heesch, © 1997-2011