LifeV
BlockJacobiPreconditioner.cpp
Go to the documentation of this file.
1 
2 #include <lifev/fsi_blocks/solver/BlockJacobiPreconditioner.hpp>
3 
4 #include <lifev/core/linear_algebra/IfpackPreconditioner.hpp>
5 #include <lifev/core/linear_algebra/MLPreconditioner.hpp>
6 #include <lifev/core/linear_algebra/TwoLevelPreconditioner.hpp>
7 #include <lifev/core/linear_algebra/AztecooOperatorAlgebra.hpp>
8 #include <lifev/core/linear_algebra/BelosOperatorAlgebra.hpp>
9 #include <lifev/core/linear_algebra/ApproximatedInvertibleRowMatrix.hpp>
10 
11 #include <lifev/core/util/Displayer.hpp>
12 #include <lifev/core/util/LifeChrono.hpp>
13 
14 
15 namespace LifeV
16 {
17 namespace Operators
18 {
19 //===========================================================================//
20 // Constructors
21 //===========================================================================//
22 
24  M_label("BlockJacobiPreconditioner"),
25  M_useTranspose(false),
31  M_shapeDerivatives ( false ),
33  M_useStabilization ( false ),
34  M_nonconforming ( false ),
35  M_useBDFStructure ( false )
36 {
37 
38 }
39 
41 {
42 
43 }
44 
45 // show information about the class
47  //std::cout<<"Dimension u: "<< M_Bt->NumGlobalRows()<<
48  //", Dimension p: "<<M_Bt->NumGlobalCols()<<std::endl;
49  //std::cout<<"Pressure correction order "<<M_p<<std::endl;
50 }
51 
52 void
54 {
55  M_FluidPrec.reset ( Operators::NSPreconditionerFactory::instance().createObject (type));
56 }
57 
58 void
60 {
61  M_monolithicMap = monolithicMap;
62 }
63 
64 void
66 {
67  M_S = S;
68  M_X_displacement.reset( new VectorEpetra_Type( M_S->map(), Unique) );
69  M_Y_displacement.reset( new VectorEpetra_Type( M_S->map(), Unique) );
70  M_structure = M_S->map().mapSize();
71 }
72 
73 void
75 {
76  M_G = G;
77  M_X_geometry.reset( new VectorEpetra_Type (M_G->map(), Unique) );
78  M_Y_geometry.reset( new VectorEpetra_Type (M_G->map(), Unique) );
79 }
80 
81 void
83  const matrixEpetraPtr_Type & Btranspose,
84  const matrixEpetraPtr_Type & B)
85 {
86  M_F = F;
87  M_Btranspose = Btranspose;
88  M_B = B;
89  M_X_velocity.reset( new VectorEpetra_Type (M_F->map(), Unique) );
90  M_X_pressure.reset( new VectorEpetra_Type (M_B->map(), Unique) );
91  M_Y_velocity.reset( new VectorEpetra_Type (M_F->map(), Unique) );
92  M_Y_pressure.reset( new VectorEpetra_Type (M_B->map(), Unique) );
93  M_fluidVelocity = M_F->map().mapSize();
94  M_fluid = M_fluidVelocity + M_B->map().mapSize();
95  M_useStabilization = false;
96 }
97 
98 void
100  const matrixEpetraPtr_Type & Btranspose,
101  const matrixEpetraPtr_Type & B,
102  const matrixEpetraPtr_Type & D)
103 {
104  M_F = F;
105  M_Btranspose = Btranspose;
106  M_B = B;
107  M_D.reset( new matrixEpetra_Type ( *D ) );
108  M_X_velocity.reset( new VectorEpetra_Type (M_F->map(), Unique) );
109  M_X_pressure.reset( new VectorEpetra_Type (M_B->map(), Unique) );
110  M_Y_velocity.reset( new VectorEpetra_Type (M_F->map(), Unique) );
111  M_Y_pressure.reset( new VectorEpetra_Type (M_B->map(), Unique) );
112  M_fluidVelocity = M_F->map().mapSize();
113  M_fluid = M_fluidVelocity + M_B->map().mapSize();
114  M_useStabilization = true;
115 }
116 
117 void
119  const matrixEpetraPtr_Type & C2transpose,
120  const matrixEpetraPtr_Type & C2,
121  const matrixEpetraPtr_Type & C1,
122  const matrixEpetraPtr_Type & C3)
123 {
124  M_C1transpose = C1transpose;
125  M_C2transpose = C2transpose;
126  M_C2 = C2;
127  M_C1 = C1;
128  M_C3 = C3;
129  M_X_lambda.reset( new VectorEpetra_Type ( M_C1->map(), Unique) );
130  M_Y_lambda.reset( new VectorEpetra_Type ( M_C1->map(), Unique) );
131  M_lambda = M_C1->map().mapSize();
132 }
133 
134 void
136  interpolationPtr_Type structureToFluid,
137  mapEpetraPtr_Type lagrangeMap)
138 {
139  M_FluidToStructureInterpolant = fluidToStructure;
140  M_StructureToFluidInterpolant = structureToFluid;
141 
142  M_lagrangeMap = lagrangeMap;
143  M_X_lambda.reset( new VectorEpetra_Type ( *M_lagrangeMap, Unique) );
144  M_Y_lambda.reset( new VectorEpetra_Type ( *M_lagrangeMap, Unique) );
145  M_lambda = M_lagrangeMap->map(Unique)->NumGlobalElements();
146  M_nonconforming = true;
147 }
148 
149 void
150 BlockJacobiPreconditioner::setUseShapeDerivatives(const bool & useShapeDerivatives)
151 {
152  M_shapeDerivatives = useShapeDerivatives;
153 }
154 
155 void
156 BlockJacobiPreconditioner::setSubiterateFluidDirichlet(const bool & subiterateFluidDirichlet)
157 {
158  M_subiterateFluidDirichlet = subiterateFluidDirichlet;
159 }
160 
161 void
163  const matrixEpetraPtr_Type & shapePressure)
164 {
165  M_shapeVelocity = shapeVelocity;
166  M_shapePressure = shapePressure;
167 }
168 
169 void
171  const matrixEpetraPtr_Type & Mp,
172  const matrixEpetraPtr_Type & Mu)
173 {
174  M_Fp = Fp;
175  M_Mp = Mp;
176  M_Mu = Mu;
177 }
178 
179 void
180 BlockJacobiPreconditioner::setOptions(const Teuchos::ParameterList& solversOptions)
181 {
182 
183  std::shared_ptr<Teuchos::ParameterList> structureMomentumOptions;
184  structureMomentumOptions.reset(new Teuchos::ParameterList(solversOptions.sublist("StructureMomentumOperator")) );
185  setStructureMomentumOptions(structureMomentumOptions);
186 
187  std::shared_ptr<Teuchos::ParameterList> geometryMomentumOptions;
188  geometryMomentumOptions.reset(new Teuchos::ParameterList(solversOptions.sublist("ALEOperator")) );
189  setGeometryOptions(geometryMomentumOptions);
190 
191  std::shared_ptr<Teuchos::ParameterList> fluidMomentumOptions;
192  fluidMomentumOptions.reset(new Teuchos::ParameterList(solversOptions.sublist("FluidMomentumOperator")) );
193  setFluidMomentumOptions(fluidMomentumOptions);
194 
195  std::shared_ptr<Teuchos::ParameterList> schurFluidOptions;
196  schurFluidOptions.reset(new Teuchos::ParameterList(solversOptions.sublist("ApproximatedSchurOperatorFluid")) );
197  setSchurOptions(schurFluidOptions);
198 
199  if ( std::strcmp(M_FluidPrec->Label(),"aPCDOperator") == 0 )
200  {
201  std::shared_ptr<Teuchos::ParameterList> pressureMassOptions;
202  pressureMassOptions.reset(new Teuchos::ParameterList(solversOptions.sublist("PressureMassOperator")) );
203  setPressureMassOptions(pressureMassOptions);
204  }
205 
206 }
207 
208 void
210 {
211  ASSERT_PRE(_oList.get() != 0, "oList pointer not valid");
213 }
214 
215 void
217 {
218  ASSERT_PRE(_oList.get() != 0, "oList pointer not valid");
219  M_geometryOptions = _oList;
220 }
221 
222 void
224 {
225  ASSERT_PRE(_oList.get() != 0, "oList pointer not valid");
226  M_fluidMomentumOptions = _oList;
227  M_FluidPrec->setMomentumOptions( M_fluidMomentumOptions );
228 }
229 
230 void
232 {
233  ASSERT_PRE(_oList.get() != 0, "oList pointer not valid");
234  M_schurOptions = _oList;
235  M_FluidPrec->setSchurOptions( M_schurOptions );
236 }
237 
238 void
240 {
241  ASSERT_PRE(_oList.get() != 0, "oList pointer not valid");
242  M_pressureMassOptions = _oList;
243  M_FluidPrec->setPressureMassOptions( M_pressureMassOptions );
244 }
245 
246 void
248 {
249  M_approximatedStructureMomentumOperator->SetRowMatrix(M_S->matrixPtr());
250  M_approximatedStructureMomentumOperator->SetParameterList(*M_structureMomentumOptions);
251  M_approximatedStructureMomentumOperator->Compute();
252 
253 }
254 
255 void
257 {
258  M_approximatedGeometryOperator->SetRowMatrix(M_G->matrixPtr());
259  M_approximatedGeometryOperator->SetParameterList(*M_geometryOptions);
260  M_approximatedGeometryOperator->Compute();
261 }
262 
263 void
265 {
266  matrixEpetraPtr_Type Fprecc;
267  matrixEpetraPtr_Type Btprecc;
268  Fprecc.reset ( new matrixEpetra_Type(*M_F) );
269  Btprecc.reset ( new matrixEpetra_Type(*M_Btranspose) );
270 
271  if ( !M_myBC->bcUpdateDone() )
272  M_myBC->bcUpdate ( *M_velocityFESpace->mesh(), M_velocityFESpace->feBd(), M_velocityFESpace->dof() );
273 
274  bcManageMatrix ( *Fprecc, *M_velocityFESpace->mesh(), M_velocityFESpace->dof(), *M_myBC, M_velocityFESpace->feBd(), 1.0, 0.0 );
275 
276  bcManageMatrix ( *Btprecc, *M_velocityFESpace->mesh(), M_velocityFESpace->dof(), *M_myBC, M_velocityFESpace->feBd(), 0.0, 0.0 );
277 
278  if ( std::strcmp(M_FluidPrec->Label(),"aSIMPLEOperator")==0 )
279  {
280  if ( !M_useStabilization )
281  M_FluidPrec->setUp( Fprecc, M_B, Btprecc);
282  else
283  M_FluidPrec->setUp( Fprecc, M_B, Btprecc, M_D);
284  }
285  else if ( std::strcmp(M_FluidPrec->Label(),"aPCDOperator")==0 )
286  {
287  M_FluidPrec->setUp( Fprecc, M_B, Btprecc, M_Fp, M_Mp, M_Mu);
288  }
289 
290  Displayer M_displayer( M_F->map().commPtr() );
291 
292  M_displayer.leaderPrint( "\tNS operator - set up the block operator...");
293  LifeChrono chrono;
294  chrono.start();
295 
296  Operators::NavierStokesOperator::operatorPtrContainer_Type operData(2,2);
297  operData(0,0) = Fprecc->matrixPtr();
298  operData(0,1) = Btprecc->matrixPtr();
299  operData(1,0) = M_B->matrixPtr();
300  if ( M_useStabilization )
301  operData(1,1) = M_D->matrixPtr();
302 
303  M_oper.reset( new Operators::NavierStokesOperator );
304  M_oper->setUp(operData, M_displayer.comm());
305  chrono.stop();
306  M_displayer.leaderPrintMax(" done in " , chrono.diff() );
307 
308  M_displayer.leaderPrint( "\tPreconditioner operator - set up the block operator...");
309  chrono.reset();
310  chrono.start();
311 
312  M_FluidPrec->setDomainMap(M_oper->OperatorDomainBlockMapPtr());
313  M_FluidPrec->setRangeMap(M_oper->OperatorRangeBlockMapPtr());
314  M_FluidPrec->updateApproximatedMomentumOperator();
315  M_FluidPrec->updateApproximatedSchurComplementOperator();
316  if ( std::strcmp(M_FluidPrec->Label(),"aPCDOperator")==0 )
317  {
318  M_displayer.leaderPrint( "\tNS operator - UPDATING PRESSURE MASS...");
319  M_FluidPrec->updateApproximatedPressureMassOperator();
320  }
321 
322  chrono.stop();
323  M_displayer.leaderPrintMax(" done in " , chrono.diff() );
324 
325  M_displayer.leaderPrint( "\tset up the Trilinos solver...");
326  chrono.start();
327 
328  std::string solverType(M_fluidMomentumOptions->sublist("FluidSolver").get<std::string>("Linear Solver Type"));
329  M_invOper.reset(Operators::InvertibleOperatorFactory::instance().createObject(solverType));
330  M_invOper->setParameterList(M_fluidMomentumOptions->sublist("FluidSolver").sublist(solverType));
331 
332  M_invOper->setOperator(M_oper);
333  M_invOper->setPreconditioner(M_FluidPrec);
334 
335  chrono.stop();
336  M_displayer.leaderPrintMax(" done in " , chrono.diff() );
337 
338 }
339 
340 inline int
342 {
343  ASSERT_PRE(X.NumVectors() == Y.NumVectors(), "X and Y must have the same number of vectors");
344 
345  //! Input vector
346  const VectorEpetra_Type X_vectorEpetra(X, M_monolithicMap, Unique);
347 
348  //! Extract each component of the input vector
349  M_X_velocity->zero();
350  M_X_velocity->subset(X_vectorEpetra, M_F->map(), 0, 0);
351 
352  M_X_pressure->zero();
353  M_X_pressure->subset(X_vectorEpetra, M_B->map(), M_fluidVelocity, 0 );
354 
355  M_X_displacement->zero();
356  M_X_displacement->subset(X_vectorEpetra, M_S->map(), M_fluid, 0 );
357 
358  if ( M_nonconforming )
359  {
360  M_X_lambda->zero();
361  M_X_lambda->subset(X_vectorEpetra, *M_lagrangeMap, M_fluid + M_structure, 0 );
362  }
363  else
364  {
365  M_X_lambda->zero();
366  M_X_lambda->subset(X_vectorEpetra, M_C1->map(), M_fluid + M_structure, 0 );
367  }
368 
369  M_X_geometry->zero();
370  M_X_geometry->subset(X_vectorEpetra, M_G->map(), M_fluid + M_structure + M_lambda , 0 );
371 
372  M_Y_displacement->zero();
373  M_approximatedStructureMomentumOperator->ApplyInverse(M_X_displacement->epetraVector(), M_Y_displacement->epetraVector() );
374 
375  if ( M_nonconforming )
376  {
377  M_Y_geometry->zero();
378  VectorEpetraPtr_Type tmp_geo ( new VectorEpetra_Type ( M_X_geometry->map() ) );
379  tmp_geo->zero();
380  M_StructureToFluidInterpolant->updateRhs(M_Y_displacement);
381  M_StructureToFluidInterpolant->interpolate();
382  M_StructureToFluidInterpolant->solution(tmp_geo);
383 
384  M_approximatedGeometryOperator->ApplyInverse(( *M_X_geometry ).epetraVector(), M_Y_geometry->epetraVector() );
385  }
386  else
387  {
388  M_approximatedGeometryOperator->ApplyInverse(( *M_X_geometry ).epetraVector(), M_Y_geometry->epetraVector() );
389  }
390 
391  VectorEpetraPtr_Type Zlambda ( new VectorEpetra_Type ( M_X_lambda->map() ) );
392  Zlambda->zero();
393 
394  if ( M_nonconforming )
395  {
396  VectorEpetraPtr_Type tmp_z_lambda ( new VectorEpetra_Type ( M_X_lambda->map() ) );
397  VectorEpetraPtr_Type tmp_z_lambda_omega ( new VectorEpetra_Type ( M_X_velocity->map() ) );
398  tmp_z_lambda->zero();
399  tmp_z_lambda_omega->zero();
400 
401  M_StructureToFluidInterpolant->updateRhs(M_Y_displacement);
402  M_StructureToFluidInterpolant->interpolate();
403  M_StructureToFluidInterpolant->solution(tmp_z_lambda_omega);
404 
405  *tmp_z_lambda_omega /= M_timeStep;
406 
407  if ( M_useBDFStructure )
408  {
409  *tmp_z_lambda_omega *= M_bdfCoef;
410  }
411  else
412  {
413  *tmp_z_lambda_omega *= M_gamma;
414  *tmp_z_lambda_omega /= M_beta;
415  }
416 
417  M_FluidToStructureInterpolant->restrictOmegaToGamma_Known(tmp_z_lambda_omega, tmp_z_lambda);
418 
419  *Zlambda = ( *M_X_lambda - *tmp_z_lambda ) ;
420  }
421  else
422  {
423  *Zlambda = ( *M_X_lambda + *M_C2* ( *M_Y_displacement ) ) ;
424  }
425 
426 
427  VectorEpetra_Type Zf_velocity ( *M_X_velocity );
428  VectorEpetra_Type Zf_pressure ( *M_X_pressure );
429  VectorEpetra_Type Wf_velocity ( Zf_velocity.map() );
430  Wf_velocity.zero();
431 
432  if ( M_nonconforming )
433  {
434  Wf_velocity += Zf_velocity;
435 
436  if ( !M_myBC->bcUpdateDone() )
437  {
438  M_myBC->bcUpdate ( *M_velocityFESpace->mesh(), M_velocityFESpace->feBd(), M_velocityFESpace->dof() );
439  }
440 
441  bcManageRhs ( Wf_velocity, *M_velocityFESpace->mesh(), M_velocityFESpace->dof(), *M_myBC, M_velocityFESpace->feBd(), 0.0, 0.0 );
442 
443  VectorEpetraPtr_Type Zlambda_omega ( new VectorEpetra_Type ( Wf_velocity.map() ) );
444 
445  M_FluidToStructureInterpolant->expandGammaToOmega_Known( Zlambda, Zlambda_omega );
446 
447  Wf_velocity += *Zlambda_omega;
448  }
449  else
450  {
451  Wf_velocity = Zf_velocity - ( *M_C1transpose * (*M_C1 * Zf_velocity) - ( *M_C1transpose * ( *Zlambda ) ) );
452  }
453 
454  M_Y_velocity->zero();
455  M_Y_pressure->zero();
456 
457  M_FluidPrec->ApplyInverse( Wf_velocity, Zf_pressure, *M_Y_velocity, *M_Y_pressure);
458 
459  M_Y_lambda->zero();
460 
461  if ( M_nonconforming )
462  {
463  VectorEpetraPtr_Type tmp_omega ( new VectorEpetra_Type ( M_Y_velocity->map() ) );
464  tmp_omega->zero();
465 
466  VectorEpetraPtr_Type tmp_gamma ( new VectorEpetra_Type ( M_Y_lambda->map() ) );
467  tmp_gamma->zero();
468 
469  *tmp_omega = Zf_velocity + ( *M_F * ( *M_Y_velocity ) + *M_Btranspose * ( *M_Y_pressure ) );
470 
471  M_FluidToStructureInterpolant->restrictOmegaToGamma_Known( tmp_omega, tmp_gamma);
472 
473  *M_Y_lambda += *tmp_gamma;
474  }
475  else
476  {
477  *M_Y_lambda = *M_C1 * ( Zf_velocity + ( *M_F * ( *M_Y_velocity ) ) );
478  }
479 
480  VectorEpetra_Type Y_vectorEpetra(Y, M_monolithicMap, Unique);
481  Y_vectorEpetra.zero();
482 
483  Y_vectorEpetra.subset(*M_Y_velocity, M_Y_velocity->map(), 0, 0 );
484  Y_vectorEpetra.subset(*M_Y_pressure, M_Y_pressure->map(), 0, M_fluidVelocity );
485  Y_vectorEpetra.subset(*M_Y_displacement, M_Y_displacement->map(), 0, M_fluid );
486  Y_vectorEpetra.subset(*M_Y_lambda, M_Y_lambda->map(), 0, M_fluid + M_structure );
487  Y_vectorEpetra.subset(*M_Y_geometry, M_Y_geometry->map(), 0, M_fluid + M_structure + M_lambda );
488  Y = dynamic_cast<Epetra_MultiVector &>( Y_vectorEpetra.epetraVector() );
489 
490  return 0;
491 }
492 
493 } /* end namespace Operators */
494 
495 } /*end namespace */
std::shared_ptr< Teuchos::ParameterList > parameterListPtr_Type
void start()
Start the timer.
Definition: LifeChrono.hpp:93
void setPressureMassOptions(const parameterListPtr_Type &_oList)
Set the list of the shur complement of the fluid.
void setStructureBlock(const matrixEpetraPtr_Type &S)
Set the structure block.
matrixEpetraPtr_Type M_C1transpose
Coupling blocks.
void setOptions(const Teuchos::ParameterList &solversOptions)
Interface to set the parameters of each block.
void setUseShapeDerivatives(const bool &useShapeDerivatives)
Set the use of shape derivatives.
parameterListPtr_Type M_structureMomentumOptions
Parameters for the structure.
parameterListPtr_Type M_geometryOptions
Parameters for the geometry.
void setGeometryOptions(const parameterListPtr_Type &_oList)
Set the list of the geometry.
VectorEpetra(const MapEpetra &map, const MapEpetraType &mapType=Unique, const combineMode_Type combineMode=Add)
Constructor - Using Maps.
void updateApproximatedStructureMomentumOperator()
Update the approximation of the structure momentum.
void updateInverseJacobian(const UInt &iQuadPt)
void setFluidBlocks(const matrixEpetraPtr_Type &F, const matrixEpetraPtr_Type &Btranspose, const matrixEpetraPtr_Type &B, const matrixEpetraPtr_Type &D)
Set the fluid blocks.
parameterListPtr_Type M_pressureMassOptions
Parameters for the pressure mass of the PCD.
void setGeometryBlock(const matrixEpetraPtr_Type &G)
Set the geometry block.
int ApplyInverse(const vector_Type &X, vector_Type &Y) const
Returns the High Order Yosida approximation of the inverse pressure Schur Complement applied to X...
void setStructureMomentumOptions(const parameterListPtr_Type &_oList)
Set the list of the structure momentum.
VectorEpetra & operator+=(const VectorEpetra &vector)
Addition operator.
std::shared_ptr< VectorEpetra_Type > VectorEpetraPtr_Type
#define ASSERT_PRE(X, A)
Definition: LifeAssert.hpp:96
const MapEpetra & map() const
Return the MapEpetra of the vector.
void setPCDBlocks(const matrixEpetraPtr_Type &Fp, const matrixEpetraPtr_Type &Mp, const matrixEpetraPtr_Type &Mu)
Set the blocks needed by the PCD preconditioner.
void setCouplingOperators_nonconforming(interpolationPtr_Type fluidToStructure, interpolationPtr_Type structureToFluid, mapEpetraPtr_Type lagrangeMap)
Copy the pointer of the interpolation objects.
parameterListPtr_Type M_schurOptions
Parameters for the shur complent of the fluid.
void showMe()
Show information about the class.
void setFluidBlocks(const matrixEpetraPtr_Type &F, const matrixEpetraPtr_Type &Btranspose, const matrixEpetraPtr_Type &B)
Set the fluid blocks.
void setFluidPreconditioner(const std::string &type)
Set the preconditioner type.
parameterListPtr_Type M_fluidMomentumOptions
Parameters for the fluid momentum.
void setFluidMomentumOptions(const parameterListPtr_Type &_oList)
Set the list of the fluid momentum.
void stop()
Stop the timer.
Definition: LifeChrono.hpp:100
void setSchurOptions(const parameterListPtr_Type &_oList)
Set the list of the shur complement of the fluid.
void updateApproximatedGeometryOperator()
Update the approximation of the the geometry.
void setShapeDerivativesBlocks(const matrixEpetraPtr_Type &ShapeVelocity, const matrixEpetraPtr_Type &ShapePressure)
Set the shape derivatives.
std::shared_ptr< Interpolation > interpolationPtr_Type
void setSubiterateFluidDirichlet(const bool &subiterateFluidDirichlet)
void updateApproximatedFluidOperator()
Update the approximation of the the geometry.
std::shared_ptr< mapEpetra_Type > mapEpetraPtr_Type
void zero()
set zero in all the vector entries
void setCouplingBlocks(const matrixEpetraPtr_Type &C1transpose, const matrixEpetraPtr_Type &C2transpose, const matrixEpetraPtr_Type &C2, const matrixEpetraPtr_Type &C1, const matrixEpetraPtr_Type &C3)
Set the coupling blocks.
Displayer - This class is used to display messages in parallel simulations.
Definition: Displayer.hpp:62
std::shared_ptr< matrixEpetra_Type > matrixEpetraPtr_Type
void setMonolithicMap(const mapEpetraPtr_Type &monolithicMap)
Set the monolithic map.