OOFEM 3.0
Loading...
Searching...
No Matches
mpmproblem.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
35#include "mpmproblem.h"
36#include "timestep.h"
37#include "element.h"
38#include "dofmanager.h"
39#include "dof.h"
40#include "dictionary.h"
41#include "verbose.h"
42#include "classfactory.h"
43#include "mathfem.h"
44#include "assemblercallback.h"
47#include "primaryfield.h"
48#include "maskedprimaryfield.h"
49#include "nrsolver.h"
50#include "activebc.h"
51#include "boundarycondition.h"
52#include "boundaryload.h"
53#include "outputmanager.h"
54#include "mpm.h"
55
56namespace oofem {
58
59UPLhsAssembler :: UPLhsAssembler(double alpha, double deltaT) :
61{}
62
63
64void UPLhsAssembler :: matrixFromElement(FloatMatrix &answer, Element &el, TimeStep *tStep) const
65{
66 FloatMatrix contrib;
67 IntArray locu, locp;
68 MPElement *e = dynamic_cast<MPElement*>(&el);
69 int ndofs = e->giveNumberOfDofs();
70 answer.resize(ndofs, ndofs);
71 answer.zero();
72
73 e->getLocalCodeNumbers (locu, Variable::VariableQuantity::Displacement);
74 e->getLocalCodeNumbers (locp, Variable::VariableQuantity::Pressure);
75
76 e->giveCharacteristicMatrix(contrib, MomentumBalance_StiffnessMatrix, tStep);
77 contrib.times(this->alpha);
78 answer.assemble(contrib, locu, locu);
79 e->giveCharacteristicMatrix(contrib, MomentumBalance_PressureCouplingMatrix, tStep);
80 contrib.times((-1.0)*this->alpha);
81 answer.assemble(contrib, locu, locp);
82
83 e->giveCharacteristicMatrix(contrib, MassBalance_PermeabilityMatrix, tStep);
84 contrib.times((-1.0)*this->alpha*this->alpha*this->deltaT);
85 answer.assemble(contrib, locp, locp);
86 e->giveCharacteristicMatrix(contrib, MassBalance_CompresibilityMatrix, tStep);
87 contrib.times((-1.0)*this->alpha);
88 answer.assemble(contrib, locp, locp);
89 e->giveCharacteristicMatrix(contrib, MassBalance_StressCouplingMatrix, tStep);
90 contrib.times((-1.0)*this->alpha);
91 answer.assemble(contrib, locp, locu);
92}
93
94void UPResidualAssembler :: vectorFromElement(FloatArray &vec, Element &element, TimeStep *tStep, ValueModeType mode) const
95{
96 FloatArray contrib;
97 IntArray locu, locp;
98 MPElement *e = dynamic_cast<MPElement*>(&element);
99 int ndofs = e->giveNumberOfDofs();
100 vec.resize(ndofs);
101 vec.zero();
102
103 e->getLocalCodeNumbers (locu, Variable::VariableQuantity::Displacement);
104 e->getLocalCodeNumbers (locp, Variable::VariableQuantity::Pressure);
105
106 e->giveCharacteristicVector(contrib, MomentumBalance_StressResidual, mode, tStep);
107 vec.assemble(contrib, locu);
108 e->giveCharacteristicVector(contrib, MomentumBalance_PressureResidual, mode, tStep);
109 contrib.times((-1.0));
110 vec.assemble(contrib, locu);
111
112 e->giveCharacteristicVector(contrib, MassBalance_StressRateResidual, mode, tStep);
113 contrib.times(-1.0*alpha*deltaT);
114 vec.assemble(contrib, locp);
115 e->giveCharacteristicVector(contrib, MassBalance_PressureResidual, mode, tStep);
116 contrib.times(-1.0*alpha*deltaT);
117 vec.assemble(contrib, locp);
118 e->giveCharacteristicVector(contrib, MassBalance_PressureRateResidual, mode, tStep);
119 contrib.times(-1.0*alpha*deltaT);
120 vec.assemble(contrib, locp);
121
122 //vec.negated();
123}
124
125
126TMLhsAssembler :: TMLhsAssembler(double alpha, double deltaT) :
128{}
129
130
131void TMLhsAssembler :: matrixFromElement(FloatMatrix &answer, Element &el, TimeStep *tStep) const
132{
133 FloatMatrix contrib;
134 IntArray locu, loct;
135 MPElement *e = dynamic_cast<MPElement*>(&el);
136 int ndofs = e->giveNumberOfDofs();
137 answer.resize(ndofs, ndofs);
138 answer.zero();
139
140 e->getLocalCodeNumbers (locu, Variable::VariableQuantity::Displacement);
141 e->getLocalCodeNumbers (loct, Variable::VariableQuantity::Temperature);
142
143 e->giveCharacteristicMatrix(contrib, MomentumBalance_StiffnessMatrix, tStep);
144 contrib.times(this->alpha);
145 answer.assemble(contrib, locu, locu);
146 e->giveCharacteristicMatrix(contrib, MomentumBalance_ThermalCouplingMatrix, tStep);
147 contrib.times(this->alpha);
148 answer.assemble(contrib, locu, loct);
149
150 e->giveCharacteristicMatrix(contrib, EnergyBalance_ConductivityMatrix, tStep);
151 contrib.times(this->alpha);
152 answer.assemble(contrib, loct, loct);
153 e->giveCharacteristicMatrix(contrib, EnergyBalance_CapacityMatrix, tStep);
154 contrib.times(1/tStep->giveTimeIncrement());
155 answer.assemble(contrib, loct, loct);
156
157 // @bp: experimental: evaluate element load linearization as part of residual
158 // note: extend bctracker to track bc applied via sets and directly on elements!
159 // node: ideally all external load assembled using term concept as part of residual vector! (including nodes)
160 // this would allow for consistent assembly of linearized terms as well.
161 BCTracker *bct = el.giveDomain()->giveBCTracker();
163 // loop over all boundary conditions applied to the element
164 for (BCTracker::entryListType::iterator it = bcList.begin(); it != bcList.end(); ++it) {
165 BoundaryLoad *bc = dynamic_cast<BoundaryLoad*>(el.giveDomain()->giveBc((*it).bcNumber));
166 int boundaryID = (*it).boundaryId;
167 if (bc) {
168 if (bc->giveType() == ConvectionBC) {
169 e->giveCharacteristicMatrixFromBC(contrib, EnergyBalance_ConvectionBCMatrix, tStep, bc, boundaryID);
170 if(contrib.isNotEmpty()) {
171 contrib.times(this->alpha);
173 e->getSurfaceElementCodeNumbers(loct, Variable::VariableQuantity::Temperature, boundaryID);
174 } else {
175 e->getEdgeElementCodeNumbers(loct, Variable::VariableQuantity::Temperature, boundaryID);
176 }
177 answer.assemble(contrib, loct, loct);
178 }
179 }
180 }
181
182 }
183
184}
185
186void TMResidualAssembler :: vectorFromElement(FloatArray &vec, Element &element, TimeStep *tStep, ValueModeType mode) const
187{
188 FloatArray contrib;
189 IntArray locu, loct;
190 MPElement *e = dynamic_cast<MPElement*>(&element);
191 int ndofs = e->giveNumberOfDofs();
192 vec.resize(ndofs);
193 vec.zero();
194
195 e->getLocalCodeNumbers (locu, Variable::VariableQuantity::Displacement);
196 e->getLocalCodeNumbers (loct, Variable::VariableQuantity::Temperature);
197
198 e->giveCharacteristicVector(contrib, MomentumBalance_StressResidual, mode, tStep);
199 vec.assemble(contrib, locu);
200
201 e->giveCharacteristicVector(contrib, EnergyBalance_Residual, mode, tStep);
202 vec.assemble(contrib, loct);
203
204 BCTracker *bct = e->giveDomain()->giveBCTracker();
206 // loop over all boundary conditions applied to the element
207 for (BCTracker::entryListType::iterator it = bcList.begin(); it != bcList.end(); ++it) {
208 BoundaryLoad *bc = dynamic_cast<BoundaryLoad*>(element.giveDomain()->giveBc((*it).bcNumber));
209 int boundaryID = (*it).boundaryId;
210 if (bc) {
211 if (bc->giveType() == ConvectionBC) {
212 e->giveCharacteristicVectorFromBC(contrib, EnergyBalance_ConvectionBCResidual, mode, tStep, bc, boundaryID);
213 if(contrib.isNotEmpty()) {
215 e->getSurfaceElementCodeNumbers(loct, Variable::VariableQuantity::Temperature, boundaryID);
216 } else {
217 e->getEdgeElementCodeNumbers(loct, Variable::VariableQuantity::Temperature, boundaryID);
218 }
219 vec.assemble(contrib, loct);
220 }
221 }
222 }
223
224 }
225
226}
227
228
229
230MPMProblem :: MPMProblem(int i, EngngModel *_master = nullptr) : EngngModel(i, _master)
231{
232 ndomains = 1;
233}
234
235NumericalMethod *MPMProblem :: giveNumericalMethod(MetaStep *mStep)
236{
237 if ( !nMethod ) {
238 nMethod = std::make_unique<NRSolver>(this->giveDomain(1), this);
239 }
240 return nMethod.get();
241}
242
243
244
245void
246MPMProblem :: initializeFrom(InputRecord &ir)
247{
248 EngngModel :: initializeFrom(ir);
249
250 int val = SMT_Skyline;
252 this->sparseMtrxType = ( SparseMtrxType ) val;
253
256 }
257
260 } else if ( ir.hasField(_IFT_MPMProblem_deltatfunction) ) {
262 } else if ( ir.hasField(_IFT_MPMProblem_prescribedtimes) ) {
264 } else {
265 throw ValueInputException(ir, "none", "Time step not defined");
266 }
267
269 problemType = "up"; // compatibility mode @TODO Remove default value
271 if (!((problemType == "up")||(problemType == "tm"))) {
272 throw ValueInputException(ir, "none", "Problem type not recognized");
273 }
274 OOFEM_LOG_RELEVANT("MPM: %s formulation\n", problemType.c_str());
275
277 field = std::make_unique<DofDistributedPrimaryField>(this, 1, FT_TransportProblemUnknowns, 2, this->alpha);
278
279 // read field export flag
280 exportFields.clear();
282 if ( exportFields.giveSize() ) {
283 FieldManager *fm = this->giveContext()->giveFieldManager();
284 for ( int i = 1; i <= exportFields.giveSize(); i++ ) {
285 if ( exportFields.at(i) == FT_Displacements ) {
286 FieldPtr _displacementField( new MaskedPrimaryField ( ( FieldType ) exportFields.at(i), this->field.get(), {D_u, D_v, D_w} ) );
287 fm->registerField( _displacementField, ( FieldType ) exportFields.at(i) );
288 } else if ( exportFields.at(i) == FT_Pressure ) {
289 FieldPtr _pressureField( new MaskedPrimaryField ( ( FieldType ) exportFields.at(i), this->field.get(), {P_f} ) );
290 fm->registerField( _pressureField, ( FieldType ) exportFields.at(i) );
291 }
292 }
293 }
294}
295
296double MPMProblem :: giveUnknownComponent(ValueModeType mode, TimeStep *tStep, Domain *d, Dof *dof)
297{
298 return this->field->giveUnknownValue(dof, mode, tStep);
299}
300
301
302double
303MPMProblem :: giveDeltaT(int n)
304{
305 if ( this->dtFunction ) {
306 return this->giveDomain(1)->giveFunction(this->dtFunction)->evaluateAtTime(n);
307 } else if ( this->prescribedTimes.giveSize() > 0 ) {
308 return this->giveDiscreteTime(n) - this->giveDiscreteTime(n - 1);
309 } else {
310 return this->deltaT;
311 }
312}
313
314double
315MPMProblem :: giveDiscreteTime(int iStep)
316{
317 if ( iStep > 0 && iStep <= this->prescribedTimes.giveSize() ) {
318 return ( this->prescribedTimes.at(iStep) );
319 } else if ( iStep == 0 ) {
320 return initT;
321 }
322
323 OOFEM_ERROR("invalid iStep");
324 return 0.0;
325}
326
327
328TimeStep *MPMProblem :: giveNextStep()
329{
330 if ( !currentStep ) {
331 // first step -> generate initial step
332 currentStep = std::make_unique<TimeStep>( *giveSolutionStepWhenIcApply() );
333 }
334
335 double dt = this->giveDeltaT(currentStep->giveNumber()+1);
336 previousStep = std :: move(currentStep);
337 currentStep = std::make_unique<TimeStep>(*previousStep, dt);
338 currentStep->setIntrinsicTime(previousStep->giveTargetTime() + alpha * dt);
339 return currentStep.get();
340}
341
342
343TimeStep *MPMProblem :: giveSolutionStepWhenIcApply(bool force)
344{
345 if ( master && (!force)) {
346 return master->giveSolutionStepWhenIcApply();
347 } else {
348 if ( !stepWhenIcApply ) {
349 double dt = this->giveDeltaT(1);
350 stepWhenIcApply = std::make_unique<TimeStep>(giveNumberOfTimeStepWhenIcApply(), this, 0, this->initT, dt, 0);
351 // The initial step goes from [-dt, 0], so the intrinsic time is at: -deltaT + alpha*dt
352 stepWhenIcApply->setIntrinsicTime(-dt + alpha * dt);
353 }
354
355 return stepWhenIcApply.get();
356 }
357}
358
359void MPMProblem :: solveYourselfAt(TimeStep *tStep)
360{
361 OOFEM_LOG_INFO( "\nSolving [step number %5d, time %e]\n", tStep->giveNumber(), tStep->giveTargetTime() );
362
363 Domain *d = this->giveDomain(1);
365
366 if ( tStep->isTheFirstStep() ) {
367 this->applyIC();
368 }
369
370 field->advanceSolution(tStep);
371 field->initialize(VM_Total, tStep, solution, EModelDefaultEquationNumbering());
372
373 if ( !effectiveMatrix ) {
374 effectiveMatrix = classFactory.createSparseMtrx(sparseMtrxType);
375 effectiveMatrix->buildInternalStructure( this, 1, EModelDefaultEquationNumbering() );
376 }
377
378 OOFEM_LOG_INFO("Assembling external forces\n");
379 FloatArray externalForces(neq);
380 externalForces.zero();
381 this->assembleVector( externalForces, tStep, ExternalForceAssembler(), VM_Total, EModelDefaultEquationNumbering(), d );
383
384 // set-up numerical method
386 OOFEM_LOG_INFO("Solving for %d unknowns...\n", neq);
387
388 internalForces.resize(neq);
389
390 FloatArray incrementOfSolution;
391 double loadLevel;
392 int currentIterations = 0;
393 this->updateInternalRHS(this->internalForces, tStep, this->giveDomain(1), &this->eNorm);
394 ConvergedReason status = this->nMethod->solve(*this->effectiveMatrix,
395 externalForces,
396 nullptr, // ignore
397 this->solution,
398 incrementOfSolution,
399 this->internalForces,
400 this->eNorm,
401 loadLevel, // ignore
402 SparseNonLinearSystemNM :: rlm_total, // ignore
403 currentIterations, // ignore
404 tStep);
405 tStep->numberOfIterations = currentIterations;
406 tStep->convergedReason = status;
407}
408
409
410void
411MPMProblem :: updateSolution(FloatArray &solutionVector, TimeStep *tStep, Domain *d)
412{
414 this->field->update(VM_Total, tStep, solutionVector, EModelDefaultEquationNumbering());
417 this->field->applyBoundaryCondition(tStep);
418}
419
420
421void
422MPMProblem :: updateInternalRHS(FloatArray &answer, TimeStep *tStep, Domain *d, FloatArray *eNorm)
423{
424 // F_eff = F(T^(k)) + C * dT/dt^(k)
425 answer.zero();
426 if (this->problemType == "up") {
427 this->assembleVector(answer, tStep, UPResidualAssembler(this->alpha, tStep->giveTimeIncrement()), VM_Total, EModelDefaultEquationNumbering(), d, eNorm);
428 } else if (this->problemType == "tm") {
429 this->assembleVector(answer, tStep, TMResidualAssembler(this->alpha, tStep->giveTimeIncrement()), VM_Total, EModelDefaultEquationNumbering(), d, eNorm);
430 } else {
431 OOFEM_ERROR ("unsupported problemType");
432 }
434}
435
436
437void
438MPMProblem :: updateMatrix(SparseMtrx &mat, TimeStep *tStep, Domain *d)
439{
440 // K_eff = (a*K + C/dt)
441 if ( !this->keepTangent || !this->hasTangent ) {
442 mat.zero();
443 if (this->problemType == "up") {
444 UPLhsAssembler jacobianAssembler(this->alpha, tStep->giveTimeIncrement());
445 //Assembling left hand side
446 this->assemble( *effectiveMatrix, tStep, jacobianAssembler,
448 } else if (this->problemType == "tm") {
449 TMLhsAssembler jacobianAssembler(this->alpha, tStep->giveTimeIncrement());
450 //Assembling left hand side
451 this->assemble( *effectiveMatrix, tStep, jacobianAssembler,
453 } else {
454 OOFEM_ERROR ("unsupported problemType");
455 }
456
457 this->hasTangent = true;
458 }
459}
460
461
462void
463MPMProblem :: updateComponent(TimeStep *tStep, NumericalCmpn cmpn, Domain *d)
464{
466 this->field->update(VM_Total, tStep, solution, EModelDefaultEquationNumbering());
469 this->field->applyBoundaryCondition(tStep);
470
471 if ( cmpn == InternalRhs ) {
472 // F_eff = F(T^(k)) + C * dT/dt^(k)
473 this->internalForces.zero();
474 if (this->problemType == "up") {
476 } else if (this->problemType == "tm") {
478 } else {
479 OOFEM_ERROR ("unsupported problemType");
480 }
482 } else if ( cmpn == NonLinearLhs ) {
483 // K_eff = (a*K + C/dt)
484 if ( !this->keepTangent || !this->hasTangent ) {
485 this->effectiveMatrix->zero();
486 if (this->problemType == "up") {
487 UPLhsAssembler jacobianAssembler(this->alpha, tStep->giveTimeIncrement());
488 //Assembling left hand side
489 this->assemble( *effectiveMatrix, tStep, jacobianAssembler,
491 } else if (this->problemType == "tm") {
492 TMLhsAssembler jacobianAssembler(this->alpha, tStep->giveTimeIncrement());
493 //Assembling left hand side
494 this->assemble( *effectiveMatrix, tStep, jacobianAssembler,
496 } else {
497 OOFEM_ERROR ("unsupported problemType");
498 }
499 this->hasTangent = true;
500 }
501 } else {
502 OOFEM_ERROR("Unknown component");
503 }
504}
505
506
507void
508MPMProblem :: applyIC()
509{
510 Domain *domain = this->giveDomain(1);
511 OOFEM_LOG_INFO("Applying initial conditions\n");
512
513 this->field->applyDefaultInitialCondition();
514
515 // set initial field IP values (needed by some nonlinear materials)
517 for ( auto &elem : domain->giveElements() ) {
518 Element *element = elem.get();
519 element->updateInternalState(s);
520 element->updateYourself(s);
521 }
522}
523
524
525bool
526MPMProblem :: requiresEquationRenumbering(TimeStep *tStep)
527{
529 if ( tStep->isTheFirstStep() ) {
530 return true;
531 }
532 // Check if Dirichlet b.c.s has changed.
533 Domain *d = this->giveDomain(1);
534 for ( auto &gbc : d->giveBcs() ) {
535 ActiveBoundaryCondition *active_bc = dynamic_cast< ActiveBoundaryCondition * >(gbc.get());
536 BoundaryCondition *bc = dynamic_cast< BoundaryCondition * >(gbc.get());
537 // We only need to consider Dirichlet b.c.s
538 if ( bc || ( active_bc && ( active_bc->requiresActiveDofs() || active_bc->giveNumberOfInternalDofManagers() ) ) ) {
539 // Check of the dirichlet b.c. has changed in the last step (if so we need to renumber)
540 if ( gbc->isImposed(tStep) != gbc->isImposed(tStep->givePreviousStep()) ) {
541 return true;
542 }
543 }
544 }
545 return false;
546}
547
548int
549MPMProblem :: forceEquationNumbering()
550{
551 this->effectiveMatrix = nullptr;
552 return EngngModel :: forceEquationNumbering();
553}
554
555
556void
557MPMProblem :: printOutputAt(FILE *file, TimeStep *tStep)
558{
559 if ( !this->giveDomain(1)->giveOutputManager()->testTimeStepOutput(tStep) ) {
560 return; // Do not print even Solution step header
561 }
562
563 EngngModel :: printOutputAt(file, tStep);
564
565
566 /*
567 // computes and prints reaction forces in all supported or restrained dofs
568 fprintf(file, "\n\n\tR E A C T I O N S O U T P U T:\n\t_______________________________\n\n\n");
569
570 IntArray restrDofMans, restrDofs, eqn;
571 int di=1;
572 //from StructuralEngngModel :: buildReactionTable(dofManMap, dofidMap, eqnMap, tStep, 1);
573 // determine number of restrained dofs
574 Domain *domain = this->giveDomain(di);
575 int numRestrDofs = this->giveNumberOfDomainEquations( di, EModelDefaultPrescribedEquationNumbering() );
576 int ndofMan = domain->giveNumberOfDofManagers();
577 int rindex, count = 0;
578
579 // initialize corresponding dofManagers and dofs for each restrained dof
580 restrDofMans.resize(numRestrDofs);
581 restrDofs.resize(numRestrDofs);
582 eqn.resize(numRestrDofs);
583
584 for ( int i = 1; i <= ndofMan; i++ ) {
585 DofManager *inode = domain->giveDofManager(i);
586 for ( Dof *jdof: *inode ) {
587 if ( jdof->isPrimaryDof() && ( jdof->hasBc(tStep) ) ) { // skip slave dofs
588 rindex = jdof->__givePrescribedEquationNumber();
589 if ( rindex ) {
590 count++;
591 restrDofMans.at(count) = i;
592 restrDofs.at(count) = jdof->giveDofID();
593 eqn.at(count) = rindex;
594 } else {
595 // NullDof has no equation number and no prescribed equation number
596 //_error("No prescribed equation number assigned to supported DOF");
597 }
598 }
599 }
600 }
601 // Trim to size.
602 restrDofMans.resizeWithValues(count);
603 restrDofs.resizeWithValues(count);
604 eqn.resizeWithValues(count);
605
606 //restrDofMans.printYourself();
607 //restrDofs.printYourself();
608 //eqn.printYourself();
609
610 //from StructuralEngngModel :: computeReaction()
611 FloatArray internal, external;
612 internal.resize( this->giveNumberOfDomainEquations( di, EModelDefaultPrescribedEquationNumbering() ) );
613 internal.zero();
614
615 // Add internal forces
616 this->assembleVector( internal, tStep, InternalForceAssembler(), VM_Total,
617 EModelDefaultPrescribedEquationNumbering(), this->giveDomain(di), &this->eNorm );
618 // Subtract external loading
619 external.resize(internal.giveSize());
620 this->assembleVector( external, tStep, ExternalForceAssembler(), VM_Total, EModelDefaultPrescribedEquationNumbering(), this->giveDomain(di), &this->eNorm );
621
622 internal.subtract(external);
623 //internal.printYourself();
624
625 //
626 // loop over reactions and print them
627 //
628 for ( int i = 1; i <= restrDofMans.giveSize(); i++ ) {
629 if ( domain->giveOutputManager()->testDofManOutput(restrDofMans.at(i), tStep) ) {
630 fprintf(file, "\tNode %8d iDof %2d reaction % .4e [bc-id: %d]\n",
631 domain->giveDofManager( restrDofMans.at(i) )->giveLabel(),
632 restrDofs.at(i), internal.at( eqn.at(i) ),
633 domain->giveDofManager( restrDofMans.at(i) )->giveDofWithID( restrDofs.at(i) )->giveBcId() );
634 }
635 }
636 */
637}
638
639
640void
641MPMProblem :: updateYourself(TimeStep *tStep)
642{
643 EngngModel :: updateYourself(tStep);
644}
645
646void
647MPMProblem :: saveContext(DataStream &stream, ContextMode mode)
648{
649 EngngModel :: saveContext(stream, mode);
650 field->saveContext(stream);
651}
652
653
654void
655MPMProblem :: restoreContext(DataStream &stream, ContextMode mode)
656{
657 EngngModel :: restoreContext(stream, mode);
658 field->restoreContext(stream);
659}
660
661
662int
663MPMProblem :: giveUnknownDictHashIndx(ValueModeType mode, TimeStep *tStep)
664{
665 return tStep->giveNumber() % 2;
666}
667
668
669int
670MPMProblem :: requiresUnknownsDictionaryUpdate()
671{
672 return true;
673}
674
675int
676MPMProblem :: checkConsistency()
677{
678 return EngngModel :: checkConsistency();
679}
680
681
682void
683MPMProblem :: updateDomainLinks()
684{
685 EngngModel :: updateDomainLinks();
686 this->giveNumericalMethod( this->giveCurrentMetaStep() )->setDomain( this->giveDomain(1) );
687}
688
689
691{
692 /* Note: the current implementation uses MaskedPrimaryField, that is automatically updated with the model progress,
693 so the returned field always refers to active solution step.
694 */
695
696 if ( tStep != this->giveCurrentStep()) {
697 OOFEM_ERROR("Unable to return field representation for non-current time step");
698 }
699 if ( key == FT_Displacements ) {
700 return std::make_shared<MaskedPrimaryField>( key, this->field.get(), IntArray{D_u, D_v, D_w} );
701 } else if ( key == FT_Pressure ) {
702 return std::make_shared<MaskedPrimaryField>( key, this->field.get(), IntArray{P_f} );
703 } else if ( key == FT_Temperature ) {
704 return std::make_shared<MaskedPrimaryField>( key, this->field.get(), IntArray{T_f} );
705 } else {
706 return FieldPtr();
707 }
708}
709
710
711
712} // end namespace oofem
#define REGISTER_EngngModel(class)
virtual bool requiresActiveDofs()
Definition activebc.h:151
const entryListType & getElementRecords(int elem)
Definition bctracker.C:133
std::list< Entry > entryListType
Definition bctracker.h:67
bcType giveType() const override
std ::vector< std ::unique_ptr< GeneralBoundaryCondition > > & giveBcs()
Definition domain.h:349
std ::vector< std ::unique_ptr< Element > > & giveElements()
Definition domain.h:294
BCTracker * giveBCTracker()
Definition domain.C:413
virtual void giveCharacteristicMatrix(FloatMatrix &answer, CharType type, TimeStep *tStep)
Definition element.C:620
virtual int giveNumberOfDofs()
Definition element.h:239
virtual void updateYourself(TimeStep *tStep)
Definition element.C:824
virtual void giveCharacteristicVector(FloatArray &answer, CharType type, ValueModeType mode, TimeStep *tStep)
Definition element.C:631
virtual void updateInternalState(TimeStep *tStep)
Definition element.h:769
int giveNumberOfTimeStepWhenIcApply()
Returns the time step number, when initial conditions should apply.
Definition engngm.h:787
virtual TimeStep * giveCurrentStep(bool force=false)
Definition engngm.h:717
virtual int giveNumberOfDomainEquations(int di, const UnknownNumberingScheme &num)
Definition engngm.C:452
EngngModelContext * giveContext()
Context requesting service.
Definition engngm.h:1174
EngngModel(int i, EngngModel *_master=NULL)
Definition engngm.C:99
std ::unique_ptr< TimeStep > previousStep
Previous time step.
Definition engngm.h:243
MetaStep * giveCurrentMetaStep()
Returns current meta step.
Definition engngm.C:1900
int ndomains
Number of receiver domains.
Definition engngm.h:215
Domain * giveDomain(int n)
Definition engngm.C:1936
std ::unique_ptr< TimeStep > currentStep
Current time step.
Definition engngm.h:241
@ InternalForcesExchangeTag
Definition engngm.h:321
EngngModel * master
Master e-model; if defined receiver is in maintained (slave) mode.
Definition engngm.h:274
int updateSharedDofManagers(FloatArray &answer, const UnknownNumberingScheme &s, int ExchangeTag)
Definition engngm.C:2162
std ::unique_ptr< TimeStep > stepWhenIcApply
Solution step when IC (initial conditions) apply.
Definition engngm.h:239
void assembleVector(FloatArray &answer, TimeStep *tStep, const VectorAssembler &va, ValueModeType mode, const UnknownNumberingScheme &s, Domain *domain, FloatArray *eNorms=NULL)
Definition engngm.C:1106
Domain * giveDomain() const
Definition femcmpnn.h:97
int giveNumber() const
Definition femcmpnn.h:104
void registerField(FieldPtr eField, FieldType key)
void assemble(const FloatArray &fe, const IntArray &loc)
Definition floatarray.C:616
void resize(Index s)
Definition floatarray.C:94
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
void times(double s)
Definition floatarray.C:834
bool isNotEmpty() const
Returns true if receiver is not empty.
Definition floatarray.h:263
void times(double f)
void resize(Index rows, Index cols)
Definition floatmatrix.C:79
void zero()
Zeroes all coefficient of receiver.
bool isNotEmpty() const
Tests for empty matrix.
void assemble(const FloatMatrix &src, const IntArray &loc)
virtual int giveNumberOfInternalDofManagers()
Gives the number of internal dof managers.
virtual bcGeomType giveBCGeoType() const
virtual bool hasField(InputFieldType id)=0
Returns true if record contains field identified by idString keyword.
Base class for elements based on mp (multi-physics) concept.
Definition mpm.h:282
virtual void getSurfaceElementCodeNumbers(IntArray &answer, const Variable::VariableQuantity q, int isurf) const
Returns element code numbers of the unknowns associated with given boundary entity.
Definition mpm.h:403
virtual void getEdgeElementCodeNumbers(IntArray &answer, const Variable::VariableQuantity q, int isurf) const
Definition mpm.h:411
virtual void getLocalCodeNumbers(IntArray &answer, const Variable::VariableQuantity q) const
Definition mpm.h:375
virtual void giveCharacteristicMatrixFromBC(FloatMatrix &answer, CharType type, TimeStep *tStep, GeneralBoundaryCondition *bc, int boundaryID)
Definition mpm.h:524
virtual void giveCharacteristicVectorFromBC(FloatArray &answer, CharType type, ValueModeType mode, TimeStep *tStep, GeneralBoundaryCondition *bc, int boundaryID)
Definition mpm.h:527
double deltaT
Length of time step.
Definition mpmproblem.h:145
FloatArray prescribedTimes
Specified times where the problem is solved.
Definition mpmproblem.h:150
std::string problemType
identifies what problem to solve (UP, UPV, etc)
Definition mpmproblem.h:154
virtual void applyIC()
Definition mpmproblem.C:508
int dtFunction
Associated time function for time step increment.
Definition mpmproblem.h:148
SparseMtrxType sparseMtrxType
Definition mpmproblem.h:130
void updateInternalRHS(FloatArray &answer, TimeStep *tStep, Domain *d, FloatArray *eNorm) override
Definition mpmproblem.C:422
std ::unique_ptr< SparseNonLinearSystemNM > nMethod
Numerical method used to solve the problem.
Definition mpmproblem.h:140
FloatArray eNorm
Definition mpmproblem.h:137
FieldPtr giveField(FieldType key, TimeStep *tStep) override
Definition mpmproblem.C:690
std ::unique_ptr< SparseMtrx > effectiveMatrix
Definition mpmproblem.h:133
NumericalMethod * giveNumericalMethod(MetaStep *mStep) override
Returns reference to receiver's numerical method.
Definition mpmproblem.C:235
std ::unique_ptr< DofDistributedPrimaryField > field
Definition mpmproblem.h:131
double initT
Initial time from which the computation runs. Default is zero.
Definition mpmproblem.h:143
double giveDiscreteTime(int iStep)
Definition mpmproblem.C:315
IntArray exportFields
Definition mpmproblem.h:152
double giveDeltaT(int n)
Definition mpmproblem.C:303
FloatArray internalForces
Definition mpmproblem.h:136
FloatArray solution
Definition mpmproblem.h:135
TimeStep * giveSolutionStepWhenIcApply(bool force=false) override
Definition mpmproblem.C:343
virtual void zero()=0
Zeroes the receiver.
ConvergedReason convergedReason
Status of solution step (Converged,.
Definition timestep.h:120
double giveTimeIncrement()
Returns solution step associated time increment.
Definition timestep.h:168
double giveTargetTime()
Returns target time.
Definition timestep.h:164
int numberOfIterations
Number of itarations needed to achieve convergence.
Definition timestep.h:116
int giveNumber()
Returns receiver's number.
Definition timestep.h:144
TimeStep * givePreviousStep()
Returns pointer to previous solution step.
Definition timestep.C:132
bool isTheFirstStep()
Definition timestep.C:148
#define _IFT_EngngModel_smtype
Definition engngm.h:92
#define OOFEM_ERROR(...)
Definition error.h:79
#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_RELEVANT(...)
Definition logger.h:142
#define _IFT_MPMProblem_deltat
Definition mpmproblem.h:50
#define _IFT_MPMProblem_initt
Definition mpmproblem.h:49
#define _IFT_MPMProblem_deltatfunction
Definition mpmproblem.h:51
#define _IFT_MPMProblem_prescribedtimes
Definition mpmproblem.h:52
#define _IFT_MPMProblem_alpha
Definition mpmproblem.h:53
#define _IFT_MPMProblem_problemType
Definition mpmproblem.h:56
#define _IFT_MPMProblem_exportFields
Fields to export for staggered problems.
Definition mpmproblem.h:55
#define _IFT_MPMProblem_keepTangent
Fixes the tangent to be reused on each step.
Definition mpmproblem.h:54
long ContextMode
Definition contextmode.h:43
FieldType
Physical type of field.
Definition field.h:64
@ SurfaceLoadBGT
Distributed surface load.
Definition bcgeomtype.h:45
FloatArrayF< N > assemble(const FloatArrayF< M > &x, int const (&c)[M])
Assemble components into zero matrix.
@ SMT_Skyline
Symmetric skyline.
ClassFactory & classFactory
@ ConvectionBC
Newton type - transfer coefficient.
Definition bctype.h:44
std::shared_ptr< Field > FieldPtr
Definition field.h:78
@ NonLinearLhs
@ InternalRhs

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