41 #ifndef DTK_SPLINEINTERPOLATIONOPERATOR_IMPL_HPP 42 #define DTK_SPLINEINTERPOLATIONOPERATOR_IMPL_HPP 44 #include "DTK_BasicEntityPredicates.hpp" 47 #include "DTK_PredicateComposition.hpp" 54 #include <Teuchos_ArrayRCP.hpp> 55 #include <Teuchos_CommHelpers.hpp> 56 #include <Teuchos_ParameterList.hpp> 57 #include <Teuchos_Ptr.hpp> 58 #include <Teuchos_XMLParameterListCoreHelpers.hpp> 60 #include <BelosPseudoBlockGmresSolMgr.hpp> 62 #include <Thyra_DefaultAddedLinearOp.hpp> 63 #include <Thyra_DefaultMultipliedLinearOp.hpp> 64 #include <Thyra_DefaultScaledAdjointLinearOp.hpp> 65 #include <Thyra_LinearOpWithSolveFactoryHelpers.hpp> 66 #include <Thyra_TpetraThyraWrappers.hpp> 68 #include <Stratimikos_DefaultLinearSolverBuilder.hpp> 74 template <
class Basis,
int DIM>
75 SplineInterpolationOperator<Basis, DIM>::SplineInterpolationOperator(
76 const Teuchos::RCP<const TpetraMap> &domain_map,
77 const Teuchos::RCP<const TpetraMap> &range_map,
78 const Teuchos::ParameterList ¶meters )
79 : Base( domain_map, range_map )
83 , d_domain_entity_dim( 0 )
84 , d_range_entity_dim( 0 )
87 if ( parameters.isParameter(
"Type of Search" ) )
89 if (
"Radius" == parameters.get<std::string>(
"Type of Search" ) )
93 else if (
"Nearest Neighbor" ==
94 parameters.get<std::string>(
"Type of Search" ) )
108 DTK_REQUIRE( parameters.isParameter(
"Num Neighbors" ) );
109 d_knn = parameters.get<
int>(
"Num Neighbors" );
115 DTK_REQUIRE( parameters.isParameter(
"RBF Radius" ) );
116 d_radius = parameters.get<
double>(
"RBF Radius" );
121 if ( parameters.isParameter(
"Domain Entity Dimension" ) )
123 d_domain_entity_dim = parameters.get<
int>(
"Domain Entity Dimension" );
125 if ( parameters.isParameter(
"Range Entity Dimension" ) )
127 d_range_entity_dim = parameters.get<
int>(
"Range Entity Dimension" );
131 if ( parameters.isSublist(
"Stratimikos" ) )
133 d_stratimikos_list = Teuchos::rcp(
134 new Teuchos::ParameterList( parameters.sublist(
"Stratimikos" ) ) );
140 template <
class Basis,
int DIM>
141 void SplineInterpolationOperator<Basis, DIM>::setupImpl(
142 const Teuchos::RCP<FunctionSpace> &domain_space,
143 const Teuchos::RCP<FunctionSpace> &range_space )
145 DTK_REQUIRE( Teuchos::nonnull( domain_space ) );
146 DTK_REQUIRE( Teuchos::nonnull( range_space ) );
149 const Teuchos::RCP<const typename Base::TpetraMap> domain_map =
150 this->getDomainMap();
151 const Teuchos::RCP<const typename Base::TpetraMap> range_map =
155 Teuchos::RCP<const Root> S;
158 Teuchos::RCP<const Root> P;
161 Teuchos::RCP<const Root> M;
164 Teuchos::RCP<const Root> Q;
167 Teuchos::RCP<const Root> N;
170 buildConcreteOperators( domain_space, range_space, S, P, M, Q, N );
173 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar>>
174 thyra_range_vector_space_S =
175 Thyra::createVectorSpace<Scalar>( S->getRangeMap() );
176 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar>>
177 thyra_domain_vector_space_S =
178 Thyra::createVectorSpace<Scalar>( S->getDomainMap() );
179 Teuchos::RCP<const Thyra::TpetraLinearOp<Scalar, LO, GO>> thyra_S =
180 Teuchos::rcp(
new Thyra::TpetraLinearOp<Scalar, LO, GO>() );
181 Teuchos::rcp_const_cast<Thyra::TpetraLinearOp<Scalar, LO, GO>>( thyra_S )
182 ->constInitialize( thyra_range_vector_space_S,
183 thyra_domain_vector_space_S, S );
186 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar>>
187 thyra_range_vector_space_P =
188 Thyra::createVectorSpace<Scalar>( P->getRangeMap() );
189 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar>>
190 thyra_domain_vector_space_P =
191 Thyra::createVectorSpace<Scalar>( P->getDomainMap() );
192 Teuchos::RCP<const Thyra::TpetraLinearOp<Scalar, LO, GO>> thyra_P =
193 Teuchos::rcp(
new Thyra::TpetraLinearOp<Scalar, LO, GO>() );
194 Teuchos::rcp_const_cast<Thyra::TpetraLinearOp<Scalar, LO, GO>>( thyra_P )
195 ->constInitialize( thyra_range_vector_space_P,
196 thyra_domain_vector_space_P, P );
199 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar>>
200 thyra_range_vector_space_M =
201 Thyra::createVectorSpace<Scalar>( M->getRangeMap() );
202 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar>>
203 thyra_domain_vector_space_M =
204 Thyra::createVectorSpace<Scalar>( M->getDomainMap() );
205 Teuchos::RCP<const Thyra::TpetraLinearOp<Scalar, LO, GO>> thyra_M =
206 Teuchos::rcp(
new Thyra::TpetraLinearOp<Scalar, LO, GO>() );
207 Teuchos::rcp_const_cast<Thyra::TpetraLinearOp<Scalar, LO, GO>>( thyra_M )
208 ->constInitialize( thyra_range_vector_space_M,
209 thyra_domain_vector_space_M, M );
212 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar>>
213 thyra_range_vector_space_Q =
214 Thyra::createVectorSpace<Scalar>( Q->getRangeMap() );
215 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar>>
216 thyra_domain_vector_space_Q =
217 Thyra::createVectorSpace<Scalar>( Q->getDomainMap() );
218 Teuchos::RCP<const Thyra::TpetraLinearOp<Scalar, LO, GO>> thyra_Q =
219 Teuchos::rcp(
new Thyra::TpetraLinearOp<Scalar, LO, GO>() );
220 Teuchos::rcp_const_cast<Thyra::TpetraLinearOp<Scalar, LO, GO>>( thyra_Q )
221 ->constInitialize( thyra_range_vector_space_Q,
222 thyra_domain_vector_space_Q, Q );
225 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar>>
226 thyra_range_vector_space_N =
227 Thyra::createVectorSpace<Scalar>( N->getRangeMap() );
228 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar>>
229 thyra_domain_vector_space_N =
230 Thyra::createVectorSpace<Scalar>( N->getDomainMap() );
231 Teuchos::RCP<const Thyra::TpetraLinearOp<Scalar, LO, GO>> thyra_N =
232 Teuchos::rcp(
new Thyra::TpetraLinearOp<Scalar, LO, GO>() );
233 Teuchos::rcp_const_cast<Thyra::TpetraLinearOp<Scalar, LO, GO>>( thyra_N )
234 ->constInitialize( thyra_range_vector_space_N,
235 thyra_domain_vector_space_N, N );
239 Teuchos::RCP<const Thyra::LinearOpBase<Scalar>> thyra_P_T =
240 Thyra::transpose<Scalar>( thyra_P );
243 Teuchos::RCP<const Thyra::LinearOpBase<Scalar>> thyra_PpM =
244 Thyra::add<Scalar>( thyra_P, thyra_M );
245 Teuchos::RCP<const Thyra::LinearOpBase<Scalar>> thyra_C =
246 Thyra::add<Scalar>( thyra_PpM, thyra_P_T );
250 if ( Teuchos::is_null( d_stratimikos_list ) )
252 d_stratimikos_list = Teuchos::parameterList(
"Stratimikos" );
254 d_stratimikos_list->set(
"Linear Solver Type",
"Belos" );
255 d_stratimikos_list->set(
"Preconditioner Type",
"None" );
257 auto &linear_solver_types_list =
258 d_stratimikos_list->sublist(
"Linear Solver Types" );
259 auto &belos_list = linear_solver_types_list.sublist(
"Belos" );
260 belos_list.set(
"Solver Type",
"Pseudo Block GMRES" );
261 auto &solver_types_list = belos_list.sublist(
"Solver Types" );
262 auto &gmres_list = solver_types_list.sublist(
"Pseudo Block GMRES" );
263 gmres_list.set(
"Convergence Tolerance", 1.0e-10 );
264 gmres_list.set(
"Verbosity",
265 Belos::Errors + Belos::Warnings + Belos::TimingDetails +
266 Belos::FinalSummary + Belos::StatusTestDetails );
267 gmres_list.set(
"Output Frequency", 1 );
271 Stratimikos::DefaultLinearSolverBuilder builder;
272 builder.setParameterList( d_stratimikos_list );
273 Teuchos::RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar>> factory =
274 Thyra::createLinearSolveStrategy( builder );
275 Teuchos::RCP<const Thyra::LinearOpBase<Scalar>> thyra_C_inv =
276 Thyra::inverse<Scalar>( *factory, thyra_C );
279 Teuchos::RCP<const Thyra::LinearOpBase<Scalar>> thyra_B =
280 Thyra::add<Scalar>( thyra_Q, thyra_N );
284 Thyra::multiply<Scalar>( thyra_B, thyra_C_inv, thyra_S );
285 DTK_ENSURE( Teuchos::nonnull( d_coupling_matrix ) );
290 template <
class Basis,
int DIM>
292 const TpetraMultiVector &X, TpetraMultiVector &Y, Teuchos::ETransp mode,
293 Scalar alpha, Scalar beta )
const 295 DTK_REQUIRE( Teuchos::NO_TRANS == mode );
296 Teuchos::RCP<const Thyra::MultiVectorBase<Scalar>> thyra_X =
297 Thyra::createConstMultiVector<Scalar>( Teuchos::rcpFromRef( X ) );
298 Teuchos::RCP<Thyra::MultiVectorBase<Scalar>> thyra_Y =
299 Thyra::createMultiVector<Scalar>( Teuchos::rcpFromRef( Y ) );
300 d_coupling_matrix->apply( Thyra::NOTRANS, *thyra_X, thyra_Y.ptr(), alpha,
306 template <
class Basis,
int DIM>
316 template <
class Basis,
int DIM>
318 const Teuchos::RCP<FunctionSpace> &domain_space,
319 const Teuchos::RCP<FunctionSpace> &range_space, Teuchos::RCP<const Root> &S,
320 Teuchos::RCP<const Root> &P, Teuchos::RCP<const Root> &M,
321 Teuchos::RCP<const Root> &Q, Teuchos::RCP<const Root> &N )
const 324 const Teuchos::RCP<const typename Base::TpetraMap> domain_map =
325 this->getDomainMap();
326 const Teuchos::RCP<const typename Base::TpetraMap> range_map =
330 bool nonnull_domain = Teuchos::nonnull( domain_space->entitySet() );
331 bool nonnull_range = Teuchos::nonnull( range_space->entitySet() );
334 Teuchos::RCP<const Teuchos::Comm<int>> comm = domain_map->getComm();
337 Teuchos::ArrayRCP<double> source_centers;
338 Teuchos::ArrayRCP<GO> source_support_ids;
339 getNodeCoordsAndIds( domain_space, d_domain_entity_dim, source_centers,
340 source_support_ids );
343 Teuchos::ArrayRCP<double> target_centers;
344 Teuchos::ArrayRCP<GO> target_support_ids;
345 getNodeCoordsAndIds( range_space, d_range_entity_dim, target_centers,
346 target_support_ids );
351 double source_proximity = 0.0;
355 Teuchos::Tuple<double, 6> local_box;
356 domain_space->entitySet()->localBoundingBox( local_box );
359 source_proximity = local_box[3] - local_box[0];
360 for (
int d = 1; d < DIM; ++d )
363 std::max( source_proximity, local_box[d + 3] - local_box[d] );
367 source_proximity *= 0.1;
371 source_proximity = d_radius;
376 Teuchos::Array<double> dist_sources;
379 source_proximity, dist_sources );
382 Teuchos::Array<GO> dist_source_support_ids(
383 source_distributor.getNumImports() );
384 Teuchos::ArrayView<const GO> source_support_ids_view = source_support_ids();
385 Teuchos::ArrayView<GO> dist_gids_view = dist_source_support_ids();
386 source_distributor.
distribute( source_support_ids_view, dist_gids_view );
390 dist_sources(), source_centers(), d_use_knn, d_knn, d_radius );
396 GO offset = comm->getRank() ? 0 : DIM + 1;
400 Teuchos::RCP<const Tpetra::Map<int, GO>> prolongated_map = S->getRangeMap();
405 prolongated_map, source_centers(), source_support_ids(), dist_sources(),
406 dist_source_support_ids(), source_pairings, *basis );
411 dist_source_support_ids.clear();
417 double target_proximity = 0.0;
421 Teuchos::Tuple<double, 6> local_box;
422 range_space->entitySet()->localBoundingBox( local_box );
425 target_proximity = local_box[3] - local_box[0];
426 for (
int d = 1; d < DIM; ++d )
429 std::max( target_proximity, local_box[d + 3] - local_box[d] );
433 target_proximity *= 0.1;
437 target_proximity = d_radius;
444 target_proximity, dist_sources );
447 dist_source_support_ids.resize( target_distributor.getNumImports() );
448 source_support_ids_view = source_support_ids();
449 dist_gids_view = dist_source_support_ids();
450 target_distributor.
distribute( source_support_ids_view, dist_gids_view );
454 dist_sources(), target_centers(), d_use_knn, d_knn, d_radius );
458 prolongated_map, range_map, target_centers(), target_support_ids(),
459 dist_sources(), dist_source_support_ids(), target_pairings, *basis );
463 DTK_ENSURE( Teuchos::nonnull( S ) );
464 DTK_ENSURE( Teuchos::nonnull( P ) );
465 DTK_ENSURE( Teuchos::nonnull( M ) );
466 DTK_ENSURE( Teuchos::nonnull( Q ) );
467 DTK_ENSURE( Teuchos::nonnull( N ) );
472 template <
class Basis,
int DIM>
474 const Teuchos::RCP<FunctionSpace> &space,
const int entity_dim,
475 Teuchos::ArrayRCP<double> ¢ers,
476 Teuchos::ArrayRCP<GO> &support_ids )
const 480 if ( Teuchos::nonnull( space->entitySet() ) )
482 LocalEntityPredicate local_predicate(
483 space->entitySet()->communicator()->getRank() );
485 space->selectFunction(), local_predicate.getFunction() );
486 iterator = space->entitySet()->entityIterator( entity_dim, predicate );
490 int local_num_node = iterator.size();
491 centers = Teuchos::ArrayRCP<double>( DIM * local_num_node );
492 support_ids = Teuchos::ArrayRCP<GO>( local_num_node );
493 Teuchos::Array<SupportId> node_supports;
496 int entity_counter = 0;
498 ++entity, ++entity_counter )
500 space->shapeFunction()->entitySupportIds( *entity, node_supports );
501 DTK_CHECK( 1 == node_supports.size() );
502 support_ids[entity_counter] = node_supports[0];
503 space->localMap()->centroid( *entity,
504 centers( DIM * entity_counter, DIM ) );
514 #endif // end DTK_SPLINEINTERPOLATIONOPERATOR_IMPL_HPP Local source/parent center pairings.
Sparse spline transformation operator (the A matrix). A = N + Q.
Spline interpolation coefficient matrix.
Sparse spline coefficient matrix.
Entity iterator interface.
static Teuchos::RCP< RadialBasis > create()
Creation method.
Prolongation operator for projecting a vector into the extended spline space.
Assertions and Design-by-Contract for error handling.
void applyImpl(const TpetraMultiVector &X, TpetraMultiVector &Y, Teuchos::ETransp mode=Teuchos::NO_TRANS, double alpha=Teuchos::ScalarTraits< double >::one(), double beta=Teuchos::ScalarTraits< double >::zero()) const override
Apply the operator.
Parallel spline interpolator.
std::function< bool(Entity)> PredicateFunction
Predicate function typedef.
Spline transformation operator.
Global source distributor.
Parallel spline interpolator.
Global center distributor.
Spline transformation operator.
Local child/parent center pairings.
void distribute(const Teuchos::ArrayView< const T > &source_decomp_data, const Teuchos::ArrayView< T > &target_decomp_data) const
Given a set of scalar values at the given source centers in the source decomposition, distribute them to the target decomposition.