// // Write a DPD input file-style molecule definition. // private static void write_molecule_type(StreamWriter f, DPDMoleculeType mol, DPDSim sim) { var N_sites = mol.site_internal_ids.Count; var N_bonds = mol.bond_k.Count; var N_angles = mol.angle_k.Count; f.WriteLine("molecule"); f.WriteLine("\tname {0}", mol.name); f.WriteLine("\tcount {0}", mol.count); for (var si = 0; si < N_sites; si++) { var i = mol.site_internal_ids[si]; f.WriteLine("\tsite {0}", sim.site_types[i].name); } for (var bi = 0; bi < N_bonds; bi++) { var i = mol.bond_site_indices[bi * 2 + 0]; var j = mol.bond_site_indices[bi * 2 + 1]; f.WriteLine("\tbond\t{0}\t{1}\t\t{2}\t{3}\n", i, j, mol.bond_eq[bi], mol.bond_k[bi]); } for (var ai = 0; ai < N_angles; ai++) { var i = mol.angle_site_indices[ai * 3 + 0]; var j = mol.angle_site_indices[ai * 3 + 1]; var k = mol.angle_site_indices[ai * 3 + 2]; f.WriteLine("\tangle\t{0}\t{1}\t{2}\t\t{3}\t{4}\n", i, j, k, mol.angle_eq[ai], mol.angle_k[ai]); } f.WriteLine("end\n"); }
private static void parse_dpd_sim(StreamReader f, DPDSim sim) { var delim = new char[] { ' ', ',', '\t' }; string linebuffer; bool cell_found = false; ParseState parse_state = ParseState.None; int site_upto = 0, line_no = 0; var site = new DPDSiteType(); var mol = new DPDMoleculeType(); mol.Clear(); sim.Clear(); while ((linebuffer = f.ReadLine()) != null) { line_no++; var tokens = linebuffer.Split(delim, StringSplitOptions.RemoveEmptyEntries); if (tokens.Length < 1) { continue; } if (tokens[0].Length < 1 || tokens[0][0] == '#') { continue; } // if we hit an end flag if (tokens[0] == "end") { if (parse_state == ParseState.None) { DPDError("Unexpected 'end' token"); } if (parse_state == ParseState.Molecule) { sim.molecule_types.Add(mol); mol = new DPDMoleculeType(); } parse_state = ParseState.None; } // if parsing the system settings ... else if (parse_state == ParseState.Settings) { var key = tokens[0]; if (key == "kBT") { sim.target_kBT = Convert.ToDouble(tokens[1]); } else if (key == "sigma") { sim.sigma = Convert.ToDouble(tokens[1]); } else if (key == "lambda") { sim.lambda = Convert.ToDouble(tokens[1]); } else if (key == "delta_t") { sim.delta_t = Convert.ToDouble(tokens[1]); } else if (key == "step_no") { sim.step_no = Convert.ToInt32(tokens[1]); } else if (key == "max_steps") { sim.max_steps = Convert.ToInt32(tokens[1]); } else if (key == "save_every") { sim.save_every = Convert.ToInt32(tokens[1]); } else if (key == "print_every") { sim.print_every = Convert.ToInt32(tokens[1]); } else if (key == "ran1") { sim.ran1_value = Convert.ToInt64(tokens[1]); } else if (key == "dumb") { sim.i_am_dumb = 1; } else if (key == "cell") { cell_found = true; sim.cell[0] = Convert.ToDouble(tokens[1]); sim.cell[1] = Convert.ToDouble(tokens[2]); sim.cell[2] = Convert.ToDouble(tokens[3]); } else { Console.WriteLine("Unknown entry {0} found on line {1} in settings; ignoring.", key, line_no); } } // if parsing the site declarations ... else if (parse_state == ParseState.Sites) { site.name = tokens[0]; site.internal_id = sim.site_types.Count; sim.site_types.Add(site); site = new DPDSiteType(); } // if parsing the nonbonded interaction parameters ... else if (parse_state == ParseState.Interactions) { var N_site_types = sim.site_types.Count; var i = get_site_type_from_name(tokens[0], sim); var j = get_site_type_from_name(tokens[1], sim); // j and l are the internal ids, so use them. sim.interactions[(i * N_site_types) + j] = Convert.ToDouble(tokens[2]); // symmetrical! sim.interactions[(j * N_site_types) + i] = sim.interactions[(i * N_site_types) + j]; } // if parsing a molecule ... else if (parse_state == ParseState.Molecule) { var key = tokens[0]; if (key == "name") { mol.name = tokens[1]; } else if (key == "count") { mol.count = Convert.ToInt32(tokens[1]); } else if (key == "site") { var i = get_site_type_from_name(tokens[1], sim); if (i == -1) { DPDError("Error on line {0}; unable to find a type id for molecule site of type {1} in {2}. Probably undefined.", line_no, tokens[1], mol.name); } mol.site_internal_ids.Add(i); } else if (key == "bond") { var N = mol.site_internal_ids.Count; // check sites exist! for (var i = 0; i < 2; i++) { var idx = Convert.ToInt32(tokens[1 + i]); if (idx < 1 || idx > N) { DPDError("Error on line {0}; bond index {1} is invalid.", line_no, idx); } mol.bond_site_indices.Add(idx); } mol.bond_eq.Add(Convert.ToDouble(tokens[3])); mol.bond_k.Add(Convert.ToDouble(tokens[4])); } else if (key == "angle") { var N = mol.site_internal_ids.Count; // check sites exist! for (var i = 0; i < 3; i++) { var idx = Convert.ToInt32(tokens[1 + i]); if (idx < 1 || idx > N) { DPDError("Error on line {0}; angle index {1} is invalid.", line_no, idx); } mol.angle_site_indices.Add(idx); } mol.angle_eq.Add(Convert.ToDouble(tokens[4])); mol.angle_k.Add(Convert.ToDouble(tokens[5])); } else { Console.WriteLine("Unknown entry {0} found on line {1} in molecule; ignoring.", key, line_no); } } // if parsing the coords ... else if (parse_state == ParseState.Coords) { if (site_upto > sim.site_ids.Length) { DPDError("Error on line {0}; this site should not exist", line_no); } var i = get_site_type_from_name(tokens[0], sim); if (i == -1) { DPDError("Error on line {0}; this site ( {1} ) is not recognised as a defined site type", line_no, tokens[0]); } sim.site_ids[site_upto] = i; sim.r[(site_upto * 3) + 0] = Convert.ToDouble(tokens[1]); sim.r[(site_upto * 3) + 1] = Convert.ToDouble(tokens[2]); sim.r[(site_upto * 3) + 2] = Convert.ToDouble(tokens[3]); // ignore velocity and force info if start of sim; this can also be used to force reset of info. if (sim.step_no > 0) { if (tokens.Length > 4) // try to get velocities from file { if (tokens.Length < 7) { DPDError("Error on line {0}; incomplete velocity entry for site! Only {1} value, and expecting 3 ( vx vy vz )", line_no, tokens.Length - 4); } sim.v[(site_upto * 3) + 0] = Convert.ToDouble(tokens[4]); sim.v[(site_upto * 3) + 1] = Convert.ToDouble(tokens[5]); sim.v[(site_upto * 3) + 2] = Convert.ToDouble(tokens[6]); } if (tokens.Length > 7) // try to get forces from file { if (tokens.Length < 10) { DPDError("Error on line {0}; incomplete force entry for site! Only {1} value, and expecting 3 ( fx fy fz )", line_no, tokens.Length - 7); } sim.f[(site_upto * 3) + 0] = Convert.ToDouble(tokens[7]); sim.f[(site_upto * 3) + 1] = Convert.ToDouble(tokens[8]); sim.f[(site_upto * 3) + 2] = Convert.ToDouble(tokens[9]); } } site_upto++; } // did we find the start of a defined parse section? else { string key = tokens[0]; if (key == "settings") { parse_state = ParseState.Settings; } else if (key == "sites") { parse_state = ParseState.Sites; } else if (key == "interactions") { var N_site_types = sim.site_types.Count; if (N_site_types < 1) { DPDError("Error on line {0}; attempting to define interactions without sites having been specified.", line_no); } Array.Resize(ref sim.interactions, N_site_types * N_site_types); for (var i = 0; i < sim.interactions.Length; i++) { sim.interactions[i] = 0.0; } parse_state = ParseState.Interactions; } else if (key == "molecule") { parse_state = ParseState.Molecule; } else if (key == "coords") { var N_sites = 0; foreach (var mt in sim.molecule_types) { N_sites += (mt.site_internal_ids.Count * mt.count); } Array.Resize(ref sim.site_ids, N_sites); Array.Resize(ref sim.molecule_ids, N_sites); Array.Resize(ref sim.r, N_sites * 3); Array.Resize(ref sim.v, N_sites * 3); Array.Resize(ref sim.f, N_sites * 3); Array.Resize(ref sim.v_, N_sites * 3); Array.Resize(ref sim.f_, N_sites * 3); parse_state = ParseState.Coords; } else { DPDError("Unknown parse section '{0}'' on line {1}", key, line_no); } } } // // Check for some obvious problems with the input. // if (!cell_found) { DPDError("cell not defined in DPD sim file"); } if (sim.cell[0] / 2.0 < sim.rcut || sim.cell[1] / 2.0 < sim.rcut || sim.cell[2] / 2.0 < sim.rcut) { DPDError("A cell dimension divided by two is smaller than rcut"); } if (sim.site_types.Count == 0) { DPDError("No sites defined in file"); } if (sim.molecule_types.Count == 0) { DPDError("No molecules defined in file"); } if (sim.interactions.Length == 0) { DPDError("No interactions defined in file"); } if (sim.site_ids.Length == 0) { DPDError("No site coordinates defined in file"); } if (site_upto != sim.site_ids.Length) { DPDError("Error in number of sites found; got {0}, wanted {1}\n", site_upto, sim.site_ids.Length); } // // Print some system information. // // // System settings // { Console.WriteLine("DPD simulation parameters:"); Console.WriteLine("\tstep_no is {0}", sim.step_no); Console.WriteLine("\tmax_steps is {0}", sim.max_steps); Console.WriteLine("\tsave_every is {0}", sim.save_every); Console.WriteLine("\tprint_every is {0}", sim.print_every); Console.WriteLine("\tdelta_t is {0}", sim.delta_t); Console.WriteLine("\tran1 initialised with {0}", sim.ran1_value); Console.WriteLine("\trcut is {0}", sim.rcut); Console.WriteLine("\tlambda is {0}", sim.lambda); Console.WriteLine("\tsigma is {0}", sim.sigma); Console.WriteLine("\tkBT is {0}", sim.target_kBT); Console.WriteLine("\tcell is {0}, {1}, {2}", sim.cell[0], sim.cell[1], sim.cell[2]); if (sim.i_am_dumb == 1) { Console.WriteLine("\t!!! This simulation is dumb regarding nonbonded interactions !!!"); } } // // Site types // Console.WriteLine("{0} site types:", sim.site_types.Count); for (var i = 0; i < sim.site_types.Count; i++) { Console.WriteLine("\t{0}; (internal {1})", sim.site_types[i].name, sim.site_types[i].internal_id); } // // Molecule types // Console.WriteLine("{0} molecule types:", sim.molecule_types.Count); for (int mi = 0; mi < sim.molecule_types.Count; mi++) { Console.WriteLine("\t{0}; {1} counts in system:", sim.molecule_types[mi].name, sim.molecule_types[mi].count); Console.WriteLine("\t\t{0} sites", sim.molecule_types[mi].site_internal_ids.Count); for (int si = 0; si < sim.molecule_types[mi].site_internal_ids.Count; si++) { var id = sim.molecule_types[mi].site_internal_ids[si]; Console.WriteLine("\t\t\t{0}, (id {1})", sim.site_types[id].name, sim.site_types[id].internal_id); } var n_bonds = sim.molecule_types[mi].bond_site_indices.Count / 2; Console.WriteLine("\t\t{0} bonds", n_bonds); for (var bi = 0; bi < n_bonds; bi++) { Console.WriteLine("\t\t\t{0} - {1} : eq length {2:F3}, k {3:F3}", sim.molecule_types[mi].bond_site_indices[bi * 2 + 0], sim.molecule_types[mi].bond_site_indices[bi * 2 + 1], sim.molecule_types[mi].bond_eq[bi], sim.molecule_types[mi].bond_k[bi]); } var n_angles = sim.molecule_types[mi].angle_site_indices.Count / 3; Console.WriteLine("\t\t{0} angles", n_angles); for (var ai = 0; ai < n_angles; ai++) { Console.WriteLine("\t\t\t{0} - {1} - {2} : eq length {3:F3}, k {4:F3}", sim.molecule_types[mi].angle_site_indices[ai * 2 + 0], sim.molecule_types[mi].angle_site_indices[ai * 2 + 1], sim.molecule_types[mi].angle_site_indices[ai * 2 + 1], sim.molecule_types[mi].angle_eq[ai], sim.molecule_types[mi].angle_k[ai]); } } // // Nonbonded interaction table // { var N_site_types = sim.site_types.Count; Console.Write("{0} interactions (defined in kBT):\n{1,12:S}", N_site_types, " "); for (var i = 0; i < N_site_types; i++) { Console.Write("\t{0,12:S}", sim.site_types[i].name); } Console.WriteLine(""); for (var i = 0; i < N_site_types; i++) { Console.Write("\t{0,12:S}", sim.site_types[i].name); for (var j = 0; j < N_site_types; j++) { Console.Write("\t{0,9:F3}", sim.interactions[(i * N_site_types) + j]); } Console.WriteLine(""); } } // // Check the list of sites agrees with the types expected from the molecule definitions // { var l = 0; for (var mi = 0; mi < sim.molecule_types.Count; mi++) { for (var j = 0; j < sim.molecule_types[mi].count; j++) { for (var k = 0; k < sim.molecule_types[mi].site_internal_ids.Count; k++) { var expected_type = sim.molecule_types[mi].site_internal_ids[k]; var actual_type = sim.site_ids[l]; var expected_name = sim.site_types[expected_type].name; var actual_name = sim.site_types[actual_type].name; if (actual_type != expected_type) { DPDError("Error in site id; wanted {0} ( \"{1}\" from molecule \"{2}\" number {3}, atom {4} ) but found {5} ( \"{6}\" )", expected_type, expected_name, sim.molecule_types[mi].name, j + 1, k + 1, actual_type, actual_name); } l++; } } } } Console.WriteLine("{0} sites", sim.site_ids.Length); }