The problem is that the regular expression you are using as an address is terminated by the first /, which might be in ${rundir} or might be the / immediately following that; it is certainly not the / after posttest.
In general, interpolating variables into a regular expression is somewhat dangerous. If the variable's contents include regular expression metacharacters, then things are likely to fail in unexpected ways. If, as is the case here, the variable's value might include the regular expression terminator, then part of the variable's value will be interpreted as a command.
With that warning in mind, you have a couple of options. If you know that some character, say :, does not appear in ${rundir}, then you can use the that character as a regular expression terminator. (Note the backslash, which is how you tell sed that what follows is a regular expression.)
sed -e "\:^#PBS -o ${rundir}/posttest:s#_CMODEL#${cmodel}#" \ -e "\:^#PBS -e ${rundir}/posttest:s#_CMODEL#${cmodel}#" \ "${rundir}/run_post.shell" >"${rundir}/run_post.${cmodel}.sh"
Alternatively, you could backslash-escape the literal / and use bash's pattern-substitution syntax to backslash-escape all the / in $rundir:
${rundir//\//\\/}
(As mentioned above, you really should escape all possible metacharacters, including backslashes themselves.)
${rundir}have/characters in it?/^#PBS -o ${rundir}/posttest/to be a regex pattern which indicates which lines thescommand will apply to, then you need to escape the inner/. Otherwise, some explanation of what you are trying to do would be helpful.posttestand the ones that are in the variable.-[eo]is quite a bit easier on the eyes than-\(o\|e\), and\|is a Gnu sed extension which may not be available in all seds.