//----------------------------------------------------------------------------- void ALE::move(Mesh& mesh, const GenericFunction& displacement) { // Check dimensions const std::size_t gdim = mesh.geometry().dim(); if (!((displacement.value_rank() == 0 && gdim == 1) || (displacement.value_rank() == 1 && gdim == displacement.value_dimension(0)))) { dolfin_error("ALE.cpp", "move mesh using mesh smoothing", "Illegal value dimension of displacement function"); } // Interpolate at vertices const std::size_t N = mesh.num_vertices(); std::vector<double> vertex_values; displacement.compute_vertex_values(vertex_values, mesh); // Move vertex coordinates MeshGeometry& geometry = mesh.geometry(); std::vector<double> x(gdim); for (std::size_t i = 0; i < N; i++) { for (std::size_t j = 0; j < gdim; j++) x[j] = geometry.x(i, j) + vertex_values[j*N + i]; geometry.set(i, x.data()); } }
void CBaseEntity::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { if (!scripted || !ScriptsActive()) { RealUse( pActivator, pCaller, useType, value ); return; } GenericFunction *pfn = my_script->funcs->GetFn(M_USE); if (!pfn) { RealUse( pActivator, pCaller, useType, value ); return; } if (NoErrors()) { pfn->PreExecute(); int i = ENTINDEX(edict()), j = ENTINDEX(pCaller->edict()), t = (int)useType; double v = value; if (pfn->argc > 0) pfn->PassArg(0, Type(&i, _INT)); if (pfn->argc > 1) pfn->PassArg(1, Type(&j, _INT)); if (pfn->argc > 2) pfn->PassArg(2, Type(&t, _INT)); if (pfn->argc > 3) pfn->PassArg(3, Type(&v, DOUBLE)); switch (pfn->specification) { case SPECIFICATION_BEFORE: pfn->Execute(); RealUse( pActivator, pCaller, useType, value ); break; case SPECIFICATION_INSTEAD: pfn->Execute(); break; default: RealUse( pActivator, pCaller, useType, value ); pfn->Execute(); break; } } else RealUse( pActivator, pCaller, useType, value ); }
void DispatchThink( edict_t *pent ) { CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent); if (pEntity) { if ( FBitSet( pEntity->pev->flags, FL_DORMANT ) ) ALERT( at_error, "Dormant entity %s is thinking!!\n", STRING(pEntity->pev->classname) ); //LLAPb begin if (!pEntity->scripted || !ScriptsActive()) { pEntity->Think(); return; } GenericFunction *pfn = pEntity->my_script->funcs->GetFn(M_THINK); if (!pfn) { pEntity->Think(); return; } if (NoErrors()) { pfn->PreExecute(); int i = ENTINDEX(pent); double f = gpGlobals->frametime; if (pfn->argc > 0) pfn->PassArg(0, Type(&i, _INT)); if (pfn->argc > 1) pfn->PassArg(1, Type(&f, DOUBLE)); switch (pfn->specification) { case SPECIFICATION_BEFORE: pfn->Execute(); pEntity->Think(); break; case SPECIFICATION_INSTEAD: pfn->Execute(); break; default: pEntity->Think(); pfn->Execute(); break; } } else //LLAPb end pEntity->Think(); } }
//----------------------------------------------------------------------------- void Function::interpolate(const GenericFunction& v) { dolfin_assert(_vector); dolfin_assert(_function_space); // Gather off-process dofs v.update(); // Interpolate _function_space->interpolate(*_vector, v); }
void CBaseEntity::ReSpawn( void ) { if (scripted && ScriptsActive()) { GenericFunction *pfn = my_script->funcs->GetFn(M_SPAWN); if (!pfn) { RealReSpawn(); return; } if (NoErrors()) { pfn->PreExecute(); int i = ENTINDEX(edict()); if (pfn->argc > 0) pfn->PassArg(0, Type(&i, _INT)); switch (pfn->specification) { case SPECIFICATION_BEFORE: pfn->Execute(); RealReSpawn(); break; case SPECIFICATION_INSTEAD: pfn->Execute(); break; default: RealReSpawn(); pfn->Execute(); break; } } else RealReSpawn(); } else RealReSpawn(); }
//----------------------------------------------------------------------------- void FunctionSpace::interpolate(GenericVector& expansion_coefficients, const GenericFunction& v) const { dolfin_assert(_mesh); dolfin_assert(_element); dolfin_assert(_dofmap); // Check that function ranks match if (_element->value_rank() != v.value_rank()) { dolfin_error("FunctionSpace.cpp", "interpolate function into function space", "Rank of function (%d) does not match rank of function space (%d)", v.value_rank(), element()->value_rank()); } // Check that function dims match for (std::size_t i = 0; i < _element->value_rank(); ++i) { if (_element->value_dimension(i) != v.value_dimension(i)) { dolfin_error("FunctionSpace.cpp", "interpolate function into function space", "Dimension %d of function (%d) does not match dimension %d of function space (%d)", i, v.value_dimension(i), i, element()->value_dimension(i)); } } // Initialize vector of expansion coefficients if (expansion_coefficients.size() != _dofmap->global_dimension()) { dolfin_error("FunctionSpace.cpp", "interpolate function into function space", "Wrong size of vector"); } expansion_coefficients.zero(); // Initialize local arrays std::vector<double> cell_coefficients(_dofmap->max_element_dofs()); // Iterate over mesh and interpolate on each cell ufc::cell ufc_cell; std::vector<double> vertex_coordinates; for (CellIterator cell(*_mesh); !cell.end(); ++cell) { // Update to current cell cell->get_vertex_coordinates(vertex_coordinates); cell->get_cell_data(ufc_cell); // Restrict function to cell v.restrict(cell_coefficients.data(), *_element, *cell, vertex_coordinates.data(), ufc_cell); // Tabulate dofs const ArrayView<const dolfin::la_index> cell_dofs = _dofmap->cell_dofs(cell->index()); // Copy dofs to vector expansion_coefficients.set_local(cell_coefficients.data(), _dofmap->num_element_dofs(cell->index()), cell_dofs.data()); } // Finalise changes expansion_coefficients.apply("insert"); }
int CBaseEntity :: TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ) { if (!scripted || !ScriptsActive()) { return RealTakeDamage( pevInflictor, pevAttacker, flDamage, bitsDamageType ); } GenericFunction *pfn = my_script->funcs->GetFn(M_DAMAGED); if (!pfn) { return RealTakeDamage( pevInflictor, pevAttacker, flDamage, bitsDamageType ); } if (NoErrors()) { pfn->PreExecute(); int i = ENTINDEX(edict()), j = ENTINDEX(ENT(pevAttacker)); double v = flDamage; TraceResult tr; if (pevInflictor == pevAttacker && pevAttacker)//yep... bad way { CBaseEntity *pEnt = CBaseEntity::Instance(pevAttacker); if (pEnt->IsPlayer()) { CBasePlayer *pPlayer = (CBasePlayer*)pEnt; if (pPlayer) { UTIL_MakeVectors(pPlayer->pev->v_angle); Vector vec_dir = gpGlobals->v_forward * 32000; UTIL_TraceLine(pPlayer->GetGunPosition(), pevInflictor->origin + vec_dir, dont_ignore_monsters, ENT(pevInflictor), &tr); } else UTIL_TraceLine(pevInflictor->origin, pev->origin, dont_ignore_monsters, ENT(pevInflictor), &tr); } else UTIL_TraceLine(pevInflictor->origin, pev->origin, dont_ignore_monsters, ENT(pevInflictor), &tr); } else UTIL_TraceLine(pevInflictor->origin, pev->origin, dont_ignore_monsters, ENT(pevInflictor), &tr); double x = tr.vecEndPos.x; double y = tr.vecEndPos.y; double z = tr.vecEndPos.z; Type arg3[3] = {Type(&x, DOUBLE), Type(&y, DOUBLE), Type(&z, DOUBLE)}; if (pfn->argc > 0) pfn->PassArg(0, Type(&i, _INT)); if (pfn->argc > 1) pfn->PassArg(1, Type(&j, _INT)); if (pfn->argc > 2) pfn->PassArg(2, Type(&v, DOUBLE)); if (pfn->argc > 3) pfn->PassArg(3, Type(&arg3[0], VECTOR_T, 3)); if (pfn->argc > 4) pfn->PassArg(4, Type(&bitsDamageType, _INT)); if (pfn->argc > 5) pfn->PassArg(5, Type(&tr.iHitgroup, _INT)); switch (pfn->specification) { case SPECIFICATION_BEFORE: { Type res = pfn->Execute(); if (res.my_type == DOUBLE) return RealTakeDamage( pevInflictor, pevAttacker, res.doublev, bitsDamageType ); else if (res.my_type == _INT) return RealTakeDamage( pevInflictor, pevAttacker, res.intv, bitsDamageType ); return RealTakeDamage( pevInflictor, pevAttacker, flDamage, bitsDamageType ); } case SPECIFICATION_INSTEAD: pfn->Execute(); return 1; default: { int v = RealTakeDamage( pevInflictor, pevAttacker, flDamage, bitsDamageType ); pfn->Execute(); return v; } } } else return RealTakeDamage( pevInflictor, pevAttacker, flDamage, bitsDamageType ); }
//LLAPb: this function is bullshit!!! Must of all calls of "Use" are coming not from engine. F**k!!! void DispatchUse( edict_t *pentUsed, edict_t *pentOther ) { CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pentUsed); CBaseEntity *pOther = (CBaseEntity *)GET_PRIVATE(pentOther); //LLAPb begin if (pEntity && !(pEntity->pev->flags & FL_KILLME) ) { if (!pEntity->scripted || !ScriptsActive()) { pEntity->Use( pOther, pOther, USE_TOGGLE, 0 ); return; } GenericFunction *pfn = pEntity->my_script->funcs->GetFn(M_USE); if (!pfn) { pEntity->Use( pOther, pOther, USE_TOGGLE, 0 ); return; } if (NoErrors()) { pfn->PreExecute(); int i = ENTINDEX(pentUsed), j = ENTINDEX(pentOther), t = (int)USE_TOGGLE; double v = 0; if (pfn->argc > 0) pfn->PassArg(0, Type(&i, _INT)); if (pfn->argc > 1) pfn->PassArg(1, Type(&j, _INT)); if (pfn->argc > 2) pfn->PassArg(2, Type(&t, _INT)); if (pfn->argc > 3) pfn->PassArg(3, Type(&v, DOUBLE)); switch (pfn->specification) { case SPECIFICATION_BEFORE: pfn->Execute(); pEntity->Use( pOther, pOther, USE_TOGGLE, 0 ); break; case SPECIFICATION_INSTEAD: pfn->Execute(); break; default: pEntity->Use( pOther, pOther, USE_TOGGLE, 0 ); pfn->Execute(); break; } } else pEntity->Use( pOther, pOther, USE_TOGGLE, 0 ); } //LLAPb end }
void DispatchTouch( edict_t *pentTouched, edict_t *pentOther ) { if ( gTouchDisabled ) return; CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pentTouched); CBaseEntity *pOther = (CBaseEntity *)GET_PRIVATE( pentOther ); //LLAPb changes begin if ( pEntity && pOther && ! ((pEntity->pev->flags | pOther->pev->flags) & FL_KILLME) ) { if (!pEntity->scripted || !ScriptsActive()) { pEntity->Touch( pOther ); return; } GenericFunction *pfn = pEntity->my_script->funcs->GetFn(M_TOUCH); if (!pfn) { pEntity->Touch( pOther ); return; } if (NoErrors()) { pfn->PreExecute(); int i = ENTINDEX(pentTouched), j = ENTINDEX(pentOther); if (pfn->argc > 0) pfn->PassArg(0, Type(&i, _INT)); if (pfn->argc > 1) pfn->PassArg(1, Type(&j, _INT)); switch (pfn->specification) { case SPECIFICATION_BEFORE: pfn->Execute(); pEntity->Touch( pOther ); break; case SPECIFICATION_INSTEAD: pfn->Execute(); break; default: pEntity->Touch( pOther ); pfn->Execute(); break; } } else pEntity->Touch( pOther ); } //LLAPb changes end }
//LLAPb: I do not trust this callback, there's a lots of directly calls of "Spawn" in code. Must be reason... int DispatchSpawn( edict_t *pent ) { CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent); if (pEntity) { // Initialize these or entities who don't link to the world won't have anything in here pEntity->pev->absmin = pEntity->pev->origin - Vector(1,1,1); pEntity->pev->absmax = pEntity->pev->origin + Vector(1,1,1); //LLAPb begin if (!FStringNull(pEntity->script_file)) { pEntity->PRECACHE_SCRIPT((char*)STRING(pEntity->script_file)); } if (pEntity->scripted && ScriptsActive()) { GenericFunction *pfn = pEntity->my_script->funcs->GetFn(M_SPAWN); if (!pfn) { pEntity->Spawn(); goto LLAPb_end; } if (NoErrors()) { pfn->PreExecute(); int i = ENTINDEX(pent); if (pfn->argc > 0) pfn->PassArg(0, Type(&i, _INT)); switch (pfn->specification) { case SPECIFICATION_BEFORE: pfn->Execute(); pEntity->Spawn(); break; case SPECIFICATION_INSTEAD: pfn->Execute(); break; default: pEntity->Spawn(); pfn->Execute(); break; } } else pEntity->Spawn(); } else pEntity->Spawn(); LLAPb_end: //LLAPb end // Try to get the pointer again, in case the spawn function deleted the entity. // UNDONE: Spawn() should really return a code to ask that the entity be deleted, but // that would touch too much code for me to do that right now. pEntity = (CBaseEntity *)GET_PRIVATE(pent); if ( pEntity ) { pEntity->pev->colormap = ENTINDEX(pent); if ( g_pGameRules && !g_pGameRules->IsAllowedToSpawn( pEntity ) ) return -1; // return that this entity should be deleted if ( pEntity->pev->flags & FL_KILLME ) return -1; } // Handle global stuff here if ( pEntity && pEntity->pev->globalname ) { const globalentity_t *pGlobal = gGlobalState.EntityFromTable( pEntity->pev->globalname ); if ( pGlobal ) { // Already dead? delete if ( pGlobal->state == GLOBAL_DEAD ) return -1; else if ( !FStrEq( STRING(gpGlobals->mapname), pGlobal->levelName ) ) pEntity->MakeDormant(); // Hasn't been moved to this level yet, wait but stay alive // In this level & not dead, continue on as normal } else { // Spawned entities default to 'On' gGlobalState.EntityAdd( pEntity->pev->globalname, gpGlobals->mapname, GLOBAL_ON ); // ALERT( at_console, "Added global entity %s (%s)\n", STRING(pEntity->pev->classname), STRING(pEntity->pev->globalname) ); } } } return 0; }
void interpolate_nonmatching_mesh(const GenericFunction& u0, Function& u) { // Interpolate from GenericFunction u0 to FunctionSpace of Function u // The FunctionSpace of u can have a different mesh than that of u0 // (if u0 has a mesh) // // The algorithm is like this // // 1) Tabulate all coordinates for all dofs in u.function_space() // 2) Create a map from dof to component number in Mixed Space. // 3) Evaluate u0 for all coordinates in u (computed in 1)). // Problem here is that u0 and u will have different meshes // and as such a vertex in u will not necessarily be found // on the same processor for u0. Hence the vertex will be // passed around and searched on all ranks until found. // 4) Set all values in local u using the dof to component map // Get the function space interpolated to boost::shared_ptr<const FunctionSpace> V = u.function_space(); // Get mesh and dimension of the FunctionSpace interpolated to const Mesh& mesh = *V->mesh(); const std::size_t gdim = mesh.geometry().dim(); // Create arrays used to evaluate one point std::vector<double> x(gdim); std::vector<double> values(u.value_size()); Array<double> _x(gdim, x.data()); Array<double> _values(u.value_size(), values.data()); // Create vector to hold all local values of u std::vector<double> local_u_vector(u.vector()->local_size()); // Get coordinates of all dofs on mesh of this processor std::vector<double> coords = V->dofmap()->tabulate_all_coordinates(mesh); // Get dof ownership range std::pair<std::size_t, std::size_t> owner_range = V->dofmap()->ownership_range(); // Get a map from global dofs to component number in mixed space std::map<std::size_t, std::size_t> dof_component_map; int component = -1; extract_dof_component_map(dof_component_map, *V, &component); // Search this process first for all coordinates in u's local mesh std::vector<std::size_t> global_dofs_not_found; std::vector<double> coords_not_found; for (std::size_t j=0; j<coords.size()/gdim; j++) { std::copy(coords.begin()+j*gdim, coords.begin()+(j+1)*gdim, x.begin()); try { // store when point is found u0.eval(_values, _x); // This evaluates all dofs, but need only one component. Possible fix? local_u_vector[j] = values[dof_component_map[j+owner_range.first]]; } catch (std::exception &e) { // If not found then it must be seached on the other processes global_dofs_not_found.push_back(j+owner_range.first); for (std::size_t jj=0; jj<gdim; jj++) coords_not_found.push_back(x[jj]); } } // Send all points not found to processor with one higher rank. // Search there and send found points back to owner and not found to // next processor in line. By the end of this loop all processors // will have been searched and thus if not found the point is not // in the mesh of Function u0. In that case the point will take // the value of zero. std::size_t num_processes = MPI::num_processes(); std::size_t rank = MPI::process_number(); for (std::size_t k = 1; k < num_processes; ++k) { std::vector<double> coords_recv; std::vector<std::size_t> global_dofs_recv; std::size_t src = (rank-1+num_processes) % num_processes; std::size_t dest = (rank+1) % num_processes; MPI::send_recv(global_dofs_not_found, dest, global_dofs_recv, src); MPI::send_recv(coords_not_found, dest, coords_recv, src); global_dofs_not_found.clear(); coords_not_found.clear(); // Search this processor for received points std::vector<std::size_t> global_dofs_found; std::vector<std::vector<double> > coefficients_found; for (std::size_t j=0; j<coords_recv.size()/gdim; j++) { std::size_t m = global_dofs_recv[j]; std::copy(coords_recv.begin()+j*gdim, coords_recv.begin()+(j+1)*gdim, x.begin()); try { // push back when point is found u0.eval(_values, _x); coefficients_found.push_back(values); global_dofs_found.push_back(m); } catch (std::exception &e) { // If not found then collect and send to next rank global_dofs_not_found.push_back(m); for (std::size_t jj=0; jj<gdim; jj++) coords_not_found.push_back(x[jj]); } } // Send found coefficients back to owner (dest) std::vector<std::size_t> global_dofs_found_recv; std::vector<std::vector<double> > coefficients_found_recv; dest = (rank-k+num_processes) % num_processes; src = (rank+k) % num_processes; MPI::send_recv(global_dofs_found, dest, global_dofs_found_recv, src); MPI::send_recv(coefficients_found, dest, coefficients_found_recv, src); // Move all found coefficients onto the local_u_vector // Choose the correct component using dof_component_map for (std::size_t j=0; j<global_dofs_found_recv.size(); j++) { std::size_t m = global_dofs_found_recv[j]-owner_range.first; std::size_t n = dof_component_map[m+owner_range.first]; local_u_vector[m] = coefficients_found_recv[j][n]; } // Note that this algorithm computes and sends back all values, // i.e., coefficients_found pushes back the entire vector for all // components in mixed space. An alternative algorithm is to send // around the correct component number in addition to global dof number // and coordinates and then just send back the correct value. } u.vector()->set_local(local_u_vector); }