92 {
93 int count_meshset_sides = 0;
95
96 auto check = [](
auto &
b,
auto &
m,
auto &
bit) {
97 return ((
bit & b).any()) && ((
bit &
m) ==
bit);
98 };
99
100 auto set_child_data = [](auto &parent_data, auto &child_data) {
102 child_data.getEntDataBitRefLevel() = parent_data.getEntDataBitRefLevel();
103 child_data.sPace = parent_data.getSpace();
104 child_data.bAse = parent_data.getBase();
105 child_data.sEnse = parent_data.getSense();
106 child_data.oRder = parent_data.getOrder();
107 child_data.iNdices.swap(parent_data.getIndices());
108 child_data.localIndices.swap(parent_data.getLocalIndices());
109 child_data.dOfs.swap(parent_data.getFieldDofs());
110 child_data.fieldData.swap(parent_data.getFieldData());
111 child_data.fieldEntities.swap(parent_data.getFieldEntities());
113 };
114
115
116
117
118
119
120
121 auto set_child_base = [](auto &parent_data, auto &child_data) {
123 child_data.resetFieldDependentData();
124 child_data.getEntDataBitRefLevel() = parent_data.getEntDataBitRefLevel();
125 child_data.sPace = parent_data.getSpace();
126 child_data.getEntDataBitRefLevel() = parent_data.getEntDataBitRefLevel();
127
128#ifndef NDEBUG
131#endif
132
135 for (auto derivative = 0; derivative != BaseDerivatives::LastDerivative;
136 ++derivative) {
137 auto parent_base =
140 if (parent_base) {
141 auto child_base = child_data.getNSharedPtr(
144 if (!child_base)
145 child_base = boost::make_shared<MatrixDouble>();
146 child_base->swap(*parent_base);
147 }
148 }
149 }
150
152 };
153
154 auto switch_of_dofs_children = [](auto &parent_ent_data, auto &child_data) {
156 for (
auto i : parent_ent_data.getIndices()) {
158 for (auto &child_ent_data : child_data) {
159 auto it = std::find(child_ent_data.getIndices().begin(),
160 child_ent_data.getIndices().end(),
i);
161 if (it != child_ent_data.getIndices().end()) {
162 const auto dof_idx =
163 std::distance(child_ent_data.getIndices().begin(), it);
164 child_ent_data.getIndices()[dof_idx] = -1;
165 child_ent_data.getLocalIndices()[dof_idx] = -1;
166 child_ent_data.getFieldData()[dof_idx] = 0;
167 }
168 }
169 }
170 }
172 };
173
174
175
176 auto do_work_parent_hook = [&](
DataOperator *op_ptr,
int side,
178 EntitiesFieldData::EntData &data) {
180
181 BitRefLevel &bit_ent = data.getEntDataBitRefLevel();
182
183
185 ++count_meshset_sides;
186
189 << "Add entity data to meshset "
190 << "side/type: " << side << "/" << CN::EntityTypeName(type)
193 }
194
195 auto &data_on_meshset = entities_field_data.dataOnEntities[MBENTITYSET];
196 if (data_on_meshset.size() < count_meshset_sides) {
198 data_on_meshset.transfer(data_on_meshset.end(),
200 } else {
201 entities_field_data.dataOnEntities[MBENTITYSET].resize(
202 count_meshset_sides);
203 }
204 }
205
206 auto &child_data_meshset =
207 entities_field_data
208 .dataOnEntities[MBENTITYSET][count_meshset_sides - 1];
209
211 CHKERR set_child_base(data, child_data_meshset);
212 child_data_meshset.resetFieldDependentData();
213
214 } else {
215
216 auto &field_entities = data.getFieldEntities();
217
218
219 if (field_entities.size() > 1) {
220 int dof_idx = 0;
221 for (auto dof : data.getFieldDofs()) {
222 auto &bit_ent = dof->getBitRefLevel();
224 data.getIndices()[dof_idx] = -1;
225 data.getLocalIndices()[dof_idx] = -1;
226 data.getFieldData()[dof_idx] = 0;
227 }
228 ++dof_idx;
229 }
230 }
231
232#ifndef NDEBUG
234 for (auto field_ent : field_entities) {
236 << "Parent field entity bit: " << field_ent->getBitRefLevel()
237 << " " << *field_ent;
238 }
239 }
240#endif
241
242 if (field_entities.size()) {
243 boost::container::static_vector<EntityType, 128> ents_type;
244 ents_type.reserve(field_entities.size());
245 for (auto fe : field_entities)
246 ents_type.push_back(fe->getEntType());
247 std::sort(ents_type.begin(), ents_type.end());
248
249 auto end = std::unique(ents_type.begin(), ents_type.end());
250 for (auto it_t = ents_type.begin(); it_t != end; ++it_t)
251 CHKERR switch_of_dofs_children(
252 data, entities_field_data.dataOnEntities[*it_t]);
253 if (type == MBENTITYSET)
254 CHKERR switch_of_dofs_children(
255 data, entities_field_data.dataOnEntities[type]);
256 }
257
258 CHKERR set_child_data(data, child_data_meshset);
259 }
260 }
261
263 };
264
265
268
271 }
272
273 auto loop_parent_fe = [&]() {
275
276 parentElePtr->getOpPtrVector().back().doWorkRhsHook = do_work_parent_hook;
279
280#ifndef NDEBUG
282 if (
getGaussPts().size1() != parent_gauss_pts.size1()) {
284 MOFEM_LOG(
"SELF", Sev::error) << parent_gauss_pts;
286 "Wrong number of weights");
287 }
288 if (
getGaussPts().size2() != parent_gauss_pts.size2()) {
290 "Wrong number of integration points");
291 }
292#endif
293
295 };
296
298 }
299
302 << "Number of meshset entities "
303 << entities_field_data.dataOnEntities[MBENTITYSET].size();
304 }
305
306 auto &data_on_meshset = entities_field_data.dataOnEntities[MBENTITYSET];
307 auto it = data_on_meshset.begin();
308
309 if (count_meshset_sides < data_on_meshset.size()) {
310 for (auto s = 0; s != count_meshset_sides; ++s)
311 ++it;
313 data_on_meshset);
314 }
315
316 auto set_up_derivative_ent_data = [&](auto &entities_field_data,
317 auto &derivative_entities_field_data) {
319
320 using EntData = EntitiesFieldData::EntData;
321 using DerivedEntData = DerivedEntitiesFieldData::DerivedEntData;
322
324 auto &ents_data = entities_field_data.dataOnEntities[MBENTITYSET];
325 auto &dev_ents_data =
326 derivative_entities_field_data.dataOnEntities[MBENTITYSET];
327 dev_ents_data.clear();
328 for (
auto c = 0;
c < ents_data.size(); ++
c) {
329 boost::shared_ptr<EntData> ent_data_ptr(data_ptr, &ents_data[
c]);
330 dev_ents_data.push_back(new DerivedEntData(ent_data_ptr));
331 }
333 };
334
336 CHKERR set_up_derivative_ent_data(
337 entities_field_data,
339 }
340
341#ifndef NDEBUG
342 auto &side_table =
344 for (auto &data : entities_field_data.dataOnEntities[MBENTITYSET]) {
345 for (auto dof : data.getFieldDofs()) {
346 auto &bit_dof = dof->getBitRefLevel();
348 auto ent = dof->getEnt();
349 if (side_table.find(ent) == side_table.end()) {
351 "Adjacency not found");
352 }
353 }
354 }
355 }
356#endif
357
359}
FieldApproximationBase
approximation base
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
@ AINSWORTH_BERNSTEIN_BEZIER_BASE
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
static const char *const FieldSpaceNames[]
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_DATA_INCONSISTENCY
static const char *const ApproximationBaseNames[]
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
FTensor::Index< 'm', SPACE_DIM > m
#define MOFEM_LOG(channel, severity)
Log.
FTensor::Index< 'i', SPACE_DIM > i
const double c
speed of light (cm/ns)
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
EntitiesFieldData::EntData::BaseDerivatives BaseDerivatives
DataOperator(const bool symm=true)
Data on single entity (This is passed as argument to DataOperator::doWork)
boost::shared_ptr< const NumeredEntFiniteElement > numeredEntFiniteElementPtr
MoFEMErrorCode loopParent(const string &fe_name, ForcesAndSourcesCore *parent_fe, const int verb=QUIET, const LogManager::SeverityLevel sev=Sev::noisy)
User call this function to loop over parent elements. This function calls finite element with is oper...
std::string getFEName() const
Get name of the element.
ForcesAndSourcesCore * getPtrFE() const
@ OPSPACE
operator do Work is execute on space data
const FEMethod * getFEMethod() const
Return raw pointer to Finite Element Method object.
MatrixDouble & getGaussPts()
matrix of integration (Gauss) points for Volume Element
auto & getDataOnElementBySpaceArray()
Get data on entities and space.
boost::ptr_deque< EntitiesFieldData::EntData > poolEntsVector