Line |
Branch |
Exec |
Source |
1 |
|
|
// ______ ______ _ _ _____ ______ |
2 |
|
|
// | ____| ____| | (_)/ ____| | ____| |
3 |
|
|
// | |__ | |__ | | _| (___ ___| |__ |
4 |
|
|
// | __| | __| | | | |\___ \ / __| __| |
5 |
|
|
// | | | |____| |____| |____) | (__| |____ |
6 |
|
|
// |_| |______|______|_|_____/ \___|______| |
7 |
|
|
// Finite Elements for Life Sciences and Engineering |
8 |
|
|
// |
9 |
|
|
// License: LGL2.1 License |
10 |
|
|
// FELiScE default license: LICENSE in root folder |
11 |
|
|
// |
12 |
|
|
// Main authors: M. Aletti |
13 |
|
|
// |
14 |
|
|
|
15 |
|
|
#if FELISCE_WITH_CVGRAPH |
16 |
|
|
#ifndef _CVGMAINSLAVE_HPP |
17 |
|
|
#define _CVGMAINSLAVE_HPP |
18 |
|
|
|
19 |
|
|
// System includes |
20 |
|
|
|
21 |
|
|
// External includes |
22 |
|
|
|
23 |
|
|
// Project includes |
24 |
|
|
#include "Graph/cvgraph.hpp" |
25 |
|
|
#include "MessageInterface/messageAdm.hpp" |
26 |
|
|
#include "Solver/linearProblem.hpp" |
27 |
|
|
#include "PETScInterface/petscMatrix.hpp" |
28 |
|
|
#include "Core/chrono.hpp" |
29 |
|
|
|
30 |
|
|
using namespace cvgraph; |
31 |
|
|
|
32 |
|
|
/*! |
33 |
|
|
\file cvgMainSlave.hpp |
34 |
|
|
\authors M. Aletti |
35 |
|
|
\date Oct 2016 |
36 |
|
|
\brief cvgMainSlave class. |
37 |
|
|
|
38 |
|
|
This class is meant to be a wrapper of the cvgraph utilities. |
39 |
|
|
This class can be used (and compiled) only when the flag FELISCE_WITHCVGRAPH |
40 |
|
|
is activated. |
41 |
|
|
The class is meant to work correctly in parallel, however the communications |
42 |
|
|
and the interpolation are done only by the master. |
43 |
|
|
This parallel/sequential difference should be handled inside the class. |
44 |
|
|
From outside this class should be considered as parallel. |
45 |
|
|
|
46 |
|
|
This object is associated to a compartment (node) of the graph. |
47 |
|
|
|
48 |
|
|
TODO: |
49 |
|
|
1. change the name from cvgMainSlave to something better. |
50 |
|
|
2. the class contains a pointer to a linear problem. What if we want to use a felisce model that contains two linear problems? |
51 |
|
|
*/ |
52 |
|
|
namespace felisce |
53 |
|
|
{ |
54 |
|
|
class cvgMainSlave |
55 |
|
|
{ |
56 |
|
|
private: |
57 |
|
|
// The empty constructor is removed. |
58 |
|
|
cvgMainSlave(); |
59 |
|
|
public: |
60 |
|
|
// Constructor |
61 |
|
|
cvgMainSlave(int argc, char ** argv); |
62 |
|
|
//Sending time before exchanging initial condition |
63 |
|
|
void exchangeInitialCondition(); |
64 |
|
|
// To build m_interpolator matrix, and exchange interface information. |
65 |
|
|
void buildInterpolator(LinearProblem* pt); |
66 |
|
|
// First contact with the master |
67 |
|
|
void firstContact(); |
68 |
|
|
// Interpolate the data and send them |
69 |
|
|
void sendData(std::vector<PetscVector>& sequentialVolumeVectors, std::size_t iConn); |
70 |
|
|
// just receive them |
71 |
|
|
void receiveData(std::vector<PetscVector>& sequentialVolumeVectors, std::size_t iConn); |
72 |
|
|
// update time iteration in the case of a new time step |
73 |
|
|
void printIteration(int& timeIteration); |
74 |
|
|
|
75 |
|
|
// Useful functions to check the time status. |
76 |
|
✗ |
inline bool newTimeStep() const { |
77 |
|
✗ |
return this->checkTimeStatus(cvgraph::CVG_TIME_STATUS_NEW_TIME_STEP); |
78 |
|
|
} |
79 |
|
✗ |
inline bool redoTimeStep() const { |
80 |
|
✗ |
return this->checkTimeStatus(cvgraph::CVG_TIME_STATUS_REDO_TIME_STEP); |
81 |
|
|
} |
82 |
|
✗ |
inline bool redoTimeStepOnlyCVGData() const { |
83 |
|
✗ |
return this->checkTimeStatus(cvgraph::CVG_TIME_STATUS_REDO_TIME_STEP_ONLY_CVGDATA); |
84 |
|
|
} |
85 |
|
|
inline bool stop() const { |
86 |
|
|
return this->checkTimeStatus(cvgraph::CVG_TIME_STATUS_STOP); |
87 |
|
|
} |
88 |
|
✗ |
inline const std::vector<int>& interfaceLabels(std::size_t iConn) const { |
89 |
|
✗ |
return m_interfaceLabels[iConn]; |
90 |
|
|
} |
91 |
|
|
// Getters |
92 |
|
✗ |
inline const MessageInfo& msgInfo() const { |
93 |
|
✗ |
return m_msgInfo; |
94 |
|
|
} |
95 |
|
|
inline const CVGraphParam& cvgParam() const { |
96 |
|
|
return CVGraphParam::instance(); |
97 |
|
|
} |
98 |
|
✗ |
inline std::size_t numVarToRead(std::size_t iConn) const { |
99 |
|
✗ |
return m_numVarToRead[iConn]; |
100 |
|
|
} |
101 |
|
✗ |
inline std::size_t numVarToSend(std::size_t iConn) const { |
102 |
|
✗ |
return m_numVarToSend[iConn]; |
103 |
|
|
} |
104 |
|
✗ |
inline const std::string& sendVariable(std::size_t iConn, std::size_t cVar) const { |
105 |
|
✗ |
FEL_ASSERT(iConn<m_sendVariables.size()); |
106 |
|
✗ |
FEL_ASSERT(cVar<m_sendVariables[iConn].size()); |
107 |
|
✗ |
return m_sendVariables[iConn][cVar]; |
108 |
|
|
} |
109 |
|
✗ |
inline const std::string& readVariable(std::size_t iConn, std::size_t cVar) const { |
110 |
|
✗ |
return m_readVariables[iConn][cVar]; |
111 |
|
|
} |
112 |
|
✗ |
inline std::size_t numConnections() const { |
113 |
|
✗ |
return m_numOfNeighbours; |
114 |
|
|
} |
115 |
|
✗ |
inline std::size_t residualInterpolationType(std::size_t iConn) const { |
116 |
|
✗ |
return m_residualInterpolationType[iConn]; |
117 |
|
|
} |
118 |
|
|
|
119 |
|
|
bool initialConditionNeeded( std::size_t iConn ) const; |
120 |
|
|
|
121 |
|
|
// Ids |
122 |
|
✗ |
std::size_t iConn(std::size_t IdConn) const { |
123 |
|
✗ |
return m_iConnFromIds.at(IdConn); |
124 |
|
|
} |
125 |
|
✗ |
std::size_t IdConn(std::size_t iConn) const { |
126 |
|
✗ |
return m_IdsOfConnections[iConn]; |
127 |
|
|
} |
128 |
|
|
|
129 |
|
|
void print() const; |
130 |
|
|
private: |
131 |
|
|
// Data of the compartment |
132 |
|
|
int m_cmptId; // id of the current compartment in the graph |
133 |
|
|
std::string m_cmptName; // its name |
134 |
|
|
LinearProblem* m_lpb; // its linear problem |
135 |
|
|
|
136 |
|
|
// General cvg info |
137 |
|
|
CVGraph m_cvg; // the graph |
138 |
|
|
int m_protocol; // protocol |
139 |
|
|
MessageInfo m_msgInfo; // message info |
140 |
|
|
MessageAdm* m_msg; // ptr to the message administrator |
141 |
|
|
int m_verbose; // cvgraph verbosity level |
142 |
|
|
|
143 |
|
|
// COMMENT ON THE IDs. |
144 |
|
|
// the current compartment has m_numOfNeighbours neighbours. |
145 |
|
|
// Each of these compartments is connected to the current one via one connections. |
146 |
|
|
// |
147 |
|
|
// Inside this class iConn and iCmpt take values in 0...m_numOfNeighbours - 1 and are interchangeable. |
148 |
|
|
// However, in the global graph each compartment is described by a different ids in 0...NUM OF NODES |
149 |
|
|
// Similarly there are ids for the connections in 0...NUM OF EDGES |
150 |
|
|
// Consider that NUM OF NODES != NUM OF EDGES. |
151 |
|
|
// |
152 |
|
|
// Finally consider that in cvgraph the so-called descriptor are used to identify a connection-edge or a compartment-node. |
153 |
|
|
// These are object of the boost library and they can be obtained from the Ids through some utility functions in cvgraph. |
154 |
|
|
std::size_t m_numOfNeighbours; // the number of nodes that are connected to it |
155 |
|
|
std::vector<std::size_t> m_IdsOfOtherCompartments; // the ids of those nodes in the graph |
156 |
|
|
std::vector<std::size_t> m_IdsOfConnections; // the ids of the corresponding connections |
157 |
|
|
std::map<std::size_t,std::size_t> m_iConnFromIds; // inverse of the std::vector above |
158 |
|
|
|
159 |
|
|
|
160 |
|
|
// For each connection we have an interpolator |
161 |
|
|
std::vector<PetscMatrix*> m_interpolator; // interpolator matrix from this compartments to another one |
162 |
|
|
std::vector<PetscMatrix*> m_interpolatorBackward; // interpolator matrix from another compartment to this one. (its transpose has the same dimension as the interpolator |
163 |
|
|
|
164 |
|
|
std::vector<std::vector<int> > m_interfaceLabels; // for each connection, the list of the surface label of the interface |
165 |
|
|
|
166 |
|
|
std::vector<CVGraphData*> m_data_recv; |
167 |
|
|
std::vector<CVGraphData*> m_data_send; |
168 |
|
|
|
169 |
|
|
std::vector<int> m_dimOfDataToReceive; //ncols; |
170 |
|
|
std::vector<int> m_dimOfDataToSend; //nrows; |
171 |
|
|
|
172 |
|
|
std::vector<PetscVector> m_dataSendPreInterpolation; |
173 |
|
|
std::vector<PetscVector> m_dataSend; |
174 |
|
|
|
175 |
|
|
bool checkTimeStatus( const cvgraph::CVGStatus flag) const; |
176 |
|
|
void checkCustomFileCompleted( std::string keyword, std::size_t iBD ) const; |
177 |
|
|
void customFileCompleted( std::string keyword, std::size_t iBD ) const; |
178 |
|
|
std::string fileName(std::string keyword, std::size_t iConn, std::string readOrWrite, std::string folder="") const; |
179 |
|
|
ChronoInstance::Pointer m_receiveChronoPtr; |
180 |
|
|
|
181 |
|
|
// For each connection, this compartment knows which variable (denoted by a std::string) has to be sent or read. |
182 |
|
|
// depending on this the user can make the different choices. |
183 |
|
|
// These to functions are private because the user is not supposed to use them, he should use the getters sendVariable/readVariable |
184 |
|
✗ |
std::string variableToSend( int IdConn, std::size_t cVar ) { |
185 |
|
✗ |
return m_cvg.graph()[m_cvg.connectDescriptor( IdConn ) ].toBeSentVariable(m_cmptName, cVar); |
186 |
|
|
} |
187 |
|
✗ |
std::string variableToRead( int IdConn, std::size_t cVar ) { |
188 |
|
✗ |
return m_cvg.graph()[m_cvg.connectDescriptor( IdConn ) ].toBeReadVariable(m_cmptName, cVar); |
189 |
|
|
} |
190 |
|
|
std::vector<std::size_t> m_numVarToRead, m_numVarToSend; |
191 |
|
|
std::vector<std::vector<std::string> > m_sendVariables, m_readVariables; |
192 |
|
|
|
193 |
|
|
// id of the variable which has to be passed. For instance 0 for velocity in NS. If we wanted for some reason to couple the pressure it should be one |
194 |
|
|
std::vector<std::size_t> m_IdsOfVarToExchange; // It is std::vector because in principle we could couple more than one variable at the same time (think about poro elasticity, where could couple displacement, but also the flow). For now, it has been always used as a scalar. |
195 |
|
|
|
196 |
|
|
void handleCouplingVariablesAndOverwriteBC(); |
197 |
|
|
std::vector<int> m_residualInterpolationType; |
198 |
|
|
void exchangeBackwardInterpolators(); |
199 |
|
|
|
200 |
|
|
public: |
201 |
|
|
// Utility functions to classify the nature of the BCs on a given connection |
202 |
|
|
|
203 |
|
|
// Wether we need to sum the residual directly in the RHS. |
204 |
|
|
// This happend for neumann and for robin conditions, but only when the residualInterpType == 1 |
205 |
|
✗ |
inline bool sumDirectlyIntoRHS(std::size_t iConn) const { |
206 |
|
✗ |
return ( neumann(iConn) || robin(iConn) ) && m_residualInterpolationType[iConn] == 1; |
207 |
|
|
} |
208 |
|
|
// neumann bondary condition, one variable to read and of type neumann |
209 |
|
✗ |
inline bool neumann(std::size_t iConn) const { |
210 |
|
✗ |
return m_numVarToRead[iConn] == 1 && CVGraph::neumannTypeVariable(m_readVariables[iConn][0]); |
211 |
|
|
} |
212 |
|
|
// dirichlet bondary condition, one variable to read and of type dirichlet |
213 |
|
✗ |
inline bool dirichlet(std::size_t iConn) const { |
214 |
|
✗ |
return m_numVarToRead[iConn] == 1 && CVGraph::dirichletTypeVariable(m_readVariables[iConn][0]); |
215 |
|
|
} |
216 |
|
|
// robin boundary condition, two variables to read. |
217 |
|
✗ |
inline bool robin(std::size_t iConn) const { |
218 |
|
✗ |
return m_numVarToRead[iConn] == 2; |
219 |
|
|
} |
220 |
|
|
// returns the neumann of the boundary condition if it is of neumann or robin type |
221 |
|
|
// if it is of dirichlet type it returns "Error" |
222 |
|
|
std::string neumannVariable(std::size_t iConn) const; |
223 |
|
|
|
224 |
|
|
// return true if there is at least one dirichlet condition |
225 |
|
✗ |
inline bool thereIsAtLeastOneDirichletCondition() const { |
226 |
|
✗ |
return thereIsAtLeastOneConditionOfType(&cvgMainSlave::dirichlet); |
227 |
|
|
} |
228 |
|
|
// return true if there is at least one robin condition |
229 |
|
✗ |
inline bool thereIsAtLeastOneRobinCondition() const { |
230 |
|
✗ |
return thereIsAtLeastOneConditionOfType(&cvgMainSlave::robin); |
231 |
|
|
} |
232 |
|
|
// return true if there is at least one neumann condition |
233 |
|
✗ |
inline bool thereIsAtLeastOneNeumannCondition() const { |
234 |
|
✗ |
return thereIsAtLeastOneConditionOfType(&cvgMainSlave::neumann); |
235 |
|
|
} |
236 |
|
✗ |
inline bool thereIsAtLeastOneNaturalCondition() const { |
237 |
|
✗ |
return thereIsAtLeastOneNeumannCondition() || thereIsAtLeastOneRobinCondition(); |
238 |
|
|
} |
239 |
|
|
private: |
240 |
|
|
// return true if there is at least one connection satisfying the function test. |
241 |
|
|
bool thereIsAtLeastOneConditionOfType(bool(cvgMainSlave::*test)(std::size_t) const) const; |
242 |
|
|
}; |
243 |
|
|
} |
244 |
|
|
#endif |
245 |
|
|
#endif |
246 |
|
|
|