Example #1
0
def run(test=False):
  # use a smiles string to query the pubchem search database and read the mol file returned from the http request
  # if cannot get to internet, read local cached response from pubchem
  try:
    s = system.read_pubchem_smiles('c1=cc=cc=c1')
  except:
      import os
      s = system.read_mol(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir, 'c1=cc=cc=c1.mol'))
  
  # the resulting system (benzene) has alternating double bonds
  # we want pysimm to recognize the ring as aromatic, so we define each bond in the ring to be bond order 'A'
  for b in s.bonds:
    if b.a.elem=='C' and b.b.elem=='C':
      b.order='A'
  
  # the resulting system has sufficient information to type with a forcefield, here we will use the GAFF2 force field
  # we will also determine partial charges using the gasteiger algorithm
  s.apply_forcefield(forcefield.Gaff2(), charges='gasteiger')
  
  # we'll perform a 2 step energy minimization using the steepest decent and conjugate gradient algorithms in LAMMPS
  lmps.quick_min(s, min_style='sd', name='min_sd')
  lmps.quick_min(s, min_style='cg', name='min_cg')
  
  # write a few different file formats
  s.write_xyz('benzene.xyz')
  s.write_yaml('benzene.yaml')
  s.write_lammps('benzene.lmps')
  s.write_chemdoodle_json('benzene.json')
Example #2
0
def monomer():
    try:
        s = system.read_pubchem_smiles('CC')
    except:
        import os
        s = system.read_mol(
            os.path.join(os.path.dirname(os.path.realpath(__file__)),
                         os.pardir, 'CC.mol'))
    f = forcefield.Gaff2()
    s.apply_forcefield(f)

    c1 = s.particles[1]
    c2 = s.particles[2]
    c1.linker = 'head'
    c2.linker = 'tail'

    for b in c1.bonds:
        if b.a.elem == 'H' or b.b.elem == 'H':
            pb = b.a if b.b is c1 else b.b
            s.particles.remove(pb.tag, update=False)
            break

    for b in c2.bonds:
        if b.a.elem == 'H' or b.b.elem == 'H':
            pb = b.a if b.b is c2 else b.b
            s.particles.remove(pb.tag, update=False)
            break

    s.remove_spare_bonding()

    lmps.quick_min(s, min_style='fire')

    s.add_particle_bonding()

    return s
Example #3
0
def monomer():
    try:
        import os
        s = system.read_mol(
            os.path.join(os.path.dirname(os.path.realpath(__file__)),
                         os.pardir, 'disGde.mol'))
    # s = system.read_pubchem_smiles('O=C(OCCSSCCC(O)=O)CC')
    except:
        import os
        s = system.read_mol(
            os.path.join(os.path.dirname(os.path.realpath(__file__)),
                         os.pardir, 'CC(C)C(=O)OC.mol'))
    f = forcefield.Gaff2()
    s.apply_forcefield(f)

    c3 = s.particles[1]
    c4 = s.particles[2]

    for b in c3.bonds:
        if b.a.elem == 'H' or b.b.elem == 'H':
            pb = b.a if b.b is c3 else b.b
            s.particles.remove(pb.tag, update=False)
            break

    for b in c4.bonds:
        if b.a.elem == 'H' or b.b.elem == 'H':
            pb = b.a if b.b is c4 else b.b
            s.particles.remove(pb.tag, update=False)
            break

    s.remove_spare_bonding()

    c3.linker = 'head'
    c4.linker = 'tail'

    lmps.quick_min(s, min_style='cg')

    s.add_particle_bonding()
    s.apply_charges(f, charges='gasteiger')
    signal = 0
    for pb in s.particles:
        if pb.elem == 'O' and 1 in pb.bond_orders and len(set(
                pb.bond_orders)) == 1:
            signal += 1
        if signal == 2 and pb.elem == 'O' and 1 in pb.bond_orders and len(
                set(pb.bond_orders)) == 1:
            pb.charge = pb.charge - 1
    return s
Example #4
0
def monomer():
    try:
        s = system.read_pubchem_smiles('CCc1=cc=cc=c1')
    except:
        import os
        s = system.read_mol(
            os.path.join(os.path.dirname(os.path.realpath(__file__)),
                         os.pardir, 'CCc1=cc=cc=c1.mol'))
    m = s.molecules[1]
    f = forcefield.Gaff2()

    for b in s.bonds:
        if b.a.bonds.count == 3 and b.b.bonds.count == 3:
            b.order = 4

    s.apply_forcefield(f)

    c1 = s.particles[1]
    c5 = s.particles[5]

    for b in c1.bonds:
        if b.a.elem == 'H' or b.b.elem == 'H':
            pb = b.a if b.b is c1 else b.b
            s.particles.remove(pb.tag, update=False)
            break

    for b in c5.bonds:
        if b.a.elem == 'H' or b.b.elem == 'H':
            pb = b.a if b.b is c5 else b.b
            s.particles.remove(pb.tag, update=False)
            break

    s.remove_spare_bonding()

    s.set_box(padding=10)

    c1.linker = 'head'
    c5.linker = 'tail'

    lmps.quick_min(s, min_style='fire')

    s.add_particle_bonding()

    return s
Example #5
0
def run(test=False):
    # use a smiles string to query the pubchem search database and read the mol file returned from the http request
    try:
        s = system.read_pubchem_smiles('CO')
    except:
        import os
        s = system.read_mol(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir, 'CO.mol'))
    
    # the resulting system has sufficient information to type with a forcefield, here we will use the GAFF2 force field
    s.apply_forcefield(forcefield.Gaff2())
    
    # we'll perform energy minimization using the fire algorithm in LAMMPS
    lmps.quick_min(s, min_style='fire')
    
    # write a few different file formats
    s.write_xyz('methanol.xyz')
    s.write_yaml('methanol.yaml')
    s.write_lammps('methanol.lmps')
    s.write_chemdoodle_json('methanol.json')
Example #6
0
def get_types():
    types = []
    desc = []
    molfile = request.form['mol']
    ff = request.form['ff']
    typer = request.form['typer']
    s = system.read_mol(molfile)
    try:
        if ff == 'Dreiding':
            f = forcefield.Dreiding()
            s.apply_forcefield(f)
        elif ff == 'Polymer Consistent Force Field (PCFF)':
            f = forcefield.Pcff()
            s.apply_forcefield(f)
        elif ff == 'Generalized Amber Force Field (GAFF)':
            f = forcefield.Gaff2()
            if typer == 'pysimm':
                s.apply_forcefield(f)
            elif typer == 'antechamber':
                cwd = os.getcwd()
                tempdir = tempfile.mkdtemp()
                print(tempdir)
                os.chdir(tempdir)
                amber.get_forcefield_types(s, f=f)
                os.chdir(cwd)
                shutil.rmtree(tempdir)
        types = [p.type.name for p in s.particles]
        desc = [p.type.desc for p in s.particles]
    except:
        print('error typing occurred')
    p_elems = set(p.elem for p in s.particles)
    possible_types = {e: [] for e in p_elems}
    possible_types_desc = {e: [] for e in p_elems}
    for pt in f.particle_types:
        if pt.elem in p_elems:
            possible_types[pt.elem].append(pt.name)
            possible_types_desc[pt.elem].append(pt.desc)

    return jsonify(types=types,
                   desc=desc,
                   possible_types=possible_types,
                   possible_types_desc=possible_types_desc)
Example #7
0
def run(test=False):
    # we'll create a pe monomer from the pysimm.models database
    pe = monomer()
    
    # we'll instantiate a GAFF2 forcefield object for use later
    f = forcefield.Gaff2()
    
    # the monomers do not have any charges, so we will derive partial charges using the gasteiger algorithm
    pe.apply_charges(f, charges='gasteiger')
    
    # run the random_walk polymerization method making a chain of 10 repeat units
    # the forcefield object is supplied to get new forcefield types not in the monomer system
    polymer = random_walk(pe, 10, forcefield=f)
    
    # write a few different file formats
    polymer.write_xyz('polymer.xyz')
    polymer.write_yaml('polymer.yaml')
    polymer.write_lammps('polymer.lmps')
    polymer.write_chemdoodle_json('polymer.json')
    
    # if you want to restart a polymerization, the yaml file format retains linker information
    # random_walk looks for the last head and tail linkers, so just run a copolymerization with the original polymer chain and new monomers
    # we give the copolymer function a list of reference "monomers", but use the first polymer chain as the first "monomer" and only insert one
    # then we use the pattern argument to define how many of each "monomers" to add. Let's add 5 more monomers to our chain
    
    # first import the copolymer function
    
    from pysimm.apps.random_walk import copolymer
    
    # now read in the yaml file we saved after making our first polymer
    
    original_polymer = system.read_yaml('polymer.yaml')
    
    # we can use our original polyethylene monomer because it doesn't get modified during polymerization
    # the total number of monomers we're adding is 6, 1 for the original polymer chain, and 5 for our new monomers
    
    longer_polymer = copolymer([original_polymer, pe], 6, pattern=[1, 5], forcefield=f)
    
    longer_polymer.write_xyz('longer_polymer.xyz')
    longer_polymer.write_yaml('longer_polymer.yaml')
    longer_polymer.write_lammps('longer_polymer.lmps')
    longer_polymer.write_chemdoodle_json('longer_polymer.json')
Example #8
0
def run(test=False):
    # we'll make a polyethylene monomer and a polystyrene monomer from the pysimm models database
    pe = pe_monomer()
    ps = ps_monomer()

    # we'll instantiate a GAFF2 forcefield object for use later
    f = forcefield.Gaff2()

    # the monomers do not have any charges, so we will derive partial charges using the gasteiger algorithm
    pe.apply_charges(f, charges='gasteiger')
    ps.apply_charges(f, charges='gasteiger')

    # run the copolymer random walk method with 10 total repeat units, using an alternating pattern
    polymer = copolymer([pe, ps], 10, pattern=[1, 1], forcefield=f)

    # write a few different file formats
    polymer.write_xyz('polymer.xyz')
    polymer.write_yaml('polymer.yaml')
    polymer.write_lammps('polymer.lmps')
    polymer.write_chemdoodle_json('polymer.json')
Example #9
0
def get_lmps():
    molfile = request.form['mol']
    type_names = map(lambda x: x.split()[-1],
                     request.form.getlist('typeNames[]'))
    ff = request.form['ff']
    if ff == 'Dreiding':
        f = forcefield.Dreiding()
    elif ff == 'Polymer Consistent Force Field (PCFF)':
        f = forcefield.Pcff()
    elif ff == 'Generalized Amber Force Field (GAFF)':
        f = forcefield.Gaff2()
    s = system.read_mol(molfile)
    types = {
        name: s.particle_types.add(f.particle_types.get(name)[0].copy())
        for name in set(type_names)
    }
    for p, pname in zip(s.particles, type_names):
        p.type = types[pname]
    s.apply_forcefield(f, skip_ptypes=True)
    s.pair_style = f.pair_style
    return jsonify(lmpsData=s.write_lammps('string'))
Example #10
0
def monomer():
    try:
        s = system.read_pubchem_smiles('CC(C)C(=O)OC')
    except:
        import os
        s = system.read_mol(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir, 'CC(C)C(=O)OC.mol'))
    m = s.molecules[1]
    f = forcefield.Gaff2()
    
    s.apply_forcefield(f)
    
    c3 = s.particles[3]
    c4 = s.particles[4]
    
    for b in c3.bonds:
        if b.a.elem == 'H' or b.b.elem == 'H':
            pb = b.a if b.b is c3 else b.b
            s.particles.remove(pb.tag, update=False)
            break
        
    for b in c4.bonds:
        if b.a.elem == 'H' or b.b.elem == 'H':
            pb = b.a if b.b is c4 else b.b
            s.particles.remove(pb.tag, update=False)
            break
            
    s.remove_spare_bonding()

    s.set_box(padding=10)
    
    c3.linker = 'head'
    c4.linker = 'tail'
    
    lmps.quick_min(s, min_style='fire')
    
    s.add_particle_bonding()
    
    return s
Example #11
0
from pysimm import system, lmps, forcefield

# use a smiles string to query the pubchem search database and read the mol file returned from the http request
s = system.read_pubchem_smiles('CO')

# the resulting system has sufficient information to type with a forcefield, here we will use the GAFF2 force field
s.apply_forcefield(forcefield.Gaff2())

# we'll perform energy minimization using the fire algorithm in LAMMPS
lmps.quick_min(s, min_style='fire')

# write a few different file formats
s.write_xyz('methanol.xyz')
s.write_yaml('methanol.yaml')
s.write_lammps('methanol.lmps')
s.write_chemdoodle_json('methanol.json')
Example #12
0
def run(test=False):
    try:
        ethanol = system.read_pubchem_smiles('CCO')
    except:
        import os
        ethanol = system.read_mol(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'CCO.mol'))
    try:
        acetone = system.read_pubchem_smiles('CC(=O)C')
    except:
        import os
        acetone = system.read_mol(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'CC(=O)C.mol'))

    f = forcefield.Gaff2()
    
    ethanol.apply_forcefield(f, charges='gasteiger')
    acetone.apply_forcefield(f, charges='gasteiger')
    
    # amber.calc_charges(ethanol)
    # amber.calc_charges(acetone)
    
    lmps.quick_min(ethanol, min_style='fire')
    lmps.quick_min(acetone, min_style='fire')
    
    molecule_list = [ethanol, acetone]
    
    if test:
        n_molecules = [20, 20]
    else:
        n_molecules = [200, 200]
    
    s = system.replicate(molecule_list, n_molecules, density=0.3)
    
    min_settings = {
        'name': 'cg_min',
        'min_style': 'cg',
        'maxiter': int(5e+5),
        'maxeval': int(5e+6),
    }
    
    nvt_settings = {
        'name': 'nvt_md',
        'print_to_screen': True,
        'ensemble': 'nvt',
        'temperature': {
            'start': 100,
            'stop': 300
        },
        'new_v': True,
        'length': 2500
    }
    
    npt_settings = {
        'name': 'npt_md',
        'print_to_screen': True,
        'ensemble': 'npt',
        'temperature': 300,
        'new_v': True,
        'pressure': {
            'start': 1000,
            'stop': 1
        },
        'length': 5000,
    }
    
    npt_settings_add = {
        'name': 'npt_md',
        'print_to_screen': True,
        'ensemble': 'npt',
        'temperature': 300,
        'new_v': True,
        'pressure': {
            'start': 1,
            'stop': 1
        },
        'length': 5000,
    }
    
    if test:
        nvt_settings['length'] = 2000
        npt_settings['length'] = 2000
        
    sim = lmps.Simulation(s)
    sim.add_min(**min_settings)
    
    sim.add(lmps.OutputSettings(thermo={'freq': 500, 
                                        'style': 'custom', 
                                        'args': ['step', 'temp', 'etotal', 'press', 'density']}))

    sim.add_md(**nvt_settings)
    sim.add_md(**npt_settings)
    sim.add_md(**npt_settings_add)
    sim.run()

    s.write_yaml('mixture.yaml')
    s.write_lammps('mixture.lmps')
Example #13
0
def polymer_chain(length):
    mon = monomer()
    polym = random_walk(mon, length, forcefield=forcefield.Gaff2())
    return polym
Example #14
0
def run(test=False):
    try:
        ethanol = system.read_pubchem_smiles('CCO')
    except:
        import os
        ethanol = system.read_mol(
            os.path.join(os.path.dirname(os.path.realpath(__file__)),
                         'CCO.mol'))
    try:
        acetone = system.read_pubchem_smiles('CC(=O)C')
    except:
        import os
        acetone = system.read_mol(
            os.path.join(os.path.dirname(os.path.realpath(__file__)),
                         'CC(=O)C.mol'))

    f = forcefield.Gaff2()

    ethanol.apply_forcefield(f, charges='gasteiger')
    acetone.apply_forcefield(f, charges='gasteiger')

    # amber.calc_charges(ethanol)
    # amber.calc_charges(acetone)

    lmps.quick_min(ethanol, min_style='fire')
    lmps.quick_min(acetone, min_style='fire')

    molecule_list = [ethanol, acetone]

    if test:
        n_molecules = [30, 20]
    else:
        n_molecules = [300, 200]

    s = system.replicate(molecule_list, n_molecules, density=0.3)

    min_settings = {
        'name': 'fire_min',
        'min_style': 'fire',
        'print_to_screen': True
    }

    nvt_settings = {
        'name': 'nvt_md',
        'print_to_screen': True,
        'ensemble': 'nvt',
        'temperature': {
            'start': 100,
            'stop': 300
        },
        'new_v': True,
        'length': 10000
    }

    npt_settings = {
        'name': 'npt_md',
        'print_to_screen': True,
        'ensemble': 'npt',
        'temperature': 300,
        'new_v': True,
        'pressure': {
            'start': 1000,
            'stop': 1
        },
        'length': 100000,
        'thermo_style': 'custom step temp press density'
    }

    if test:
        nvt_settings['length'] = 2000
        npt_settings['length'] = 2000

    lmps.quick_min(s, **min_settings)
    lmps.quick_md(s, **nvt_settings)
    lmps.quick_md(s, **npt_settings)

    s.write_xyz('mixture.xyz')
    s.write_yaml('mixture.yaml')
    s.write_lammps('mixture.lmps')
    s.write_chemdoodle_json('mixture.json')
Example #15
0
from pysimm import system, lmps, forcefield

# use a smiles string to query the pubchem search database and read the mol file returned from the http request
s = system.read_pubchem_smiles('c1=cc=cc=c1')

# the resulting system (benzene) has alternating double bonds
# we want pysimm to recognize the ring as aromatic, so we define each bond in the ring to be bond order 'A'
for b in s.bonds:
    if b.a.elem == 'C' and b.b.elem == 'C':
        b.order = 'A'

# the resulting system has sufficient information to type with a forcefield, here we will use the GAFF2 force field
# we will also determine partial charges using the gasteiger algorithm
s.apply_forcefield(forcefield.Gaff2(), charges='gasteiger')

# we'll perform energy minimization using the fire algorithm in LAMMPS
lmps.quick_min(s, min_style='fire')

# write a few different file formats
s.write_xyz('benzene.xyz')
s.write_yaml('benzene.yaml')
s.write_lammps('benzene.lmps')
s.write_chemdoodle_json('benzene.json')
Example #16
0
def run(test=False):
    # we'll create a pmma monomer from the pysimm.models database
    pmma = monomer()

    # we'll instantiate a GAFF2 forcefield object for use later
    f = forcefield.Gaff2()

    # we're going to make 4 chains, each of 5 repeat units
    # the first system we make will be used as the initial system and then replicated to form 4 chains
    # in this case the system.replicate function take a system input(polymer),
    # replicates a defined number of times(4), and inserts the new replication randomly(rand=True) at the specified density(0.022)

    print('Building polymer chain 1...')
    polymer = random_walk(pmma, nmon=5, forcefield=f)
    print('Replicating polymer chain...')
    uniform_polymer = system.replicate(polymer, 4, density=0.022, rand=True)

    # next we're going to make 4 chains, with lengths of 2, 4, 6, and 8 monomer units
    # the first system we make will be used as the initial system for the subsequent random walk calls

    print('Building polymer chain 1...')
    nonuniform_polymer = random_walk(pmma,
                                     nmon=2,
                                     forcefield=f,
                                     density=0.3 / 4)
    print('Building polymer chain 2...')
    nonuniform_polymer = random_walk(pmma,
                                     nmon=4,
                                     s_=nonuniform_polymer,
                                     forcefield=f)
    print('Building polymer chain 3...')
    nonuniform_polymer = random_walk(pmma,
                                     nmon=6,
                                     s_=nonuniform_polymer,
                                     forcefield=f)
    print('Building polymer chain 4...')
    nonuniform_polymer = random_walk(pmma,
                                     nmon=8,
                                     s_=nonuniform_polymer,
                                     forcefield=f)

    # now that we have our two polymer systems, let's calculate their molecular weight dispersity
    uniform_polymer.set_mm_dist()
    nonuniform_polymer.set_mm_dist()

    print('')
    print('Uniform polymer')
    print('---------------')
    print('Number average molecular weight: {}'.format(uniform_polymer.mn))
    print('Weight average molecular weight: {}'.format(uniform_polymer.mw))
    print('Dispersity: {}'.format(uniform_polymer.dispersity))
    print('')
    print('Nonuniform polymer')
    print('------------------')
    print('Number average molecular weight: {}'.format(nonuniform_polymer.mn))
    print('Weight average molecular weight: {}'.format(nonuniform_polymer.mw))
    print('Dispersity: {}'.format(nonuniform_polymer.dispersity))

    # write a few different file formats
    uniform_polymer.write_yaml('uniform_polymer.yaml')
    uniform_polymer.write_xyz('uniform_polymer.xyz')

    nonuniform_polymer.write_yaml('nonuniform_polymer.yaml')
    nonuniform_polymer.write_xyz('nonuniform_polymer.xyz')
Example #17
0
from pysimm import system, lmps, forcefield

# create empty system
s = system.System()

# create new molecule in our system
m = s.molecules.add(system.Molecule())

# retrieve GAFF2 parameters
f = forcefield.Gaff2()

# get a copy of the c3 particle type object from GAFF
# get method returns a list, we need the first element
gaff_c3 = s.particle_types.add(f.particle_types.get('c3')[0].copy())

# we'll first make the carbon atom at the origin
# we'll include gasteiger charges later
c1 = s.particles.add(
    system.Particle(type=gaff_c3, x=0, y=0, z=0, charge=0, molecule=m))

# get hc particle type object from GAFF
gaff_hc = f.particle_types.get('hc')[0].copy()

# add hc particle type to system
s.particle_types.add(gaff_hc)

# now we'll add 4 hydrogen atoms bonded to our carbon atom
# these atoms will be placed randomly 1.5 angstroms from the carbon atom
# we'll optimize the structure using LAMMPS afterwords
# we supply the GAFF forcefield object so that bond and angle types can be added as well
h1 = s.add_particle_bonded_to(
Example #18
0
def run(test=False):
    # create empty system
    print('Example progress: Creating an empty system...')
    s = system.System()

    # create new molecule in our system
    print(
        'Example progress: Adding an empty molecule container to our system...'
    )
    m = s.molecules.add(system.Molecule())

    # retrieve GAFF2 parameters
    print('Example progress: Retrieving Dreiding force field parameters...')
    f = forcefield.Gaff2()
    s.forcefield = f.name

    # get a copy of the c3 particle type object from GAFF
    # get method returns a list, we need the first element
    gaff_c3 = s.particle_types.add(f.particle_types.get('c3')[0].copy())

    # get hc particle type object from GAFF
    gaff_hc = s.particle_types.add(f.particle_types.get('hc')[0].copy())

    # we'll first make the carbon atom at the origin
    # we'll include gasteiger charges later
    print('Example progress: Adding carbon atom at origin...')
    c1 = s.particles.add(
        system.Particle(type=gaff_c3, x=0, y=0, z=0, charge=0, molecule=m))

    # now we'll add 4 hydrogen atoms bonded to our carbon atom
    # these atoms will be placed randomly 1.5 angstroms from the carbon atom
    # we'll optimize the structure using LAMMPS afterwords
    # we supply the GAFF forcefield object so that bond and angle types can be added as well
    print(
        'Example progress: Adding 4 hydrogen atoms at random positions bonded to the carbon atom...'
    )
    h1 = s.add_particle_bonded_to(
        system.Particle(type=gaff_hc, charge=0, molecule=m), c1, f)
    h2 = s.add_particle_bonded_to(
        system.Particle(type=gaff_hc, charge=0, molecule=m), c1, f)
    h3 = s.add_particle_bonded_to(
        system.Particle(type=gaff_hc, charge=0, molecule=m), c1, f)
    h4 = s.add_particle_bonded_to(
        system.Particle(type=gaff_hc, charge=0, molecule=m), c1, f)

    # let's add gasteiger charges
    print('Example progress: Deriving Gasteiger charges...')
    s.apply_charges(f, charges='gasteiger')

    # right now there is no simulation box defined
    # we'll define a box surrounding our methane molecule with a 10 angstrom padding
    print(
        'Example progress: Constructing Simulation box surrounding our new molecule...'
    )
    s.set_box(padding=10)

    # before we optimize our structure, LAMMPS needs to know what type of
    # pair, bond, and angle interactions we are using
    # these are determined by the forcefield being used
    s.pair_style = 'lj'
    s.bond_style = 'harmonic'
    s.angle_style = 'harmonic'

    # we'll perform energy minimization using the fire algorithm in LAMMPS
    print('Example progress: Optimizing structure using LAMMPS...')
    lmps.quick_min(s,
                   min_style='fire',
                   name='fire_min',
                   etol=1e-10,
                   ftol=1e-10)

    # write xyz, YAML, LAMMPS data, and chemdoodle json files
    print('Example progress: Saving structure to files...')
    s.write_xyz('methane.xyz')
    s.write_yaml('methane.yaml')
    s.write_lammps('methane.lmps')
    s.write_chemdoodle_json('methane.json')

    print('Example progress: Complete!')