v0.16.3
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Private Member Functions | Private Attributes | List of all members
MoFEM::OperatorsTester Struct Reference

Calculate directional derivative of the right hand side and compare it with tangent matrix derivative. More...

#include "src/interfaces/OperatorsTester.hpp"

Inheritance diagram for MoFEM::OperatorsTester:
[legend]
Collaboration diagram for MoFEM::OperatorsTester:
[legend]

Public Types

using RandomFieldData = std::pair< std::string, std::array< double, 2 > >
 
using ScalarFunction = std::function< MoFEMErrorCode(Vec, PetscReal &)>
 
using VectorFunction = std::function< MoFEMErrorCode(Vec, Vec)>
 

Public Member Functions

MoFEMErrorCode query_interface (boost::typeindex::type_index type_index, UnknownInterface **iface) const
 
 OperatorsTester (const MoFEM::Core &core)
 
virtual ~OperatorsTester ()=default
 
SmartPetscObj< Vec > setRandomFields (SmartPetscObj< DM > dm, std::vector< RandomFieldData > random_fields, boost::shared_ptr< Range > ents=nullptr, RowColData r=RowColData::COL)
 Generate random fields.
 
SmartPetscObj< Vec > assembleVec (SmartPetscObj< DM > dm, std::string fe_name, boost::shared_ptr< FEMethod > pipeline, SmartPetscObj< Vec > x, SmartPetscObj< Vec > delta_x, SmartPetscObj< Vec > delta2_x, double time, double delta_t, CacheTupleWeakPtr cache_ptr)
 Assemble the right hand side vector.
 
SmartPetscObj< Mat > assembleMat (SmartPetscObj< DM > dm, std::string fe_name, boost::shared_ptr< FEMethod > pipeline, SmartPetscObj< Vec > x, SmartPetscObj< Vec > delta_x, SmartPetscObj< Vec > delta2_x, double time, double delta_t, CacheTupleWeakPtr cache_ptr)
 Assemble the left hand side vector.
 
SmartPetscObj< Vec > directionalCentralFiniteDifference (SmartPetscObj< DM > dm, std::string fe_name, boost::shared_ptr< FEMethod > pipeline, SmartPetscObj< Vec > x, SmartPetscObj< Vec > delta_x, SmartPetscObj< Vec > delta2_x, SmartPetscObj< Vec > diff_x, double time, double delta_t, double eps, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
 Calculate directional directive using finite difference.
 
SmartPetscObj< Vec > checkCentralFiniteDifference (SmartPetscObj< DM > dm, std::string fe_name, boost::shared_ptr< FEMethod > pipeline_rhs, boost::shared_ptr< FEMethod > pipeline_lhs, SmartPetscObj< Vec > x, SmartPetscObj< Vec > delta_x, SmartPetscObj< Vec > delta2_x, SmartPetscObj< Vec > diff_x, double time, double delta_t, double eps, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
 Check consistency between directional derivative with matrix.
 
MoFEMErrorCode checkScalarCentralFiniteDifference (Vec x, Vec direction, Vec gradient, double eps, const ScalarFunction &evaluate, PetscReal &finite_difference, PetscReal &assembled_derivative)
 
MoFEMErrorCode checkVectorCentralFiniteDifference (Vec x, Vec direction, Vec function_layout, Mat jacobian, double eps, const VectorFunction &evaluate, Vec error)
 
- Public Member Functions inherited from MoFEM::UnknownInterface
template<class IFACE >
MoFEMErrorCode registerInterface (bool error_if_registration_failed=true)
 Register interface.
 
template<class IFACE >
MoFEMErrorCode getInterface (IFACE *&iface) const
 Get interface reference to pointer of interface.
 
template<class IFACE >
MoFEMErrorCode getInterface (IFACE **const iface) const
 Get interface pointer to pointer of interface.
 
template<class IFACE , typename boost::enable_if< boost::is_pointer< IFACE >, int >::type = 0>
IFACE getInterface () const
 Get interface pointer to pointer of interface.
 
template<class IFACE , typename boost::enable_if< boost::is_reference< IFACE >, int >::type = 0>
IFACE getInterface () const
 Get reference to interface.
 
template<class IFACE >
IFACE * getInterface () const
 Function returning pointer to interface.
 
virtual ~UnknownInterface ()=default
 

Private Member Functions

std::pair< SmartPetscObj< Vec >, SmartPetscObj< Vec > > setPipelineX (boost::shared_ptr< FEMethod > pipeline, SmartPetscObj< Vec > x, SmartPetscObj< Vec > delta_x, SmartPetscObj< Vec > delta2_x, double delta_t)
 Set vectors, x, x_t, and x_tt to finite element instance.
 

Private Attributes

MoFEM::Core & cOre
 

Additional Inherited Members

- Static Public Member Functions inherited from MoFEM::UnknownInterface
static MoFEMErrorCode getLibVersion (Version &version)
 Get library version.
 
static MoFEMErrorCode getFileVersion (moab::Interface &moab, Version &version)
 Get database major version.
 
static MoFEMErrorCode setFileVersion (moab::Interface &moab, Version version=Version(MoFEM_VERSION_MAJOR, MoFEM_VERSION_MINOR, MoFEM_VERSION_BUILD))
 Get database major version.
 
static MoFEMErrorCode getInterfaceVersion (Version &version)
 Get database major version.
 

Detailed Description

Calculate directional derivative of the right hand side and compare it with tangent matrix derivative.

Examples
mofem/atom_tests/operators_tests.cpp, mofem/atom_tests/tensor_divergence_operator.cpp, mofem/tutorials/adv-0_plasticity/plastic.cpp, mofem/tutorials/adv-3_level_set/level_set.cpp, and mofem/tutorials/vec-7_shape_optimisation/adjoint.cpp.

Definition at line 21 of file OperatorsTester.hpp.

Member Typedef Documentation

◆ RandomFieldData

using MoFEM::OperatorsTester::RandomFieldData = std::pair<std::string, std::array<double, 2> >

Definition at line 29 of file OperatorsTester.hpp.

◆ ScalarFunction

using MoFEM::OperatorsTester::ScalarFunction = std::function<MoFEMErrorCode(Vec, PetscReal &)>

Definition at line 30 of file OperatorsTester.hpp.

◆ VectorFunction

using MoFEM::OperatorsTester::VectorFunction = std::function<MoFEMErrorCode(Vec, Vec)>

Definition at line 32 of file OperatorsTester.hpp.

Constructor & Destructor Documentation

◆ OperatorsTester()

MoFEM::OperatorsTester::OperatorsTester ( const MoFEM::Core &  core)

Definition at line 13 of file OperatorsTester.cpp.

14 : cOre(const_cast<Core &>(core)) {}
CoreTmp< 0 > Core
Definition Core.hpp:1154

◆ ~OperatorsTester()

virtual MoFEM::OperatorsTester::~OperatorsTester ( )
virtualdefault

Member Function Documentation

◆ assembleMat()

SmartPetscObj< Mat > MoFEM::OperatorsTester::assembleMat ( SmartPetscObj< DM >  dm,
std::string  fe_name,
boost::shared_ptr< FEMethod >  pipeline,
SmartPetscObj< Vec >  x,
SmartPetscObj< Vec >  delta_x,
SmartPetscObj< Vec >  delta2_x,
double  time,
double  delta_t,
CacheTupleWeakPtr  cache_ptr 
)

Assemble the left hand side vector.

Parameters
dm
fe_name// fe name
pipeline// pipeline, i.e. fe instance
x// problem (dm) vector
delta_x// vector for x rate, can be null, i.e, SmartPetscObj<Vec>()
delta2_x// vector for x second rate, i.e. acceleration
time// time
delta_t// time increment
cache_ptr// finite element data cache, can be null
Returns
SmartPetscObj<Vec>

Definition at line 149 of file OperatorsTester.cpp.

153 {
154 auto m = createDMMatrix(dm);
155
156 pipeline->data_ctx =
158 pipeline->A = m;
159 pipeline->B = m;
160
161 pipeline->ts_t = time;
162
163 pipeline->ts_dt = delta_t;
164 pipeline->ts_a = 1. / delta_t;
165 pipeline->ts_aa = 1. / pow(delta_t, 2);
166
167 pipeline->ksp_ctx = KspMethod::KSPContext::CTX_OPERATORS;
170
171 auto [v, a] = setPipelineX(pipeline, x, delta_x, delta2_x, delta_t);
172 std::ignore = a;
173 std::ignore = v;
174
176 DMoFEMMeshToLocalVector(dm, x, INSERT_VALUES, SCATTER_REVERSE),
177 "loc to vec");
178 CHK_THROW_MESSAGE(DMoFEMLoopFiniteElements(dm, fe_name, pipeline, cache_ptr),
179 "Run assemble pipeline");
180 CHK_THROW_MESSAGE(MatAssemblyBegin(m, MAT_FINAL_ASSEMBLY), "Asmb mat");
181 CHK_THROW_MESSAGE(MatAssemblyEnd(m, MAT_FINAL_ASSEMBLY), "Asmb mat");
182
183 auto get_norm = [](auto m) {
184 double fnorm;
185 MatNorm(m, NORM_1, &fnorm);
186 return fnorm;
187 };
188 MOFEM_LOG_CHANNEL("WORLD");
189 MOFEM_TAG_AND_LOG_C("WORLD", Sev::noisy, "OpTester", "Matrix norm %3.4e",
190 get_norm(m));
191
192 return m;
193}
#define MOFEM_TAG_AND_LOG_C(channel, severity, tag, format,...)
Tag and log in channel.
constexpr double a
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
PetscErrorCode DMoFEMMeshToLocalVector(DM dm, Vec l, InsertMode mode, ScatterMode scatter_mode, RowColData rc=RowColData::COL)
set local (or ghosted) vector values on mesh for partition only
Definition DMMoFEM.cpp:543
PetscErrorCode DMoFEMLoopFiniteElements(DM dm, const char fe_name[], MoFEM::FEMethod *method, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
Definition DMMoFEM.cpp:605
auto createDMMatrix(DM dm)
Get smart matrix from DM.
Definition DMMoFEM.hpp:1207
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
const double v
phase velocity of light in medium (cm/ns)
FTensor::Index< 'm', 3 > m
@ CTX_OPERATORS
Setting up linear operators.
std::pair< SmartPetscObj< Vec >, SmartPetscObj< Vec > > setPipelineX(boost::shared_ptr< FEMethod > pipeline, SmartPetscObj< Vec > x, SmartPetscObj< Vec > delta_x, SmartPetscObj< Vec > delta2_x, double delta_t)
Set vectors, x, x_t, and x_tt to finite element instance.
static constexpr Switches CtxSetA
Jacobian matrix switch.
static constexpr Switches CtxSetB
Preconditioner matrix switch.
static constexpr Switches CtxSetTime
Time value switch.
@ CTX_SNESSETJACOBIAN
Setting up Jacobian matrix computation.
@ CTX_TSSETIJACOBIAN
Setting up implicit Jacobian.

◆ assembleVec()

SmartPetscObj< Vec > MoFEM::OperatorsTester::assembleVec ( SmartPetscObj< DM >  dm,
std::string  fe_name,
boost::shared_ptr< FEMethod >  pipeline,
SmartPetscObj< Vec >  x,
SmartPetscObj< Vec >  delta_x,
SmartPetscObj< Vec >  delta2_x,
double  time,
double  delta_t,
CacheTupleWeakPtr  cache_ptr 
)

Assemble the right hand side vector.

Parameters
dm
fe_name// fe name
pipeline// pipeline, i.e. fe instance
x// problem (dm) vector
delta_x// vector for x rate, can be null, i.e, SmartPetscObj<Vec>()
delta2_x// vector for x second rate, i.e. acceleration
time// time
delta_t// time increment
cache_ptr// finite element data cache, can be null
Returns
SmartPetscObj<Vec>

Definition at line 99 of file OperatorsTester.cpp.

103 {
104
105 pipeline->data_ctx = PetscData::CtxSetF | PetscData::CtxSetTime;
106 auto f = createDMVector(dm);
107 pipeline->f = f;
108 pipeline->ts_t = time;
109 pipeline->ts_dt = delta_t;
110
111 pipeline->ksp_ctx = KspMethod::KSPContext::CTX_SETFUNCTION;
114
115 auto [v, a] = setPipelineX(pipeline, x, delta_x, delta2_x, delta_t);
116 std::ignore = a;
117 std::ignore = v;
118
120 DMoFEMMeshToLocalVector(dm, x, INSERT_VALUES, SCATTER_REVERSE),
121 "loc to vec");
122 CHK_THROW_MESSAGE(DMoFEMLoopFiniteElements(dm, fe_name, pipeline, cache_ptr),
123 "Run assemble pipeline");
124 CHK_THROW_MESSAGE(VecAssemblyBegin(f), "Asmb vector");
125 CHK_THROW_MESSAGE(VecAssemblyEnd(f), "Asmb vector");
126
127 CHK_THROW_MESSAGE(VecGhostUpdateBegin(f, ADD_VALUES, SCATTER_REVERSE),
128 "Update vec");
129 CHK_THROW_MESSAGE(VecGhostUpdateEnd(f, ADD_VALUES, SCATTER_REVERSE),
130 "Update vec");
131 CHK_THROW_MESSAGE(VecGhostUpdateBegin(f, INSERT_VALUES, SCATTER_FORWARD),
132 "Update vec");
133 CHK_THROW_MESSAGE(VecGhostUpdateEnd(f, INSERT_VALUES, SCATTER_FORWARD),
134 "Update vec");
135
136 auto get_norm = [](auto f) {
137 double fnorm;
138 VecNorm(f, NORM_2, &fnorm);
139 return fnorm;
140 };
141 MOFEM_LOG_CHANNEL("WORLD");
142 MOFEM_TAG_AND_LOG_C("WORLD", Sev::noisy, "OpTester", "Vec norm %3.4e",
143 get_norm(f));
144
145 return f;
146}
auto createDMVector(DM dm, RowColData rc=RowColData::COL)
Get smart vector from DM.
Definition DMMoFEM.hpp:1250
@ CTX_SETFUNCTION
Setting up the linear system function.
static constexpr Switches CtxSetF
Residual vector switch.
@ CTX_SNESSETFUNCTION
Setting up nonlinear function evaluation.
@ CTX_TSSETIFUNCTION
Setting up implicit function.

◆ checkCentralFiniteDifference()

SmartPetscObj< Vec > MoFEM::OperatorsTester::checkCentralFiniteDifference ( SmartPetscObj< DM >  dm,
std::string  fe_name,
boost::shared_ptr< FEMethod >  pipeline_rhs,
boost::shared_ptr< FEMethod >  pipeline_lhs,
SmartPetscObj< Vec >  x,
SmartPetscObj< Vec >  delta_x,
SmartPetscObj< Vec >  delta2_x,
SmartPetscObj< Vec >  diff_x,
double  time,
double  delta_t,
double  eps,
CacheTupleWeakPtr  cache_ptr = CacheTupleSharedPtr() 
)

Check consistency between directional derivative with matrix.

Parameters
dm
fe_name
pipeline_rhs
pipeline_lhs
x
delta_x
delta2_x
diff_x
time
delta_t
eps
cache_ptr
Returns
SmartPetscObj<Vec>

Definition at line 252 of file OperatorsTester.cpp.

258 {
259
261 dm, fe_name, pipeline_rhs, x, delta_x, delta2_x, diff_x, time, delta_t,
262 eps, cache_ptr);
263
264 auto m = assembleMat(dm, fe_name, pipeline_lhs, x, delta_x, delta2_x, time,
265 delta_t, cache_ptr);
266
267 auto fm = vectorDuplicate(fd_diff);
268 CHK_THROW_MESSAGE(MatMult(m, diff_x, fm), "Mat mult");
269 CHK_THROW_MESSAGE(VecAXPY(fd_diff, -1., fm), "Add");
270
271 return fd_diff;
272}
static const double eps
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
SmartPetscObj< Mat > assembleMat(SmartPetscObj< DM > dm, std::string fe_name, boost::shared_ptr< FEMethod > pipeline, SmartPetscObj< Vec > x, SmartPetscObj< Vec > delta_x, SmartPetscObj< Vec > delta2_x, double time, double delta_t, CacheTupleWeakPtr cache_ptr)
Assemble the left hand side vector.
SmartPetscObj< Vec > directionalCentralFiniteDifference(SmartPetscObj< DM > dm, std::string fe_name, boost::shared_ptr< FEMethod > pipeline, SmartPetscObj< Vec > x, SmartPetscObj< Vec > delta_x, SmartPetscObj< Vec > delta2_x, SmartPetscObj< Vec > diff_x, double time, double delta_t, double eps, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Calculate directional directive using finite difference.

◆ checkScalarCentralFiniteDifference()

MoFEMErrorCode MoFEM::OperatorsTester::checkScalarCentralFiniteDifference ( Vec  x,
Vec  direction,
Vec  gradient,
double  eps,
const ScalarFunction &  evaluate,
PetscReal &  finite_difference,
PetscReal &  assembled_derivative 
)

Check a scalar function derivative against gradient dot direction.

Definition at line 274 of file OperatorsTester.cpp.

277 {
279 if (!(eps > 0) || !evaluate)
280 SETERRQ(PETSC_COMM_SELF, MOFEM_INVALID_DATA,
281 "Scalar directional-derivative test requires a positive step "
282 "and evaluator");
283 auto x_plus = vectorDuplicate(x);
284 auto x_minus = vectorDuplicate(x);
285 CHKERR VecWAXPY(x_plus, eps, direction, x);
286 CHKERR VecWAXPY(x_minus, -eps, direction, x);
287 CHKERR VecGhostUpdateBegin(x_plus, INSERT_VALUES, SCATTER_FORWARD);
288 CHKERR VecGhostUpdateEnd(x_plus, INSERT_VALUES, SCATTER_FORWARD);
289 CHKERR VecGhostUpdateBegin(x_minus, INSERT_VALUES, SCATTER_FORWARD);
290 CHKERR VecGhostUpdateEnd(x_minus, INSERT_VALUES, SCATTER_FORWARD);
291 PetscReal value_plus = 0;
292 PetscReal value_minus = 0;
293 CHKERR evaluate(x_plus, value_plus);
294 CHKERR evaluate(x_minus, value_minus);
295 finite_difference = (value_plus - value_minus) / (2 * eps);
296 PetscScalar derivative = 0;
297 CHKERR VecDot(gradient, direction, &derivative);
298 assembled_derivative = PetscRealPart(derivative);
300}
SmartPetscObj< Vec > gradient
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_INVALID_DATA
Definition definitions.h:36
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.

◆ checkVectorCentralFiniteDifference()

MoFEMErrorCode MoFEM::OperatorsTester::checkVectorCentralFiniteDifference ( Vec  x,
Vec  direction,
Vec  function_layout,
Mat  jacobian,
double  eps,
const VectorFunction &  evaluate,
Vec  error 
)

Check a vector function derivative against Jacobian times direction. The returned error is written into a vector with the function layout.

Definition at line 302 of file OperatorsTester.cpp.

304 {
306 if (!(eps > 0) || !evaluate)
307 SETERRQ(PETSC_COMM_SELF, MOFEM_INVALID_DATA,
308 "Vector directional-derivative test requires a positive step "
309 "and evaluator");
310 auto x_plus = vectorDuplicate(x);
311 auto x_minus = vectorDuplicate(x);
312 auto value_plus = vectorDuplicate(function_layout);
313 auto value_minus = vectorDuplicate(function_layout);
314 auto assembled = vectorDuplicate(function_layout);
315 CHKERR VecWAXPY(x_plus, eps, direction, x);
316 CHKERR VecWAXPY(x_minus, -eps, direction, x);
317 CHKERR VecGhostUpdateBegin(x_plus, INSERT_VALUES, SCATTER_FORWARD);
318 CHKERR VecGhostUpdateEnd(x_plus, INSERT_VALUES, SCATTER_FORWARD);
319 CHKERR VecGhostUpdateBegin(x_minus, INSERT_VALUES, SCATTER_FORWARD);
320 CHKERR VecGhostUpdateEnd(x_minus, INSERT_VALUES, SCATTER_FORWARD);
321 CHKERR evaluate(x_plus, value_plus);
322 CHKERR evaluate(x_minus, value_minus);
323 CHKERR VecCopy(value_plus, error);
324 CHKERR VecAXPY(error, -1., value_minus);
325 CHKERR VecScale(error, 1. / (2 * eps));
326 CHKERR MatMult(jacobian, direction, assembled);
327 CHKERR VecAXPY(error, -1., assembled);
329}
SmartPetscObj< Mat > jacobian

◆ directionalCentralFiniteDifference()

SmartPetscObj< Vec > MoFEM::OperatorsTester::directionalCentralFiniteDifference ( SmartPetscObj< DM >  dm,
std::string  fe_name,
boost::shared_ptr< FEMethod >  pipeline,
SmartPetscObj< Vec >  x,
SmartPetscObj< Vec >  delta_x,
SmartPetscObj< Vec >  delta2_x,
SmartPetscObj< Vec >  diff_x,
double  time,
double  delta_t,
double  eps,
CacheTupleWeakPtr  cache_ptr = CacheTupleSharedPtr() 
)

Calculate directional directive using finite difference.

Parameters
dm
fe_name
pipeline
x
delta_x
delta2_x
diff_x// direction of derivative
time
delta_t
eps
cache_ptr
Returns
SmartPetscObj<Vec>

Definition at line 195 of file OperatorsTester.cpp.

200 {
201
202 auto axpy = [&](auto v0, auto diff_v, auto eps) {
203 SmartPetscObj<Vec> v;
204 if (v0.use_count()) {
205 v = vectorDuplicate(v0);
206 CHK_THROW_MESSAGE(VecCopy(v0, v), "Cpy");
207 CHK_THROW_MESSAGE(VecAXPY(v, eps, diff_v), "Add");
208 CHK_THROW_MESSAGE(VecGhostUpdateBegin(v, INSERT_VALUES, SCATTER_FORWARD),
209 "ghost");
210 CHK_THROW_MESSAGE(VecGhostUpdateEnd(v, INSERT_VALUES, SCATTER_FORWARD),
211 "ghost");
212 }
213 return v;
214 };
215
216 auto fm1 = assembleVec(dm, fe_name, pipeline,
217 //
218 axpy(x, diff_x, -eps),
219 //
220 axpy(delta_x, diff_x, -eps),
221 //
222 axpy(delta2_x, diff_x, -eps),
223 //
224 time, delta_t, cache_ptr);
225
226 auto fp1 = assembleVec(dm, fe_name, pipeline,
227 //
228 axpy(x, diff_x, eps),
229 //
230 axpy(delta_x, diff_x, eps),
231 //
232 axpy(delta2_x, diff_x, eps),
233 //
234 time, delta_t, cache_ptr);
235
236 auto calculate_derivative = [eps](auto fm1, auto fp1) {
237 int size;
238 VecGetLocalSize(fp1, &size);
239 VecAXPY(fp1, -1, fm1);
240 double *array;
241 VecGetArray(fp1, &array);
242 for (int j = 0; j != size; ++j) {
243 array[j] /= 2 * eps;
244 }
245 VecRestoreArray(fp1, &array);
246 return fp1;
247 };
248
249 return calculate_derivative(fm1, fp1);
250}
PetscInt size
FTensor::Index< 'j', 3 > j
SmartPetscObj< Vec > assembleVec(SmartPetscObj< DM > dm, std::string fe_name, boost::shared_ptr< FEMethod > pipeline, SmartPetscObj< Vec > x, SmartPetscObj< Vec > delta_x, SmartPetscObj< Vec > delta2_x, double time, double delta_t, CacheTupleWeakPtr cache_ptr)
Assemble the right hand side vector.

◆ query_interface()

MoFEMErrorCode MoFEM::OperatorsTester::query_interface ( boost::typeindex::type_index  type_index,
UnknownInterface **  iface 
) const
virtual

Implements MoFEM::UnknownInterface.

Definition at line 17 of file OperatorsTester.cpp.

18 {
19 *iface = const_cast<OperatorsTester *>(this);
20 return 0;
21}
OperatorsTester(const MoFEM::Core &core)

◆ setPipelineX()

std::pair< SmartPetscObj< Vec >, SmartPetscObj< Vec > > MoFEM::OperatorsTester::setPipelineX ( boost::shared_ptr< FEMethod >  pipeline,
SmartPetscObj< Vec >  x,
SmartPetscObj< Vec >  delta_x,
SmartPetscObj< Vec >  delta2_x,
double  delta_t 
)
private

Set vectors, x, x_t, and x_tt to finite element instance.

Finite element instance is a pipeline. x_t and x_tt are evaluated for given delta_x, delta2_x and delta_t.

Parameters
pipeline
x
delta_x
delta2_x
delta_t
Returns
std::pair<SmartPetscObj<Vec>, SmartPetscObj<Vec>>

Definition at line 332 of file OperatorsTester.cpp.

334 {
335
336 // Set dofs vector to finite element instance
337 pipeline->x = x;
338 pipeline->data_ctx |= PetscData::CTX_SET_X;
339
340 SmartPetscObj<Vec> x_t, x_tt;
341
342 // Set velocity dofs vector to finite element instance
343
344 if (delta_x.use_count()) {
345 x_t = vectorDuplicate(x);
346 VecCopy(delta_x, x_t);
347 VecScale(x_t, 1. / delta_t);
348 CHK_THROW_MESSAGE(VecGhostUpdateBegin(x_t, INSERT_VALUES, SCATTER_FORWARD),
349 "ghost");
350 CHK_THROW_MESSAGE(VecGhostUpdateEnd(x_t, INSERT_VALUES, SCATTER_FORWARD),
351 "ghost");
352 pipeline->x_t = x_t;
353 pipeline->data_ctx |= PetscData::CTX_SET_X_T;
354 } else {
355 pipeline->x_t = PETSC_NULLPTR;
356 }
357
358 // Set acceleration dofs vector to finite element instance
359
360 if (delta2_x.use_count()) {
361 x_tt = vectorDuplicate(x);
362 VecCopy(delta2_x, x_tt);
363 VecScale(x_tt, 1. / pow(delta_t, 2));
364 CHK_THROW_MESSAGE(VecGhostUpdateBegin(x_tt, INSERT_VALUES, SCATTER_FORWARD),
365 "ghost");
366 CHK_THROW_MESSAGE(VecGhostUpdateEnd(x_tt, INSERT_VALUES, SCATTER_FORWARD),
367 "ghost");
368 pipeline->x_tt = x_tt;
369 pipeline->data_ctx |= PetscData::CTX_SET_X_TT;
370 } else {
371 pipeline->x_tt = PETSC_NULLPTR;
372 }
373
374 return std::make_pair(x_t, x_tt);
375}
@ CTX_SET_X_T
Time derivative X_t is set.
@ CTX_SET_X
Solution vector X is set.
@ CTX_SET_X_TT
Second time derivative X_tt is set.

◆ setRandomFields()

SmartPetscObj< Vec > MoFEM::OperatorsTester::setRandomFields ( SmartPetscObj< DM >  dm,
std::vector< RandomFieldData >  random_fields,
boost::shared_ptr< Range >  ents = nullptr,
RowColData  r = RowColData::COL 
)

Generate random fields.

Example: generate random vector for DM (problem) from simple interface, where FIELD random values of DOFs are in range from -1 to 1, and FIELD2 random values are in range from 0 to 1.

auto x = opt->setRandomFields(simple->getDM(),
{{"FIELD1", {-1, 1}}, {"FIELD2", {0,1}}});
void simple(double P1[], double P2[], double P3[], double c[], const int N)
Definition acoustic.cpp:69

TODO: Set random field to specific entities, and potentially order for testing proposes to dissect error in tangent matrix.

Parameters
dm
random_fieldslook at definition RandomFieldData
Returns
SmartPetscObj<Vec> smart vector
Examples
mofem/atom_tests/tensor_divergence_operator.cpp.

Definition at line 23 of file OperatorsTester.cpp.

25 {
26
27 MoFEM::Interface &m_field = cOre;
28
29 auto prb_ptr = getProblemPtr(dm);
30 std::mt19937 rng(0x4d584431u);
31
32 auto get_random_number = [&rng](auto &range) {
33 std::uniform_real_distribution<double> dist(range[0], range[1]);
34 return dist(rng);
35 };
36
37 auto v = createDMVector(dm, r);
38 double *array;
39 CHKERR VecGetArray(v, &array);
40
41 int size;
42 CHKERR VecGetLocalSize(v, &size);
43
44 MOFEM_LOG_CHANNEL("WORLD");
45
46 for (auto &rf : random_fields) {
47 const auto field_id = m_field.get_field_bit_number(rf.first);
48 MOFEM_TAG_AND_LOG("WORLD", Sev::noisy, "OperatorsTester")
49 << "Set random field " << rf.first << " " << static_cast<int>(field_id);
50
51 auto get_numbered_dofs = [&]() {
52 switch (r) {
53 case RowColData::ROW:
54 return prb_ptr->getNumeredRowDofsPtr();
55 case RowColData::COL:
56 return prb_ptr->getNumeredColDofsPtr();
57 default:
58 throw std::runtime_error("Invalid RowColData");
59 }
60 };
61
62 if (!ents_ptr) {
63 auto lo = get_numbered_dofs()->lower_bound(
65 const auto hi = get_numbered_dofs()->upper_bound(
67 for (; lo != hi; ++lo) {
68 const auto idx = (*lo)->getPetscLocalDofIdx();
69 if (idx >= 0 && idx < size) {
70 array[idx] = get_random_number(rf.second);
71 }
72 }
73 } else {
74 for (auto pit = ents_ptr->const_pair_begin();
75 pit != ents_ptr->const_pair_end(); ++pit) {
76 auto lo = get_numbered_dofs()->get<Unique_mi_tag>().lower_bound(
77 DofEntity::getLoFieldEntityUId(field_id, pit->first));
78 auto hi = get_numbered_dofs()->get<Unique_mi_tag>().upper_bound(
79 DofEntity::getHiFieldEntityUId(field_id, pit->second));
80 for (; lo != hi; ++lo) {
81 const auto idx = (*lo)->getPetscLocalDofIdx();
82 if (idx >= 0 && idx < size) {
83 array[idx] = get_random_number(rf.second);
84 }
85 }
86 }
87 }
88 }
89
90 CHKERR VecRestoreArray(v, &array);
91
92 CHKERR VecGhostUpdateBegin(v, INSERT_VALUES, SCATTER_FORWARD);
93 CHKERR VecGhostUpdateEnd(v, INSERT_VALUES, SCATTER_FORWARD);
94
95 return v;
96};
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
@ COL
@ ROW
auto getProblemPtr(DM dm)
get problem pointer from DM
Definition DMMoFEM.hpp:1195
virtual FieldBitNumber get_field_bit_number(const std::string name) const =0
get field bit number
Deprecated interface functions.
static UId getLoFieldEntityUId(const FieldBitNumber bit, const EntityHandle ent)
static UId getHiFieldEntityUId(const FieldBitNumber bit, const EntityHandle ent)
static UId getHiBitNumberUId(const FieldBitNumber bit_number)
static UId getLoBitNumberUId(const FieldBitNumber bit_number)

Member Data Documentation

◆ cOre

MoFEM::Core& MoFEM::OperatorsTester::cOre
private

Definition at line 163 of file OperatorsTester.hpp.


The documentation for this struct was generated from the following files: