Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enhance template read me #87

Merged
merged 12 commits into from
Feb 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 103 additions & 4 deletions FileGenerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,109 @@ def _generate_static_files(self, target: Path, name: str) -> None:
pass

def _generate_README(self) -> None:
"""Generates the README.md file"""
self._generate_static_files(target=self.structure.README,
name="README.md")
"""Generates the README.md file with dynamic content based on simulation configuration"""
# Comprehensive solver documentation links
SOLVER_DOCS = {
# CFD Solvers
'openfoam': 'https://www.openfoam.com/documentation',
'su2': 'https://su2code.github.io/docs/home/',
'foam-extend': 'https://sourceforge.net/p/foam-extend/',

# Structural Solvers
'calculix': 'https://www.calculix.de/',
'elmer': 'https://www.elmersolver.com/documentation/',
'code_aster': 'https://www.code-aster.org/V2/doc/default/en/index.php',

# Other Solvers
'fenics': 'https://fenicsproject.org/docs/',
'dealii': 'https://dealii.org/current/doxygen/deal.II/index.html',

# Fallback
'default': 'https://precice.org/adapter-list.html'
}

# Read the template README with explicit UTF-8 encoding
with open(Path(__file__).parent / "templates" / "template_README.md", 'r', encoding='utf-8') as template_file:
readme_content = template_file.read()

# Extract participants and their solvers
participants_list = []
solvers_list = []
solver_links = {}
original_solver_names = {}

# Ensure participants exist before processing
if not hasattr(self.user_ui, 'participants') or not self.user_ui.participants:
self.logger.warning("No participants found. Using default placeholders.")
participants_list = ["DefaultParticipant"]
solvers_list = ["DefaultSolver"]
original_solver_names = {"defaultparticipant": "DefaultSolver"}
else:
for participant_name, participant_info in self.user_ui.participants.items():
# Preserve original solver name
original_solver_name = getattr(participant_info, 'solverName', 'UnknownSolver')
solver_name = original_solver_name.lower()

participants_list.append(participant_name)
solvers_list.append(original_solver_name)
original_solver_names[participant_name.lower()] = original_solver_name

# Get solver documentation link, use default if not found
solver_links[solver_name] = SOLVER_DOCS.get(solver_name, SOLVER_DOCS['default'])

# Determine coupling strategy (you might want to extract this from topology.yaml)
coupling_strategy = "Partitioned" if len(participants_list) > 1 else "Single Solver"

# Replace placeholders
readme_content = readme_content.replace("{PARTICIPANTS_LIST}", "\n ".join(f"- {p}" for p in participants_list))
readme_content = readme_content.replace("{SOLVERS_LIST}", "\n ".join(f"- {s}" for s in solvers_list))
readme_content = readme_content.replace("{COUPLING_STRATEGY}", coupling_strategy)

# Explicitly replace solver-specific placeholders
readme_content = readme_content.replace("{SOLVER1_NAME}", solvers_list[0] if solvers_list else "Solver1")
readme_content = readme_content.replace("{SOLVER2_NAME}", solvers_list[1] if len(solvers_list) > 1 else "Solver2")

# Generate adapter configuration paths for all participants
adapter_config_paths = []
print("Participants:", participants_list)
print("Original Solver Names:", original_solver_names)

for participant in participants_list:
# Find the corresponding solver name for this participant
solver_name = original_solver_names.get(participant.lower(), 'solver')
print(f"Participant: {participant}, Solver Name: {solver_name}")
adapter_config_paths.append(f"- **{participant}**: `{participant}-{solver_name}/adapter-config.json`")

# Replace adapter configuration section
readme_content = readme_content.replace(
"- **Adapter Configuration**: `{PARTICIPANT_NAME}/adapter-config.json`",
"**Adapter Configurations**:\n" + "\n".join(adapter_config_paths)
)

# Explicitly replace solver links
readme_content = readme_content.replace(
"[Link1]",
f"[{solvers_list[0] if solvers_list else 'Solver1'}]({solver_links.get(solvers_list[0].lower(), '#') if solvers_list else '#'})"
)
readme_content = readme_content.replace(
"[Link2]",
f"[{solvers_list[1] if len(solvers_list) > 1 else 'Solver2'}]({solver_links.get(solvers_list[1].lower(), '#') if len(solvers_list) > 1 else '#'})"
)

# Generate comprehensive solver links
solver_links_section = "**Solvers Links and Names**:\n"
for solver_name, solver_link in solver_links.items():
solver_links_section += f"- {original_solver_names.get(solver_name, solver_name.capitalize())}: [{solver_name.upper()}]({solver_link})\n"

# Replace the placeholder with the generated solver links
readme_content = readme_content.replace("[Solvers Links and Names]", solver_links_section)

# Write the updated README with UTF-8 encoding
with open(self.structure.README, 'w', encoding='utf-8') as readme_file:
readme_file.write(readme_content)

self.logger.success(f"Generated README at {self.structure.README}")

def _generate_run(self, run_sh: Path) -> None:
"""Generates the run.sh file
:param run_sh: Path to the run.sh file"""
Expand All @@ -117,8 +216,8 @@ def _generate_adapter_config(self, target_participant: str, adapter_config: Path
def generate_level_0(self) -> None:
"""Fills out the files of level 0 (everything in the root folder)."""
self._generate_clean()
self._generate_README()
self._generate_precice_config()
self._generate_README()

def _extract_participants(self) -> list[str]:
"""Extracts the participants from the topology.yaml file."""
Expand Down
97 changes: 72 additions & 25 deletions templates/template_README.md
Original file line number Diff line number Diff line change
@@ -1,57 +1,104 @@
# πŸš€ Simulation README
# πŸš€ Multiphysics Simulation Project

This `README.md` file was auto-generated by the `FileGenerator.py` script.
This `README.md` file was auto-generated by the `FileGenerator.py` script, providing a comprehensive guide to your coupled simulation.

---

## πŸƒβ€β™‚οΈ Running the Simulation
## πŸ“‹ Project Overview

To run the simulation:
This project utilizes **preCICE** (Precise Code Interaction Coupling Environment) for a multiphysics simulation involving:

1. Navigate to the `_generated` folder.
2. Execute the following command:
- **Participants**:
{PARTICIPANTS_LIST}

```bash
bash run.sh
```
or
- **Solvers**:
{SOLVERS_LIST}

- **Coupling Strategy**:
{COUPLING_STRATEGY}

---

## πŸ›  Prerequisites

Before running the simulation, ensure you have the following installed:
- preCICE library
- {SOLVER1_NAME} solver
- {SOLVER2_NAME} solver
- Required dependencies for each solver

---

## πŸƒβ€β™‚οΈ Running the Simulation

### Quick Start

```bash
# Navigate to the `_generated` folder
cd _generated/

# Make the run script executable
chmod +x run.sh

# Execute the simulation
./run.sh
```

### Advanced Execution

For more control or debugging:
- Check `run.sh` for specific command-line arguments
- Modify solver-specific parameters in `adapter-config.json`

---

## 🧹 Cleaning the artifacts of the Simulation
## πŸ” Simulation Configuration

To clean up:
- **preCICE Configuration**: `precice-config.xml`
- Defines coupling interface and communication strategy
- Modify with caution, refer to preCICE documentation

1. Navigate to the `_generated` folder.
2. Execute the following command:
- **Adapter Configuration**: `{PARTICIPANT_NAME}/adapter-config.json`
- Solver-specific coupling parameters
- Adjust solver input/output mappings here

```bash
bash clean.sh
```
or
---

## 🧹 Cleaning Simulation Artifacts

```bash
# Make the clean script executable
chmod +x clean.sh

# Remove generated files and reset workspace
./clean.sh
```

---
**Warning**: This will remove all generated files except preserved ones.

## πŸ“š Learning Materials
---

Want to dive deeper into **preCICE**? Check out the official tutorials:
## πŸ“š Additional Resources

πŸ”— [preCICE Tutorials](https://precice.org/tutorials.html)
- πŸ”— [preCICE Tutorials](https://precice.org/tutorials.html)
- πŸ”— [preCICE Documentation](https://precice.org/docs.html)
- πŸ”— Solver-specific documentation:
[Solvers Links and Names]

---

## 🀝 Contributions
## 🀝 Troubleshooting

We welcome contributions! To contribute to this project:
Common issues and solutions:
- Ensure all solvers are compatible with preCICE version
- Check network/communication settings
- Verify adapter configuration mappings

For specific problems, consult:
- Solver documentation
- preCICE community forums
- Project-specific documentation

---

πŸ‘‰ Visit our repository: [preCICE GitHub Repo](https://www.github.com/precice)
*Generated by FileGenerator.py - Simplifying Multiphysics Simulation Workflows*