/*************************************************************** ADD_AT(pos,b,NEWLIST) = ADDLIST(b,NEWLIST); ADD_AT(pos,b,ADDLIST(t,l)) = if pos=0 then ADDLIST(b,ADDLIST(t,l)) else ADD_AT(pos-1,b,l); ***************************************************************/ BOXLIST *add_at(int position,BOX *box,BOXLIST *boxlistpointer) { BOXLIST *newboxlist; if(boxlistpointer==NULL) { newboxlist=create_boxlist(); newboxlist->box=box; newboxlist->link=NULL; return newboxlist; } else { if(position==0) { newboxlist=create_boxlist(); newboxlist->box=box; newboxlist->link=boxlistpointer; return newboxlist; } else { boxlistpointer->link=add_at(position-1, box, boxlistpointer->link); return boxlistpointer; } } }
int main(int argc, char const *argv[]) { list_t *list = (list_t*)malloc(sizeof (list_t)); init(list); //make a node add_at(list, (void*)2, 0); assert(list->head && list->tail); assert((int) get(list, 0) == 2); //do more adding int i = 3; for(; i < 15; ++i){ add_front(list, (void*)i); assert(list->head && list->tail); assert((int) get(list, 0) == i); } assert((int) get(list, list->size - 1) == 2); assert((int) fold_left(list, add_list, (void*)0) == 104); assert((int) fold_left(list, add_list, (void*)0) == (int)fold_right(list, add_list, (void*)0)); add_back(list, (void*)0); assert(list->tail->data == (void*)0); assert((int) get(list, list->size - 1) == 0); add_front(list, (void*)2); add_front(list, (void*)2); assert((int) fold_left(list, count_2, (void*)0) == 3); remove_data(list, (void*)2, is_2); return 0; }
void this_thread_executor<Scheduler>::add_after( boost::chrono::steady_clock::duration const& rel_time, closure_type && f, char const* desc, threads::thread_stacksize stacksize, error_code& ec) { return add_at(boost::chrono::steady_clock::now() + rel_time, std::move(f), desc, stacksize, ec); }
void thread_pool_os_executor<Scheduler>::add_after( util::steady_clock::duration const& rel_time, closure_type && f, util::thread_description const& desc, threads::thread_stacksize stacksize, error_code& ec) { return add_at(util::steady_clock::now() + rel_time, std::move(f), desc, stacksize, ec); }
// Schedule given function for execution in this executor no sooner // than time rel_time from now. This call never blocks, and may // violate bounds on the executor's queue size. void service_executor::add_after( boost::chrono::steady_clock::duration const& rel_time, closure_type&& f, util::thread_description const& desc, threads::thread_stacksize stacksize, error_code& ec) { return add_at(boost::chrono::steady_clock::now() + rel_time, std::move(f), desc, stacksize, ec); }
void Matrix::do_jacobi_rotation(int p, int q, /*out*/ Matrix & current_transformation) { check_index(p); check_index(q); // check for invalid rotation if(p == q) { Logger::warning("incorrect jacobi rotation: `p` and `q` must be different indices", __FILE__, __LINE__); return; } // if element is already zeroed if(0 == get_at(p,q)) return; // r is the remaining index: not p and not q int r = 3 - p - q; // theta is cotangent of Real rotation angle Real theta = (get_at(q,q) - get_at(p,p))/get_at(p,q)/2; // t is sin/cos of rotation angle // it is determined from equation t^2 + 2*t*theta - 1 = 0, // which implies from definition of theta as (cos^2 - sin^2)/(2*sin*cos) Real t = (0 != theta) ? sign(theta)/(abs(theta) + sqrt(theta*theta + 1)) : 1; Real cosine = 1/sqrt(t*t + 1); Real sine = t*cosine; // tau is tangent of half of rotation angle Real tau = sine/(1 + cosine); add_at(p, p, - t*get_at(p,q)); add_at(q, q, + t*get_at(p,q)); // correction to element at (r,p) Real rp_correction = - sine*(get_at(r,q) + tau*get_at(r,p)); // correction to element at (r,q) Real rq_correction = + sine*(get_at(r,p) - tau*get_at(r,q)); add_at(r, p, rp_correction); add_at(p, r, rp_correction); add_at(r, q, rq_correction); add_at(q, r, rq_correction); set_at(p, q, 0); set_at(q, p, 0); // construct matrix of applied jacobi rotation Matrix rotation = Matrix::IDENTITY; rotation.set_at(p, p, cosine); rotation.set_at(q, q, cosine); rotation.set_at(p, q, sine); rotation.set_at(q, p, - sine); current_transformation = current_transformation*rotation; }
static void get_verlet_buffer_atomtypes(const gmx_mtop_t *mtop, verletbuf_atomtype_t **att_p, int *natt_p, int *n_nonlin_vsite) { verletbuf_atomtype_t *att; int natt; int mb, nmol, ft, i, a1, a2, a3, a; const t_atoms *atoms; const t_ilist *il; const t_iparams *ip; atom_nonbonded_kinetic_prop_t *prop; real *vsite_m; int n_nonlin_vsite_mol; att = NULL; natt = 0; if (n_nonlin_vsite != NULL) { *n_nonlin_vsite = 0; } for (mb = 0; mb < mtop->nmolblock; mb++) { nmol = mtop->molblock[mb].nmol; atoms = &mtop->moltype[mtop->molblock[mb].type].atoms; /* Check for constraints, as they affect the kinetic energy. * For virtual sites we need the masses and geometry of * the constructing atoms to determine their velocity distribution. */ snew(prop, atoms->nr); snew(vsite_m, atoms->nr); for (ft = F_CONSTR; ft <= F_CONSTRNC; ft++) { il = &mtop->moltype[mtop->molblock[mb].type].ilist[ft]; for (i = 0; i < il->nr; i += 1+NRAL(ft)) { ip = &mtop->ffparams.iparams[il->iatoms[i]]; a1 = il->iatoms[i+1]; a2 = il->iatoms[i+2]; if (atoms->atom[a2].m > prop[a1].con_mass) { prop[a1].con_mass = atoms->atom[a2].m; prop[a1].con_len = ip->constr.dA; } if (atoms->atom[a1].m > prop[a2].con_mass) { prop[a2].con_mass = atoms->atom[a1].m; prop[a2].con_len = ip->constr.dA; } } } il = &mtop->moltype[mtop->molblock[mb].type].ilist[F_SETTLE]; for (i = 0; i < il->nr; i += 1+NRAL(F_SETTLE)) { ip = &mtop->ffparams.iparams[il->iatoms[i]]; a1 = il->iatoms[i+1]; a2 = il->iatoms[i+2]; a3 = il->iatoms[i+3]; /* Usually the mass of a1 (usually oxygen) is larger than a2/a3. * If this is not the case, we overestimate the displacement, * which leads to a larger buffer (ok since this is an exotic case). */ prop[a1].con_mass = atoms->atom[a2].m; prop[a1].con_len = ip->settle.doh; prop[a2].con_mass = atoms->atom[a1].m; prop[a2].con_len = ip->settle.doh; prop[a3].con_mass = atoms->atom[a1].m; prop[a3].con_len = ip->settle.doh; } get_vsite_masses(&mtop->moltype[mtop->molblock[mb].type], &mtop->ffparams, vsite_m, &n_nonlin_vsite_mol); if (n_nonlin_vsite != NULL) { *n_nonlin_vsite += nmol*n_nonlin_vsite_mol; } for (a = 0; a < atoms->nr; a++) { if (atoms->atom[a].ptype == eptVSite) { prop[a].mass = vsite_m[a]; } else { prop[a].mass = atoms->atom[a].m; } prop[a].type = atoms->atom[a].type; prop[a].q = atoms->atom[a].q; /* We consider an atom constrained, #DOF=2, when it is * connected with constraints to (at least one) atom with * a mass of more than 0.4x its own mass. This is not a critical * parameter, since with roughly equal masses the unconstrained * and constrained displacement will not differ much (and both * overestimate the displacement). */ prop[a].bConstr = (prop[a].con_mass > 0.4*prop[a].mass); add_at(&att, &natt, &prop[a], nmol); } sfree(vsite_m); sfree(prop); } if (gmx_debug_at) { for (a = 0; a < natt; a++) { fprintf(debug, "type %d: m %5.2f t %d q %6.3f con %d con_m %5.3f con_l %5.3f n %d\n", a, att[a].prop.mass, att[a].prop.type, att[a].prop.q, att[a].prop.bConstr, att[a].prop.con_mass, att[a].prop.con_len, att[a].n); } } *att_p = att; *natt_p = natt; }
static void get_verlet_buffer_atomtypes(const gmx_mtop_t *mtop, verletbuf_atomtype_t **att_p, int *natt_p, int *n_nonlin_vsite) { verletbuf_atomtype_t *att; int natt; int mb, nmol, ft, i, j, a1, a2, a3, a; const t_atoms *atoms; const t_ilist *il; const t_atom *at; const t_iparams *ip; real *con_m, *vsite_m, cam[5]; att = NULL; natt = 0; if (n_nonlin_vsite != NULL) { *n_nonlin_vsite = 0; } for (mb = 0; mb < mtop->nmolblock; mb++) { nmol = mtop->molblock[mb].nmol; atoms = &mtop->moltype[mtop->molblock[mb].type].atoms; /* Check for constraints, as they affect the kinetic energy */ snew(con_m, atoms->nr); snew(vsite_m, atoms->nr); for (ft = F_CONSTR; ft <= F_CONSTRNC; ft++) { il = &mtop->moltype[mtop->molblock[mb].type].ilist[ft]; for (i = 0; i < il->nr; i += 1+NRAL(ft)) { a1 = il->iatoms[i+1]; a2 = il->iatoms[i+2]; con_m[a1] += atoms->atom[a2].m; con_m[a2] += atoms->atom[a1].m; } } il = &mtop->moltype[mtop->molblock[mb].type].ilist[F_SETTLE]; for (i = 0; i < il->nr; i += 1+NRAL(F_SETTLE)) { a1 = il->iatoms[i+1]; a2 = il->iatoms[i+2]; a3 = il->iatoms[i+3]; con_m[a1] += atoms->atom[a2].m + atoms->atom[a3].m; con_m[a2] += atoms->atom[a1].m + atoms->atom[a3].m; con_m[a3] += atoms->atom[a1].m + atoms->atom[a2].m; } /* Check for virtual sites, determine mass from constructing atoms */ for (ft = 0; ft < F_NRE; ft++) { if (IS_VSITE(ft)) { il = &mtop->moltype[mtop->molblock[mb].type].ilist[ft]; for (i = 0; i < il->nr; i += 1+NRAL(ft)) { ip = &mtop->ffparams.iparams[il->iatoms[i]]; a1 = il->iatoms[i+1]; for (j = 1; j < NRAL(ft); j++) { cam[j] = atoms->atom[il->iatoms[i+1+j]].m; if (cam[j] == 0) { cam[j] = vsite_m[il->iatoms[i+1+j]]; } if (cam[j] == 0) { gmx_fatal(FARGS, "In molecule type '%s' %s construction involves atom %d, which is a virtual site of equal or high complexity. This is not supported.", *mtop->moltype[mtop->molblock[mb].type].name, interaction_function[ft].longname, il->iatoms[i+1+j]+1); } } switch (ft) { case F_VSITE2: /* Exact except for ignoring constraints */ vsite_m[a1] = (cam[2]*sqr(1-ip->vsite.a) + cam[1]*sqr(ip->vsite.a))/(cam[1]*cam[2]); break; case F_VSITE3: /* Exact except for ignoring constraints */ vsite_m[a1] = (cam[2]*cam[3]*sqr(1-ip->vsite.a-ip->vsite.b) + cam[1]*cam[3]*sqr(ip->vsite.a) + cam[1]*cam[2]*sqr(ip->vsite.b))/(cam[1]*cam[2]*cam[3]); break; default: /* Use the mass of the lightest constructing atom. * This is an approximation. * If the distance of the virtual site to the * constructing atom is less than all distances * between constructing atoms, this is a safe * over-estimate of the displacement of the vsite. * This condition holds for all H mass replacement * replacement vsite constructions, except for SP2/3 * groups. In SP3 groups one H will have a F_VSITE3 * construction, so even there the total drift * estimation shouldn't be far off. */ assert(j >= 1); vsite_m[a1] = cam[1]; for (j = 2; j < NRAL(ft); j++) { vsite_m[a1] = min(vsite_m[a1], cam[j]); } if (n_nonlin_vsite != NULL) { *n_nonlin_vsite += nmol; } break; } } } } for (a = 0; a < atoms->nr; a++) { at = &atoms->atom[a]; /* We consider an atom constrained, #DOF=2, when it is * connected with constraints to one or more atoms with * total mass larger than 1.5 that of the atom itself. */ add_at(&att, &natt, at->m, at->type, at->q, con_m[a] > 1.5*at->m, nmol); } sfree(vsite_m); sfree(con_m); } if (gmx_debug_at) { for (a = 0; a < natt; a++) { fprintf(debug, "type %d: m %5.2f t %d q %6.3f con %d n %d\n", a, att[a].mass, att[a].type, att[a].q, att[a].con, att[a].n); } } *att_p = att; *natt_p = natt; }