Software engineering is focused on the process of creating and maintaining software, including all aspects of requirements engineering, design, implementation, testing, and distribution. Robust software engineering processes are critical to software projects that meet both functional and nonfunctional requirements. Functional requirements describe what software should do. Nonfunctional requirements include important aspects of software that are not related to functionality, such as extensibility, maintainability, modifiability, scalability, portability, performance portability, reusability, robustness, testability, readability, reliability, resilience, sustainability, and usability.
Use of CSE software in making important decisions based on large-scale simulations is increasing roughly as fast as technology and resources allow. CSE software development inherently requires deep domain knowledge. Yet, domain experts commonly lack the software engineering skills to adequately meet several nonfunctional requirements, often including extensibility, maintainability, modifiability, or reusability. Conversely, most software engineers lack sufficient expertise in the science domains and understanding of the CSE community and are unable to effectively participate in CSE software projects. Historically, CSE software projects were more heavily focused on research, but recently an increased focus on production-quality software has necessitated a greater effort in software engineering. While improvements have been achieved, the gap between the software engineering practices of a typical CSE software team and software teams from other disciplines is still significant.