void SimpleCrossSection :: giveTemperatureVector(FloatArray &answer, GaussPoint *gp, TimeStep *tStep) { Element *elem = gp->giveElement(); answer.clear(); //sum up all prescribed temperatures over an element StructuralElement *selem = dynamic_cast< StructuralElement * >(elem); selem->computeResultingIPTemperatureAt(answer, tStep, gp, VM_Total); /* add external source, if provided */ FieldManager *fm = this->domain->giveEngngModel()->giveContext()->giveFieldManager(); FM_FieldPtr tf; if ( ( tf = fm->giveField(FT_Temperature) ) ) { // temperature field registered FloatArray gcoords, et2; int err; elem->computeGlobalCoordinates( gcoords, gp->giveNaturalCoordinates() ); if ( ( err = tf->evaluateAt(et2, gcoords, VM_Total, tStep) ) ) { OOFEM_ERROR("tf->evaluateAt failed, element %d, error code %d", elem->giveNumber(), err); } if ( et2.isNotEmpty() ) { if ( answer.isEmpty() ) { answer = et2; } else { answer.at(1) += et2.at(1); } } } }
Metric Filler::get_metric(double x,double y,double z,GEntity* ge){ Metric m; SMetric3 temp; SVector3 v1,v2,v3; Field* field; FieldManager* manager; v1 = SVector3(1.0,0.0,0.0); v2 = SVector3(0.0,1.0,0.0); v3 = SVector3(0.0,0.0,1.0); manager = ge->model()->getFields(); if(manager->getBackgroundField()>0){ field = manager->get(manager->getBackgroundField()); if(field){ (*field)(x,y,z,temp,ge); } } m.set_m11(v1.x()); m.set_m21(v1.y()); m.set_m31(v1.z()); m.set_m12(v2.x()); m.set_m22(v2.y()); m.set_m32(v2.z()); m.set_m13(v3.x()); m.set_m23(v3.y()); m.set_m33(v3.z()); return m; }
double B3SolidMaterial :: giveHumidityIncrement(GaussPoint *gp, TimeStep *tStep) //computes humidity increment at given TimeStep { double humIncrement = 0.; int err, wflag = 0; /* ask for humidity from external sources, if provided */ FieldManager *fm = domain->giveEngngModel()->giveContext()->giveFieldManager(); FM_FieldPtr tf; FloatArray gcoords, et2, ei2; if ( ( tf = fm->giveField(FT_HumidityConcentration) ) ) { // humidity field registered gp->giveElement()->computeGlobalCoordinates( gcoords, gp->giveNaturalCoordinates() ); if ( ( err = tf->evaluateAt(et2, gcoords, VM_Total, tStep) ) ) { OOFEM_ERROR("tf->evaluateAt failed, error value %d", err); } if ( ( err = tf->evaluateAt(ei2, gcoords, VM_Incremental, tStep) ) ) { OOFEM_ERROR("tf->evaluateAt failed, error value %d", err); } // convert water mass to relative humidity humIncrement = this->inverse_sorption_isotherm( et2.at(1) ) - this->inverse_sorption_isotherm( et2.at(1) - ei2.at(1) ); wflag = 1; } if ( wflag == 0 ) { OOFEM_ERROR("external fields not found"); } return humIncrement; }
static void field_new_cb(Fl_Widget *w, void *data) { Fl_Menu_Button* mb = ((Fl_Menu_Button*)w); FieldManager *fields = GModel::current()->getFields(); int id = fields->newId(); add_field(id, mb->text(), GModel::current()->getFileName()); if((*fields)[id]) FlGui::instance()->fields->editField((*fields)[id]); }
TEUCHOS_UNIT_TEST(evaluator_macros, basic) { using namespace std; using namespace Teuchos; using namespace PHX; FieldManager<MyTraits> fm; // Mock evaluators for testing MACRO definitions using Ev1 = EvaluatorWithMacros1<MyTraits::Residual,MyTraits>; using Ev2 = EvaluatorWithMacros2<MyTraits::Residual,MyTraits>; { auto plist_a = Teuchos::parameterList("A"); RCP<Ev1> a = rcp(new Ev1(*plist_a)); a->setName("Eval_A"); a->evaluates("A"); a->requires("B"); a->requires("C"); fm.registerEvaluator<MyTraits::Residual>(a); } { auto plist_b = Teuchos::parameterList("B"); RCP<Ev2> b = rcp(new Ev2(*plist_b)); b->setName("Eval_B"); b->evaluates("B"); b->requires("D"); fm.registerEvaluator<MyTraits::Residual>(b); } { auto plist_c = Teuchos::parameterList("C"); RCP<Ev2> c = rcp(new Ev2(*plist_c)); c->setName("Eval_C"); c->evaluates("C"); c->requires("D"); fm.registerEvaluator<MyTraits::Residual>(c); } { auto plist_d = Teuchos::parameterList("D"); RCP<Ev1> d = rcp(new Ev1(*plist_d)); d->setName("Eval_D"); d->evaluates("D"); fm.registerEvaluator<MyTraits::Residual>(d); } RCP<PHX::MDALayout<CELL,BASIS>> dl = rcp(new PHX::MDALayout<CELL,BASIS>("H-Grad",100,4)); PHX::Tag<MyTraits::Residual::ScalarT> tag("A",dl); fm.requireField<MyTraits::Residual>(tag); fm.postRegistrationSetup(0); fm.preEvaluate<MyTraits::Residual>(1); fm.evaluateFields<MyTraits::Residual>(1); fm.postEvaluate<MyTraits::Residual>(1); }
IRResultType CBS :: initializeFrom(InputRecord *ir) { IRResultType result; // Required by IR_GIVE_FIELD macro int val = 0; IR_GIVE_OPTIONAL_FIELD(ir, val, _IFT_EngngModel_lstype); solverType = ( LinSystSolverType ) val; val = 0; IR_GIVE_OPTIONAL_FIELD(ir, val, _IFT_EngngModel_smtype); sparseMtrxType = ( SparseMtrxType ) val; IR_GIVE_FIELD(ir, deltaT, _IFT_CBS_deltat); minDeltaT = 0.; IR_GIVE_OPTIONAL_FIELD(ir, minDeltaT, _IFT_CBS_mindeltat); IR_GIVE_OPTIONAL_FIELD(ir, consistentMassFlag, _IFT_CBS_cmflag); theta1 = theta2 = 1.0; IR_GIVE_OPTIONAL_FIELD(ir, theta1, _IFT_CBS_theta1); IR_GIVE_OPTIONAL_FIELD(ir, theta2, _IFT_CBS_theta2); val = 0; IR_GIVE_OPTIONAL_FIELD(ir, val, _IFT_CBS_scaleflag); equationScalingFlag = val > 0; if ( equationScalingFlag ) { IR_GIVE_FIELD(ir, lscale, _IFT_CBS_lscale); IR_GIVE_FIELD(ir, uscale, _IFT_CBS_uscale); IR_GIVE_FIELD(ir, dscale, _IFT_CBS_dscale); double vref = 1.0; // reference viscosity Re = dscale * uscale * lscale / vref; } else { lscale = uscale = dscale = 1.0; Re = 1.0; } //<RESTRICTED_SECTION> val = 0; IR_GIVE_OPTIONAL_FIELD(ir, val, _IFT_CBS_miflag); if ( val ) { this->materialInterface.reset( new LEPlic( 1, this->giveDomain(1) ) ); // export velocity field FieldManager *fm = this->giveContext()->giveFieldManager(); IntArray mask = {V_u, V_v, V_w}; //std::shared_ptr<Field> _velocityField = make_shared<MaskedPrimaryField>(FT_Velocity, &this->VelocityField, mask); std :: shared_ptr< Field > _velocityField( new MaskedPrimaryField ( FT_Velocity, &this->VelocityField, mask ) ); fm->registerField(_velocityField, FT_Velocity); } //</RESTRICTED_SECTION> return EngngModel :: initializeFrom(ir); }
IRResultType StationaryTransportProblem :: initializeFrom(InputRecord *ir) { const char *__proc = "initializeFrom"; // Required by IR_GIVE_FIELD macro IRResultType result; // Required by IR_GIVE_FIELD macro EngngModel :: initializeFrom(ir); int val = SMT_Skyline; IR_GIVE_OPTIONAL_FIELD(ir, val, _IFT_EngngModel_smtype); this->sparseMtrxType = ( SparseMtrxType ) val; ///@todo Combine this option with structural problems, where it is possible to keep the secant tangent elastic tangent (or generally, the initial tangent) etc. One option should fit all common needs here. this->keepTangent = ir->hasField(_IFT_StationaryTransportProblem_keepTangent); // read field export flag IntArray exportFields; exportFields.resize(0); IR_GIVE_OPTIONAL_FIELD(ir, exportFields, _IFT_StationaryTransportProblem_exportfields); if ( exportFields.giveSize() ) { IntArray mask(1); FieldManager *fm = this->giveContext()->giveFieldManager(); for ( int i = 1; i <= exportFields.giveSize(); i++ ) { if ( exportFields.at(i) == FT_Temperature ) { mask.at(1) = T_f; #ifdef FIELDMANAGER_USE_SHARED_PTR //std::tr1::shared_ptr<Field> _temperatureField = make_shared<MaskedPrimaryField>(FT_Temperature, this->UnknownsField, mask); std::tr1::shared_ptr<Field> _temperatureField (new MaskedPrimaryField(FT_Temperature, this->UnknownsField, mask)); fm->registerField(_temperatureField, ( FieldType ) exportFields.at(i)); #else MaskedPrimaryField *_temperatureField = new MaskedPrimaryField(FT_Temperature, this->UnknownsField, mask); fm->registerField(_temperatureField, ( FieldType ) exportFields.at(i), true); #endif } else if ( exportFields.at(i) == FT_HumidityConcentration ) { mask.at(1) = C_1; #ifdef FIELDMANAGER_USE_SHARED_PTR //std::tr1::shared_ptr<Field> _temperatureField = make_shared<MaskedPrimaryField>(FT_Temperature, this->UnknownsField, mask); std::tr1::shared_ptr<Field> _concentrationField (new MaskedPrimaryField(FT_HumidityConcentration, this->UnknownsField, mask)); fm->registerField(_concentrationField, ( FieldType ) exportFields.at(i)); #else MaskedPrimaryField *_concentrationField = new MaskedPrimaryField(FT_HumidityConcentration, this->UnknownsField, mask); fm->registerField(_concentrationField, ( FieldType ) exportFields.at(i), true); #endif } } } if( UnknownsField == NULL ){ // can exist from nonstationary transport problem UnknownsField = new PrimaryField(this, 1, FT_TransportProblemUnknowns, EID_ConservationEquation, 0); } return IRRT_OK; }
double Filler::get_size(double x,double y,double z,GEntity* ge){ double h; Field* field; FieldManager* manager; h = 1.0; manager = ge->model()->getFields(); if(manager->getBackgroundField()>0){ field = manager->get(manager->getBackgroundField()); if(field){ h = (*field)(x,y,z,ge); } } return h; }
IRResultType TransientTransportProblem :: initializeFrom(InputRecord *ir) { IRResultType result; // Required by IR_GIVE_FIELD macro int val = SMT_Skyline; IR_GIVE_OPTIONAL_FIELD(ir, val, _IFT_EngngModel_smtype); this->sparseMtrxType = ( SparseMtrxType ) val; IR_GIVE_FIELD(ir, this->alpha, _IFT_TransientTransportProblem_alpha); prescribedTimes.clear(); dtFunction = 0; if ( ir->hasField(_IFT_TransientTransportProblem_dtFunction) ) { IR_GIVE_FIELD(ir, this->dtFunction, _IFT_TransientTransportProblem_dtFunction); } else if ( ir->hasField(_IFT_TransientTransportProblem_prescribedTimes) ) { IR_GIVE_FIELD(ir, this->prescribedTimes, _IFT_TransientTransportProblem_prescribedTimes); } else { IR_GIVE_FIELD(ir, this->deltaT, _IFT_TransientTransportProblem_deltaT); } this->keepTangent = ir->hasField(_IFT_TransientTransportProblem_keepTangent); this->lumped = ir->hasField(_IFT_TransientTransportProblem_lumped); field.reset( new DofDistributedPrimaryField(this, 1, FT_TransportProblemUnknowns, 0) ); // read field export flag exportFields.clear(); IR_GIVE_OPTIONAL_FIELD(ir, exportFields, _IFT_TransientTransportProblem_exportFields); if ( exportFields.giveSize() ) { FieldManager *fm = this->giveContext()->giveFieldManager(); for ( int i = 1; i <= exportFields.giveSize(); i++ ) { if ( exportFields.at(i) == FT_Temperature ) { FM_FieldPtr _temperatureField( new MaskedPrimaryField ( ( FieldType ) exportFields.at(i), this->field.get(), {T_f} ) ); fm->registerField( _temperatureField, ( FieldType ) exportFields.at(i) ); } else if ( exportFields.at(i) == FT_HumidityConcentration ) { FM_FieldPtr _concentrationField( new MaskedPrimaryField ( ( FieldType ) exportFields.at(i), this->field.get(), {C_1} ) ); fm->registerField( _concentrationField, ( FieldType ) exportFields.at(i) ); } } } return EngngModel :: initializeFrom(ir); }
// anisotropic version of the background field SMetric3 BGM_MeshMetric(GEntity *ge, double U, double V, double X, double Y, double Z) { // Metrics based on element size // Element size = min. between default lc and lc from point (if applicable), // constrained by lcMin and lcMax double lc = CTX::instance()->lc; if(CTX::instance()->mesh.lcFromPoints && ge->dim() < 2) lc = std::min(lc, LC_MVertex_PNTS(ge, U, V)); lc = std::min(lc, ge->getMeshSize()); lc = std::max(lc, CTX::instance()->mesh.lcMin); lc = std::min(lc, CTX::instance()->mesh.lcMax); if(lc <= 0.){ Msg::Error("Wrong mesh element size lc = %g (lcmin = %g, lcmax = %g)", lc, CTX::instance()->mesh.lcMin, CTX::instance()->mesh.lcMax); lc = CTX::instance()->lc; } SMetric3 m0(1./(lc*lc)); // Intersect with metrics from fields if applicable FieldManager *fields = ge->model()->getFields(); SMetric3 m1 = m0; if(fields->getBackgroundField() > 0){ Field *f = fields->get(fields->getBackgroundField()); if(f) { SMetric3 l4; if (!f->isotropic()) (*f)(X, Y, Z, l4, ge); else { const double L = (*f)(X, Y, Z, ge); l4 = SMetric3(1/(L*L)); } m1 = intersection(l4, m0); } } // Intersect with metrics from curvature if applicable SMetric3 m = (CTX::instance()->mesh.lcFromCurvature && ge->dim() < 3) ? intersection(m1, LC_MVertex_CURV_ANISO(ge, U, V)) : m1; return m; }
// This is the only function that is used by the meshers double BGM_MeshSize(GEntity *ge, double U, double V, double X, double Y, double Z) { // default lc (mesh size == size of the model) double l1 = CTX::instance()->lc; // lc from points double l2 = MAX_LC; if(CTX::instance()->mesh.lcFromPoints && ge->dim() < 2) l2 = LC_MVertex_PNTS(ge, U, V); // lc from curvature double l3 = MAX_LC; if(CTX::instance()->mesh.lcFromCurvature && ge->dim() < 3) l3 = LC_MVertex_CURV(ge, U, V); // lc from fields double l4 = MAX_LC; FieldManager *fields = ge->model()->getFields(); if(fields->getBackgroundField() > 0){ Field *f = fields->get(fields->getBackgroundField()); if(f) l4 = (*f)(X, Y, Z, ge); } // global lc from entity double l5 = ge->getMeshSize(); // take the minimum, then constrain by lcMin and lcMax double lc = std::min(std::min(std::min(std::min(l1, l2), l3), l4), l5); lc = std::max(lc, CTX::instance()->mesh.lcMin); lc = std::min(lc, CTX::instance()->mesh.lcMax); if(lc <= 0.){ Msg::Error("Wrong mesh element size lc = %g (lcmin = %g, lcmax = %g)", lc, CTX::instance()->mesh.lcMin, CTX::instance()->mesh.lcMax); lc = l1; } return lc * CTX::instance()->mesh.lcFactor; }
static double F_Lc_aniso(GEdge *ge, double t) { #if defined(HAVE_ANN) FieldManager *fields = ge->model()->getFields(); BoundaryLayerField *blf = 0; Field *bl_field = fields->get(fields->getBoundaryLayerField()); blf = dynamic_cast<BoundaryLayerField*> (bl_field); #else bool blf = false; #endif GPoint p = ge->point(t); SMetric3 lc_here; Range<double> bounds = ge->parBounds(0); double t_begin = bounds.low(); double t_end = bounds.high(); if(t == t_begin) lc_here = BGM_MeshMetric(ge->getBeginVertex(), t, 0, p.x(), p.y(), p.z()); else if(t == t_end) lc_here = BGM_MeshMetric(ge->getEndVertex(), t, 0, p.x(), p.y(), p.z()); else lc_here = BGM_MeshMetric(ge, t, 0, p.x(), p.y(), p.z()); #if defined(HAVE_ANN) if (blf && !blf->isEdgeBL(ge->tag())){ SMetric3 lc_bgm; blf->computeFor1dMesh ( p.x(), p.y(), p.z() , lc_bgm ); lc_here = intersection_conserveM1 (lc_here, lc_bgm ); } #endif SVector3 der = ge->firstDer(t); double lSquared = dot(der, lc_here, der); return sqrt(lSquared); }
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int main(int argc, char *argv[]) { using namespace std; using namespace Teuchos; using namespace PHX; GlobalMPISession mpi_session(&argc, &argv); try { PHX::InitializeKokkosDevice(); RCP<Time> total_time = TimeMonitor::getNewTimer("Total Run Time"); TimeMonitor tm(*total_time); bool print_debug_info = false; { cout << "\nStarting MultiDimensionalArray EnergyFlux Example!" << endl; // Assume we have 102 cells on processor and can fit 20 cells in cache typedef PHX::Device::size_type size_type; const size_type num_local_cells = 102; const size_type workset_size = 20; RCP<DataLayout> qp_scalar = rcp(new MDALayout<Cell,Node>(workset_size,4)); RCP<DataLayout> node_scalar = rcp(new MDALayout<Cell,QuadPoint>(workset_size,4)); RCP<DataLayout> qp_vec = rcp(new MDALayout<Cell,Node,Dim>(workset_size,4,3)); RCP<DataLayout> node_vec = rcp(new MDALayout<Cell,QuadPoint,Dim>(workset_size,4,3)); RCP<DataLayout> qp_mat = rcp(new MDALayout<Cell,Node,Dim,Dim>(workset_size,4,3,3)); RCP<DataLayout> node_mat = rcp(new MDALayout<Cell,QuadPoint,Dim,Dim>(workset_size,4,3,3)); // Parser will build parameter list that determines the field // evaluators to build map<string, RCP<ParameterList> > evaluators_to_build; { // Temperature RCP<ParameterList> p = rcp(new ParameterList); int type = MyFactoryTraits<MyTraits>::id_constant; p->set<int>("Type", type); p->set<string>("Name", "Temperature"); p->set<double>("Value", 2.0); p->set< RCP<DataLayout> >("Data Layout", node_scalar); evaluators_to_build["DOF_Temperature"] = p; } { // Density RCP<ParameterList> p = rcp(new ParameterList); int type = MyFactoryTraits<MyTraits>::id_density; p->set<int>("Type", type); p->set< RCP<DataLayout> >("Data Layout", qp_scalar); evaluators_to_build["Density"] = p; } { // Constant Thermal Conductivity RCP<ParameterList> p = rcp(new ParameterList); int type = MyFactoryTraits<MyTraits>::id_constant; p->set<int>("Type", type); p->set<string>("Name", "Thermal Conductivity"); p->set<double>("Value", 2.0); p->set< RCP<DataLayout> >("Data Layout", qp_scalar); evaluators_to_build["Thermal Conductivity"] = p; } { // Nonlinear Source RCP<ParameterList> p = rcp(new ParameterList); int type = MyFactoryTraits<MyTraits>::id_nonlinearsource; p->set<int>("Type", type); p->set< RCP<DataLayout> >("Data Layout", qp_scalar); evaluators_to_build["Nonlinear Source"] = p; } { // Fourier Energy Flux RCP<ParameterList> p = rcp(new ParameterList); int type = MyFactoryTraits<MyTraits>::id_fourier; p->set<int>("Type", type); p->set< RCP<DataLayout> >("Scalar Data Layout", qp_scalar); p->set< RCP<DataLayout> >("Vector Data Layout", qp_vec); evaluators_to_build["Energy Flux"] = p; } { // FE Interpolation RCP<ParameterList> p = rcp(new ParameterList); int type = MyFactoryTraits<MyTraits>::id_feinterpolation; p->set<int>("Type", type); p->set<string>("Node Variable Name", "Temperature"); p->set<string>("QP Variable Name", "Temperature"); p->set<string>("Gradient QP Variable Name", "Temperature Gradient"); p->set< RCP<DataLayout> >("Node Data Layout", node_scalar); p->set< RCP<DataLayout> >("QP Scalar Data Layout", qp_scalar); p->set< RCP<DataLayout> >("QP Vector Data Layout", qp_vec); evaluators_to_build["FE Interpolation"] = p; } // Build Field Evaluators for each evaluation type EvaluatorFactory<MyTraits,MyFactoryTraits<MyTraits> > factory; RCP< vector< RCP<Evaluator_TemplateManager<MyTraits> > > > evaluators; evaluators = factory.buildEvaluators(evaluators_to_build); // Create a FieldManager FieldManager<MyTraits> fm; // Register all Evaluators registerEvaluators(evaluators, fm); // Request quantities to assemble RESIDUAL PDE operators typedef MyTraits::Residual::ScalarT ResScalarT; Tag<ResScalarT> energy_flux_tag("Energy_Flux", qp_vec); fm.requireField<MyTraits::Residual>(energy_flux_tag); Tag<ResScalarT> source_tag("Nonlinear Source", qp_scalar); fm.requireField<MyTraits::Residual>(source_tag); // Request quantities to assemble JACOBIAN PDE operators typedef MyTraits::Jacobian::ScalarT JacScalarT; Tag<JacScalarT> j_energy_flux_tag("Energy_Flux", qp_vec); fm.requireField<MyTraits::Jacobian>(j_energy_flux_tag); Tag<JacScalarT> j_source_tag("Nonlinear Source", qp_scalar); fm.requireField<MyTraits::Jacobian>(j_source_tag); // For Kokkos extended types (Sacado FAD) set derivtive array // size std::vector<PHX::index_size_type> derivative_dimensions; derivative_dimensions.push_back(8); fm.setKokkosExtendedDataTypeDimensions<MyTraits::Jacobian>(derivative_dimensions); RCP<Time> registration_time = TimeMonitor::getNewTimer("Post Registration Setup Time"); { TimeMonitor t(*registration_time); fm.postRegistrationSetup(NULL); } cout << fm << endl; fm.writeGraphvizFile<MyTraits::Residual>("graph_residual.dot"); fm.writeGraphvizFile<MyTraits::Jacobian>("graph_jacobian.dot"); fm.writeGraphvizFile("all_graph", ".dot"); // Create Workset information: Cells and EvalData objects std::vector<MyCell> cells(num_local_cells); for (std::size_t i = 0; i < cells.size(); ++i) cells[i].setLocalIndex(i); std::vector<MyWorkset> worksets; std::vector<MyCell>::iterator cell_it = cells.begin(); std::size_t count = 0; MyWorkset w; w.local_offset = cell_it->localIndex(); w.begin = cell_it; for (; cell_it != cells.end(); ++cell_it) { ++count; std::vector<MyCell>::iterator next = cell_it; ++next; if ( count == workset_size || next == cells.end()) { w.end = next; w.num_cells = count; worksets.push_back(w); count = 0; if (next != cells.end()) { w.local_offset = next->localIndex(); w.begin = next; } } } if (print_debug_info) { for (std::size_t i = 0; i < worksets.size(); ++i) { cout << "worksets[" << i << "]" << endl; cout << " num_cells =" << worksets[i].num_cells << endl; cout << " local_offset =" << worksets[i].local_offset << endl; std::vector<MyCell>::iterator it = worksets[i].begin; for (; it != worksets[i].end; ++it) cout << " cell_local_index =" << it->localIndex() << endl; } cout << endl; } // Create local vectors to hold flux and source at quad points std::vector<double> local_energy_flux_at_qp(num_local_cells * qp_vec->size()); std::vector<double> local_source_at_qp(num_local_cells * qp_scalar->size()); // Fields we require MDField<double,Cell,QuadPoint,Dim> energy_flux(energy_flux_tag); MDField<double,Cell,QuadPoint> source(source_tag); fm.getFieldData<double,MyTraits::Residual,Cell,QuadPoint,Dim>(energy_flux); fm.getFieldData<double,MyTraits::Residual,Cell,QuadPoint>(source); // Get host arrays to copy from device back to host auto host_energy_flux = Kokkos::create_mirror_view(energy_flux.get_kokkos_view()); auto host_source = Kokkos::create_mirror_view(source.get_kokkos_view()); RCP<Time> eval_time = TimeMonitor::getNewTimer("Evaluation Time"); fm.preEvaluate<MyTraits::Residual>(NULL); { TimeMonitor t(*eval_time); for (std::size_t i = 0; i < worksets.size(); ++i) { #ifdef PHX_ENABLE_KOKKOS_AMT fm.evaluateFieldsTaskParallel<MyTraits::Residual>(1,worksets[i]); #else fm.evaluateFields<MyTraits::Residual>(worksets[i]); #endif // Use values: in this example, move values into local host arrays Kokkos::deep_copy(host_energy_flux,energy_flux.get_kokkos_view()); Kokkos::deep_copy(host_source,source.get_kokkos_view()); for (size_type cell = 0; cell < energy_flux.dimension(0); ++cell) { for (size_type ip = 0; ip < energy_flux.dimension(1); ++ip) { for (size_type dim = 0; dim < energy_flux.dimension(2); ++dim) { std::size_t index = cell * energy_flux.dimension(0) + ip * energy_flux.dimension(1) + dim; local_energy_flux_at_qp[index] = host_energy_flux(cell,ip,dim); } } } for (size_type cell = 0; cell < energy_flux.dimension(0); ++cell) { for (size_type ip = 0; ip < energy_flux.dimension(1); ++ip) { std::size_t index = cell * energy_flux.dimension(0) + ip; local_source_at_qp[index] = host_source(cell,ip); } } } } fm.postEvaluate<MyTraits::Residual>(NULL); // Test data retrieval cout << "Testing data members" << endl; Tag<double> d_var("Density", qp_scalar); MDField<double> den(d_var); fm.getFieldData<double,MyTraits::Residual>(den); cout << "size of density = " << den.size() << ", should be " << d_var.dataLayout().size() << "." << endl; TEUCHOS_TEST_FOR_EXCEPTION(den.size() != d_var.dataLayout().size(), std::runtime_error, "Returned arrays are not sized correctly!"); cout << endl; //Jacobian: std::vector<JacScalarT> j_local_energy_flux_at_qp(num_local_cells * qp_vec->size()); std::vector<JacScalarT> j_local_source_at_qp(num_local_cells * qp_scalar->size()); // Fields we require MDField<JacScalarT,Cell,QuadPoint,Dim> j_energy_flux(j_energy_flux_tag); MDField<JacScalarT,Cell,QuadPoint> j_source(j_source_tag); fm.getFieldData<JacScalarT,MyTraits::Jacobian,Cell,QuadPoint,Dim>(j_energy_flux); fm.getFieldData<JacScalarT,MyTraits::Jacobian,Cell,QuadPoint>(j_source); RCP<Time> eval_time2 = TimeMonitor::getNewTimer("Evaluation Time Jacobian"); auto host_j_energy_flux = Kokkos::create_mirror_view(j_energy_flux.get_kokkos_view()); auto host_j_source = Kokkos::create_mirror_view(j_source.get_kokkos_view()); fm.preEvaluate<MyTraits::Jacobian>(NULL); { TimeMonitor t(*eval_time2); for (std::size_t i = 0; i < worksets.size(); ++i) { #ifdef PHX_ENABLE_KOKKOS_AMT fm.evaluateFieldsTaskParallel<MyTraits::Jacobian>(1,worksets[i]); #else fm.evaluateFields<MyTraits::Jacobian>(worksets[i]); #endif Kokkos::deep_copy(host_j_energy_flux,j_energy_flux.get_kokkos_view()); Kokkos::deep_copy(host_j_source,j_source.get_kokkos_view()); for (size_type cell = 0; cell < j_energy_flux.dimension(0); ++cell) { for (size_type ip = 0; ip < j_energy_flux.dimension(1); ++ip) { for (size_type dim = 0; dim < j_energy_flux.dimension(2); ++dim) { std::size_t index = cell * j_energy_flux.dimension(0) + ip * j_energy_flux.dimension(1) + dim; j_local_energy_flux_at_qp[index] = host_j_energy_flux(cell,ip,dim); } } } for (size_type cell = 0; cell < j_energy_flux.dimension(0); ++cell) { for (size_type ip = 0; ip < j_energy_flux.dimension(1); ++ip) { std::size_t index = cell * j_energy_flux.dimension(0) + ip; j_local_source_at_qp[index] = host_j_source(cell,ip); } } } } fm.postEvaluate<MyTraits::Jacobian>(NULL); double scalability = 0.0; double parallelizability = 1.0; fm.analyzeGraph<MyTraits::Residual>(scalability,parallelizability); std::cout << "Residual Scalability = " << scalability << std::endl; std::cout << "Residual Parallelizability = " << parallelizability << std::endl; fm.analyzeGraph<MyTraits::Jacobian>(scalability,parallelizability); std::cout << "Residual Scalability = " << scalability << std::endl; std::cout << "Residual Parallelizability = " << parallelizability << std::endl; } // ********************************************************************* // Finished all testing // ********************************************************************* std::cout << "\nRun has completed successfully!\n" << std::endl; // ********************************************************************* // ********************************************************************* PHX::FinalizeKokkosDevice(); } catch (const std::exception& e) { std::cout << "************************************************" << endl; std::cout << "************************************************" << endl; std::cout << "Exception Caught!" << endl; std::cout << "Error message is below\n " << e.what() << endl; std::cout << "************************************************" << endl; } catch (...) { std::cout << "************************************************" << endl; std::cout << "************************************************" << endl; std::cout << "Unknown Exception Caught!" << endl; std::cout << "************************************************" << endl; } TimeMonitor::summarize(); return 0; }
bool frameFieldBackgroundMesh2D::compute_RK_infos(double u,double v, double x, double y, double z, RK_form &infos) { // check if point is in domain if (!inDomain(u,v)) return false; // get stored angle double angle_current = angle(u,v); // compute t1,t2: cross field directions // get the unit normal at that point GFace *face = dynamic_cast<GFace*>(gf); if(!face) { Msg::Error("Entity is not a face in background mesh"); return false; } Pair<SVector3, SVector3> der = face->firstDer(SPoint2(u,v)); SVector3 s1 = der.first(); SVector3 s2 = der.second(); SVector3 n = crossprod(s1,s2); n.normalize(); SVector3 basis_u = s1; basis_u.normalize(); SVector3 basis_v = crossprod(n,basis_u); // normalize vector t1 that is tangent to gf at uv SVector3 t1 = basis_u * cos(angle_current) + basis_v * sin(angle_current) ; t1.normalize(); // compute the second direction t2 and normalize (t1,t2,n) is the tangent frame SVector3 t2 = crossprod(n,t1); t2.normalize(); // get metric double L = size(u,v); infos.metricField = SMetric3(1./(L*L)); FieldManager *fields = gf->model()->getFields(); if(fields->getBackgroundField() > 0) { Field *f = fields->get(fields->getBackgroundField()); if (!f->isotropic()) { (*f)(x,y,z, infos.metricField,gf); } else { L = (*f)(x,y,z,gf); infos.metricField = SMetric3(1./(L*L)); } } double M = dot(s1,s1); double N = dot(s2,s2); double E = dot(s1,s2); // compute the first fundamental form i.e. the metric tensor at the point // M_{ij} = s_i \cdot s_j double metric[2][2] = {{M,E},{E,N}}; // get sizes double size_1 = sqrt(1. / dot(t1,infos.metricField,t1)); double size_2 = sqrt(1. / dot(t2,infos.metricField,t2)); // compute covariant coordinates of t1 and t2 - cross field directions in parametric domain double covar1[2],covar2[2]; // t1 = a s1 + b s2 --> // t1 . s1 = a M + b E // t1 . s2 = a E + b N --> solve the 2 x 2 system // and get covariant coordinates a and b double rhs1[2] = {dot(t1,s1),dot(t1,s2)}; bool singular = false; if (!sys2x2(metric,rhs1,covar1)) { Msg::Info("Argh surface %d %g %g %g -- %g %g %g -- %g %g",gf->tag(),s1.x(),s1.y(),s1.z(),s2.x(),s2.y(),s2.z(),size_1,size_2); covar1[1] = 1.0; covar1[0] = 0.0; singular = true; } double rhs2[2] = {dot(t2,s1),dot(t2,s2)}; if (!sys2x2(metric,rhs2,covar2)) { Msg::Info("Argh surface %d %g %g %g -- %g %g %g",gf->tag(),s1.x(),s1.y(),s1.z(),s2.x(),s2.y(),s2.z()); covar2[0] = 1.0; covar2[1] = 0.0; singular = true; } // transform the sizes with respect to the metric // consider a vector v of size 1 in the parameter plane // its length is sqrt (v^T M v) --> if I want a real size // of size1 in direction v, it should be sqrt(v^T M v) * size1 double l1 = sqrt(covar1[0]*covar1[0]+covar1[1]*covar1[1]); double l2 = sqrt(covar2[0]*covar2[0]+covar2[1]*covar2[1]); covar1[0] /= l1; covar1[1] /= l1; covar2[0] /= l2; covar2[1] /= l2; double size_param_1 = size_1 / sqrt ( M*covar1[0]*covar1[0]+ 2*E*covar1[1]*covar1[0]+ N*covar1[1]*covar1[1]); double size_param_2 = size_2 / sqrt ( M*covar2[0]*covar2[0]+ 2*E*covar2[1]*covar2[0]+ N*covar2[1]*covar2[1]); if (singular) { size_param_1 = size_param_2 = std::min (size_param_1,size_param_2); } // filling form... infos.t1 = t1; infos.h.first = size_1; infos.h.second = size_2; infos.paramh.first = size_param_1; infos.paramh.second = size_param_2; infos.paramt1 = SPoint2(covar1[0],covar1[1]); infos.paramt2 = SPoint2(covar2[0],covar2[1]); infos.angle = angle_current; infos.localsize = L; infos.normal = n; return true; }
void meshGEdge::operator() (GEdge *ge) { #if defined(HAVE_ANN) FieldManager *fields = ge->model()->getFields(); BoundaryLayerField *blf = 0; Field *bl_field = fields->get(fields->getBoundaryLayerField()); blf = dynamic_cast<BoundaryLayerField*> (bl_field); #else bool blf = false; #endif ge->model()->setCurrentMeshEntity(ge); if(ge->geomType() == GEntity::DiscreteCurve) return; if(ge->geomType() == GEntity::BoundaryLayerCurve) return; if(ge->meshAttributes.method == MESH_NONE) return; if(CTX::instance()->mesh.meshOnlyVisible && !ge->getVisibility()) return; // look if we are doing the STL triangulation std::vector<MVertex*> &mesh_vertices = ge->mesh_vertices ; std::vector<MLine*> &lines = ge->lines ; deMeshGEdge dem; dem(ge); if(MeshExtrudedCurve(ge)) return; if (ge->meshMaster() != ge){ GEdge *gef = dynamic_cast<GEdge*> (ge->meshMaster()); if (gef->meshStatistics.status == GEdge::PENDING) return; Msg::Info("Meshing curve %d (%s) as a copy of %d", ge->tag(), ge->getTypeString().c_str(), ge->meshMaster()->tag()); copyMesh(gef, ge, ge->masterOrientation); ge->meshStatistics.status = GEdge::DONE; return; } Msg::Info("Meshing curve %d (%s)", ge->tag(), ge->getTypeString().c_str()); // compute bounds Range<double> bounds = ge->parBounds(0); double t_begin = bounds.low(); double t_end = bounds.high(); // first compute the length of the curve by integrating one double length; std::vector<IntPoint> Points; if(ge->geomType() == GEntity::Line && ge->getBeginVertex() == ge->getEndVertex() && //do not consider closed lines as degenerated (ge->position(0.5) - ge->getBeginVertex()->xyz()).norm() < CTX::instance()->geom.tolerance) length = 0.; // special case t avoid infinite loop in integration else length = Integration(ge, t_begin, t_end, F_One, Points, 1.e-8 * CTX::instance()->lc); ge->setLength(length); Points.clear(); if(length < CTX::instance()->mesh.toleranceEdgeLength){ ge->setTooSmall(true); } // Integrate detJ/lc du double a; int N; if(length == 0. && CTX::instance()->mesh.toleranceEdgeLength == 0.){ Msg::Warning("Curve %d has a zero length", ge->tag()); a = 0.; N = 1; } else if(ge->degenerate(0)){ a = 0.; N = 1; } else if(ge->meshAttributes.method == MESH_TRANSFINITE){ a = Integration(ge, t_begin, t_end, F_Transfinite, Points, CTX::instance()->mesh.lcIntegrationPrecision); N = ge->meshAttributes.nbPointsTransfinite; if(CTX::instance()->mesh.flexibleTransfinite && CTX::instance()->mesh.lcFactor) N /= CTX::instance()->mesh.lcFactor; } else{ if (CTX::instance()->mesh.algo2d == ALGO_2D_BAMG || blf){ a = Integration(ge, t_begin, t_end, F_Lc_aniso, Points, CTX::instance()->mesh.lcIntegrationPrecision); } else{ a = Integration(ge, t_begin, t_end, F_Lc, Points, CTX::instance()->mesh.lcIntegrationPrecision); } // we should maybe provide an option to disable the smoothing for (unsigned int i = 0; i < Points.size(); i++){ IntPoint &pt = Points[i]; SVector3 der = ge->firstDer(pt.t); pt.xp = der.norm(); } a = smoothPrimitive(ge, sqrt(CTX::instance()->mesh.smoothRatio), Points); N = std::max(ge->minimumMeshSegments() + 1, (int)(a + 1.99)); } // force odd number of points if blossom is used for recombination if((ge->meshAttributes.method != MESH_TRANSFINITE || CTX::instance()->mesh.flexibleTransfinite) && CTX::instance()->mesh.algoRecombine != 0){ if(CTX::instance()->mesh.recombineAll){ if (N % 2 == 0) N++; if (CTX::instance()->mesh.algoRecombine == 2) N = increaseN(N); } else{ std::list<GFace*> faces = ge->faces(); for(std::list<GFace*>::iterator it = faces.begin(); it != faces.end(); it++){ if((*it)->meshAttributes.recombine){ if (N % 2 == 0) N ++; if (CTX::instance()->mesh.algoRecombine == 2) N = increaseN(N); break; } } } } // printFandPrimitive(ge->tag(),Points); // if the curve is periodic and if the begin vertex is identical to // the end vertex and if this vertex has only one model curve // adjacent to it, then the vertex is not connecting any other // curve. So, the mesh vertex and its associated geom vertex are not // necessary at the same location GPoint beg_p, end_p; if(ge->getBeginVertex() == ge->getEndVertex() && ge->getBeginVertex()->edges().size() == 1){ end_p = beg_p = ge->point(t_begin); Msg::Debug("Meshing periodic closed curve"); } else{ MVertex *v0 = ge->getBeginVertex()->mesh_vertices[0]; MVertex *v1 = ge->getEndVertex()->mesh_vertices[0]; beg_p = GPoint(v0->x(), v0->y(), v0->z()); end_p = GPoint(v1->x(), v1->y(), v1->z()); } // do not consider the first and the last vertex (those are not // classified on this mesh edge) if(N > 1){ const double b = a / (double)(N - 1); int count = 1, NUMP = 1; IntPoint P1, P2; mesh_vertices.resize(N - 2); while(NUMP < N - 1) { P1 = Points[count - 1]; P2 = Points[count]; const double d = (double)NUMP * b; if((fabs(P2.p) >= fabs(d)) && (fabs(P1.p) < fabs(d))) { double dt = P2.t - P1.t; double dlc = P2.lc - P1.lc; double dp = P2.p - P1.p; double t = P1.t + dt / dp * (d - P1.p); SVector3 der = ge->firstDer(t); const double d = norm(der); double lc = d/(P1.lc + dlc / dp * (d - P1.p)); GPoint V = ge->point(t); mesh_vertices[NUMP - 1] = new MEdgeVertex(V.x(), V.y(), V.z(), ge, t, lc); NUMP++; } else { count++; } } mesh_vertices.resize(NUMP - 1); } for(unsigned int i = 0; i < mesh_vertices.size() + 1; i++){ MVertex *v0 = (i == 0) ? ge->getBeginVertex()->mesh_vertices[0] : mesh_vertices[i - 1]; MVertex *v1 = (i == mesh_vertices.size()) ? ge->getEndVertex()->mesh_vertices[0] : mesh_vertices[i]; lines.push_back(new MLine(v0, v1)); } if(ge->getBeginVertex() == ge->getEndVertex() && ge->getBeginVertex()->edges().size() == 1){ MVertex *v0 = ge->getBeginVertex()->mesh_vertices[0]; v0->x() = beg_p.x(); v0->y() = beg_p.y(); v0->z() = beg_p.z(); } ge->meshStatistics.status = GEdge::DONE; }
IRResultType SUPG :: initializeFrom(InputRecord *ir) { IRResultType result; // Required by IR_GIVE_FIELD macro result = FluidModel :: initializeFrom(ir); if ( result != IRRT_OK ) { return result; } IR_GIVE_FIELD(ir, rtolv, _IFT_SUPG_rtolv); atolv = 1.e-15; IR_GIVE_OPTIONAL_FIELD(ir, atolv, _IFT_SUPG_atolv); stopmaxiter = ir->hasField(_IFT_SUPG_stopmaxiter); maxiter = 200; IR_GIVE_OPTIONAL_FIELD(ir, maxiter, _IFT_SUPG_maxiter); int val = 0; IR_GIVE_OPTIONAL_FIELD(ir, val, _IFT_EngngModel_lstype); solverType = ( LinSystSolverType ) val; val = 0; IR_GIVE_OPTIONAL_FIELD(ir, val, _IFT_EngngModel_smtype); sparseMtrxType = ( SparseMtrxType ) val; IR_GIVE_FIELD(ir, deltaT, _IFT_SUPG_deltat); deltaTF = 0; IR_GIVE_OPTIONAL_FIELD(ir, deltaTF, _IFT_SUPG_deltatFunction); IR_GIVE_OPTIONAL_FIELD(ir, consistentMassFlag, _IFT_SUPG_cmflag); alpha = 0.5; IR_GIVE_OPTIONAL_FIELD(ir, alpha, _IFT_SUPG_alpha); val = 0; IR_GIVE_OPTIONAL_FIELD(ir, val, _IFT_SUPG_scaleflag); equationScalingFlag = val > 0; if ( equationScalingFlag ) { IR_GIVE_FIELD(ir, lscale, _IFT_SUPG_lscale); IR_GIVE_FIELD(ir, uscale, _IFT_SUPG_uscale); IR_GIVE_FIELD(ir, dscale, _IFT_SUPG_dscale); double vref = 1.0; // reference viscosity Re = dscale * uscale * lscale / vref; } else { lscale = uscale = dscale = 1.0; Re = 1.0; } if ( requiresUnknownsDictionaryUpdate() ) { VelocityPressureField.reset( new DofDistributedPrimaryField(this, 1, FT_VelocityPressure, 1) ); } else { VelocityPressureField.reset( new PrimaryField(this, 1, FT_VelocityPressure, 1) ); } val = 0; IR_GIVE_OPTIONAL_FIELD(ir, val, _IFT_SUPG_miflag); if ( val == 1 ) { this->materialInterface.reset( new LEPlic( 1, this->giveDomain(1) ) ); this->materialInterface->initializeFrom(ir); // export velocity field FieldManager *fm = this->giveContext()->giveFieldManager(); IntArray mask; mask = {V_u, V_v, V_w}; std :: shared_ptr< Field > _velocityField( new MaskedPrimaryField ( FT_Velocity, this->VelocityPressureField.get(), mask ) ); fm->registerField(_velocityField, FT_Velocity); //fsflag = 0; //IR_GIVE_OPTIONAL_FIELD (ir, fsflag, _IFT_SUPG_fsflag, "fsflag"); } else if ( val == 2 ) { // positive coefficient scheme level set alg this->materialInterface.reset( new LevelSetPCS( 1, this->giveDomain(1) ) ); this->materialInterface->initializeFrom(ir); } return IRRT_OK; }
bool gmshFace::buildSTLTriangulation(bool force) { return false; if(va_geom_triangles){ if(force) delete va_geom_triangles; else return true; } stl_vertices.clear(); stl_triangles.clear(); #if defined(HAVE_MESH) if (!triangles.size()){ contextMeshOptions _temp = CTX::instance()->mesh; FieldManager *fields = model()->getFields(); int BGM = fields->getBackgroundField(); fields->setBackgroundField(0); CTX::instance()->mesh.lcFromPoints = 0; CTX::instance()->mesh.lcFromCurvature = 1; CTX::instance()->mesh.lcExtendFromBoundary = 0; CTX::instance()->mesh.scalingFactor = 1; CTX::instance()->mesh.lcFactor = 1; CTX::instance()->mesh.order = 1; CTX::instance()->mesh.lcIntegrationPrecision = 1.e-3; // CTX::instance()->mesh.Algorithm = 5; model()->mesh(2); CTX::instance()->mesh = _temp; fields->setBackgroundField(fields->get(BGM)); } #endif std::map<MVertex*,int> _v; int COUNT =0; for (unsigned int j = 0; j < triangles.size(); j++){ for (int i = 0; i < 3; i++){ std::map<MVertex*,int>::iterator it = _v.find(triangles[j]->getVertex(j)); if (it != _v.end()){ stl_triangles.push_back(COUNT); _v[triangles[j]->getVertex(j)] = COUNT++; } else stl_triangles.push_back(it->second); } } std::map<MVertex*,int>::iterator itv = _v.begin(); for ( ; itv != _v.end() ; ++itv){ MVertex *v = itv->first; SPoint2 param; reparamMeshVertexOnFace(v, this, param); stl_vertices.push_back(param); } va_geom_triangles = new VertexArray(3, stl_triangles.size() / 3); unsigned int c = CTX::instance()->color.geom.surface; unsigned int col[4] = {c, c, c, c}; for (unsigned int i = 0; i < stl_triangles.size(); i += 3){ SPoint2 &p1(stl_vertices[stl_triangles[i]]); SPoint2 &p2(stl_vertices[stl_triangles[i + 1]]); SPoint2 &p3(stl_vertices[stl_triangles[i + 2]]); GPoint gp1 = GFace::point(p1); GPoint gp2 = GFace::point(p2); GPoint gp3 = GFace::point(p3); double x[3] = {gp1.x(), gp2.x(), gp3.x()}; double y[3] = {gp1.y(), gp2.y(), gp3.y()}; double z[3] = {gp1.z(), gp2.z(), gp3.z()}; SVector3 n[3] = {normal(p1), normal(p2), normal(p3)}; va_geom_triangles->add(x, y, z, n, col); } va_geom_triangles->finalize(); return true; }