@@ -245,15 +245,16 @@ public:
245245// ------------------------------------------------------------
246246// System implementation
247247void System ::project_vector (NumericVector < Number > & vector ,
248- int is_adjoint ) const
248+ int is_adjoint ,
249+ std ::optional < ConstElemRange > active_local_range ) const
249250{
250251 // Create a copy of the vector, which currently
251252 // contains the old data.
252253 std ::unique_ptr < NumericVector < Number >>
253254 old_vector (vector .clone ());
254255
255256 // Project the old vector to the new vector
256- this -> project_vector (* old_vector , vector , is_adjoint );
257+ this -> project_vector (* old_vector , vector , is_adjoint , active_local_range );
257258}
258259
259260
@@ -264,7 +265,8 @@ void System::project_vector (NumericVector<Number> & vector,
264265 */
265266void System ::project_vector (const NumericVector < Number > & old_v ,
266267 NumericVector < Number > & new_v ,
267- int is_adjoint ) const
268+ int is_adjoint ,
269+ std ::optional < ConstElemRange > active_local_range ) const
268270{
269271 LOG_SCOPE ("project_vector(old,new)" , "System" );
270272
@@ -285,9 +287,12 @@ void System::project_vector (const NumericVector<Number> & old_v,
285287 std ::unique_ptr < NumericVector < Number >> local_old_vector_built ;
286288 const NumericVector < Number > * old_vector_ptr = nullptr ;
287289
288- ConstElemRange active_local_elem_range
289- (this -> get_mesh ().active_local_elements_begin (),
290- this -> get_mesh ().active_local_elements_end ());
290+ if (!active_local_range )
291+ {
292+ active_local_range .emplace
293+ (this -> get_mesh ().active_local_elements_begin (),
294+ this -> get_mesh ().active_local_elements_end ());
295+ }
291296
292297 // If the old vector was uniprocessor, make the new
293298 // vector uniprocessor
@@ -304,7 +309,7 @@ void System::project_vector (const NumericVector<Number> & old_v,
304309 {
305310 // Build a send list for efficient localization
306311 BuildProjectionList projection_list (* this );
307- Threads ::parallel_reduce (active_local_elem_range ,
312+ Threads ::parallel_reduce (active_local_range . value () ,
308313 projection_list );
309314
310315 // Create a sorted, unique send_list
@@ -328,7 +333,7 @@ void System::project_vector (const NumericVector<Number> & old_v,
328333 {
329334 // Build a send list for efficient localization
330335 BuildProjectionList projection_list (* this );
331- Threads ::parallel_reduce (active_local_elem_range ,
336+ Threads ::parallel_reduce (active_local_range . value () ,
332337 projection_list );
333338
334339 // Create a sorted, unique send_list
@@ -389,7 +394,7 @@ void System::project_vector (const NumericVector<Number> & old_v,
389394 g (* this , old_vector , & regular_vars );
390395
391396 FEMProjector projector (* this , f , & g , setter , regular_vars );
392- projector .project (active_local_elem_range );
397+ projector .project (active_local_range . value () );
393398 }
394399
395400 if (!vector_vars .empty ())
@@ -403,7 +408,7 @@ void System::project_vector (const NumericVector<Number> & old_v,
403408 OldSolutionValue < Tensor , & FEMContext ::point_gradient > g_vector (* this , old_vector , & vector_vars );
404409
405410 FEMVectorProjector vector_projector (* this , f_vector , & g_vector , setter , vector_vars );
406- vector_projector .project (active_local_elem_range );
411+ vector_projector .project (active_local_range . value () );
407412 }
408413
409414 // Copy the SCALAR dofs from old_vector to new_vector
@@ -1068,11 +1073,12 @@ void System::project_vector (ValueFunctionPointer fptr,
10681073 GradientFunctionPointer gptr ,
10691074 const Parameters & function_parameters ,
10701075 NumericVector < Number > & new_vector ,
1071- int is_adjoint ) const
1076+ int is_adjoint ,
1077+ std ::optional < ConstElemRange > active_local_range ) const
10721078{
10731079 WrappedFunction < Number > f (* this , fptr , & function_parameters );
10741080 WrappedFunction < Gradient > g (* this , gptr , & function_parameters );
1075- this -> project_vector (new_vector , & f , & g , is_adjoint );
1081+ this -> project_vector (new_vector , & f , & g , is_adjoint , active_local_range );
10761082}
10771083
10781084/**
@@ -1082,7 +1088,8 @@ void System::project_vector (ValueFunctionPointer fptr,
10821088void System ::project_vector (NumericVector < Number > & new_vector ,
10831089 FunctionBase < Number > * f ,
10841090 FunctionBase < Gradient > * g ,
1085- int is_adjoint ) const
1091+ int is_adjoint ,
1092+ std ::optional < ConstElemRange > active_local_range ) const
10861093{
10871094 LOG_SCOPE ("project_vector(FunctionBase)" , "System" );
10881095
@@ -1094,10 +1101,10 @@ void System::project_vector (NumericVector<Number> & new_vector,
10941101 {
10951102 WrappedFunctor < Gradient > g_fem (* g );
10961103
1097- this -> project_vector (new_vector , & f_fem , & g_fem , is_adjoint );
1104+ this -> project_vector (new_vector , & f_fem , & g_fem , is_adjoint , active_local_range );
10981105 }
10991106 else
1100- this -> project_vector (new_vector , & f_fem , nullptr , is_adjoint );
1107+ this -> project_vector (new_vector , & f_fem , nullptr , is_adjoint , active_local_range );
11011108}
11021109
11031110
@@ -1108,15 +1115,19 @@ void System::project_vector (NumericVector<Number> & new_vector,
11081115void System ::project_vector (NumericVector < Number > & new_vector ,
11091116 FEMFunctionBase < Number > * f ,
11101117 FEMFunctionBase < Gradient > * g ,
1111- int is_adjoint ) const
1118+ int is_adjoint ,
1119+ std ::optional < ConstElemRange > active_local_range ) const
11121120{
11131121 LOG_SCOPE ("project_fem_vector()" , "System" );
11141122
11151123 libmesh_assert (f );
11161124
1117- ConstElemRange active_local_range
1118- (this -> get_mesh ().active_local_elements_begin (),
1119- this -> get_mesh ().active_local_elements_end () );
1125+ if (!active_local_range )
1126+ {
1127+ active_local_range .emplace
1128+ (this -> get_mesh ().active_local_elements_begin (),
1129+ this -> get_mesh ().active_local_elements_end ());
1130+ }
11201131
11211132 VectorSetAction < Number > setter (new_vector );
11221133
@@ -1137,12 +1148,12 @@ void System::project_vector (NumericVector<Number> & new_vector,
11371148 FEMFunctionWrapper < Gradient > gw (* g );
11381149
11391150 FEMProjector projector (* this , fw , & gw , setter , vars );
1140- projector .project (active_local_range );
1151+ projector .project (active_local_range . value () );
11411152 }
11421153 else
11431154 {
11441155 FEMProjector projector (* this , fw , nullptr , setter , vars );
1145- projector .project (active_local_range );
1156+ projector .project (active_local_range . value () );
11461157 }
11471158
11481159 // Also, load values into the SCALAR dofs
@@ -1197,7 +1208,7 @@ void System::project_vector (NumericVector<Number> & new_vector,
11971208 {
11981209 // Look for a spline node: a NodeElem with a rational variable
11991210 // on it.
1200- for (auto & elem : active_local_range )
1211+ for (auto & elem : active_local_range . value () )
12011212 if (elem -> type () == NODEELEM )
12021213 for (auto rational_var : rational_vars )
12031214 if (rational_var -> active_on_subdomain (elem -> subdomain_id ()))
@@ -1274,12 +1285,13 @@ void System::boundary_project_vector (const std::set<boundary_id_type> & b,
12741285 GradientFunctionPointer gptr ,
12751286 const Parameters & function_parameters ,
12761287 NumericVector < Number > & new_vector ,
1277- int is_adjoint ) const
1288+ int is_adjoint ,
1289+ std ::optional < ConstElemRange > active_local_range ) const
12781290{
12791291 WrappedFunction < Number > f (* this , fptr , & function_parameters );
12801292 WrappedFunction < Gradient > g (* this , gptr , & function_parameters );
12811293 this -> boundary_project_vector (b , variables , new_vector , & f , & g ,
1282- is_adjoint );
1294+ is_adjoint , active_local_range );
12831295}
12841296
12851297/**
@@ -1291,13 +1303,20 @@ void System::boundary_project_vector (const std::set<boundary_id_type> & b,
12911303 NumericVector < Number > & new_vector ,
12921304 FunctionBase < Number > * f ,
12931305 FunctionBase < Gradient > * g ,
1294- int is_adjoint ) const
1306+ int is_adjoint ,
1307+ std ::optional < ConstElemRange > active_local_range ) const
12951308{
12961309 LOG_SCOPE ("boundary_project_vector()" , "System" );
12971310
1311+ if (!active_local_range )
1312+ {
1313+ active_local_range .emplace
1314+ (this -> get_mesh ().active_local_elements_begin (),
1315+ this -> get_mesh ().active_local_elements_end ());
1316+ }
1317+
12981318 Threads ::parallel_for
1299- (ConstElemRange (this -> get_mesh ().active_local_elements_begin (),
1300- this -> get_mesh ().active_local_elements_end () ),
1319+ (active_local_range .value (),
13011320 BoundaryProjectSolution (b , variables , * this , f , g ,
13021321 this -> get_equation_systems ().parameters ,
13031322 new_vector )
0 commit comments