OOFEM 3.0
Loading...
Searching...
No Matches
stokesflowvelocityhomogenization.C
Go to the documentation of this file.
1/*
2 *
3 * ##### ##### ###### ###### ### ###
4 * ## ## ## ## ## ## ## ### ##
5 * ## ## ## ## #### #### ## # ##
6 * ## ## ## ## ## ## ## ##
7 * ## ## ## ## ## ## ## ##
8 * ##### ##### ## ###### ## ##
9 *
10 * OOFEM : Object Oriented Finite Element Code
11 *
12 * Copyright (C) 1993 - 2025 Borek Patzak
13 *
14 *
15 *
16 * Czech Technical University, Faculty of Civil Engineering,
17 * Department of Structural Mechanics, 166 29 Prague, Czech Republic
18 *
19 * This library is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU Lesser General Public
21 * License as published by the Free Software Foundation; either
22 * version 2.1 of the License, or (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 * Lesser General Public License for more details.
28 *
29 * You should have received a copy of the GNU Lesser General Public
30 * License along with this library; if not, write to the Free Software
31 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
32 */
33
35#include "classfactory.h"
36#include "dofmanager.h"
37#include "gausspoint.h"
38#include "feinterpol.h"
40#include "sparsemtrx.h"
41#include "deadweight.h"
42#include "mathfem.h"
43
44namespace oofem {
46
47StokesFlowVelocityHomogenization :: StokesFlowVelocityHomogenization(int i, EngngModel *_master) : StokesFlow(i, _master)
48{
49}
50
51
52double
53StokesFlowVelocityHomogenization :: giveAreaOfRVE()
54{
55 auto min = this->giveDomain(1)->giveDofManager(1)->giveCoordinates();
56 auto max = this->giveDomain(1)->giveDofManager(1)->giveCoordinates();
57
58 for ( auto &node : this->giveDomain(1)->giveDofManagers() ) {
59 min.beMinOf( min, node->giveCoordinates() );
60 max.beMaxOf( max, node->giveCoordinates() );
61 }
62
63 max.subtract(min);
64 return max.product();
65}
66
67
68void
69StokesFlowVelocityHomogenization :: computeSeepage(FloatArray &v, TimeStep *tStep)
70{
72 FloatArray v_hatTemp, unknowns;
73
74 v.clear();
75
76 for ( auto &elem : this->giveDomain(1)->giveElements() ) {
77 this->integrateNMatrix(N, *elem, tStep);
78 elem->computeVectorOf({V_u, V_v, V_w}, VM_Total, tStep, unknowns);
79 v_hatTemp.beProductOf(N, unknowns);
80 v.add(v_hatTemp);
81 }
82
83 v.times( 1. / this->giveAreaOfRVE() );
84}
85
86
87void
88StokesFlowVelocityHomogenization :: computeTangent(FloatMatrix &answer, TimeStep *tStep)
89{
90 IntArray loc, col;
91
92 Domain *domain = this->giveDomain(1);
93 int nsd = domain->giveNumberOfSpatialDimensions();
95
96 // Build F matrix
97 IntArray dofs(nsd);
98 for ( int i = 0; i < nsd; ++i ) {
99 dofs[i] = V_u + i;
100 }
101 FloatMatrix F(ndof, nsd), Fe, N;
102 col.enumerate(nsd);
103
104 for ( auto &elem : domain->giveElements() ) {
105
106 this->integrateNMatrix(N, *elem, tStep);
107
108 elem->giveLocationArray( loc, dofs, EModelDefaultEquationNumbering() );
110 F.assemble(Fe, loc, col);
111 }
112
113 FloatMatrix H;
114
115 std :: unique_ptr< SparseLinearSystemNM > solver( classFactory.createSparseLinSolver(solverType, this->giveDomain(1), this) );
116
117 H.resize( F.giveNumberOfRows(), F.giveNumberOfColumns() );
118 H.zero();
119
120 // For correct homogenization, the tangent at the converged values should be used
121 // (the one from the Newton iterations from solveYourselfAt is not updated to contain the latest values).
122 SparseMtrxType stype = solver->giveRecommendedMatrix(true);
123 std :: unique_ptr< SparseMtrx > Kff( classFactory.createSparseMtrx( stype ) );
124 Kff->buildInternalStructure(this, domain->giveNumber(), EModelDefaultEquationNumbering() );
125 this->assemble(*Kff, tStep, TangentAssembler(TangentStiffness), EModelDefaultEquationNumbering(), domain);
126 solver->solve(*Kff, F, H);
127
128 answer.beTProductOf(H, F);
129 answer.times( 1. / this->giveAreaOfRVE() );
130}
131
132
133void
134StokesFlowVelocityHomogenization :: integrateNMatrix(FloatMatrix &N, Element &elem, TimeStep *tStep)
135{
136 FloatArray n, n2;
137
138 for ( GaussPoint *gp: *elem.giveDefaultIntegrationRulePtr() ) {
139 const FloatArray &lcoords = gp->giveNaturalCoordinates();
140
142 elem.giveInterpolation()->evalN( n, lcoords, FEIElementGeometryWrapper(&elem) );
143 double detJ = fabs( elem.giveInterpolation()->giveTransformationJacobian( lcoords, FEIElementGeometryWrapper(&elem) ) );
144 n2.add(gp->giveWeight() * detJ, n);
145 }
146
147 N.beNMatrixOf(n2, this->giveDomain(1)->giveNumberOfSpatialDimensions());
148}
149
150
151void
152StokesFlowVelocityHomogenization :: applyPressureGradient(const FloatArray &grad)
153{
154 FloatArray components = grad;
155 components.negated();
156
158 for ( auto &bc : this->giveDomain(1)->giveBcs() ) {
159 DeadWeight *load = dynamic_cast< DeadWeight* >( bc.get() );
160 if ( load ) {
161 load->setDeadWeighComponents(components);
162 break;
163 }
164 }
165}
166
167}
#define N(a, b)
#define REGISTER_EngngModel(class)
void setDeadWeighComponents(FloatArray newComponents)
Definition deadweight.C:48
int giveNumber()
Returns domain number.
Definition domain.h:281
int giveNumberOfSpatialDimensions()
Returns number of spatial dimensions.
Definition domain.C:1137
std ::vector< std ::unique_ptr< Element > > & giveElements()
Definition domain.h:294
virtual FEInterpolation * giveInterpolation() const
Definition element.h:648
virtual IntegrationRule * giveDefaultIntegrationRulePtr()
Definition element.h:886
virtual int giveNumberOfDomainEquations(int di, const UnknownNumberingScheme &num)
Definition engngm.C:452
Domain * giveDomain(int n)
Definition engngm.C:1936
virtual void evalN(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const =0
virtual double giveTransformationJacobian(const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
Definition feinterpol.C:81
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Definition floatarray.C:689
void add(const FloatArray &src)
Definition floatarray.C:218
void times(double s)
Definition floatarray.C:834
void times(double f)
void resize(Index rows, Index cols)
Definition floatmatrix.C:79
void beTranspositionOf(const FloatMatrix &src)
void zero()
Zeroes all coefficient of receiver.
void beTProductOf(const FloatMatrix &a, const FloatMatrix &b)
void enumerate(int maxVal)
Definition intarray.C:85
void integrateNMatrix(FloatMatrix &N, Element &elem, TimeStep *tStep)
LinSystSolverType solverType
Linear solver type.
Definition stokesflow.h:75
StokesFlow(int i, EngngModel *_master=nullptr)
Definition stokesflow.C:53
FloatArrayF< N > min(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
FloatArrayF< N > assemble(const FloatArrayF< M > &x, int const (&c)[M])
Assemble components into zero matrix.
FloatArrayF< N > max(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
ClassFactory & classFactory

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