void TransientMultiApp::resetApp( unsigned int global_app, Real /*time*/) // FIXME: Note that we are passing in time but also grabbing it below { if (hasLocalApp(global_app)) { unsigned int local_app = globalAppToLocal(global_app); // Grab the current time the App is at so we can start the new one at the same place Real time = _transient_executioners[local_app]->getTime() + _apps[local_app]->getGlobalTimeOffset(); // Reset the Multiapp MultiApp::resetApp(global_app, time); Moose::ScopedCommSwapper swapper(_my_comm); // Setup the app, disable the output so that the initial condition does not output // When an app is reset the initial condition was effectively already output before reset FEProblemBase & problem = appProblemBase(local_app); problem.allowOutput(false); setupApp(local_app, time); problem.allowOutput(true); } }
Real TransientMultiApp::computeDT() { if (_sub_cycling) // Bow out of the timestep selection dance return std::numeric_limits<Real>::max(); Real smallest_dt = std::numeric_limits<Real>::max(); if (_has_an_app) { Moose::ScopedCommSwapper swapper(_my_comm); for (unsigned int i = 0; i < _my_num_apps; i++) { Transient * ex = _transient_executioners[i]; ex->computeDT(); Real dt = ex->getDT(); smallest_dt = std::min(dt, smallest_dt); } } if (_tolerate_failure) // Bow out of the timestep selection dance, we do this down here because we // need to call computeConstrainedDT at least once for these // executioners... return std::numeric_limits<Real>::max(); _communicator.min(smallest_dt); return smallest_dt; }
void DES::Cipher(int plainBlock[64],int RoundKeys[16][64],int cipherBlock[64]) { permute(64,64,plainBlock,inBlock,initialPermutationTable); split(64,32,inBlock,leftBlock,rightBlock); for(round=1;round<=16;++round) { mixer(leftBlock,rightBlock,RoundKeys); if(round!=16) swapper(leftBlock,rightBlock); } combine(32,64,leftBlock,rightBlock,outBlock); permute(64,64,outBlock,cipherBlock,finalPermutationTable); }
void TransientMultiApp::initialSetup() { MultiApp::initialSetup(); if (!_has_an_app) return; Moose::ScopedCommSwapper swapper(_my_comm); if (_has_an_app) { _transient_executioners.resize(_my_num_apps); // Grab Transient Executioners from each app for (unsigned int i = 0; i < _my_num_apps; i++) setupApp(i); } }
/* * System startup; initialize the world, create process 0, mount root * filesystem, and fork to create init and pagedaemon. Most of the * hard work is done in the lower-level initialization routines including * startup(), which does memory initialization and autoconfiguration. * * This allows simple addition of new kernel subsystems that require * boot time initialization. It also allows substitution of subsystem * (for instance, a scheduler, kernel profiler, or VM system) by object * module. Finally, it allows for optional "kernel threads". */ void mi_startup(void) { register struct sysinit **sipp; /* system initialization*/ register struct sysinit **xipp; /* interior loop of sort*/ register struct sysinit *save; /* bubble*/ #if defined(VERBOSE_SYSINIT) int last; int verbose; #endif if (boothowto & RB_VERBOSE) bootverbose++; if (sysinit == NULL) { sysinit = SET_BEGIN(sysinit_set); sysinit_end = SET_LIMIT(sysinit_set); } restart: /* * Perform a bubble sort of the system initialization objects by * their subsystem (primary key) and order (secondary key). */ for (sipp = sysinit; sipp < sysinit_end; sipp++) { for (xipp = sipp + 1; xipp < sysinit_end; xipp++) { if ((*sipp)->subsystem < (*xipp)->subsystem || ((*sipp)->subsystem == (*xipp)->subsystem && (*sipp)->order <= (*xipp)->order)) continue; /* skip*/ save = *sipp; *sipp = *xipp; *xipp = save; } } #if defined(VERBOSE_SYSINIT) last = SI_SUB_COPYRIGHT; verbose = 0; #if !defined(DDB) printf("VERBOSE_SYSINIT: DDB not enabled, symbol lookups disabled.\n"); #endif #endif /* * Traverse the (now) ordered list of system initialization tasks. * Perform each task, and continue on to the next task. */ for (sipp = sysinit; sipp < sysinit_end; sipp++) { if ((*sipp)->subsystem == SI_SUB_DUMMY) continue; /* skip dummy task(s)*/ if ((*sipp)->subsystem == SI_SUB_DONE) continue; #if defined(VERBOSE_SYSINIT) if ((*sipp)->subsystem > last) { verbose = 1; last = (*sipp)->subsystem; printf("subsystem %x\n", last); } if (verbose) { #if defined(DDB) const char *func, *data; func = symbol_name((vm_offset_t)(*sipp)->func, DB_STGY_PROC); data = symbol_name((vm_offset_t)(*sipp)->udata, DB_STGY_ANY); if (func != NULL && data != NULL) printf(" %s(&%s)... ", func, data); else if (func != NULL) printf(" %s(%p)... ", func, (*sipp)->udata); else #endif printf(" %p(%p)... ", (*sipp)->func, (*sipp)->udata); } #endif /* Call function */ (*((*sipp)->func))((*sipp)->udata); #if defined(VERBOSE_SYSINIT) if (verbose) printf("done.\n"); #endif /* Check off the one we're just done */ (*sipp)->subsystem = SI_SUB_DONE; /* Check if we've installed more sysinit items via KLD */ if (newsysinit != NULL) { if (sysinit != SET_BEGIN(sysinit_set)) free(sysinit, M_TEMP); sysinit = newsysinit; sysinit_end = newsysinit_end; newsysinit = NULL; newsysinit_end = NULL; goto restart; } } mtx_assert(&Giant, MA_OWNED | MA_NOTRECURSED); mtx_unlock(&Giant); /* * Now hand over this thread to swapper. */ swapper(); /* NOTREACHED*/ }
void TestTest::test_swapper() { int number_to_swap = 12345; swapper(number_to_swap); QCOMPARE(swapped_number, 54321); }
bool TransientMultiApp::solveStep(Real dt, Real target_time, bool auto_advance) { if (!_has_an_app) return true; _auto_advance = auto_advance; _console << "Solving MultiApp " << name() << std::endl; // "target_time" must always be in global time target_time += _app.getGlobalTimeOffset(); Moose::ScopedCommSwapper swapper(_my_comm); bool return_value = true; // Make sure we swap back the communicator regardless of how this routine is exited try { int rank; int ierr; ierr = MPI_Comm_rank(_orig_comm, &rank); mooseCheckMPIErr(ierr); for (unsigned int i = 0; i < _my_num_apps; i++) { FEProblemBase & problem = appProblemBase(_first_local_app + i); Transient * ex = _transient_executioners[i]; // The App might have a different local time from the rest of the problem Real app_time_offset = _apps[i]->getGlobalTimeOffset(); // Maybe this MultiApp was already solved if ((ex->getTime() + app_time_offset + 2e-14 >= target_time) || (ex->getTime() >= ex->endTime())) continue; if (_sub_cycling) { Real time_old = ex->getTime() + app_time_offset; if (_interpolate_transfers) { AuxiliarySystem & aux_system = problem.getAuxiliarySystem(); System & libmesh_aux_system = aux_system.system(); NumericVector<Number> & solution = *libmesh_aux_system.solution; NumericVector<Number> & transfer_old = libmesh_aux_system.get_vector("transfer_old"); solution.close(); // Save off the current auxiliary solution transfer_old = solution; transfer_old.close(); // Snag all of the local dof indices for all of these variables AllLocalDofIndicesThread aldit(libmesh_aux_system, _transferred_vars); ConstElemRange & elem_range = *problem.mesh().getActiveLocalElementRange(); Threads::parallel_reduce(elem_range, aldit); _transferred_dofs = aldit._all_dof_indices; } // Disable/enable output for sub cycling problem.allowOutput(_output_sub_cycles); // disables all outputs, including console problem.allowOutput<Console>(_print_sub_cycles); // re-enables Console to print, if desired ex->setTargetTime(target_time - app_time_offset); // unsigned int failures = 0; bool at_steady = false; if (_first && !_app.isRecovering()) problem.advanceState(); bool local_first = _first; // Now do all of the solves we need while ((!at_steady && ex->getTime() + app_time_offset + 2e-14 < target_time) || !ex->lastSolveConverged()) { if (local_first != true) ex->incrementStepOrReject(); local_first = false; ex->preStep(); ex->computeDT(); if (_interpolate_transfers) { // See what time this executioner is going to go to. Real future_time = ex->getTime() + app_time_offset + ex->getDT(); // How far along we are towards the target time: Real step_percent = (future_time - time_old) / (target_time - time_old); Real one_minus_step_percent = 1.0 - step_percent; // Do the interpolation for each variable that was transferred to FEProblemBase & problem = appProblemBase(_first_local_app + i); AuxiliarySystem & aux_system = problem.getAuxiliarySystem(); System & libmesh_aux_system = aux_system.system(); NumericVector<Number> & solution = *libmesh_aux_system.solution; NumericVector<Number> & transfer = libmesh_aux_system.get_vector("transfer"); NumericVector<Number> & transfer_old = libmesh_aux_system.get_vector("transfer_old"); solution.close(); // Just to be sure transfer.close(); transfer_old.close(); for (const auto & dof : _transferred_dofs) { solution.set(dof, (transfer_old(dof) * one_minus_step_percent) + (transfer(dof) * step_percent)); // solution.set(dof, transfer_old(dof)); // solution.set(dof, transfer(dof)); // solution.set(dof, 1); } solution.close(); } ex->takeStep(); bool converged = ex->lastSolveConverged(); if (!converged) { mooseWarning( "While sub_cycling ", name(), _first_local_app + i, " failed to converge!\n"); _failures++; if (_failures > _max_failures) { std::stringstream oss; oss << "While sub_cycling " << name() << _first_local_app << i << " REALLY failed!"; throw MultiAppSolveFailure(oss.str()); } } Real solution_change_norm = ex->getSolutionChangeNorm(); if (_detect_steady_state) _console << "Solution change norm: " << solution_change_norm << std::endl; if (converged && _detect_steady_state && solution_change_norm < _steady_state_tol) { _console << "Detected Steady State! Fast-forwarding to " << target_time << std::endl; at_steady = true; // Indicate that the next output call (occurs in ex->endStep()) should output, // regardless of intervals etc... problem.forceOutput(); // Clean up the end ex->endStep(target_time - app_time_offset); ex->postStep(); } else { ex->endStep(); ex->postStep(); } } // If we were looking for a steady state, but didn't reach one, we still need to output one // more time, regardless of interval if (!at_steady) problem.outputStep(EXEC_FORCED); } // sub_cycling else if (_tolerate_failure) { ex->takeStep(dt); ex->endStep(target_time - app_time_offset); ex->postStep(); } else { _console << "Solving Normal Step!" << std::endl; if (_first && !_app.isRecovering()) problem.advanceState(); if (auto_advance) problem.allowOutput(true); ex->takeStep(dt); if (auto_advance) { ex->endStep(); ex->postStep(); if (!ex->lastSolveConverged()) { mooseWarning(name(), _first_local_app + i, " failed to converge!\n"); if (_catch_up) { _console << "Starting Catch Up!" << std::endl; bool caught_up = false; unsigned int catch_up_step = 0; Real catch_up_dt = dt / 2; while (!caught_up && catch_up_step < _max_catch_up_steps) { _console << "Solving " << name() << " catch up step " << catch_up_step << std::endl; ex->incrementStepOrReject(); ex->computeDT(); ex->takeStep(catch_up_dt); // Cut the timestep in half to try two half-step solves ex->endStep(); if (ex->lastSolveConverged()) { if (ex->getTime() + app_time_offset + (ex->timestepTol() * std::abs(ex->getTime())) >= target_time) { problem.outputStep(EXEC_FORCED); caught_up = true; } } else catch_up_dt /= 2.0; ex->postStep(); catch_up_step++; } if (!caught_up) throw MultiAppSolveFailure(name() + " Failed to catch up!\n"); } } } else { if (!ex->lastSolveConverged()) { // Even if we don't allow auto_advance - we can still catch up to the current time if // possible if (_catch_up) { _console << "Starting Catch Up!" << std::endl; bool caught_up = false; unsigned int catch_up_step = 0; Real catch_up_dt = dt / 2; // Note: this loop will _break_ if target_time is satisfied while (catch_up_step < _max_catch_up_steps) { _console << "Solving " << name() << " catch up step " << catch_up_step << std::endl; ex->incrementStepOrReject(); ex->computeDT(); ex->takeStep(catch_up_dt); // Cut the timestep in half to try two half-step solves // This is required because we can't call endStep() yet // (which normally increments time) Real current_time = ex->getTime() + ex->getDT(); if (ex->lastSolveConverged()) { if (current_time + app_time_offset + (ex->timestepTol() * std::abs(current_time)) >= target_time) { caught_up = true; break; // break here so that we don't run endStep() or postStep() since this // MultiApp should NOT be auto_advanced } } else catch_up_dt /= 2.0; ex->endStep(); ex->postStep(); catch_up_step++; } if (!caught_up) throw MultiAppSolveFailure(name() + " Failed to catch up!\n"); } else throw MultiAppSolveFailure(name() + " failed to converge"); } } } // Re-enable all output (it may of been disabled by sub-cycling) problem.allowOutput(true); } _first = false; _console << "Successfully Solved MultiApp " << name() << "." << std::endl; } catch (MultiAppSolveFailure & e) { mooseWarning(e.what()); _console << "Failed to Solve MultiApp " << name() << ", attempting to recover." << std::endl; return_value = false; } _transferred_vars.clear(); return return_value; }
void MultiAppInterpolationTransfer::execute() { _console << "Beginning InterpolationTransfer " << name() << std::endl; switch (_direction) { case TO_MULTIAPP: { FEProblemBase & from_problem = _multi_app->problemBase(); MooseVariableFE & from_var = from_problem.getVariable(0, _from_var_name); MeshBase * from_mesh = NULL; if (_displaced_source_mesh && from_problem.getDisplacedProblem()) from_mesh = &from_problem.getDisplacedProblem()->mesh().getMesh(); else from_mesh = &from_problem.mesh().getMesh(); SystemBase & from_system_base = from_var.sys(); System & from_sys = from_system_base.system(); unsigned int from_sys_num = from_sys.number(); unsigned int from_var_num = from_sys.variable_number(from_var.name()); bool from_is_nodal = from_sys.variable_type(from_var_num).family == LAGRANGE; // EquationSystems & from_es = from_sys.get_equation_systems(); NumericVector<Number> & from_solution = *from_sys.solution; InverseDistanceInterpolation<LIBMESH_DIM> * idi; switch (_interp_type) { case 0: idi = new InverseDistanceInterpolation<LIBMESH_DIM>(from_sys.comm(), _num_points, _power); break; case 1: idi = new RadialBasisInterpolation<LIBMESH_DIM>(from_sys.comm(), _radius); break; default: mooseError("Unknown interpolation type!"); } std::vector<Point> & src_pts(idi->get_source_points()); std::vector<Number> & src_vals(idi->get_source_vals()); std::vector<std::string> field_vars; field_vars.push_back(_to_var_name); idi->set_field_variables(field_vars); std::vector<std::string> vars; vars.push_back(_to_var_name); if (from_is_nodal) { MeshBase::const_node_iterator from_nodes_it = from_mesh->local_nodes_begin(); MeshBase::const_node_iterator from_nodes_end = from_mesh->local_nodes_end(); for (; from_nodes_it != from_nodes_end; ++from_nodes_it) { Node * from_node = *from_nodes_it; // Assuming LAGRANGE! dof_id_type from_dof = from_node->dof_number(from_sys_num, from_var_num, 0); src_pts.push_back(*from_node); src_vals.push_back(from_solution(from_dof)); } } else { MeshBase::const_element_iterator from_elements_it = from_mesh->local_elements_begin(); MeshBase::const_element_iterator from_elements_end = from_mesh->local_elements_end(); for (; from_elements_it != from_elements_end; ++from_elements_it) { Elem * from_elem = *from_elements_it; // Assuming CONSTANT MONOMIAL dof_id_type from_dof = from_elem->dof_number(from_sys_num, from_var_num, 0); src_pts.push_back(from_elem->centroid()); src_vals.push_back(from_solution(from_dof)); } } // We have only set local values - prepare for use by gathering remote gata idi->prepare_for_use(); for (unsigned int i = 0; i < _multi_app->numGlobalApps(); i++) { if (_multi_app->hasLocalApp(i)) { Moose::ScopedCommSwapper swapper(_multi_app->comm()); // Loop over the master nodes and set the value of the variable System * to_sys = find_sys(_multi_app->appProblemBase(i).es(), _to_var_name); unsigned int sys_num = to_sys->number(); unsigned int var_num = to_sys->variable_number(_to_var_name); NumericVector<Real> & solution = _multi_app->appTransferVector(i, _to_var_name); MeshBase * mesh = NULL; if (_displaced_target_mesh && _multi_app->appProblemBase(i).getDisplacedProblem()) mesh = &_multi_app->appProblemBase(i).getDisplacedProblem()->mesh().getMesh(); else mesh = &_multi_app->appProblemBase(i).mesh().getMesh(); bool is_nodal = to_sys->variable_type(var_num).family == LAGRANGE; if (is_nodal) { MeshBase::const_node_iterator node_it = mesh->local_nodes_begin(); MeshBase::const_node_iterator node_end = mesh->local_nodes_end(); for (; node_it != node_end; ++node_it) { Node * node = *node_it; Point actual_position = *node + _multi_app->position(i); if (node->n_dofs(sys_num, var_num) > 0) // If this variable has dofs at this node { std::vector<Point> pts; std::vector<Number> vals; pts.push_back(actual_position); vals.resize(1); idi->interpolate_field_data(vars, pts, vals); Real value = vals.front(); // The zero only works for LAGRANGE! dof_id_type dof = node->dof_number(sys_num, var_num, 0); solution.set(dof, value); } } } else // Elemental { MeshBase::const_element_iterator elem_it = mesh->local_elements_begin(); MeshBase::const_element_iterator elem_end = mesh->local_elements_end(); for (; elem_it != elem_end; ++elem_it) { Elem * elem = *elem_it; Point centroid = elem->centroid(); Point actual_position = centroid + _multi_app->position(i); if (elem->n_dofs(sys_num, var_num) > 0) // If this variable has dofs at this elem { std::vector<Point> pts; std::vector<Number> vals; pts.push_back(actual_position); vals.resize(1); idi->interpolate_field_data(vars, pts, vals); Real value = vals.front(); dof_id_type dof = elem->dof_number(sys_num, var_num, 0); solution.set(dof, value); } } } solution.close(); to_sys->update(); } } delete idi; break; } case FROM_MULTIAPP: { FEProblemBase & to_problem = _multi_app->problemBase(); MooseVariableFE & to_var = to_problem.getVariable(0, _to_var_name); SystemBase & to_system_base = to_var.sys(); System & to_sys = to_system_base.system(); NumericVector<Real> & to_solution = *to_sys.solution; unsigned int to_sys_num = to_sys.number(); // Only works with a serialized mesh to transfer to! mooseAssert(to_sys.get_mesh().is_serial(), "MultiAppInterpolationTransfer only works with ReplicatedMesh!"); unsigned int to_var_num = to_sys.variable_number(to_var.name()); // EquationSystems & to_es = to_sys.get_equation_systems(); MeshBase * to_mesh = NULL; if (_displaced_target_mesh && to_problem.getDisplacedProblem()) to_mesh = &to_problem.getDisplacedProblem()->mesh().getMesh(); else to_mesh = &to_problem.mesh().getMesh(); bool is_nodal = to_sys.variable_type(to_var_num).family == LAGRANGE; InverseDistanceInterpolation<LIBMESH_DIM> * idi; switch (_interp_type) { case 0: idi = new InverseDistanceInterpolation<LIBMESH_DIM>(to_sys.comm(), _num_points, _power); break; case 1: idi = new RadialBasisInterpolation<LIBMESH_DIM>(to_sys.comm(), _radius); break; default: mooseError("Unknown interpolation type!"); } std::vector<Point> & src_pts(idi->get_source_points()); std::vector<Number> & src_vals(idi->get_source_vals()); std::vector<std::string> field_vars; field_vars.push_back(_to_var_name); idi->set_field_variables(field_vars); std::vector<std::string> vars; vars.push_back(_to_var_name); for (unsigned int i = 0; i < _multi_app->numGlobalApps(); i++) { if (!_multi_app->hasLocalApp(i)) continue; Moose::ScopedCommSwapper swapper(_multi_app->comm()); FEProblemBase & from_problem = _multi_app->appProblemBase(i); MooseVariableFE & from_var = from_problem.getVariable(0, _from_var_name); SystemBase & from_system_base = from_var.sys(); System & from_sys = from_system_base.system(); unsigned int from_sys_num = from_sys.number(); unsigned int from_var_num = from_sys.variable_number(from_var.name()); bool from_is_nodal = from_sys.variable_type(from_var_num).family == LAGRANGE; // EquationSystems & from_es = from_sys.get_equation_systems(); NumericVector<Number> & from_solution = *from_sys.solution; MeshBase * from_mesh = NULL; if (_displaced_source_mesh && from_problem.getDisplacedProblem()) from_mesh = &from_problem.getDisplacedProblem()->mesh().getMesh(); else from_mesh = &from_problem.mesh().getMesh(); Point app_position = _multi_app->position(i); if (from_is_nodal) { MeshBase::const_node_iterator from_nodes_it = from_mesh->local_nodes_begin(); MeshBase::const_node_iterator from_nodes_end = from_mesh->local_nodes_end(); for (; from_nodes_it != from_nodes_end; ++from_nodes_it) { Node * from_node = *from_nodes_it; // Assuming LAGRANGE! dof_id_type from_dof = from_node->dof_number(from_sys_num, from_var_num, 0); src_pts.push_back(*from_node + app_position); src_vals.push_back(from_solution(from_dof)); } } else { MeshBase::const_element_iterator from_elements_it = from_mesh->local_elements_begin(); MeshBase::const_element_iterator from_elements_end = from_mesh->local_elements_end(); for (; from_elements_it != from_elements_end; ++from_elements_it) { Elem * from_element = *from_elements_it; // Assuming LAGRANGE! dof_id_type from_dof = from_element->dof_number(from_sys_num, from_var_num, 0); src_pts.push_back(from_element->centroid() + app_position); src_vals.push_back(from_solution(from_dof)); } } } // We have only set local values - prepare for use by gathering remote gata idi->prepare_for_use(); // Now do the interpolation to the target system if (is_nodal) { MeshBase::const_node_iterator node_it = to_mesh->local_nodes_begin(); MeshBase::const_node_iterator node_end = to_mesh->local_nodes_end(); for (; node_it != node_end; ++node_it) { Node * node = *node_it; if (node->n_dofs(to_sys_num, to_var_num) > 0) // If this variable has dofs at this node { std::vector<Point> pts; std::vector<Number> vals; pts.push_back(*node); vals.resize(1); idi->interpolate_field_data(vars, pts, vals); Real value = vals.front(); // The zero only works for LAGRANGE! dof_id_type dof = node->dof_number(to_sys_num, to_var_num, 0); to_solution.set(dof, value); } } } else // Elemental { MeshBase::const_element_iterator elem_it = to_mesh->local_elements_begin(); MeshBase::const_element_iterator elem_end = to_mesh->local_elements_end(); for (; elem_it != elem_end; ++elem_it) { Elem * elem = *elem_it; Point centroid = elem->centroid(); if (elem->n_dofs(to_sys_num, to_var_num) > 0) // If this variable has dofs at this elem { std::vector<Point> pts; std::vector<Number> vals; pts.push_back(centroid); vals.resize(1); idi->interpolate_field_data(vars, pts, vals); Real value = vals.front(); dof_id_type dof = elem->dof_number(to_sys_num, to_var_num, 0); to_solution.set(dof, value); } } } to_solution.close(); to_sys.update(); delete idi; break; } } _console << "Finished InterpolationTransfer " << name() << std::endl; }
void MultiAppUserObjectTransfer::execute() { _console << "Beginning MultiAppUserObjectTransfer " << name() << std::endl; switch (_direction) { case TO_MULTIAPP: { for (unsigned int i = 0; i < _multi_app->numGlobalApps(); i++) { if (_multi_app->hasLocalApp(i)) { Moose::ScopedCommSwapper swapper(_multi_app->comm()); // Loop over the master nodes and set the value of the variable System * to_sys = find_sys(_multi_app->appProblemBase(i).es(), _to_var_name); unsigned int sys_num = to_sys->number(); unsigned int var_num = to_sys->variable_number(_to_var_name); NumericVector<Real> & solution = _multi_app->appTransferVector(i, _to_var_name); MeshBase * mesh = NULL; if (_displaced_target_mesh && _multi_app->appProblemBase(i).getDisplacedProblem()) { mesh = &_multi_app->appProblemBase(i).getDisplacedProblem()->mesh().getMesh(); } else mesh = &_multi_app->appProblemBase(i).mesh().getMesh(); bool is_nodal = to_sys->variable_type(var_num).family == LAGRANGE; const UserObject & user_object = _multi_app->problemBase().getUserObjectBase(_user_object_name); if (is_nodal) { for (auto & node : mesh->local_node_ptr_range()) { if (node->n_dofs(sys_num, var_num) > 0) // If this variable has dofs at this node { // The zero only works for LAGRANGE! dof_id_type dof = node->dof_number(sys_num, var_num, 0); swapper.forceSwap(); Real from_value = user_object.spatialValue(*node + _multi_app->position(i)); swapper.forceSwap(); solution.set(dof, from_value); } } } else // Elemental { for (auto & elem : as_range(mesh->local_elements_begin(), mesh->local_elements_end())) { Point centroid = elem->centroid(); if (elem->n_dofs(sys_num, var_num) > 0) // If this variable has dofs at this elem { // The zero only works for LAGRANGE! dof_id_type dof = elem->dof_number(sys_num, var_num, 0); swapper.forceSwap(); Real from_value = user_object.spatialValue(centroid + _multi_app->position(i)); swapper.forceSwap(); solution.set(dof, from_value); } } } solution.close(); to_sys->update(); } } break; } case FROM_MULTIAPP: { FEProblemBase & to_problem = _multi_app->problemBase(); MooseVariableFEBase & to_var = to_problem.getVariable( 0, _to_var_name, Moose::VarKindType::VAR_ANY, Moose::VarFieldType::VAR_FIELD_STANDARD); SystemBase & to_system_base = to_var.sys(); System & to_sys = to_system_base.system(); unsigned int to_sys_num = to_sys.number(); // Only works with a serialized mesh to transfer to! mooseAssert(to_sys.get_mesh().is_serial(), "MultiAppUserObjectTransfer only works with ReplicatedMesh!"); unsigned int to_var_num = to_sys.variable_number(to_var.name()); _console << "Transferring to: " << to_var.name() << std::endl; // EquationSystems & to_es = to_sys.get_equation_systems(); // Create a serialized version of the solution vector NumericVector<Number> * to_solution = to_sys.solution.get(); MeshBase * to_mesh = NULL; if (_displaced_target_mesh && to_problem.getDisplacedProblem()) to_mesh = &to_problem.getDisplacedProblem()->mesh().getMesh(); else to_mesh = &to_problem.mesh().getMesh(); bool is_nodal = to_sys.variable_type(to_var_num).family == LAGRANGE; for (unsigned int i = 0; i < _multi_app->numGlobalApps(); i++) { if (!_multi_app->hasLocalApp(i)) continue; Point app_position = _multi_app->position(i); BoundingBox app_box = _multi_app->getBoundingBox(i, _displaced_source_mesh); const UserObject & user_object = _multi_app->appUserObjectBase(i, _user_object_name); if (is_nodal) { for (auto & node : to_mesh->node_ptr_range()) { if (node->n_dofs(to_sys_num, to_var_num) > 0) // If this variable has dofs at this node { // See if this node falls in this bounding box if (app_box.contains_point(*node)) { dof_id_type dof = node->dof_number(to_sys_num, to_var_num, 0); Real from_value = 0; { Moose::ScopedCommSwapper swapper(_multi_app->comm()); from_value = user_object.spatialValue(*node - app_position); } to_solution->set(dof, from_value); } } } } else // Elemental { for (auto & elem : as_range(to_mesh->elements_begin(), to_mesh->elements_end())) { if (elem->n_dofs(to_sys_num, to_var_num) > 0) // If this variable has dofs at this elem { Point centroid = elem->centroid(); // See if this elem falls in this bounding box if (app_box.contains_point(centroid)) { dof_id_type dof = elem->dof_number(to_sys_num, to_var_num, 0); Real from_value = 0; { Moose::ScopedCommSwapper swapper(_multi_app->comm()); from_value = user_object.spatialValue(centroid - app_position); } to_solution->set(dof, from_value); } } } } } to_solution->close(); to_sys.update(); break; } } _console << "Finished MultiAppUserObjectTransfer " << name() << std::endl; }