OOFEM 3.0
Loading...
Searching...
No Matches
fluidmaterialevaluator.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"
41#include "function.h"
42#include "classfactory.h"
43
44#include <fstream>
45
46namespace oofem {
48
49FluidMaterialEvaluator :: FluidMaterialEvaluator(int i, EngngModel *_master) : EngngModel(i, _master)
50{
51 this->ndomains = 1;
52}
53
54
55void FluidMaterialEvaluator :: initializeFrom(InputRecord &ir)
56{
57 this->deltaT = 1.0;
60
62
67
69
70 // Compute the strain control (everything not controlled by stress)
71 int components = ( ndim * ( ndim + 1 ) ) / 2;
72 for ( int i = 1; i <= components; ++i ) {
73 if ( !sControl.contains(i) ) {
74 eControl.followedBy(i);
75 }
76 }
77}
78
79
80void FluidMaterialEvaluator :: solveYourself()
81{
82 Domain *d = this->giveDomain(1);
83
84
85 MaterialMode mode;
86 if ( ndim == 1 ) {
87 OOFEM_ERROR("1d flow not supported (should be added)")
88 //mode = _1dFlow;
89 } else if ( ndim == 2 ) {
90 mode = _2dFlow;
91 } else {
92 mode = _3dFlow;
93 }
94
95 int components = ( ndim * ( ndim + 1 ) ) / 2;
96 FloatArray initialStrain(components);
97 initialStrain.zero();
98 gps.clear();
99 gps.reserve(d->giveNumberOfMaterialModels());
100 for ( int i = 1; i <= d->giveNumberOfMaterialModels(); i++ ) {
101 gps.emplace_back( std::make_unique<GaussPoint>(nullptr, i, FloatArray(), 1, mode) );
102 // Initialize the strain vector;
103 FluidDynamicMaterial *mat = static_cast< FluidDynamicMaterial * >( d->giveMaterial(i) );
104 FluidDynamicMaterialStatus *status = static_cast< FluidDynamicMaterialStatus * >( mat->giveStatus( &*gps[i-1] ) );
105 status->letDeviatoricStrainRateVectorBe(initialStrain);
106 }
107
108 std :: string outname = this->giveOutputBaseFileName() + ".matdata";
109 this->outfile.open( outname.c_str() );
110
111 this->timer.startTimer(EngngModelTimer :: EMTT_AnalysisTimer);
112
113 TimeStep *tStep = giveNextStep();
114
115 // Note, strain == strain-rate (kept as strain for brevity)
116 int maxiter = 100; // User input?
117 double tolerance = 1.e-6; // Needs to be normalized somehow, or user input
118 double strainVolC = 0.;
119 FloatArray stressDevC( sControl.giveSize() ), res( sControl.giveSize() );
120
121 for ( int istep = 1; istep <= this->numberOfSteps; ++istep ) {
122 this->timer.startTimer(EngngModelTimer :: EMTT_SolutionStepTimer);
123 for ( int imat = 1; imat <= d->giveNumberOfMaterialModels(); ++imat ) {
124 GaussPoint *gp = &*gps[imat-1];
125 FluidDynamicMaterial *mat = static_cast< FluidDynamicMaterial * >( d->giveMaterial(imat) );
126 FluidDynamicMaterialStatus *status = static_cast< FluidDynamicMaterialStatus * >( mat->giveStatus(gp) );
127
128 auto strainDev = status->giveDeviatoricStrainRateVector();
129 double pressure = 0.;
130 // Update the controlled parts
131 for ( int j = 1; j <= eControl.giveSize(); ++j ) {
132 int p = eControl.at(j);
133 strainDev.at(p) = d->giveFunction( cmpntFunctions.at(p) )->evaluateAtTime( tStep->giveIntrinsicTime() );
134 }
135
136 for ( int j = 1; j <= sControl.giveSize(); ++j ) {
137 int p = sControl.at(j);
138 stressDevC.at(j) = d->giveFunction( cmpntFunctions.at(p) )->evaluateAtTime( tStep->giveIntrinsicTime() );
139 }
140
141 if ( pressureControl ) {
142 pressure = d->giveFunction(volFunction)->evaluateAtTime( tStep->giveIntrinsicTime() );
143 } else {
144 strainVolC = d->giveFunction(volFunction)->evaluateAtTime( tStep->giveIntrinsicTime() );
145 }
146
147 for ( int iter = 1; iter < maxiter; iter++ ) {
148 FloatMatrix tangent, reducedTangent;
149 FloatArray dsdp, dedd;
150 double dedp;
151 double strainVol;
152 FloatArray stressDev;
153 if ( ndim == 3 ) {
154 auto val = mat->computeDeviatoricStress3D(strainDev, pressure, gp, tStep);
155 stressDev = val.first;
156 strainVol = val.second;
157 } else {
158 auto val = mat->computeDeviatoricStress2D({strainDev[0], strainDev[1], strainDev[5]}, pressure, gp, tStep);
159 stressDev = val.first;
160 strainVol = val.second;
161 }
162
163 for ( int j = 1; j <= sControl.giveSize(); ++j ) {
164 res.at(j) = stressDevC.at(j) - stressDev.at( sControl.at(j) );
165 }
166 double resVol = 0.;
167 if ( !pressureControl ) {
168 resVol = strainVolC - strainVol;
169 }
170
171 OOFEM_LOG_RELEVANT( "Time step: %d, Material %d, Iteration: %d, Residual = %e, Resvol = %e\n", istep, imat, iter, norm(res), resVol );
172 if ( norm(res) <= tolerance && resVol <= tolerance ) {
173 break;
174 }
175 if ( ndim == 3 ) {
176 auto t = mat->computeTangents3D(TangentStiffness, gp, tStep);
177 tangent = t.dsdd;
178 dsdp = t.dsdp;
179 dedd = t.dedd;
180 dedp = t.dedp;
181 } else {
182 auto t = mat->computeTangents2D(TangentStiffness, gp, tStep);
183 tangent = t.dsdd;
184 dsdp = t.dsdp;
185 dedd = t.dedd;
186 dedp = t.dedp;
187 }
188 if ( res.giveSize() > 0 ) {
189 // Add mean part to make it invertible
190 double norm = tangent.computeFrobeniusNorm();
191 for ( int i = 1; i <= this->ndim; ++i ) {
192 for ( int j = 1; j <= this->ndim; ++j ) {
193 tangent.at(i, j) += norm;
194 }
195 }
196
197 // Pick out the stress-controlled part;
198 reducedTangent.beSubMatrixOf(tangent, sControl, sControl);
199
200 // Update stress-controlled part of the strain
201 FloatArray deltaStrain;
202 reducedTangent.solveForRhs(res, deltaStrain);
203 for ( int j = 1; j <= sControl.giveSize(); ++j ) {
204 strainDev.at( sControl.at(j) ) += deltaStrain.at(j);
205 }
206 }
207 if ( !pressureControl ) {
208 pressure -= resVol/dedp;
209 }
210 }
211
212 if ( res.computeNorm() > tolerance ) {
213 OOFEM_WARNING("Residual did not converge!");
214 }
215
216 // This material model has converged, so we update it and go on to the next.
217 gp->updateYourself(tStep);
218 }
219
220 this->timer.stopTimer(EngngModelTimer :: EMTT_SolutionStepTimer);
221 this->doStepOutput(tStep);
222 tStep = giveNextStep();
223 }
224
225 this->timer.stopTimer(EngngModelTimer :: EMTT_AnalysisTimer);
226 this->outfile.close();
227}
228
229int FluidMaterialEvaluator :: checkConsistency()
230{
231 Domain *d = this->giveDomain(1);
232 for ( int i = 1; i <= d->giveNumberOfMaterialModels(); i++ ) {
233 if ( !dynamic_cast< FluidDynamicMaterial * >( d->giveMaterial(i) ) ) {
234 return 0;
235 }
236 }
237
238 return EngngModel :: checkConsistency();
239}
240
241void FluidMaterialEvaluator :: doStepOutput(TimeStep *tStep)
242{
243 FloatArray outputValue;
244 Domain *d = this->giveDomain(1);
245 if ( tStep->isTheFirstStep() ) {
246 this->outfile << "# Time";
247 for ( int var: this->vars ) {
248 this->outfile << ", " << __InternalStateTypeToString( ( InternalStateType ) var );
249 }
250
251 this->outfile << '\n';
252 }
253
254 outfile << tStep->giveIntrinsicTime();
255 for ( int i = 1; i <= d->giveNumberOfMaterialModels(); i++ ) {
256 GaussPoint *gp = &*gps[i-1];
257 FluidDynamicMaterial *mat = static_cast< FluidDynamicMaterial * >( d->giveMaterial(i) );
258 for ( int j = 1; j <= this->vars.giveSize(); ++j ) {
259 mat->giveIPValue(outputValue, gp, ( InternalStateType ) this->vars.at(j), tStep);
260 outfile << " " << outputValue;
261 }
262 }
263
264 outfile << std :: endl;
265}
266
267TimeStep *FluidMaterialEvaluator :: giveNextStep()
268{
269 if ( !currentStep ) {
270 // first step -> generate initial step
271 //currentStep = std::make_unique<TimeStep>(*giveSolutionStepWhenIcApply());
272 currentStep = std::make_unique<TimeStep>(giveNumberOfTimeStepWhenIcApply(), this, 1, 0., this->deltaT, 0);
273 }
274 previousStep = std :: move(currentStep);
275 currentStep = std::make_unique<TimeStep>(*previousStep, this->deltaT);
276
277 return currentStep.get();
278
279}
280} // 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
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
double computeNorm() const
Definition floatarray.C:861
double & at(Index i)
Definition floatarray.h:202
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
void beSubMatrixOf(const FloatMatrix &src, Index topRow, Index bottomRow, Index topCol, Index bottomCol)
double computeFrobeniusNorm() const
double at(std::size_t i, std::size_t j) const
bool solveForRhs(const FloatArray &b, FloatArray &answer, bool transpose=false)
const FloatArrayF< 6 > & giveDeviatoricStrainRateVector() const
void letDeviatoricStrainRateVectorBe(const FloatArrayF< 6 > &v)
virtual Tangents< 6 > computeTangents3D(MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) const
virtual std::pair< FloatArrayF< 3 >, double > computeDeviatoricStress2D(const FloatArrayF< 3 > &eps, double pressure, GaussPoint *gp, TimeStep *tStep) const
int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep) override
virtual std::pair< FloatArrayF< 6 >, double > computeDeviatoricStress3D(const FloatArrayF< 6 > &eps, double pressure, GaussPoint *gp, TimeStep *tStep) const
virtual Tangents< 3 > computeTangents2D(MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) const
IntArray cmpntFunctions
Number of spatial dimensions.
TimeStep * giveNextStep() override
Returns next time step (next to current step) of receiver.
IntArray sControl
Time function controlling the volumetric/pressure part.
void doStepOutput(TimeStep *tStep) override
int volFunction
Time functions controlling each component of the deviatoric part of the stress.
std::vector< std ::unique_ptr< GaussPoint > > gps
virtual double evaluateAtTime(double t)
Definition function.C:78
void updateYourself(TimeStep *tStep)
Definition gausspoint.C:127
virtual MaterialStatus * giveStatus(GaussPoint *gp) const
Definition material.C:206
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 OOFEM_ERROR(...)
Definition error.h:79
#define _IFT_FluidMaterialEvaluator_componentFunctions
Integer list of time functions for each component.
#define _IFT_FluidMaterialEvaluator_volFunction
Integer of time function for volumetric part.
#define _IFT_FluidMaterialEvaluator_stressControl
Integer list of the stress components which are controlled.
#define _IFT_FluidMaterialEvaluator_nDimensions
Number of dimensions (2 or 3).
#define _IFT_FluidMaterialEvaluator_deltat
#define _IFT_FluidMaterialEvaluator_outputVariables
Variables (from integration point) to be written.
#define _IFT_FluidMaterialEvaluator_numberOfTimeSteps
#define _IFT_FluidMaterialEvaluator_pressureControl
Bool(Integer) determining if pressure or volumetric strain-rate is controlled.
#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_RELEVANT(...)
Definition logger.h:142
const char * __InternalStateTypeToString(InternalStateType _value)
Definition cltypes.C:309
double norm(const FloatArray &x)
const double tolerance

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