#include "BlockTopology.hxx"
#include "ComponentTopology.hxx"
#include "ParaFIELD.hxx"
+#include "ParaSUPPORT.hxx"
#include "DEC.hxx"
#include "ICoCoField.hxx"
#include "ICoCoMEDField.hxx"
If the processor is on the receiving end of the DEC, the field
will be updated by a recvData() call.
Reversely, if the processor is on the sending end, the field will be read, possibly transformed, and sent appropriately to the other side.
+
+ The \a field nature should correspond to interpolation \a method.
*/
- void DEC::attachLocalField(const ParaFIELD* field)
+ void DEC::attachLocalField(const ParaFIELD* field, const string& method)
{
_local_field=field;
_comm_interface=&(field->getTopology()->getProcGroup()->getCommInterface());
+
+ setMethod( method );
+ compareFieldAndMethod();
}
/*! Attaches a local field to a DEC. The method will test whether the processor
will be updated by a recvData() call.
Reversely, if the processor is on the sending end, the field will be read, possibly transformed,
and sent appropriately to the other side.
+
+ The \a field nature should correspond to interpolation \a method.
*/
- void DEC::attachLocalField(MEDMEM::FIELD<double>* field)
+ void DEC::attachLocalField(MEDMEM::FIELD<double>* field, const string& method)
{
ProcessorGroup* local_group;
if (_source_group->containsMyRank())
_local_field= new ParaFIELD(field, *local_group);
_owns_field=true;
_comm_interface=&(local_group->getCommInterface());
+
+ setMethod( method );
+ compareFieldAndMethod();
}
/*!
- a ICoCo::MEDField, that is created from a MEDMEM structure
- a ICOCo::TrioField, that is created from tables extracted from a TRIO-U structure.
+ The \a field nature should correspond to interpolation \a method.
*/
- void DEC::attachLocalField(const ICoCo::Field* field)
+ void DEC::attachLocalField(const ICoCo::Field* field, const string& method)
{
const ICoCo::MEDField* medfield =dynamic_cast<const ICoCo::MEDField*> (field);
if(medfield !=0)
{
- attachLocalField(medfield->getField());
+ attachLocalField(medfield->getField(), method);
return;
}
const ICoCo::TrioField* triofield=dynamic_cast<const ICoCo::TrioField*> (field);
else localgroup=_target_group;
_icoco_field=new ICoCo::MEDField(*const_cast<ICoCo::TrioField* >(triofield), *localgroup);
// _owns_field = true;
- attachLocalField(_icoco_field);
+ attachLocalField(_icoco_field, method);
return;
}
throw MEDMEM::MEDEXCEPTION("incompatible field type");
}
}
}
+ //================================================================================
+ /*!
+ Throws an exception if nature of the attached local field does not correspond to
+ interpolation method
+ */
+ //================================================================================
+
+ void DEC::compareFieldAndMethod() const
+ {
+ if (_local_field)
+ {
+ MED_EN::medEntityMesh entity = _local_field->getSupport()->getSupport()->getEntity();
+ if ( getMethod() == "P0" ) {
+ if ( entity != MED_EN::MED_CELL )
+ throw MEDMEM::MEDEXCEPTION("Field support and interpolation method mismatch."
+ " For P0 interpolation, field must be on MED_CELL's");
+ if ( _local_field->getField()->getGaussPresence() )
+ throw MEDMEM::MEDEXCEPTION("Field nature and interpolation method mismatch."
+ " For P0 interpolation, field must have one value per cell");
+ }
+ else if ( getMethod() == "P1" ) {
+ if ( entity != MED_EN::MED_NODE )
+ throw MEDMEM::MEDEXCEPTION("Field support and interpolation method mismatch."
+ " For P1 interpolation, field must be on MED_NODE's");
+ if ( _local_field->getField()->getGaussPresence() )
+ throw MEDMEM::MEDEXCEPTION("Field nature and interpolation method mismatch."
+ " For P1 interpolation, field must have one value per node");
+ }
+ else if ( getMethod() == "P1d" ) {
+ if ( entity != MED_EN::MED_CELL )
+ throw MEDMEM::MEDEXCEPTION("Field support and interpolation method mismatch."
+ " For P1d interpolation, field must be on MED_CELL's");
+ if ( !_local_field->getField()->getGaussPresence() )
+ throw MEDMEM::MEDEXCEPTION("Field nature and interpolation method mismatch."
+ " For P1d interpolation, field must have several values per cell");
+ MED_EN::medGeometryElement type = _local_field->getSupport()->getSupport()->getTypes()[0];
+ if ( _local_field->getField()->getNumberOfGaussPoints( type ) != type%100 )
+ throw MEDMEM::MEDEXCEPTION("Field nature and interpolation method mismatch."
+ " For P1d interpolation, number of values per cell "
+ "must be equal to number of nodes per cell");
+ if ( _target_group->containsMyRank() )
+ throw MEDMEM::MEDEXCEPTION("Projection to P1d field not supported");
+ }
+ else {
+ throw MEDMEM::MEDEXCEPTION("Unknown interpolation method. Possible methods: P0, P1, P1d");
+ }
+ }
+ }
/*! @} */
}
public:
DEC():_local_field(0){}
DEC(ProcessorGroup& local_group, ProcessorGroup& distant_group);
- void attachLocalField( MEDMEM::FIELD<double>* field);
- void attachLocalField(const ParaFIELD* field);
- void attachLocalField(const ICoCo::Field* field);
+ void attachLocalField( MEDMEM::FIELD<double>* field, const string& method ="P0");
+ void attachLocalField(const ParaFIELD* field, const string& method ="P0");
+ void attachLocalField(const ICoCo::Field* field, const string& method ="P0");
virtual void prepareSourceDE()=0;
virtual void prepareTargetDE()=0;
virtual void computeProcGroup(){}
void renormalizeTargetField();
protected:
+
+ void compareFieldAndMethod() const;
+
const ParaFIELD* _local_field;
//! Processor group representing the union of target and source processors
ProcessorGroup* _union_group;