21 state_tags.begin(), state_tags.end(),
22 [](
const auto &lhs,
const auto &rhs) { return lhs.name < rhs.name; });
40 <<
"Tag name: " << name
41 <<
" is already registered with tag: " << it->second
42 <<
". Overwriting with new tag: " << tag;
48 if (p.second == tag) {
50 "Tag: " + std::to_string(tag) +
51 " is already registered with name: " + p.first);
62 if (p.second > max_tag) {
73 <<
"Tag name: " << name
92 if (p.second == tag) {
113 Data(
const std::string &data_name,
116 Data(
const std::string &data_name,
int num_components,
Tag data_tag = 0)
117 :
name(data_name),
data(num_components, 1),
136 struct DataSequence_mi_tag;
137 struct DataName_mi_tag;
143 boost::multi_index::indexed_by<
145 boost::multi_index::sequenced<
146 boost::multi_index::tag<DataSequence_mi_tag>>,
148 boost::multi_index::hashed_unique<
149 boost::multi_index::tag<DataName_mi_tag>,
150 boost::multi_index::member<Data, std::string, &Data::name>>>>;
153 return boost::multi_index::get<DataName_mi_tag>(
dataCommon);
157 return boost::multi_index::get<DataName_mi_tag>(
dataActive);
161 return boost::multi_index::get<DataName_mi_tag>(
dataDependent);
169 return boost::multi_index::get<DataName_mi_tag>(
dataState);
173 return boost::multi_index::get<DataSequence_mi_tag>(
dataState);
176 std::pair<bool, MatrixPtr>
179 int shift = 0)
override {
181 return {insert_ret.second,
182 boost::shared_ptr<MatrixDouble>(this->shared_from_this(),
183 &insert_ret.first->data)};
186 std::pair<bool, MatrixPtr>
189 int shift = 0)
override {
191 return {insert_ret.second,
192 boost::shared_ptr<MatrixDouble>(this->shared_from_this(),
193 &insert_ret.first->data)};
196 std::pair<bool, MatrixPtr>
199 int shift = 0)
override {
201 return {insert_ret.second,
202 boost::shared_ptr<MatrixDouble>(this->shared_from_this(),
203 &insert_ret.first->data)};
206 std::pair<bool, MatrixPtr>
209 int shift = 0)
override {
212 return {insert_ret.second,
213 boost::shared_ptr<MatrixDouble>(this->shared_from_this(),
214 &insert_ret.first->data)};
219 auto it = data_by_name.find(name);
220 if (it == data_by_name.end()) {
222 "Common data with name " + name +
" not found");
225 return boost::shared_ptr<MatrixDouble>(this->shared_from_this(), &it->data);
230 auto it = data_by_name.find(name);
231 if (it == data_by_name.end()) {
233 "Active data with name " + name +
" not found");
236 return boost::shared_ptr<MatrixDouble>(this->shared_from_this(), &it->data);
241 auto it = data_by_name.find(name);
242 if (it == data_by_name.end()) {
244 "Dependent data with name " + name +
" not found");
247 return boost::shared_ptr<MatrixDouble>(this->shared_from_this(), &it->data);
252 auto it = data_by_name.find(name);
253 if (it == data_by_name.end()) {
255 "Dependent derivatives data with name " + name +
259 return boost::shared_ptr<MatrixDouble>(this->shared_from_this(), &it->data);
265 auto it = state_by_name.find(name);
266 if (it == state_by_name.end()) {
268 "State data with name " + name +
" not found");
273 "MoFEM interface for state data is not set");
278 "State entity is not set");
283 "State gauss point out of range");
289 "State data " + name +
290 " is not initialised; call setupStateData() after binding");
293 const auto required_size = it->numComponents * (gg + 1);
294 if (gg == 0 || ent != it->cachedEntity || !it->cachedPtr ||
295 required_size > it->cachedSize) {
296 it->resetStateCache();
297 double *tag_data =
nullptr;
300 auto rval = moab.tag_get_by_ptr(it->tag, &ent, 1,
301 (
const void **)&tag_data, &tag_size);
302 if (tag_data && tag_size > 0 && tag_size % it->numComponents != 0) {
304 "Inconsistent state tag size for " + name);
307 if (
rval != MB_SUCCESS || !tag_data || tag_size < required_size) {
308 std::vector<double> storage(required_size, 0);
309 if (
rval == MB_SUCCESS && tag_data && tag_size > 0) {
310 std::copy_n(tag_data, std::min(tag_size, required_size),
313 void const *storage_ptr[] = {storage.data()};
314 int storage_size = required_size;
316 moab.tag_set_by_ptr(it->tag, &ent, 1, storage_ptr, &storage_size),
317 "Failed to set state data " + name);
319 (
const void **)&tag_data,
321 "Failed to get state data " + name);
323 if (!tag_data || tag_size < required_size ||
324 (tag_size > 0 && tag_size % it->numComponents != 0)) {
326 "Inconsistent state tag size for " + name);
330 it->cachedEntity = ent;
331 it->cachedPtr = tag_data;
332 it->cachedSize = tag_size;
335 auto *ptr = it->cachedPtr + gg * it->numComponents;
336 return boost::make_shared<MatrixAdaptor>(
337 it->numComponents, 1,
338 ublas::shallow_array_adaptor<double>(it->numComponents, ptr));
343 const auto &state_by_sequence =
344 boost::multi_index::get<DataSequence_mi_tag>(
dataState);
346 for (
const auto &state_data : state_by_sequence) {
347 if (!state_data.tag || state_data.name.empty() ||
348 state_data.numComponents <= 0)
350 state_tags.push_back(
351 {state_data.name, state_data.tag, state_data.numComponents});
359 const std::string &name,
360 int num_components)
override {
363 state_data.resetStateCache();
369 "State data name can not be empty");
372 if (num_components <= 0) {
374 "State data %s has non-positive number of components %d",
375 name.c_str(), num_components);
379 auto it = state_by_name.find(name);
380 if (it != state_by_name.end()) {
381 if (it->numComponents != num_components) {
383 "State data %s already exists with incompatible size",
387 state_by_name.insert(
Data{name, num_components});
397 "MoFEM interface for state data is not set");
401 state_data.resetStateCache();
403 const auto state_tag_name =
"_ADOLC_STATE_" +
404 std::to_string(state_data.numComponents) +
405 "_" + state_data.name;
407 state_tag_name.c_str(), 0, MB_TYPE_DOUBLE, tag,
408 MB_TAG_CREAT | MB_TAG_VARLEN | MB_TAG_SPARSE, PETSC_NULLPTR);
411 [&](
auto &data) { data.tag = tag; });
423 std::vector<double> &dependent_variables)
override {
428 std::vector<double> &dependent_variables_derivatives)
override {
430 dependent_variables_derivatives);
434 const std::vector<double> &active_variables)
override {
439 const std::vector<double> &dependent_variables)
override {
444 const std::vector<double> &dependent_variables_derivatives)
override {
446 dependent_variables_derivatives);
451 std::vector<double> &variables) {
454 auto &data_by_sequence =
455 boost::multi_index::get<DataSequence_mi_tag>(data_container);
457 int nb_variables = 0;
458 for (
const auto &d : data_by_sequence)
459 nb_variables += d.data.data().size();
461 variables.resize(nb_variables);
464 for (
const auto &d : data_by_sequence) {
466 for (
auto it = d.data.data().begin(); it != d.data.data().end();
468 variables[shift] = *it;
475 const std::vector<double> &variables) {
478 auto &data_by_sequence =
479 boost::multi_index::get<DataSequence_mi_tag>(data_container);
481 int nb_variables = 0;
482 for (
const auto &d : data_by_sequence)
483 nb_variables += d.data.data().size();
485 if (variables.size() !=
static_cast<size_t>(nb_variables)) {
487 "Inconsistent size of continuous vector");
491 for (
const auto &d : data_by_sequence) {
493 for (
auto it = d.data.data().begin(); it != d.data.data().end();
495 *it = variables[shift];
519 std::pair<bool, MatrixPtr>
522 int shift = 0)
override {
523 return baseImplPtr->insertCommonData(name, data, shift);
527 return boost::multi_index::get<DataName_mi_tag>(
dataActive);
531 return boost::multi_index::get<DataName_mi_tag>(
dataDependent);
538 std::pair<bool, MatrixPtr>
541 int shift = 0)
override {
543 if (!insert_ret.second)
545 return {
true, boost::shared_ptr<MatrixDouble>(this->shared_from_this(),
546 &insert_ret.first->data)};
549 std::pair<bool, MatrixPtr>
552 int shift = 0)
override {
554 if (!insert_ret.second)
556 return {
true, boost::shared_ptr<MatrixDouble>(this->shared_from_this(),
557 &insert_ret.first->data)};
560 std::pair<bool, MatrixPtr>
563 int shift = 0)
override {
566 if (!insert_ret.second)
568 return {
true, boost::shared_ptr<MatrixDouble>(this->shared_from_this(),
569 &insert_ret.first->data)};
582 auto it = data_by_name.find(name);
583 if (it == data_by_name.end()) {
585 "Active data with name " + name +
" not found");
588 return boost::shared_ptr<MatrixDouble>(this->shared_from_this(), &it->data);
593 auto it = data_by_name.find(name);
594 if (it == data_by_name.end()) {
596 "Dependent data with name " + name +
" not found");
599 return boost::shared_ptr<MatrixDouble>(this->shared_from_this(), &it->data);
604 auto it = data_by_name.find(name);
605 if (it == data_by_name.end()) {
607 "Dependent derivatives data with name " + name +
611 return boost::shared_ptr<MatrixDouble>(this->shared_from_this(), &it->data);
618 return baseImplPtr->getStateDataPtr(it->second, ent, gg);
619 return baseImplPtr->getStateDataPtr(name, ent, gg);
624 for (
auto &tag_info : state_tags) {
626 if (base_name == tag_info.name) {
627 tag_info.name = alias_name;
637 const std::string &name,
638 int num_components)
override {
641 return baseImplPtr->bindStateTag(m_field, it->second, num_components);
642 return baseImplPtr->bindStateTag(m_field, name, num_components);
655 std::vector<double> &dependent_variables)
override {
660 std::vector<double> &dependent_variables_derivatives)
override {
662 dependent_variables_derivatives);
666 const std::vector<double> &active_variables)
override {
671 const std::vector<double> &dependent_variables)
override {
676 const std::vector<double> &dependent_variables_derivatives)
override {
678 dependent_variables_derivatives);
691 static boost::shared_ptr<MatOpsDataImpl>
693 auto base_data = base_data_ptr.lock();
696 "Base MatOps data pointer expired");
699 auto base_impl_ptr = boost::dynamic_pointer_cast<MatOpsDataImpl>(base_data);
700 if (!base_impl_ptr) {
702 "Base MatOps data pointer has incompatible type");
705 return base_impl_ptr;
710 return boost::make_shared<MatOpsDataImpl>();
713boost::shared_ptr<MatOpsData>
717 return boost::make_shared<MatOpsDataDerivedImpl>(
718 base_data_ptr, common_data_dictionary, state_data_dictionary);
722 boost::shared_ptr<MatOpsData> mat_ops_data_ptr,
int tag,
723 EntityHandle entity,
int gg) {
725 CHKERR mat_ops_data_ptr->setActiveContinuousVector(
727 CHKERR mat_ops_data_ptr->setDependentContinuousVector(
729 constexpr int adolc_return_value = 0;
732 if (PetscUnlikely(r < adolc_return_value)) {
734 "ADOL-C function evaluation with error");
736 CHKERR mat_ops_data_ptr->getDependentContinuousVector(
742 boost::shared_ptr<MatOpsData> mat_ops_data_ptr,
int tag,
743 EntityHandle entity,
int gg) {
745 constexpr int adolc_return_value = 0;
746 CHKERR mat_ops_data_ptr->setActiveContinuousVector(
748 CHKERR mat_ops_data_ptr->setDependentContinuousVector(
751 const auto number_of_active_variables =
753 const auto number_of_dependent_variables =
756 number_of_dependent_variables * number_of_active_variables);
758 for (
unsigned int n = 0;
n != number_of_dependent_variables; ++
n) {
761 [
n * number_of_active_variables]);
766 if (PetscUnlikely(r < adolc_return_value)) {
768 "ADOL-C function evaluation with error");
770 CHKERR mat_ops_data_ptr->getDependentDerivativesContinuousVector(
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_OPERATION_UNSUCCESSFUL
#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 ...
#define MOFEM_LOG(channel, severity)
Log.
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
const double n
refractive index of diffusive medium
static void sortStateTags(StateTags &state_tags)
std::map< std::string, std::string > DataDictionary
std::vector< StateTag > StateTags
boost::shared_ptr< MatOpsData > createMatOpsDataPtr()
static MoFEMErrorCodeGeneric< moab::ErrorCode > rval
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
UBlasMatrix< double > MatrixDouble
implementation of Data Operators for Forces and Sources
static MoFEMErrorCode evaluateVariable(boost::shared_ptr< MatOpsData > mat_ops_data_ptr, int tag, EntityHandle entity, int gg)
static std::vector< double > dependentVariablesDerivatives
static std::vector< double > dependentVariables
static MoFEMErrorCode evaluateDerivatives(boost::shared_ptr< MatOpsData > mat_ops_data_ptr, int tag, EntityHandle entity, int gg)
static std::vector< double > activeVariables
static std::vector< double * > jacPtrVec
std::pair< bool, MatrixPtr > insertDependentDerivativesData(const std::string &name, const MatrixDouble &data=MatrixDouble(), int shift=0) override
DataDictionary commonDataDictionary
auto & getDataDependentByName()
MoFEMErrorCode setDependentDerivativesContinuousVector(std::vector< double > &dependent_variables_derivatives) override
std::pair< bool, MatrixPtr > insertCommonData(const std::string &name, const MatrixDouble &data=MatrixDouble(), int shift=0) override
MoFEMErrorCode bindStateTag(MoFEM::Interface &m_field, const std::string &name, int num_components) override
MatOpsDataDerivedImpl(boost::weak_ptr< MatOpsData > base_data_ptr, DataDictionary common_data_dictionary, DataDictionary state_data_dictionary)
StateMatrixPtr getStateDataPtr(const std::string &name, EntityHandle ent, int gg) override
Start each integration-point sweep at gg == 0 to refresh cached tag storage.
MoFEMErrorCode getDependentDerivativesContinuousVector(const std::vector< double > &dependent_variables_derivatives) override
StateTags getStateTags() const override
DataContainer dataDependentDerivatives
auto & getDataActiveByName()
MoFEMErrorCode getActiveContinuousVector(const std::vector< double > &active_variables) override
MatrixPtr getCommonDataPtr(const std::string &name) override
MatrixPtr getDependentDerivativesDataPtr(const std::string &name) override
MatrixPtr getActiveDataPtr(const std::string &name) override
MoFEMErrorCode getDependentContinuousVector(const std::vector< double > &dependent_variables) override
MoFEMErrorCode setDependentContinuousVector(std::vector< double > &dependent_variables) override
MoFEMErrorCode setActiveContinuousVector(std::vector< double > &active_variables) override
std::pair< bool, MatrixPtr > insertActiveData(const std::string &name, const MatrixDouble &data=MatrixDouble(), int shift=0) override
MatrixPtr getDependentDataPtr(const std::string &name) override
auto & getDataDependentDerivativesByName()
DataDictionary stateDataDictionary
DataContainer dataDependent
std::pair< bool, MatrixPtr > insertDependentData(const std::string &name, const MatrixDouble &data=MatrixDouble(), int shift=0) override
static boost::shared_ptr< MatOpsDataImpl > lockBaseImplPtr(boost::weak_ptr< MatOpsData > base_data_ptr)
boost::shared_ptr< MatOpsDataImpl > baseImplPtr
MoFEMErrorCode setupStateData() override
EntityHandle cachedEntity
Data(const std::string &data_name, int num_components, Tag data_tag=0)
Data(const std::string &data_name, const MatrixDouble &data_value=MatrixDouble(), int data_shift=0)
void resetStateCache() const
DataContainer dataDependentDerivatives
MoFEMErrorCode getActiveContinuousVector(const std::vector< double > &active_variables) override
MoFEM::Interface * mFieldPtr
StateMatrixPtr getStateDataPtr(const std::string &name, EntityHandle ent, int gg) override
Start each integration-point sweep at gg == 0 to refresh cached tag storage.
auto & getDataActiveByName()
void setUserDataPtr(boost::shared_ptr< UserData > user_data_ptr) override
Set data owned by this container; back-references should be weak.
MoFEMErrorCode setupStateData() override
DataContainer dataDependent
boost::multi_index::multi_index_container< Data, boost::multi_index::indexed_by< boost::multi_index::sequenced< boost::multi_index::tag< DataSequence_mi_tag > >, boost::multi_index::hashed_unique< boost::multi_index::tag< DataName_mi_tag >, boost::multi_index::member< Data, std::string, &Data::name > > > > DataContainer
MatOpsData::StateMatrixPtr StateMatrixPtr
std::pair< bool, MatrixPtr > insertDependentDerivativesData(const std::string &name, const MatrixDouble &data=MatrixDouble(), int shift=0) override
std::pair< bool, MatrixPtr > insertDependentData(const std::string &name, const MatrixDouble &data=MatrixDouble(), int shift=0) override
MoFEMErrorCode setContinuousVector(DataContainer &data_container, std::vector< double > &variables)
auto & getDataDependentByName()
MoFEMErrorCode getDependentContinuousVector(const std::vector< double > &dependent_variables) override
MatrixPtr getCommonDataPtr(const std::string &name) override
MoFEMErrorCode bindStateTag(MoFEM::Interface &m_field, const std::string &name, int num_components) override
MatrixPtr getDependentDataPtr(const std::string &name) override
MatOpsData::MatrixPtr MatrixPtr
MoFEMErrorCode getDependentDerivativesContinuousVector(const std::vector< double > &dependent_variables_derivatives) override
MoFEMErrorCode setDependentDerivativesContinuousVector(std::vector< double > &dependent_variables_derivatives) override
auto & getDataDependentDerivativesByName()
auto & getStateDataByName()
std::pair< bool, MatrixPtr > insertCommonData(const std::string &name, const MatrixDouble &data=MatrixDouble(), int shift=0) override
MatrixPtr getDependentDerivativesDataPtr(const std::string &name) override
StateTags getStateTags() const override
MatrixPtr getActiveDataPtr(const std::string &name) override
boost::shared_ptr< UserData > getUserDataPtr() const override
Get the optional user-defined material data.
std::pair< bool, MatrixPtr > insertActiveData(const std::string &name, const MatrixDouble &data=MatrixDouble(), int shift=0) override
auto & getDataCommonByName()
auto & getStateDataBySequence()
MoFEMErrorCode setDependentContinuousVector(std::vector< double > &dependent_variables) override
MoFEMErrorCode setActiveContinuousVector(std::vector< double > &active_variables) override
boost::shared_ptr< UserData > userDataPtr
MoFEMErrorCode getContinuousVector(DataContainer &data_container, const std::vector< double > &variables)
boost::shared_ptr< MatrixAdaptor > StateMatrixPtr
boost::shared_ptr< MatrixDouble > MatrixPtr
virtual moab::Interface & get_moab()=0
Deprecated interface functions.