v0.16.0
Loading...
Searching...
No Matches
NaturalMeshsetType.hpp
Go to the documentation of this file.
1/**
2 * @file NaturalMeshsetType.hpp
3 * @brief Specialisation for NaturalMeshsetType
4 * @version 0.13.2
5 * @date 2022-09-18
6 *
7 * @copyright Copyright (c) 2022
8 *
9 */
10
11#ifndef _NATURAL_MESHSET_TYPE_HPP_
12#define _NATURAL_MESHSET_TYPE_HPP_
13
14namespace MoFEM {
15
16/**
17 * @brief Type generating natural b.c. specialisations for meshsets
18 *
19 * @tparam BCTYP
20 */
21template <CubitBC BCTYP> struct NaturalMeshsetType {};
22template <CubitBC BCTYP> struct NaturalMeshsetPressureType {};
23
24/** Evaluate boundary integral on the right hand side*/
25template <int FIELD_DIM, AssemblyType A, IntegrationType I, typename OpBase>
27 : OpFluxRhsImpl<NaturalMeshsetType<UNKNOWNSET>, 1, FIELD_DIM, A, I,
28 OpBase> {
29
31 MoFEM::Interface &m_field, int ms_id, const std::string field_name,
32 std::vector<boost::shared_ptr<ScalingMethod>> smv,
33 ScalarFun user_fun = [](double, double, double) { return 1; });
34
35protected:
36 /**
37 * @brief Extract information stored on meshset (BLOCKSET)
38 *
39 * @param m_field
40 * @param ms_id
41 * @return MoFEMErrorCode
42 */
43 MoFEMErrorCode getMeshsetData(MoFEM::Interface &m_field, int ms_id);
44};
45
46template <int FIELD_DIM, AssemblyType A, IntegrationType I, typename OpBase>
48 : OpFluxRhsImpl<NaturalMeshsetType<UNKNOWNSET>, 1, FIELD_DIM, A, I,
49 OpBase> {
50
52 MoFEM::Interface &m_field, int ms_id, const std::string field_name,
53 std::vector<boost::shared_ptr<ScalingMethod>> smv,
54 ScalarFun user_fun = [](double, double, double) { return 1; });
55
56 using Parent =
59
60protected:
61 MoFEMErrorCode getMeshsetData(MoFEM::Interface &m_field, int ms_id);
62};
63
64template <int FIELD_DIM, AssemblyType A, IntegrationType I, typename OpBase>
66 OpBase> : OpFluxRhsImpl<NaturalMeshsetType<UNKNOWNSET>, 1,
67 FIELD_DIM, A, I, OpBase> {
68
69 using Parent =
72
74 MoFEM::Interface &m_field, int ms_id, const std::string field_name,
75 std::vector<boost::shared_ptr<ScalingMethod>> smv,
76 ScalarFun user_fun = [](double, double, double) { return 1; });
77
78protected:
80 MoFEM::Interface &m_field, const std::string field_name,
81 std::vector<boost::shared_ptr<ScalingMethod>> smv,
82 ScalarFun user_fun = [](double, double, double) { return 1; });
83
84 MoFEMErrorCode iNtegrate(EntData &data);
85 MoFEMErrorCode getMeshsetData(MoFEM::Interface &m_field, int ms_id);
88};
89
90template <int FIELD_DIM, AssemblyType A, IntegrationType I, typename OpBase>
92 OpBase> : OpFluxRhsImpl<NaturalMeshsetType<PRESSURESET>, 1,
93 FIELD_DIM, A, I, OpBase> {
94
96 I, OpBase>;
98
100 MoFEM::Interface &m_field, int ms_id, const std::string field_name,
101 std::vector<boost::shared_ptr<ScalingMethod>> smv,
102 ScalarFun user_fun = [](double, double, double) { return 1; });
103
104protected:
105
106
107 MoFEMErrorCode getMeshsetData(MoFEM::Interface &m_field, int ms_id);
108};
109
110/**
111 * @brief Base class for OpFluxRhsImpl<NaturalMeshsetType<T>, 1, FIELD_DIM, A,
112 I, OpBase>
113 *
114 * This is only for scalar bases.
115 *
116 * @note It is derivitive from FormsIntegrators<OpBase>::template
117 Assembly<A>::template LinearForm< I>::template OpSource<1, FIELD_DIM>
118 *
119 * @tparam FIELD_DIM field dimension
120 * @tparam A
121 * @tparam I
122 * @tparam OpBase Base element operator for integration volume, face, edge, or
123 vertex
124 */
125template <int FIELD_DIM, AssemblyType A, IntegrationType I, typename OpBase>
127 : FormsIntegrators<OpBase>::template Assembly<A>::template LinearForm<
128 I>::template OpSource<1, FIELD_DIM> {
129
132
134 const std::string field_name, FTensor::Tensor1<double, FIELD_DIM> t_force,
135 boost::shared_ptr<Range> ents_ptr,
136 std::vector<boost::shared_ptr<ScalingMethod>> smv,
137 ScalarFun user_fun = [](double, double, double) { return 1; });
138
139protected:
141 const std::string field_name,
142 std::vector<boost::shared_ptr<ScalingMethod>> smv,
143 ScalarFun user_fun = [](double, double, double) { return 1; });
148};
149
150template <AssemblyType A, IntegrationType I, typename OpBase>
152 : FormsIntegrators<OpBase>::template Assembly<A>::template LinearForm<
153 I>::template OpSource<1, 1> {
154
157
159 const std::string field_name, double value,
160 boost::shared_ptr<Range> ents_ptr,
161 std::vector<boost::shared_ptr<ScalingMethod>> smv,
162 ScalarFun user_fun = [](double, double, double) { return 1; });
163
164protected:
166 const std::string field_name,
167 std::vector<boost::shared_ptr<ScalingMethod>> smv,
168 ScalarFun user_fun = [](double, double, double) { return 1; });
169
171
172 double scalarValue = 0;
174
176};
177
178template <AssemblyType A, IntegrationType I, typename OpBase>
180 : OpFluxRhsImpl<NaturalMeshsetType<UNKNOWNSET>, 1, 1, A, I, OpBase> {
181
182 using Parent =
184
186 MoFEM::Interface &m_field, int ms_id, const std::string field_name,
187 std::vector<boost::shared_ptr<ScalingMethod>> smv,
188 ScalarFun user_fun = [](double, double, double) { return 1; });
189
190protected:
191 MoFEMErrorCode getMeshsetData(MoFEM::Interface &m_field, int ms_id);
192};
193
194template <AssemblyType A, IntegrationType I, typename OpBase>
196 : OpFluxRhsImpl<NaturalMeshsetType<UNKNOWNSET>, 1, 1, A, I, OpBase> {
197
198 using Parent =
200
202 MoFEM::Interface &m_field, int ms_id, const std::string field_name,
203 std::vector<boost::shared_ptr<ScalingMethod>> smv,
204 ScalarFun user_fun = [](double, double, double) { return 1; });
205
206protected:
207 MoFEMErrorCode getMeshsetData(MoFEM::Interface &m_field, int ms_id);
208};
209
210template <int FIELD_DIM, AssemblyType A, IntegrationType I, typename OpBase>
212 : FormsIntegrators<OpBase>::template Assembly<A>::template LinearForm<
213 I>::template OpNormalMixVecTimesScalar<FIELD_DIM> {
214
216 A>::template LinearForm<I>::template OpNormalMixVecTimesScalar<FIELD_DIM>;
217
219 const std::string field_name, const double value,
220 boost::shared_ptr<Range> ents_ptr,
221 std::vector<boost::shared_ptr<ScalingMethod>> smv,
222 ScalarFun user_fun = [](double, double, double) { return 1; });
223
224protected:
226 const std::string field_name,
227 std::vector<boost::shared_ptr<ScalingMethod>> smv,
228 ScalarFun user_fun = [](double, double, double) { return 1; });
232};
233
234template <int FIELD_DIM, AssemblyType A, IntegrationType I, typename OpBase>
236 : OpFluxRhsImpl<NaturalMeshsetType<UNKNOWNSET>, 3, FIELD_DIM, A, I,
237 OpBase> {
239 MoFEM::Interface &m_field, int ms_id, const std::string field_name,
240 std::vector<boost::shared_ptr<ScalingMethod>> smv,
241 ScalarFun user_fun = [](double, double, double) { return 1; });
242
243protected:
244 MoFEMErrorCode getMeshsetData(MoFEM::Interface &m_field, int ms_id);
245};
246
247template <int FIELD_DIM, AssemblyType A, IntegrationType I, typename OpBase>
249 OpBase> : OpFluxRhsImpl<NaturalMeshsetType<UNKNOWNSET>, 3,
250 FIELD_DIM, A, I, OpBase> {
252 MoFEM::Interface &m_field, int ms_id, const std::string field_name,
253 std::vector<boost::shared_ptr<ScalingMethod>> smv,
254 ScalarFun user_fun = [](double, double, double) { return 1; });
255
256protected:
257 MoFEMErrorCode getMeshsetData(MoFEM::Interface &m_field, int ms_id);
258};
259
260template <CubitBC BCTYP> struct NaturalMeshsetTypeVectorScaling {};
261
262template <int FIELD_DIM, AssemblyType A, IntegrationType I, typename OpBase>
264 I, OpBase>
265 : OpFluxRhsImpl<NaturalMeshsetTypeVectorScaling<UNKNOWNSET>, 1, FIELD_DIM,
266 A, I, OpBase> {
267
269 MoFEM::Interface &m_field, int ms_id, const std::string field_name,
270 std::vector<boost::shared_ptr<TimeScaleVector<FIELD_DIM>>> smv,
271 ScalarFun user_fun = [](double, double, double) { return 1; });
272
273protected:
274 MoFEMErrorCode getMeshsetData(MoFEM::Interface &m_field, int ms_id);
275};
276
277template <int FIELD_DIM, AssemblyType A, IntegrationType I, typename OpBase>
279 A, I, OpBase>
280 : FormsIntegrators<OpBase>::template Assembly<A>::template LinearForm<
281 I>::template OpSource<1, FIELD_DIM> {
282
285
287 const std::string field_name, FTensor::Tensor1<double, FIELD_DIM> t_force,
288 boost::shared_ptr<Range> ents_ptr,
289 std::vector<boost::shared_ptr<TimeScaleVector<FIELD_DIM>>> smv,
290 ScalarFun user_fun = [](double, double, double) { return 1; });
291
292protected:
294 const std::string field_name,
295 std::vector<boost::shared_ptr<TimeScaleVector<FIELD_DIM>>> smv,
296 ScalarFun user_fun = [](double, double, double) { return 1; });
297
301};
302
303// Definitions
304
305template <int FIELD_DIM, AssemblyType A, IntegrationType I, typename OpBase>
307 OpFluxRhsImpl(const std::string field_name,
309 boost::shared_ptr<Range> ents_ptr,
310 std::vector<boost::shared_ptr<ScalingMethod>> smv,
311 ScalarFun user_fun)
312 : OpFluxRhsImpl(field_name, smv, user_fun) {
314 this->tForce(i) = t_force(i);
315 this->entsPtr = ents_ptr;
316}
317
318template <int FIELD_DIM, AssemblyType A, IntegrationType I, typename OpBase>
320 OpFluxRhsImpl(const std::string field_name,
321 std::vector<boost::shared_ptr<ScalingMethod>> smv,
322 ScalarFun user_fun)
324
325 [this](const double x, const double y, const double z) {
327 tScaledForce(i) = tForce(i) * userFun(x, y, z);
328 return tScaledForce;
329 }
330
331 ),
332 vecOfTimeScalingMethods(smv), userFun(user_fun) {
333 this->timeScalingFun = [this](const double t) {
334 double s = 1;
335 for (auto &o : vecOfTimeScalingMethods) {
336 s *= o->getScale(t);
337 }
338 return s;
339 };
340
341 static_assert(FIELD_DIM > 1, "Not implemented for scalar field");
342}
343
344template <int FIELD_DIM, AssemblyType A, IntegrationType I, typename OpBase>
346 OpFluxRhsImpl(MoFEM::Interface &m_field, int ms_id,
347 const std::string field_name,
348 std::vector<boost::shared_ptr<ScalingMethod>> smv,
349 ScalarFun user_fun)
351 field_name, smv, user_fun) {
352 CHK_THROW_MESSAGE(getMeshsetData(m_field, ms_id), "Get meshset data");
353}
354
355template <int FIELD_DIM, AssemblyType A, IntegrationType I, typename OpBase>
357 OpBase>::getMeshsetData(MoFEM::Interface &m_field,
358 int ms_id) {
360
361 auto cubit_meshset_ptr =
362 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(ms_id,
363 NODESET);
364
365 ForceCubitBcData bc_data;
366 CHKERR cubit_meshset_ptr->getBcDataStructure(bc_data);
367
368 this->tForce(0) = bc_data.data.value3;
369 if constexpr (FIELD_DIM > 1)
370 this->tForce(1) = bc_data.data.value4;
371 if constexpr (FIELD_DIM > 2)
372 this->tForce(2) = bc_data.data.value5;
373
375 this->tForce(i) *= bc_data.data.value1;
376
377 this->entsPtr = boost::make_shared<Range>();
378 CHKERR m_field.get_moab().get_entities_by_handle(cubit_meshset_ptr->meshset,
379 *(this->entsPtr), true);
380
382}
383
384template <int FIELD_DIM, AssemblyType A, IntegrationType I, typename OpBase>
386 OpFluxRhsImpl(MoFEM::Interface &m_field, int ms_id,
387 const std::string field_name,
388 std::vector<boost::shared_ptr<ScalingMethod>> smv,
389 ScalarFun user_fun)
391 field_name, smv, user_fun) {
392 CHK_THROW_MESSAGE(getMeshsetData(m_field, ms_id), "Get meshset data");
393}
394
395template <int FIELD_DIM, AssemblyType A, IntegrationType I, typename OpBase>
397 OpBase>::getMeshsetData(MoFEM::Interface &m_field,
398 int ms_id) {
400
401 auto cubit_meshset_ptr =
402 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(ms_id,
403 BLOCKSET);
404
405 std::vector<double> block_data;
406 CHKERR cubit_meshset_ptr->getAttributes(block_data);
407
408 if (block_data.size() != FIELD_DIM) {
409 MOFEM_LOG("SELF", Sev::warning)
410 << "BLOCKSET is expected to have " << FIELD_DIM
411 << " attributes but has size " << block_data.size();
412 if (block_data.size() < FIELD_DIM) {
413 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
414 "Size of attribute in BLOCKSET is too small");
415 }
416 }
417
418 for (unsigned int ii = 0; ii != FIELD_DIM; ++ii) {
419 this->tForce(ii) = block_data[ii];
420 }
421
422 MOFEM_LOG("WORLD", Sev::inform)
423 << "Flux blockset " << cubit_meshset_ptr->getName();
424 MOFEM_LOG("WORLD", Sev::inform)
425 << "Number of attributes " << block_data.size();
426
427 this->entsPtr = boost::make_shared<Range>();
428 CHKERR m_field.get_moab().get_entities_by_handle(cubit_meshset_ptr->meshset,
429 *(this->entsPtr), true);
430
431 MOFEM_LOG("WORLD", Sev::inform)
432 << "tForce vector initialised: " << this->tForce;
433 MOFEM_LOG("WORLD", Sev::inform)
434 << "Number of elements " << this->entsPtr->size();
435
437}
438
439template <int FIELD_DIM, AssemblyType A, IntegrationType I, typename OpBase>
441 OpFluxRhsImpl(MoFEM::Interface &m_field, int ms_id,
442 const std::string field_name,
443 std::vector<boost::shared_ptr<ScalingMethod>> smv,
444 ScalarFun user_fun)
446 field_name, smv, user_fun) {
447 CHK_THROW_MESSAGE(getMeshsetData(m_field, ms_id), "Get meshset data");
448}
449
450template <int FIELD_DIM, AssemblyType A, IntegrationType I, typename OpBase>
452 OpFluxRhsImpl(MoFEM::Interface &m_field, const std::string field_name,
453 std::vector<boost::shared_ptr<ScalingMethod>> smv,
454 ScalarFun user_fun)
456 field_name, smv, user_fun) {}
457
458template <int FIELD_DIM, AssemblyType A, IntegrationType I, typename OpBase>
460 I, OpBase>::iNtegrate(EntData &data) {
462
464
465 auto t_normal = Parent::OpSource::getFTensor1NormalsAtGaussPts();
466 auto t_w = Parent::OpSource::getFTensor0IntegrationWeight();
467
468 auto t_row_base = data.getFTensor0N();
469
470 // loop over integration points
471 for (int gg = 0; gg != Parent::OpSource::nbIntegrationPts; gg++) {
472 const double alpha = t_w * this->surfacePressure;
473 auto t_nf =
474 getFTensor1FromArray<FIELD_DIM, FIELD_DIM>(Parent::OpSource::locF);
475 int rr = 0;
476 for (; rr != Parent::OpSource::nbRows / FIELD_DIM; ++rr) {
477 t_nf(i) += alpha * t_row_base * t_normal(i);
478 ++t_row_base;
479 ++t_nf;
480 }
481 for (; rr < Parent::OpSource::nbRowBaseFunctions; ++rr)
482 ++t_row_base;
483
484 ++t_normal;
485 ++t_w; // move to another integration weight
486 }
487
488 EntityType fe_type =
489 Parent::OpSource::getNumeredEntFiniteElementPtr()->getEntType();
490 if (fe_type == MBTRI) {
491 Parent::OpSource::locF /= 2;
492 }
493
495}
496
497template <int FIELD_DIM, AssemblyType A, IntegrationType I, typename OpBase>
500 OpBase>::getMeshsetData(MoFEM::Interface &m_field, int ms_id) {
502
503 auto cubit_meshset_ptr =
504 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(ms_id,
505 SIDESET);
506
507 PressureCubitBcData pressure_data;
508 CHKERR cubit_meshset_ptr->getBcDataStructure(pressure_data);
509 this->surfacePressure = pressure_data.data.value1;
510
511 this->entsPtr = boost::make_shared<Range>();
512 CHKERR m_field.get_moab().get_entities_by_handle(cubit_meshset_ptr->meshset,
513 *(this->entsPtr), true);
514 MOFEM_LOG("WORLD", Sev::inform)
515 << "Pressure blockset from PRESSURESET ms_id = " << ms_id;
516 MOFEM_LOG("WORLD", Sev::inform)
517 << "Number of elements " << this->entsPtr->size();
519}
520
521template <int FIELD_DIM, AssemblyType A, IntegrationType I, typename OpBase>
524 OpBase>::OpFluxRhsImpl(MoFEM::Interface &m_field, int ms_id,
525 const std::string field_name,
526 std::vector<boost::shared_ptr<ScalingMethod>> smv,
527 ScalarFun user_fun)
528 : Parent(m_field, field_name, smv, user_fun) {
529 CHK_THROW_MESSAGE(getMeshsetData(m_field, ms_id), "Get meshset data");
530}
531
532template <int FIELD_DIM, AssemblyType A, IntegrationType I, typename OpBase>
535 OpBase>::getMeshsetData(MoFEM::Interface &m_field, int ms_id) {
537
538 auto cubit_meshset_ptr =
539 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(ms_id,
540 BLOCKSET);
541
542 std::vector<double> block_data;
543 CHKERR cubit_meshset_ptr->getAttributes(block_data);
544
545 MOFEM_LOG("SELF", Sev::warning)
546 << "BLOCKSET is expected to have " << FIELD_DIM
547 << " attributes but has size " << block_data.size();
548 if (block_data.size() != 1) {
549 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
550 "Size of attribute in BLOCKSET is too small");
551 }
552 this->surfacePressure = block_data[0];
553
554 MOFEM_LOG("WORLD", Sev::inform)
555 << "Pressure blockset " << cubit_meshset_ptr->getName();
556
557 this->entsPtr = boost::make_shared<Range>();
558 CHKERR m_field.get_moab().get_entities_by_handle(cubit_meshset_ptr->meshset,
559 *(this->entsPtr), true);
560 MOFEM_LOG("WORLD", Sev::inform)
561 << "Number of elements " << this->entsPtr->size();
562
564}
565
566template <AssemblyType A, IntegrationType I, typename OpBase>
568 OpFluxRhsImpl(const std::string field_name, const double value,
569 boost::shared_ptr<Range> ents_ptr,
570 std::vector<boost::shared_ptr<ScalingMethod>> smv,
571 ScalarFun user_fun)
572 : OpFluxRhsImpl(field_name, smv, user_fun) {
573 this->scalarValue = value;
574 this->entsPtr = ents_ptr;
575}
576
577template <AssemblyType A, IntegrationType I, typename OpBase>
579 OpFluxRhsImpl(const std::string field_name,
580 std::vector<boost::shared_ptr<ScalingMethod>> smv,
581 ScalarFun user_fun)
583
584 [this](const double x, const double y, const double z) {
585 return scalarValue * userFun(x, y, z);
586 }
587
588 ),
589 vecOfTimeScalingMethods(smv), userFun(user_fun) {
590
591 this->timeScalingFun = [this](const double t) {
592 double s = 1;
593 for (auto &o : vecOfTimeScalingMethods) {
594 s *= o->getScale(t);
595 }
596 return s;
597 };
598}
599
600template <AssemblyType A, IntegrationType I, typename OpBase>
602 MoFEM::Interface &m_field, int ms_id, const std::string field_name,
603 std::vector<boost::shared_ptr<ScalingMethod>> smv, ScalarFun user_fun)
605 field_name, smv, user_fun) {
606 CHK_THROW_MESSAGE(getMeshsetData(m_field, ms_id), "Get meshset data");
607}
608
609template <AssemblyType A, IntegrationType I, typename OpBase>
612 MoFEM::Interface &m_field, int ms_id) {
614
615 auto cubit_meshset_ptr =
616 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(ms_id,
617 BLOCKSET);
618 std::vector<double> block_data;
619 CHKERR cubit_meshset_ptr->getAttributes(block_data);
620 if (block_data.size() != 1) {
621 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
622 "Expected that block has one attribute, e.g. heat flux value");
623 }
624 this->scalarValue = block_data[0];
625
626 this->entsPtr = boost::make_shared<Range>();
627 CHKERR m_field.get_moab().get_entities_by_handle(cubit_meshset_ptr->meshset,
628 *(this->entsPtr), true);
629
630 MOFEM_LOG("WORLD", Sev::inform)
631 << "Flux blockset " << cubit_meshset_ptr->getName();
632 MOFEM_LOG("WORLD", Sev::inform)
633 << "Scalar attribute value: " << this->scalarValue;
634
636}
637
638template <AssemblyType A, IntegrationType I, typename OpBase>
640 OpFluxRhsImpl(MoFEM::Interface &m_field, int ms_id,
641 const std::string field_name,
642 std::vector<boost::shared_ptr<ScalingMethod>> smv,
643 ScalarFun user_fun)
645 field_name, smv, user_fun) {
646 CHK_THROW_MESSAGE(getMeshsetData(m_field, ms_id), "Get meshset data");
647}
648
649template <AssemblyType A, IntegrationType I, typename OpBase>
651 OpBase>::getMeshsetData(MoFEM::Interface &m_field,
652 int ms_id) {
654
655 auto cubit_meshset_ptr =
656 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(ms_id,
657 SIDESET);
658 HeatFluxCubitBcData heat_flux;
659 CHKERR cubit_meshset_ptr->getBcDataStructure(heat_flux);
660 this->scalarValue = heat_flux.data.value1;
661
662 this->entsPtr = boost::make_shared<Range>();
663 CHKERR m_field.get_moab().get_entities_by_handle(cubit_meshset_ptr->meshset,
664 *(this->entsPtr), true);
665
667}
668
669template <int FIELD_DIM, AssemblyType A, IntegrationType I, typename OpBase>
671 OpFluxRhsImpl(const std::string field_name, const double value,
672 boost::shared_ptr<Range> ents_ptr,
673 std::vector<boost::shared_ptr<ScalingMethod>> smv,
674 ScalarFun user_fun)
675 : OpFluxRhsImpl(field_name, smv) {
676 this->scalarValue = value;
677 this->entsPtr = ents_ptr;
678}
679
680template <int FIELD_DIM, AssemblyType A, IntegrationType I, typename OpBase>
682 OpFluxRhsImpl(const std::string field_name,
683 std::vector<boost::shared_ptr<ScalingMethod>> smv,
684 ScalarFun user_fun)
686
687 [this](const double x, const double y, const double z) {
688 return scalarValue * userFun(x, y, z);
689 }
690
691 ),
692 vecOfTimeScalingMethods(smv), userFun(user_fun) {
693
694 this->timeScalingFun = [this](const double t) {
695 double s = 1;
696 for (auto &o : vecOfTimeScalingMethods) {
697 s *= o->getScale(t);
698 }
699 return s;
700 };
701}
702
703template <int FIELD_DIM, AssemblyType A, IntegrationType I, typename OpBase>
705 OpFluxRhsImpl(MoFEM::Interface &m_field, int ms_id,
706 const std::string field_name,
707 std::vector<boost::shared_ptr<ScalingMethod>> smv,
708 ScalarFun user_fun)
710 field_name, smv, user_fun) {
711 CHK_THROW_MESSAGE(getMeshsetData(m_field, ms_id), "Get meshset data");
712}
713
714template <int FIELD_DIM, AssemblyType A, IntegrationType I, typename OpBase>
716 OpBase>::getMeshsetData(MoFEM::Interface &m_field,
717 int ms_id) {
719
720 auto cubit_meshset_ptr =
721 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(ms_id,
722 BLOCKSET);
723 std::vector<double> attr_vec;
724 cubit_meshset_ptr->getAttributes(attr_vec);
725 if (attr_vec.size() != 1)
726 SETERRQ(PETSC_COMM_SELF, MOFEM_INVALID_DATA, "Should be one attribute");
727 this->scalarValue = attr_vec[0];
728
729 this->entsPtr = boost::make_shared<Range>();
730 CHKERR m_field.get_moab().get_entities_by_handle(cubit_meshset_ptr->meshset,
731 *(this->entsPtr), true);
732
734}
735
736template <int FIELD_DIM, AssemblyType A, IntegrationType I, typename OpBase>
738 OpFluxRhsImpl(MoFEM::Interface &m_field, int ms_id,
739 const std::string field_name,
740 std::vector<boost::shared_ptr<ScalingMethod>> smv,
741 ScalarFun user_fun)
743 field_name, smv, user_fun) {
744 CHK_THROW_MESSAGE(getMeshsetData(m_field, ms_id), "Get meshset data");
745}
746
747template <int FIELD_DIM, AssemblyType A, IntegrationType I, typename OpBase>
750 OpBase>::getMeshsetData(MoFEM::Interface &m_field, int ms_id) {
752
753 auto cubit_meshset_ptr =
754 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(ms_id,
755 NODESET);
756
758 CHKERR cubit_meshset_ptr->getBcDataStructure(mydata);
759 this->scalarValue = mydata.data.value1;
760
761 this->entsPtr = boost::make_shared<Range>();
762 CHKERR m_field.get_moab().get_entities_by_handle(cubit_meshset_ptr->meshset,
763 *(this->entsPtr), true);
764
766}
767
768/**
769 * @brief Function to push operators to rhs pipeline. This function user API.
770 *
771 * @tparam BCTYPE
772 * @tparam BASE_DIM
773 * @tparam FIELD_DIM
774 * @tparam A
775 * @tparam I
776 * @tparam OpBase
777 */
778template <int FIELD_DIM, AssemblyType A, IntegrationType I, typename OpBase>
781 OpFluxRhsImpl(
782 const std::string field_name,
784 boost::shared_ptr<Range> ents_ptr,
785 std::vector<boost::shared_ptr<TimeScaleVector<FIELD_DIM>>> smv,
786 ScalarFun user_fun)
787 : OpFluxRhsImpl(field_name, smv, user_fun) {
789 this->tForce(i) = t_force(i);
790 this->entsPtr = ents_ptr;
791}
792
793template <int FIELD_DIM, AssemblyType A, IntegrationType I, typename OpBase>
796 OpFluxRhsImpl(
797 const std::string field_name,
798 std::vector<boost::shared_ptr<TimeScaleVector<FIELD_DIM>>> smv,
799 ScalarFun user_fun)
801 [this](double x, double y, double z) {
803 auto t = this->getFEMethod()->ts_t;
804 for (auto &o : vecOfTimeVectorScalingMethods) {
805 auto vec = o->getVector(t);
806 this->tForce(i) = vec(i) * userFun(x, y, z);
807 }
808 return this->tForce;
809 }),
810 vecOfTimeVectorScalingMethods(smv), userFun(user_fun) {
811
812 static_assert(FIELD_DIM > 1, "Not implemented for scalar field");
813}
814
815template <int FIELD_DIM, AssemblyType A, IntegrationType I, typename OpBase>
816OpFluxRhsImpl<NaturalMeshsetTypeVectorScaling<BLOCKSET>, 1, FIELD_DIM, A, I,
818 OpFluxRhsImpl(
819 MoFEM::Interface &m_field, int ms_id, const std::string field_name,
820 std::vector<boost::shared_ptr<TimeScaleVector<FIELD_DIM>>> smv,
821 ScalarFun user_fun)
823 A, I, OpBase>(field_name, smv, user_fun) {
824 CHK_THROW_MESSAGE(getMeshsetData(m_field, ms_id), "Get meshset data");
825}
826
827template <int FIELD_DIM, AssemblyType A, IntegrationType I, typename OpBase>
830 OpBase>::getMeshsetData(MoFEM::Interface &m_field, int ms_id) {
832
833 auto cubit_meshset_ptr =
834 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(ms_id,
835 BLOCKSET);
836
837 std::vector<double> block_data;
838 CHKERR cubit_meshset_ptr->getAttributes(block_data);
839 if (block_data.size() != FIELD_DIM) {
840 MOFEM_LOG("SELF", Sev::warning)
841 << "BLOCKSET is expected to have " << FIELD_DIM
842 << " attributes but has size " << block_data.size();
843 if (block_data.size() < FIELD_DIM) {
844
845 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
846 "Size of attribute in BLOCKSET is too small");
847 }
848 }
849
850 for (unsigned int ii = 0; ii != FIELD_DIM; ++ii) {
851 this->tForce(ii) = block_data[ii];
852 }
853
854 MOFEM_LOG("WORLD", Sev::inform)
855 << "Flux blockset " << cubit_meshset_ptr->getName();
856 MOFEM_LOG("WORLD", Sev::inform)
857 << "Number of attributes " << block_data.size();
858 MOFEM_LOG("WORLD", Sev::inform)
859 << "tForce vector initialised: " << this->tForce;
860
861 this->entsPtr = boost::make_shared<Range>();
862 CHKERR m_field.get_moab().get_entities_by_handle(cubit_meshset_ptr->meshset,
863 *(this->entsPtr), true);
864
866}
867
868template <CubitBC BCTYPE, int BASE_DIM, int FIELD_DIM, AssemblyType A,
869 IntegrationType I, typename OpBase>
871
873 OpBase>,
874 A, I, OpBase
875
876 > {
877
879
881
882 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
883 MoFEM::Interface &m_field, const std::string field_name,
884 std::vector<boost::shared_ptr<ScalingMethod>> smv, std::string block_name,
885 ScalarFun user_fun, FEFun fe_fun, Sev sev
886
887 ) {
889
890 using OP = typename NaturalBC<OpBase>::template Assembly<
893
894 auto add_op = [&](auto &&meshset_vec_ptr) {
895 for (auto m : meshset_vec_ptr) {
896 MOFEM_TAG_AND_LOG("WORLD", sev, "OpFlux") << "Add " << *m;
897 auto op = new OP(m_field, m->getMeshsetId(), field_name, smv, user_fun);
898 op->feScalingFun = fe_fun;
899 pipeline.push_back(op);
900 }
901 MOFEM_LOG_CHANNEL("WORLD");
902 };
903
904 switch (BCTYPE) {
905 case TEMPERATURESET:
906 case FORCESET:
908 NODESET | BCTYPE));
909 case PRESSURESET:
910 case HEATFLUXSET:
912 SIDESET | BCTYPE));
913 break;
914 case BLOCKSET:
915 add_op(
916
918 std::regex(
919
920 (boost::format("%s(.*)") % block_name).str()
921
922 ))
923
924 );
925
926 break;
927 default:
928 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
929 "Handling of bc type not implemented");
930 break;
931 }
933 }
934
936
937 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
938 MoFEM::Interface &m_field, const std::string field_name,
939 std::vector<boost::shared_ptr<ScalingMethod>> smv, std::string block_name,
940 ScalarFun user_fun, Sev sev
941
942 ) {
943 return add(
944 pipeline, m_field, field_name, smv, block_name, user_fun,
945 [](const FEMethod *) { return 1; }, sev);
946 }
947
948 static MoFEMErrorCode
949 add(boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
950 MoFEM::Interface &m_field, const std::string field_name,
951 std::vector<boost::shared_ptr<ScalingMethod>> smv, std::string block_name,
952 Sev sev) {
953 return add(
954 pipeline, m_field, field_name, smv, block_name,
955 [](double, double, double) { return 1; }, sev);
956 }
957};
958
959template <CubitBC BCTYPE, int BASE_DIM, int FIELD_DIM, AssemblyType A,
960 IntegrationType I, typename OpBase>
962
964 OpBase>,
965 A, I, OpBase
966
967 > {
968
970
972
973 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
974 MoFEM::Interface &m_field, const std::string field_name,
975 std::vector<boost::shared_ptr<ScalingMethod>> smv, std::string block_name,
976 ScalarFun user_fun, Sev sev
977
978 ) {
980
981 using OPV =
982 typename NaturalBC<OpBase>::template Assembly<A>::template LinearForm<
984 FIELD_DIM>;
985
986 auto add_opv = [&](auto &&meshset_vec_ptr) {
987 for (auto m : meshset_vec_ptr) {
988 MOFEM_TAG_AND_LOG("WORLD", sev, "OpFlux") << "Add " << *m;
989 pipeline.push_back(
990 new OPV(m_field, m->getMeshsetId(), field_name, smv, user_fun));
991 }
992 MOFEM_LOG_CHANNEL("WORLD");
993 };
994
995 switch (BCTYPE) {
996 case BLOCKSET:
997 add_opv(
998
1000 std::regex(
1001
1002 (boost::format("%s(.*)") % block_name).str()
1003
1004 ))
1005
1006 );
1007
1008 break;
1009 default:
1010 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
1011 "Handling of bc type not implemented");
1012 break;
1013 }
1015 }
1016
1017 static MoFEMErrorCode
1018 add(boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
1019 MoFEM::Interface &m_field, const std::string field_name,
1020 std::vector<boost::shared_ptr<ScalingMethod>> smv, std::string block_name,
1021 Sev sev) {
1022 return add(
1023 pipeline, m_field, field_name, smv, block_name,
1024 [](double, double, double) { return 1; }, sev);
1025 }
1026};
1027
1028template <CubitBC BCTYPE, int BASE_DIM, int FIELD_DIM, AssemblyType A,
1029 IntegrationType I, typename OpBase>
1031
1033 A, I, OpBase>,
1034 A, I, OpBase
1035
1036 > {
1037
1039
1041
1042 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
1043 MoFEM::Interface &m_field, const std::string field_name,
1044 std::vector<boost::shared_ptr<ScalingMethod>> smv,
1045 std::vector<boost::shared_ptr<TimeScaleVector<FIELD_DIM>>> vsmv,
1046 std::string block_name, ScalarFun user_fun, FEFun fe_fun, Sev sev
1047
1048 ) {
1050
1051 using OPV =
1052 typename NaturalBC<OpBase>::template Assembly<A>::template LinearForm<
1055
1056 auto add_opv = [&](auto &&meshset_vec_ptr) {
1057 for (auto m : meshset_vec_ptr) {
1058 MOFEM_TAG_AND_LOG("WORLD", sev, "OpFlux") << "Add " << *m;
1059 auto op =
1060 new OPV(m_field, m->getMeshsetId(), field_name, vsmv, user_fun);
1061 op->feScalingFun = fe_fun;
1062 pipeline.push_back(op);
1063 }
1064 MOFEM_LOG_CHANNEL("WORLD");
1065 };
1066
1067 switch (BCTYPE) {
1068 case BLOCKSET:
1069 add_opv(
1070
1072 std::regex(
1073
1074 (boost::format("%s(.*)") % block_name).str()
1075
1076 ))
1077
1078 );
1079
1080 break;
1081 default:
1082 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
1083 "Handling of bc type not implemented");
1084 break;
1085 }
1087 }
1088
1090
1091 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
1092 MoFEM::Interface &m_field, const std::string field_name,
1093 std::vector<boost::shared_ptr<ScalingMethod>> smv,
1094 std::vector<boost::shared_ptr<TimeScaleVector<FIELD_DIM>>> vsmv,
1095 std::string block_name, ScalarFun user_fun, Sev sev
1096
1097 ) {
1098 return add(
1099 pipeline, m_field, field_name, smv, vsmv, block_name, user_fun,
1100 [](const FEMethod *) { return 1; }, sev);
1101 }
1102
1103 static MoFEMErrorCode
1104 add(boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
1105 MoFEM::Interface &m_field, const std::string field_name,
1106 std::vector<boost::shared_ptr<ScalingMethod>> smv,
1107 std::vector<boost::shared_ptr<TimeScaleVector<FIELD_DIM>>> vsmv,
1108 std::string block_name, Sev sev) {
1109 return add(
1110 pipeline, m_field, field_name, smv, vsmv, block_name,
1111 [](double, double, double) { return 1; }, sev);
1112 }
1113};
1114
1115} // namespace MoFEM
1116
1117#endif //_NATURAL_MESHSET_TYPE_HPP_
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
constexpr int FIELD_DIM
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
CubitBC
Types of sets and boundary conditions.
@ TEMPERATURESET
@ PRESSURESET
@ FORCESET
@ HEATFLUXSET
@ NODESET
@ SIDESET
@ UNKNOWNSET
@ BLOCKSET
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
@ MOFEM_INVALID_DATA
Definition definitions.h:36
@ MOFEM_NOT_IMPLEMENTED
Definition definitions.h:32
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
constexpr int BASE_DIM
IntegrationType
Form integrator integration types.
boost::function< double(const double, const double, const double)> ScalarFun
Scalar function type.
AssemblyType
[Storage and set boundary conditions]
#define MOFEM_LOG(channel, severity)
Log.
SeverityLevel
Severity levels.
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
MoFEMErrorCode getCubitMeshsetPtr(const int ms_id, const CubitBCType cubit_bc_type, const CubitMeshSets **cubit_meshset_ptr) const
get cubit meshset
FTensor::Index< 'i', SPACE_DIM > i
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
std::vector< boost::shared_ptr< TimeScaleVector< FIELD_DIM > > > VecOfTimeVectorScalingMethods
Vector of time vector scaling methods.
Definition Natural.hpp:28
boost::function< double(const FEMethod *fe_ptr)> FEFun
Lambda function used to scale with time.
std::vector< boost::shared_ptr< ScalingMethod > > VecOfTimeScalingMethods
Vector of time scaling methods.
Definition Natural.hpp:20
constexpr IntegrationType I
constexpr AssemblyType A
constexpr double t
plate stiffness
Definition plate.cpp:58
constexpr auto field_name
FTensor::Index< 'm', 3 > m
static MoFEMErrorCode add(boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, MoFEM::Interface &m_field, const std::string field_name, std::vector< boost::shared_ptr< ScalingMethod > > smv, std::string block_name, Sev sev)
static MoFEMErrorCode add(boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, MoFEM::Interface &m_field, const std::string field_name, std::vector< boost::shared_ptr< ScalingMethod > > smv, std::string block_name, ScalarFun user_fun, Sev sev)
static MoFEMErrorCode add(boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, MoFEM::Interface &m_field, const std::string field_name, std::vector< boost::shared_ptr< ScalingMethod > > smv, std::vector< boost::shared_ptr< TimeScaleVector< FIELD_DIM > > > vsmv, std::string block_name, Sev sev)
static MoFEMErrorCode add(boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, MoFEM::Interface &m_field, const std::string field_name, std::vector< boost::shared_ptr< ScalingMethod > > smv, std::vector< boost::shared_ptr< TimeScaleVector< FIELD_DIM > > > vsmv, std::string block_name, ScalarFun user_fun, Sev sev)
static MoFEMErrorCode add(boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, MoFEM::Interface &m_field, const std::string field_name, std::vector< boost::shared_ptr< ScalingMethod > > smv, std::vector< boost::shared_ptr< TimeScaleVector< FIELD_DIM > > > vsmv, std::string block_name, ScalarFun user_fun, FEFun fe_fun, Sev sev)
static MoFEMErrorCode add(boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, MoFEM::Interface &m_field, const std::string field_name, std::vector< boost::shared_ptr< ScalingMethod > > smv, std::string block_name, ScalarFun user_fun, Sev sev)
static MoFEMErrorCode add(boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, MoFEM::Interface &m_field, const std::string field_name, std::vector< boost::shared_ptr< ScalingMethod > > smv, std::string block_name, ScalarFun user_fun, FEFun fe_fun, Sev sev)
static MoFEMErrorCode add(boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, MoFEM::Interface &m_field, const std::string field_name, std::vector< boost::shared_ptr< ScalingMethod > > smv, std::string block_name, Sev sev)
virtual moab::Interface & get_moab()=0
Deprecated interface functions.
Data on single entity (This is passed as argument to DataOperator::doWork)
FTensor::Tensor0< FTensor::PackPtr< double *, 1 > > getFTensor0N(const FieldApproximationBase base)
Get base function as Tensor0.
Structure for user loop methods on finite elements.
Definition of the force bc data structure.
Definition BCData.hpp:135
Definition of the heat flux bc data structure.
Definition BCData.hpp:423
Interface for managing meshsets containing materials and boundary conditions.
Natural boundary conditions.
Definition Natural.hpp:57
Type generating natural b.c. specialisations for meshsets.
typename FormsIntegrators< OpBase >::template Assembly< A >::template LinearForm< I >::template OpSource< 1, FIELD_DIM > OpSource
typename FormsIntegrators< OpBase >::template Assembly< A >::template LinearForm< I >::template OpSource< 1, 1 > OpSource
MoFEMErrorCode getMeshsetData(MoFEM::Interface &m_field, int ms_id)
Base class for OpFluxRhsImpl<NaturalMeshsetType<T>, 1, FIELD_DIM, A, I, OpBase>
typename FormsIntegrators< OpBase >::template Assembly< A >::template LinearForm< I >::template OpSource< 1, FIELD_DIM > OpSource
typename FormsIntegrators< OpBase >::template Assembly< A >::template LinearForm< I >::template OpNormalMixVecTimesScalar< FIELD_DIM > OpSource
Definition of the pressure bc data structure.
Definition BCData.hpp:375
Definition of the temperature bc data structure.
Definition BCData.hpp:302
Force scale operator for reading four columns (time and vector)
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.